diff options
author | Torbjörn Andersson | 2003-08-28 06:36:15 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2003-08-28 06:36:15 +0000 |
commit | f7ce39763e36af527d85683b47ff18ea2e534174 (patch) | |
tree | d943c4e564ca308feb4118696457ce2830eb4f1e /sword2/driver/menu.cpp | |
parent | 76df5a2733d7fd4b1d1e78d800649aa4c3e1e773 (diff) | |
download | scummvm-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.cpp | 99 |
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 |