[Scummvm-git-logs] scummvm master -> 9c5ddedf4de216b9331170cc100ca05f3df8352f

OMGPizzaGuy noreply at scummvm.org
Sat Nov 12 00:43:29 UTC 2022


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
9c5ddedf4d ULTIMA8: Improve mini map gump rendering


Commit: 9c5ddedf4de216b9331170cc100ca05f3df8352f
    https://github.com/scummvm/scummvm/commit/9c5ddedf4de216b9331170cc100ca05f3df8352f
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-11-11T18:43:14-06:00

Commit Message:
ULTIMA8: Improve mini map gump rendering

The mini map gump now attempts a second color sample for a point if the first item failed to sample. The minimap surface now has an alpha channel to distinguish between sampled black pixels and unsampled transparent pixels.

Changed paths:
    engines/ultima/ultima8/gumps/minimap_gump.cpp
    engines/ultima/ultima8/gumps/minimap_gump.h


diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index ea95684ede4..a95f81d685f 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -27,6 +27,7 @@
 #include "ultima/ultima8/graphics/render_surface.h"
 #include "ultima/ultima8/graphics/palette.h"
 #include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/world/item_sorter.h"
 
 namespace Ultima {
 namespace Ultima8 {
@@ -39,11 +40,13 @@ static const int MINMAPGUMP_SCALE = 8;
 MiniMapGump::MiniMapGump(int x, int y) :
 	Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
 	     FLAG_DRAGGABLE, LAYER_NORMAL), _minimap(), _lastMapNum(0) {
-	_minimap = Graphics::ManagedSurface((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
-										RenderSurface::getPixelFormat());
+	_minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
+		Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 }
 
 MiniMapGump::MiniMapGump() : Gump() , _lastMapNum(0){
+	_minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
+		Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 }
 
 MiniMapGump::~MiniMapGump(void) {
@@ -57,8 +60,8 @@ void MiniMapGump::run() {
 	int mapChunkSize = currentmap->getChunkSize();
 
 	if (currentmap->getNum() != _lastMapNum) {
-		_minimap.fillRect(Common::Rect(0, 0, _minimap.w, _minimap.h), 0);
 		_lastMapNum = currentmap->getNum();
+		_minimap.clear();
 	}
 
 	// Draw into the map surface
@@ -66,13 +69,14 @@ void MiniMapGump::run() {
 		for (int xv = 0; xv < MAP_NUM_CHUNKS; xv++) {
 			if (currentmap->isChunkFast(xv, yv)) {
 				for (int j = 0; j < MINMAPGUMP_SCALE; j++) for (int i = 0; i < MINMAPGUMP_SCALE; i++) {
-					uint32 val = _minimap.getPixel(xv * MINMAPGUMP_SCALE + i, yv * MINMAPGUMP_SCALE + j);
+					int x = xv * MINMAPGUMP_SCALE + i;
+					int y = yv * MINMAPGUMP_SCALE + j;
+					uint32 val = _minimap.getPixel(x, y);
 					if (val == 0) {
-						val = sampleAtPoint(
+						val = sampleAtPoint(currentmap,
 							xv * mapChunkSize + mapChunkSize / (MINMAPGUMP_SCALE * 2) + (mapChunkSize * i) / MINMAPGUMP_SCALE,
-							yv * mapChunkSize + mapChunkSize / (MINMAPGUMP_SCALE * 2) + (mapChunkSize * j) / MINMAPGUMP_SCALE,
-							currentmap);
-						_minimap.setPixel(xv * MINMAPGUMP_SCALE + i, yv * MINMAPGUMP_SCALE + j, val);
+							yv * mapChunkSize + mapChunkSize / (MINMAPGUMP_SCALE * 2) + (mapChunkSize * j) / MINMAPGUMP_SCALE);
+						_minimap.setPixel(x, y, val);
 					}
 				}
 			}
@@ -86,10 +90,17 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
 	int mapChunkSize = currentmap->getChunkSize();
 
 	// Draw the yellow border
-	surf->Fill32(0xFFFFAF00, 0, 0, MAP_NUM_CHUNKS * 2 + 3, 1);
-	surf->Fill32(0xFFFFAF00, 0, 1, 1, MAP_NUM_CHUNKS * 2 + 1);
-	surf->Fill32(0xFFFFAF00, 1, MAP_NUM_CHUNKS * 2 + 1, MAP_NUM_CHUNKS * 2 + 1, 1);
-	surf->Fill32(0xFFFFAF00, MAP_NUM_CHUNKS * 2 + 1, 1, 1, MAP_NUM_CHUNKS * 2 + 1);
+	surf->Fill32(0xFFFFAF00, 0, 0, _dims.width(), 1);
+	surf->Fill32(0xFFFFAF00, 0, 1, 1, _dims.height());
+	surf->Fill32(0xFFFFAF00, 1, _dims.bottom - 1, _dims.width(), 1);
+	surf->Fill32(0xFFFFAF00, _dims.right - 1, 1, 1, _dims.height());
+
+	// Dimensions minus border
+	Rect dims = _dims;
+	dims.grow(-1);
+
+	// Fill the background
+	surf->Fill32(0xFF000000, dims.left, dims.top, dims.width(), dims.height());
 
 	// Center on avatar
 	int sx = 0, sy = 0, ox = 0, oy = 0, lx = 0, ly = 0;
@@ -108,78 +119,92 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
 
 	if (sx < 0) {
 		ox = -sx;
-		surf->Fill32(0, 1, 1, ox, MAP_NUM_CHUNKS * 2);
-	} else if ((sx + MAP_NUM_CHUNKS * 2) > (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE)) {
-		lx = (sx + MAP_NUM_CHUNKS * 2) - (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE);
-		surf->Fill32(0, 1 + (MAP_NUM_CHUNKS * 2) - lx, 1, lx, MAP_NUM_CHUNKS * 2);
+	} else if ((sx + dims.width()) > _minimap.w) {
+		lx = (sx + dims.width()) - _minimap.w;
 	}
 
 	if (sy < 0) {
 		oy = -sy;
-		surf->Fill32(0, 1, 1, MAP_NUM_CHUNKS * 2, oy);
-	} else if ((sy + MAP_NUM_CHUNKS * 2) > (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE)) {
-		ly = (sy + MAP_NUM_CHUNKS * 2) - (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE);
-		surf->Fill32(0, 1, 1 + (MAP_NUM_CHUNKS * 2) - ly, MAP_NUM_CHUNKS * 2, ly);
+	} else if ((sy + dims.height()) > _minimap.h) {
+		ly = (sy + dims.height()) - _minimap.h;
 	}
 
-	surf->Blit(&_minimap, sx + ox, sy + oy, MAP_NUM_CHUNKS * 2 - (ox + lx), MAP_NUM_CHUNKS * 2 - (oy + ly), 1 + ox, 1 + oy);
+	surf->Blit(&_minimap, sx + ox, sy + oy, dims.width() - (ox + lx), dims.height() - (oy + ly), 1 + ox, 1 + oy);
 
+	// Paint the avatar position marker
 	surf->Fill32(0xFFFFFF00, 1 + ax - 2, 1 + ay + 0, 2, 1);
 	surf->Fill32(0xFFFFFF00, 1 + ax + 0, 1 + ay - 2, 1, 2);
 	surf->Fill32(0xFFFFFF00, 1 + ax + 1, 1 + ay + 0, 2, 1);
 	surf->Fill32(0xFFFFFF00, 1 + ax + 0, 1 + ay + 1, 1, 2);
 }
 
-uint32 MiniMapGump::sampleAtPoint(int x, int y, CurrentMap *currentmap) {
+uint32 MiniMapGump::sampleAtPoint(CurrentMap *currentmap, int x, int y) {
+	uint32 val = 0;
 	const Item *item = currentmap->traceTopItem(x, y, 1 << 15, -1, 0, ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
-
 	if (item) {
-		int32 ix, iy, iz, idx, idy, idz;
-		item->getLocation(ix, iy, iz);
-		item->getFootpadWorld(idx, idy, idz);
-
-		ix -= x;
-		iy -= y;
-
-		const Shape *sh = item->getShapeObject();
-		if (!sh)
-			return 0;
-
-		const ShapeFrame *frame = sh->getFrame(item->getFrame());
-		if (!frame)
-			return 0;
-
-		const Palette *pal = sh->getPalette();
-		if (!pal)
-			return 0;
-
-		// Screenspace bounding box bottom x_ coord (RNB x_ coord)
-		int sx = (ix - iy) / 4;
-		// Screenspace bounding box bottom extent  (RNB y_ coord)
-		int sy = (ix + iy) / 8 + idz;
-
-		uint16 r = 0, g = 0, b = 0, c = 0;
-
-		for (int j = 0; j < 2; j++) {
-			for (int i = 0; i < 2; i++) {
-				if (!frame->hasPoint(i - sx, j - sy)) continue;
-
-				byte r2, g2, b2;
-				UNPACK_RGB8(pal->_native_untransformed[frame->getPixelAtPoint(i - sx, j - sy)], r2, g2, b2);
-				r += RenderSurface::_gamma22toGamma10[r2];
-				g += RenderSurface::_gamma22toGamma10[g2];
-				b += RenderSurface::_gamma22toGamma10[b2];
-				c++;
+		val = sampleAtPoint(item, x, y);
+		if (val == 0) {
+			item = currentmap->traceTopItem(x, y, 1 << 15, -1, item->getObjId(), ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
+			if (item) {
+				val = sampleAtPoint(item, x, y);
 			}
 		}
 
-		if (!c)
-			return 0;
+		if (val == 0) {
+			// set to avoid reprocessing
+			val = _minimap.format.RGBToColor(0x00, 0x00, 0x00);
+		}
+	}
+	return val;
+}
+
+
+uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y)
+{
+	int32 ix, iy, iz, idx, idy, idz;
+	item->getLocation(ix, iy, iz);
+	item->getFootpadWorld(idx, idy, idz);
+
+	ix -= x;
+	iy -= y;
+
+	const Shape *sh = item->getShapeObject();
+	if (!sh)
+		return 0;
 
-		return PACK_RGB8(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
-	} else {
+	const ShapeFrame *frame = sh->getFrame(item->getFrame());
+	if (!frame)
 		return 0;
+
+	const Palette *pal = sh->getPalette();
+	if (!pal)
+		return 0;
+
+	// Screenspace bounding box bottom x_ coord (RNB x_ coord)
+	int sx = (ix - iy) / 4;
+	// Screenspace bounding box bottom extent  (RNB y_ coord)
+	int sy = (ix + iy) / 8 + idz;
+
+	uint16 r = 0, g = 0, b = 0, c = 0;
+
+	for (int j = 0; j < 2; j++) {
+		for (int i = 0; i < 2; i++) {
+			if (!frame->hasPoint(i - sx, j - sy)) continue;
+
+			byte r2, g2, b2;
+			UNPACK_RGB8(pal->_native_untransformed[frame->getPixelAtPoint(i - sx, j - sy)], r2, g2, b2);
+			r += RenderSurface::_gamma22toGamma10[r2];
+			g += RenderSurface::_gamma22toGamma10[g2];
+			b += RenderSurface::_gamma22toGamma10[b2];
+			c++;
+		}
 	}
+
+	if (c > 0) {
+		return _minimap.format.RGBToColor(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
+	}
+
+	return 0;
 }
 
 void MiniMapGump::saveData(Common::WriteStream *ws) {
@@ -191,7 +216,7 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
 		return false;
 
 	_lastMapNum = 0;
-	_minimap.create(MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, RenderSurface::getPixelFormat());
+	_minimap.clear();
 
 	return true;
 }
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.h b/engines/ultima/ultima8/gumps/minimap_gump.h
index 63f41524f55..18ffbdb54c1 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.h
+++ b/engines/ultima/ultima8/gumps/minimap_gump.h
@@ -35,7 +35,8 @@ private:
 	Graphics::ManagedSurface _minimap;
 	unsigned int        _lastMapNum;
 
-	uint32 sampleAtPoint(int x, int y, CurrentMap *map);
+	uint32 sampleAtPoint(CurrentMap *map, int x, int y);
+	uint32 sampleAtPoint(const Item *item, int x, int y);
 public:
 	ENABLE_RUNTIME_CLASSTYPE()
 




More information about the Scummvm-git-logs mailing list