aboutsummaryrefslogtreecommitdiff
path: root/sword2/driver/menu.cpp
diff options
context:
space:
mode:
authorTorbjörn Andersson2003-08-28 06:36:15 +0000
committerTorbjörn Andersson2003-08-28 06:36:15 +0000
commitf7ce39763e36af527d85683b47ff18ea2e534174 (patch)
treed943c4e564ca308feb4118696457ce2830eb4f1e /sword2/driver/menu.cpp
parent76df5a2733d7fd4b1d1e78d800649aa4c3e1e773 (diff)
downloadscummvm-rg350-f7ce39763e36af527d85683b47ff18ea2e534174.tar.gz
scummvm-rg350-f7ce39763e36af527d85683b47ff18ea2e534174.tar.bz2
scummvm-rg350-f7ce39763e36af527d85683b47ff18ea2e534174.zip
Removed the Surface class in favor of small struct specially made for the
block surfaces. (A block surface is a 64x64 tile of a parallax layer.) I've also done a few things to try and optimize the drawing: * The back buffer is no longer cleared between frames. This may cause regressions, but I do believe that the entire picture area is always completely re-rendered for each frame. As a result of this, the menu code is now responsible for clearing the icon areas itself. * A few unnecessary copy_rect() calls were commented out in favor of one big copy_rect() in ServiceWindows(). * Completely opaque block surfaces are copied with memcpy(), one line at a time. Unless we manage to add intelligent screen redrawing, I don't think it will get that much faster than this, though there is some unnecessary data copying in DrawSprite() that could be removed. And the game is still a terrible CPU hog. I believe the animation runs at approximately 12 fps. If there's still time left, it will pump out further frames to get smooth scrolling. We ought to put a cap on that, and if it has already reached the scroll target it should sleep for the rest of the render cycle. svn-id: r9886
Diffstat (limited to 'sword2/driver/menu.cpp')
-rw-r--r--sword2/driver/menu.cpp99
1 files changed, 77 insertions, 22 deletions
diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp
index 2f6d1d6314..142653fbea 100644
--- a/sword2/driver/menu.cpp
+++ b/sword2/driver/menu.cpp
@@ -122,7 +122,7 @@ static uint8 menuStatus[2] = {
RDMENU_HIDDEN, RDMENU_HIDDEN
};
-static uint8 *icons[2][RDMENU_MAXPOCKETS] = {
+static byte *icons[2][RDMENU_MAXPOCKETS] = {
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
@@ -134,14 +134,32 @@ static uint8 pocketStatus[2][RDMENU_MAXPOCKETS] = {
static uint8 iconCount = 0;
+void ClearIconArea(int menu, int pocket, ScummVM::Rect *r) {
+ byte *dst;
+ int i;
+
+ r->top = menu * (RENDERDEEP + MENUDEEP) + (MENUDEEP - RDMENU_ICONDEEP) / 2;
+ r->bottom = r->top + RDMENU_ICONDEEP;
+ r->left = RDMENU_ICONSTART + pocket * (RDMENU_ICONWIDE + RDMENU_ICONSPACING);
+ r->right = r->left + RDMENU_ICONWIDE;
+
+ dst = lpBackBuffer + r->top * screenWide + r->left;
+
+ for (i = 0; i < RDMENU_ICONDEEP; i++) {
+ memset(dst, 0, RDMENU_ICONWIDE);
+ dst += screenWide;
+ }
+}
+
int32 ProcessMenu(void) {
+ byte *src, *dst;
uint8 menu;
- uint8 i;
+ uint8 i, j;
uint8 complete;
uint8 frameCount;
int32 curx, xoff;
int32 cury, yoff;
- ScummVM::Rect r;
+ ScummVM::Rect r1, r2;
int32 delta;
static int32 lastTime = 0;
@@ -188,6 +206,11 @@ int32 ProcessMenu(void) {
// Propagate the animation from the first icon.
for (i = RDMENU_MAXPOCKETS - 1; i > 0; i--) {
+ if (icons[menu][i] && pocketStatus[menu][i] != 0 && pocketStatus[menu][i - 1] == 0) {
+ ClearIconArea(menu, i, &r1);
+ UploadRect(&r1);
+ }
+
pocketStatus[menu][i] = pocketStatus[menu][i - 1];
if (pocketStatus[menu][i] != 0)
complete = 0;
@@ -196,10 +219,16 @@ int32 ProcessMenu(void) {
complete = 0;
// ... and animate the first icon
- if (pocketStatus[menu][0] != 0)
+ if (pocketStatus[menu][0] != 0) {
pocketStatus[menu][0]--;
- // Check to see if the menu is fully open
+ if (pocketStatus[menu][0] == 0) {
+ ClearIconArea(menu, 0, &r1);
+ UploadRect(&r1);
+ }
+ }
+
+ // Check to see if the menu is fully closed
if (complete)
menuStatus[menu] = RDMENU_HIDDEN;
}
@@ -215,41 +244,49 @@ int32 ProcessMenu(void) {
for (i = 0; i < RDMENU_MAXPOCKETS; i++) {
if (icons[menu][i]) {
+ // Since we no longer clear the screen
+ // after each frame we need to clear
+ // the icon area.
+
+ ClearIconArea(menu, i, &r1);
+
if (pocketStatus[menu][i] == MAXMENUANIMS) {
xoff = (RDMENU_ICONWIDE / 2);
- r.left = curx - xoff;
- r.right = r.left + RDMENU_ICONWIDE;
+ r2.left = curx - xoff;
+ r2.right = r2.left + RDMENU_ICONWIDE;
yoff = (RDMENU_ICONDEEP / 2);
- r.top = cury - yoff;
- r.bottom = r.top + RDMENU_ICONDEEP;
+ r2.top = cury - yoff;
+ r2.bottom = r2.top + RDMENU_ICONDEEP;
} else {
xoff = (RDMENU_ICONWIDE / 2) * pocketStatus[menu][i] / MAXMENUANIMS;
- r.left = curx - xoff;
- r.right = curx + xoff;
+ r2.left = curx - xoff;
+ r2.right = curx + xoff;
yoff = (RDMENU_ICONDEEP / 2) * pocketStatus[menu][i] / MAXMENUANIMS;
- r.top = cury - yoff;
- r.bottom = cury + yoff;
+ r2.top = cury - yoff;
+ r2.bottom = cury + yoff;
}
if (xoff != 0 && yoff != 0) {
- byte *dst = lpBackBuffer->_pixels + r.top * lpBackBuffer->_width + r.left;
- byte *src = icons[menu][i];
+ dst = lpBackBuffer + r2.top * screenWide + r2.left;
+ src = icons[menu][i];
if (pocketStatus[menu][i] != MAXMENUANIMS) {
SquashImage(
- dst, lpBackBuffer->_width, r.right - r.left, r.bottom - r.top,
+ dst, screenWide, r2.right - r2.left, r2.bottom - r2.top,
src, RDMENU_ICONWIDE, RDMENU_ICONWIDE, RDMENU_ICONDEEP, NULL);
} else {
- for (int j = 0; j < RDMENU_ICONDEEP; j++) {
+ for (j = 0; j < RDMENU_ICONDEEP; j++) {
memcpy(dst, src, RDMENU_ICONWIDE);
src += RDMENU_ICONWIDE;
- dst += lpBackBuffer->_width;
+ dst += screenWide;
}
}
- UploadRect(&r);
+ UploadRect(&r1);
}
}
curx += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
+ r1.left += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
+ r1.right += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
}
}
}
@@ -501,15 +538,31 @@ int32 HideMenu(uint8 menu) {
return RD_OK;
}
-int32 CloseMenuImmediately(void)
-{
+int32 CloseMenuImmediately(void) {
+ ScummVM::Rect r;
+ int i;
+
menuStatus[0] = RDMENU_HIDDEN;
menuStatus[1] = RDMENU_HIDDEN;
+
+ for (i = 0; i < RDMENU_MAXPOCKETS; i++) {
+ if (icons[0][i]) {
+ ClearIconArea(0, i, &r);
+ UploadRect(&r);
+ }
+ if (icons[1][i]) {
+ ClearIconArea(1, i, &r);
+ UploadRect(&r);
+ }
+ }
+
memset(pocketStatus, 0, sizeof(uint8) * 2 * RDMENU_MAXPOCKETS);
- return (RD_OK);
+ return RD_OK;
}
int32 SetMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) {
+ ScummVM::Rect r;
+
debug(5, "stub SetMenuIcon( %d, %d )", menu, pocket);
// Check for invalid menu parameter.
@@ -525,6 +578,8 @@ int32 SetMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) {
iconCount--;
free(icons[menu][pocket]);
icons[menu][pocket] = NULL;
+ ClearIconArea(menu, pocket, &r);
+ UploadRect(&r);
}
// Only put the icon in the pocket if it is not NULL