aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2015-06-11 19:52:41 +0200
committerMartin Kiewitz2015-06-11 19:52:41 +0200
commit515d5422a7574971140d7b93e2db5275b5afec2f (patch)
tree56dd6588c3babef5cd5b037a004cc7517cc94f7d
parentd6ca620a7cdc6e9ba18b2f45ded3080ec186aab7 (diff)
downloadscummvm-rg350-515d5422a7574971140d7b93e2db5275b5afec2f.tar.gz
scummvm-rg350-515d5422a7574971140d7b93e2db5275b5afec2f.tar.bz2
scummvm-rg350-515d5422a7574971140d7b93e2db5275b5afec2f.zip
SHERLOCK: some work on 3DO room data
-rw-r--r--engines/sherlock/objects.cpp140
-rw-r--r--engines/sherlock/objects.h3
-rw-r--r--engines/sherlock/scene.cpp573
-rw-r--r--engines/sherlock/scene.h3
4 files changed, 537 insertions, 182 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index ce0480a7b2..80712cfe59 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -674,6 +674,27 @@ void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
_target = Common::String(buffer);
}
+void UseType::load3DO(Common::SeekableReadStream &s) {
+ char buffer[12];
+
+ _cAnimNum = s.readByte();
+ _cAnimSpeed = s.readByte();
+ if (_cAnimSpeed & 0x80)
+ _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ s.read(buffer, 12);
+ _names[idx] = Common::String(buffer);
+ }
+
+ _useFlag = s.readSint16BE();
+
+ s.skip(6);
+
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
+
/*----------------------------------------------------------------*/
SherlockEngine *Object::_vm;
@@ -781,6 +802,98 @@ void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
}
}
+void Object::load3DO(Common::SeekableReadStream &s) {
+ char buffer[41];
+
+ _examine.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+
+ // on 3DO all of this data is reordered!!!
+ s.skip(4);
+ _sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
+ s.seek(10, SEEK_CUR);
+
+ _walkCount = 0; // ??? s.readByte();
+ _allow = 0; // ??? s.readByte();
+ _frameNumber = s.readSint16BE();
+ _sequenceNumber = s.readSint16BE();
+ _position.x = s.readSint16BE();
+ _position.y = s.readSint16BE();
+ _delta.x = s.readSint16BE();
+ _delta.y = s.readSint16BE();
+ _type = (SpriteType)s.readUint16BE();
+ _oldPosition.x = s.readSint16BE();
+ _oldPosition.y = s.readSint16BE();
+ _oldSize.x = s.readUint16BE();
+ _oldSize.y = s.readUint16BE();
+
+ _goto.x = s.readSint16BE();
+ _goto.y = s.readSint16BE();
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+
+ s.skip(16); // Unknown
+
+#if 0
+ _pickup = s.readByte();
+ _defaultCommand = s.readByte();
+ _lookFlag = s.readSint16BE();
+ _pickupFlag = s.readSint16BE();
+ _requiredFlag = s.readSint16BE();
+ _noShapeSize.x = s.readUint16BE();
+ _noShapeSize.y = s.readUint16BE();
+ _status = s.readUint16BE();
+ _maxFrames = s.readUint16BE();
+
+ _aOpen.load(s);
+
+ _aType = (AType)s.readByte();
+ _lookFrames = s.readByte();
+ _seqCounter = s.readByte();
+ _lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
+ _lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
+ _lookFacing = s.readByte();
+ _lookcAnim = s.readByte();
+
+ _aClose.load(s);
+
+ _seqStack = s.readByte();
+ _seqTo = s.readByte();
+#endif
+ warning("pos %d", s.pos());
+
+ _descOffset = s.readUint16BE();
+ _seqCounter2 = 0; // ???
+ _seqSize = s.readUint16BE();
+
+ s.skip(446);
+
+#if 0
+ s.skip(1);
+ _aMove.load(s);
+ s.skip(8);
+
+ for (int idx = 0; idx < 4; ++idx)
+ _use[idx].load(s, false);
+#endif
+
+ // 3DO: name is at the end
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+ s.read(buffer, 41);
+ _description = Common::String(buffer);
+
+ s.skip(4); // Unknown
+
+ // Probably those here?!?!
+ _misc = s.readByte();
+ _flags = s.readByte();
+
+ s.skip(21); // Unknown
+}
+
void Object::toggleHidden() {
if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
if (_seqTo != 0)
@@ -1516,6 +1629,33 @@ void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
_teleportDir = s.readSint16LE();
}
+void CAnim::load3DO(Common::SeekableReadStream &s) {
+ char buffer[12];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+
+ s.read(_sequences, 30);
+
+ _position.x = s.readSint16BE();
+ _position.y = s.readSint16BE();
+
+ _size = s.readUint32BE();
+ _type = (SpriteType)s.readUint16BE();
+ _flags = s.readByte();
+
+ _goto.x = s.readSint16BE();
+ _goto.y = s.readSint16BE();
+ _gotoDir = s.readSint16BE();
+ _teleportPos.x = s.readSint16BE();
+ _teleportPos.y = s.readSint16BE();
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+ _teleportPos.x = _teleportPos.x * FIXED_INT_MULTIPLIER / 100;
+ _teleportPos.y = _teleportPos.y * FIXED_INT_MULTIPLIER / 100;
+
+ _teleportDir = s.readSint16BE();
+}
+
/*----------------------------------------------------------------*/
CAnimStream::CAnimStream() {
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index addadccd9d..6561a370fa 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -159,6 +159,7 @@ struct UseType {
* Load the data for the UseType
*/
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
};
class BaseObject {
@@ -344,6 +345,7 @@ public:
* Load the data for the object
*/
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
/**
* Toggle the type of an object between hidden and active
@@ -436,6 +438,7 @@ struct CAnim {
* Load the data for the animation
*/
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
};
class CAnimStream {
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index c16d1f208b..028e262999 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -84,6 +84,16 @@ void BgFileHeaderInfo::load(Common::SeekableReadStream &s) {
_filename = Common::String(buffer);
}
+void BgFileHeaderInfo::load3DO(Common::SeekableReadStream &s) {
+ _filesize = s.readUint32BE();
+ _maxFrames = s.readByte();
+
+ char buffer[9];
+ s.read(buffer, 9);
+ _filename = Common::String(buffer);
+ s.skip(2); // only on 3DO!
+}
+
/*----------------------------------------------------------------*/
void Exit::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
@@ -121,6 +131,13 @@ void SceneEntry::load(Common::SeekableReadStream &s) {
_allow = s.readByte();
}
+void SceneEntry::load3DO(Common::SeekableReadStream &s) {
+ _startPosition.x = s.readSint16BE();
+ _startPosition.y = s.readSint16BE();
+ _startDir = s.readByte();
+ _allow = s.readByte();
+}
+
void SceneSound::load(Common::SeekableReadStream &s) {
char buffer[9];
s.read(buffer, 8);
@@ -130,6 +147,10 @@ void SceneSound::load(Common::SeekableReadStream &s) {
_priority = s.readByte();
}
+void SceneSound::load3DO(Common::SeekableReadStream &s) {
+ load(s);
+}
+
/*----------------------------------------------------------------*/
int ObjectArray::indexOf(const Object &obj) const {
@@ -285,140 +306,376 @@ bool Scene::loadScene(const Common::String &filename) {
// Load the room resource file for the scene
//
- Common::String rrmFile = filename + ".rrm";
- flag = _vm->_res->exists(rrmFile);
- if (flag) {
- Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile);
+ if (_vm->getPlatform() != Common::kPlatform3DO) {
+ // PC version
+ Common::String rrmFile = filename + ".rrm";
+ flag = _vm->_res->exists(rrmFile);
+ if (flag) {
+ Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile);
- rrmStream->seek(39);
- if (IS_SERRATED_SCALPEL) {
- _version = rrmStream->readByte();
- _lzwMode = _version == 10;
- } else {
- _lzwMode = rrmStream->readByte() > 0;
- }
+ rrmStream->seek(39);
+ if (IS_SERRATED_SCALPEL) {
+ _version = rrmStream->readByte();
+ _lzwMode = _version == 10;
+ } else {
+ _lzwMode = rrmStream->readByte() > 0;
+ }
+
+ // Go to header and read it in
+ rrmStream->seek(rrmStream->readUint32LE());
+
+ BgFileHeader bgHeader;
+ bgHeader.load(*rrmStream, IS_ROSE_TATTOO);
+ _invGraphicItems = bgHeader._numImages + 1;
+
+ if (IS_ROSE_TATTOO) {
+ screen.initPaletteFade(bgHeader._bytesWritten);
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+
+ paletteLoaded();
+
+ // Read in background
+ if (_lzwMode) {
+ res.decompress(*rrmStream, (byte *)screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ } else {
+ rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ }
+ }
+
+ // Read in the shapes header info
+ Common::Array<BgFileHeaderInfo> bgInfo;
+ bgInfo.resize(bgHeader._numStructs);
- // Go to header and read it in
- rrmStream->seek(rrmStream->readUint32LE());
+ for (uint idx = 0; idx < bgInfo.size(); ++idx)
+ bgInfo[idx].load(*rrmStream);
- BgFileHeader bgHeader;
- bgHeader.load(*rrmStream, IS_ROSE_TATTOO);
- _invGraphicItems = bgHeader._numImages + 1;
+ // Read information
+ if (IS_ROSE_TATTOO) {
+ // Load shapes
+ Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
- if (IS_ROSE_TATTOO) {
- screen.initPaletteFade(bgHeader._bytesWritten);
- rrmStream->read(screen._cMap, PALETTE_SIZE);
- screen.translatePalette(screen._cMap);
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo);
- paletteLoaded();
+ if (_lzwMode)
+ delete infoStream;
- // Read in background
- if (_lzwMode) {
- res.decompress(*rrmStream, (byte *)screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ // Load description text
+ _descText.resize(bgHeader._descSize);
+ if (_lzwMode)
+ res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
+ else
+ rrmStream->read(&_descText[0], bgHeader._descSize);
+
+ // Load sequences
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ if (_lzwMode)
+ res.decompress(*rrmStream, &_sequenceBuffer[0], bgHeader._seqSize);
+ else
+ rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ } else if (!_lzwMode) {
+ // Serrated Scalpel uncompressed info
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*rrmStream, false);
+
+ if (bgHeader._descSize) {
+ _descText.resize(bgHeader._descSize);
+ rrmStream->read(&_descText[0], bgHeader._descSize);
+ }
+
+ if (bgHeader._seqSize) {
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ }
} else {
- rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ // Serrated Scalpel compressed info
+ Common::SeekableReadStream *infoStream;
+
+ // Read shapes
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569);
+
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*infoStream, false);
+
+ delete infoStream;
+
+ // Read description texts
+ if (bgHeader._descSize) {
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize);
+
+ _descText.resize(bgHeader._descSize);
+ infoStream->read(&_descText[0], bgHeader._descSize);
+
+ delete infoStream;
+ }
+
+ // Read sequences
+ if (bgHeader._seqSize) {
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._seqSize);
+
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+
+ delete infoStream;
+ }
}
- }
- // Read in the shapes header info
- Common::Array<BgFileHeaderInfo> bgInfo;
- bgInfo.resize(bgHeader._numStructs);
+ // Set up the list of images used by the scene
+ _images.resize(bgHeader._numImages + 1);
+ for (int idx = 0; idx < bgHeader._numImages; ++idx) {
+ _images[idx + 1]._filesize = bgInfo[idx]._filesize;
+ _images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
- for (uint idx = 0; idx < bgInfo.size(); ++idx)
- bgInfo[idx].load(*rrmStream);
+ // Read in the image data
+ Common::SeekableReadStream *imageStream = _lzwMode ?
+ res.decompress(*rrmStream, bgInfo[idx]._filesize) :
+ rrmStream->readStream(bgInfo[idx]._filesize);
- // Read information
- if (IS_ROSE_TATTOO) {
- // Load shapes
- Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
+ _images[idx + 1]._images = new ImageFile(*imageStream);
- _bgShapes.resize(bgHeader._numStructs);
- for (int idx = 0; idx < bgHeader._numStructs; ++idx)
- _bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo);
+ delete imageStream;
+ }
- if (_lzwMode)
- delete infoStream;
+ // Set up the bgShapes
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx) {
+ _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images;
+ _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr :
+ &(*_bgShapes[idx]._images)[0];
+
+ _bgShapes[idx]._examine = Common::String(&_descText[_bgShapes[idx]._descOffset]);
+ _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset];
+ _bgShapes[idx]._misc = 0;
+ _bgShapes[idx]._seqCounter = 0;
+ _bgShapes[idx]._seqCounter2 = 0;
+ _bgShapes[idx]._seqStack = 0;
+ _bgShapes[idx]._frameNumber = -1;
+ _bgShapes[idx]._oldPosition = Common::Point(0, 0);
+ _bgShapes[idx]._oldSize = Common::Point(1, 1);
+ }
- // Load description text
- _descText.resize(bgHeader._descSize);
- if (_lzwMode)
- res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
- else
- rrmStream->read(&_descText[0], bgHeader._descSize);
+ // Load in cAnim list
+ _cAnim.clear();
+ if (bgHeader._numcAnimations) {
+ int animSize = IS_SERRATED_SCALPEL ? 65 : 47;
+ Common::SeekableReadStream *canimStream = _lzwMode ?
+ res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
+ rrmStream->readStream(animSize * bgHeader._numcAnimations);
- // Load sequences
- _sequenceBuffer.resize(bgHeader._seqSize);
- if (_lzwMode)
- res.decompress(*rrmStream, &_sequenceBuffer[0], bgHeader._seqSize);
- else
- rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
- } else if (!_lzwMode) {
- // Serrated Scalpel uncompressed info
- _bgShapes.resize(bgHeader._numStructs);
- for (int idx = 0; idx < bgHeader._numStructs; ++idx)
- _bgShapes[idx].load(*rrmStream, false);
-
- if (bgHeader._descSize) {
- _descText.resize(bgHeader._descSize);
- rrmStream->read(&_descText[0], bgHeader._descSize);
+ _cAnim.resize(bgHeader._numcAnimations);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx)
+ _cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
+
+ delete canimStream;
}
- if (bgHeader._seqSize) {
- _sequenceBuffer.resize(bgHeader._seqSize);
- rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ // Read in the room bounding areas
+ int size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
+ res.decompress(*rrmStream, size);
+
+ _zones.resize(size / 10);
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ _zones[idx].left = boundsStream->readSint16LE();
+ _zones[idx].top = boundsStream->readSint16LE();
+ _zones[idx].setWidth(boundsStream->readSint16LE() + 1);
+ _zones[idx].setHeight(boundsStream->readSint16LE() + 1);
+ boundsStream->skip(2); // Skip unused scene number field
}
- } else {
- // Serrated Scalpel compressed info
- Common::SeekableReadStream *infoStream;
- // Read shapes
- infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569);
+ if (_lzwMode)
+ delete boundsStream;
- _bgShapes.resize(bgHeader._numStructs);
- for (int idx = 0; idx < bgHeader._numStructs; ++idx)
- _bgShapes[idx].load(*infoStream, false);
+ // Ensure we've reached the path version byte
+ if (rrmStream->readByte() != (IS_SERRATED_SCALPEL ? 254 : 251))
+ error("Invalid scene path data");
- delete infoStream;
+ // Load the walk directory
+ assert(_zones.size() < MAX_ZONES);
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
+ _walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
+ }
- // Read description texts
- if (bgHeader._descSize) {
- infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize);
+ // Read in the walk data
+ size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
+ res.decompress(*rrmStream, size);
- _descText.resize(bgHeader._descSize);
- infoStream->read(&_descText[0], bgHeader._descSize);
+ _walkData.resize(size);
+ walkStream->read(&_walkData[0], size);
- delete infoStream;
+ if (_lzwMode)
+ delete walkStream;
+
+ if (IS_ROSE_TATTOO) {
+ // Read in the entrance
+ _entrance.load(*rrmStream);
+
+ // Load scale zones
+ _scaleZones.resize(rrmStream->readByte());
+ for (uint idx = 0; idx < _scaleZones.size(); ++idx)
+ _scaleZones[idx].load(*rrmStream);
}
- // Read sequences
- if (bgHeader._seqSize) {
- infoStream = Resources::decompressLZ(*rrmStream, bgHeader._seqSize);
+ // Read in the exits
+ _exitZone = -1;
+ int numExits = rrmStream->readByte();
+ _exits.resize(numExits);
- _sequenceBuffer.resize(bgHeader._seqSize);
- infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ for (int idx = 0; idx < numExits; ++idx)
+ _exits[idx].load(*rrmStream, IS_ROSE_TATTOO);
- delete infoStream;
+ if (IS_SERRATED_SCALPEL)
+ // Read in the entrance
+ _entrance.load(*rrmStream);
+
+ // Initialize sound list
+ int numSounds = rrmStream->readByte();
+ _sounds.resize(numSounds);
+
+ for (int idx = 0; idx < numSounds; ++idx)
+ _sounds[idx].load(*rrmStream);
+
+ loadSceneSounds();
+
+ if (IS_ROSE_TATTOO) {
+ // Load the object sound list
+ char buffer[27];
+
+ _objSoundList.resize(rrmStream->readUint16LE());
+ for (uint idx = 0; idx < _objSoundList.size(); ++idx) {
+ rrmStream->read(buffer, 27);
+ _objSoundList[idx] = Common::String(buffer);
+ }
+ } else {
+ // Read in palette
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+ Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
+
+ // Read in the background
+ Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
+ res.decompress(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ if (_lzwMode)
+ delete bgStream;
}
+
+ // Backup the image and set the palette
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+ screen.setPalette(screen._cMap);
+
+ delete rrmStream;
}
- // Set up the list of images used by the scene
- _images.resize(bgHeader._numImages + 1);
- for (int idx = 0; idx < bgHeader._numImages; ++idx) {
+ } else {
+ // === 3DO version ===
+ Common::String roomFile = "rooms/" + filename + ".rrm";
+ flag = _vm->_res->exists(roomFile);
+ if (!flag)
+ error("loadScene: 3DO room file not found");
+
+ Common::SeekableReadStream *roomStream = _vm->_res->load(roomFile);
+
+ // Read 3DO header
+ roomStream->skip(4); // UINT32: offset graphic data?
+ uint16 header3DO_numStructs = roomStream->readUint16BE();
+ uint16 header3DO_numImages = roomStream->readUint16BE();
+ uint16 header3DO_numAnimations = roomStream->readUint16BE();
+ roomStream->skip(6);
+
+ uint32 header3DO_bgInfo_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgInfo_size = roomStream->readUint32BE();
+ uint32 header3DO_bgShapes_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgShapes_size = roomStream->readUint32BE();
+ uint32 header3DO_descriptions_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_descriptions_size = roomStream->readUint32BE();
+ uint32 header3DO_sequence_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_sequence_size = roomStream->readUint32BE();
+ uint32 header3DO_cAnim_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_cAnim_size = roomStream->readUint32BE();
+ uint32 header3DO_roomBounding_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_roomBounding_size = roomStream->readUint32BE();
+ uint32 header3DO_walkDirectory_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_walkDirectory_size = roomStream->readUint32BE();
+ uint32 header3DO_walkData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_walkData_size = roomStream->readUint32BE();
+ uint32 header3DO_exits_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_exits_size = roomStream->readUint32BE();
+ uint32 header3DO_entranceData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_entranceData_size = roomStream->readUint32BE();
+ uint32 header3DO_soundList_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_soundList_size = roomStream->readUint32BE();
+ uint32 header3DO_unknown_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_unknown_size = roomStream->readUint32BE();
+ uint32 header3DO_bgGraphicData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgGraphicData_size = roomStream->readUint32BE();
+
+ int32 header3DO_soundList_count = header3DO_soundList_size / 9;
+
+ _invGraphicItems = header3DO_numImages + 1;
+
+ // === BGINFO === read in the shapes header info
+ Common::Array<BgFileHeaderInfo> bgInfo;
+
+ roomStream->seek(header3DO_bgInfo_offset);
+ bgInfo.resize(header3DO_numStructs);
+ for (uint idx = 0; idx < bgInfo.size(); ++idx)
+ bgInfo[idx].load3DO(*roomStream);
+
+ // === BGSHAPES === read in the shapes info
+ roomStream->seek(header3DO_bgShapes_offset);
+ _bgShapes.resize(header3DO_numStructs);
+ for (int idx = 0; idx < header3DO_numStructs; ++idx)
+ _bgShapes[idx].load3DO(*roomStream);
+
+ // === DESCRIPTION === read description text
+ if (header3DO_descriptions_size) {
+ roomStream->seek(header3DO_descriptions_offset);
+ _descText.resize(header3DO_descriptions_size);
+ roomStream->read(&_descText[0], header3DO_descriptions_size);
+ }
+
+ // === SEQUENCE === read sequence buffer
+ if (header3DO_sequence_size) {
+ roomStream->seek(header3DO_sequence_offset);
+ _sequenceBuffer.resize(header3DO_sequence_size);
+ roomStream->read(&_sequenceBuffer[0], header3DO_sequence_size);
+ }
+
+ // === IMAGES === set up the list of images used by the scene
+ roomStream->seek(header3DO_bgGraphicData_offset);
+ _images.resize(header3DO_numImages + 1);
+ for (int idx = 0; idx < header3DO_numImages; ++idx) {
_images[idx + 1]._filesize = bgInfo[idx]._filesize;
_images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
+ // Read the image data
+ // It seems it's a 8 byte header per frame
+ // followed by a copy of the cel header
+ // which is then followed by cel data
+ // TODO
+ warning("image %d, maxFrames %d", idx, bgInfo[idx]._maxFrames);
+ warning("size %d", bgInfo[idx]._filesize);
+
// Read in the image data
- Common::SeekableReadStream *imageStream = _lzwMode ?
- res.decompress(*rrmStream, bgInfo[idx]._filesize) :
- rrmStream->readStream(bgInfo[idx]._filesize);
+ //Common::SeekableReadStream *imageStream = roomStream->readStream(bgInfo[idx]._filesize);
- _images[idx + 1]._images = new ImageFile(*imageStream);
+ //_images[idx + 1]._images = new ImageFile(*imageStream);
- delete imageStream;
+ //delete imageStream;
+ warning("end");
}
- // Set up the bgShapes
- for (int idx = 0; idx < bgHeader._numStructs; ++idx) {
+ // === BGSHAPES === Set up the bgShapes
+ for (int idx = 0; idx < header3DO_numStructs; ++idx) {
+ warning("%d", _bgShapes[idx]._misc);
_bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images;
_bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr :
&(*_bgShapes[idx]._images)[0];
@@ -434,121 +691,73 @@ bool Scene::loadScene(const Common::String &filename) {
_bgShapes[idx]._oldSize = Common::Point(1, 1);
}
- // Load in cAnim list
+ // === CANIM === read cAnim list
_cAnim.clear();
- if (bgHeader._numcAnimations) {
- int animSize = IS_SERRATED_SCALPEL ? 65 : 47;
- Common::SeekableReadStream *canimStream = _lzwMode ?
- res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
- rrmStream->readStream(animSize * bgHeader._numcAnimations);
+ if (header3DO_numAnimations) {
+ int animSize = 65;
+
+ roomStream->seek(header3DO_cAnim_offset);
+ Common::SeekableReadStream *canimStream = roomStream->readStream(animSize * header3DO_numAnimations);
- _cAnim.resize(bgHeader._numcAnimations);
+ _cAnim.resize(header3DO_numAnimations);
for (uint idx = 0; idx < _cAnim.size(); ++idx)
- _cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
+ _cAnim[idx].load3DO(*canimStream);
delete canimStream;
}
- // Read in the room bounding areas
- int size = rrmStream->readUint16LE();
- Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
- res.decompress(*rrmStream, size);
+ // === BOUNDING AREAS === Read in the room bounding areas
+ int roomBoundingCount = header3DO_roomBounding_size / 12;
- _zones.resize(size / 10);
+ roomStream->seek(header3DO_roomBounding_offset);
+ _zones.resize(roomBoundingCount);
for (uint idx = 0; idx < _zones.size(); ++idx) {
- _zones[idx].left = boundsStream->readSint16LE();
- _zones[idx].top = boundsStream->readSint16LE();
- _zones[idx].setWidth(boundsStream->readSint16LE() + 1);
- _zones[idx].setHeight(boundsStream->readSint16LE() + 1);
- boundsStream->skip(2); // Skip unused scene number field
+ _zones[idx].left = roomStream->readSint16BE();
+ _zones[idx].top = roomStream->readSint16BE();
+ _zones[idx].setWidth(roomStream->readSint16BE() + 1);
+ _zones[idx].setHeight(roomStream->readSint16BE() + 1);
+ roomStream->skip(4); // skip UINT32
}
- if (_lzwMode)
- delete boundsStream;
-
- // Ensure we've reached the path version byte
- if (rrmStream->readByte() != (IS_SERRATED_SCALPEL ? 254 : 251))
- error("Invalid scene path data");
-
- // Load the walk directory
+ // === WALK DIRECTORY === Load the walk directory
+ roomStream->seek(header3DO_walkDirectory_offset);
assert(_zones.size() < MAX_ZONES);
for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
- _walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
+ _walkDirectory[idx1][idx2] = roomStream->readSint16BE();
}
- // Read in the walk data
- size = rrmStream->readUint16LE();
- Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
- res.decompress(*rrmStream, size);
-
- _walkData.resize(size);
- walkStream->read(&_walkData[0], size);
-
- if (_lzwMode)
- delete walkStream;
-
- if (IS_ROSE_TATTOO) {
- // Read in the entrance
- _entrance.load(*rrmStream);
-
- // Load scale zones
- _scaleZones.resize(rrmStream->readByte());
- for (uint idx = 0; idx < _scaleZones.size(); ++idx)
- _scaleZones[idx].load(*rrmStream);
- }
+ // === WALK DATA === Read in the walk data
+ roomStream->seek(header3DO_walkData_offset);
+ _walkData.resize(header3DO_walkData_size);
+ roomStream->read(&_walkData[0], header3DO_walkData_size);
- // Read in the exits
+ // === EXITS === Read in the exits
_exitZone = -1;
- int numExits = rrmStream->readByte();
- _exits.resize(numExits);
+ _exits.resize(header3DO_exits_size); // TODO!!!!
- for (int idx = 0; idx < numExits; ++idx)
- _exits[idx].load(*rrmStream, IS_ROSE_TATTOO);
+ //for (int idx = 0; idx < numExits; ++idx)
+ // _exits[idx].load(*rrmStream, IS_ROSE_TATTOO);
- if (IS_SERRATED_SCALPEL)
- // Read in the entrance
- _entrance.load(*rrmStream);
+ // === ENTRANCE === Read in the entrance
+ roomStream->seek(header3DO_entranceData_offset);
+ _entrance.load(*roomStream);
- // Initialize sound list
- int numSounds = rrmStream->readByte();
- _sounds.resize(numSounds);
+ // === SOUND LIST === Initialize sound list
+ roomStream->seek(header3DO_soundList_offset);
+ _sounds.resize(header3DO_soundList_count);
+ for (int idx = 0; idx < header3DO_soundList_count; ++idx)
+ _sounds[idx].load3DO(*roomStream);
- for (int idx = 0; idx < numSounds; ++idx)
- _sounds[idx].load(*rrmStream);
+ // === BACKGROUND PICTURE ===
+ // load from file rooms\[filename].bg
+ // it's uncompressed 15-bit RGB555 data
- loadSceneSounds();
- if (IS_ROSE_TATTOO) {
- // Load the object sound list
- char buffer[27];
-
- _objSoundList.resize(rrmStream->readUint16LE());
- for (uint idx = 0; idx < _objSoundList.size(); ++idx) {
- rrmStream->read(buffer, 27);
- _objSoundList[idx] = Common::String(buffer);
- }
- } else {
- // Read in palette
- rrmStream->read(screen._cMap, PALETTE_SIZE);
- screen.translatePalette(screen._cMap);
- Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
- // Read in the background
- Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
- res.decompress(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
- bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
-
- if (_lzwMode)
- delete bgStream;
- }
- // Backup the image and set the palette
- screen._backBuffer2.blitFrom(screen._backBuffer1);
- screen.setPalette(screen._cMap);
- delete rrmStream;
}
// Handle drawing any on-screen interface
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index b8b2d2c9b6..8051d45c2d 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -72,6 +72,7 @@ struct BgFileHeaderInfo {
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
};
class Exit: public Common::Rect {
@@ -99,6 +100,7 @@ struct SceneEntry {
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
};
struct SceneSound {
@@ -109,6 +111,7 @@ struct SceneSound {
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
};
class ObjectArray : public Common::Array<Object> {