aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/composer/composer.h2
-rw-r--r--engines/composer/graphics.cpp53
2 files changed, 52 insertions, 3 deletions
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index ab70c864bc..ad0bbf8d04 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -144,6 +144,7 @@ private:
uint16 _currSoundPriority;
bool _needsUpdate;
+ Common::Array<Common::Rect> _dirtyRects;
Graphics::Surface _surface;
Common::List<Sprite> _sprites;
@@ -199,6 +200,7 @@ private:
const Sprite *getSpriteAtPos(const Common::Point &pos);
const Button *getButtonFor(const Sprite *sprite, const Common::Point &pos);
+ void dirtySprite(const Sprite &sprite);
void redraw();
void loadCTBL(uint16 id, uint fadePercent);
void setBackground(uint16 id);
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index bbe2e9fa3e..aaff7c1663 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -381,10 +381,13 @@ Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const
if (i->_animId && animId && (i->_animId != animId))
continue;
+ dirtySprite(*i);
+
// if the zordering is identical, modify it in-place
if (i->_zorder == zorder) {
i->_animId = animId;
i->_pos = pos;
+ dirtySprite(*i);
return &(*i);
}
@@ -402,11 +405,13 @@ Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const
if (!foundSprite) {
sprite._id = id;
if (!initSprite(sprite)) {
- warning("ignoring addSprite on invalid sprite %d", id);
+ debug(1, "ignoring addSprite on invalid sprite %d", id);
return NULL;
}
}
+ dirtySprite(sprite);
+
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
if (sprite._zorder <= i->_zorder)
continue;
@@ -425,6 +430,7 @@ void ComposerEngine::removeSprite(uint16 id, uint16 animId) {
continue;
if (i->_animId && animId && (i->_animId != animId))
continue;
+ dirtySprite(*i);
i->_surface.free();
i = _sprites.reverse_erase(i);
if (id)
@@ -445,14 +451,49 @@ const Sprite *ComposerEngine::getSpriteAtPos(const Common::Point &pos) {
return NULL;
}
+void ComposerEngine::dirtySprite(const Sprite &sprite) {
+ Common::Rect rect(sprite._pos.x, sprite._pos.y, sprite._pos.x + sprite._surface.w, sprite._pos.y + sprite._surface.h);
+ rect.clip(_surface.w, _surface.h);
+ if (rect.isEmpty())
+ return;
+
+ for (uint i = 0; i < _dirtyRects.size(); i++) {
+ if (!_dirtyRects[i].intersects(rect))
+ continue;
+ _dirtyRects[i].extend(rect);
+ return;
+ }
+
+ _dirtyRects.push_back(rect);
+}
+
void ComposerEngine::redraw() {
+ if (!_needsUpdate && _dirtyRects.empty())
+ return;
+
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
+ Common::Rect rect(i->_pos.x, i->_pos.y, i->_pos.x + i->_surface.w, i->_pos.y + i->_surface.h);
+ bool intersects = false;
+ for (uint j = 0; j < _dirtyRects.size(); j++) {
+ if (!_dirtyRects[j].intersects(rect))
+ continue;
+ intersects = true;
+ break;
+ }
+ if (!intersects)
+ continue;
drawSprite(*i);
}
- _system->copyRectToScreen((byte *)_surface.pixels, _surface.pitch, 0, 0, _surface.w, _surface.h);
+ for (uint i = 0; i < _dirtyRects.size(); i++) {
+ const Common::Rect &rect = _dirtyRects[i];
+ byte *pixels = (byte *)_surface.pixels + (rect.top * _surface.pitch) + rect.left;
+ _system->copyRectToScreen(pixels, _surface.pitch, rect.left, rect.top, rect.width(), rect.height());
+ }
_system->updateScreen();
+
_needsUpdate = false;
+ _dirtyRects.clear();
}
void ComposerEngine::loadCTBL(uint16 id, uint fadePercent) {
@@ -472,15 +513,19 @@ void ComposerEngine::loadCTBL(uint16 id, uint fadePercent) {
buffer[i] = ((unsigned int)buffer[i] * fadePercent) / 100;
_system->getPaletteManager()->setPalette(buffer, 0, numEntries);
+ _needsUpdate = true;
}
void ComposerEngine::setBackground(uint16 id) {
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
if (i->_id)
continue;
+ dirtySprite(*i);
i->_surface.free();
i->_id = id;
- initSprite(*i);
+ if (!initSprite(*i))
+ error("failed to set background %d", id);
+ dirtySprite(*i);
i->_id = 0;
return;
}
@@ -686,6 +731,8 @@ bool ComposerEngine::initSprite(Sprite &sprite) {
// RLE sprites since the width/height is ignored until the actual draw
if (type != kBitmapRLESLWM)
error("sprite (type %d) had invalid size %dx%d", type, width, height);
+ delete stream;
+ return false;
}
delete stream;