[Scummvm-cvs-logs] SF.net SVN: scummvm: [23906] scummvm/branches/branch-0-9-0/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sun Sep 17 11:54:47 CEST 2006


Revision: 23906
          http://svn.sourceforge.net/scummvm/?rev=23906&view=rev
Author:   lordhoto
Date:     2006-09-17 02:54:42 -0700 (Sun, 17 Sep 2006)

Log Message:
-----------
Backports dirty rect handling for the Kyrandia engine.

Modified Paths:
--------------
    scummvm/branches/branch-0-9-0/engines/kyra/screen.cpp
    scummvm/branches/branch-0-9-0/engines/kyra/screen.h

Modified: scummvm/branches/branch-0-9-0/engines/kyra/screen.cpp
===================================================================
--- scummvm/branches/branch-0-9-0/engines/kyra/screen.cpp	2006-09-17 09:49:33 UTC (rev 23905)
+++ scummvm/branches/branch-0-9-0/engines/kyra/screen.cpp	2006-09-17 09:54:42 UTC (rev 23906)
@@ -60,13 +60,14 @@
 
 	free(_unkPtr1);
 	free(_unkPtr2);
+
+	delete [] _dirtyRects;
 }
 
 bool Screen::init() {
 	debugC(9, kDebugLevelScreen, "Screen::init()");
 
-	// enable this for now
-	_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
+	_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, false);
 
 	_system->beginGFXTransaction();
 		_vm->initCommonGFX(false);
@@ -123,13 +124,28 @@
 	memset(_unkPtr1, 0, getRectSize(1, 144));
 	_unkPtr2 = (uint8*)malloc(getRectSize(1, 144));
 	memset(_unkPtr2, 0, getRectSize(1, 144));
+	
+	_forceFullUpdate = false;
+	_numDirtyRects = 0;
+	_dirtyRects = new Rect[kMaxDirtyRects];
+	assert(_dirtyRects);
 
 	return true;
 }
 
 void Screen::updateScreen() {
 	debugC(9, kDebugLevelScreen, "Screen::updateScreen()");
-	_system->copyRectToScreen(getPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+ 	if (_forceFullUpdate) {
+ 		_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);
+ 		}
+ 	}
+ 	_forceFullUpdate = false;
+ 	_numDirtyRects = 0;
 	//for debug reasons (needs 640x200 screen)
 	//_system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H);
 	_system->updateScreen();
@@ -138,7 +154,6 @@
 uint8 *Screen::getPagePtr(int pageNum) {
 	debugC(9, kDebugLevelScreen, "Screen::getPagePtr(%d)", pageNum);
 	assert(pageNum < SCREEN_PAGE_NUM);
-	// if pageNum == 0 wholeScreenDirty
 	return _pagePtrs[pageNum];
 }
 
@@ -151,13 +166,14 @@
 uint8 *Screen::getPageRect(int pageNum, int x, int y, int w, int h) {
 	debugC(9, kDebugLevelScreen, "Screen::getPageRect(%d, %d, %d, %d, %d)", pageNum, x, y, w, h);
 	assert(pageNum < SCREEN_PAGE_NUM);
-	// if pageNum == 0 rectDirty(x, y, w, h)
+	if (pageNum == 0 || pageNum == 1) addDirtyRect(x, y, w, h);
 	return _pagePtrs[pageNum] + y * SCREEN_W + x;
 }
 
 void Screen::clearPage(int pageNum) {
 	debugC(9, kDebugLevelScreen, "Screen::clearPage(%d)", pageNum);
 	assert(pageNum < SCREEN_PAGE_NUM);
+	if (pageNum == 0 || pageNum == 1) _forceFullUpdate = true;
 	memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE);
 }
 
@@ -171,6 +187,7 @@
 
 void Screen::clearCurPage() {
 	debugC(9, kDebugLevelScreen, "Screen::clearCurPage()");
+	if (_curPage == 0 || _curPage == 1) _forceFullUpdate = true;
 	memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE);
 }
 
@@ -185,6 +202,8 @@
 	debugC(9, kDebugLevelScreen, "Screen::setPagePixel(%d, %d, %d, %d)", pageNum, x, y, color);
 	assert(pageNum < SCREEN_PAGE_NUM);
 	assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
+	if (pageNum == 0 || pageNum == 1)
+		addDirtyRect(x, y, 1, 1);
 	_pagePtrs[pageNum][y * SCREEN_W + x] = color;
 }
 
@@ -313,6 +332,7 @@
 		seqBuf += SCREEN_W;
 		dstPage += SCREEN_W;
 	}
+	addDirtyRect(0, y, SCREEN_W, h);
 }
 
 void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage, int flags) {
@@ -348,6 +368,9 @@
 	const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W + x1;
 	assert(x2 + w <= SCREEN_W && y2 + h <= SCREEN_H);
 	uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W + x2;
+	
+	if (dstPage == 0 || dstPage == 1)
+		addDirtyRect(x2, y2, w, h);
 
 	if (flags & CR_X_FLIPPED) {
 		while (h--) {
@@ -385,6 +408,10 @@
 	debugC(9, kDebugLevelScreen, "Screen::copyBlockToPage(%d, %d, %d, %d, %d, %p)", pageNum, x, y, w, h, (const void *)src);
 	assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H);
 	uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x;
+
+ 	if (pageNum == 0 || pageNum == 1)
+ 		addDirtyRect(x, y, w, h);
+
 	while (h--) {
 		memcpy(dst, src, w);
 		dst += SCREEN_W;
@@ -411,6 +438,10 @@
 		h = 200 - y;
 	}
 	uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x * 8;
+	
+	if (_curPage == 0 || _curPage == 1)
+		addDirtyRect(x*8, y, w*8, h);
+	
 	while (h--) {
 		memcpy(dst, src, w*8);
 		dst += SCREEN_W;
@@ -486,6 +517,8 @@
 				setPagePixel(dstPage, i, j, color);
 			}
 		}
+		// forcing full update for now
+		_forceFullUpdate = true;
 		updateScreen();
 		now = (int32)_system->getMillis();
 		wait = ticks * _vm->tickLength() - (now - start);
@@ -506,6 +539,10 @@
 		pageNum = _curPage;
 	}
 	uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W + x1;
+	
+	if (pageNum == 0 || pageNum == 1)
+		addDirtyRect(x1, y1, x2-x1+1, y2-y1+1);
+	
 	for (; y1 <= y2; ++y1) {
 		memset(dst, color, x2 - x1 + 1);
 		dst += SCREEN_W;
@@ -572,12 +609,12 @@
 			drawLine(false, x1, y1, x2 - x1 + 1, color);
 }
 
-void Screen::drawLine(bool horizontal, int x, int y, int length, int color) {
-	debugC(9, kDebugLevelScreen, "Screen::drawLine(%i, %i, %i, %i, %i)", horizontal, x, y, length, color);
+void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
+	debugC(9, kDebugLevelScreen, "Screen::drawLine(%i, %i, %i, %i, %i)", vertical, x, y, length, color);
 
 	uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W + x;
 
-	if (horizontal) {
+	if (vertical) {
 		assert((y + length) <= SCREEN_H);
 		int currLine = 0;
 		while (currLine < length) {
@@ -589,6 +626,9 @@
 		assert((x + length) <= SCREEN_W);
 		memset(ptr, color, length);
 	}
+	
+	if (_curPage == 0 || _curPage == 1)
+		addDirtyRect(x, y, (vertical) ? 1 : length, (vertical) ? length : 1);
 }
 
 void Screen::setAnimBlockPtr(int size) {
@@ -775,6 +815,9 @@
 		}
 		dst += pitch;
 	}
+	
+	if (_curPage == 0 || _curPage == 1)
+		addDirtyRect(x, y, charWidth, *(fnt->fontData + fnt->charSizeOffset + 4));
 }
 
 void Screen::setScreenDim(int dim) {
@@ -973,6 +1016,8 @@
 
 	uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x;
 	uint8 *dstStart = getPagePtr(pageNum);
+	if (pageNum == 0 || pageNum == 1)
+		addDirtyRect(x, y, x2-x1, y2-y1);
 	
 	int scaleYTable[SCREEN_H];
 	assert(y1 >= 0 && y2 < SCREEN_H);
@@ -1903,22 +1948,24 @@
 	updateScreen();
 }
 
-void Screen::copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr) {
+void Screen::copyScreenFromRect(int x, int y, int w, int h, const uint8 *ptr) {
 	debugC(9, kDebugLevelScreen, "Screen::copyScreenFromRect(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)ptr);
 	x <<= 3; w <<= 3;
-	uint8 *src = ptr;
+	const uint8 *src = ptr;
 	uint8 *dst = &_pagePtrs[0][y * SCREEN_W + x];
 	for (int i = 0; i < h; ++i) {
 		memcpy(dst, src, w);
 		src += w;
 		dst += SCREEN_W;
 	}
+	
+	addDirtyRect(x, y, w, h);
 }
 
 void Screen::copyScreenToRect(int x, int y, int w, int h, uint8 *ptr) {
 	debugC(9, kDebugLevelScreen, "Screen::copyScreenToRect(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)ptr);
 	x <<= 3; w <<= 3;
-	uint8 *src = &_pagePtrs[0][y * SCREEN_W + x];
+	const uint8 *src = &_pagePtrs[0][y * SCREEN_W + x];
 	uint8 *dst = ptr;
 	for (int i = 0; i < h; ++i) {
 		memcpy(dst, src, w);
@@ -2199,6 +2246,8 @@
 
 	uint8 *srcPtr = srcData + 10 + palSize;
 	uint8 *dstData = getPagePtr(dstPage);
+	if (dstPage == 0 || tempPage == 0)
+		_forceFullUpdate = true;
 
 	switch (compType) {
 	case 0:
@@ -2218,4 +2267,31 @@
 	delete [] srcData;
 }
 
+// dirty rect handling
+
+void Screen::addDirtyRect(int x, int y, int w, int h) {
+	if (_numDirtyRects == kMaxDirtyRects || _forceFullUpdate) {
+		_forceFullUpdate = true;
+		return;
+	}
+	
+	if (w == 0 || h == 0)
+		return;
+
+	if (x < 0)
+		x = 0;
+	if (x + w >= 320)
+		w = 320 - x;
+	if (y < 0)
+		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;
+}
+
 } // End of namespace Kyra

Modified: scummvm/branches/branch-0-9-0/engines/kyra/screen.h
===================================================================
--- scummvm/branches/branch-0-9-0/engines/kyra/screen.h	2006-09-17 09:49:33 UTC (rev 23905)
+++ scummvm/branches/branch-0-9-0/engines/kyra/screen.h	2006-09-17 09:54:42 UTC (rev 23906)
@@ -112,7 +112,7 @@
 	void copyCurPageBlock(int x, int y, int w, int h, uint8 *dst);
 	void shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent);
 	void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1);
-	void drawLine(bool horizontal, int x, int y, int length, int color);
+	void drawLine(bool vertical, int x, int y, int length, int color);
 	void drawClippedLine(int x1, int y1, int x2, int y2, int color);
 	void drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2);
 	void drawBox(int x1, int y1, int x2, int y2, int color);
@@ -193,7 +193,7 @@
 	int16 encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size);
 	void restoreMouseRect();
 	void copyMouseToScreen();
-	void copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr);
+	void copyScreenFromRect(int x, int y, int w, int h, const uint8 *ptr);
 	void copyScreenToRect(int x, int y, int w, int h, uint8 *ptr);
 
 	uint8 *_pagePtrs[16];
@@ -211,6 +211,16 @@
 	Rect *_bitBlitRects;
 	int _bitBlitNum;
 	uint8 *_unkPtr1, *_unkPtr2;
+	
+	enum {
+		kMaxDirtyRects = 50
+	};
+	
+	bool _forceFullUpdate;
+	int _numDirtyRects;
+	Rect *_dirtyRects;
+	
+	void addDirtyRect(int x, int y, int w, int h);
 
 	OSystem *_system;
 	KyraEngine *_vm;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list