aboutsummaryrefslogtreecommitdiff
path: root/engines/cruise
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cruise')
-rw-r--r--engines/cruise/background.cpp3
-rw-r--r--engines/cruise/background.h1
-rw-r--r--engines/cruise/backgroundIncrust.cpp6
-rw-r--r--engines/cruise/cell.cpp5
-rw-r--r--engines/cruise/detection.cpp2
-rw-r--r--engines/cruise/function.cpp8
-rw-r--r--engines/cruise/gfxModule.cpp72
-rw-r--r--engines/cruise/gfxModule.h1
-rw-r--r--engines/cruise/mainDraw.cpp11
-rw-r--r--engines/cruise/staticres.cpp14
-rw-r--r--engines/cruise/staticres.h14
11 files changed, 120 insertions, 17 deletions
diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp
index 6635a8d621..587c790554 100644
--- a/engines/cruise/background.cpp
+++ b/engines/cruise/background.cpp
@@ -30,6 +30,7 @@ namespace Cruise {
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 @@ int loadBackground(const char *name, int idx) {
return (-2);
}
+ backgroundChanged[idx] = true;
+
ptrToFree = gfxModuleData.pPage10;
if (loadFileSub1(&ptrToFree, name, NULL) < 0) {
if (ptrToFree != gfxModuleData.pPage10)
diff --git a/engines/cruise/background.h b/engines/cruise/background.h
index 711e89a34a..6f9b89d3f0 100644
--- a/engines/cruise/background.h
+++ b/engines/cruise/background.h
@@ -36,6 +36,7 @@ struct backgroundTableStruct {
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);
diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp
index 03ed552018..78cf49c653 100644
--- a/engines/cruise/backgroundIncrust.cpp
+++ b/engines/cruise/backgroundIncrust.cpp
@@ -71,6 +71,8 @@ void restoreBackground(backgroundIncrustStruct *pIncrust) {
if (pBackground == NULL)
return;
+ backgroundChanged[pIncrust->backgroundIdx] = true;
+
int X = pIncrust->savedX;
int Y = pIncrust->savedY;
int width = pIncrust->saveWidth;
@@ -108,6 +110,8 @@ backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, int16 objectIdx,
backgroundPtr = backgroundScreens[backgroundIdx];
+ backgroundChanged[backgroundIdx] = true;
+
assert(backgroundPtr != NULL);
currentHead = pHead;
@@ -218,6 +222,8 @@ void regenerateBackgroundIncrust(backgroundIncrustStruct *pHead) {
// 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;
diff --git a/engines/cruise/cell.cpp b/engines/cruise/cell.cpp
index 7966d5ea12..aeafed4f7a 100644
--- a/engines/cruise/cell.cpp
+++ b/engines/cruise/cell.cpp
@@ -176,6 +176,11 @@ void createTextObject(cellStruct *pObject, int overlayIdx, int messageIdx, int x
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) {
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index 879fad0210..d7c1b1c22d 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -26,7 +26,7 @@
#include "base/plugins.h"
-
+#include "common/savefile.h"
#include "engines/advancedDetector.h"
#include "cruise/cruise.h"
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index 6fe82f76d4..53549bff9e 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -510,6 +510,8 @@ int16 Op_LoadBackground(void) {
gfxModuleData_gfxWaitVSync();
result = loadBackground(bgName, bgIdx);
+
+ gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200));
}
changeCursor(CURSOR_NORMAL);
@@ -788,6 +790,7 @@ int16 Op_ClearScreen(void) {
if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && (backgroundScreens[bgIdx])) {
memset(backgroundScreens[bgIdx], 0, 320 * 200);
+ backgroundChanged[bgIdx] = true;
strcpy(backgroundTable[0].name, "");
}
@@ -922,6 +925,7 @@ int16 Op_SetActiveBackground(void) {
if (newPlane >= 0 && newPlane < NBSCREENS) {
if (backgroundScreens[newPlane]) {
masterScreen = newPlane;
+ backgroundChanged[newPlane] = true;
switchPal = 1;
}
}
@@ -936,8 +940,10 @@ int16 Op_RemoveBackground(void) {
if (backgroundScreens[backgroundIdx])
free(backgroundScreens[backgroundIdx]);
- if (masterScreen == backgroundIdx)
+ if (masterScreen == backgroundIdx) {
masterScreen = 0;
+ backgroundChanged[0] = true;
+ }
strcpy(backgroundTable[backgroundIdx].name, "");
} else {
diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp
index 003a335e42..b3ac68edae 100644
--- a/engines/cruise/gfxModule.cpp
+++ b/engines/cruise/gfxModule.cpp
@@ -26,6 +26,8 @@
#include "common/system.h"
#include "common/endian.h"
+#include "common/list.h"
+#include "common/rect.h"
#include "cruise/cruise.h"
#include "cruise/cruise_main.h"
@@ -41,6 +43,12 @@ palEntry lpalette[256];
int palDirtyMin = 256;
int palDirtyMax = -1;
+typedef Common::List<Common::Rect> RectList;
+RectList _dirtyRects;
+RectList _priorFrameRects;
+
+bool _dirtyRectScreen = false;
+
gfxModuleDataStruct gfxModuleData = {
0, // use Tandy
0, // use EGA
@@ -229,7 +237,47 @@ void gfxModuleData_flipScreen(void) {
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 +293,29 @@ void flip() {
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();
}
diff --git a/engines/cruise/gfxModule.h b/engines/cruise/gfxModule.h
index dc085d8b0d..308b96ab64 100644
--- a/engines/cruise/gfxModule.h
+++ b/engines/cruise/gfxModule.h
@@ -62,6 +62,7 @@ void gfxModuleData_flipScreen(void);
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);
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
index 047f00ee90..61e8f8d85c 100644
--- a/engines/cruise/mainDraw.cpp
+++ b/engines/cruise/mainDraw.cpp
@@ -1121,6 +1121,8 @@ void mainDrawPolygons(int fileIndex, cellStruct *plWork, int X, int scale, int Y
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 @@ void drawMessage(const gfxEntryStruct *pGfxPtr, int globalX, int globalY, int wi
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,9 @@ void drawSprite(int width, int height, cellStruct *currentObjPtr, const uint8 *d
int x = 0;
int y = 0;
+ // Flag the given area as having been changed
+ gfxModuleData_addDirtyRect(Common::Rect(xs, ys, xs + width - 1, ys + height - 1));
+
cellStruct* plWork = currentObjPtr;
int workBufferSize = height * (width / 8);
@@ -1406,6 +1413,10 @@ void mainDraw(int16 param) {
if (bgPtr) {
gfxModuleData_gfxCopyScreen(bgPtr, gfxModuleData.pPage10);
+ if (backgroundChanged[masterScreen]) {
+ backgroundChanged[masterScreen] = false;
+ gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200));
+ }
}
autoCellHead.next = NULL;
diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp
index fa77555314..1ffdc5628a 100644
--- a/engines/cruise/staticres.cpp
+++ b/engines/cruise/staticres.cpp
@@ -29,28 +29,28 @@
namespace Cruise {
-int actor_move[][13] = {
+const int actor_move[][13] = {
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0}, // back
{13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0}, // right side
{25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0}, // front
{ -13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, 0}// left side
};
-int actor_end[][13] = {
+const int actor_end[][13] = {
{37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // stat back
{38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // stat right-side
{39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // stat front
{ -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // stat left-side
};
-int actor_stat[][13] = {
+const int actor_stat[][13] = {
{53, 54, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0},
{59, 60, 62, 63, 78, 0, 0, 0, 0, 0, 0, 0, 0},
{ -78, -63, -62, -60, -59, 0, 0, 0, 0, 0, 0, 0, 0},
{ -57, -56, -55, -54, -53, 0, 0, 0, 0, 0, 0, 0, 0}
};
-int actor_invstat[][13] = {
+const int actor_invstat[][13] = {
{ -53, -54, -55, -56, -57, 0, 0, 0, 0, 0, 0, 0, 0},
{57, 56, 55, 54, 53, 0, 0, 0, 0, 0, 0, 0, 0},
{78, 63, 62, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -59,7 +59,7 @@ int actor_invstat[][13] = {
// font character lookup tables
-int16 english_fontCharacterTable[256] = {
+const int16 english_fontCharacterTable[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
@@ -122,7 +122,7 @@ int16 english_fontCharacterTable[256] = {
-1,
};
-int16 german_fontCharacterTable[256] = {
+const int16 german_fontCharacterTable[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
@@ -168,7 +168,7 @@ int16 german_fontCharacterTable[256] = {
-1, -1, -1, -1
};
-int16 spanish_fontCharacterTable[256] = {
+const int16 spanish_fontCharacterTable[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
diff --git a/engines/cruise/staticres.h b/engines/cruise/staticres.h
index 964bf294dc..f17e435acd 100644
--- a/engines/cruise/staticres.h
+++ b/engines/cruise/staticres.h
@@ -31,17 +31,17 @@
namespace Cruise {
-extern int actor_move[][13];
+extern const int actor_move[][13];
-extern int actor_end[][13];
+extern const int actor_end[][13];
-extern int actor_stat[][13];
+extern const int actor_stat[][13];
-extern int actor_invstat[][13];
+extern const int actor_invstat[][13];
-extern short int english_fontCharacterTable[256];
-extern short int german_fontCharacterTable[256];
-extern short int spanish_fontCharacterTable[256];
+extern const int16 english_fontCharacterTable[256];
+extern const int16 german_fontCharacterTable[256];
+extern const int16 spanish_fontCharacterTable[256];
#define fontCharacterTable (_vm->getLanguage() == Common::DE_DEU ? \
german_fontCharacterTable : (_vm->getLanguage() == Common::ES_ESP ? \