mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
SHERLOCK: Add dirty rect handling
This commit is contained in:
parent
4b5cbc5897
commit
59c124aa60
@ -44,8 +44,21 @@ void Screen::setFont(int fontNumber) {
|
||||
}
|
||||
|
||||
void Screen::update() {
|
||||
g_system->copyRectToScreen(getPixels(), this->w, 0, 0, this->w, this->h);
|
||||
// Merge the dirty rects
|
||||
mergeDirtyRects();
|
||||
|
||||
// Loop through copying dirty areas to the physical screen
|
||||
Common::List<Common::Rect>::iterator i;
|
||||
for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
|
||||
const Common::Rect &r = *i;
|
||||
const byte *srcP = (const byte *)getBasePtr(r.left, r.top);
|
||||
g_system->copyRectToScreen(srcP, this->pitch, r.left, r.top,
|
||||
r.width(), r.height());
|
||||
}
|
||||
|
||||
// Signal the physical screen to update
|
||||
g_system->updateScreen();
|
||||
_dirtyRects.clear();
|
||||
}
|
||||
|
||||
void Screen::getPalette(byte palette[PALETTE_SIZE]) {
|
||||
@ -104,4 +117,57 @@ void Screen::fadeToBlack() {
|
||||
} while (repeatFlag && !_vm->shouldQuit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rectangle to the list of modified areas of the screen during the
|
||||
* current frame
|
||||
*/
|
||||
void Screen::addDirtyRect(const Common::Rect &r) {
|
||||
_dirtyRects.push_back(r);
|
||||
assert(r.isValidRect() && r.width() > 0 && r.height() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges together overlapping dirty areas of the screen
|
||||
*/
|
||||
void Screen::mergeDirtyRects() {
|
||||
Common::List<Common::Rect>::iterator rOuter, rInner;
|
||||
|
||||
// Ensure dirty rect list has at least two entries
|
||||
rOuter = _dirtyRects.begin();
|
||||
for (int i = 0; i < 2; ++i, ++rOuter) {
|
||||
if (rOuter == _dirtyRects.end())
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the dirty rect list to find any rects to merge
|
||||
for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
|
||||
rInner = rOuter;
|
||||
while (++rInner != _dirtyRects.end()) {
|
||||
|
||||
if ((*rOuter).intersects(*rInner)) {
|
||||
// these two rectangles overlap or
|
||||
// are next to each other - merge them
|
||||
|
||||
unionRectangle(*rOuter, *rOuter, *rInner);
|
||||
|
||||
// remove the inner rect from the list
|
||||
_dirtyRects.erase(rInner);
|
||||
|
||||
// move back to beginning of list
|
||||
rInner = rOuter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the union of two dirty area rectangles
|
||||
*/
|
||||
bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) {
|
||||
destRect = src1;
|
||||
destRect.extend(src2);
|
||||
|
||||
return !destRect.isEmpty();
|
||||
}
|
||||
|
||||
} // End of namespace Sherlock
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef SHERLOCK_SCREEN_H
|
||||
#define SHERLOCK_SCREEN_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/rect.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
@ -40,6 +41,13 @@ private:
|
||||
SherlockEngine *_vm;
|
||||
int _fontNumber;
|
||||
Surface _backBuffer1, _backBuffer2;
|
||||
Common::List<Common::Rect> _dirtyRects;
|
||||
|
||||
void mergeDirtyRects();
|
||||
|
||||
bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
|
||||
protected:
|
||||
virtual void addDirtyRect(const Common::Rect &r);
|
||||
public:
|
||||
Screen(SherlockEngine *vm);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user