aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/screen_item32.cpp
diff options
context:
space:
mode:
authorColin Snover2016-06-30 21:55:29 -0500
committerColin Snover2016-07-01 15:54:27 -0500
commit6c8661d144ddf5f36b22d70169c3005f830f08d4 (patch)
tree78eabef5e57c9e2b191eb5243bfac3863a3ab62b /engines/sci/graphics/screen_item32.cpp
parentb7dcf5f6c1f560d668d3857012e98a91bcf881d4 (diff)
downloadscummvm-rg350-6c8661d144ddf5f36b22d70169c3005f830f08d4.tar.gz
scummvm-rg350-6c8661d144ddf5f36b22d70169c3005f830f08d4.tar.bz2
scummvm-rg350-6c8661d144ddf5f36b22d70169c3005f830f08d4.zip
SCI32: Fix bad rendering of subtitle backgrounds in Torin
The way dimensions of scaled screen items are calculated changed over the lifetime of SSCI. In early low-resolution and mixed-resolution games, scaled drawing needed to use at a global cadence across the entire screen to ensure proper alignment, but in later games (like Torin), local scaling of individual screen items seems to be the way scaling is performed.
Diffstat (limited to 'engines/sci/graphics/screen_item32.cpp')
-rw-r--r--engines/sci/graphics/screen_item32.cpp71
1 files changed, 54 insertions, 17 deletions
diff --git a/engines/sci/graphics/screen_item32.cpp b/engines/sci/graphics/screen_item32.cpp
index c1644a5ea3..ebaf132890 100644
--- a/engines/sci/graphics/screen_item32.cpp
+++ b/engines/sci/graphics/screen_item32.cpp
@@ -296,7 +296,30 @@ void ScreenItem::calcRects(const Plane &plane) {
}
if (!scaleX.isOne() || !scaleY.isOne()) {
- mulinc(_screenItemRect, scaleX, scaleY);
+ // Different games use a different cel scaling mode, but the
+ // difference isn't consistent across SCI versions; instead,
+ // it seems to be related to an update that happened during
+ // SCI2.1mid where games started using hi-resolution game
+ // scripts
+ if (scriptWidth == kLowResX) {
+ mulinc(_screenItemRect, scaleX, scaleY);
+ } else {
+ _screenItemRect.left = (_screenItemRect.left * scaleX).toInt();
+ _screenItemRect.top = (_screenItemRect.top * scaleY).toInt();
+
+ if (scaleX.getNumerator() > scaleX.getDenominator()) {
+ _screenItemRect.right = (_screenItemRect.right * scaleX).toInt();
+ } else {
+ _screenItemRect.right = ((_screenItemRect.right - 1) * scaleX).toInt() + 1;
+ }
+
+ if (scaleY.getNumerator() > scaleY.getDenominator()) {
+ _screenItemRect.bottom = (_screenItemRect.bottom * scaleY).toInt();
+ } else {
+ _screenItemRect.bottom = ((_screenItemRect.bottom - 1) * scaleY).toInt() + 1;
+ }
+ }
+
displaceX = (displaceX * scaleX).toInt();
displaceY = (displaceY * scaleY).toInt();
}
@@ -538,8 +561,6 @@ void ScreenItem::update() {
_celObj = nullptr;
}
-// TODO: This code is quite similar to calcRects, so try to deduplicate
-// if possible
Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
CelObj &celObj = getCelObj();
@@ -547,10 +568,7 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
Common::Rect nsRect;
if (_useInsetRect) {
- // TODO: This is weird. Checking to see if the inset rect is
- // fully inside the bounds of the celObjRect, and then
- // clipping to the celObjRect, is pretty useless.
- if (_insetRect.right > 0 && _insetRect.bottom > 0 && _insetRect.left < celObj._width && _insetRect.top < celObj._height) {
+ if (_insetRect.intersects(celObjRect)) {
nsRect = _insetRect;
nsRect.clip(celObjRect);
} else {
@@ -594,10 +612,7 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
Ratio scriptToCelY(celObj._scaledHeight, scriptHeight);
mulru(nsRect, scriptToCelX, scriptToCelY, 0);
- // TODO: This is weird. Checking to see if the inset rect is
- // fully inside the bounds of the celObjRect, and then
- // clipping to the celObjRect, is pretty useless.
- if (nsRect.right > 0 && nsRect.bottom > 0 && nsRect.left < celObj._width && nsRect.top < celObj._height) {
+ if (nsRect.intersects(celObjRect)) {
nsRect.clip(celObjRect);
} else {
nsRect = Common::Rect();
@@ -605,12 +620,34 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
}
if (!scaleX.isOne() || !scaleY.isOne()) {
- mulinc(nsRect, scaleX, scaleY);
- // TODO: This was in the original code, baked into the
- // multiplication though it is not immediately clear
- // why this is the only one that reduces the BR corner
- nsRect.right -= 1;
- nsRect.bottom -= 1;
+ // Different games use a different cel scaling mode, but the
+ // difference isn't consistent across SCI versions; instead,
+ // it seems to be related to an update that happened during
+ // SCI2.1mid where games started using hi-resolution game
+ // scripts
+ if (scriptWidth == kLowResX) {
+ mulinc(nsRect, scaleX, scaleY);
+ // TODO: This was in the original code, baked into the
+ // multiplication though it is not immediately clear
+ // why this is the only one that reduces the BR corner
+ nsRect.right -= 1;
+ nsRect.bottom -= 1;
+ } else {
+ nsRect.left = (nsRect.left * scaleX).toInt();
+ nsRect.top = (nsRect.top * scaleY).toInt();
+
+ if (scaleX.getNumerator() > scaleX.getDenominator()) {
+ nsRect.right = (nsRect.right * scaleX).toInt();
+ } else {
+ nsRect.right = ((nsRect.right - 1) * scaleX).toInt() + 1;
+ }
+
+ if (scaleY.getNumerator() > scaleY.getDenominator()) {
+ nsRect.bottom = (nsRect.bottom * scaleY).toInt();
+ } else {
+ nsRect.bottom = ((nsRect.bottom - 1) * scaleY).toInt() + 1;
+ }
+ }
}
Ratio celToScriptX(scriptWidth, celObj._scaledWidth);