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

View file

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

View file

@ -62,8 +62,6 @@ Screen::~Screen() {
delete[] _palettes[i];
}
delete[] _dirtyRects;
CursorMan.popAllCursors();
}
@ -162,9 +160,6 @@ bool Screen::init() {
CursorMan.showMouse(false);
_forceFullUpdate = false;
_numDirtyRects = 0;
_dirtyRects = new Rect[kMaxDirtyRects];
assert(_dirtyRects);
return true;
}
@ -234,13 +229,13 @@ void Screen::updateDirtyRects() {
_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
} else {
const byte *page0 = getCPagePtr(0);
for (int i = 0; i < _numDirtyRects; ++i) {
Rect &cur = _dirtyRects[i];
_system->copyRectToScreen(page0 + cur.y * SCREEN_W + cur.x, SCREEN_W, cur.x, cur.y, cur.x2, cur.y2);
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
_system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height());
}
}
_forceFullUpdate = false;
_numDirtyRects = 0;
_dirtyRects.clear();
}
void Screen::updateDirtyRectsOvl() {
@ -255,18 +250,18 @@ void Screen::updateDirtyRectsOvl() {
const byte *page0 = getCPagePtr(0);
byte *ovl0 = _sjisOverlayPtrs[0];
for (int i = 0; i < _numDirtyRects; ++i) {
Rect &cur = _dirtyRects[i];
byte *dst = ovl0 + cur.y * 1280 + (cur.x<<1);
const byte *src = page0 + cur.y * SCREEN_W + cur.x;
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
byte *dst = ovl0 + it->top * 1280 + (it->left<<1);
const byte *src = page0 + it->top * SCREEN_W + it->left;
scale2x(dst, 640, src, SCREEN_W, cur.x2, cur.y2);
mergeOverlay(cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1);
_system->copyRectToScreen(dst, 640, cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1);
scale2x(dst, 640, src, SCREEN_W, it->width(), it->height());
mergeOverlay(it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
_system->copyRectToScreen(dst, 640, it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
}
}
_forceFullUpdate = false;
_numDirtyRects = 0;
_dirtyRects.clear();
}
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
void Screen::addDirtyRect(int x, int y, int w, int h) {
if (_numDirtyRects == kMaxDirtyRects || _forceFullUpdate) {
if (_dirtyRects.size() >= kMaxDirtyRects || _forceFullUpdate) {
_forceFullUpdate = true;
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;
if (x < 0) {
w += x;
x = 0;
// Check if the new rectangle is contained within another in the list
Common::List<Common::Rect>::iterator it;
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)
w = 320 - x;
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;
// If we got here, we can safely add r to the list of dirty rects.
_dirtyRects.push_back(r);
}
// overlay functions

View file

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

View file

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

View file

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