mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 00:15:30 +00:00
SHERLOCK: some work on 3DO room data
This commit is contained in:
parent
d6ca620a7c
commit
515d5422a7
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
rrmStream->seek(39);
|
||||
if (IS_SERRATED_SCALPEL) {
|
||||
_version = rrmStream->readByte();
|
||||
_lzwMode = _version == 10;
|
||||
} else {
|
||||
rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
|
||||
_lzwMode = rrmStream->readByte() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
} else {
|
||||
rrmStream->read(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);
|
||||
// Read in the shapes header info
|
||||
Common::Array<BgFileHeaderInfo> bgInfo;
|
||||
bgInfo.resize(bgHeader._numStructs);
|
||||
|
||||
// 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);
|
||||
for (uint idx = 0; idx < bgInfo.size(); ++idx)
|
||||
bgInfo[idx].load(*rrmStream);
|
||||
|
||||
if (bgHeader._descSize) {
|
||||
// Read information
|
||||
if (IS_ROSE_TATTOO) {
|
||||
// Load shapes
|
||||
Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
|
||||
|
||||
_bgShapes.resize(bgHeader._numStructs);
|
||||
for (int idx = 0; idx < bgHeader._numStructs; ++idx)
|
||||
_bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo);
|
||||
|
||||
if (_lzwMode)
|
||||
delete infoStream;
|
||||
|
||||
// Load description text
|
||||
_descText.resize(bgHeader._descSize);
|
||||
rrmStream->read(&_descText[0], bgHeader._descSize);
|
||||
}
|
||||
if (_lzwMode)
|
||||
res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
|
||||
else
|
||||
rrmStream->read(&_descText[0], bgHeader._descSize);
|
||||
|
||||
if (bgHeader._seqSize) {
|
||||
// Load sequences
|
||||
_sequenceBuffer.resize(bgHeader._seqSize);
|
||||
rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
|
||||
}
|
||||
} else {
|
||||
// Serrated Scalpel compressed info
|
||||
Common::SeekableReadStream *infoStream;
|
||||
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);
|
||||
|
||||
// Read shapes
|
||||
infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569);
|
||||
if (bgHeader._descSize) {
|
||||
_descText.resize(bgHeader._descSize);
|
||||
rrmStream->read(&_descText[0], bgHeader._descSize);
|
||||
}
|
||||
|
||||
_bgShapes.resize(bgHeader._numStructs);
|
||||
for (int idx = 0; idx < bgHeader._numStructs; ++idx)
|
||||
_bgShapes[idx].load(*infoStream, false);
|
||||
if (bgHeader._seqSize) {
|
||||
_sequenceBuffer.resize(bgHeader._seqSize);
|
||||
rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
|
||||
}
|
||||
} else {
|
||||
// Serrated Scalpel compressed info
|
||||
Common::SeekableReadStream *infoStream;
|
||||
|
||||
delete infoStream;
|
||||
// Read shapes
|
||||
infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569);
|
||||
|
||||
// Read description texts
|
||||
if (bgHeader._descSize) {
|
||||
infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize);
|
||||
|
||||
_descText.resize(bgHeader._descSize);
|
||||
infoStream->read(&_descText[0], bgHeader._descSize);
|
||||
_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 sequences
|
||||
if (bgHeader._seqSize) {
|
||||
infoStream = Resources::decompressLZ(*rrmStream, bgHeader._seqSize);
|
||||
// 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;
|
||||
|
||||
_sequenceBuffer.resize(bgHeader._seqSize);
|
||||
infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
|
||||
// Read in the image data
|
||||
Common::SeekableReadStream *imageStream = _lzwMode ?
|
||||
res.decompress(*rrmStream, bgInfo[idx]._filesize) :
|
||||
rrmStream->readStream(bgInfo[idx]._filesize);
|
||||
|
||||
delete infoStream;
|
||||
_images[idx + 1]._images = new ImageFile(*imageStream);
|
||||
|
||||
delete imageStream;
|
||||
}
|
||||
|
||||
// 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 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);
|
||||
|
||||
_cAnim.resize(bgHeader._numcAnimations);
|
||||
for (uint idx = 0; idx < _cAnim.size(); ++idx)
|
||||
_cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
|
||||
|
||||
delete canimStream;
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
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 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);
|
||||
}
|
||||
|
||||
// Read in the exits
|
||||
_exitZone = -1;
|
||||
int numExits = rrmStream->readByte();
|
||||
_exits.resize(numExits);
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
||||
_cAnim.resize(bgHeader._numcAnimations);
|
||||
roomStream->seek(header3DO_cAnim_offset);
|
||||
Common::SeekableReadStream *canimStream = roomStream->readStream(animSize * header3DO_numAnimations);
|
||||
|
||||
_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);
|
||||
// === WALK DATA === Read in the walk data
|
||||
roomStream->seek(header3DO_walkData_offset);
|
||||
_walkData.resize(header3DO_walkData_size);
|
||||
roomStream->read(&_walkData[0], header3DO_walkData_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);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -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> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user