From 3683719932882ab60fa1a6c22d19889c9734c355 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 May 2015 07:20:06 -0400 Subject: SHERLOCK: Implement remaining Rose Tattoo scene data loading --- engines/sherlock/scene.cpp | 133 ++++++++++++++++++++++++++++++++------------ engines/sherlock/scene.h | 24 ++++++-- engines/sherlock/sherlock.h | 3 + 3 files changed, 120 insertions(+), 40 deletions(-) (limited to 'engines') diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 0ac2eec0ff..96cfac0683 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -80,18 +80,30 @@ void BgfileheaderInfo::load(Common::SeekableReadStream &s) { /** * Load the data for the object */ -void Exit::load(Common::SeekableReadStream &s) { - int xp = s.readSint16LE(); - int yp = s.readSint16LE(); - int xSize = s.readSint16LE(); - int ySize = s.readSint16LE(); - _bounds = Common::Rect(xp, yp, xp + xSize, yp + ySize); +void Exit::load(Common::SeekableReadStream &s, bool isRoseTattoo) { + if (isRoseTattoo) { + char buffer[41]; + s.read(buffer, 41); + _dest = Common::String(buffer); + } + left = s.readSint16LE(); + top = s.readSint16LE(); + setWidth(s.readUint16LE()); + setHeight(s.readUint16LE()); + + _image = isRoseTattoo ? s.readByte() : 0; _scene = s.readSint16LE(); - _allow = s.readSint16LE(); + + if (!isRoseTattoo) + _allow = s.readSint16LE(); + _people.x = s.readSint16LE(); _people.y = s.readSint16LE(); _peopleDir = s.readUint16LE(); + + if (isRoseTattoo) + _allow = s.readSint16LE(); } /*----------------------------------------------------------------*/ @@ -134,6 +146,21 @@ int ObjectArray::indexOf(const Object &obj) const { /*----------------------------------------------------------------*/ +/** + * Load the data for the object + */ +void ScaleZone::load(Common::SeekableReadStream &s) { + left = s.readSint16LE(); + top = s.readSint16LE(); + setWidth(s.readUint16LE()); + setHeight(s.readUint16LE()); + + _topNumber = s.readByte(); + _bottomNumber = s.readByte(); +} + +/*----------------------------------------------------------------*/ + Scene::Scene(SherlockEngine *vm): _vm(vm) { for (int idx = 0; idx < SCENES_COUNT; ++idx) Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false); @@ -153,6 +180,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _animating = 0; _doBgAnimDone = true; _tempFadeStyle = 0; + _exitZone = -1; } Scene::~Scene() { @@ -280,7 +308,7 @@ bool Scene::loadScene(const Common::String &filename) { Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile); rrmStream->seek(39); - if (_vm->getGameID() == GType_SerratedScalpel) { + if (IS_SERRATED_SCALPEL) { _version = rrmStream->readByte(); _lzwMode = _version == 10; } else { @@ -291,10 +319,10 @@ bool Scene::loadScene(const Common::String &filename) { rrmStream->seek(rrmStream->readUint32LE()); BgFileHeader bgHeader; - bgHeader.synchronize(*rrmStream, _vm->getGameID() == GType_RoseTattoo); + bgHeader.synchronize(*rrmStream, IS_ROSE_TATTOO); _invGraphicItems = bgHeader._numImages + 1; - if (_vm->getGameID() == GType_RoseTattoo) { + if (IS_ROSE_TATTOO) { screen.initPaletteFade(bgHeader._bytesWritten); screen.fadeRead(*rrmStream, screen._cMap, PALETTE_SIZE); screen.setupBGArea(screen._cMap); @@ -316,7 +344,7 @@ bool Scene::loadScene(const Common::String &filename) { bgInfo[idx].load(*rrmStream); // Read information - if (_vm->getGameID() == GType_SerratedScalpel) { + if (IS_SERRATED_SCALPEL) { Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 569 + bgHeader._descSize + bgHeader._seqSize); @@ -398,14 +426,14 @@ bool Scene::loadScene(const Common::String &filename) { // Load in cAnim list _cAnim.clear(); if (bgHeader._numcAnimations) { - int animSize = _vm->getGameID() == GType_SerratedScalpel ? 65 : 47; + 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, _vm->getGameID() == GType_RoseTattoo); + _cAnim[idx].load(*canimStream, IS_ROSE_TATTOO); delete canimStream; } @@ -413,7 +441,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the room bounding areas int size = rrmStream->readUint16LE(); Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : - Resources::decompressLZ(*rrmStream, size); + res.decompress(*rrmStream, size); _zones.resize(size / 10); for (uint idx = 0; idx < _zones.size(); ++idx) { @@ -428,10 +456,11 @@ bool Scene::loadScene(const Common::String &filename) { delete boundsStream; // Ensure we've reached the path version byte - if (rrmStream->readByte() != 254) + 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(); @@ -440,7 +469,7 @@ bool Scene::loadScene(const Common::String &filename) { // Read in the walk data size = rrmStream->readUint16LE(); Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream : - Resources::decompressLZ(*rrmStream, size); + res.decompress(*rrmStream, size); _walkData.resize(size); walkStream->read(&_walkData[0], size); @@ -448,15 +477,27 @@ bool Scene::loadScene(const Common::String &filename) { 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); + _exits[idx].load(*rrmStream, IS_ROSE_TATTOO); - // Read in the entrance - _entrance.load(*rrmStream); + if (IS_SERRATED_SCALPEL) + // Read in the entrance + _entrance.load(*rrmStream); // Initialize sound list int numSounds = rrmStream->readByte(); @@ -465,24 +506,34 @@ bool Scene::loadScene(const Common::String &filename) { for (int idx = 0; idx < numSounds; ++idx) _sounds[idx].load(*rrmStream); - for (int idx = 0; idx < numSounds; ++idx) - sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); + loadSceneSounds(); - // Read in palette - rrmStream->read(screen._cMap, PALETTE_SIZE); - for (int idx = 0; idx < PALETTE_SIZE; ++idx) - screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]); + 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); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]); - Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap); + Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap); - // Read in the background - Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream : - Resources::decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); + // 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); + bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); - if (_lzwMode) - delete bgStream; + if (_lzwMode) + delete bgStream; + } // Backup the image and set the palette screen._backBuffer2.blitFrom(screen._backBuffer1); @@ -550,6 +601,16 @@ bool Scene::loadScene(const Common::String &filename) { return flag; } +/** + * Load all the sound effects specified for the current scene + */ +void Scene::loadSceneSounds() { + Sound &sound = *_vm->_sound; + + for (uint idx = 0; idx < _sounds.size(); ++idx) + sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); +} + /** * Set objects to their current persistent state. This includes things such as * opening or moving them @@ -908,7 +969,7 @@ void Scene::updateBackground() { */ Exit *Scene::checkForExit(const Common::Rect &r) { for (uint idx = 0; idx < _exits.size(); ++idx) { - if (_exits[idx]._bounds.intersects(r)) + if (_exits[idx].intersects(r)) return &_exits[idx]; } @@ -1243,7 +1304,7 @@ void Scene::doBgAnim() { _canimShapes[idx].checkObject(); } - if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + if (_currentScene == 12 && IS_SERRATED_SCALPEL) ((Scalpel::ScalpelEngine *)_vm)->eraseMirror12(); // Restore the back buffer from the back buffer 2 in the changed area @@ -1316,7 +1377,7 @@ void Scene::doBgAnim() { checkBgShapes(people[AL]._imageFrame, Common::Point(people[AL]._position.x / 100, people[AL]._position.y / 100)); - if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + if (_currentScene == 12 && IS_SERRATED_SCALPEL) ((Scalpel::ScalpelEngine *)_vm)->doMirror12(); // Draw all active shapes which are behind the person @@ -1426,7 +1487,7 @@ void Scene::doBgAnim() { } } - if (_currentScene == 12 && _vm->getGameID() == GType_SerratedScalpel) + if (_currentScene == 12 && IS_SERRATED_SCALPEL) ((Scalpel::ScalpelEngine *)_vm)->flushMirror12(); for (uint idx = 0; idx < _bgShapes.size(); ++idx) { diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 86b1e3d063..9454a4e20b 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -68,15 +68,17 @@ struct BgfileheaderInfo { void load(Common::SeekableReadStream &s); }; -struct Exit { - Common::Rect _bounds; - +class Exit: public Common::Rect { +public: int _scene; int _allow; Common::Point _people; int _peopleDir; - void load(Common::SeekableReadStream &s); + Common::String _dest; + int _image; // Arrow image to use + + void load(Common::SeekableReadStream &s, bool isRoseTattoo); }; struct SceneEntry { @@ -99,6 +101,14 @@ public: int indexOf(const Object &obj) const; }; +class ScaleZone: public Common::Rect { +public: + int _topNumber; // Numerator of scale size at the top of the zone + int _bottomNumber; // Numerator of scale size at the bottom of the zone + + void load(Common::SeekableReadStream &s); +}; + class Scene { private: SherlockEngine *_vm; @@ -109,6 +119,8 @@ private: bool loadScene(const Common::String &filename); + void loadSceneSounds(); + void checkSceneStatus(); void checkInventory(); @@ -118,6 +130,7 @@ private: void checkBgShapes(ImageFrame *frame, const Common::Point &pt); void saveSceneStatus(); + public: int _currentScene; int _goToScene; @@ -141,9 +154,12 @@ public: int _walkDirectory[MAX_ZONES][MAX_ZONES]; Common::Array _walkData; Common::Array _exits; + int _exitZone; SceneEntry _entrance; Common::Array _sounds; ObjectArray _canimShapes; + Common::Array _scaleZones; + Common::StringArray _objSoundList; bool _restoreFlag; int _animating; bool _doBgAnimDone; diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 9261ad5b05..2688b51d4c 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -139,6 +139,9 @@ public: void synchronize(Common::Serializer &s); }; +#define IS_ROSE_TATTOO (_vm->getGameID() == GType_RoseTattoo) +#define IS_SERRATED_SCALPEL (_vm->getGameID() == GType_SerratedScalpel) + } // End of namespace Sherlock #endif -- cgit v1.2.3