SHERLOCK: 3DO: support for cAnim data (startCAnim)
it's now possible to leave the first room Conflicts: engines/sherlock/objects.cpp
This commit is contained in:
parent
0f1b756242
commit
b5a4f622c2
7 changed files with 88 additions and 29 deletions
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
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();
|
||||
|
||||
|
|
|
@ -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,16 +464,41 @@ 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);
|
||||
|
||||
_cAnim.resize(bgHeader._numcAnimations);
|
||||
for (uint idx = 0; idx < _cAnim.size(); ++idx)
|
||||
_cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
|
||||
|
||||
delete canimStream;
|
||||
// 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, *cAnimOffsetPtr);
|
||||
cAnimOffsetPtr++;
|
||||
}
|
||||
|
||||
delete cAnimStream;
|
||||
delete cAnimOffsetTablePtr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Read in the room bounding areas
|
||||
int size = rrmStream->readUint16LE();
|
||||
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue