aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2009-11-05 07:28:44 +0000
committerMartin Kiewitz2009-11-05 07:28:44 +0000
commit0b8a2ff617ee1b1901fd8264daad1083a1c7c2d3 (patch)
treeb477e0a4b049e488d99659c04a5aef1730dcbde2 /engines/sci
parentb64afbdac0c66d04eac662454d2f450688b0d57b (diff)
downloadscummvm-rg350-0b8a2ff617ee1b1901fd8264daad1083a1c7c2d3.tar.gz
scummvm-rg350-0b8a2ff617ee1b1901fd8264daad1083a1c7c2d3.tar.bz2
scummvm-rg350-0b8a2ff617ee1b1901fd8264daad1083a1c7c2d3.zip
SCI/newgui: SciGuiMenu interactive keyboard support added (menu drawing still missing)
svn-id: r45684
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/gui/gui.cpp3
-rw-r--r--engines/sci/gui/gui_menu.cpp151
-rw-r--r--engines/sci/gui/gui_menu.h9
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