From 36d863f94e99e05044b2e05f92dbaaf7ff38447e Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Sat, 2 Feb 2008 12:18:36 +0000 Subject: Reworked menu in BRA (now functioning). svn-id: r30737 --- engines/parallaction/graphics.cpp | 6 +- engines/parallaction/graphics.h | 5 +- engines/parallaction/parallaction.h | 2 + engines/parallaction/parallaction_br.cpp | 120 +++++++++++++++++++++---------- 4 files changed, 93 insertions(+), 40 deletions(-) (limited to 'engines/parallaction') diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 8c00c165ef..59447c3974 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -325,7 +325,7 @@ void Gfx::drawItems() { Graphics::Surface *surf = g_system->lockScreen(); for (uint i = 0; i < _numItems; i++) { - blt(_items[i].rect, _items[i].data->getData(_items[i].frame), surf, LAYER_FOREGROUND, 0); + blt(_items[i].rect, _items[i].data->getData(_items[i].frame), surf, LAYER_FOREGROUND, _items[i].transparentColor); } g_system->unlockScreen(); } @@ -772,13 +772,15 @@ Gfx::~Gfx() { -int Gfx::setItem(Frames* frames, uint16 x, uint16 y) { +int Gfx::setItem(Frames* frames, uint16 x, uint16 y, byte transparentColor) { int id = _numItems; _items[id].data = frames; _items[id].x = x; _items[id].y = y; + _items[id].transparentColor = transparentColor; + _numItems++; return id; diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index c2b46a1fba..5543831702 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -413,7 +413,7 @@ public: void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); // other items - int setItem(Frames* frames, uint16 x, uint16 y); + int setItem(Frames* frames, uint16 x, uint16 y, byte transparentColor = 0); void setItemFrame(uint item, uint16 f); void hideDialogueStuff(); void freeBalloons(); @@ -480,8 +480,9 @@ protected: uint16 frame; Frames *data; + byte transparentColor; Common::Rect rect; - } _items[2]; + } _items[14]; uint _numItems; diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index cc78415223..f68aa5a3bb 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -909,6 +909,8 @@ private: int showMenu(); void renderMenuItem(Graphics::Surface &surf, const char *text); void invertMenuItem(Graphics::Surface &surf); + Frames* renderMenuItem(const char *text); + void splash(const char *name); diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index d1afbc2740..123a0f968e 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -180,16 +180,72 @@ void Parallaction_br::invertMenuItem(Graphics::Surface &surf) { ((byte*)surf.pixels)[i] ^= 0xD; } +/* + this adapter can handle Surfaces containing multiple frames, + provided all these frames are the same width and height +*/ +struct SurfaceToMultiFrames : public Frames { + + uint _num; + uint _width, _height; + Graphics::Surface *_surf; + + SurfaceToMultiFrames(uint num, uint w, uint h, Graphics::Surface *surf) : _num(num), _width(w), _height(h), _surf(surf) { + + } + + ~SurfaceToMultiFrames() { + delete _surf; + } + + uint16 getNum() { + return _num; + } + byte* getData(uint16 index) { + assert(index < _num); + return (byte*)_surf->getBasePtr(0, _height * index); + } + void getRect(uint16 index, Common::Rect &r) { + assert(index < _num); + r.left = 0; + r.top = 0; + r.setWidth(_width); + r.setHeight(_height); + } + +}; + +Frames* Parallaction_br::renderMenuItem(const char *text) { + // this builds a surface containing two copies of the text. + // one is in normal color, the other is inverted. + // the two 'frames' are used to display selected/unselected menu items + + Graphics::Surface *surf = new Graphics::Surface; + surf->create(MENUITEM_WIDTH, MENUITEM_HEIGHT*2, 1); + + // build first frame to be displayed when item is not selected + _menuFont->setColor(0); + _menuFont->drawString((byte*)surf->getBasePtr(5, 2), MENUITEM_WIDTH, text); + + // build second frame to be displayed when item is selected + _menuFont->drawString((byte*)surf->getBasePtr(5, 2 + MENUITEM_HEIGHT), MENUITEM_WIDTH, text); + byte *s = (byte*)surf->getBasePtr(0, MENUITEM_HEIGHT); + for (int i = 0; i < surf->w * MENUITEM_HEIGHT; i++) { + *s++ ^= 0xD; + } + + // wrap the surface into the suitable Frames adapter + return new SurfaceToMultiFrames(2, MENUITEM_WIDTH, MENUITEM_HEIGHT, surf); +} + + int Parallaction_br::showMenu() { // TODO: filter menu entries according to progress in game -#if 0 - _gfx->clearScreen(Gfx::kBitFront); -#endif - BackgroundInfo info; - Graphics::Surface _menuItems[7]; + #define NUM_MENULINES 7 + Frames *_lines[NUM_MENULINES]; - const char *menuStrings[7] = { + const char *menuStrings[NUM_MENULINES] = { "SEE INTRO", "NEW GAME", "SAVED GAME", @@ -199,7 +255,7 @@ int Parallaction_br::showMenu() { "PART 4" }; - MenuOptions options[7] = { + MenuOptions options[NUM_MENULINES] = { kMenuPart0, kMenuPart1, kMenuLoadGame, @@ -208,17 +264,24 @@ int Parallaction_br::showMenu() { kMenuPart3, kMenuPart4 }; -#if 0 - _disk->loadSlide(info, "tbra"); - _gfx->setPalette(info.palette); - _gfx->flatBlitCnv(&info.bg, 20, 50, Gfx::kBitFront); -#endif + + _gfx->clearScreen(); + _gfx->setBackground(kBackgroundSlide, "tbra", 0, 0); + _gfx->_backgroundInfo.x = 20; + _gfx->_backgroundInfo.y = 50; + int availItems = 4 + _progress; - for (int i = 0; i < availItems; i++) - renderMenuItem(_menuItems[i], menuStrings[i]); + // TODO: keep track of and destroy menu item frames/surfaces - int selectedItem = -1, oldSelectedItem = -2; + int i; + for (i = 0; i < availItems; i++) { + _lines[i] = renderMenuItem(menuStrings[i]); + uint id = _gfx->setItem(_lines[i], MENUITEMS_X, MENUITEMS_Y + MENUITEM_HEIGHT * i, 0xFF); + _gfx->setItemFrame(id, 0); + } + + int selectedItem = -1; setMousePointer(0); @@ -237,23 +300,8 @@ int Parallaction_br::showMenu() { } else selectedItem = -1; - - if (selectedItem != oldSelectedItem) { - - if (selectedItem >= 0 && selectedItem < availItems) - invertMenuItem(_menuItems[selectedItem]); - - if (oldSelectedItem >= 0 && oldSelectedItem < availItems) - invertMenuItem(_menuItems[oldSelectedItem]); - - Common::Rect r(MENUITEM_WIDTH, MENUITEM_HEIGHT); -#if 0 - for (int i = 0; i < availItems; i++) { - r.moveTo(MENUITEMS_X, MENUITEMS_Y + i * 20); - _gfx->copyRect(Gfx::kBitFront, r, (byte*)_menuItems[i].pixels, _menuItems[i].pitch); - } -#endif - oldSelectedItem = selectedItem; + for (int i = 0; i < availItems; i++) { + _gfx->setItemFrame(i, selectedItem == i ? 1 : 0); } _gfx->updateScreen(); @@ -261,11 +309,11 @@ int Parallaction_br::showMenu() { } _system->showMouse(false); + _gfx->hideDialogueStuff(); - info.bg.free(); - - for (int i = 0; i < availItems; i++) - _menuItems[i].free(); + for (i = 0; i < availItems; i++) { + delete _lines[i]; + } return options[selectedItem]; } -- cgit v1.2.3