SHERLOCK: Beginnings of sprite loading for animations

This commit is contained in:
Paul Gilbert 2015-03-15 23:16:38 -04:00
parent 92c55e2bb1
commit 6cfb7169b9
9 changed files with 66 additions and 105 deletions

View File

@ -22,6 +22,7 @@
#include "sherlock/animation.h"
#include "sherlock/sherlock.h"
#include "sherlock/sprite.h"
#include "common/algorithm.h"
namespace Sherlock {
@ -62,7 +63,6 @@ static const int TITLE_FRAMES[7][9] = {
static const int NO_FRAMES = FRAMES_END;
Animation::Animation(SherlockEngine *vm): _vm(vm) {
_useEpilogue2 = false;
}
void Animation::playPrologue(const Common::String &filename, int minDelay, int fade,
@ -80,16 +80,19 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f
// Load the animation
Common::SeekableReadStream *stream;
if (!_titleOverride.empty())
stream = _vm->_res->load(vdxName, _titleOverride);
else if (_useEpilogue2)
if (!_vm->_titleOverride.empty())
stream = _vm->_res->load(vdxName, _vm->_titleOverride);
else if (_vm->_useEpilogue2)
stream = _vm->_res->load(vdxName, "epilog2.lib");
else
stream = _vm->_res->load(vdxName, "epilogoue.lib");
int resoucreIndex = _vm->_res->resouceIndex();
int resourceIndex = _vm->_res->resourceIndex();
// Load initial image
//Common::String vdaName = baseName + ".vda";
Common::String vdaName = baseName + ".vda";
Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName);
Sprite sprite(*vdaStream);
// TODO
@ -102,7 +105,7 @@ void Animation::playPrologue(const Common::String &filename, int minDelay, int f
const int *Animation::checkForSoundFrames(const Common::String &filename) {
const int *frames = &NO_FRAMES;
if (!_soundOverride.empty()) {
if (!_vm->_soundOverride.empty()) {
for (int idx = 0; idx < PROLOGUE_NAMES_COUNT; ++idx) {
if (!scumm_stricmp(filename.c_str(), PROLOGUE_NAMES[idx])) {
frames = &PROLOGUE_FRAMES[idx][0];

View File

@ -36,9 +36,6 @@ private:
const int *checkForSoundFrames(const Common::String &filename);
public:
Common::String _soundOverride;
Common::String _titleOverride;
bool _useEpilogue2;
public:
Animation(SherlockEngine *vm);

View File

@ -212,7 +212,7 @@ void Resources::loadLibraryIndex(const Common::String &libFilename,
* This will be used primarily when loading talk files, so the engine can
* update the given conversation number in the journal
*/
int Resources::resouceIndex() const {
int Resources::resourceIndex() const {
return _resourceIndex;
}

View File

@ -77,7 +77,7 @@ public:
Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile);
int resouceIndex() const;
int resourceIndex() const;
};

View File

@ -62,8 +62,8 @@ void ScalpelEngine::showCityCutscene() {
byte palette[PALETTE_SIZE];
_sound->playMusic("prolog1.mus");
_animation->_titleOverride = "title.lib";
_animation->_soundOverride = "title.snd";
_titleOverride = "title.lib";
_soundOverride = "title.snd";
_animation->playPrologue("26open1", 1, 255, true, 2);
// TODO

View File

@ -39,6 +39,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_screen = nullptr;
_sound = nullptr;
_talk = nullptr;
_useEpilogue2 = false;
}

View File

@ -80,6 +80,9 @@ public:
Sound *_sound;
Talk *_talk;
Common::Array<bool> _flags;
Common::String _soundOverride;
Common::String _titleOverride;
bool _useEpilogue2;
public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();

View File

@ -25,101 +25,61 @@
namespace Sherlock {
/*
struct SpriteFrame {
byte *data;
int width, height;
uint16 flags;
int xofs, yofs;
byte rleMarker;
};
*/
Sprite::Sprite(Common::SeekableReadStream &stream) {
load(stream);
}
Sprite::~Sprite() {
for (uint idx = 0; idx < size(); ++idx)
(*this)[idx]._frame.free();
}
int Sprite::getFrameCount() {
return _frames.size();
}
SpriteFrame *Sprite::getFrame(int index) {
return _frames[index];
}
/**
* Load the data of the sprite
*/
void Sprite::load(Common::SeekableReadStream &stream) {
while (!stream.eos()) {
debug("frameNum = %d\n", _frames.size());
SpriteFrame *spriteFrame = new SpriteFrame();
SpriteFrame frame;
uint32 startOfs = stream.pos();
debug("startOfs = %08X\n", startOfs);
spriteFrame->frame = NULL;
spriteFrame->width = stream.readUint16LE() + 1;
spriteFrame->height = stream.readUint16LE() + 1;
spriteFrame->flags = stream.readUint16LE();
frame._width = stream.readUint16LE() + 1;
frame._height = stream.readUint16LE() + 1;
frame._flags = stream.readUint16LE();
stream.readUint16LE();
debug("width = %d; height = %d; flags = %04X\n", spriteFrame->width, spriteFrame->height, spriteFrame->flags);
if (spriteFrame->flags & 0xFF) {
spriteFrame->size = (spriteFrame->width * spriteFrame->height) / 2;
} else if (spriteFrame->flags & 0x0100) {
if (frame._flags & 0xFF) {
frame._size = (frame._width * frame._height) / 2;
} else if (frame._flags & 0x0100) {
// this size includes the header size, which we subtract
spriteFrame->size = stream.readUint16LE() - 11;
spriteFrame->rleMarker = stream.readByte();
frame._size = stream.readUint16LE() - 11;
frame._rleMarker = stream.readByte();
} else {
spriteFrame->size = spriteFrame->width * spriteFrame->height;
frame._size = frame._width * frame._height;
}
spriteFrame->data = new byte[spriteFrame->size];
stream.read(spriteFrame->data, spriteFrame->size);
decompressFrame(spriteFrame);
// Load data for frame and decompress it
byte *data = new byte[frame._size];
stream.read(data, frame._size);
decompressFrame(frame, data);
delete data;
/*
debug("size = %d (%08X)\n", spriteFrame->size, spriteFrame->size);
if (spriteFrame->frame) {
char fn[128];
sndebug(fn, 128, "%04d.spr", _frames.size());
FILE *x = fopen(fn, "wb");
fwrite(spriteFrame->frame->pixels, spriteFrame->frame->w * spriteFrame->frame->h, 1, x);
fclose(x);
}
*/
_frames.push_back(spriteFrame);
push_back(frame);
}
// debug("Done: %08X\n", stream.pos()); fflush(stdout);
}
void Sprite::decompressFrame(SpriteFrame *frame) {
/**
* Decompress a single frame for the sprite
*/
void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) {
frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
frame->frame = new Graphics::Surface();
frame->frame->create(frame->width, frame->height, Graphics::PixelFormat::createFormatCLUT8());
if (frame->flags & 0xFF) {
debug("Sprite::decompressFrame() 4-bits/pixel\n");
debug("TODO\n");
} else if (frame->flags & 0x0100) {
debug("Sprite::decompressFrame() RLE-compressed; rleMarker = %02X\n", frame->rleMarker);
const byte *src = frame->data;
byte *dst = (byte *)frame->frame->getPixels();
for (uint16 h = 0; h < frame->height; h++) {
int16 w = frame->width;
if (frame._flags & 0xFF) {
debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n");
} else if (frame._flags & 0x0100) {
byte *dst = (byte *)frame._frame.getPixels();
for (uint16 h = 0; h < frame._height; ++h) {
int16 w = frame._width;
while (w > 0) {
if (*src == frame->rleMarker) {
if (*src == frame._rleMarker) {
byte rleColor = src[1];
byte rleCount = src[2];
src += 3;
@ -133,10 +93,10 @@ void Sprite::decompressFrame(SpriteFrame *frame) {
}
}
} else {
debug("Sprite::decompressFrame() Uncompressed\n");
memcpy(frame->data, frame->frame->getPixels(), frame->width * frame->height);
// Uncompressed frame
Common::copy(src, src + frame._width * frame._height,
(byte *)frame._frame.getPixels());
}
}
} // End of namespace Sherlock

View File

@ -23,32 +23,29 @@
#ifndef SHERLOCK_SPRITE_H
#define SHERLOCK_SPRITE_H
#include "common/stream.h"
#include "common/array.h"
#include "common/rect.h"
#include "common/stream.h"
#include "graphics/surface.h"
namespace Sherlock {
struct SpriteFrame {
byte *data;
uint32 size;
uint16 width, height;
uint16 flags;
int xofs, yofs;
byte rleMarker;
Graphics::Surface *frame;
uint32 _size;
uint16 _width, _height;
int _flags;
Common::Point _offset;
byte _rleMarker;
Graphics::Surface _frame;
};
class Sprite {
class Sprite: public Common::Array<SpriteFrame> {
private:
void load(Common::SeekableReadStream &stream);
void decompressFrame(SpriteFrame &frame, const byte *src);
public:
Sprite(Common::SeekableReadStream &stream);
~Sprite();
int getFrameCount();
SpriteFrame *getFrame(int index);
protected:
Common::Array<SpriteFrame*> _frames;
void load(Common::SeekableReadStream &stream);
void decompressFrame(SpriteFrame *frame);
};
} // End of namespace Sherlock