aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-01-13 01:29:45 +0000
committerMax Horn2003-01-13 01:29:45 +0000
commiteb9726c4974111ac56bbc256658785f06d4df531 (patch)
treeed335402a935d3f49c80675f752a4d1bad1201cd
parent1f88542417b58ce2e71708217f17ebcc7de78c20 (diff)
downloadscummvm-rg350-eb9726c4974111ac56bbc256658785f06d4df531.tar.gz
scummvm-rg350-eb9726c4974111ac56bbc256658785f06d4df531.tar.bz2
scummvm-rg350-eb9726c4974111ac56bbc256658785f06d4df531.zip
added V8 scaling code
svn-id: r6440
-rw-r--r--scumm/actor.cpp30
-rw-r--r--scumm/boxes.cpp55
-rw-r--r--scumm/saveload.cpp13
-rw-r--r--scumm/saveload.h19
-rw-r--r--scumm/script_v8.cpp1
-rw-r--r--scumm/scumm.h14
-rw-r--r--scumm/scummvm.cpp23
7 files changed, 118 insertions, 37 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
index 18e7d32f80..2066f01500 100644
--- a/scumm/actor.cpp
+++ b/scumm/actor.cpp
@@ -354,7 +354,6 @@ int Actor::actorWalkStep()
void Actor::setupActorScale()
{
uint16 scale;
- byte *resptr;
if (_vm->_features & GF_NO_SCALLING) {
scalex = 0xFF;
@@ -368,20 +367,7 @@ void Actor::setupActorScale()
if (_vm->getBoxFlags(walkbox) & kBoxPlayerOnly)
return;
- scale = _vm->getBoxScale(walkbox);
-
- if (scale & 0x8000) {
- scale = (scale & 0x7FFF) + 1;
- resptr = _vm->getResourceAddress(rtScaleTable, scale);
- if (resptr == NULL)
- error("Scale table %d not defined", scale);
- int theY = y;
- if (theY >= _vm->_realHeight)
- theY = _vm->_realHeight - 1;
- else if (theY < 0)
- theY = 0;
- scale = resptr[theY];
- }
+ scale = _vm->getScale(walkbox, x, y);
// FIXME - Hack for The Dig 'Tomb' (room 88)
// Otherwise walking to the far-left door causes the actor
@@ -400,15 +386,21 @@ void Actor::setupActorScale()
// When standing at the bottom of the ladder, Ben's Y position is
// 356, and by the looks of it he ought to be unscaled there.
- if (scale == 1 && _vm->_currentRoom == 76) {
+ if (_vm->_gameId == GID_FT && scale == 1 && _vm->_currentRoom == 76) {
scale = 0xff;
if (y < 356)
scale -= 2 * (356 - y);
}
- if (scale > 255)
- warning("Actor %d at %d, scale %d out of range", number, y, scale);
-
+ if (scale > 255) {
+ if (_vm->_features & GF_AFTER_V8) {
+ // In COMI, the scale values often are bigger than 255;
+ // however, the original engine seems to just cap them at 255,
+ // hence we do the same (the result looks correct, too);
+ scale = 255;
+ } else
+ warning("Actor %d at %d, scale %d out of range", number, y, scale);
+ }
scalex = (byte)scale;
scaley = (byte)scale;
}
diff --git a/scumm/boxes.cpp b/scumm/boxes.cpp
index a22d5c5ee0..c57ca1e27e 100644
--- a/scumm/boxes.cpp
+++ b/scumm/boxes.cpp
@@ -50,7 +50,7 @@ struct Box { /* Internal walkbox file format */
int32 llx, lly;
uint32 mask; // FIXME - is 'mask' really here?
uint32 flags; // FIXME - is 'flags' really here?
- uint32 unk1;
+ uint32 scaleSlot;
uint32 scale;
uint32 unk2;
uint32 unk3;
@@ -128,6 +128,59 @@ void Scumm::setBoxScale(int box, int scale)
b->old.scale = TO_LE_16(scale);
}
+int Scumm::getScale(int box, int x, int y)
+{
+ Box *ptr = getBoxBaseAddr(box);
+ assert(ptr);
+
+ if (_features & GF_AFTER_V8) {
+ int slot = FROM_LE_32(ptr->v8.scaleSlot);
+ if (slot) {
+ assert(0 <= slot && slot < 20);
+ int scaleX = 0, scaleY = 0;
+ ScaleSlot &s = _scaleSlots[slot];
+
+ if (s.y1 == s.y2 && s.x1 == s.x2)
+ error("Invalid scale slot %d", slot);
+
+ if (s.y1 != s.y2) {
+ if (y < 0)
+ y = 0;
+
+ scaleY = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
+ if (s.x1 == s.x2) {
+ return scaleY;
+ }
+ }
+
+ scaleX = (s.scale2 - s.scale1) * (x - s.x1) / (s.x2 - s.x1) + s.scale1;
+
+ if (s.y1 == s.y2) {
+ return scaleX;
+ } else {
+ return (scaleX + scaleY - s.x1) / 2;
+ }
+ } else
+ return FROM_LE_32(ptr->v8.scale);
+ } else {
+ uint16 scale = FROM_LE_16(ptr->old.scale);
+
+ if (scale & 0x8000) {
+ scale = (scale & 0x7FFF) + 1;
+ byte *resptr = getResourceAddress(rtScaleTable, scale);
+ if (resptr == NULL)
+ error("Scale table %d not defined", scale);
+ if (y >= _realHeight)
+ y = _realHeight - 1;
+ else if (y < 0)
+ y = 0;
+ scale = resptr[y];
+ }
+
+ return scale;
+ }
+}
+
int Scumm::getBoxScale(int box)
{
if (_features & GF_NO_SCALLING)
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
index bf9ea4427c..d5520e828a 100644
--- a/scumm/saveload.cpp
+++ b/scumm/saveload.cpp
@@ -532,6 +532,16 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion)
MKEND()
};
+ const SaveLoadEntry scaleSlotsEntries[] = {
+ MKLINE(ScaleSlot, x1, sleUint16, VER_V13),
+ MKLINE(ScaleSlot, y1, sleUint16, VER_V13),
+ MKLINE(ScaleSlot, scale1, sleUint16, VER_V13),
+ MKLINE(ScaleSlot, x2, sleUint16, VER_V13),
+ MKLINE(ScaleSlot, y2, sleUint16, VER_V13),
+ MKLINE(ScaleSlot, scale2, sleUint16, VER_V13),
+ MKEND()
+ };
+
int i, j;
int var120Backup;
int var98Backup;
@@ -564,6 +574,9 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion)
s->saveLoadArrayOf(_string, 6, sizeof(_string[0]), stringTabEntries);
s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries);
+ if (savegameVersion >= VER_V13)
+ s->saveLoadArrayOf(_scaleSlots, 20, sizeof(_scaleSlots[0]), scaleSlotsEntries);
+
for (i = rtFirst; i <= rtLast; i++)
if (res.mode[i] == 0)
for (j = 1; j < res.num[i]; j++)
diff --git a/scumm/saveload.h b/scumm/saveload.h
index 9ac60b4eff..5934c8e154 100644
--- a/scumm/saveload.h
+++ b/scumm/saveload.h
@@ -25,14 +25,17 @@
// Support for "old" savegames (made with 2501 CVS build)
// Can be useful for other ports too :)
-#define VER_V12 12
-#define VER_V11 11
-#define VER_V10 10
-#define VER_V9 9
-#define VER_V8 8
-#define VER_V7 7
-
-#define CURRENT_VER VER_V12
+enum {
+ VER_V7 = 7,
+ VER_V8,
+ VER_V9,
+ VER_V10,
+ VER_V11,
+ VER_V12,
+ VER_V13
+};
+
+#define CURRENT_VER VER_V13
// To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types,
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
index 2bf668a240..b0fcb34ac3 100644
--- a/scumm/script_v8.cpp
+++ b/scumm/script_v8.cpp
@@ -1378,6 +1378,7 @@ void Scumm_v8::o8_kernelSetFunctions()
break;
case 21: // setScaleSlot
warning("o8_kernelSetFunctions: setScaleSlot(%d, %d, %d, %d, %d, %d, %d)", args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ setScaleSlot(args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
break;
case 22: // setBannerColors
// warning("o8_kernelSetFunctions: setBannerColors(%d, %d, %d, %d)", args[1], args[2], args[3], args[4]);
diff --git a/scumm/scumm.h b/scumm/scumm.h
index e7b6524b30..7c32b8ff99 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -378,7 +378,6 @@ public:
byte _numObjectsInRoom;
int8 _userPut;
int _resourceHeaderSize;
- void setScaleItem(int slot, int a, int b, int c, int d);
void clearClickedStatus();
void startManiac();
@@ -854,6 +853,19 @@ public:
Box *getBoxBaseAddr(int box);
byte getBoxFlags(int box);
int getBoxScale(int box);
+
+ int getScale(int box, int x, int y);
+ void setScaleItem(int slot, int a, int b, int c, int d);
+
+ // V8 scaling stuff: should be in V8 class
+ struct ScaleSlot {
+ int x1, y1, scale1;
+ int x2, y2, scale2;
+ };
+ ScaleSlot _scaleSlots[20]; // FIXME - not sure if this limit is right, but based on my observations it is
+ void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
+
+
byte getNumBoxes();
byte *getBoxMatrixBaseAddr();
int getPathToDestBox(byte from, byte to);
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index cb8f1d8cb7..63afbc2286 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -835,14 +835,11 @@ void Scumm::initRoomSubBlocks()
offs = ptr - roomptr;
if (_features & GF_AFTER_V8) {
for (i = 1; i < _maxScaleTable; i++, offs += 16) {
- int a = READ_LE_UINT32(roomptr + offs);
- int b = READ_LE_UINT32(roomptr + offs + 4);
- int c = READ_LE_UINT32(roomptr + offs + 8);
- int d = READ_LE_UINT32(roomptr + offs + 12);
- if (a || b || c || d) {
- setScaleItem(i, b, a, d, c);
- roomptr = getResourceAddress(rtRoom, _roomResource);
- }
+ 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);
}
} else {
for (i = 1; i < _maxScaleTable; i++, offs += 8) {
@@ -981,6 +978,16 @@ void Scumm::setScaleItem(int slot, int a, int b, int c, int d)
}
}
+void Scumm::setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2)
+{
+ _scaleSlots[slot].x2 = x2;
+ _scaleSlots[slot].y2 = y2;
+ _scaleSlots[slot].scale2 = scale2;
+ _scaleSlots[slot].x1 = x1;
+ _scaleSlots[slot].y1 = y1;
+ _scaleSlots[slot].scale1 = scale1;
+}
+
void Scumm::dumpResource(char *tag, int idx, byte *ptr)
{
char buf[256];