[Scummvm-git-logs] scummvm master -> 4ecfa0c2170d8376fe09bdcdb698fb2ee919430f

sluicebox 22204938+sluicebox at users.noreply.github.com
Sun Dec 20 06:33:14 UTC 2020


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

Summary:
4ecfa0c217 SCI: Implement SCI 1.1 view scaling algorithm


Commit: 4ecfa0c2170d8376fe09bdcdb698fb2ee919430f
    https://github.com/scummvm/scummvm/commit/4ecfa0c2170d8376fe09bdcdb698fb2ee919430f
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2020-12-19T22:31:38-08:00

Commit Message:
SCI: Implement SCI 1.1 view scaling algorithm

Replaces a home-made scaling algorithm with Sierra's algorithm.
Views should now be scaled the same as in the original interpreter.
Discrepancies were particularly noticeable when scaling down.

Examples:
ego in KQ6 after entering room 210 from 240.
ego in LSL6 after entering room 860 from 230.

Changed paths:
    engines/sci/graphics/view.cpp
    engines/sci/graphics/view.h


diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 4c6e093d53..ab44dc5c4f 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -868,11 +868,6 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
 	_screen->setCurPaletteMapValue(oldpalvalue);
 }
 
-/**
- * We don't fully follow sierra sci here, I did the scaling algo myself and it
- * is definitely not pixel-perfect with the one sierra is using. It shouldn't
- * matter because the scaled cel rect is definitely the same as in sierra sci.
- */
 void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect, const Common::Rect &clipRectTranslated,
 			int16 loopNo, int16 celNo, byte priority, int16 scaleX, int16 scaleY, uint16 scaleSignal) {
 	const Palette *palette = _embeddedPal ? &_viewPalette : &_palette->_sysPalette;
@@ -882,64 +877,21 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect,
 	const int16 celWidth = celInfo->width;
 	const byte clearKey = celInfo->clearKey;
 	const byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
-	uint16 scalingX[640];
-	uint16 scalingY[480];
-	int16 scaledWidth, scaledHeight;
-	int pixelNo, scaledPixel, scaledPixelNo, prevScaledPixelNo;
 
 	if (_embeddedPal)
 		// Merge view palette in...
 		_palette->set(&_viewPalette, false);
 
-	scaledWidth = (celInfo->width * scaleX) >> 7;
-	scaledHeight = (celInfo->height * scaleY) >> 7;
-	scaledWidth = CLIP<int16>(scaledWidth, 0, _screen->getWidth());
-	scaledHeight = CLIP<int16>(scaledHeight, 0, _screen->getHeight());
-
-	// Do we really need to do this?!
-	//memset(scalingX, 0, sizeof(scalingX));
-	//memset(scalingY, 0, sizeof(scalingY));
-
-	// Create height scaling table
-	pixelNo = 0;
-	scaledPixel = scaledPixelNo = prevScaledPixelNo = 0;
-	while (pixelNo < celHeight) {
-		scaledPixelNo = scaledPixel >> 7;
-		assert(scaledPixelNo < ARRAYSIZE(scalingY));
-		for (; prevScaledPixelNo <= scaledPixelNo; prevScaledPixelNo++)
-			scalingY[prevScaledPixelNo] = pixelNo;
-		pixelNo++;
-		scaledPixel += scaleY;
-	}
-	pixelNo--;
-	scaledPixelNo++;
-	for (; scaledPixelNo < scaledHeight; scaledPixelNo++)
-		scalingY[scaledPixelNo] = pixelNo;
-
-	// Create width scaling table
-	pixelNo = 0;
-	scaledPixel = scaledPixelNo = prevScaledPixelNo = 0;
-	while (pixelNo < celWidth) {
-		scaledPixelNo = scaledPixel >> 7;
-		assert(scaledPixelNo < ARRAYSIZE(scalingX));
-		for (; prevScaledPixelNo <= scaledPixelNo; prevScaledPixelNo++)
-			scalingX[prevScaledPixelNo] = pixelNo;
-		pixelNo++;
-		scaledPixel += scaleX;
-	}
-	pixelNo--;
-	scaledPixelNo++;
-	for (; scaledPixelNo < scaledWidth; scaledPixelNo++)
-		scalingX[scaledPixelNo] = pixelNo;
+	Common::Array<uint16> scalingX, scalingY;
+	createScalingTable(scalingX, celWidth, _screen->getWidth(), scaleX);
+	createScalingTable(scalingY, celHeight, _screen->getHeight(), scaleY);
 
-	scaledWidth = MIN(clipRect.width(), scaledWidth);
-	scaledHeight = MIN(clipRect.height(), scaledHeight);
+	int16 scaledWidth = MIN(clipRect.width(), (int16)scalingX.size());
+	int16 scaledHeight = MIN(clipRect.height(), (int16)scalingY.size());
 
 	const int16 offsetY = clipRect.top - rect.top;
 	const int16 offsetX = clipRect.left - rect.left;
 
-	assert(scaledHeight + offsetY <= ARRAYSIZE(scalingY));
-	assert(scaledWidth + offsetX <= ARRAYSIZE(scalingX));
 	const byte *bitmapData = bitmap.getUnsafeDataAt(0, celWidth * celHeight);
 	for (int y = 0; y < scaledHeight; y++) {
 		for (int x = 0; x < scaledWidth; x++) {
@@ -953,6 +905,31 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect,
 	}
 }
 
+void GfxView::createScalingTable(Common::Array<uint16> &table, int16 celSize, uint16 maxSize, int16 scale) {
+	const int16 scaledSize = (celSize * scale) >> 7;
+	const int16 clippedScaledSize = CLIP<int16>(scaledSize, 0, maxSize);
+	const int16 stepCount = scaledSize - 1;
+
+	if (stepCount <= 0) {
+		table.clear();
+		return;
+	}
+
+	uint32 acc;
+	uint32 inc = ((celSize - 1) << 16) / stepCount;
+	if ((inc & 0xffff8000) == 0) {
+		acc = 0x8000;
+	} else {
+		acc = inc & 0xffff;
+	}
+
+	table.resize(clippedScaledSize);
+	for (uint16 i = 0; i < clippedScaledSize; ++i) {
+		table[i] = acc >> 16;
+		acc += inc;
+	}
+}
+
 void GfxView::adjustToUpscaledCoordinates(int16 &y, int16 &x) {
 	_screen->adjustToUpscaledCoordinates(y, x);
 }
diff --git a/engines/sci/graphics/view.h b/engines/sci/graphics/view.h
index 76cc147586..de62b36eb0 100644
--- a/engines/sci/graphics/view.h
+++ b/engines/sci/graphics/view.h
@@ -87,6 +87,8 @@ private:
 	void unditherBitmap(SciSpan<byte> &bitmap, int16 width, int16 height, byte clearKey);
 	byte getMappedColor(byte color, uint16 scaleSignal, const Palette *palette, int x2, int y2);
 
+	static void createScalingTable(Common::Array<uint16> &table, int16 celSize, uint16 maxSize, int16 scale);
+
 	ResourceManager *_resMan;
 	GfxCoordAdjuster16 *_coordAdjuster;
 	GfxScreen *_screen;




More information about the Scummvm-git-logs mailing list