mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 01:08:25 +00:00
XEEN: Converted SpriteResource to decoding sprite frames on the fly
This commit is contained in:
parent
4f423c74b7
commit
d213db3dc1
@ -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) {
|
||||
@ -91,8 +90,6 @@ void DarkSideEngine::darkSideIntro() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace Xeen
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// Read in a copy of the file
|
||||
_filesize = f.size();
|
||||
_data = new byte[_filesize];
|
||||
f.seek(0);
|
||||
f.read(_data, _filesize);
|
||||
}
|
||||
|
||||
SpriteResource::~SpriteResource() {
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
int SpriteResource::size() const {
|
||||
return _frames.size();
|
||||
return _index.size();
|
||||
}
|
||||
|
||||
const XSurface &SpriteResource::getFrame(int frame) {
|
||||
return _frames[frame];
|
||||
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::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;
|
||||
}
|
||||
|
||||
// Create the surface
|
||||
s.create(maxWidth, maxHeight);
|
||||
|
||||
// Empty the surface
|
||||
s.fillRect(Common::Rect(0, 0, maxWidth, maxHeight), 0);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -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
|
||||
@ -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.
|
||||
@ -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
|
||||
|
@ -55,17 +55,23 @@ public:
|
||||
|
||||
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
|
||||
|
@ -33,6 +33,7 @@ namespace Xeen {
|
||||
*/
|
||||
Screen::Screen(XeenEngine *vm) : _vm(vm) {
|
||||
_fadeMode = false;
|
||||
create(SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
void Screen::update() {
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +125,7 @@ void Screen::loadPage(int pageNum) {
|
||||
_pages[1].create(SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
_pages[pageNum].blitFrom(*this);
|
||||
blitTo(_pages[pageNum]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,6 +209,8 @@ void Screen::fadeInner(int step) {
|
||||
|
||||
updatePalette();
|
||||
}
|
||||
|
||||
_vm->_events->pollEventsAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,16 +59,12 @@ private:
|
||||
|
||||
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);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/algorithm.h"
|
||||
#include "xeen/xsurface.h"
|
||||
|
||||
namespace Xeen {
|
||||
@ -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
|
||||
|
@ -32,9 +32,7 @@ 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);
|
||||
@ -42,9 +40,13 @@ public:
|
||||
|
||||
void create(uint16 w, uint16 h);
|
||||
|
||||
void transBlitFrom(const XSurface &src);
|
||||
void transBlitTo(XSurface &dest) const;
|
||||
|
||||
void blitFrom(const XSurface &src);
|
||||
void transBlitTo(XSurface &dest, const Common::Point &destPos) const;
|
||||
|
||||
void blitTo(XSurface &dest, const Common::Point &destPos) const;
|
||||
|
||||
void blitTo(XSurface &dest) const;
|
||||
|
||||
bool empty() const { return getPixels() == nullptr; }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user