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 | 
