[Scummvm-cvs-logs] SF.net SVN: scummvm:[44373] scummvm/branches/branch-1-0-0/engines/cruise
dreammaster at users.sourceforge.net
dreammaster at users.sourceforge.net
Sat Sep 26 06:38:25 CEST 2009
Revision: 44373
http://scummvm.svn.sourceforge.net/scummvm/?rev=44373&view=rev
Author: dreammaster
Date: 2009-09-26 04:38:25 +0000 (Sat, 26 Sep 2009)
Log Message:
-----------
Backport of dirty rect handling for Cruise engine
Modified Paths:
--------------
scummvm/branches/branch-1-0-0/engines/cruise/background.cpp
scummvm/branches/branch-1-0-0/engines/cruise/background.h
scummvm/branches/branch-1-0-0/engines/cruise/backgroundIncrust.cpp
scummvm/branches/branch-1-0-0/engines/cruise/cell.cpp
scummvm/branches/branch-1-0-0/engines/cruise/cruise.cpp
scummvm/branches/branch-1-0-0/engines/cruise/function.cpp
scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.cpp
scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.h
scummvm/branches/branch-1-0-0/engines/cruise/mainDraw.cpp
Modified: scummvm/branches/branch-1-0-0/engines/cruise/background.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/background.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/background.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -30,6 +30,7 @@
uint8 colorMode = 0;
uint8 *backgroundScreens[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; // wasn't initialized in original, but it's probably better
+bool backgroundChanged[8] = { false, false, false, false, false, false, false, false };
backgroundTableStruct backgroundTable[8];
char hwPage[64000];
@@ -101,6 +102,8 @@
return (-2);
}
+ backgroundChanged[idx] = true;
+
ptrToFree = gfxModuleData.pPage10;
if (loadFileSub1(&ptrToFree, name, NULL) < 0) {
if (ptrToFree != gfxModuleData.pPage10)
Modified: scummvm/branches/branch-1-0-0/engines/cruise/background.h
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/background.h 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/background.h 2009-09-26 04:38:25 UTC (rev 44373)
@@ -36,6 +36,7 @@
extern short int cvtPalette[0x20];
extern int CVTLoaded;
extern uint8 *backgroundScreens[8];
+extern bool backgroundChanged[8];
extern backgroundTableStruct backgroundTable[8];
int loadBackground(const char *name, int idx);
Modified: scummvm/branches/branch-1-0-0/engines/cruise/backgroundIncrust.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/backgroundIncrust.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/backgroundIncrust.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -71,6 +71,8 @@
if (pBackground == NULL)
return;
+ backgroundChanged[pIncrust->backgroundIdx] = true;
+
int X = pIncrust->savedX;
int Y = pIncrust->savedY;
int width = pIncrust->saveWidth;
@@ -108,6 +110,8 @@
backgroundPtr = backgroundScreens[backgroundIdx];
+ backgroundChanged[backgroundIdx] = true;
+
assert(backgroundPtr != NULL);
currentHead = pHead;
@@ -218,6 +222,8 @@
// Poly
addBackgroundIncrustSub1(frame, pl->X, pl->Y, NULL, pl->scale, (char*)backgroundScreens[pl->backgroundIdx], (char *)filesDatabase[frame].subData.ptr);
}
+
+ backgroundChanged[pl->backgroundIdx] = true;
}
pl = pl2;
Modified: scummvm/branches/branch-1-0-0/engines/cruise/cell.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/cell.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/cell.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -176,6 +176,11 @@
if (ax) {
pNewElement->gfxPtr = renderText(width, ax);
}
+
+ // WORKAROUND: This is needed for the new dirty rect handling so as to properly refresh the screen
+ // when the copy protection screen is being shown
+ if ((messageIdx == 0) && !strcmp(overlayTable[overlayIdx].overlayName, "XX2"))
+ backgroundChanged[0] = true;
}
void removeCell(cellStruct *objPtr, int ovlNumber, int objectIdx, int objType, int backgroundPlane) {
Modified: scummvm/branches/branch-1-0-0/engines/cruise/cruise.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/cruise.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/cruise.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -200,6 +200,8 @@
flipScreen();
changeCursor(_savedCursor);
}
+
+ gfxModuleData_addDirtyRect(Common::Rect(64, 100, 256, 117));
}
Common::Error CruiseEngine::loadGameState(int slot) {
Modified: scummvm/branches/branch-1-0-0/engines/cruise/function.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/function.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/function.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -510,6 +510,8 @@
gfxModuleData_gfxWaitVSync();
result = loadBackground(bgName, bgIdx);
+
+ gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200));
}
changeCursor(CURSOR_NORMAL);
@@ -788,6 +790,7 @@
if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && (backgroundScreens[bgIdx])) {
memset(backgroundScreens[bgIdx], 0, 320 * 200);
+ backgroundChanged[bgIdx] = true;
strcpy(backgroundTable[0].name, "");
}
@@ -922,6 +925,7 @@
if (newPlane >= 0 && newPlane < NBSCREENS) {
if (backgroundScreens[newPlane]) {
masterScreen = newPlane;
+ backgroundChanged[newPlane] = true;
switchPal = 1;
}
}
@@ -936,8 +940,10 @@
if (backgroundScreens[backgroundIdx])
free(backgroundScreens[backgroundIdx]);
- if (masterScreen == backgroundIdx)
+ if (masterScreen == backgroundIdx) {
masterScreen = 0;
+ backgroundChanged[0] = true;
+ }
strcpy(backgroundTable[backgroundIdx].name, "");
} else {
Modified: scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -41,6 +41,10 @@
int palDirtyMin = 256;
int palDirtyMax = -1;
+typedef Common::List<Common::Rect> RectList;
+RectList _dirtyRects;
+RectList _priorFrameRects;
+
gfxModuleDataStruct gfxModuleData = {
0, // use Tandy
0, // use EGA
@@ -229,7 +233,47 @@
flip();
}
+void gfxModuleData_addDirtyRect(const Common::Rect &r) {
+ _dirtyRects.push_back(Common::Rect( MAX(r.left, (int16)0), MAX(r.top, (int16)0),
+ MIN(r.right, (int16)320), MIN(r.bottom, (int16)200)));
+}
+
+/**
+ * Creates the union of two rectangles.
+ */
+static bool unionRectangle(Common::Rect &pDest, const Common::Rect &pSrc1, const Common::Rect &pSrc2) {
+ pDest.left = MIN(pSrc1.left, pSrc2.left);
+ pDest.top = MIN(pSrc1.top, pSrc2.top);
+ pDest.right = MAX(pSrc1.right, pSrc2.right);
+ pDest.bottom = MAX(pSrc1.bottom, pSrc2.bottom);
+
+ return !pDest.isEmpty();
+}
+
+static void mergeClipRects() {
+ RectList::iterator rOuter, rInner;
+
+ for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
+ rInner = rOuter;
+ while (++rInner != _dirtyRects.end()) {
+
+ if ((*rOuter).intersects(*rInner)) {
+ // these two rectangles overlap, so translate it to a bigger rectangle
+ // that contains both of them
+ unionRectangle(*rOuter, *rOuter, *rInner);
+
+ // remove the inner rect from the list
+ _dirtyRects.erase(rInner);
+
+ // move back to beginning of list
+ rInner = rOuter;
+ }
+ }
+ }
+}
+
void flip() {
+ RectList::iterator dr;
int i;
byte paletteRGBA[256 * 4];
@@ -245,7 +289,29 @@
palDirtyMax = -1;
}
- g_system->copyRectToScreen(globalScreen, 320, 0, 0, 320, 200);
+ // Make a copy of the prior frame's dirty rects, and then backup the current frame's rects
+ RectList tempList = _priorFrameRects;
+ _priorFrameRects = _dirtyRects;
+
+ // Merge the prior frame's dirty rects into the current frame's list
+ for (dr = tempList.begin(); dr != tempList.end(); ++dr) {
+ Common::Rect &r = *dr;
+ _dirtyRects.push_back(Common::Rect(r.left, r.top, r.right, r.bottom));
+ }
+
+ // Merge any overlapping rects to simplify the drawing process
+ mergeClipRects();
+
+ // Copy any modified areas
+ for (dr = _dirtyRects.begin(); dr != _dirtyRects.end(); ++dr) {
+ Common::Rect &r = *dr;
+ g_system->copyRectToScreen(globalScreen + 320 * r.top + r.left, 320,
+ r.left, r.top, r.width(), r.height());
+ }
+
+ _dirtyRects.clear();
+
+ // Allow the screen to update
g_system->updateScreen();
}
@@ -260,4 +326,46 @@
memset(dataPtr, 0, dataSize);
}
+/**
+ * This method compares a new background being switched in against the current background,
+ * to figure out rectangles of changed areas for dirty rectangles
+ */
+void switchBackground(const byte *newBg) {
+ const byte *bg = gfxModuleData.pPage00;
+ int sliceXStart, sliceXEnd;
+
+ // If both the upper corners are different, presume it's a full screen change
+ if ((*newBg != *bg) && (*(newBg + 319) != *(bg + 319))) {
+ gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200));
+ return;
+ }
+
+ /* For an optimisation, any changes are stored as a series of slices than have a height of a single
+ * line each. It is left up to the screen redraw code to automatically merge these together
+ */
+
+ for (int yp = 0; yp < 200; ++yp) {
+ sliceXStart = -1; sliceXEnd = -1;
+ for (int xp = 0; xp < 320; ++xp, ++bg, ++newBg) {
+ if (*bg != *newBg) {
+ if (sliceXStart == -1) {
+ // Start of a new slice
+ sliceXStart = xp;
+ sliceXEnd = MIN(xp + 7, 320);
+ } else
+ // Carry on of changed area
+ sliceXEnd = MAX(xp, sliceXEnd);
+
+ } else if ((sliceXEnd != -1) && (xp >= (sliceXEnd + 10))) {
+ // If more than 10 pixels have gone by without any changes, then end the slice
+ gfxModuleData_addDirtyRect(Common::Rect(sliceXStart, yp, sliceXEnd, MIN(yp + 2, 200)));
+ sliceXStart = sliceXEnd = -1;
+ }
+ }
+
+ if (sliceXStart != -1)
+ gfxModuleData_addDirtyRect(Common::Rect(sliceXStart, yp, 320, MIN(yp + 2, 200)));
+ }
+}
+
} // End of namespace Cruise
Modified: scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.h
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.h 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/gfxModule.h 2009-09-26 04:38:25 UTC (rev 44373)
@@ -62,10 +62,13 @@
void gfxModuleData_convertOldPalColor(uint16 oldColor, uint8 *pOutput);
void gfxModuleData_setPalEntries(const byte *ptr, int start, int num);
void gfxModuleData_setPal256(const byte *ptr);
+void gfxModuleData_addDirtyRect(const Common::Rect &r);
void flip(void);
void drawSolidBox(int32 x1, int32 y1, int32 x2, int32 y2, uint8 colour);
void resetBitmap(uint8 *dataPtr, int32 dataSize);
+void switchBackground(const byte *newBg);
+
} // End of namespace Cruise
#endif
Modified: scummvm/branches/branch-1-0-0/engines/cruise/mainDraw.cpp
===================================================================
--- scummvm/branches/branch-1-0-0/engines/cruise/mainDraw.cpp 2009-09-26 04:37:19 UTC (rev 44372)
+++ scummvm/branches/branch-1-0-0/engines/cruise/mainDraw.cpp 2009-09-26 04:38:25 UTC (rev 44373)
@@ -1121,6 +1121,8 @@
if (spriteY1 == spriteY2)
return;
+ gfxModuleData_addDirtyRect(Common::Rect(spriteX2, spriteY2, spriteX1, spriteY1));
+
var_8 = 0;
memset(polygonMask, 0xFF, (320*200) / 8);
@@ -1177,6 +1179,8 @@
globalY = 198 - pGfxPtr->height;
}
+ gfxModuleData_addDirtyRect(Common::Rect(globalX, globalY, globalX + width, globalY + height));
+
initialOuput = ouputPtr + (globalY * 320) + globalX;
for (yp = 0; yp < height; yp++) {
@@ -1206,6 +1210,13 @@
int x = 0;
int y = 0;
+ // Flag the given area as having been changed
+ Common::Point ps = Common::Point(MAX(MIN(xs, 320), 0), MAX(MIN(ys, 200), 0));
+ Common::Point pe = Common::Point(MAX(MIN(xs + width, 320), 0), MAX(MIN(ys + height, 200), 0));
+ if ((ps.x != pe.x) && (ps.y != pe.y))
+ // At least part of sprite is on-screen
+ gfxModuleData_addDirtyRect(Common::Rect(ps.x, ps.y, pe.x, pe.y));
+
cellStruct* plWork = currentObjPtr;
int workBufferSize = height * (width / 8);
@@ -1406,6 +1417,10 @@
if (bgPtr) {
gfxModuleData_gfxCopyScreen(bgPtr, gfxModuleData.pPage10);
+ if (backgroundChanged[masterScreen]) {
+ backgroundChanged[masterScreen] = false;
+ switchBackground(bgPtr);
+ }
}
autoCellHead.next = NULL;
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