STARK: The image resources now load their xmg files

Contains fixes to the XMG code from ST and Somaen's branch
This commit is contained in:
Bastien Bouclet 2015-01-02 13:22:12 +01:00
parent fae93d84a2
commit 016e46b386
8 changed files with 133 additions and 38 deletions

View file

@ -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<Direction>();
}
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<Image>(_currentFrame);
return _currentFrameImage->getVisual();
}
void AnimSub1::printData() {
Anim::printData();

View file

@ -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<Direction *> _directions;
Image *_currentFrameImage;
};
class AnimSub2 : public Anim {

View file

@ -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() {

View file

@ -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<Polygon> _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

View file

@ -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");

View file

@ -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

View file

@ -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

View file

@ -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