aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-07-03 01:24:50 +0000
committerMax Horn2003-07-03 01:24:50 +0000
commita0133fdbc61fb54f5d5e373490ad53858faafb6f (patch)
treec07d8f1d5aa6806cb92d9307f41229cbfe1df0d5
parent6598673ac3030ee5c1d0c9018a5c46749d244e57 (diff)
downloadscummvm-rg350-a0133fdbc61fb54f5d5e373490ad53858faafb6f.tar.gz
scummvm-rg350-a0133fdbc61fb54f5d5e373490ad53858faafb6f.tar.bz2
scummvm-rg350-a0133fdbc61fb54f5d5e373490ad53858faafb6f.zip
code transformation on setScaleItem: this shows that rtScaleTable's are actually (almost) the same as scale slots in V8.
svn-id: r8719
-rw-r--r--scumm/script_v6.cpp1
-rw-r--r--scumm/scummvm.cpp54
2 files changed, 34 insertions, 21 deletions
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index e2a65615c0..64bed83975 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -2502,6 +2502,7 @@ void Scumm_v6::o6_kernelSetFunctions() {
case 20:
// Occurs in The Dig, at the alien pyramid. See bug #742979.
// Also occurs in the first scene of The Dig.
+ // Maybe this corresponds to setBoxScaleSlot from V8 ?!
warning("o6_kernelSetFunctions: stub20(%d, %d)", args[1], args[2]);
break;
case 107:
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index a663efa91a..ef5221225a 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -1581,22 +1581,23 @@ void Scumm::initRoomSubBlocks() {
ptr = findResourceData(MKID('SCAL'), roomptr);
if (ptr) {
offs = ptr - roomptr;
+ int s1, s2, y1, y2;
if (_version == 8) {
for (i = 1; i < _maxScaleTable; i++, offs += 16) {
- int scale1 = READ_LE_UINT32(roomptr + offs);
- int y1 = READ_LE_UINT32(roomptr + offs + 4);
- int scale2 = READ_LE_UINT32(roomptr + offs + 8);
- int y2 = READ_LE_UINT32(roomptr + offs + 12);
- setScaleSlot(i, 0, y1, scale1, 0, y2, scale2);
+ s1 = READ_LE_UINT32(roomptr + offs);
+ y1 = READ_LE_UINT32(roomptr + offs + 4);
+ s2 = READ_LE_UINT32(roomptr + offs + 8);
+ y2 = READ_LE_UINT32(roomptr + offs + 12);
+ setScaleSlot(i, 0, y1, s1, 0, y2, s2);
}
} else {
for (i = 1; i < _maxScaleTable; i++, offs += 8) {
- int a = READ_LE_UINT16(roomptr + offs);
- int b = READ_LE_UINT16(roomptr + offs + 2);
- int c = READ_LE_UINT16(roomptr + offs + 4);
- int d = READ_LE_UINT16(roomptr + offs + 6);
- if (a || b || c || d) {
- setScaleItem(i, b, a, d, c);
+ s1 = READ_LE_UINT16(roomptr + offs);
+ y1 = READ_LE_UINT16(roomptr + offs + 2);
+ s2 = READ_LE_UINT16(roomptr + offs + 4);
+ y2 = READ_LE_UINT16(roomptr + offs + 6);
+ if (s1 || y1 || s2 || y2) {
+ setScaleItem(i, y1, s1, y2, s2);
roomptr = getResourceAddress(rtRoom, _roomResource);
}
}
@@ -1739,26 +1740,37 @@ void Scumm::initRoomSubBlocks() {
initBGBuffers(_roomHeight);
}
-void Scumm::setScaleItem(int slot, int a, int b, int c, int d) {
+/*
+ FIXME: It seems that scale items and scale slots are the same thing after
+ all - they only differ in some details (scale item is used to precompute
+ a scale table, while for the scale slots the computations are done on the
+ fly; also for scale slots, the scale along the x axis can vary, too).
+
+ Now, there are various known scale glitches in FT (and apparently also
+ in The Dig, see FIXME comments in Actor::setupActorScale). In this context
+ it is very interesting that for V5, there is an opcode which invokes
+ setScaleItem, and for V8 one that invokes setScaleSlot. But there is no
+ such opcode to be found for V6/V7 games.
+
+ Hypothesis: we simple are missing this opcode, and implementing it might
+ fix some or all of the Dig/FT scaling issues.
+*/
+void Scumm::setScaleItem(int slot, int y1, int scale1, int y2, int scale2) {
byte *ptr;
- int cur, amounttoadd, i, tmp;
+ int y, tmp;
- ptr = createResource(rtScaleTable, slot, 200);
-
- if (a == c)
+ if (y1 == y2)
return;
- cur = (b - d) * a;
- amounttoadd = d - b;
+ ptr = createResource(rtScaleTable, slot, 200);
- for (i = 200; i > 0; i--) {
- tmp = cur / (c - a) + b;
+ for (y = 0; y < 200; y++) {
+ tmp = ((scale2 - scale1) * (y - y1)) / (y2 - y1) + scale1;
if (tmp < 1)
tmp = 1;
if (tmp > 255)
tmp = 255;
*ptr++ = tmp;
- cur += amounttoadd;
}
}