[Scummvm-git-logs] scummvm master -> 0ccf4a9ff620a86c144945b655eda3ebe544f478
OMGPizzaGuy
noreply at scummvm.org
Fri Sep 8 23:26:11 UTC 2023
This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
447e14e072 ULTIMA8: Merge RenderSurface and SoftRenderSurface
26df05f718 ULTIMA8: Clean up RenderSurface member variables
0aed7b6f00 ULTIMA8: Remove build rule for deleted file
ebf130e42c ULTIMA8: Clean up pixels pointer and pitch handling in RenderSurface
e381469830 ULTIMA8: Clean up RenderSurface blit and fill methods
bea3e12656 ULTIMA8: Fix RenderSurface blit methods for 32 bpp
04b9b2cdae ULTIMA8: Remove flipped clip window calculations from RenderSurface.
e0e9d02f18 ULTIMA8: Store shape frame pixels in a surface to allow use in standard blit methods
4a59130ca5 ULTIMA8: Remove unused parameter on shape paint methods
c24d47c672 ULTIMA8: Rewrite shape frame paint for improved readibility and faster clipping
9c67d5684f ULTIMA8: Remove PaintNoClip method as it no longer provides a measurable performance increase over other shape paint met
0ccf4a9ff6 ULTIMA8: Allow any 16 or 32 bpp pixel formats
Commit: 447e14e0726616dc6faca568d44fbde0e9d23d12
https://github.com/scummvm/scummvm/commit/447e14e0726616dc6faca568d44fbde0e9d23d12
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Merge RenderSurface and SoftRenderSurface
Changed paths:
A engines/ultima/ultima8/graphics/render_surface.inl
R engines/ultima/ultima8/graphics/soft_render_surface.cpp
R engines/ultima/ultima8/graphics/soft_render_surface.h
R engines/ultima/ultima8/graphics/soft_render_surface.inl
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.h
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index b8a35390985..712029ea7c1 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -20,9 +20,11 @@
*/
#include "ultima/ultima8/misc/debugger.h"
-#include "ultima/ultima8/graphics/soft_render_surface.h"
#include "ultima/ultima8/graphics/palette.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
#include "ultima/ultima8/graphics/texture.h"
+#include "ultima/ultima8/graphics/xform_blend.h"
#include "ultima/ultima8/ultima8.h"
#include "common/system.h"
#include "engines/util.h"
@@ -330,6 +332,144 @@ void RenderSurface::Fill32(uint32 rgb, const Rect &r) {
_surface->fillRect(Common::Rect(rect.left + _ox, rect.top + _oy, rect.right + _ox, rect.bottom + _oy), rgb);
}
+
+// #define CHECK_ALPHA_FILLS
+namespace {
+
+template<typename uintX>
+void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Rect &rect, const Graphics::PixelFormat &format) {
+ uint32 aMask = format.aMax() << format.aShift;
+ int32 w = rect.width();
+ int32 h = rect.height();
+
+ if (!w || !h || !aMask)
+ return;
+
+ // An optimization.
+ if (w * format.bytesPerPixel == pitch) {
+ w *= h;
+ h = 1;
+ }
+
+ uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
+ uint8 *end = pixel + h * pitch;
+
+ uint8 *line_end = pixel + w * format.bytesPerPixel;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ uint32 a = (((uint32)alpha) << format.aShift) & aMask;
+
+#ifdef CHECK_ALPHA_FILLS
+ uint32 c;
+ uint32 m;
+ if (a == 0) {
+ c = (format.bMask >> 1) & format.bMask;
+ m = format.bMask;
+ } else {
+ c = (format.rMask >> 1) & format.rMask;
+ m = format.rMask;
+ }
+#endif
+
+ while (pixel != end) {
+ while (pixel != line_end) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+ *dest = (*dest & ~aMask) | a;
+#ifdef CHECK_ALPHA_FILLS
+ *dest = (*dest & ~m) | (c + (((*dest & m) >> 1) & m));
+#endif
+ pixel += format.bytesPerPixel;
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ }
+}
+
+} // End of anonymous namespace
+
+//
+// RenderSurface::FillAlpha(uint8 alpha, Rect r)
+//
+// Desc: Fill alpha channel
+//
+void RenderSurface::FillAlpha(uint8 alpha, const Rect &r) {
+ Rect rect = r;
+ rect.clip(_clipWindow);
+
+ if (_surface->format.bytesPerPixel == 4)
+ fillAlphaLogic<uint32>(_pixels, _pitch, alpha, rect, _surface->format);
+ else if (_surface->format.bytesPerPixel == 2)
+ fillAlphaLogic<uint16>(_pixels, _pitch, alpha, rect, _surface->format);
+}
+
+namespace {
+
+template<typename uintX>
+void inline fillBlendedLogic(uint8 *pixels, int32 pitch, uint32 rgba, const Rect &rect, const Graphics::PixelFormat &format) {
+ int32 w = rect.width();
+ int32 h = rect.height();
+
+ if (!w || !h)
+ return;
+
+ // An optimization.
+ if (w * format.bytesPerPixel == pitch) {
+ w *= h;
+ h = 1;
+ }
+
+ uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
+ uint8 *end = pixel + h * pitch;
+
+ uint8 *line_end = pixel + w * format.bytesPerPixel;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ uint32 aMask = format.aMax() << format.aShift;
+ int alpha = TEX32_A(rgba);
+ rgba = TEX32_PACK_RGBA((TEX32_R(rgba) * alpha) >> 8,
+ (TEX32_G(rgba) * alpha) >> 8,
+ (TEX32_B(rgba) * alpha) >> 8,
+ (255 * alpha) >> 8);
+
+ while (pixel != end) {
+ while (pixel != line_end) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+ uint32 d = *dest;
+ *dest = (d & aMask) | BlendPreModFast(rgba, d, format);
+ pixel += format.bytesPerPixel;
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ }
+}
+
+} // End of anonymous namespace
+
+//
+// RenderSurface::FillBlended(uint32 rgba, Rect r)
+//
+// Desc: Fill the region doing alpha blending
+//
+void RenderSurface::FillBlended(uint32 rgba, const Rect &r) {
+ int alpha = TEX32_A(rgba);
+ if (alpha == 0xFF) {
+ Fill32(rgba, r);
+ return;
+ } else if (!alpha) {
+ return;
+ }
+
+ Rect rect = r;
+ rect.clip(_clipWindow);
+
+ if (_surface->format.bytesPerPixel == 4)
+ fillBlendedLogic<uint32>(_pixels, _pitch, rgba, rect, _surface->format);
+ else if (_surface->format.bytesPerPixel == 2)
+ fillBlendedLogic<uint16>(_pixels, _pitch, rgba, rect, _surface->format);
+}
+
//
// RenderSurface::DrawLine32(uint32 rgb, int32 sx, int32 sy, int32 ex, int32 ey);
//
@@ -354,6 +494,301 @@ void RenderSurface::Blit(const Graphics::ManagedSurface &src, const Common::Rect
}
}
+namespace {
+
+template<typename uintX>
+void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Graphics::ManagedSurface &src,
+ const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
+ int32 w = srcRect.width();
+ int32 h = srcRect.height();
+
+ // Clamp or wrap or return?
+ if (w > static_cast<int32>(src.w))
+ return;
+
+ // Clamp or wrap or return?
+ if (h > static_cast<int32>(src.h))
+ return;
+
+ // Clip to window
+ int px = dx, py = dy;
+
+ Rect rect(dx, dy, dx + w, dy + h);
+ rect.clip(clipWindow);
+ dx = rect.left;
+ dy = rect.top;
+ w = rect.width();
+ h = rect.height();
+
+ if (!w || !h)
+ return;
+
+ int32 sx = srcRect.left;
+ int32 sy = srcRect.top;
+
+ // Adjust source x and y
+ if (px != dx)
+ sx += dx - px;
+ if (py != dy)
+ sy += dy - py;
+
+ uint8 *pixel = pixels + dy * pitch + dx * format.bytesPerPixel;
+ uint8 *line_end = pixel + w * format.bytesPerPixel;
+ uint8 *end = pixel + h * pitch;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ uint32 a = TEX32_A(col32);
+ uint32 ia = 256 - a;
+ uint32 r = (TEX32_R(col32) * a);
+ uint32 g = (TEX32_G(col32) * a);
+ uint32 b = (TEX32_B(col32) * a);
+
+ const Graphics::PixelFormat &texformat = src.rawSurface().format;
+
+ if (texformat.bpp() == 32) {
+ const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
+ int tex_diff = src.w - w;
+
+ while (pixel != end) {
+ if (!alpha_blend)
+ while (pixel != line_end) {
+ if (TEX32_A(*texel)) {
+ *(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
+ format.RGBToColor(
+ (TEX32_R(*texel) * ia + r) >> 8,
+ (TEX32_G(*texel) * ia + g) >> 8,
+ (TEX32_B(*texel) * ia + b) >> 8));
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+ else
+ while (pixel != line_end) {
+ uint32 alpha = TEX32_A(*texel);
+ if (alpha == 0xFF) {
+ *(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
+ format.RGBToColor(
+ (TEX32_R(*texel) * ia + r) >> 8,
+ (TEX32_G(*texel) * ia + g) >> 8,
+ (TEX32_B(*texel) * ia + b) >> 8));
+ } else if (alpha) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+
+ uint32 Tsrc = *texel;
+ uint8 r2, g2, b2;
+ format.colorToRGB(*dest, r2, g2, b2);
+
+ uint32 dr = r2 * (256 - alpha);
+ uint32 dg = g2 * (256 - alpha);
+ uint32 db = b2 * (256 - alpha);
+ dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
+ dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
+ db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
+
+ *dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ texel += tex_diff;
+ }
+ } else if (texformat == format) {
+ const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
+ int tex_diff = src.w - w;
+
+ while (pixel != end) {
+ while (pixel != line_end) {
+ // Uh, not supported right now
+ // if (TEX32_A(*texel))
+ {
+ *(reinterpret_cast<uintX *>(pixel)) = BlendHighlight(*texel, r, g, b, 1, ia, format);
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ texel += tex_diff;
+ }
+ } else {
+ error("FadedBlit not supported from %d bpp to %d bpp", texformat.bpp(), format.bpp());
+ }
+}
+
+} // End of anonymous namespace
+
+//
+// void RenderSurface::FadedBlit(Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32)
+//
+// Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
+//
+void RenderSurface::FadedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
+ if (_surface->format.bytesPerPixel == 4)
+ fadedBlitLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, src, srcRect, dx, dy, col32, alpha_blend);
+ else if (_surface->format.bytesPerPixel == 2)
+ fadedBlitLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, src, srcRect, dx, dy, col32, alpha_blend);
+}
+
+namespace {
+
+template<typename uintX>
+void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Graphics::ManagedSurface &src,
+ const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
+ int32 w = srcRect.width();
+ int32 h = srcRect.height();
+
+ // Clamp or wrap or return?
+ if (w > static_cast<int32>(src.w))
+ return;
+
+ // Clamp or wrap or return?
+ if (h > static_cast<int32>(src.h))
+ return;
+
+ // Clip to window
+ int px = dx, py = dy;
+
+ Rect rect(dx, dy, dx + w, dy + h);
+ rect.clip(clipWindow);
+ dx = rect.left;
+ dy = rect.top;
+ w = rect.width();
+ h = rect.height();
+
+ if (!w || !h)
+ return;
+
+ int32 sx = srcRect.left;
+ int32 sy = srcRect.top;
+
+ // Adjust source x and y
+ if (px != dx)
+ sx += dx - px;
+ if (py != dy)
+ sy += dy - py;
+
+ uint8 *pixel = pixels + dy * pitch + dx * format.bytesPerPixel;
+ uint8 *line_end = pixel + w * format.bytesPerPixel;
+ uint8 *end = pixel + h * pitch;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ uint32 a = TEX32_A(col32);
+ uint32 ia = 256 - a;
+ uint32 r = (TEX32_R(col32) * a);
+ uint32 g = (TEX32_G(col32) * a);
+ uint32 b = (TEX32_B(col32) * a);
+
+ uint32 aMask = format.aMax() << format.aShift;
+ int texbpp = src.rawSurface().format.bpp();
+
+ if (texbpp == 32) {
+ const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
+ int tex_diff = src.w - w;
+
+ while (pixel != end) {
+ if (!alpha_blend) {
+ while (pixel != line_end) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+
+ if (TEX32_A(*texel)) {
+ if (!aMask || (*dest & aMask)) {
+ *dest = static_cast<uintX>(
+ format.RGBToColor(
+ (TEX32_R(*texel) * ia + r) >> 8,
+ (TEX32_G(*texel) * ia + g) >> 8,
+ (TEX32_B(*texel) * ia + b) >> 8));
+ }
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+ } else {
+ while (pixel != line_end) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+
+ if (!aMask || (*dest & aMask)) {
+ uint32 alpha = TEX32_A(*texel);
+ if (alpha == 0xFF) {
+ *dest = static_cast<uintX>(
+ format.RGBToColor(
+ (TEX32_R(*texel) * ia + r) >> 8,
+ (TEX32_G(*texel) * ia + g) >> 8,
+ (TEX32_B(*texel) * ia + b) >> 8));
+ } else if (alpha) {
+ uint32 Tsrc = *texel;
+ uint8 r2, g2, b2;
+ format.colorToRGB(*dest, r2, g2, b2);
+
+ uint32 dr = r2 * (256 - alpha);
+ uint32 dg = g2 * (256 - alpha);
+ uint32 db = b2 * (256 - alpha);
+ dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
+ dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
+ db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
+
+ *dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
+ }
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ texel += tex_diff;
+ }
+ } else if (texbpp == format.bpp()) {
+ const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
+ int tex_diff = src.w - w;
+
+ while (pixel != end) {
+ while (pixel != line_end) {
+ uintX *dest = reinterpret_cast<uintX *>(pixel);
+
+ // Uh, not completely supported right now
+ // if ((*texel & format.a_mask) && (*dest & format.a_mask))
+ if (*dest & aMask) {
+ *dest = BlendHighlight(*texel, r, g, b, 1, ia, format);
+ }
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
+
+ line_end += pitch;
+ pixel += diff;
+ texel += tex_diff;
+ }
+ } else {
+ error("unsupported texture format %d bpp", texbpp);
+ }
+}
+
+} // End of anonymous namespace
+
+//
+// void RenderSurface::MaskedBlit(Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend=false)
+//
+// Desc Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
+//
+//
+void RenderSurface::MaskedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
+ if (_surface->format.bytesPerPixel == 4)
+ maskedBlitLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, src, srcRect, dx, dy, col32, alpha_blend);
+ else if (_surface->format.bytesPerPixel == 2)
+ maskedBlitLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, src, srcRect, dx, dy, col32, alpha_blend);
+}
+
//
// RenderSurface::SetVideoMode()
//
@@ -380,34 +815,224 @@ RenderSurface *RenderSurface::SetVideoMode(uint32 width, uint32 height, int bpp)
Graphics::ManagedSurface *surface = new Graphics::Screen(width, height, pixelFormat);
assert(surface);
- // Now create the SoftRenderSurface
- RenderSurface *surf;
- if (pixelFormat.bytesPerPixel == 4) surf = new SoftRenderSurface<uint32>(surface);
- else surf = new SoftRenderSurface<uint16>(surface);
-
// Initialize gamma correction tables
for (int i = 0; i < 256; i++) {
_gamma22toGamma10[i] = static_cast<uint8>(0.5 + (pow(i / 255.0, 2.2 / 1.0) * 255.0));
_gamma10toGamma22[i] = static_cast<uint8>(0.5 + (pow(i / 255.0, 1.0 / 2.2) * 255.0));
}
- return surf;
+ return new RenderSurface(surface);
}
// Create a SecondaryRenderSurface with an associated Texture object
RenderSurface *RenderSurface::CreateSecondaryRenderSurface(uint32 width, uint32 height) {
const Graphics::PixelFormat &format = Ultima8Engine::get_instance()->getScreen()->format;
- // Now create the SoftRenderSurface
- RenderSurface *surf;
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface(width, height, format);
+ return new RenderSurface(surface);
+}
+
+namespace {
+
+template<typename uintX>
+
+void inline paintLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+#include "ultima/ultima8/graphics/render_surface.inl"
+}
+
+template<class uintX>
+void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+#define NO_CLIPPING
+#include "ultima/ultima8/graphics/render_surface.inl"
+#undef NO_CLIPPING
+}
+
+template<class uintX>
+void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+#define XFORM_SHAPES
+#include "ultima/ultima8/graphics/render_surface.inl"
+#undef XFORM_SHAPES
+}
+
+template<class uintX>
+void inline paintMirroredLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
+#define FLIP_SHAPES
+#define XFORM_SHAPES
+#define XFORM_CONDITIONAL trans
+
+#include "ultima/ultima8/graphics/render_surface.inl"
+
+#undef FLIP_SHAPES
+#undef XFORM_SHAPES
+#undef XFORM_CONDITIONAL
+}
+
+template<class uintX>
+void inline paintInvisibleLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
+#define FLIP_SHAPES
+#define FLIP_CONDITIONAL mirrored
+#define XFORM_SHAPES
+#define XFORM_CONDITIONAL trans
+#define BLEND_SHAPES(src, dst) BlendInvisible(src, dst, format)
- // TODO: Change this
- Graphics::ManagedSurface *managedSurface = new Graphics::ManagedSurface(width, height, format);
- if (format.bytesPerPixel == 4)
- surf = new SoftRenderSurface<uint32>(managedSurface);
- else
- surf = new SoftRenderSurface<uint16>(managedSurface);
- return surf;
+#include "ultima/ultima8/graphics/render_surface.inl"
+
+#undef FLIP_SHAPES
+#undef FLIP_CONDITIONAL
+#undef XFORM_SHAPES
+#undef XFORM_CONDITIONAL
+#undef BLEND_SHAPES
+}
+
+template<class uintX>
+void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+#define FLIP_SHAPES
+#define FLIP_CONDITIONAL mirrored
+#define XFORM_SHAPES
+#define XFORM_CONDITIONAL trans
+#define BLEND_SHAPES(src, dst) BlendHighlight(src, cr, cg, cb, ca, 255 - ca, format)
+
+ uint32 ca = TEX32_A(col32);
+ uint32 cr = TEX32_R(col32);
+ uint32 cg = TEX32_G(col32);
+ uint32 cb = TEX32_B(col32);
+
+#include "ultima/ultima8/graphics/render_surface.inl"
+
+#undef FLIP_SHAPES
+#undef FLIP_CONDITIONAL
+#undef XFORM_SHAPES
+#undef XFORM_CONDITIONAL
+#undef BLEND_SHAPES
+}
+
+template<class uintX>
+void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
+ const Rect &clipWindow,
+ const Graphics::PixelFormat &format,
+ const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+#define FLIP_SHAPES
+#define FLIP_CONDITIONAL mirrored
+#define XFORM_SHAPES
+#define XFORM_CONDITIONAL trans
+#define BLEND_SHAPES(src, dst) BlendHighlightInvis(src, dst, cr, cg, cb, ca, 255 - ca, format)
+
+ uint32 ca = TEX32_A(col32);
+ uint32 cr = TEX32_R(col32);
+ uint32 cg = TEX32_G(col32);
+ uint32 cb = TEX32_B(col32);
+
+#include "ultima/ultima8/graphics/render_surface.inl"
+
+#undef FLIP_SHAPES
+#undef FLIP_CONDITIONAL
+#undef XFORM_SHAPES
+#undef XFORM_CONDITIONAL
+#undef BLEND_SHAPES
+}
+
+} // End of anonymous namespace
+
+//
+// void RenderSurface::Paint(Shape*s, uint32 framenum, int32 x, int32 y)
+//
+// Desc: Standard shape drawing functions. Clips but doesn't do anything else
+//
+void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintNoClip(Shape*s, uint32 framenum, int32 x, int32 y)
+//
+// Desc: Standard shape drawing functions. Doesn't clip
+//
+void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintNoClipLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintNoClipLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintTranslucent(Shape*s, uint32 framenum, int32 x, int32 y)
+//
+// Desc: Standard shape drawing functions. Clips and XForms
+//
+void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintTranslucentLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintTranslucentLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintMirrored(Shape*s, uint32 framenum, int32 x, int32 y, bool trans)
+//
+// Desc: Standard shape drawing functions. Clips, Flips and conditionally XForms
+//
+void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintMirroredLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintMirroredLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintInvisible(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
+//
+// Desc: Standard shape drawing functions. Invisible, Clips, and conditionally Flips and Xforms
+//
+void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintInvisibleLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintInvisibleLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintHighlight(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
+//
+// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms
+//
+void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintHighlightLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintHighlightLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+}
+
+//
+// void RenderSurface::PaintHighlightInvis(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
+//
+// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms. 50% translucent
+//
+void RenderSurface::PaintHighlightInvis(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ if (_surface->format.bytesPerPixel == 4)
+ paintHighlightInvisLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ else if (_surface->format.bytesPerPixel == 2)
+ paintHighlightInvisLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index b87c3517071..a243023164f 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -44,7 +44,7 @@ class Scaler;
// Desc: The base class for rendering in Pentagram
//
class RenderSurface {
-protected:
+private:
// Frame buffer
uint8 *_pixels; // Pointer to logical pixel 0,0
uint8 *_pixels00; // Pointer to physical pixel 0,0
@@ -79,8 +79,7 @@ public:
//! Create a SecondaryRenderSurface with an associated Texture object
static RenderSurface *CreateSecondaryRenderSurface(uint32 width, uint32 height);
- // Virtual Destructor
- virtual ~RenderSurface();
+ ~RenderSurface();
//
// Being/End Painting
@@ -89,40 +88,40 @@ public:
//! Begin painting to the buffer. MUST BE CALLED BEFORE DOING ANYTHING TO THE SURFACE!
// \note Can be called multiple times
// \return true on success, false on failure
- virtual bool BeginPainting();
+ bool BeginPainting();
//! Finish paining to the buffer.
// \note MUST BE CALLED FOR EACH CALL TO BeginPainting()
// \return true on success, false on failure
- virtual bool EndPainting();
+ bool EndPainting();
//
// Surface Properties
//
//! Set the Origin of the Surface
- virtual void SetOrigin(int32 x, int32 y);
+ void SetOrigin(int32 x, int32 y);
//! Set the Origin of the Surface
- virtual void GetOrigin(int32 &x, int32 &y) const;
+ void GetOrigin(int32 &x, int32 &y) const;
//! Get the Surface Dimensions
- virtual void GetSurfaceDims(Rect &) const;
+ void GetSurfaceDims(Rect &) const;
//! Get Clipping Rectangle
- virtual void GetClippingRect(Rect &) const;
+ void GetClippingRect(Rect &) const;
//! Set Clipping Rectangle
- virtual void SetClippingRect(const Rect &);
+ void SetClippingRect(const Rect &);
//! Flip the surface
- virtual void SetFlipped(bool flipped);
+ void SetFlipped(bool flipped);
//! Has the render surface been flipped?
- virtual bool IsFlipped() const;
+ bool IsFlipped() const;
//! Get a reference to the underlying surface that's being encapsulated
- virtual Graphics::ManagedSurface *getRawSurface() const {
+ Graphics::ManagedSurface *getRawSurface() const {
return _surface;
};
@@ -130,7 +129,7 @@ public:
// Surface Palettes
//
- virtual void CreateNativePalette(Palette *palette, int maxindex = 0);
+ void CreateNativePalette(Palette *palette, int maxindex = 0);
//
@@ -142,13 +141,13 @@ public:
Fill32(rgb, Rect(sx, sy, sx + w, sy + h));
}
- virtual void Fill32(uint32 rgb, const Rect &r);
+ void Fill32(uint32 rgb, const Rect &r);
//! Fill alpha channel
- virtual void FillAlpha(uint8 alpha, const Rect &r) = 0;
+ void FillAlpha(uint8 alpha, const Rect &r);
//! Fill the region doing alpha blending
- virtual void FillBlended(uint32 rgba, const Rect &r) = 0;
+ void FillBlended(uint32 rgba, const Rect &r);
//
// The rule for painting methods:
@@ -163,32 +162,32 @@ public:
//
//! Paint a Shape
- virtual void Paint(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) = 0;
+ void Paint(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
//! Paint a Shape without clipping
- virtual void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) = 0;
+ void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
//! Paint a Translucent Shape.
- virtual void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) = 0;
+ void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
//! Paint a Mirrored Shape
- virtual void PaintMirrored(const Shape *s, uint32 frame, int32 x, int32 y, bool trans = false, bool untformed_pal = false) = 0;
+ void PaintMirrored(const Shape *s, uint32 frame, int32 x, int32 y, bool trans = false, bool untformed_pal = false);
//! Paint an Invisible Shape
- virtual void PaintInvisible(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal = false) = 0;
+ void PaintInvisible(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal = false);
//! Paint a Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- virtual void PaintHighlight(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false) = 0;
+ void PaintHighlight(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false);
//! Paint a Invisible Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- virtual void PaintHighlightInvis(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false) = 0;
+ void PaintHighlightInvis(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false);
//
// Basic Line Drawing
//
// Draw a RGB Line
- virtual void DrawLine32(uint32 rgb, int32 sx, int32 sy, int32 ex, int32 ey);
+ void DrawLine32(uint32 rgb, int32 sx, int32 sy, int32 ex, int32 ey);
//
@@ -196,13 +195,13 @@ public:
//
//! Blit a region from a Texture (Alpha == 0 -> skipped)
- virtual void Blit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, bool alpha_blend = false);
+ void Blit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, bool alpha_blend = false);
//! Blit a region from a Texture with a Colour blend (AlphaTex == 0 -> skipped. AlphaCol32 -> Blend Factors)
- virtual void FadedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
+ void FadedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false);
//! Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
- virtual void MaskedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
+ void MaskedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false);
};
diff --git a/engines/ultima/ultima8/graphics/soft_render_surface.inl b/engines/ultima/ultima8/graphics/render_surface.inl
similarity index 92%
rename from engines/ultima/ultima8/graphics/soft_render_surface.inl
rename to engines/ultima/ultima8/graphics/render_surface.inl
index d8426670268..19f34b284a2 100644
--- a/engines/ultima/ultima8/graphics/soft_render_surface.inl
+++ b/engines/ultima/ultima8/graphics/render_surface.inl
@@ -105,24 +105,24 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
#define LINE_END_ASSIGN //
#define NOT_CLIPPED_X (1)
#define NOT_CLIPPED_Y (1)
-#define OFFSET_PIXELS (_pixels)
+#define OFFSET_PIXELS (pixels)
//
// No Clipping = FALSE
//
#else
- const int scrn_width = _clipWindow.width();
- const int scrn_height = _clipWindow.height();
+ const int scrn_width = clipWindow.width();
+ const int scrn_height = clipWindow.height();
#define LINE_END_ASSIGN const uintX *dst_line_end = dst_line_start + scrn_width
#define NOT_CLIPPED_X (dstpix >= dst_line_start && dstpix < dst_line_end)
#define NOT_CLIPPED_Y (line >= 0 && line < scrn_height)
#define OFFSET_PIXELS (off_pixels)
- uint8 *off_pixels = _pixels + _clipWindow.left * sizeof(uintX) + _clipWindow.top * _pitch;
- x -= _clipWindow.left;
- y -= _clipWindow.top;
+ uint8 *off_pixels = pixels + clipWindow.left * sizeof(uintX) + clipWindow.top * pitch;
+ x -= clipWindow.left;
+ y -= clipWindow.top;
#endif
@@ -170,9 +170,6 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
if (s->getPalette() == 0)
return;
-#ifdef XFORM_SHAPES
- const Graphics::PixelFormat &format = _surface->format;
-#endif
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame)
return;
@@ -193,14 +190,14 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
x -= XNEG(frame->_xoff);
y -= frame->_yoff;
- assert(_pixels00 && _pixels && srcpixels);
+ assert(pixels && srcpixels);
for (int i = 0; i < height_; i++) {
const int line = y + i;
if (NOT_CLIPPED_Y) {
const uint8 *srcline = srcpixels + i * width_;
- uintX *dst_line_start = reinterpret_cast<uintX *>(OFFSET_PIXELS + _pitch * line);
+ uintX *dst_line_start = reinterpret_cast<uintX *>(OFFSET_PIXELS + pitch * line);
LINE_END_ASSIGN;
for (int xpos = 0; xpos < width_; xpos++) {
diff --git a/engines/ultima/ultima8/graphics/soft_render_surface.cpp b/engines/ultima/ultima8/graphics/soft_render_surface.cpp
deleted file mode 100644
index 94cfe786fd1..00000000000
--- a/engines/ultima/ultima8/graphics/soft_render_surface.cpp
+++ /dev/null
@@ -1,556 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "ultima/ultima8/misc/debugger.h"
-#include "ultima/ultima8/graphics/soft_render_surface.h"
-#include "ultima/ultima8/graphics/shape.h"
-#include "ultima/ultima8/graphics/shape_frame.h"
-#include "ultima/ultima8/graphics/palette.h"
-#include "ultima/ultima8/graphics/xform_blend.h"
-#include "ultima/ultima8/ultima8.h"
-
-namespace Ultima {
-namespace Ultima8 {
-
-///////////////////////
-// //
-// SoftRenderSurface //
-// //
-///////////////////////
-
-
-//
-// SoftRenderSurface::SoftRenderSurface(Graphics::Surface *s)
-//
-// Desc: Create a SoftRenderSurface from a managed surface
-//
-template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(Graphics::ManagedSurface *s)
- : RenderSurface(s) {
-}
-
-//
-// SoftRenderSurface::FillAlpha(uint8 alpha, int32 sx, int32 sy, int32 w, int32 h)
-//
-// Desc: Fill alpha channel
-//
-
-//#define CHECK_ALPHA_FILLS
-
-template<class uintX> void SoftRenderSurface<uintX>::FillAlpha(uint8 alpha, const Rect &r) {
- const Graphics::PixelFormat &format = _surface->format;
- uint32 aMask = format.aMax() << format.aShift;
- Rect rect = r;
- rect.clip(_clipWindow);
- int32 w = rect.width();
- int32 h = rect.height();
-
- if (!w || !h || !aMask)
- return;
-
- // An optimization.
- if (w * format.bytesPerPixel == _pitch) {
- w *= h;
- h = 1;
- }
-
- uint8 *pixel = _pixels + rect.top * _pitch + rect.left * format.bytesPerPixel;
- uint8 *end = pixel + h * _pitch;
-
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- int diff = _pitch - w * format.bytesPerPixel;
-
- uint32 a = (((uint32)alpha) << format.aShift) & aMask;
-
-#ifdef CHECK_ALPHA_FILLS
- uint32 c;
- uint32 m;
- if (a == 0) {
- c = (format.bMask >> 1)&format.bMask;
- m = format.bMask;
- } else {
- c = (format.rMask >> 1)&format.rMask;
- m = format.rMask;
- }
-#endif
-
- while (pixel != end) {
- while (pixel != line_end) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
- *dest = (*dest & ~aMask) | a;
-#ifdef CHECK_ALPHA_FILLS
- *dest = (*dest & ~m) | (c + (((*dest & m) >> 1)&m));
-#endif
- pixel += format.bytesPerPixel;
- }
-
- line_end += _pitch;
- pixel += diff;
- }
-}
-
-template<class uintX> void SoftRenderSurface<uintX>::FillBlended(uint32 rgba, const Rect &r) {
- int alpha = TEX32_A(rgba);
- if (alpha == 0xFF) {
- Fill32(rgba, r);
- return;
- } else if (!alpha) {
- return;
- }
-
- Rect rect = r;
- rect.clip(_clipWindow);
- int32 w = rect.width();
- int32 h = rect.height();
-
- if (!w || !h) return;
-
- const Graphics::PixelFormat &format = _surface->format;
-
- // An optimization.
- if (w * format.bytesPerPixel == _pitch) {
- w *= h;
- h = 1;
- }
-
- uint8 *pixel = _pixels + rect.top * _pitch + rect.left * format.bytesPerPixel;
- uint8 *end = pixel + h * _pitch;
-
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- int diff = _pitch - w * format.bytesPerPixel;
-
- uint32 aMask = format.aMax() << format.aShift;
- rgba = TEX32_PACK_RGBA((TEX32_R(rgba) * alpha) >> 8,
- (TEX32_G(rgba) * alpha) >> 8,
- (TEX32_B(rgba) * alpha) >> 8,
- (255 * alpha) >> 8);
-
- while (pixel != end) {
- while (pixel != line_end) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
- uint32 d = *dest;
- *dest = (d & aMask) | BlendPreModFast(rgba, d, format);
- pixel += format.bytesPerPixel;
- }
-
- line_end += _pitch;
- pixel += diff;
- }
-}
-
-//
-// void SoftRenderSurface::FadedBlit(Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32)
-//
-// Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
-//
-template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
- int32 w = srcRect.width();
- int32 h = srcRect.height();
-
- // Clamp or wrap or return?
- if (w > static_cast<int32>(src.w))
- return;
-
- // Clamp or wrap or return?
- if (h > static_cast<int32>(src.h))
- return;
-
- // Clip to window
- int px = dx, py = dy;
-
- Rect rect(dx, dy, dx + w, dy + h);
- rect.clip(_clipWindow);
- dx = rect.left;
- dy = rect.top;
- w = rect.width();
- h = rect.height();
-
- if (!w || !h) return;
-
- int32 sx = srcRect.left;
- int32 sy = srcRect.top;
-
- // Adjust source x and y
- if (px != dx) sx += dx - px;
- if (py != dy) sy += dy - py;
-
- const Graphics::PixelFormat &format = _surface->format;
-
- uint8 *pixel = _pixels + dy * _pitch + dx * format.bytesPerPixel;
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- uint8 *end = pixel + h * _pitch;
- int diff = _pitch - w * format.bytesPerPixel;
-
- uint32 a = TEX32_A(col32);
- uint32 ia = 256 - a;
- uint32 r = (TEX32_R(col32) * a);
- uint32 g = (TEX32_G(col32) * a);
- uint32 b = (TEX32_B(col32) * a);
-
- const Graphics::PixelFormat &texformat = src.rawSurface().format;
-
- if (texformat.bpp() == 32) {
- const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
- int tex_diff = src.w - w;
-
- while (pixel != end) {
- if (!alpha_blend) while (pixel != line_end) {
- if (TEX32_A(*texel)) {
- *(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
- format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
- else while (pixel != line_end) {
- uint32 alpha = TEX32_A(*texel);
- if (alpha == 0xFF) {
- *(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
- format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- } else if (alpha) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
-
- uint32 Tsrc = *texel;
- uint8 r2, g2, b2;
- format.colorToRGB(*dest, r2, g2, b2);
-
- uint32 dr = r2 * (256 - alpha);
- uint32 dg = g2 * (256 - alpha);
- uint32 db = b2 * (256 - alpha);
- dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
- dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
- db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
-
- *dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
-
- line_end += _pitch;
- pixel += diff;
- texel += tex_diff;
- }
- } else if (texformat == format) {
- const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
- int tex_diff = src.w - w;
-
- while (pixel != end) {
- while (pixel != line_end) {
- // Uh, not supported right now
- //if (TEX32_A(*texel))
- {
- *(reinterpret_cast<uintX *>(pixel)) = BlendHighlight(*texel, r, g, b, 1, ia, format);
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
-
- line_end += _pitch;
- pixel += diff;
- texel += tex_diff;
- }
- } else {
- error("FadedBlit not supported from %d bpp to %d bpp", texformat.bpp(), format.bpp());
- }
-}
-
-
-//
-// void SoftRenderSurface::MaskedBlit(Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend=false)
-//
-// Desc Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
-//
-//
-template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
- int32 w = srcRect.width();
- int32 h = srcRect.height();
-
- // Clamp or wrap or return?
- if (w > static_cast<int32>(src.w))
- return;
-
- // Clamp or wrap or return?
- if (h > static_cast<int32>(src.h))
- return;
-
- // Clip to window
- int px = dx, py = dy;
-
- Rect rect(dx, dy, dx + w, dy + h);
- rect.clip(_clipWindow);
- dx = rect.left;
- dy = rect.top;
- w = rect.width();
- h = rect.height();
-
- if (!w || !h)
- return;
-
- int32 sx = srcRect.left;
- int32 sy = srcRect.top;
-
- // Adjust source x and y
- if (px != dx) sx += dx - px;
- if (py != dy) sy += dy - py;
-
- const Graphics::PixelFormat &format = _surface->format;
-
- uint8 *pixel = _pixels + dy * _pitch + dx * format.bytesPerPixel;
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- uint8 *end = pixel + h * _pitch;
- int diff = _pitch - w * format.bytesPerPixel;
-
- uint32 a = TEX32_A(col32);
- uint32 ia = 256 - a;
- uint32 r = (TEX32_R(col32) * a);
- uint32 g = (TEX32_G(col32) * a);
- uint32 b = (TEX32_B(col32) * a);
-
- uint32 aMask = format.aMax() << format.aShift;
- int texbpp = src.rawSurface().format.bpp();
-
- if (texbpp == 32) {
- const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
- int tex_diff = src.w - w;
-
- while (pixel != end) {
- if (!alpha_blend) {
- while (pixel != line_end) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
-
- if (TEX32_A(*texel)) {
- if (!aMask || (*dest & aMask)) {
- *dest = static_cast<uintX>(
- format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- }
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
- } else {
- while (pixel != line_end) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
-
- if (!aMask || (*dest & aMask)) {
- uint32 alpha = TEX32_A(*texel);
- if (alpha == 0xFF) {
- *dest = static_cast<uintX>(
- format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- } else if (alpha) {
- uint32 Tsrc = *texel;
- uint8 r2, g2, b2;
- format.colorToRGB(*dest, r2, g2, b2);
-
- uint32 dr = r2 * (256 - alpha);
- uint32 dg = g2 * (256 - alpha);
- uint32 db = b2 * (256 - alpha);
- dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
- dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
- db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
-
- *dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
- }
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
- }
-
- line_end += _pitch;
- pixel += diff;
- texel += tex_diff;
- }
- } else if (texbpp == format.bpp()) {
- const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
- int tex_diff = src.w - w;
-
- while (pixel != end) {
- while (pixel != line_end) {
- uintX *dest = reinterpret_cast<uintX *>(pixel);
-
- // Uh, not completely supported right now
- //if ((*texel & format.a_mask) && (*dest & format.a_mask))
- if (*dest & aMask) {
- *dest = BlendHighlight(*texel, r, g, b, 1, ia, format);
- }
- pixel += format.bytesPerPixel;
- texel++;
- }
-
- line_end += _pitch;
- pixel += diff;
- texel += tex_diff;
- }
- } else {
- error("unsupported texture format %d bpp", texbpp);
- }
-}
-
-
-//
-// void SoftRenderSurface::Paint(Shape*s, uint32 framenum, int32 x, int32 y)
-//
-// Desc: Standard shape drawing functions. Clips but doesn't do anything else
-//
-template<class uintX> void SoftRenderSurface<uintX>::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-}
-
-
-//
-// void SoftRenderSurface::PaintNoClip(Shape*s, uint32 framenum, int32 x, int32 y)
-//
-// Desc: Standard shape drawing functions. Doesn't clip
-//
-template<class uintX> void SoftRenderSurface<uintX>::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
-#define NO_CLIPPING
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-#undef NO_CLIPPING
-}
-
-
-//
-// void SoftRenderSurface::PaintTranslucent(Shape*s, uint32 framenum, int32 x, int32 y)
-//
-// Desc: Standard shape drawing functions. Clips and XForms
-//
-template<class uintX> void SoftRenderSurface<uintX>::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
-#define XFORM_SHAPES
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-#undef XFORM_SHAPES
-}
-
-
-//
-// void SoftRenderSurface::PaintMirrored(Shape*s, uint32 framenum, int32 x, int32 y, bool trans)
-//
-// Desc: Standard shape drawing functions. Clips, Flips and conditionally XForms
-//
-template<class uintX> void SoftRenderSurface<uintX>::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
-#define FLIP_SHAPES
-#define XFORM_SHAPES
-#define XFORM_CONDITIONAL trans
-
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-
-#undef FLIP_SHAPES
-#undef XFORM_SHAPES
-#undef XFORM_CONDITIONAL
-}
-
-
-//
-// void SoftRenderSurface::PaintInvisible(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
-//
-// Desc: Standard shape drawing functions. Invisible, Clips, and conditionally Flips and Xforms
-//
-
-template<class uintX> void SoftRenderSurface<uintX>::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
-#define XFORM_SHAPES
-#define XFORM_CONDITIONAL trans
-#define BLEND_SHAPES(src, dst) BlendInvisible(src, dst, format)
-
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
-#undef XFORM_SHAPES
-#undef XFORM_CONDITIONAL
-#undef BLEND_SHAPES
-}
-
-
-//
-// void SoftRenderSurface::PaintHighlight(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
-//
-// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms
-//
-
-template<class uintX> void SoftRenderSurface<uintX>::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
-#define XFORM_SHAPES
-#define XFORM_CONDITIONAL trans
-#define BLEND_SHAPES(src, dst) BlendHighlight(src, cr, cg, cb, ca, 255 - ca, format)
-
- uint32 ca = TEX32_A(col32);
- uint32 cr = TEX32_R(col32);
- uint32 cg = TEX32_G(col32);
- uint32 cb = TEX32_B(col32);
-
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
-#undef XFORM_SHAPES
-#undef XFORM_CONDITIONAL
-#undef BLEND_SHAPES
-}
-
-//
-// void SoftRenderSurface::PaintHighlightInvis(Shape* s, uint32 frame, int32 x, int32 y, bool mirrored)
-//
-// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms. 50% translucent
-//
-
-template<class uintX> void SoftRenderSurface<uintX>::PaintHighlightInvis(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
-#define XFORM_SHAPES
-#define XFORM_CONDITIONAL trans
-#define BLEND_SHAPES(src, dst) BlendHighlightInvis(src, dst, cr, cg, cb, ca, 255 - ca, format)
-
- uint32 ca = TEX32_A(col32);
- uint32 cr = TEX32_R(col32);
- uint32 cg = TEX32_G(col32);
- uint32 cb = TEX32_B(col32);
-
-#include "ultima/ultima8/graphics/soft_render_surface.inl"
-
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
-#undef XFORM_SHAPES
-#undef XFORM_CONDITIONAL
-#undef BLEND_SHAPES
-}
-
-//
-// Instantiate the SoftRenderSurface Class
-//
-template class SoftRenderSurface<uint16>;
-template class SoftRenderSurface<uint32>;
-
-} // End of namespace Ultima8
-} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/graphics/soft_render_surface.h b/engines/ultima/ultima8/graphics/soft_render_surface.h
deleted file mode 100644
index d3ff2537e66..00000000000
--- a/engines/ultima/ultima8/graphics/soft_render_surface.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef ULTIMA8_GRAPHICS_SOFTRENDERSURFACE_H
-#define ULTIMA8_GRAPHICS_SOFTRENDERSURFACE_H
-
-#include "ultima/ultima8/graphics/render_surface.h"
-#include "graphics/managed_surface.h"
-
-namespace Ultima {
-namespace Ultima8 {
-
-//
-// SoftRenderSurface
-//
-// Desc: The class for software rendering in Pentagram
-//
-template<class uintX> class SoftRenderSurface : public RenderSurface {
-public:
-
- // Create from a managed surface
- SoftRenderSurface(Graphics::ManagedSurface *managed);
-
- //
- // Surface Filling
- //
-
- //! Fill alpha channel
- void FillAlpha(uint8 alpha, const Rect &r) override;
-
- // Fill the region doing alpha blending
- void FillBlended(uint32 rgba, const Rect &r) override;
-
- //
- // The rule for painting methods:
- //
- // First arg are the source object to 'draw' with
- // Next args are any other required data to define the 'source'
- // Next args are the destination position
- //
-
- //
- // Basic Shape Painting
- //
-
- // Paint a Shape
- void Paint(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) override;
-
- // Paint a Shape without clipping
- void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) override;
-
- // Paint a Translucent Shape.
- void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false) override;
-
- // Paint a Mirrored Shape
- void PaintMirrored(const Shape *s, uint32 frame, int32 x, int32 y, bool trans = false, bool untformed_pal = false) override;
-
- // Paint a Invisible Shape
- void PaintInvisible(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal = false) override;
-
- // Paint a Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- void PaintHighlight(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false) override;
-
- // Paint a Invisible Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- void PaintHighlightInvis(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false) override;
-
- // Blit a region from a Texture with a Colour blend (AlphaTex == 0 -> skipped. AlphaCol32 -> Blend Factors)
- void FadedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
-
- // Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
- void MaskedBlit(const Graphics::ManagedSurface &src, const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
-};
-
-} // End of namespace Ultima8
-} // End of namespace Ultima
-
-#endif
Commit: 26df05f718247eb7408dddc476ded090f70794a3
https://github.com/scummvm/scummvm/commit/26df05f718247eb7408dddc476ded090f70794a3
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Clean up RenderSurface member variables
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.h
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 712029ea7c1..3f7c9d8478c 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -36,12 +36,11 @@ namespace Ultima8 {
uint8 RenderSurface::_gamma10toGamma22[256];
uint8 RenderSurface::_gamma22toGamma10[256];
-RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _pixels00(nullptr),
- _ox(0), _oy(0), _width(0), _height(0), _pitch(0),
+RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _ox(0), _oy(0), _pitch(0),
_flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0),
_surface(s) {
- _clipWindow.setWidth(_width = _surface->w);
- _clipWindow.setHeight(_height = _surface->h);
+ _clipWindow.setWidth(_surface->w);
+ _clipWindow.setHeight(_surface->h);
_pitch = _surface->pitch;
SetPixelsPointer();
@@ -53,14 +52,15 @@ RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _p
// Desc: Destructor
//
RenderSurface::~RenderSurface() {
+ delete _surface;
}
void RenderSurface::SetPixelsPointer()
{
- uint8 *pix00 = _pixels00;
+ uint8 *pix00 = static_cast<uint8 *>(_surface->getPixels());
if (_flipped) {
- pix00 += -_pitch * (_height - 1);
+ pix00 += -_pitch * (_surface->h - 1);
}
_pixels = pix00 + _ox * _surface->format.bytesPerPixel + _oy * _pitch;
@@ -74,26 +74,15 @@ void RenderSurface::SetPixelsPointer()
//
bool RenderSurface::BeginPainting() {
if (!_lockCount) {
+ _surface->markAllDirty();
- if (_surface) {
- // Pixels pointer
- Graphics::Surface s = _surface->getSubArea(Common::Rect(0, 0, _surface->w, _surface->h));
- _pixels00 = static_cast<uint8 *>(s.getPixels());
-
- _pitch = _surface->pitch;
- if (_flipped)
- _pitch = -_pitch;
- }
- // else, nothing to lock.
+ _pitch = _surface->pitch;
+ if (_flipped)
+ _pitch = -_pitch;
}
_lockCount++;
- if (_pixels00 == nullptr) {
- error("Error: Surface Locked with NULL RenderSurface::_pixels pointer!");
- return false;
- }
-
// Origin offset pointers
SetPixelsPointer();
@@ -118,16 +107,13 @@ bool RenderSurface::EndPainting() {
--_lockCount;
if (!_lockCount) {
- if (_surface) {
- // Clear pointers
- _pixels = _pixels00 = 0;
-
- // Render the screen if this is it (slight hack..)
- Graphics::Screen *screen = dynamic_cast<Graphics::Screen *>(_surface);
- if (screen)
- screen->update();
- }
- // else, nothing to unlock.
+ // Clear pointers
+ _pixels = 0;
+
+ // Render the screen if this is it (slight hack..)
+ Graphics::Screen *screen = dynamic_cast<Graphics::Screen *>(_surface);
+ if (screen)
+ screen->update();
}
// No error
@@ -230,8 +216,8 @@ void RenderSurface::CreateNativePalette(Palette *palette, int maxindex) {
//
void RenderSurface::GetSurfaceDims(Rect &r) const {
r.moveTo(_ox, _oy);
- r.setWidth(_width);
- r.setHeight(_height);
+ r.setWidth(_surface->w);
+ r.setHeight(_surface->h);
}
//
@@ -269,7 +255,7 @@ void RenderSurface::GetOrigin(int32 &x, int32 &y) const {
// r: Rect object to fill
//
void RenderSurface::GetClippingRect(Rect &r) const {
- r = _clipWindow;
+ r = Rect(_clipWindow.left, _clipWindow.top, _clipWindow.right, _clipWindow.bottom);
}
//
@@ -280,8 +266,8 @@ void RenderSurface::GetClippingRect(Rect &r) const {
//
void RenderSurface::SetClippingRect(const Rect &r) {
// What we need to do is to clip the clipping rect to the phyiscal screen
- _clipWindow = r;
- _clipWindow.clip(Rect(-_ox, -_oy, -_ox + _width, -_oy + _height));
+ _clipWindow = Common::Rect(r.left, r.top, r.right, r.bottom);
+ _clipWindow.clip(Common::Rect(-_ox, -_oy, -_ox + _surface->w, -_oy + _surface->h));
}
//
@@ -303,7 +289,7 @@ void RenderSurface::SetFlipped(bool wantFlipped) {
// We keep the 'origin' in the same position relative to the clipping window
_oy -= _clipWindow.top;
- _clipWindow.setHeight(_height - _clipWindow.top + _clipWindow.height());
+ _clipWindow.setHeight(_surface->h - _clipWindow.top + _clipWindow.height());
_oy += _clipWindow.top;
_pitch = -_pitch;
@@ -326,7 +312,7 @@ bool RenderSurface::IsFlipped() const {
// Desc: Fill buffer (using a RGB colour)
//
void RenderSurface::Fill32(uint32 rgb, const Rect &r) {
- Rect rect = r;
+ Common::Rect rect(r.left, r.top, r.right, r.bottom);
rect.clip(_clipWindow);
rgb = _surface->format.RGBToColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF);
_surface->fillRect(Common::Rect(rect.left + _ox, rect.top + _oy, rect.right + _ox, rect.bottom + _oy), rgb);
@@ -337,7 +323,7 @@ void RenderSurface::Fill32(uint32 rgb, const Rect &r) {
namespace {
template<typename uintX>
-void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Rect &rect, const Graphics::PixelFormat &format) {
+void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Common::Rect &rect, const Graphics::PixelFormat &format) {
uint32 aMask = format.aMax() << format.aShift;
int32 w = rect.width();
int32 h = rect.height();
@@ -394,7 +380,7 @@ void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Rect &
// Desc: Fill alpha channel
//
void RenderSurface::FillAlpha(uint8 alpha, const Rect &r) {
- Rect rect = r;
+ Common::Rect rect(r.left, r.top, r.right, r.bottom);
rect.clip(_clipWindow);
if (_surface->format.bytesPerPixel == 4)
@@ -406,7 +392,7 @@ void RenderSurface::FillAlpha(uint8 alpha, const Rect &r) {
namespace {
template<typename uintX>
-void inline fillBlendedLogic(uint8 *pixels, int32 pitch, uint32 rgba, const Rect &rect, const Graphics::PixelFormat &format) {
+void inline fillBlendedLogic(uint8 *pixels, int32 pitch, uint32 rgba, const Common::Rect &rect, const Graphics::PixelFormat &format) {
int32 w = rect.width();
int32 h = rect.height();
@@ -461,7 +447,7 @@ void RenderSurface::FillBlended(uint32 rgba, const Rect &r) {
return;
}
- Rect rect = r;
+ Common::Rect rect(r.left, r.top, r.right, r.bottom);
rect.clip(_clipWindow);
if (_surface->format.bytesPerPixel == 4)
@@ -498,7 +484,7 @@ namespace {
template<typename uintX>
void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Graphics::ManagedSurface &src,
const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
@@ -516,7 +502,7 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
// Clip to window
int px = dx, py = dy;
- Rect rect(dx, dy, dx + w, dy + h);
+ Common::Rect rect(dx, dy, dx + w, dy + h);
rect.clip(clipWindow);
dx = rect.left;
dy = rect.top;
@@ -640,7 +626,7 @@ namespace {
template<typename uintX>
void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Graphics::ManagedSurface &src,
const Common::Rect &srcRect, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
@@ -658,7 +644,7 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
// Clip to window
int px = dx, py = dy;
- Rect rect(dx, dy, dx + w, dy + h);
+ Common::Rect rect(dx, dy, dx + w, dy + h);
rect.clip(clipWindow);
dx = rect.left;
dy = rect.top;
@@ -837,7 +823,7 @@ namespace {
template<typename uintX>
void inline paintLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
#include "ultima/ultima8/graphics/render_surface.inl"
@@ -845,7 +831,7 @@ void inline paintLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
#define NO_CLIPPING
@@ -855,7 +841,7 @@ void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
#define XFORM_SHAPES
@@ -865,7 +851,7 @@ void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintMirroredLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
#define FLIP_SHAPES
@@ -881,7 +867,7 @@ void inline paintMirroredLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintInvisibleLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
#define FLIP_SHAPES
@@ -901,7 +887,7 @@ void inline paintInvisibleLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
#define FLIP_SHAPES
@@ -926,7 +912,7 @@ void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
template<class uintX>
void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
- const Rect &clipWindow,
+ const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
#define FLIP_SHAPES
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index a243023164f..6da3f7fa3bc 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -22,21 +22,16 @@
#ifndef ULTIMA8_GRAPHICS_RENDERSURFACE_H
#define ULTIMA8_GRAPHICS_RENDERSURFACE_H
-#include "graphics/pixelformat.h"
#include "graphics/managed_surface.h"
#include "ultima/ultima8/misc/rect.h"
namespace Ultima {
namespace Ultima8 {
-class Texture;
class Shape;
-class ShapeFont;
-struct FixedWidthFont;
struct Palette;
struct Rect;
-class Scaler;
//
// RenderSurface
@@ -47,16 +42,14 @@ class RenderSurface {
private:
// Frame buffer
uint8 *_pixels; // Pointer to logical pixel 0,0
- uint8 *_pixels00; // Pointer to physical pixel 0,0
// Dimensions
int32 _ox, _oy; // Physical Pixel for Logical Origin
- int32 _width, _height; // Width and height
int32 _pitch; // Frame buffer pitch (bytes) (could be negated)
bool _flipped;
// Clipping Rectangle
- Rect _clipWindow;
+ Common::Rect _clipWindow;
// Locking count
uint32 _lockCount; // Number of locks on surface
Commit: 0aed7b6f0050e5ac25466dede7d454a36f610961
https://github.com/scummvm/scummvm/commit/0aed7b6f0050e5ac25466dede7d454a36f610961
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Remove build rule for deleted file
Changed paths:
engines/ultima/module.mk
diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 47633060c58..897f5409265 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -429,7 +429,6 @@ MODULE_OBJS := \
ultima8/graphics/shape_frame.o \
ultima8/graphics/shape_info.o \
ultima8/graphics/skf_player.o \
- ultima8/graphics/soft_render_surface.o \
ultima8/graphics/type_flags.o \
ultima8/graphics/wpn_ovlay_dat.o \
ultima8/graphics/xform_blend.o \
Commit: ebf130e42c59b59143e9cd5ac8dfaa34a339a1e1
https://github.com/scummvm/scummvm/commit/ebf130e42c59b59143e9cd5ac8dfaa34a339a1e1
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Clean up pixels pointer and pitch handling in RenderSurface
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 3f7c9d8478c..44ebeb9d2b1 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -41,7 +41,6 @@ RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _o
_surface(s) {
_clipWindow.setWidth(_surface->w);
_clipWindow.setHeight(_surface->h);
- _pitch = _surface->pitch;
SetPixelsPointer();
}
@@ -57,13 +56,14 @@ RenderSurface::~RenderSurface() {
void RenderSurface::SetPixelsPointer()
{
- uint8 *pix00 = static_cast<uint8 *>(_surface->getPixels());
+ _pixels = static_cast<uint8 *>(_surface->getBasePtr(_ox, _oy));
+ _pitch = _surface->pitch;
if (_flipped) {
- pix00 += -_pitch * (_surface->h - 1);
+ _pixels = static_cast<uint8 *>(_surface->getBasePtr(_ox, _surface->h - 1 - _oy));
+ _pitch = -_pitch;
}
- _pixels = pix00 + _ox * _surface->format.bytesPerPixel + _oy * _pitch;
}
//
@@ -75,10 +75,6 @@ void RenderSurface::SetPixelsPointer()
bool RenderSurface::BeginPainting() {
if (!_lockCount) {
_surface->markAllDirty();
-
- _pitch = _surface->pitch;
- if (_flipped)
- _pitch = -_pitch;
}
_lockCount++;
@@ -292,8 +288,6 @@ void RenderSurface::SetFlipped(bool wantFlipped) {
_clipWindow.setHeight(_surface->h - _clipWindow.top + _clipWindow.height());
_oy += _clipWindow.top;
- _pitch = -_pitch;
-
SetPixelsPointer();
}
Commit: e381469830d89c4cad7a26bf4b89650a159dde04
https://github.com/scummvm/scummvm/commit/e381469830d89c4cad7a26bf4b89650a159dde04
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Clean up RenderSurface blit and fill methods
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 44ebeb9d2b1..5dde8613a80 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -325,18 +325,6 @@ void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Common
if (!w || !h || !aMask)
return;
- // An optimization.
- if (w * format.bytesPerPixel == pitch) {
- w *= h;
- h = 1;
- }
-
- uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
- uint8 *end = pixel + h * pitch;
-
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- int diff = pitch - w * format.bytesPerPixel;
-
uint32 a = (((uint32)alpha) << format.aShift) & aMask;
#ifdef CHECK_ALPHA_FILLS
@@ -351,8 +339,11 @@ void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Common
}
#endif
- while (pixel != end) {
- while (pixel != line_end) {
+ uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
*dest = (*dest & ~aMask) | a;
#ifdef CHECK_ALPHA_FILLS
@@ -361,7 +352,6 @@ void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Common
pixel += format.bytesPerPixel;
}
- line_end += pitch;
pixel += diff;
}
}
@@ -393,18 +383,6 @@ void inline fillBlendedLogic(uint8 *pixels, int32 pitch, uint32 rgba, const Comm
if (!w || !h)
return;
- // An optimization.
- if (w * format.bytesPerPixel == pitch) {
- w *= h;
- h = 1;
- }
-
- uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
- uint8 *end = pixel + h * pitch;
-
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- int diff = pitch - w * format.bytesPerPixel;
-
uint32 aMask = format.aMax() << format.aShift;
int alpha = TEX32_A(rgba);
rgba = TEX32_PACK_RGBA((TEX32_R(rgba) * alpha) >> 8,
@@ -412,15 +390,17 @@ void inline fillBlendedLogic(uint8 *pixels, int32 pitch, uint32 rgba, const Comm
(TEX32_B(rgba) * alpha) >> 8,
(255 * alpha) >> 8);
- while (pixel != end) {
- while (pixel != line_end) {
+ uint8 *pixel = pixels + rect.top * pitch + rect.left * format.bytesPerPixel;
+ int diff = pitch - w * format.bytesPerPixel;
+
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
uint32 d = *dest;
*dest = (d & aMask) | BlendPreModFast(rgba, d, format);
pixel += format.bytesPerPixel;
}
- line_end += pitch;
pixel += diff;
}
}
@@ -516,8 +496,6 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
sy += dy - py;
uint8 *pixel = pixels + dy * pitch + dx * format.bytesPerPixel;
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- uint8 *end = pixel + h * pitch;
int diff = pitch - w * format.bytesPerPixel;
uint32 a = TEX32_A(col32);
@@ -532,9 +510,9 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
- while (pixel != end) {
+ for (int y = 0; y < h; ++y) {
if (!alpha_blend)
- while (pixel != line_end) {
+ for (int x = 0; x < w; ++x) {
if (TEX32_A(*texel)) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
format.RGBToColor(
@@ -546,7 +524,7 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
texel++;
}
else
- while (pixel != line_end) {
+ for (int x = 0; x < w; ++x) {
uint32 alpha = TEX32_A(*texel);
if (alpha == 0xFF) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
@@ -574,7 +552,6 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
texel++;
}
- line_end += pitch;
pixel += diff;
texel += tex_diff;
}
@@ -582,8 +559,8 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
- while (pixel != end) {
- while (pixel != line_end) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
// Uh, not supported right now
// if (TEX32_A(*texel))
{
@@ -593,7 +570,6 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
texel++;
}
- line_end += pitch;
pixel += diff;
texel += tex_diff;
}
@@ -658,8 +634,6 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
sy += dy - py;
uint8 *pixel = pixels + dy * pitch + dx * format.bytesPerPixel;
- uint8 *line_end = pixel + w * format.bytesPerPixel;
- uint8 *end = pixel + h * pitch;
int diff = pitch - w * format.bytesPerPixel;
uint32 a = TEX32_A(col32);
@@ -675,9 +649,9 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
- while (pixel != end) {
+ for (int y = 0; y < h; ++y) {
if (!alpha_blend) {
- while (pixel != line_end) {
+ for (int x = 0; x < w; ++x) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
if (TEX32_A(*texel)) {
@@ -693,7 +667,7 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
texel++;
}
} else {
- while (pixel != line_end) {
+ for (int x = 0; x < w; ++x) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
if (!aMask || (*dest & aMask)) {
@@ -724,7 +698,6 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
}
}
- line_end += pitch;
pixel += diff;
texel += tex_diff;
}
@@ -732,8 +705,8 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
- while (pixel != end) {
- while (pixel != line_end) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
// Uh, not completely supported right now
@@ -745,7 +718,6 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
texel++;
}
- line_end += pitch;
pixel += diff;
texel += tex_diff;
}
Commit: bea3e12656df4ca9c012db28868e33a5a92cefe3
https://github.com/scummvm/scummvm/commit/bea3e12656df4ca9c012db28868e33a5a92cefe3
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Fix RenderSurface blit methods for 32 bpp
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 5dde8613a80..aed7514fefc 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -504,54 +504,51 @@ void inline fadedBlitLogic(uint8 *pixels, int32 pitch,
uint32 g = (TEX32_G(col32) * a);
uint32 b = (TEX32_B(col32) * a);
- const Graphics::PixelFormat &texformat = src.rawSurface().format;
+ const Graphics::PixelFormat &texformat = src.format;
if (texformat.bpp() == 32) {
const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
for (int y = 0; y < h; ++y) {
- if (!alpha_blend)
- for (int x = 0; x < w; ++x) {
- if (TEX32_A(*texel)) {
+ for (int x = 0; x < w; ++x) {
+ uint8 sa, sr, sg, sb;
+ texformat.colorToARGB(*texel, sa, sr, sg, sb);
+
+ if (!alpha_blend) {
+ if (sa) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
+ (sr * ia + r) >> 8,
+ (sg * ia + g) >> 8,
+ (sb * ia + b) >> 8));
}
- pixel += format.bytesPerPixel;
- texel++;
- }
- else
- for (int x = 0; x < w; ++x) {
- uint32 alpha = TEX32_A(*texel);
- if (alpha == 0xFF) {
+ } else {
+ if (sa == 0xFF) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(
format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- } else if (alpha) {
+ (sr * ia + r) >> 8,
+ (sg * ia + g) >> 8,
+ (sb * ia + b) >> 8));
+ } else if (sa) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
- uint32 Tsrc = *texel;
uint8 r2, g2, b2;
format.colorToRGB(*dest, r2, g2, b2);
- uint32 dr = r2 * (256 - alpha);
- uint32 dg = g2 * (256 - alpha);
- uint32 db = b2 * (256 - alpha);
- dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
- dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
- db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
+ uint32 dr = r2 * (256 - sa);
+ uint32 dg = g2 * (256 - sa);
+ uint32 db = b2 * (256 - sa);
+ dr += sr * ia + ((r * sa) >> 8);
+ dg += sg * ia + ((g * sa) >> 8);
+ db += sb * ia + ((b * sa) >> 8);
*dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
}
- pixel += format.bytesPerPixel;
- texel++;
}
-
+ pixel += format.bytesPerPixel;
+ texel++;
+ }
pixel += diff;
texel += tex_diff;
}
@@ -643,65 +640,63 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
uint32 b = (TEX32_B(col32) * a);
uint32 aMask = format.aMax() << format.aShift;
- int texbpp = src.rawSurface().format.bpp();
- if (texbpp == 32) {
+ const Graphics::PixelFormat &texformat = src.format;
+
+ if (texformat.bpp() == 32) {
const uint32 *texel = static_cast<const uint32 *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
for (int y = 0; y < h; ++y) {
- if (!alpha_blend) {
- for (int x = 0; x < w; ++x) {
+ for (int x = 0; x < w; ++x) {
+ uint8 sa, sr, sg, sb;
+ texformat.colorToARGB(*texel, sa, sr, sg, sb);
+
+ if (!alpha_blend) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
- if (TEX32_A(*texel)) {
+ if (sa) {
if (!aMask || (*dest & aMask)) {
*dest = static_cast<uintX>(
format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
+ (sr * ia + r) >> 8,
+ (sg * ia + g) >> 8,
+ (sb * ia + b) >> 8));
}
}
- pixel += format.bytesPerPixel;
- texel++;
- }
- } else {
- for (int x = 0; x < w; ++x) {
+ } else {
uintX *dest = reinterpret_cast<uintX *>(pixel);
if (!aMask || (*dest & aMask)) {
- uint32 alpha = TEX32_A(*texel);
- if (alpha == 0xFF) {
+ if (sa == 0xFF) {
*dest = static_cast<uintX>(
format.RGBToColor(
- (TEX32_R(*texel) * ia + r) >> 8,
- (TEX32_G(*texel) * ia + g) >> 8,
- (TEX32_B(*texel) * ia + b) >> 8));
- } else if (alpha) {
- uint32 Tsrc = *texel;
+ (sr * ia + r) >> 8,
+ (sg * ia + g) >> 8,
+ (sb * ia + b) >> 8));
+ } else if (sa) {
uint8 r2, g2, b2;
format.colorToRGB(*dest, r2, g2, b2);
- uint32 dr = r2 * (256 - alpha);
- uint32 dg = g2 * (256 - alpha);
- uint32 db = b2 * (256 - alpha);
- dr += TEX32_R(Tsrc) * ia + ((r * alpha) >> 8);
- dg += TEX32_G(Tsrc) * ia + ((g * alpha) >> 8);
- db += TEX32_B(Tsrc) * ia + ((b * alpha) >> 8);
+ uint32 dr = r2 * (256 - sa);
+ uint32 dg = g2 * (256 - sa);
+ uint32 db = b2 * (256 - sa);
+ dr += sr * ia + ((r * sa) >> 8);
+ dg += sg * ia + ((g * sa) >> 8);
+ db += sb * ia + ((b * sa) >> 8);
*dest = format.RGBToColor(dr >> 8, dg >> 8, db >> 8);
}
}
- pixel += format.bytesPerPixel;
- texel++;
}
+ pixel += format.bytesPerPixel;
+ texel++;
}
pixel += diff;
texel += tex_diff;
}
- } else if (texbpp == format.bpp()) {
+ } else if (texformat == format) {
const uintX *texel = reinterpret_cast<const uintX *>(src.getBasePtr(sx, sy));
int tex_diff = src.w - w;
@@ -722,7 +717,7 @@ void inline maskedBlitLogic(uint8 *pixels, int32 pitch,
texel += tex_diff;
}
} else {
- error("unsupported texture format %d bpp", texbpp);
+ error("unsupported texture format %d bpp", texformat.bpp());
}
}
Commit: 04b9b2cdae2a9d785d620e17879f7490d0250ec5
https://github.com/scummvm/scummvm/commit/04b9b2cdae2a9d785d620e17879f7490d0250ec5
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Remove flipped clip window calculations from RenderSurface.
This was not needed for a full-height clipping window when top left is the same as the offset (GameMapGump) and was incorrect for other movable gumps.
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index aed7514fefc..7c65e8d8ba4 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -272,22 +272,8 @@ void RenderSurface::SetClippingRect(const Rect &r) {
// Desc: Flip the surface
//
void RenderSurface::SetFlipped(bool wantFlipped) {
- // Flipping is not terrible complex
- // But is a bit of a pain to set up
-
- // First we check to see if we are currently _flipped
- if (wantFlipped == _flipped)
- return;
-
_flipped = wantFlipped;
- // What we 'need' to do is negate the pitches, and flip the clipping window
- // We keep the 'origin' in the same position relative to the clipping window
-
- _oy -= _clipWindow.top;
- _clipWindow.setHeight(_surface->h - _clipWindow.top + _clipWindow.height());
- _oy += _clipWindow.top;
-
SetPixelsPointer();
}
@@ -308,8 +294,9 @@ bool RenderSurface::IsFlipped() const {
void RenderSurface::Fill32(uint32 rgb, const Rect &r) {
Common::Rect rect(r.left, r.top, r.right, r.bottom);
rect.clip(_clipWindow);
+ rect.translate(_ox, _oy);
rgb = _surface->format.RGBToColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF);
- _surface->fillRect(Common::Rect(rect.left + _ox, rect.top + _oy, rect.right + _ox, rect.bottom + _oy), rgb);
+ _surface->fillRect(rect, rgb);
}
@@ -331,11 +318,13 @@ void inline fillAlphaLogic(uint8 *pixels, int32 pitch, uint8 alpha, const Common
uint32 c;
uint32 m;
if (a == 0) {
- c = (format.bMask >> 1) & format.bMask;
- m = format.bMask;
+ uint32 bMask = format.bMax() << format.bShift;
+ c = (bMask >> 1) & bMask;
+ m = bMask;
} else {
- c = (format.rMask >> 1) & format.rMask;
- m = format.rMask;
+ uint32 rMask = format.rMax() << format.rShift;
+ c = (rMask >> 1) & rMask;
+ m = rMask;
}
#endif
Commit: e0e9d02f18e915747de32b1d49090331f86462d4
https://github.com/scummvm/scummvm/commit/e0e9d02f18e915747de32b1d49090331f86462d4
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Store shape frame pixels in a surface to allow use in standard blit methods
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.inl
engines/ultima/ultima8/graphics/shape_frame.cpp
engines/ultima/ultima8/graphics/shape_frame.h
engines/ultima/ultima8/gumps/difficulty_gump.cpp
engines/ultima/ultima8/gumps/difficulty_gump.h
engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
engines/ultima/ultima8/kernel/mouse.cpp
engines/ultima/ultima8/world/minimap.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 7c65e8d8ba4..d67d5550953 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -775,7 +775,8 @@ template<typename uintX>
void inline paintLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y,
+ const uint32 *map) {
#include "ultima/ultima8/graphics/render_surface.inl"
}
@@ -783,7 +784,8 @@ template<class uintX>
void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y,
+ const uint32 *map) {
#define NO_CLIPPING
#include "ultima/ultima8/graphics/render_surface.inl"
#undef NO_CLIPPING
@@ -793,7 +795,8 @@ template<class uintX>
void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y,
+ const uint32 *map, const uint32 *xform_map) {
#define XFORM_SHAPES
#include "ultima/ultima8/graphics/render_surface.inl"
#undef XFORM_SHAPES
@@ -803,7 +806,8 @@ template<class uintX>
void inline paintMirroredLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y, bool trans,
+ const uint32 *map, const uint32 *xform_map) {
#define FLIP_SHAPES
#define XFORM_SHAPES
#define XFORM_CONDITIONAL trans
@@ -819,7 +823,8 @@ template<class uintX>
void inline paintInvisibleLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored,
+ const uint32 *map, const uint32 *xform_map) {
#define FLIP_SHAPES
#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
@@ -839,7 +844,8 @@ template<class uintX>
void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32,
+ const uint32 *map, const uint32 *xform_map) {
#define FLIP_SHAPES
#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
@@ -864,7 +870,8 @@ template<class uintX>
void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
const Graphics::PixelFormat &format,
- const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32,
+ const uint32 *map, const uint32 *xform_map) {
#define FLIP_SHAPES
#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
@@ -893,10 +900,16 @@ void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
// Desc: Standard shape drawing functions. Clips but doesn't do anything else
//
void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+
if (_surface->format.bytesPerPixel == 4)
- paintLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
else if (_surface->format.bytesPerPixel == 2)
- paintLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
}
//
@@ -905,10 +918,16 @@ void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, boo
// Desc: Standard shape drawing functions. Doesn't clip
//
void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+
if (_surface->format.bytesPerPixel == 4)
- paintNoClipLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintNoClipLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
else if (_surface->format.bytesPerPixel == 2)
- paintNoClipLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintNoClipLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
}
//
@@ -917,10 +936,17 @@ void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32
// Desc: Standard shape drawing functions. Clips and XForms
//
void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+
if (_surface->format.bytesPerPixel == 4)
- paintTranslucentLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintTranslucentLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map, xform_map);
else if (_surface->format.bytesPerPixel == 2)
- paintTranslucentLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, untformed_pal);
+ paintTranslucentLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map, xform_map);
}
//
@@ -929,10 +955,17 @@ void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, i
// Desc: Standard shape drawing functions. Clips, Flips and conditionally XForms
//
void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+
if (_surface->format.bytesPerPixel == 4)
- paintMirroredLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, untformed_pal);
+ paintMirroredLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, map, xform_map);
else if (_surface->format.bytesPerPixel == 2)
- paintMirroredLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, untformed_pal);
+ paintMirroredLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, map, xform_map);
}
//
@@ -941,10 +974,17 @@ void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int3
// Desc: Standard shape drawing functions. Invisible, Clips, and conditionally Flips and Xforms
//
void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+
if (_surface->format.bytesPerPixel == 4)
- paintInvisibleLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, untformed_pal);
+ paintInvisibleLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, map, xform_map);
else if (_surface->format.bytesPerPixel == 2)
- paintInvisibleLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, untformed_pal);
+ paintInvisibleLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, map, xform_map);
}
//
@@ -953,10 +993,17 @@ void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int
// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms
//
void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+
if (_surface->format.bytesPerPixel == 4)
- paintHighlightLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ paintHighlightLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
else if (_surface->format.bytesPerPixel == 2)
- paintHighlightLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ paintHighlightLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
}
//
@@ -965,10 +1012,17 @@ void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int
// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms. 50% translucent
//
void RenderSurface::PaintHighlightInvis(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+ const ShapeFrame *frame = s->getFrame(framenum);
+ if (!frame || !s->getPalette())
+ return;
+
+ const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+
if (_surface->format.bytesPerPixel == 4)
- paintHighlightInvisLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ paintHighlightInvisLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
else if (_surface->format.bytesPerPixel == 2)
- paintHighlightInvisLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, s, framenum, x, y, trans, mirrored, col32, untformed_pal);
+ paintHighlightInvisLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/graphics/render_surface.inl b/engines/ultima/ultima8/graphics/render_surface.inl
index 19f34b284a2..1c743125a37 100644
--- a/engines/ultima/ultima8/graphics/render_surface.inl
+++ b/engines/ultima/ultima8/graphics/render_surface.inl
@@ -66,9 +66,9 @@
#ifdef XFORM_SHAPES
#ifdef XFORM_CONDITIONAL
-#define USE_XFORM_FUNC ((XFORM_CONDITIONAL) && xform_pal[*srcpix])
+#define USE_XFORM_FUNC ((XFORM_CONDITIONAL) && xform_map[*srcpix])
#else
-#define USE_XFORM_FUNC (xform_pal[*srcpix])
+#define USE_XFORM_FUNC (xform_map[*srcpix])
#endif
//
@@ -164,29 +164,13 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
// The Function
//
- // Sanity check
- if (framenum >= s->frameCount())
- return;
- if (s->getPalette() == 0)
- return;
+ const uint8 keycolor = frame->_keycolor;
- const ShapeFrame *frame = s->getFrame(framenum);
- if (!frame)
- return;
- const uint8 *srcpixels = frame->_pixels;
- const uint8 keycolor = frame->_keycolor;
- const uint32 *pal = untformed_pal ?
- s->getPalette()->_native_untransformed:
- s->getPalette()->_native;
+ const Graphics::Surface &src = frame->getSurface();
+ const uint8 *srcpixels = reinterpret_cast<const uint8 *>(src.getPixels());
-#ifdef XFORM_SHAPES
- const uint32 *xform_pal = untformed_pal ?
- s->getPalette()->_xform_untransformed:
- s->getPalette()->_xform;
-#endif
-
- const int32 width_ = frame->_width;
- const int32 height_ = frame->_height;
+ const int width_ = src.w;
+ const int height_ = src.h;
x -= XNEG(frame->_xoff);
y -= frame->_yoff;
@@ -210,12 +194,12 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
const uint8 *srcpix = srcline + xpos;
#ifdef XFORM_SHAPES
if (USE_XFORM_FUNC) {
- *dstpix = CUSTOM_BLEND(BlendPreModulated(xform_pal[*srcpix], *dstpix, format));
+ *dstpix = CUSTOM_BLEND(BlendPreModulated(xform_map[*srcpix], *dstpix, format));
}
else
#endif
{
- *dstpix = CUSTOM_BLEND(pal[*srcpix]);
+ *dstpix = CUSTOM_BLEND(map[*srcpix]);
}
}
}
diff --git a/engines/ultima/ultima8/graphics/shape_frame.cpp b/engines/ultima/ultima8/graphics/shape_frame.cpp
index 3b430d21ae9..cf5628de046 100644
--- a/engines/ultima/ultima8/graphics/shape_frame.cpp
+++ b/engines/ultima/ultima8/graphics/shape_frame.cpp
@@ -28,11 +28,11 @@ namespace Ultima {
namespace Ultima8 {
ShapeFrame::ShapeFrame(const RawShapeFrame *rawframe) :
+ _width(_surface.w), _height(_surface.h),
_xoff(rawframe->_xoff), _yoff(rawframe->_yoff),
- _width(rawframe->_width), _height(rawframe->_height),
_keycolor(0xFF) {
- _pixels = new uint8[_width * _height]();
+ _surface.create(rawframe->_width, rawframe->_height, Graphics::PixelFormat::createFormatCLUT8());
// load adjusting keycolor until success
if (!load(rawframe, _keycolor)) {
@@ -44,21 +44,22 @@ ShapeFrame::ShapeFrame(const RawShapeFrame *rawframe) :
}
ShapeFrame::~ShapeFrame() {
- delete [] _pixels;
+ _surface.free();
}
bool ShapeFrame::load(const RawShapeFrame *rawframe, uint8 keycolor) {
bool result = true;
- memset(_pixels, keycolor, _width * _height);
+ uint8 *pixels = reinterpret_cast<uint8 *>(_surface.getPixels());
+ memset(pixels, keycolor, _surface.w * _surface.h);
- for (int y = 0; y < _height; y++) {
+ for (int y = 0; y < _surface.h; y++) {
int32 xpos = 0;
const uint8 *linedata = rawframe->_rle_data + rawframe->_line_offsets[y];
do {
xpos += *linedata++;
- if (xpos >= _width)
+ if (xpos >= _surface.w)
break;
int32 dlen = *linedata++;
@@ -72,7 +73,7 @@ bool ShapeFrame::load(const RawShapeFrame *rawframe, uint8 keycolor) {
for (int doff = 0; doff < dlen; doff++) {
if (*linedata == keycolor)
result = false;
- _pixels[y * _width + xpos + doff] = *linedata;
+ pixels[y * _surface.w + xpos + doff] = *linedata;
if (!type) {
linedata++;
}
@@ -83,35 +84,35 @@ bool ShapeFrame::load(const RawShapeFrame *rawframe, uint8 keycolor) {
linedata++;
}
- } while (xpos < _width);
+ } while (xpos < _surface.w);
}
return result;
}
// Checks to see if the frame has a pixel at the point
-bool ShapeFrame::hasPoint(int32 x, int32 y) const {
+bool ShapeFrame::hasPoint(int x, int y) const {
// Add the offset
x += _xoff;
y += _yoff;
// First gross culling based on dims
- if (x < 0 || y < 0 || x >= _width || y >= _height)
+ if (x < 0 || y < 0 || x >= _surface.w || y >= _surface.h)
return false;
- return _pixels[y * _width + x] != _keycolor;
+ return _surface.getPixel(x, y) != _keycolor;
}
// Get the pixel at the point
-uint8 ShapeFrame::getPixelAtPoint(int32 x, int32 y) const {
+uint8 ShapeFrame::getPixel(int x, int y) const {
// Add the offset
x += _xoff;
y += _yoff;
// First gross culling based on dims
- if (x < 0 || y < 0 || x >= _width || y >= _height)
+ if (x < 0 || y < 0 || x >= _surface.w || y >= _surface.h)
return _keycolor;
- return _pixels[y * _width + x];
+ return _surface.getPixel(x, y);
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/graphics/shape_frame.h b/engines/ultima/ultima8/graphics/shape_frame.h
index a4098c78194..2bc4bbb5c56 100644
--- a/engines/ultima/ultima8/graphics/shape_frame.h
+++ b/engines/ultima/ultima8/graphics/shape_frame.h
@@ -22,6 +22,8 @@
#ifndef ULTIMA8_GRAPHICS_SHAPEFRAME_H
#define ULTIMA8_GRAPHICS_SHAPEFRAME_H
+#include "graphics/surface.h"
+
namespace Ultima {
namespace Ultima8 {
@@ -34,17 +36,21 @@ public:
ShapeFrame(const RawShapeFrame *rawframe);
~ShapeFrame();
- int32 _width, _height;
- int32 _xoff, _yoff;
+ int16 &_width;
+ int16 &_height;
+ int16 _xoff, _yoff;
- uint8 *_pixels;
uint8 _keycolor;
- bool hasPoint(int32 x, int32 y) const; // Check to see if a point is in the frame
+ bool hasPoint(int x, int y) const; // Check to see if a point is in the frame
+
+ uint8 getPixel(int x, int y) const; // Get the pixel at the point
- uint8 getPixelAtPoint(int32 x, int32 y) const; // Get the pixel at the point
+ const Graphics::Surface &getSurface() const { return _surface; }
private:
+ Graphics::Surface _surface;
+
/**
* Load the pixel data from the raw shape rle data using key color for transparency
* @param rawframe the raw shape to load rle data
diff --git a/engines/ultima/ultima8/gumps/difficulty_gump.cpp b/engines/ultima/ultima8/gumps/difficulty_gump.cpp
index ab5a31e50a0..04672eb441d 100644
--- a/engines/ultima/ultima8/gumps/difficulty_gump.cpp
+++ b/engines/ultima/ultima8/gumps/difficulty_gump.cpp
@@ -116,7 +116,7 @@ void DifficultyGump::InitGump(Gump *newparent, bool take_focus) {
_buttonHeight = MAX(_buttonHeight, leftFrame->_height);
_buttonHeight = MAX(_buttonHeight, rightFrame->_height);
- _buttonWidth = MAX(_buttonWidth, leftFrame->_width + rightFrame->_width);
+ _buttonWidth = MAX(_buttonWidth, static_cast<int16>(leftFrame->_width + rightFrame->_width));
}
// remove focus from children (just in case)
diff --git a/engines/ultima/ultima8/gumps/difficulty_gump.h b/engines/ultima/ultima8/gumps/difficulty_gump.h
index 34d0e69416e..6ea6870620e 100644
--- a/engines/ultima/ultima8/gumps/difficulty_gump.h
+++ b/engines/ultima/ultima8/gumps/difficulty_gump.h
@@ -47,8 +47,8 @@ public:
private:
int _highlighted;
- int32 _buttonWidth;
- int32 _buttonHeight;
+ int16 _buttonWidth;
+ int16 _buttonHeight;
void selectEntry(int num);
};
diff --git a/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp b/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
index 86fcd4580f8..7c2c32ee6f8 100644
--- a/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
+++ b/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
@@ -173,7 +173,7 @@ void ShapeViewerGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool /*s
rely -= _shapeY;
const ShapeFrame *frame = shape->getFrame(_curFrame);
if (frame && frame->hasPoint(relx, rely)) {
- uint8 rawpx = frame->getPixelAtPoint(relx, rely);
+ uint8 rawpx = frame->getPixel(relx, rely);
uint8 px_r = shape->getPalette()->_palette[rawpx * 3];
uint8 px_g = shape->getPalette()->_palette[rawpx * 3 + 1];
uint8 px_b = shape->getPalette()->_palette[rawpx * 3 + 2];
diff --git a/engines/ultima/ultima8/kernel/mouse.cpp b/engines/ultima/ultima8/kernel/mouse.cpp
index 9accca97a55..e7ab098dd5b 100644
--- a/engines/ultima/ultima8/kernel/mouse.cpp
+++ b/engines/ultima/ultima8/kernel/mouse.cpp
@@ -560,7 +560,7 @@ void Mouse::update() {
if (frame >= 0 && (uint)frame < mouse->frameCount()) {
const ShapeFrame *f = mouse->getFrame(frame);
- CursorMan.replaceCursor(f->_pixels, f->_width, f->_height, f->_xoff, f->_yoff, f->_keycolor);
+ CursorMan.replaceCursor(f->getSurface(), f->_xoff, f->_yoff, f->_keycolor);
CursorMan.replaceCursorPalette(mouse->getPalette()->_palette, 0, 256);
CursorMan.showMouse(true);
} else {
diff --git a/engines/ultima/ultima8/world/minimap.cpp b/engines/ultima/ultima8/world/minimap.cpp
index bea2fa4cb57..0a55072e387 100644
--- a/engines/ultima/ultima8/world/minimap.cpp
+++ b/engines/ultima/ultima8/world/minimap.cpp
@@ -153,7 +153,7 @@ uint32 MiniMap::sampleAtPoint(const Item &item, int x, int y) {
if (!frame->hasPoint(i - sx, j - sy))
continue;
- uint8 p = frame->getPixelAtPoint(i - sx, j - sy);
+ uint8 p = frame->getPixel(i - sx, j - sy);
byte r2 = pal->_palette[p * 3 + 0];
byte g2 = pal->_palette[p * 3 + 1];
byte b2 = pal->_palette[p * 3 + 2];
Commit: 4a59130ca566b55bf7e7e92480ee244aab9e829b
https://github.com/scummvm/scummvm/commit/4a59130ca566b55bf7e7e92480ee244aab9e829b
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Remove unused parameter on shape paint methods
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.h
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index d67d5550953..eff03db817f 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -899,12 +899,12 @@ void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
//
// Desc: Standard shape drawing functions. Clips but doesn't do anything else
//
-void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *map = s->getPalette()->_native;
if (_surface->format.bytesPerPixel == 4)
paintLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
@@ -917,12 +917,12 @@ void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y, boo
//
// Desc: Standard shape drawing functions. Doesn't clip
//
-void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
+ const uint32 *map = s->getPalette()->_native;
if (_surface->format.bytesPerPixel == 4)
paintNoClipLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
@@ -935,13 +935,13 @@ void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32
//
// Desc: Standard shape drawing functions. Clips and XForms
//
-void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, int32 y, bool untformed_pal) {
+void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, int32 y) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
- const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+ const uint32 *map = s->getPalette()->_native;
+ const uint32 *xform_map = s->getPalette()->_xform;
if (_surface->format.bytesPerPixel == 4)
paintTranslucentLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map, xform_map);
@@ -954,13 +954,13 @@ void RenderSurface::PaintTranslucent(const Shape *s, uint32 framenum, int32 x, i
//
// Desc: Standard shape drawing functions. Clips, Flips and conditionally XForms
//
-void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool untformed_pal) {
+void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
- const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+ const uint32 *map = s->getPalette()->_native;
+ const uint32 *xform_map = s->getPalette()->_xform;
if (_surface->format.bytesPerPixel == 4)
paintMirroredLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, map, xform_map);
@@ -973,13 +973,13 @@ void RenderSurface::PaintMirrored(const Shape *s, uint32 framenum, int32 x, int3
//
// Desc: Standard shape drawing functions. Invisible, Clips, and conditionally Flips and Xforms
//
-void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal) {
+void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
- const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+ const uint32 *map = s->getPalette()->_native;
+ const uint32 *xform_map = s->getPalette()->_xform;
if (_surface->format.bytesPerPixel == 4)
paintInvisibleLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, map, xform_map);
@@ -992,13 +992,13 @@ void RenderSurface::PaintInvisible(const Shape *s, uint32 framenum, int32 x, int
//
// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms
//
-void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
- const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+ const uint32 *map = s->getPalette()->_native;
+ const uint32 *xform_map = s->getPalette()->_xform;
if (_surface->format.bytesPerPixel == 4)
paintHighlightLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
@@ -1011,13 +1011,13 @@ void RenderSurface::PaintHighlight(const Shape *s, uint32 framenum, int32 x, int
//
// Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms. 50% translucent
//
-void RenderSurface::PaintHighlightInvis(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal) {
+void RenderSurface::PaintHighlightInvis(const Shape *s, uint32 framenum, int32 x, int32 y, bool trans, bool mirrored, uint32 col32) {
const ShapeFrame *frame = s->getFrame(framenum);
if (!frame || !s->getPalette())
return;
- const uint32 *map = untformed_pal ? s->getPalette()->_native_untransformed : s->getPalette()->_native;
- const uint32 *xform_map = untformed_pal ? s->getPalette()->_xform_untransformed : s->getPalette()->_xform;
+ const uint32 *map = s->getPalette()->_native;
+ const uint32 *xform_map = s->getPalette()->_xform;
if (_surface->format.bytesPerPixel == 4)
paintHighlightInvisLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, trans, mirrored, col32, map, xform_map);
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index 6da3f7fa3bc..c3e56e06da6 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -155,25 +155,25 @@ public:
//
//! Paint a Shape
- void Paint(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
+ void Paint(const Shape *s, uint32 frame, int32 x, int32 y);
//! Paint a Shape without clipping
- void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
+ void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y);
//! Paint a Translucent Shape.
- void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y, bool untformed_pal = false);
+ void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y);
//! Paint a Mirrored Shape
- void PaintMirrored(const Shape *s, uint32 frame, int32 x, int32 y, bool trans = false, bool untformed_pal = false);
+ void PaintMirrored(const Shape *s, uint32 frame, int32 x, int32 y, bool trans = false);
//! Paint an Invisible Shape
- void PaintInvisible(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, bool untformed_pal = false);
+ void PaintInvisible(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored);
//! Paint a Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- void PaintHighlight(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false);
+ void PaintHighlight(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32);
//! Paint a Invisible Highlighted Shape of using the 32 Bit Colour col32 (0xAARRGGBB Alpha is blend level)
- void PaintHighlightInvis(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal = false);
+ void PaintHighlightInvis(const Shape *s, uint32 frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32);
//
// Basic Line Drawing
Commit: c24d47c672bd376bcf978a87e1f0b7019ef49422
https://github.com/scummvm/scummvm/commit/c24d47c672bd376bcf978a87e1f0b7019ef49422
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Rewrite shape frame paint for improved readibility and faster clipping
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.inl
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index eff03db817f..51c33b16fc9 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -777,6 +777,7 @@ void inline paintLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y,
const uint32 *map) {
+ const bool mirrored = false;
#include "ultima/ultima8/graphics/render_surface.inl"
}
@@ -786,6 +787,7 @@ void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y,
const uint32 *map) {
+ const bool mirrored = false;
#define NO_CLIPPING
#include "ultima/ultima8/graphics/render_surface.inl"
#undef NO_CLIPPING
@@ -797,6 +799,7 @@ void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y,
const uint32 *map, const uint32 *xform_map) {
+ const bool mirrored = false;
#define XFORM_SHAPES
#include "ultima/ultima8/graphics/render_surface.inl"
#undef XFORM_SHAPES
@@ -808,13 +811,12 @@ void inline paintMirroredLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y, bool trans,
const uint32 *map, const uint32 *xform_map) {
-#define FLIP_SHAPES
+ const bool mirrored = true;
#define XFORM_SHAPES
#define XFORM_CONDITIONAL trans
#include "ultima/ultima8/graphics/render_surface.inl"
-#undef FLIP_SHAPES
#undef XFORM_SHAPES
#undef XFORM_CONDITIONAL
}
@@ -825,16 +827,12 @@ void inline paintInvisibleLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored,
const uint32 *map, const uint32 *xform_map) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
#define XFORM_CONDITIONAL trans
#define BLEND_SHAPES(src, dst) BlendInvisible(src, dst, format)
#include "ultima/ultima8/graphics/render_surface.inl"
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
#undef XFORM_SHAPES
#undef XFORM_CONDITIONAL
#undef BLEND_SHAPES
@@ -846,8 +844,6 @@ void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32,
const uint32 *map, const uint32 *xform_map) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
#define XFORM_CONDITIONAL trans
#define BLEND_SHAPES(src, dst) BlendHighlight(src, cr, cg, cb, ca, 255 - ca, format)
@@ -859,8 +855,6 @@ void inline paintHighlightLogic(uint8 *pixels, int32 pitch,
#include "ultima/ultima8/graphics/render_surface.inl"
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
#undef XFORM_SHAPES
#undef XFORM_CONDITIONAL
#undef BLEND_SHAPES
@@ -872,8 +866,6 @@ void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
const Graphics::PixelFormat &format,
const ShapeFrame *frame, int32 x, int32 y, bool trans, bool mirrored, uint32 col32,
const uint32 *map, const uint32 *xform_map) {
-#define FLIP_SHAPES
-#define FLIP_CONDITIONAL mirrored
#define XFORM_SHAPES
#define XFORM_CONDITIONAL trans
#define BLEND_SHAPES(src, dst) BlendHighlightInvis(src, dst, cr, cg, cb, ca, 255 - ca, format)
@@ -885,8 +877,6 @@ void inline paintHighlightInvisLogic(uint8 *pixels, int32 pitch,
#include "ultima/ultima8/graphics/render_surface.inl"
-#undef FLIP_SHAPES
-#undef FLIP_CONDITIONAL
#undef XFORM_SHAPES
#undef XFORM_CONDITIONAL
#undef BLEND_SHAPES
diff --git a/engines/ultima/ultima8/graphics/render_surface.inl b/engines/ultima/ultima8/graphics/render_surface.inl
index 1c743125a37..a3d7bb88bd3 100644
--- a/engines/ultima/ultima8/graphics/render_surface.inl
+++ b/engines/ultima/ultima8/graphics/render_surface.inl
@@ -28,11 +28,6 @@
//
// #define NO_CLIPPING to disable shape clipping
//
-// #define FLIP_SHAPES to flip rendering
-//
-// #define FLIP_CONDITIONAL to an argument of the function so FLIPPING can be
-// enabled/disabled with a bool
-//
// #define XFORM_SHAPES to enable XFORMing
//
// #define XFORM_CONDITIONAL to an argument of the function so XFORM can be
@@ -47,14 +42,6 @@
//
// Macros defined by this file:
//
-// NOT_CLIPPED_Y - Does Y Clipping check per line
-//
-// NOT_CLIPPED_X - Does X Clipping check per Pixel
-//
-// LINE_END_ASSIGN - Calcuates the line_end pointer required for X clipping
-//
-// XNEG - Negates X values if doing shape flipping
-//
// USE_XFORM_FUNC - Checks to see if we want to use XForm Blending for this pixel
//
// CUSTOM_BLEND - Final Blend for invisiblity
@@ -66,9 +53,9 @@
#ifdef XFORM_SHAPES
#ifdef XFORM_CONDITIONAL
-#define USE_XFORM_FUNC ((XFORM_CONDITIONAL) && xform_map[*srcpix])
+#define USE_XFORM_FUNC ((XFORM_CONDITIONAL) && xform_map[color])
#else
-#define USE_XFORM_FUNC (xform_map[*srcpix])
+#define USE_XFORM_FUNC (xform_map[color])
#endif
//
@@ -78,55 +65,6 @@
#define USE_XFORM_FUNC 0
#endif
-
-//
-// Flipping = TRUE
-//
-#ifdef FLIP_SHAPES
-
-#ifdef FLIP_CONDITIONAL
-const int32 neg = (FLIP_CONDITIONAL)?-1:0;
-#define XNEG(x) (((x)+neg)^neg)
-#else
-#define XNEG(x) (-(x))
-#endif
-
-// Flipping = FALSE
-#else
-#define XNEG(x)(+(x))
-#endif
-
-
-//
-// No Clipping = TRUE
-//
-#ifdef NO_CLIPPING
-
-#define LINE_END_ASSIGN //
-#define NOT_CLIPPED_X (1)
-#define NOT_CLIPPED_Y (1)
-#define OFFSET_PIXELS (pixels)
-
-//
-// No Clipping = FALSE
-//
-#else
-
- const int scrn_width = clipWindow.width();
- const int scrn_height = clipWindow.height();
-
-#define LINE_END_ASSIGN const uintX *dst_line_end = dst_line_start + scrn_width
-#define NOT_CLIPPED_X (dstpix >= dst_line_start && dstpix < dst_line_end)
-#define NOT_CLIPPED_Y (line >= 0 && line < scrn_height)
-#define OFFSET_PIXELS (off_pixels)
-
- uint8 *off_pixels = pixels + clipWindow.left * sizeof(uintX) + clipWindow.top * pitch;
- x -= clipWindow.left;
- y -= clipWindow.top;
-
-#endif
-
-
//
// Invisilibity = TRUE
//
@@ -148,69 +86,86 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
#endif
//
-// Destination Alpha Masking
+// The Function
//
-#ifdef DESTALPHA_MASK
-#define NOT_DESTINATION_MASKED (*pixptr & RenderSurface::_format.aMask)
+ const Graphics::Surface &src = frame->getSurface();
+ const uint8 keycolor = frame->_keycolor;
-#else
+ Common::Rect srcRect(0, 0, src.w, src.h);
+ Common::Rect dstRect(x, y, x, y + src.h);
-#define NOT_DESTINATION_MASKED (1)
+ const int srcStep = sizeof(uint8);
+ int dstStep = sizeof(uintX);
-#endif
+ if (mirrored) {
+ dstRect.translate(frame->_xoff, -frame->_yoff);
+ dstRect.left = dstRect.right - src.w;
+ dstStep = -dstStep;
+ } else {
+ dstRect.translate(-frame->_xoff, -frame->_yoff);
+ dstRect.right = dstRect.left + src.w;
+ }
-//
-// The Function
-//
+#ifndef NO_CLIPPING
+
+ if (dstRect.left < clipWindow.left) {
+ if (mirrored) {
+ srcRect.right += dstRect.left - clipWindow.left;
+ } else {
+ srcRect.left -= dstRect.left - clipWindow.left;
+ }
+ dstRect.left = clipWindow.left;
+ }
+ if (dstRect.top < clipWindow.top) {
+ srcRect.top -= dstRect.top - clipWindow.top;
+ dstRect.top = clipWindow.top;
+ }
+ if (dstRect.right > clipWindow.right) {
+ if (mirrored) {
+ srcRect.left += dstRect.right - clipWindow.right;
+ } else {
+ srcRect.right -= dstRect.right - clipWindow.right;
+ }
+ dstRect.right = clipWindow.right;
+ }
+ if (dstRect.bottom > clipWindow.bottom) {
+ srcRect.bottom -= dstRect.bottom - clipWindow.bottom;
+ dstRect.bottom = clipWindow.bottom;
+ }
- const uint8 keycolor = frame->_keycolor;
+#endif
- const Graphics::Surface &src = frame->getSurface();
- const uint8 *srcpixels = reinterpret_cast<const uint8 *>(src.getPixels());
-
- const int width_ = src.w;
- const int height_ = src.h;
- x -= XNEG(frame->_xoff);
- y -= frame->_yoff;
-
- assert(pixels && srcpixels);
-
- for (int i = 0; i < height_; i++) {
- const int line = y + i;
-
- if (NOT_CLIPPED_Y) {
- const uint8 *srcline = srcpixels + i * width_;
- uintX *dst_line_start = reinterpret_cast<uintX *>(OFFSET_PIXELS + pitch * line);
- LINE_END_ASSIGN;
-
- for (int xpos = 0; xpos < width_; xpos++) {
- if (srcline[xpos] == keycolor)
- continue;
-
- uintX *dstpix = dst_line_start + x + XNEG(xpos);
-
- if (NOT_CLIPPED_X && NOT_DESTINATION_MASKED) {
- const uint8 *srcpix = srcline + xpos;
- #ifdef XFORM_SHAPES
- if (USE_XFORM_FUNC) {
- *dstpix = CUSTOM_BLEND(BlendPreModulated(xform_map[*srcpix], *dstpix, format));
- }
- else
- #endif
- {
- *dstpix = CUSTOM_BLEND(map[*srcpix]);
- }
+ const int w = srcRect.width();
+ const int h = srcRect.height();
+ const int srcDelta = src.pitch - (w * srcStep);
+ const int dstDelta = pitch - (w * dstStep);
+
+ const uint8 *srcPixels = reinterpret_cast<const uint8 *>(src.getBasePtr(srcRect.left, srcRect.top));
+ uint8 *dstPixels = reinterpret_cast<uint8 *>(pixels + (mirrored ? dstRect.right - 1 : dstRect.left) * sizeof(uintX) + pitch * dstRect.top);
+
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ const uint8 color = *srcPixels;
+ if (color != keycolor) {
+ uintX *dstpix = reinterpret_cast<uintX *>(dstPixels);
+ #ifdef XFORM_SHAPES
+ if (USE_XFORM_FUNC) {
+ *dstpix = CUSTOM_BLEND(BlendPreModulated(xform_map[color], *dstpix, format));
+ }
+ else
+ #endif
+ {
+ *dstpix = CUSTOM_BLEND(map[color]);
}
}
+ srcPixels += srcStep;
+ dstPixels += dstStep;
}
+
+ srcPixels += srcDelta;
+ dstPixels += dstDelta;
}
-#undef NOT_DESTINATION_MASKED
-#undef OFFSET_PIXELS
#undef CUSTOM_BLEND
-#undef LINE_END_ASSIGN
-#undef NOT_CLIPPED_X
-#undef NOT_CLIPPED_Y
-#undef XNEG
#undef USE_XFORM_FUNC
Commit: 9c67d5684f2001a1b46f1542658393ee49762ebe
https://github.com/scummvm/scummvm/commit/9c67d5684f2001a1b46f1542658393ee49762ebe
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Remove PaintNoClip method as it no longer provides a measurable performance increase over other shape paint methods
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.h
engines/ultima/ultima8/graphics/render_surface.inl
engines/ultima/ultima8/misc/debugger.cpp
engines/ultima/ultima8/world/item_sorter.cpp
engines/ultima/ultima8/world/sort_item.h
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index 51c33b16fc9..f73581f1511 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -781,18 +781,6 @@ void inline paintLogic(uint8 *pixels, int32 pitch,
#include "ultima/ultima8/graphics/render_surface.inl"
}
-template<class uintX>
-void inline paintNoClipLogic(uint8 *pixels, int32 pitch,
- const Common::Rect &clipWindow,
- const Graphics::PixelFormat &format,
- const ShapeFrame *frame, int32 x, int32 y,
- const uint32 *map) {
- const bool mirrored = false;
-#define NO_CLIPPING
-#include "ultima/ultima8/graphics/render_surface.inl"
-#undef NO_CLIPPING
-}
-
template<class uintX>
void inline paintTranslucentLogic(uint8 *pixels, int32 pitch,
const Common::Rect &clipWindow,
@@ -902,24 +890,6 @@ void RenderSurface::Paint(const Shape *s, uint32 framenum, int32 x, int32 y) {
paintLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
}
-//
-// void RenderSurface::PaintNoClip(Shape*s, uint32 framenum, int32 x, int32 y)
-//
-// Desc: Standard shape drawing functions. Doesn't clip
-//
-void RenderSurface::PaintNoClip(const Shape *s, uint32 framenum, int32 x, int32 y) {
- const ShapeFrame *frame = s->getFrame(framenum);
- if (!frame || !s->getPalette())
- return;
-
- const uint32 *map = s->getPalette()->_native;
-
- if (_surface->format.bytesPerPixel == 4)
- paintNoClipLogic<uint32>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
- else if (_surface->format.bytesPerPixel == 2)
- paintNoClipLogic<uint16>(_pixels, _pitch, _clipWindow, _surface->format, frame, x, y, map);
-}
-
//
// void RenderSurface::PaintTranslucent(Shape*s, uint32 framenum, int32 x, int32 y)
//
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index c3e56e06da6..a8a0c78f357 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -157,9 +157,6 @@ public:
//! Paint a Shape
void Paint(const Shape *s, uint32 frame, int32 x, int32 y);
- //! Paint a Shape without clipping
- void PaintNoClip(const Shape *s, uint32 frame, int32 x, int32 y);
-
//! Paint a Translucent Shape.
void PaintTranslucent(const Shape *s, uint32 frame, int32 x, int32 y);
diff --git a/engines/ultima/ultima8/graphics/render_surface.inl b/engines/ultima/ultima8/graphics/render_surface.inl
index a3d7bb88bd3..a5db87a6a23 100644
--- a/engines/ultima/ultima8/graphics/render_surface.inl
+++ b/engines/ultima/ultima8/graphics/render_surface.inl
@@ -26,8 +26,6 @@
//
// Macros to define before including this:
//
-// #define NO_CLIPPING to disable shape clipping
-//
// #define XFORM_SHAPES to enable XFORMing
//
// #define XFORM_CONDITIONAL to an argument of the function so XFORM can be
@@ -107,8 +105,6 @@
dstRect.right = dstRect.left + src.w;
}
-#ifndef NO_CLIPPING
-
if (dstRect.left < clipWindow.left) {
if (mirrored) {
srcRect.right += dstRect.left - clipWindow.left;
@@ -134,8 +130,6 @@
dstRect.bottom = clipWindow.bottom;
}
-#endif
-
const int w = srcRect.width();
const int h = srcRect.height();
const int srcDelta = src.pitch - (w * srcStep);
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index 3c1184b912f..44a4e50a83c 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -1835,13 +1835,6 @@ bool Debugger::cmdBenchmarkRenderSurface(int argc, const char **argv) {
end = g_system->getMillis();
debugPrintf("Paint: %d\n", end - start);
- start = g_system->getMillis();
- for (int i = 0; i < count; i++) {
- surface->PaintNoClip(s, frame, 160, 100);
- }
- end = g_system->getMillis();
- debugPrintf("PaintNoClip: %d\n", end - start);
-
start = g_system->getMillis();
for (int i = 0; i < count; i++) {
surface->PaintTranslucent(s, frame, 160, 100);
diff --git a/engines/ultima/ultima8/world/item_sorter.cpp b/engines/ultima/ultima8/world/item_sorter.cpp
index dae41148484..c9fbe1e88ca 100644
--- a/engines/ultima/ultima8/world/item_sorter.cpp
+++ b/engines/ultima/ultima8/world/item_sorter.cpp
@@ -156,8 +156,6 @@ void ItemSorter::AddItem(int32 x, int32 y, int32 z, uint32 shapeNum, uint32 fram
return;
}
- si->_clipped = !_clipWindow.contains(si->_sr);
-
// These help out with sorting. We calc them now, so it will be faster
si->_fbigsq = (xd == 128 && yd == 128) || (xd == 256 && yd == 256) || (xd == 512 && yd == 512);
si->_flat = zd == 0;
@@ -327,8 +325,6 @@ bool ItemSorter::PaintSortItem(RenderSurface *surf, SortItem *si) {
surf->PaintMirrored(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans);
else if (si->_trans)
surf->PaintTranslucent(si->_shape, si->_frame, si->_sxBot, si->_syBot);
- else if (!si->_clipped)
- surf->PaintNoClip(si->_shape, si->_frame, si->_sxBot, si->_syBot);
else
surf->Paint(si->_shape, si->_frame, si->_sxBot, si->_syBot);
diff --git a/engines/ultima/ultima8/world/sort_item.h b/engines/ultima/ultima8/world/sort_item.h
index 5c21733e0ce..c6c7a9a1471 100644
--- a/engines/ultima/ultima8/world/sort_item.h
+++ b/engines/ultima/ultima8/world/sort_item.h
@@ -47,7 +47,7 @@ struct SortItem {
_syTop(0), _sxBot(0), _syBot(0),_fbigsq(false), _flat(false),
_occl(false), _solid(false), _draw(false), _roof(false),
_noisy(false), _anim(false), _trans(false), _fixed(false),
- _land(false), _occluded(false), _clipped(false), _sprite(false),
+ _land(false), _occluded(false), _sprite(false),
_invitem(false) { }
SortItem *_next;
@@ -108,7 +108,6 @@ struct SortItem {
bool _invitem : 1; // Crusader inventory item, should appear above other things
bool _occluded : 1; // Set true if occluded
- bool _clipped : 1; // Clipped to RenderSurface
int32 _order; // Rendering _order. -1 is not yet drawn
Commit: 0ccf4a9ff620a86c144945b655eda3ebe544f478
https://github.com/scummvm/scummvm/commit/0ccf4a9ff620a86c144945b655eda3ebe544f478
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-09-08T18:25:19-05:00
Commit Message:
ULTIMA8: Allow any 16 or 32 bpp pixel formats
Changed paths:
engines/ultima/ultima8/graphics/render_surface.cpp
engines/ultima/ultima8/graphics/render_surface.h
engines/ultima/ultima8/ultima8.cpp
diff --git a/engines/ultima/ultima8/graphics/render_surface.cpp b/engines/ultima/ultima8/graphics/render_surface.cpp
index f73581f1511..00167b849e1 100644
--- a/engines/ultima/ultima8/graphics/render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/render_surface.cpp
@@ -36,9 +36,11 @@ namespace Ultima8 {
uint8 RenderSurface::_gamma10toGamma22[256];
uint8 RenderSurface::_gamma22toGamma10[256];
-RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _ox(0), _oy(0), _pitch(0),
- _flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0),
- _surface(s) {
+RenderSurface::RenderSurface(Graphics::ManagedSurface *s, DisposeAfterUse::Flag disposeAfterUse) :
+ _pixels(nullptr), _ox(0), _oy(0), _pitch(0),
+ _flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0),
+ _surface(s), _disposeAfterUse(disposeAfterUse) {
+
_clipWindow.setWidth(_surface->w);
_clipWindow.setHeight(_surface->h);
@@ -51,7 +53,8 @@ RenderSurface::RenderSurface(Graphics::ManagedSurface *s) : _pixels(nullptr), _o
// Desc: Destructor
//
RenderSurface::~RenderSurface() {
- delete _surface;
+ if (_disposeAfterUse == DisposeAfterUse::YES)
+ delete _surface;
}
void RenderSurface::SetPixelsPointer()
@@ -104,12 +107,7 @@ bool RenderSurface::EndPainting() {
if (!_lockCount) {
// Clear pointers
- _pixels = 0;
-
- // Render the screen if this is it (slight hack..)
- Graphics::Screen *screen = dynamic_cast<Graphics::Screen *>(_surface);
- if (screen)
- screen->update();
+ _pixels = nullptr;
}
// No error
@@ -732,23 +730,23 @@ void RenderSurface::MaskedBlit(const Graphics::ManagedSurface &src, const Common
// Returns: Created RenderSurface or 0
//
-RenderSurface *RenderSurface::SetVideoMode(uint32 width, uint32 height, int bpp) {
- // Set up the pixel format to use
- Graphics::PixelFormat pixelFormat;
+RenderSurface *RenderSurface::SetVideoMode(uint32 width, uint32 height) {
+ Common::List<Graphics::PixelFormat> tryModes = g_system->getSupportedFormats();
+ for (Common::List<Graphics::PixelFormat>::iterator g = tryModes.begin(); g != tryModes.end(); ++g) {
+ if (g->bytesPerPixel != 2 && g->bytesPerPixel != 4) {
+ g = tryModes.reverse_erase(g);
+ }
+ }
- if (bpp == 16) {
- pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
- } else if (bpp == 32) {
- pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- } else {
+ initGraphics(width, height, tryModes);
+
+ Graphics::PixelFormat format = g_system->getScreenFormat();
+ if (format.bytesPerPixel != 2 && format.bytesPerPixel != 4) {
error("Only 16 bit and 32 bit video modes supported");
}
- // Set up screen mode
- initGraphics(width, height, &pixelFormat);
-
// Set up blitting surface
- Graphics::ManagedSurface *surface = new Graphics::Screen(width, height, pixelFormat);
+ Graphics::ManagedSurface *surface = new Graphics::Screen(width, height, format);
assert(surface);
// Initialize gamma correction tables
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index a8a0c78f357..a80dbeb5bf8 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -55,9 +55,10 @@ private:
uint32 _lockCount; // Number of locks on surface
Graphics::ManagedSurface *_surface;
+ DisposeAfterUse::Flag _disposeAfterUse;
// Create from a managed surface
- RenderSurface(Graphics::ManagedSurface *);
+ RenderSurface(Graphics::ManagedSurface *s, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
// Update the Pixels Pointer
void SetPixelsPointer();
@@ -67,7 +68,7 @@ public:
static uint8 _gamma22toGamma10[256];
//! Create a standard RenderSurface
- static RenderSurface *SetVideoMode(uint32 width, uint32 height, int bpp);
+ static RenderSurface *SetVideoMode(uint32 width, uint32 height);
//! Create a SecondaryRenderSurface with an associated Texture object
static RenderSurface *CreateSecondaryRenderSurface(uint32 width, uint32 height);
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 0939e858b5f..3bdc7c03f17 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -701,6 +701,10 @@ void Ultima8Engine::paint() {
// End _painting
_screen->EndPainting();
+
+ Graphics::Screen *screen = getScreen();
+ if (screen)
+ screen->update();
}
void Ultima8Engine::GraphicSysInit() {
@@ -715,31 +719,28 @@ void Ultima8Engine::GraphicSysInit() {
ConfMan.registerDefault("width", _highRes ? CRUSADER_HIRES_SCREEN_WIDTH : CRUSADER_DEFAULT_SCREEN_WIDTH);
ConfMan.registerDefault("height", _highRes ? CRUSADER_HIRES_SCREEN_HEIGHT : CRUSADER_DEFAULT_SCREEN_HEIGHT);
}
- ConfMan.registerDefault("bpp", 16);
int width = ConfMan.getInt("width");
int height = ConfMan.getInt("height");
- int bpp = ConfMan.getInt("bpp");
if (_screen) {
Rect old_dims;
_screen->GetSurfaceDims(old_dims);
if (width == old_dims.width() && height == old_dims.height())
return;
- bpp = _screen->getRawSurface()->format.bpp();
delete _screen;
}
_screen = nullptr;
// Set Screen Resolution
- debugN(MM_INFO, "Setting Video Mode %dx%dx%d...\n", width, height, bpp);
+ debugN(MM_INFO, "Setting Video Mode %dx%d...\n", width, height);
- RenderSurface *new_screen = RenderSurface::SetVideoMode(width, height, bpp);
+ RenderSurface *new_screen = RenderSurface::SetVideoMode(width, height);
if (!new_screen) {
- warning("Unable to set new video mode. Trying %dx%dx32", U8_DEFAULT_SCREEN_WIDTH, U8_DEFAULT_SCREEN_HEIGHT);
- new_screen = RenderSurface::SetVideoMode(U8_DEFAULT_SCREEN_WIDTH, U8_DEFAULT_SCREEN_HEIGHT, 32);
+ warning("Unable to set new video mode. Trying %dx%d", U8_DEFAULT_SCREEN_WIDTH, U8_DEFAULT_SCREEN_HEIGHT);
+ new_screen = RenderSurface::SetVideoMode(U8_DEFAULT_SCREEN_WIDTH, U8_DEFAULT_SCREEN_HEIGHT);
}
if (!new_screen) {
More information about the Scummvm-git-logs
mailing list