aboutsummaryrefslogtreecommitdiff
path: root/engines/toltecs/sprite.cpp
diff options
context:
space:
mode:
authorBenjamin Haisch2008-09-20 19:06:41 +0000
committerWillem Jan Palenstijn2011-11-20 22:43:06 +0100
commit7b97e8cd9370095b999b22371c1aef606a8464a1 (patch)
tree5b498423cef9e27432934da0b19794fbc1f2c038 /engines/toltecs/sprite.cpp
parent37a5f9e9ef9039808b225f598d02c1c48bc9fa95 (diff)
downloadscummvm-rg350-7b97e8cd9370095b999b22371c1aef606a8464a1.tar.gz
scummvm-rg350-7b97e8cd9370095b999b22371c1aef606a8464a1.tar.bz2
scummvm-rg350-7b97e8cd9370095b999b22371c1aef606a8464a1.zip
TOLTECS: A lot of changes in the graphics code:
- Optimized drawing code; now only items (sprites, text, screen masks) which have changed from the previous frame are redrawn, this speeds up things a lot - Implemented dirty rectangles using a microtile array - The previously committed Microtile Array implementation from SEL seemed buggy so I wrote my own version which works nicely so far (and is less code and GPL), only MicroTileArray::getRectangles uses parts from the old version, this will be changed later - One known bug related to dirty rectangles remains: Sometimes the background isn't restored correctly and gfx artifacts are visible
Diffstat (limited to 'engines/toltecs/sprite.cpp')
-rw-r--r--engines/toltecs/sprite.cpp79
1 files changed, 34 insertions, 45 deletions
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 3327f04bdd..4e5af5f293 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -36,6 +36,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
#include "toltecs/script.h"
@@ -45,7 +46,7 @@ namespace Toltecs {
class SpriteReader : public SpriteFilter {
public:
- SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ SpriteReader(byte *source, const SpriteDrawItem &sprite) : SpriteFilter(sprite), _source(source) {
_curWidth = _sprite->origWidth;
_curHeight = _sprite->origHeight;
}
@@ -95,7 +96,7 @@ protected:
class SpriteFilterScaleDown : public SpriteFilter {
public:
- SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleDown(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
@@ -146,7 +147,7 @@ protected:
class SpriteFilterScaleUp : public SpriteFilter {
public:
- SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleUp(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
@@ -205,12 +206,15 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (drawRequest.flags == 0xFFFF)
return;
+ frameNum = drawRequest.flags & 0x0FFF;
+
sprite.flags = 0;
sprite.baseColor = drawRequest.baseColor;
sprite.x = drawRequest.x;
sprite.y = drawRequest.y;
sprite.priority = drawRequest.y;
sprite.resIndex = drawRequest.resIndex;
+ sprite.frameNum = frameNum;
spriteData = _vm->_res->load(drawRequest.resIndex);
@@ -226,8 +230,6 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.flags |= 0x40;
}
- frameNum = drawRequest.flags & 0x0FFF;
-
// First initialize the sprite item with the values from the sprite resource
SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
@@ -391,48 +393,43 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (sprite.width <= 0)
return;
- // Add sprite sorted by priority
- Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
- while (iter != _spriteDrawList.end() && (*iter).priority <= sprite.priority) {
- iter++;
- }
- _spriteDrawList.insert(iter, sprite);
+ _renderQueue->addSprite(sprite);
}
-void Screen::drawSprite(SpriteDrawItem *sprite) {
+void Screen::drawSprite(const SpriteDrawItem &sprite) {
debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
- sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
- sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
+ sprite.x, sprite.y, sprite.flags, sprite.resIndex, sprite.offset,
+ sprite.x - _vm->_cameraX, sprite.y - _vm->_cameraY);
debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
- sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
+ sprite.width, sprite.height, sprite.origWidth, sprite.origHeight);
- byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
- byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
+ byte *source = _vm->_res->load(sprite.resIndex) + sprite.offset;
+ byte *dest = _frontScreen + sprite.x + sprite.y * 640;
SpriteReader spriteReader(source, sprite);
- if (sprite->flags & 0x40) {
+ if (sprite.flags & 0x40) {
// Shadow sprites
- if (sprite->flags & 1) {
+ if (sprite.flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
+ } else if (sprite.flags & 2) {
SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else {
drawSpriteCore(dest, spriteReader, sprite);
}
- } else if (sprite->flags & 0x10) {
+ } else if (sprite.flags & 0x10) {
// 256 color sprite
drawSpriteCore(dest, spriteReader, sprite);
} else {
// 16 color sprite
- if (sprite->flags & 1) {
+ if (sprite.flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
+ } else if (sprite.flags & 2) {
SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else {
@@ -444,13 +441,13 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
}
-void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite) {
+void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite) {
int16 destInc;
- if (sprite->flags & 4) {
+ if (sprite.flags & 4) {
destInc = -1;
- dest += sprite->width;
+ dest += sprite.width;
} else {
destInc = 1;
}
@@ -459,10 +456,10 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
PixelPacket packet;
byte *destp = dest;
- int16 skipX = sprite->skipX;
+ int16 skipX = sprite.skipX;
- int16 w = sprite->width;
- int16 h = sprite->height;
+ int16 w = sprite.width;
+ int16 h = sprite.height;
do {
status = reader.readPacket(packet);
@@ -483,20 +480,20 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
w -= packet.count;
- if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
- ((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
- !(sprite->flags & 0x10) && (packet.pixel != 0))
+ if (((sprite.flags & 0x40) && (packet.pixel != 0)) ||
+ ((sprite.flags & 0x10) && (packet.pixel != 0xFF)) ||
+ !(sprite.flags & 0x10) && (packet.pixel != 0))
{
- if (sprite->flags & 0x40) {
+ if (sprite.flags & 0x40) {
while (packet.count--) {
*dest = _vm->_palette->getColorTransPixel(*dest);
dest += destInc;
}
} else {
- if (sprite->flags & 0x10) {
+ if (sprite.flags & 0x10) {
packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
} else {
- packet.pixel += sprite->baseColor - 1;
+ packet.pixel += sprite.baseColor - 1;
}
while (packet.count--) {
*dest = packet.pixel;
@@ -515,8 +512,8 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
dest = destp + 640;
destp = dest;
- skipX = sprite->skipX;
- w = sprite->width;
+ skipX = sprite.skipX;
+ w = sprite.width;
h--;
}
@@ -524,12 +521,4 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
-void Screen::drawSprites() {
- for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
- SpriteDrawItem *sprite = &(*iter);
- drawSprite(sprite);
- _vm->_segmap->restoreMasksBySprite(sprite);
- }
-}
-
} // End of namespace Toltecs