diff --git a/engines/stark/resources/anim.cpp b/engines/stark/resources/anim.cpp index ec7b212d53c..42499f0b1d5 100644 --- a/engines/stark/resources/anim.cpp +++ b/engines/stark/resources/anim.cpp @@ -23,6 +23,8 @@ #include "common/debug.h" #include "engines/stark/resources/anim.h" +#include "engines/stark/resources/direction.h" +#include "engines/stark/resources/image.h" #include "engines/stark/xrcreader.h" namespace Stark { @@ -62,6 +64,10 @@ void Anim::readData(XRCReadStream *stream) { void Anim::selectFrame(uint32 frameIndex) { } +SceneElement *Anim::getVisual() { + return nullptr; +} + void Anim::reference(Item *item) { _refCount++; } @@ -82,7 +88,9 @@ AnimSub1::~AnimSub1() { AnimSub1::AnimSub1(Resource *parent, byte subType, uint16 index, const Common::String &name) : Anim(parent, subType, index, name), - _field_3C(0) { + _field_3C(0), + _currentDirection(0), + _currentFrameImage(nullptr) { } void AnimSub1::readData(XRCReadStream *stream) { @@ -91,6 +99,12 @@ void AnimSub1::readData(XRCReadStream *stream) { _field_3C = stream->readFloat(); } +void AnimSub1::onAllLoaded() { + Anim::onAllLoaded(); + + _directions = listChildren(); +} + void AnimSub1::selectFrame(uint32 frameIndex) { if (frameIndex > _numFrames) { error("Error setting frame %d for anim '%s'", frameIndex, getName().c_str()); @@ -99,6 +113,12 @@ void AnimSub1::selectFrame(uint32 frameIndex) { _currentFrame = frameIndex; } +SceneElement *AnimSub1::getVisual() { + Direction *direction = _directions[_currentDirection]; + _currentFrameImage = direction->findChildWithIndex(_currentFrame); + return _currentFrameImage->getVisual(); +} + void AnimSub1::printData() { Anim::printData(); diff --git a/engines/stark/resources/anim.h b/engines/stark/resources/anim.h index 3dc54fe717c..5362a7b71a7 100644 --- a/engines/stark/resources/anim.h +++ b/engines/stark/resources/anim.h @@ -29,7 +29,10 @@ namespace Stark { +class Direction; +class Image; class Item; +class SceneElement; class XRCReadStream; class Anim : public Resource { @@ -53,6 +56,7 @@ public: void readData(XRCReadStream *stream) override; virtual void selectFrame(uint32 frameIndex); + virtual SceneElement *getVisual(); // Refcounting, used to know if the anim script needs to run virtual void reference(Item *item); @@ -75,14 +79,21 @@ public: // Resource API void readData(XRCReadStream *stream) override; + void onAllLoaded() override; // Anim API void selectFrame(uint32 frameIndex) override; + SceneElement *getVisual() override; protected: void printData() override; float _field_3C; + + uint32 _currentDirection; + Common::Array _directions; + + Image *_currentFrameImage; }; class AnimSub2 : public Anim { diff --git a/engines/stark/resources/image.cpp b/engines/stark/resources/image.cpp index 8d6ce49ab5f..391c7b4baef 100644 --- a/engines/stark/resources/image.cpp +++ b/engines/stark/resources/image.cpp @@ -20,9 +20,13 @@ * */ +#include "engines/stark/resources/image.h" + #include "common/debug.h" -#include "engines/stark/resources/image.h" +#include "engines/stark/archiveloader.h" +#include "engines/stark/stark.h" +#include "engines/stark/xmg.h" #include "engines/stark/xrcreader.h" namespace Stark { @@ -47,7 +51,8 @@ Image::Image(Resource *parent, byte subType, uint16 index, const Common::String _transparent(false), _transparency(0), _field_44_ADF(0), - _field_48_ADF(30) { + _field_48_ADF(30), + _visual(nullptr) { _type = TYPE; } @@ -68,6 +73,12 @@ void Image::readData(XRCReadStream *stream) { _polygons.push_back(polygon); } + + _archiveName = stream->getArchiveName(); +} + +SceneElement *Image::getVisual() { + return nullptr; } void Image::printData() { @@ -91,7 +102,8 @@ ImageSub23::~ImageSub23() { } ImageSub23::ImageSub23(Resource *parent, byte subType, uint16 index, const Common::String &name) : - Image(parent, subType, index, name) { + Image(parent, subType, index, name), + _noName(false) { } void ImageSub23::readData(XRCReadStream *stream) { @@ -105,6 +117,36 @@ void ImageSub23::readData(XRCReadStream *stream) { if (stream->isDataLeft()) { _field_48_ADF = stream->readUint32LE(); } + + _noName = _filename == "noname" || _filename == "noname.xmg"; +} + +void ImageSub23::onPostRead() { + initVisual(); +} + +SceneElement *ImageSub23::getVisual() { + initVisual(); + return _visual; +} + +void ImageSub23::initVisual() { + if (_visual) { + return; // The visual is already there + } + + if (_noName) { + return; // No file to load + } + + // Get the archive loader service + ArchiveLoader *archiveLoader = StarkServices::instance().archiveLoader; + + Common::ReadStream *stream = archiveLoader->getFile(_filename, _archiveName); + + _visual = SceneElementXMG::load(stream); + + delete stream; } void ImageSub23::printData() { diff --git a/engines/stark/resources/image.h b/engines/stark/resources/image.h index abbd7afba03..a3aec940d7b 100644 --- a/engines/stark/resources/image.h +++ b/engines/stark/resources/image.h @@ -30,6 +30,7 @@ namespace Stark { +class SceneElement; class XRCReadStream; class Image : public Resource { @@ -50,18 +51,25 @@ public: Image(Resource *parent, byte subType, uint16 index, const Common::String &name); virtual ~Image(); + // Resource API void readData(XRCReadStream *stream) override; + virtual SceneElement *getVisual(); + protected: void printData() override; Common::String _filename; - Common::Point _hotspot; + Common::String _archiveName; + + SceneElement *_visual; + bool _transparent; uint32 _transparency; uint32 _field_44_ADF; uint32 _field_48_ADF; + Common::Point _hotspot; Common::Array _polygons; }; @@ -70,10 +78,19 @@ public: ImageSub23(Resource *parent, byte subType, uint16 index, const Common::String &name); virtual ~ImageSub23(); - virtual void readData(XRCReadStream *stream) override; + // Resource API + void readData(XRCReadStream *stream) override; + void onPostRead() override; + + // Image API + SceneElement *getVisual() override; protected: void printData() override; + + void initVisual(); + + bool _noName; }; } // End of namespace Stark diff --git a/engines/stark/scene.cpp b/engines/stark/scene.cpp index 6763dfff5da..3ce013f91ff 100644 --- a/engines/stark/scene.cpp +++ b/engines/stark/scene.cpp @@ -34,15 +34,15 @@ Scene::Scene(GfxDriver *gfx) : _gfx(gfx) { if (!xarc.open("45/00/00.xarc")) warning("couldn't open archive"); - _elements.push_back(SceneElementXMG::load(&xarc, "house_layercenter.xmg", 0, 0)); - //_elements.push_back(SceneElementXMG::load(&xarc, "vista-scapehaze-more-fog3-final.xmg", 0, 0)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop01_pillow.xmg", 384, 267)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop02_pillow.xmg", 324, 299)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop03_pillow.xmg", 141, 312)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop4_armrest.xmg", 171, 184)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop5_chair.xmg", 170, 164)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop6_wall.xmg", 0, 0)); - _elements.push_back(SceneElementXMG::load(&xarc, "house_prop8_pillar.xmg", 534, 0)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_layercenter.xmg", 0, 0)); +// //_elements.push_back(SceneElementXMG::load(&xarc, "vista-scapehaze-more-fog3-final.xmg", 0, 0)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop01_pillow.xmg", 384, 267)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop02_pillow.xmg", 324, 299)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop03_pillow.xmg", 141, 312)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop4_armrest.xmg", 171, 184)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop5_chair.xmg", 170, 164)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop6_wall.xmg", 0, 0)); +// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop8_pillar.xmg", 534, 0)); SceneElementActor *actor = SceneElementActor::load(&xarc, "oldapril.cir"); actor->setAnim(&xarc, "oldapril_idle.ani"); diff --git a/engines/stark/sceneelement.h b/engines/stark/sceneelement.h index da0e886d7b4..0d0ce7847e1 100644 --- a/engines/stark/sceneelement.h +++ b/engines/stark/sceneelement.h @@ -23,6 +23,7 @@ #ifndef STARK_SCENEELEMENT_H #define STARK_SCENEELEMENT_H +#include "common/rect.h" #include "common/scummsys.h" namespace Stark { @@ -36,6 +37,18 @@ public: virtual void render(GfxDriver *gfx) = 0; }; +class SceneElement2D : public SceneElement { +public: + virtual ~SceneElement2D() {}; + + void setPosition(const Common::Point &position) { + _position = position; + } + +protected: + Common::Point _position; +}; + } // End of namespace Stark #endif // STARK_SCENEELEMENT_H diff --git a/engines/stark/xmg.cpp b/engines/stark/xmg.cpp index 3166fc8117c..e1e19924b50 100644 --- a/engines/stark/xmg.cpp +++ b/engines/stark/xmg.cpp @@ -73,6 +73,9 @@ Graphics::Surface *XMGDecoder::decodeImage(Common::ReadStream *stream) { // Read the image size uint32 width = stream->readUint32LE(); uint32 height = stream->readUint32LE(); + if (width % 2) { + width++; + } debugC(10, kDebugXMG, "Stark::XMG: Version=%d, TransparencyColor=0x%08x, size=%dx%d", version, _transColor, width, height); // Read the scan length @@ -93,9 +96,7 @@ Graphics::Surface *XMGDecoder::decodeImage(Common::ReadStream *stream) { Graphics::Surface *surface = new Graphics::Surface(); if (!surface) return NULL; - // Placeholder pixelformat - Graphics::PixelFormat pixFormat(4, 8, 8, 8, 8, 24, 16, 8 ,0); - surface->create(width, height, pixFormat); + surface->create(width, height, Graphics::PixelFormat(4,8,8,8,8,24,16,8,0)); _pixels = (uint32 *)surface->getPixels(); uint32 currX = 0, currY = 0; @@ -117,7 +118,7 @@ Graphics::Surface *XMGDecoder::decodeImage(Common::ReadStream *stream) { count = op & 0x3F; } else { count = ((op & 0xF) << 8) + stream->readByte(); - op <<= 4; + op <<= 2; } op &= 0xC0; @@ -219,7 +220,9 @@ void XMGDecoder::processRGB() { // SCENE ELEMENT XMG -SceneElementXMG::SceneElementXMG() : _surface(NULL) { +SceneElementXMG::SceneElementXMG() : + SceneElement2D(), + _surface(NULL) { } SceneElementXMG::~SceneElementXMG() { @@ -229,29 +232,19 @@ SceneElementXMG::~SceneElementXMG() { delete _surface; } -SceneElementXMG *SceneElementXMG::load(const Common::Archive *archive, const Common::String &name, uint16 x, uint16 y) { - // Open the resource - Common::SeekableReadStream *res = archive->createReadStreamForMember(name); - if (!res) - return NULL; - +SceneElementXMG *SceneElementXMG::load(Common::ReadStream *stream) { // Create the element to return SceneElementXMG *element = new SceneElementXMG(); // Decode the XMG - element->_surface = XMGDecoder::decode(res); - delete res; - - // Save the rendering coordinates - element->_x = x; - element->_y = y; + element->_surface = XMGDecoder::decode(stream); return element; } void SceneElementXMG::render(GfxDriver *gfx) { // Draw the current element - gfx->drawSurface(_surface, Common::Point(_x, _y)); + gfx->drawSurface(_surface, _position); } } // End of namespace Stark diff --git a/engines/stark/xmg.h b/engines/stark/xmg.h index d08ecc183c7..516c85e649d 100644 --- a/engines/stark/xmg.h +++ b/engines/stark/xmg.h @@ -25,7 +25,7 @@ #include "engines/stark/sceneelement.h" -#include "common/archive.h" +#include "common/stream.h" namespace Graphics { struct Surface; @@ -36,19 +36,18 @@ namespace Stark { /** * XMG (still image) decoder and renderer */ -class SceneElementXMG : public SceneElement { +class SceneElementXMG : public SceneElement2D { private: SceneElementXMG(); public: ~SceneElementXMG(); - static SceneElementXMG *load(const Common::Archive *archive, const Common::String &name, uint16 x, uint16 y); + static SceneElementXMG *load(Common::ReadStream *stream); - void render(GfxDriver *gfx); + void render(GfxDriver *gfx) override; private: Graphics::Surface *_surface; - uint16 _x, _y; }; } // End of namespace Stark