aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sword2/driver/driver96.h3
-rw-r--r--sword2/driver/menu.cpp205
2 files changed, 96 insertions, 112 deletions
diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h
index 0bf6803c4e..412257ac19 100644
--- a/sword2/driver/driver96.h
+++ b/sword2/driver/driver96.h
@@ -119,7 +119,8 @@ enum {
RDMENU_HIDDEN,
RDMENU_SHOWN,
RDMENU_OPENING,
- RDMENU_CLOSING
+ RDMENU_CLOSING,
+ RDMENU_ALMOST_HIDDEN
};
#define RDMENU_ICONWIDE 35
diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp
index 79245fe0db..28ab6b955e 100644
--- a/sword2/driver/menu.cpp
+++ b/sword2/driver/menu.cpp
@@ -28,17 +28,14 @@ namespace Sword2 {
#define MAXMENUANIMS 8
void Graphics::clearIconArea(int menu, int pocket, Common::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 = _buffer + r->top * _screenWide + r->left;
+ byte *dst = _buffer + r->top * _screenWide + r->left;
- for (i = 0; i < RDMENU_ICONDEEP; i++) {
+ for (int i = 0; i < RDMENU_ICONDEEP; i++) {
memset(dst, 0, RDMENU_ICONWIDE);
dst += _screenWide;
}
@@ -51,22 +48,18 @@ void Graphics::clearIconArea(int menu, int pocket, Common::Rect *r) {
*/
void Graphics::processMenu(void) {
- byte *src, *dst;
uint8 menu;
uint8 i, j;
- uint8 complete;
uint8 frameCount;
- int32 curx, xoff;
- int32 cury, yoff;
Common::Rect r1, r2;
- int32 delta;
static int32 lastTime = 0;
if (lastTime == 0) {
lastTime = _vm->_system->get_msecs();
frameCount = 1;
} else {
- delta = _vm->_system->get_msecs() - lastTime;
+ int32 delta = _vm->_system->get_msecs() - lastTime;
+
if (delta > 250) {
lastTime += delta;
delta = 250;
@@ -77,116 +70,106 @@ void Graphics::processMenu(void) {
}
}
+ // Note: The "almost hidden" menu state exists only so that the menu
+ // will be redrawn one last time before it's completely hidden. We do
+ // not need a corresponding "almost shown" state because the menu will
+ // always be redrawn while it's shown anyway. (We may want to change
+ // this later.)
+
while (frameCount-- > 0) {
for (menu = RDMENU_TOP; menu <= RDMENU_BOTTOM; menu++) {
- if (_menuStatus[menu] == RDMENU_OPENING) {
- // The menu is opening, so process it here
- complete = 1;
-
- // Propagate the animation from the first icon.
- for (i = RDMENU_MAXPOCKETS - 1; i > 0; i--) {
- _pocketStatus[menu][i] = _pocketStatus[menu][i - 1];
- if (_pocketStatus[menu][i] != MAXMENUANIMS)
- complete = 0;
- }
- if (_pocketStatus[menu][i] != MAXMENUANIMS)
- complete = 0;
-
- // ... and animate the first icon
- if (_pocketStatus[menu][0] != MAXMENUANIMS)
- _pocketStatus[menu][0]++;
-
- // Check to see if the menu is fully open
- if (complete)
- _menuStatus[menu] = RDMENU_SHOWN;
- } else if (_menuStatus[menu] == RDMENU_CLOSING) {
- // The menu is closing, so process it here
- complete = 1;
-
- // 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);
- updateRect(&r1);
- }
+ if (_menuStatus[menu] == RDMENU_HIDDEN || _menuStatus[menu] == RDMENU_ALMOST_HIDDEN || _menuStatus[menu] == RDMENU_SHOWN)
+ continue;
- _pocketStatus[menu][i] = _pocketStatus[menu][i - 1];
- if (_pocketStatus[menu][i] != 0)
- complete = 0;
- }
- if (_pocketStatus[menu][i] != 0)
- complete = 0;
+ int target, direction, nextState;
- // ... and animate the first icon
- if (_pocketStatus[menu][0] != 0) {
- _pocketStatus[menu][0]--;
+ if (_menuStatus[menu] == RDMENU_OPENING) {
+ target = MAXMENUANIMS;
+ direction = 1;
+ nextState = RDMENU_SHOWN;
+ } else {
+ target = 0;
+ direction = -1;
+ nextState = RDMENU_ALMOST_HIDDEN;
+ }
- if (_pocketStatus[menu][0] == 0) {
- clearIconArea(menu, 0, &r1);
- updateRect(&r1);
- }
- }
+ bool complete = true;
+
+ // Propagate animation from the first icon...
+ for (i = RDMENU_MAXPOCKETS - 1; i > 0; i--) {
+ _pocketStatus[menu][i] = _pocketStatus[menu][i - 1];
- // Check to see if the menu is fully closed
- if (complete)
- _menuStatus[menu] = RDMENU_HIDDEN;
+ if (_pocketStatus[menu][i] != target)
+ complete = false;
}
+
+ if (_pocketStatus[menu][i] != target)
+ complete = false;
+
+ // ...and animate the first icon
+ if (_pocketStatus[menu][0] != target)
+ _pocketStatus[menu][0] += direction;
+
+ if (complete)
+ _menuStatus[menu] = nextState;
}
}
-
- // Does the menu need to be drawn?
+
for (menu = RDMENU_TOP; menu <= RDMENU_BOTTOM; menu++) {
- if (_menuStatus[menu] != RDMENU_HIDDEN) {
- // Draw the menu here.
- curx = RDMENU_ICONSTART + RDMENU_ICONWIDE / 2;
- cury = (MENUDEEP / 2) + (RENDERDEEP + MENUDEEP) * menu;
-
- 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 (_menuStatus[menu] == RDMENU_HIDDEN)
+ continue;
+
+ if (_menuStatus[menu] == RDMENU_ALMOST_HIDDEN)
+ _menuStatus[menu] = RDMENU_HIDDEN;
+
+ // Draw the menu here.
+ int32 curx = RDMENU_ICONSTART + RDMENU_ICONWIDE / 2;
+ int32 cury = (MENUDEEP / 2) + (RENDERDEEP + MENUDEEP) * menu;
+
+ for (i = 0; i < RDMENU_MAXPOCKETS; i++) {
+ if (_icons[menu][i]) {
+ int32 xoff, yoff;
+
+ // 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);
- r2.left = curx - xoff;
- r2.right = r2.left + RDMENU_ICONWIDE;
- yoff = (RDMENU_ICONDEEP / 2);
- r2.top = cury - yoff;
- r2.bottom = r2.top + RDMENU_ICONDEEP;
- } else {
- xoff = (RDMENU_ICONWIDE / 2) * _pocketStatus[menu][i] / MAXMENUANIMS;
- r2.left = curx - xoff;
- r2.right = curx + xoff;
- yoff = (RDMENU_ICONDEEP / 2) * _pocketStatus[menu][i] / MAXMENUANIMS;
- r2.top = cury - yoff;
- r2.bottom = cury + yoff;
- }
+ if (_pocketStatus[menu][i] == MAXMENUANIMS) {
+ xoff = (RDMENU_ICONWIDE / 2);
+ r2.left = curx - xoff;
+ r2.right = r2.left + RDMENU_ICONWIDE;
+ yoff = (RDMENU_ICONDEEP / 2);
+ r2.top = cury - yoff;
+ r2.bottom = r2.top + RDMENU_ICONDEEP;
+ } else {
+ xoff = (RDMENU_ICONWIDE / 2) * _pocketStatus[menu][i] / MAXMENUANIMS;
+ r2.left = curx - xoff;
+ r2.right = curx + xoff;
+ yoff = (RDMENU_ICONDEEP / 2) * _pocketStatus[menu][i] / MAXMENUANIMS;
+ r2.top = cury - yoff;
+ r2.bottom = cury + yoff;
+ }
+
+ if (xoff != 0 && yoff != 0) {
+ byte *dst = _buffer + r2.top * _screenWide + r2.left;
+ byte *src = _icons[menu][i];
- if (xoff != 0 && yoff != 0) {
- dst = _buffer + r2.top * _screenWide + r2.left;
- src = _icons[menu][i];
-
- if (_pocketStatus[menu][i] != MAXMENUANIMS) {
- squashImage(
- dst, _screenWide, r2.right - r2.left, r2.bottom - r2.top,
- src, RDMENU_ICONWIDE, RDMENU_ICONWIDE, RDMENU_ICONDEEP, NULL);
- } else {
- for (j = 0; j < RDMENU_ICONDEEP; j++) {
- memcpy(dst, src, RDMENU_ICONWIDE);
- src += RDMENU_ICONWIDE;
- dst += _screenWide;
- }
+ if (_pocketStatus[menu][i] != MAXMENUANIMS) {
+ squashImage(
+ dst, _screenWide, r2.right - r2.left, r2.bottom - r2.top,
+ src, RDMENU_ICONWIDE, RDMENU_ICONWIDE, RDMENU_ICONDEEP, NULL);
+ } else {
+ for (j = 0; j < RDMENU_ICONDEEP; j++) {
+ memcpy(dst, src, RDMENU_ICONWIDE);
+ src += RDMENU_ICONWIDE;
+ dst += _screenWide;
}
- updateRect(&r1);
}
}
- curx += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
- r1.left += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
- r1.right += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
+ updateRect(&r1);
}
+ curx += (RDMENU_ICONSPACING + RDMENU_ICONWIDE);
}
}
}
@@ -239,16 +222,16 @@ void Graphics::closeMenuImmediately(void) {
Common::Rect r;
int i;
- _menuStatus[0] = RDMENU_HIDDEN;
- _menuStatus[1] = RDMENU_HIDDEN;
+ _menuStatus[RDMENU_TOP] = RDMENU_HIDDEN;
+ _menuStatus[RDMENU_BOTTOM] = RDMENU_HIDDEN;
for (i = 0; i < RDMENU_MAXPOCKETS; i++) {
- if (_icons[0][i]) {
- clearIconArea(0, i, &r);
+ if (_icons[RDMENU_TOP][i]) {
+ clearIconArea(RDMENU_TOP, i, &r);
updateRect(&r);
}
- if (_icons[1][i]) {
- clearIconArea(1, i, &r);
+ if (_icons[RDMENU_BOTTOM][i]) {
+ clearIconArea(RDMENU_BOTTOM, i, &r);
updateRect(&r);
}
}