aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r--engines/sci/graphics/frameout.cpp48
-rw-r--r--engines/sci/graphics/frameout.h1
2 files changed, 47 insertions, 2 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index d33bf4c64e..dca6441e85 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -349,6 +349,36 @@ void GfxFrameout::deletePlaneLine(reg_t object, reg_t hunkId) {
}
}
+// Adapted from GfxAnimate::applyGlobalScaling()
+void GfxFrameout::applyGlobalScaling(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 celHeight) {
+ // Global scaling uses global var 2 and some other stuff to calculate scaleX/scaleY
+ int16 maxScale = readSelectorValue(_segMan, itemEntry->object, SELECTOR(maxScale));
+ int16 maxCelHeight = (maxScale * celHeight) >> 7;
+ reg_t globalVar2 = g_sci->getEngineState()->variables[VAR_GLOBAL][2]; // current room object
+ int16 vanishingY = readSelectorValue(_segMan, globalVar2, SELECTOR(vanishingY));
+
+ int16 fixedPortY = planeRect.bottom - vanishingY;
+ int16 fixedEntryY = itemEntry->y - vanishingY;
+ if (!fixedEntryY)
+ fixedEntryY = 1;
+
+ if ((celHeight == 0) || (fixedPortY == 0))
+ error("global scaling panic");
+
+ itemEntry->scaleY = (maxCelHeight * fixedEntryY) / fixedPortY;
+ itemEntry->scaleY = (itemEntry->scaleY * maxScale) / celHeight;
+
+ // Make sure that the calculated value is sane
+ if (itemEntry->scaleY < 1 /*|| itemEntry->scaleY > 128*/)
+ itemEntry->scaleY = 128;
+
+ itemEntry->scaleX = itemEntry->scaleY;
+
+ // and set objects scale selectors
+ //writeSelectorValue(_segMan, itemEntry->object, SELECTOR(scaleX), itemEntry->scaleX);
+ //writeSelectorValue(_segMan, itemEntry->object, SELECTOR(scaleY), itemEntry->scaleY);
+}
+
void GfxFrameout::kernelAddScreenItem(reg_t object) {
// Ignore invalid items
if (!_segMan->isObject(object)) {
@@ -390,8 +420,14 @@ void GfxFrameout::kernelUpdateScreenItem(reg_t object) {
itemEntry->priority = itemEntry->y;
itemEntry->signal = readSelectorValue(_segMan, object, SELECTOR(signal));
- itemEntry->scaleX = readSelectorValue(_segMan, object, SELECTOR(scaleX));
- itemEntry->scaleY = readSelectorValue(_segMan, object, SELECTOR(scaleY));
+ itemEntry->scaleSignal = readSelectorValue(_segMan, object, SELECTOR(scaleSignal));
+ if (itemEntry->scaleSignal == 1) {
+ itemEntry->scaleX = readSelectorValue(_segMan, object, SELECTOR(scaleX));
+ itemEntry->scaleY = readSelectorValue(_segMan, object, SELECTOR(scaleY));
+ } else {
+ itemEntry->scaleX = 128;
+ itemEntry->scaleY = 128;
+ }
itemEntry->visible = true;
// Check if the entry can be hidden
@@ -699,6 +735,14 @@ void GfxFrameout::kernelFrameout() {
// TODO: maybe we should clip the cels rect with this, i'm not sure
// the only currently known usage is game menu of gk1
} else if (view) {
+ // Process global scaling, if needed.
+ // TODO: Seems like SCI32 always processes global scaling for scaled objects
+ if (itemEntry->scaleSignal != 0 && itemEntry->scaleSignal != 1)
+ error("Unknown scale signal: %d", itemEntry->scaleSignal);
+ // TODO: We can only process symmetrical scaling for now (i.e. same value for scaleX/scaleY)
+ if (itemEntry->scaleSignal == 1 && itemEntry->scaleX == itemEntry->scaleY)
+ applyGlobalScaling(itemEntry, it->planeRect, view->getHeight(itemEntry->loopNo, itemEntry->celNo));
+
if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
view->getCelRect(itemEntry->loopNo, itemEntry->celNo,
itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect);
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index 5fd2824224..5dadca674d 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -113,6 +113,7 @@ public:
void kernelAddPlane(reg_t object);
void kernelUpdatePlane(reg_t object);
void kernelDeletePlane(reg_t object);
+ void applyGlobalScaling(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 celHeight);
void kernelAddScreenItem(reg_t object);
void kernelUpdateScreenItem(reg_t object);
void kernelDeleteScreenItem(reg_t object);