[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