From 4fc8fe80239ba18a6406fc2349b0932c6ea6d87c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 11 Sep 2009 11:36:16 +0000 Subject: Added an experimental screen transition dirty rect calculation code which should make background changes faster on slower devices or when scalers are active svn-id: r44032 --- engines/cruise/gfxModule.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ engines/cruise/gfxModule.h | 2 ++ engines/cruise/mainDraw.cpp | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp index b3ac68edae..3ed7ee6fce 100644 --- a/engines/cruise/gfxModule.cpp +++ b/engines/cruise/gfxModule.cpp @@ -330,4 +330,46 @@ void resetBitmap(uint8 *dataPtr, int32 dataSize) { 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 + 7, 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, yp + 1)); + sliceXStart = sliceXEnd = -1; + } + } + + if (sliceXStart != -1) + gfxModuleData_addDirtyRect(Common::Rect(sliceXStart, yp, 320, yp + 1)); + } +} + } // End of namespace Cruise diff --git a/engines/cruise/gfxModule.h b/engines/cruise/gfxModule.h index 308b96ab64..1048fa8296 100644 --- a/engines/cruise/gfxModule.h +++ b/engines/cruise/gfxModule.h @@ -67,6 +67,8 @@ 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 diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp index fe5454d57f..edd28748ae 100644 --- a/engines/cruise/mainDraw.cpp +++ b/engines/cruise/mainDraw.cpp @@ -1415,7 +1415,7 @@ void mainDraw(int16 param) { gfxModuleData_gfxCopyScreen(bgPtr, gfxModuleData.pPage10); if (backgroundChanged[masterScreen]) { backgroundChanged[masterScreen] = false; - gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200)); + switchBackground(bgPtr); } } -- cgit v1.2.3