aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/image_file.cpp3
-rw-r--r--engines/sherlock/objects.cpp17
-rw-r--r--engines/sherlock/objects.h7
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp19
-rw-r--r--engines/sherlock/scene.cpp66
-rw-r--r--engines/sherlock/scene.h2
-rw-r--r--engines/sherlock/sherlock.cpp1
7 files changed, 87 insertions, 28 deletions
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index 95f34dc24b..342e5ee4e3 100644
--- a/engines/sherlock/image_file.cpp
+++ b/engines/sherlock/image_file.cpp
@@ -244,11 +244,14 @@ void ImageFile3DO::setVm(SherlockEngine *vm) {
}
ImageFile3DO::ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType) {
+#if 0
Common::File *dataStream = new Common::File();
if (!dataStream->open(name)) {
error("unable to open %s\n", name.c_str());
}
+#endif
+ Common::SeekableReadStream *dataStream = _vm->_res->load(name);
switch(imageFile3DOType) {
case kImageFile3DOType_Animation:
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 8e75ce7336..cbc3cbde07 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -1503,14 +1503,14 @@ const Common::Rect Object::getOldBounds() const {
/*----------------------------------------------------------------*/
-void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo, uint32 dataOffset) {
char buffer[12];
s.read(buffer, 12);
_name = Common::String(buffer);
if (isRoseTattoo) {
Common::fill(&_sequences[0], &_sequences[30], 0);
- _size = s.readUint32LE();
+ _dataSize = s.readUint32LE();
} else {
s.read(_sequences, 30);
}
@@ -1522,7 +1522,7 @@ void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
_flags = s.readByte();
_scaleVal = s.readSint16LE();
} else {
- _size = s.readUint32LE();
+ _dataSize = s.readUint32LE();
_type = (SpriteType)s.readUint16LE();
_flags = s.readByte();
}
@@ -1557,13 +1557,20 @@ void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
_teleport[0].x = _teleport[0].x * FIXED_INT_MULTIPLIER / 100;
_teleport[0].y = _teleport[0].y * FIXED_INT_MULTIPLIER / 100;
}
+
+ // Save offset of data, which is actually inside another table inside the room data file
+ // This table is at offset 44 for Serrated Scalpel
+ // TODO: find it for the other game
+ _dataOffset = dataOffset;
}
-void CAnim::load3DO(Common::SeekableReadStream &s) {
+void CAnim::load3DO(Common::SeekableReadStream &s, uint32 dataOffset) {
// this got reordered on 3DO
// maybe it was the 3DO compiler
- _size = s.readUint32BE();
+ _dataSize = s.readUint32BE();
+ // Save offset of data, which is inside another table inside the room data file
+ _dataOffset = dataOffset;
_position.x = s.readSint16BE();
_position.y = s.readSint16BE();
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index 935b4b3cb2..6a71166ee9 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -444,7 +444,8 @@ public:
struct CAnim {
Common::String _name; // Name
Common::Point _position; // Position
- int _size; // Size of uncompressed animation
+ int _dataSize; // Size of uncompressed animation data
+ uint32 _dataOffset; // offset within room file of animation data
int _flags; // Tells if can be walked behind
PositionFacing _goto[2]; // Position Holmes (and NPC in Rose Tattoo) should walk to before anim starts
PositionFacing _teleport[2]; // Location Holmes (and NPC) shoul teleport to after playing canim
@@ -459,8 +460,8 @@ struct CAnim {
/**
* Load the data for the animation
*/
- void load(Common::SeekableReadStream &s, bool isRoseTattoo);
- void load3DO(Common::SeekableReadStream &s);
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo, uint32 dataOffset);
+ void load3DO(Common::SeekableReadStream &s, uint32 dataOffset);
};
class CAnimStream {
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index 813e4188ae..c4da8e09a0 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -568,21 +568,26 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
Common::String fname = cAnim._name + ".vgs";
if (!res.isInCache(fname)) {
// Set up RRM scene data
- Common::SeekableReadStream *rrmStream = res.load(_rrmName);
- rrmStream->seek(44 + cAnimNum * 4);
- rrmStream->seek(rrmStream->readUint32LE());
+ Common::SeekableReadStream *roomStream = res.load(_roomFilename);
+ roomStream->seek(cAnim._dataOffset);
+ //rrmStream->seek(44 + cAnimNum * 4);
+ //rrmStream->seek(rrmStream->readUint32LE());
// Load the canimation into the cache
- Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) :
- Resources::decompressLZ(*rrmStream, cAnim._size);
+ Common::SeekableReadStream *imgStream = !_lzwMode ? roomStream->readStream(cAnim._dataSize) :
+ Resources::decompressLZ(*roomStream, cAnim._dataSize);
res.addToCache(fname, *imgStream);
delete imgStream;
- delete rrmStream;
+ delete roomStream;
}
// Now load the resource as an image
- cObj._images = new ImageFile(fname);
+ if (_vm->getPlatform() != Common::kPlatform3DO) {
+ cObj._images = new ImageFile(fname);
+ } else {
+ cObj._images = new ImageFile3DO(fname, kImageFile3DOType_RoomFormat);
+ }
cObj._imageFrame = &(*cObj._images)[0];
cObj._maxFrames = cObj._images->size();
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index da7f088a06..760307f31a 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -310,7 +310,7 @@ bool Scene::loadScene(const Common::String &filename) {
if (_vm->getPlatform() != Common::kPlatform3DO) {
// PC version
Common::String roomFilename = filename + ".rrm";
- _rrmName = roomFilename;
+ _roomFilename = roomFilename;
flag = _vm->_res->exists(roomFilename);
if (flag) {
@@ -464,17 +464,42 @@ bool Scene::loadScene(const Common::String &filename) {
_cAnim.clear();
if (bgHeader._numcAnimations) {
int animSize = IS_SERRATED_SCALPEL ? 65 : 47;
- Common::SeekableReadStream *canimStream = _lzwMode ?
+ Common::SeekableReadStream *cAnimStream = _lzwMode ?
res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
rrmStream->readStream(animSize * bgHeader._numcAnimations);
+ // Load cAnim offset table as well
+ uint32 *cAnimOffsetTablePtr = new uint32[bgHeader._numcAnimations];
+ uint32 *cAnimOffsetPtr = cAnimOffsetTablePtr;
+ memset(cAnimOffsetTablePtr, 0, bgHeader._numcAnimations);
+ if (IS_SERRATED_SCALPEL) {
+ // Save current stream offset
+ int32 curOffset = rrmStream->pos();
+ rrmStream->seek(44); // Seek to cAnim-Offset-Table
+ for (uint16 curCAnim = 0; curCAnim < bgHeader._numcAnimations; curCAnim++) {
+ *cAnimOffsetPtr = rrmStream->readUint32LE();
+ cAnimOffsetPtr++;
+ }
+ // Seek back to original stream offset
+ rrmStream->seek(curOffset);
+ }
+ // TODO: load offset table for Rose Tattoo as well
+
+ // Go to the start of the cAnimOffsetTable
+ cAnimOffsetPtr = cAnimOffsetTablePtr;
+
_cAnim.resize(bgHeader._numcAnimations);
- for (uint idx = 0; idx < _cAnim.size(); ++idx)
- _cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx) {
+ _cAnim[idx].load(*cAnimStream, IS_ROSE_TATTOO, *cAnimOffsetPtr);
+ cAnimOffsetPtr++;
+ }
- delete canimStream;
+ delete cAnimStream;
+ delete cAnimOffsetTablePtr;
}
+
+
// Read in the room bounding areas
int size = rrmStream->readUint16LE();
Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
@@ -579,12 +604,12 @@ bool Scene::loadScene(const Common::String &filename) {
} else {
// === 3DO version ===
- Common::String roomFilename = "rooms/" + filename + ".rrm";
- flag = _vm->_res->exists(roomFilename);
+ _roomFilename = "rooms/" + filename + ".rrm";
+ flag = _vm->_res->exists(_roomFilename);
if (!flag)
error("loadScene: 3DO room data file not found");
- Common::SeekableReadStream *roomStream = _vm->_res->load(roomFilename);
+ Common::SeekableReadStream *roomStream = _vm->_res->load(_roomFilename);
// Read 3DO header
roomStream->skip(4); // UINT32: offset graphic data?
@@ -690,13 +715,30 @@ bool Scene::loadScene(const Common::String &filename) {
_cAnim.clear();
if (header3DO_numAnimations) {
roomStream->seek(header3DO_cAnim_offset);
- Common::SeekableReadStream *canimStream = roomStream->readStream(header3DO_cAnim_size);
+ Common::SeekableReadStream *cAnimStream = roomStream->readStream(header3DO_cAnim_size);
+
+ uint32 *cAnimOffsetTablePtr = new uint32[header3DO_numAnimations];
+ uint32 *cAnimOffsetPtr = cAnimOffsetTablePtr;
+ memset(cAnimOffsetTablePtr, 0, header3DO_numAnimations);
+
+ // Seek to end of graphics data and load cAnim offset table from there
+ roomStream->seek(header3DO_bgGraphicData_offset + header3DO_bgGraphicData_size);
+ for (uint16 curCAnim = 0; curCAnim < header3DO_numAnimations; curCAnim++) {
+ *cAnimOffsetPtr = roomStream->readUint32BE();
+ cAnimOffsetPtr++;
+ }
+
+ // Go to the start of the cAnimOffsetTable
+ cAnimOffsetPtr = cAnimOffsetTablePtr;
_cAnim.resize(header3DO_numAnimations);
- for (uint idx = 0; idx < _cAnim.size(); ++idx)
- _cAnim[idx].load3DO(*canimStream);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx) {
+ _cAnim[idx].load3DO(*cAnimStream, *cAnimOffsetPtr);
+ cAnimOffsetPtr++;
+ }
- delete canimStream;
+ delete cAnimStream;
+ delete cAnimOffsetTablePtr;
}
// === BOUNDING AREAS === Read in the room bounding areas
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index a3542026e6..8c428659ae 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -165,7 +165,7 @@ private:
void saveSceneStatus();
protected:
SherlockEngine *_vm;
- Common::String _rrmName;
+ Common::String _roomFilename;
/**
* Loads the data associated for a given scene. The room resource file's format is:
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index bc150cae92..9c397e3794 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -78,6 +78,7 @@ void SherlockEngine::initialize() {
DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging");
ImageFile::setVm(this);
+ ImageFile3DO::setVm(this);
Object::setVm(this);
Sprite::setVm(this);