diff options
-rw-r--r-- | engines/sci/gui/gui.cpp | 3 | ||||
-rw-r--r-- | engines/sci/gui/gui_menu.cpp | 151 | ||||
-rw-r--r-- | engines/sci/gui/gui_menu.h | 9 |
3 files changed, 144 insertions, 19 deletions
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index 46deb21a7f..c6ca37427e 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -89,6 +89,7 @@ void SciGui::init(bool usesOldGfxFunctions) { _gfx->init(_text); _windowMgr->init(_s->_gameName); + _menu->init(_s->gfx_state); initPriorityBands(); } @@ -308,6 +309,8 @@ void SciGui::drawMenuBar(bool clear) { if (!clear) { GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort); _menu->drawBar(); + if (_screen->_picNotValid == 0) + _gfx->BitsShow(_gfx->_menuRect); _gfx->SetPort(oldPort); } else { drawStatus("", 0, 0); diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp index e1de704b1d..c30dd1176d 100644 --- a/engines/sci/gui/gui_menu.cpp +++ b/engines/sci/gui/gui_menu.cpp @@ -29,6 +29,8 @@ #include "sci/sci.h" #include "sci/engine/state.h" +#include "sci/gfx/gfx_state_internal.h" +#include "sci/gui/gui_helpers.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_cursor.h" #include "sci/gui/gui_font.h" @@ -42,11 +44,22 @@ SciGuiMenu::SciGuiMenu(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, Sci : _segMan(segMan), _gfx(gfx), _text(text), _screen(screen), _cursor(cursor) { _listCount = 0; + // We actually set active item in here and remember last selection of the user + // sierra sci always defaulted to first item every time menu was called via ESC, we dont follow that logic + _curMenuId = 1; + _curItemId = 1; + + _menuSaveHandle = NULL_REG; + _oldPort = NULL; } SciGuiMenu::~SciGuiMenu() { } +void SciGuiMenu::init(GfxState *gfxstate) { + _gfxstate = gfxstate; +} + void SciGuiMenu::add(Common::String title, Common::String content, reg_t contentVmPtr) { GuiMenuEntry *menuEntry; uint16 itemCount = 0; @@ -224,6 +237,7 @@ void SciGuiMenu::setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, case SCI_MENU_ATTRIBUTE_TEXT: itemEntry->text = _segMan->getString(value); itemEntry->textVmPtr = value; + // We assume here that no script ever creates a separatorLine dynamically break; case SCI_MENU_ATTRIBUTE_KEYPRESS: itemEntry->keyPress = tolower(value.offset); @@ -280,9 +294,9 @@ void SciGuiMenu::drawBar() { listIterator++; } - _gfx->BitsShow(_gfx->_menuRect); } +// This helper calculates all text widths for all menus/items void SciGuiMenu::calculateTextWidth() { GuiMenuList::iterator menuIterator; GuiMenuList::iterator menuEnd = _list.end(); @@ -309,22 +323,9 @@ void SciGuiMenu::calculateTextWidth() { } } -GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() { - calculateTextWidth(); - - return NULL; -} - -GuiMenuItemEntry *SciGuiMenu::interactiveWithMouse() { - calculateTextWidth(); - - return NULL; -} - reg_t SciGuiMenu::select(reg_t eventObject) { int16 eventType = GET_SEL32V(_segMan, eventObject, type); - int16 keyPress = GET_SEL32V(_segMan, eventObject, message); - int16 keyModifier = GET_SEL32V(_segMan, eventObject, modifiers); + int16 keyPress, keyModifier; Common::Point mousePosition; GuiMenuItemList::iterator itemIterator = _itemList.begin(); GuiMenuItemList::iterator itemEnd = _itemList.end(); @@ -333,10 +334,16 @@ reg_t SciGuiMenu::select(reg_t eventObject) { switch (eventType) { case SCI_EVT_KEYBOARD: - if (keyPress == SCI_K_ESC) { + keyPress = GET_SEL32V(_segMan, eventObject, message); + keyModifier = GET_SEL32V(_segMan, eventObject, modifiers); + switch (keyPress) { + case 0: + break; + case SCI_K_ESC: itemEntry = interactiveWithKeyboard(); forceClaimed = true; - } else if (keyPress) { + break; + default: while (itemIterator != itemEnd) { itemEntry = *itemIterator; if ((itemEntry->keyPress == keyPress) && (itemEntry->keyModifier == keyModifier)) @@ -347,8 +354,19 @@ reg_t SciGuiMenu::select(reg_t eventObject) { itemEntry = NULL; } break; + case SCI_EVT_SAID: + while (itemIterator != itemEnd) { + itemEntry = *itemIterator; + // TODO: said comparsion + // said(_s, itemEntry->said.c_str(), 0) != SAID_NO_MATCH + // Where is this used anyway, so we can test it out? + itemIterator++; + } + if (itemIterator == itemEnd) + itemEntry = NULL; break; + case SCI_EVT_MOUSE_PRESS: mousePosition = _cursor->getPosition(); if (mousePosition.y < 10) { @@ -358,12 +376,107 @@ reg_t SciGuiMenu::select(reg_t eventObject) { break; } - if ((itemEntry) || (forceClaimed)) { - PUT_SEL32(_segMan, eventObject, claimed, make_reg(0, 1)); + if (!_menuSaveHandle.isNull()) { + _gfx->BitsRestore(_menuSaveHandle); + _gfx->BitsShow(_gfx->_menuRect); } + if (_oldPort) + _gfx->SetPort(_oldPort); + + if ((itemEntry) || (forceClaimed)) + PUT_SEL32(_segMan, eventObject, claimed, make_reg(0, 1)); if (itemEntry) return make_reg(0, (itemEntry->menuId << 8) | (itemEntry->id)); return NULL_REG; } +GuiMenuItemEntry *SciGuiMenu::interactiveGetItem(uint16 menuId, uint16 itemId) { + GuiMenuItemList::iterator itemIterator = _itemList.begin(); + GuiMenuItemList::iterator itemEnd = _itemList.end(); + GuiMenuItemEntry *itemEntry; + GuiMenuItemEntry *lastItemEntry = NULL; + + // Fixup menuId if needed + menuId = CLIP<uint16>(menuId, 1, _listCount); + // Fixup itemId as well + if (itemId == 0) + itemId = 32678; + while (itemIterator != itemEnd) { + itemEntry = *itemIterator; + if (itemEntry->menuId == menuId) { + if (itemEntry->id == itemId) + return itemEntry; + if ((!lastItemEntry) || (itemEntry->id > lastItemEntry->id)) + lastItemEntry = itemEntry; + } + itemIterator++; + } + return lastItemEntry; +} + +GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() { + sci_event_t curEvent; + uint16 newMenuId = _curMenuId; + uint16 newItemId = _curItemId; + GuiMenuItemEntry *curItemEntry = findItem(_curMenuId, _curItemId); + GuiMenuItemEntry *newItemEntry = curItemEntry; + + calculateTextWidth(); + _oldPort = _gfx->SetPort(_gfx->_menuPort); + _menuSaveHandle = _gfx->BitsSave(_gfx->_menuRect, SCI_SCREEN_MASK_VISUAL); + drawBar(); + + _gfx->BitsShow(_gfx->_menuRect); + + while (true) { + curEvent = gfxop_get_event(_gfxstate, SCI_EVT_ANY); + + switch (curEvent.type) { + case SCI_EVT_KEYBOARD: + switch (curEvent.data) { + case SCI_K_ESC: + _curMenuId = curItemEntry->menuId; _curItemId = curItemEntry->id; + return NULL; + case SCI_K_ENTER: + _curMenuId = curItemEntry->menuId; _curItemId = curItemEntry->id; + return curItemEntry; + case SCI_K_LEFT: + newMenuId--; + break; + case SCI_K_RIGHT: + newMenuId++; + break; + case SCI_K_UP: + newItemId--; + break; + case SCI_K_DOWN: + newItemId++; + break; + } + if ((newMenuId != curItemEntry->menuId) || (newItemId != curItemEntry->id)) { + // Selection changed, fix up new selection if required and paint old and new + newItemEntry = interactiveGetItem(newMenuId, newItemId); + newMenuId = newItemEntry->menuId; newItemId = newItemEntry->id; + + if (newMenuId != curItemEntry->menuId) { + // Menu changed, remove cur menu and paint new menu + } + + curItemEntry = newItemEntry; + } + break; + + case SCI_EVT_NONE: + gfxop_sleep(_gfxstate, 2500 / 1000); + break; + } + } +} + +GuiMenuItemEntry *SciGuiMenu::interactiveWithMouse() { + calculateTextWidth(); + + return NULL; +} + } // End of namespace Sci diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h index 6cd072fd35..a3eb9e8443 100644 --- a/engines/sci/gui/gui_menu.h +++ b/engines/sci/gui/gui_menu.h @@ -81,6 +81,7 @@ public: SciGuiMenu(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor); ~SciGuiMenu(); + void init(GfxState *gfxstate); void add(Common::String title, Common::String content, reg_t contentVmPtr); void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); reg_t getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId); @@ -93,7 +94,9 @@ private: void calculateTextWidth(); GuiMenuItemEntry *interactiveWithKeyboard(); GuiMenuItemEntry *interactiveWithMouse(); + GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId); + GfxState *_gfxstate; SegManager *_segMan; SciGuiGfx *_gfx; SciGuiText *_text; @@ -103,6 +106,12 @@ private: uint16 _listCount; GuiMenuList _list; GuiMenuItemList _itemList; + + uint16 _curMenuId; + uint16 _curItemId; + + GuiPort *_oldPort; + GuiMemoryHandle _menuSaveHandle; }; } // End of namespace Sci |