KYRA: Replaced Rect class by Common::Rect; replaced dirty rect handling code by code similiar to the one used in SAGA and the frontend GUI code

svn-id: r39929
This commit is contained in:
Max Horn 2009-04-11 09:57:57 +00:00
parent 7287457672
commit 5749b363d5
6 changed files with 67 additions and 74 deletions

View file

@ -57,12 +57,12 @@ int KyraEngine_LoK::findDuplicateItemShape(int shape) {
void KyraEngine_LoK::addToNoDropRects(int x, int y, int w, int h) { void KyraEngine_LoK::addToNoDropRects(int x, int y, int w, int h) {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h); debugC(9, kDebugLevelMain, "KyraEngine_LoK::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h);
for (int rect = 0; rect < 11; ++rect) { for (int rect = 0; rect < ARRAYSIZE(_noDropRects); ++rect) {
if (_noDropRects[rect].x == -1) { if (_noDropRects[rect].top == -1) {
_noDropRects[rect].x = x; _noDropRects[rect].left = x;
_noDropRects[rect].y = y; _noDropRects[rect].top = y;
_noDropRects[rect].x2 = x + w - 1; _noDropRects[rect].right = x + w;
_noDropRects[rect].y2 = y + h - 1; _noDropRects[rect].bottom = y + h;
break; break;
} }
} }
@ -466,25 +466,25 @@ int KyraEngine_LoK::checkNoDropRects(int x, int y) {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkNoDropRects(%d, %d)", x, y); debugC(9, kDebugLevelMain, "KyraEngine_LoK::checkNoDropRects(%d, %d)", x, y);
if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16)
_lastProcessedItemHeight = 16; _lastProcessedItemHeight = 16;
if (_noDropRects[0].x == -1) if (_noDropRects[0].left == -1)
return 0; return 0;
for (int i = 0; i < 11; ++i) { for (int i = 0; i < ARRAYSIZE(_noDropRects); ++i) {
if (_noDropRects[i].x == -1) if (_noDropRects[i].left == -1)
break; break;
int xpos = _noDropRects[i].x; int xpos = _noDropRects[i].left;
int ypos = _noDropRects[i].y; int ypos = _noDropRects[i].top;
int xpos2 = _noDropRects[i].x2; int xpos2 = _noDropRects[i].right;
int ypos2 = _noDropRects[i].y2; int ypos2 = _noDropRects[i].bottom;
if (xpos > x + 16) if (xpos > x + 16)
continue; continue;
if (xpos2 < x) if (xpos2 <= x)
continue; continue;
if (y < ypos) if (y < ypos)
continue; continue;
if (ypos2 < y - _lastProcessedItemHeight) if (ypos2 <= y - _lastProcessedItemHeight)
continue; continue;
return 1; return 1;
} }

View file

@ -422,7 +422,7 @@ protected:
int32 _scaleMode; int32 _scaleMode;
int16 _scaleTable[145]; int16 _scaleTable[145];
Rect _noDropRects[11]; Common::Rect _noDropRects[11];
int8 _birthstoneGemTable[4]; int8 _birthstoneGemTable[4];
int8 _idolGemsTable[3]; int8 _idolGemsTable[3];

View file

@ -62,8 +62,6 @@ Screen::~Screen() {
delete[] _palettes[i]; delete[] _palettes[i];
} }
delete[] _dirtyRects;
CursorMan.popAllCursors(); CursorMan.popAllCursors();
} }
@ -162,9 +160,6 @@ bool Screen::init() {
CursorMan.showMouse(false); CursorMan.showMouse(false);
_forceFullUpdate = false; _forceFullUpdate = false;
_numDirtyRects = 0;
_dirtyRects = new Rect[kMaxDirtyRects];
assert(_dirtyRects);
return true; return true;
} }
@ -234,13 +229,13 @@ void Screen::updateDirtyRects() {
_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
} else { } else {
const byte *page0 = getCPagePtr(0); const byte *page0 = getCPagePtr(0);
for (int i = 0; i < _numDirtyRects; ++i) { Common::List<Common::Rect>::iterator it;
Rect &cur = _dirtyRects[i]; for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
_system->copyRectToScreen(page0 + cur.y * SCREEN_W + cur.x, SCREEN_W, cur.x, cur.y, cur.x2, cur.y2); _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height());
} }
} }
_forceFullUpdate = false; _forceFullUpdate = false;
_numDirtyRects = 0; _dirtyRects.clear();
} }
void Screen::updateDirtyRectsOvl() { void Screen::updateDirtyRectsOvl() {
@ -255,18 +250,18 @@ void Screen::updateDirtyRectsOvl() {
const byte *page0 = getCPagePtr(0); const byte *page0 = getCPagePtr(0);
byte *ovl0 = _sjisOverlayPtrs[0]; byte *ovl0 = _sjisOverlayPtrs[0];
for (int i = 0; i < _numDirtyRects; ++i) { Common::List<Common::Rect>::iterator it;
Rect &cur = _dirtyRects[i]; for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
byte *dst = ovl0 + cur.y * 1280 + (cur.x<<1); byte *dst = ovl0 + it->top * 1280 + (it->left<<1);
const byte *src = page0 + cur.y * SCREEN_W + cur.x; const byte *src = page0 + it->top * SCREEN_W + it->left;
scale2x(dst, 640, src, SCREEN_W, cur.x2, cur.y2); scale2x(dst, 640, src, SCREEN_W, it->width(), it->height());
mergeOverlay(cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1); mergeOverlay(it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
_system->copyRectToScreen(dst, 640, cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1); _system->copyRectToScreen(dst, 640, it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
} }
} }
_forceFullUpdate = false; _forceFullUpdate = false;
_numDirtyRects = 0; _dirtyRects.clear();
} }
void Screen::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) { void Screen::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
@ -2835,35 +2830,38 @@ void Screen::loadPalette(const byte *data, uint8 *palData, int bytes) {
// dirty rect handling // dirty rect handling
void Screen::addDirtyRect(int x, int y, int w, int h) { void Screen::addDirtyRect(int x, int y, int w, int h) {
if (_numDirtyRects == kMaxDirtyRects || _forceFullUpdate) { if (_dirtyRects.size() >= kMaxDirtyRects || _forceFullUpdate) {
_forceFullUpdate = true; _forceFullUpdate = true;
return; return;
} }
if (w == 0 || h == 0 || x >= SCREEN_W || y >= SCREEN_H || x + w < 0 || y + h < 0) Common::Rect r(x, y, x + w, y + h);
// Clip rectangle
r.clip(SCREEN_W, SCREEN_H);
// If it is empty after clipping, we are done
if (r.isEmpty())
return; return;
if (x < 0) { // Check if the new rectangle is contained within another in the list
w += x; Common::List<Common::Rect>::iterator it;
x = 0; for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ) {
// If we find a rectangle which fully contains the new one,
// we can abort the search.
if (it->contains(r))
return;
// Conversely, if we find rectangles which are contained in
// the new one, we can remove them
if (r.contains(*it))
it = _dirtyRects.erase(it);
else
++it;
} }
if (x + w >= 320) // If we got here, we can safely add r to the list of dirty rects.
w = 320 - x; _dirtyRects.push_back(r);
if (y < 0) {
h += y;
y = 0;
}
if (y + h >= 200)
h = 200 - y;
Rect &cur = _dirtyRects[_numDirtyRects++];
cur.x = x;
cur.x2 = w;
cur.y = y;
cur.y2 = h;
} }
// overlay functions // overlay functions

View file

@ -28,6 +28,8 @@
#include "common/util.h" #include "common/util.h"
#include "common/func.h" #include "common/func.h"
#include "common/list.h"
#include "common/rect.h"
class OSystem; class OSystem;
@ -37,11 +39,6 @@ typedef Common::Functor0<void> UpdateFunctor;
class KyraEngine_v1; class KyraEngine_v1;
struct Rect {
int x, y;
int x2, y2;
};
struct ScreenDim { struct ScreenDim {
uint16 sx; uint16 sx;
uint16 sy; uint16 sy;
@ -300,8 +297,7 @@ protected:
}; };
bool _forceFullUpdate; bool _forceFullUpdate;
int _numDirtyRects; Common::List<Common::Rect> _dirtyRects;
Rect *_dirtyRects;
void addDirtyRect(int x, int y, int w, int h); void addDirtyRect(int x, int y, int w, int h);

View file

@ -28,7 +28,6 @@
namespace Kyra { namespace Kyra {
#define BITBLIT_RECTS 10
Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system) Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system)
: Screen(vm, system) { : Screen(vm, system) {
@ -36,8 +35,6 @@ Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system)
} }
Screen_LoK::~Screen_LoK() { Screen_LoK::~Screen_LoK() {
delete[] _bitBlitRects;
for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) {
delete[] _saveLoadPage[i]; delete[] _saveLoadPage[i];
_saveLoadPage[i] = 0; _saveLoadPage[i] = 0;
@ -56,9 +53,7 @@ bool Screen_LoK::init() {
if (!Screen::init()) if (!Screen::init())
return false; return false;
_bitBlitRects = new Rect[BITBLIT_RECTS]; memset(_bitBlitRects, 0, sizeof(_bitBlitRects));
assert(_bitBlitRects);
memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS);
_bitBlitNum = 0; _bitBlitNum = 0;
memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); memset(_saveLoadPage, 0, sizeof(_saveLoadPage));
memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl));
@ -104,19 +99,19 @@ void Screen_LoK::addBitBlitRect(int x, int y, int w, int h) {
if (_bitBlitNum >= BITBLIT_RECTS) if (_bitBlitNum >= BITBLIT_RECTS)
error("too many bit blit rects"); error("too many bit blit rects");
_bitBlitRects[_bitBlitNum].x = x; _bitBlitRects[_bitBlitNum].left = x;
_bitBlitRects[_bitBlitNum].y = y; _bitBlitRects[_bitBlitNum].top = y;
_bitBlitRects[_bitBlitNum].x2 = w; _bitBlitRects[_bitBlitNum].right = x + w;
_bitBlitRects[_bitBlitNum].y2 = h; _bitBlitRects[_bitBlitNum].bottom = y + h;
++_bitBlitNum; ++_bitBlitNum;
} }
void Screen_LoK::bitBlitRects() { void Screen_LoK::bitBlitRects() {
debugC(9, kDebugLevelScreen, "Screen_LoK::bitBlitRects()"); debugC(9, kDebugLevelScreen, "Screen_LoK::bitBlitRects()");
Rect *cur = _bitBlitRects; Common::Rect *cur = _bitBlitRects;
while (_bitBlitNum) { while (_bitBlitNum) {
_bitBlitNum--; _bitBlitNum--;
copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); copyRegion(cur->left, cur->top, cur->left, cur->top, cur->width(), cur->height(), 2, 0);
++cur; ++cur;
} }
} }

View file

@ -32,6 +32,10 @@ namespace Kyra {
class KyraEngine_LoK; class KyraEngine_LoK;
enum {
BITBLIT_RECTS = 10
};
class Screen_LoK : public Screen { class Screen_LoK : public Screen {
public: public:
Screen_LoK(KyraEngine_LoK *vm, OSystem *system); Screen_LoK(KyraEngine_LoK *vm, OSystem *system);
@ -65,7 +69,7 @@ protected:
static const ScreenDim _screenDimTable[]; static const ScreenDim _screenDimTable[];
static const int _screenDimTableCount; static const int _screenDimTableCount;
Rect *_bitBlitRects; Common::Rect _bitBlitRects[BITBLIT_RECTS];
int _bitBlitNum; int _bitBlitNum;
uint8 *_unkPtr1, *_unkPtr2; uint8 *_unkPtr1, *_unkPtr2;