Skip to content

Commit

Permalink
XEEN: Converted SpriteResource to decoding sprite frames on the fly
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Dec 26, 2014
1 parent 4f423c7 commit d213db3
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 100 deletions.
7 changes: 2 additions & 5 deletions engines/xeen/darkside/darkside_game.cpp
Expand Up @@ -59,11 +59,10 @@ void DarkSideEngine::darkSideIntro() {

bool breakFlag = false;
int nwcIndex = 0, nwcFrame = 0;
for (int idx = 0; idx < 55 && !shouldQuit(); ++idx) {
for (int idx = 0; idx < 55 && !shouldQuit() && !breakFlag; ++idx) {
_events->updateGameCounter();
_screen->vertMerge(0);
const XSurface &frame = nwc[nwcIndex].getFrame(nwcFrame);
_screen->transBlitFrom(frame, Common::Point(0, 0));
nwc[nwcIndex].draw(*_screen, nwcFrame, Common::Point(0, 0));
_screen->draw();

switch (idx) {
Expand Down Expand Up @@ -91,8 +90,6 @@ void DarkSideEngine::darkSideIntro() {
}
}
}


}

} // End of namespace Xeen
79 changes: 30 additions & 49 deletions engines/xeen/resources.cpp
Expand Up @@ -217,70 +217,45 @@ void File::openFile(const Common::String &filename) {
/*------------------------------------------------------------------------*/

SpriteResource::SpriteResource(const Common::String &filename) {
// Open the resource
File f(filename);

// Read in the index
int count = f.readUint16LE();
Common::Array<uint32> index;
index.resize(count);
for (int i = 0; i < count; ++i)
index[i] = f.readUint32LE();

// Process each shape
_frames.resize(count);
for (int i = 0; i < count; ++i) {
uint16 cell1 = index[i] & 0xffff, cell2 = index[i] >> 16;
assert(cell1);
_index.resize(count);

setFrameSize(f, cell1, cell2, _frames[i]);
decodeFrame(f, cell1, _frames[i]);
decodeFrame(f, cell2, _frames[i]);
for (int i = 0; i < count; ++i) {
_index[i]._offset1 = f.readUint16LE();
_index[i]._offset2 = f.readUint16LE();
}
}

int SpriteResource::size() const {
return _frames.size();
// Read in a copy of the file
_filesize = f.size();
_data = new byte[_filesize];
f.seek(0);
f.read(_data, _filesize);
}

const XSurface &SpriteResource::getFrame(int frame) {
return _frames[frame];
SpriteResource::~SpriteResource() {
delete[] _data;
}

void SpriteResource::setFrameSize(File &f, uint16 offset1, uint16 offset2, XSurface &s) {
int maxWidth = 0, maxHeight = 0;

// Check each of the two cells for the frame for their sizes
for (int i = 0; i < 2; ++i) {
uint16 offset = (i == 0) ? offset1 : offset2;
if (!offset)
break;

// Get the cell dimensions
f.seek(offset);
int x = f.readUint16LE();
int w = f.readUint16LE();
int y = f.readUint16LE();
int h = f.readUint16LE();

// Check for total size of the frame
if ((x + w) > maxWidth)
maxWidth = x + w;
if ((y + h) > maxHeight)
maxHeight = x + h;
}
int SpriteResource::size() const {
return _index.size();
}

// Create the surface
s.create(maxWidth, maxHeight);

// Empty the surface
s.fillRect(Common::Rect(0, 0, maxWidth, maxHeight), 0);
void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos) const {
drawOffset(dest, _index[frame]._offset1, destPos);
if (_index[frame]._offset2)
drawOffset(dest, _index[frame]._offset2, destPos);
}

void SpriteResource::decodeFrame(File &f, uint16 offset, XSurface &s) {
void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Point &destPos) const {
// Get cell header
Common::MemoryReadStream f(_data, _filesize);
f.seek(offset);
int xOffset = f.readUint16LE();
f.skip(2);
int width = f.readUint16LE();
int yOffset = f.readUint16LE();
int height = f.readUint16LE();

Expand All @@ -300,7 +275,7 @@ void SpriteResource::decodeFrame(File &f, uint16 offset, XSurface &s) {
} else {
// Skip the transparent pixels at the beginning of the scan line
int xPos = f.readByte() + xOffset; ++byteCount;
byte *destP = (byte *)s.getBasePtr(xPos, yPos);
byte *destP = (byte *)dest.getBasePtr(destPos.x + xPos, destPos.y + yPos);

while (byteCount < lineLength) {
// The next byte is an opcode that determines what
Expand All @@ -314,8 +289,9 @@ void SpriteResource::decodeFrame(File &f, uint16 offset, XSurface &s) {
switch (cmd) {
case 0: // The following len + 1 bytes are stored as indexes into the color table.
case 1: // The following len + 33 bytes are stored as indexes into the color table.
for (int i = 0; i < opcode + 1; ++i, ++xPos)
for (int i = 0; i < opcode + 1; ++i, ++xPos) {
*destP++ = f.readByte(); ++byteCount;
}
break;

case 2: // The following byte is an index into the color table, draw it len + 3 times.
Expand Down Expand Up @@ -364,8 +340,13 @@ void SpriteResource::decodeFrame(File &f, uint16 offset, XSurface &s) {
break;
}
}

assert(byteCount == lineLength);
}
}

dest.addDirtyRect(Common::Rect(destPos.x, destPos.y,
destPos.x + xOffset + width, destPos.y + yOffset + height));
}

} // End of namespace Xeen
14 changes: 10 additions & 4 deletions engines/xeen/resources.h
Expand Up @@ -55,17 +55,23 @@ class File : public Common::File {

class SpriteResource {
private:
Common::Array<XSurface> _frames;
struct IndexEntry {
uint16 _offset1, _offset2;
};
Common::Array<IndexEntry> _index;

void setFrameSize(File &f, uint16 offset1, uint16 offset2, XSurface &s);
int32 _filesize;
byte *_data;

void decodeFrame(File &f, uint16 offset, XSurface &s);
void drawOffset(XSurface &dest, uint16 offset, const Common::Point &destPos) const;
public:
SpriteResource(const Common::String &filename);

~SpriteResource();

int size() const;

const XSurface &getFrame(int frame);
void draw(XSurface &dest, int frame, const Common::Point &destPos) const;
};

} // End of namespace Xeen
Expand Down
18 changes: 6 additions & 12 deletions engines/xeen/screen.cpp
Expand Up @@ -33,6 +33,7 @@ namespace Xeen {
*/
Screen::Screen(XeenEngine *vm) : _vm(vm) {
_fadeMode = false;
create(SCREEN_WIDTH, SCREEN_HEIGHT);
}

void Screen::update() {
Expand All @@ -57,16 +58,6 @@ void Screen::addDirtyRect(const Common::Rect &r) {
_dirtyRects.push_back(r);
}

void Screen::transBlitFrom(const XSurface &src, const Common::Point &destPos) {
XSurface::transBlitFrom(src, destPos);
addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + src.w, destPos.y + src.h));
}

void Screen::blitFrom(const XSurface &src, const Common::Point &destPos) {
XSurface::blitFrom(src, destPos);
addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + src.w, destPos.y + src.h));
}

void Screen::mergeDirtyRects() {
Common::List<Common::Rect>::iterator rOuter, rInner;

Expand Down Expand Up @@ -110,7 +101,8 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co
*/
void Screen::loadPalette(const Common::String &name) {
File f(name);
f.read(_tempPaltte, PALETTE_SIZE);
for (int i = 0; i < PALETTE_SIZE; ++i)
_tempPaltte[i] = f.readByte() << 2;
}

/**
Expand All @@ -133,7 +125,7 @@ void Screen::loadPage(int pageNum) {
_pages[1].create(SCREEN_WIDTH, SCREEN_HEIGHT);
}

_pages[pageNum].blitFrom(*this);
blitTo(_pages[pageNum]);
}

/**
Expand Down Expand Up @@ -217,6 +209,8 @@ void Screen::fadeInner(int step) {

updatePalette();
}

_vm->_events->pollEventsAndWait();
}
}

Expand Down
6 changes: 1 addition & 5 deletions engines/xeen/screen.h
Expand Up @@ -59,16 +59,12 @@ class Screen: public XSurface {

void updatePalette(const byte *pal, int start, int count16);
public:
virtual void transBlitFrom(const XSurface &src, const Common::Point &destPos);

virtual void blitFrom(const XSurface &src, const Common::Point &destPos);
virtual void addDirtyRect(const Common::Rect &r);
public:
Screen(XeenEngine *vm);

void update();

void addDirtyRect(const Common::Rect &r);

void loadPalette(const Common::String &name);

void loadBackground(const Common::String &name);
Expand Down
43 changes: 23 additions & 20 deletions engines/xeen/xsurface.cpp
Expand Up @@ -20,6 +20,7 @@
*
*/

#include "common/algorithm.h"
#include "xeen/xsurface.h"

namespace Xeen {
Expand All @@ -39,41 +40,43 @@ void XSurface::create(uint16 w, uint16 h) {
Graphics::Surface::create(w, h, Graphics::PixelFormat::createFormatCLUT8());
}

void XSurface::transBlitFrom(const XSurface &src) {
transBlitFrom(src, Common::Point());
void XSurface::transBlitTo(XSurface &dest) const {
transBlitTo(dest, Common::Point());
}

void XSurface::blitFrom(const XSurface &src) {
blitFrom(src, Common::Point());
void XSurface::blitTo(XSurface &dest) const {
blitTo(dest, Common::Point());
}

void XSurface::transBlitFrom(const XSurface &src, const Common::Point &destPos) {
if (getPixels() == nullptr)
create(w, h);
void XSurface::transBlitTo(XSurface &dest, const Common::Point &destPos) const {
if (dest.getPixels() == nullptr)
dest.create(w, h);

for (int yp = 0; yp < src.h; ++yp) {
const byte *srcP = (const byte *)src.getBasePtr(0, yp);
byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yp);
for (int yp = 0; yp < h; ++yp) {
const byte *srcP = (const byte *)getBasePtr(0, yp);
byte *destP = (byte *)dest.getBasePtr(destPos.x, destPos.y + yp);

for (int xp = 0; xp < this->w; ++xp, ++srcP, ++destP) {
for (int xp = 0; xp < w; ++xp, ++srcP, ++destP) {
if (*srcP != 0)
*destP = *srcP;
}
}

dest.addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + w, destPos.y));
}

void XSurface::blitFrom(const XSurface &src, const Common::Point &destPos) {
if (getPixels() == nullptr)
create(w, h);
void XSurface::blitTo(XSurface &dest, const Common::Point &destPos) const {
if (dest.getPixels() == nullptr)
dest.create(w, h);

for (int yp = 0; yp < src.h; ++yp) {
const byte *srcP = (const byte *)src.getBasePtr(0, yp);
byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yp);
for (int yp = 0; yp < h; ++yp) {
const byte *srcP = (const byte *)getBasePtr(0, yp);
byte *destP = (byte *)dest.getBasePtr(destPos.x, destPos.y + yp);

for (int xp = 0; xp < this->w; ++xp, ++srcP, ++destP) {
*destP = *srcP;
}
Common::copy(srcP, srcP + w, destP);
}

dest.addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + w, destPos.y));
}

} // End of namespace Xeen
12 changes: 7 additions & 5 deletions engines/xeen/xsurface.h
Expand Up @@ -32,19 +32,21 @@ namespace Xeen {

class XSurface: public Graphics::Surface {
public:
virtual void transBlitFrom(const XSurface &src, const Common::Point &destPos);

virtual void blitFrom(const XSurface &src, const Common::Point &destPos);
virtual void addDirtyRect(const Common::Rect &r) {}
public:
XSurface();
XSurface(int w, int h);
~XSurface();

void create(uint16 w, uint16 h);

void transBlitFrom(const XSurface &src);
void transBlitTo(XSurface &dest) const;

void transBlitTo(XSurface &dest, const Common::Point &destPos) const;

void blitTo(XSurface &dest, const Common::Point &destPos) const;

void blitFrom(const XSurface &src);
void blitTo(XSurface &dest) const;

bool empty() const { return getPixels() == nullptr; }
};
Expand Down

0 comments on commit d213db3

Please sign in to comment.