[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