aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMartin Kiewitz2009-11-02 17:59:19 +0000
committerMartin Kiewitz2009-11-02 17:59:19 +0000
commit10a902735afa9f1a7c5eeef868293bee68003a66 (patch)
tree4625fb0daf4cee51bdd5fa33049a5dd0094a63b8 /engines
parentab3eb81dfb3839fcae13edb83fc85a5759106b1c (diff)
downloadscummvm-rg350-10a902735afa9f1a7c5eeef868293bee68003a66.tar.gz
scummvm-rg350-10a902735afa9f1a7c5eeef868293bee68003a66.tar.bz2
scummvm-rg350-10a902735afa9f1a7c5eeef868293bee68003a66.zip
SCI: SciGuiMenu created, kMenu-related stuff now using SciGui
svn-id: r45612
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kmenu.cpp300
-rw-r--r--engines/sci/gui/gui.cpp26
-rw-r--r--engines/sci/gui/gui.h10
-rw-r--r--engines/sci/gui/gui_menu.cpp51
-rw-r--r--engines/sci/gui/gui_menu.h47
-rw-r--r--engines/sci/gui32/gui32.cpp282
-rw-r--r--engines/sci/gui32/gui32.h8
-rw-r--r--engines/sci/module.mk1
8 files changed, 426 insertions, 299 deletions
diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp
index bfad83cf0a..a08593946d 100644
--- a/engines/sci/engine/kmenu.cpp
+++ b/engines/sci/engine/kmenu.cpp
@@ -38,41 +38,25 @@
namespace Sci {
reg_t kAddMenu(EngineState *s, int argc, reg_t *argv) {
- Common::String name = s->_segMan->getString(argv[0]);
- Common::String contents = s->_segMan->getString(argv[1]);
-
- int titlebarFont = 0;
-
-#ifdef INCLUDE_OLDGFX
- titlebarFont = s->titlebar_port->_font;
-#else
- // TODO: titlebar port font
-#endif
-
- s->_menubar->addMenu(s->gfx_state, name,
- contents, titlebarFont, argv[1]);
+ Common::String title = s->_segMan->getString(argv[0]);
+ Common::String content = s->_segMan->getString(argv[1]);
+ s->_gui->menuAdd(title, content, argv[1]);
return s->r_acc;
-
}
reg_t kSetMenu(EngineState *s, int argc, reg_t *argv) {
- int index = argv[0].toUint16();
- int i = 2;
-
- while (i < argc) {
- s->_menubar->setAttribute(s, (index >> 8) - 1, (index & 0xff) - 1, argv[i - 1].toUint16(), argv[i]);
- i += 2;
- }
-
+ s->_gui->menuSet(argc, argv);
return s->r_acc;
}
reg_t kGetMenu(EngineState *s, int argc, reg_t *argv) {
- int index = argv[0].toUint16();
+ uint16 menuId = argv[0].toUint16() >> 8;
+ uint16 itemId = argv[0].toUint16() & 0xFF;
+ uint16 attributeId = argv[1].toUint16();
- return s->_menubar->getAttribute((index >> 8) - 1, (index & 0xff) - 1, argv[1].toUint16());
+ return s->_gui->menuGet(menuId, itemId, attributeId);
}
@@ -92,272 +76,18 @@ reg_t kDrawStatus(EngineState *s, int argc, reg_t *argv) {
}
reg_t kDrawMenuBar(EngineState *s, int argc, reg_t *argv) {
- if (argv[0].toSint16())
- s->_gui->drawMenuBar();
- else
- s->_gui->clearMenuBar();
- return s->r_acc;
-}
+ bool clear = argv[0].isNull() ? true : false;
-
-static int _menu_go_down(Menubar *menubar, int menu_nr, int item_nr) {
- int seeker;
- const int max = menubar->_menus[menu_nr]._items.size();
- seeker = item_nr + 1;
-
- while ((seeker < max) && !menubar->itemValid(menu_nr, seeker))
- ++seeker;
-
- if (seeker != max)
- return seeker;
- else
- return item_nr;
+ s->_gui->drawMenuBar(clear);
+ return s->r_acc;
}
-// TODO/FIXME: avoid full screen updates
-#ifdef INCLUDE_OLDGFX
-#define FULL_REDRAW \
- s->visual->draw(Common::Point(0, 0)); \
- gfxop_update(s->gfx_state);
-#else
-#define FULL_REDRAW \
- s->_gui->graphRedrawBox(Common::Rect(0, 0, 319, 219));
-#endif
-
reg_t kMenuSelect(EngineState *s, int argc, reg_t *argv) {
- SegManager *segMan = s->_segMan;
- reg_t event = argv[0];
- /*int pause_sound = (argc > 1) ? argv[1].toUint16() : 1;*/ /* FIXME: Do this eventually */
- bool claimed = false;
- int type = GET_SEL32V(segMan, event, type);
- int message = GET_SEL32V(segMan, event, message);
- int modifiers = GET_SEL32V(segMan, event, modifiers);
- int menu_nr = -1, item_nr = 0;
- MenuItem *item;
- int menu_mode = 0; /* Menu is active */
- int mouse_down = 0;
-
-#ifdef DEBUG_PARSER
- const int debug_parser = 1;
-#else
- const int debug_parser = 0;
-#endif
-
-#ifdef INCLUDE_OLDGFX
- gfxop_set_clip_zone(s->gfx_state, gfx_rect_fullscreen);
-#endif
-
- /* Check whether we can claim the event directly as a keyboard or said event */
- if (type & (SCI_EVT_KEYBOARD | SCI_EVT_SAID)) {
- int menuc, itemc;
-
- if ((type == SCI_EVT_KEYBOARD)
- && (message == SCI_K_ESC))
- menu_mode = 1;
-
- else if ((type == SCI_EVT_SAID) || message) { /* Don't claim 0 keyboard event */
- debugC(2, kDebugLevelMenu, "Menu: Got %s event: %04x/%04x\n",
- ((type == SCI_EVT_SAID) ? "SAID" : "KBD"), message, modifiers);
-
- for (menuc = 0; menuc < (int)s->_menubar->_menus.size(); menuc++)
- for (itemc = 0; itemc < (int)s->_menubar->_menus[menuc]._items.size(); itemc++) {
- item = &s->_menubar->_menus[menuc]._items[itemc];
-
- debugC(2, kDebugLevelMenu, "Menu: Checking against %s: %04x/%04x (type %d, %s)\n",
- !item->_text.empty() ? item->_text.c_str() : "--bar--", item->_key, item->_modifiers,
- item->_type, item->_enabled ? "enabled" : "disabled");
-
- if ((item->_type == MENU_TYPE_NORMAL && item->_enabled)
- && ((type == SCI_EVT_KEYBOARD
- && item->matchKey(message, modifiers)
- )
- ||
- (type == SCI_EVT_SAID
- && (item->_flags & MENU_ATTRIBUTE_FLAGS_SAID)
- && said(s, item->_said, debug_parser) != SAID_NO_MATCH
- )
- )
- ) {
- /* Claim the event */
- debugC(2, kDebugLevelMenu, "Menu: Event CLAIMED for %d/%d\n", menuc, itemc);
- claimed = true;
- menu_nr = menuc;
- item_nr = itemc;
- }
- }
- }
- }
-
- Common::Point cursorPos = s->_cursor->getPosition();
-
- if ((type == SCI_EVT_MOUSE_PRESS) && (cursorPos.y < 10)) {
- menu_mode = 1;
- mouse_down = 1;
- }
-
- if (menu_mode) {
- int old_item;
- int old_menu;
- Common::Rect portBounds = Common::Rect(4, 9, 200, 50);
-
-#ifdef INCLUDE_OLDGFX
- GfxPort *port = sciw_new_menu(s, s->titlebar_port, s->_menubar, 0);
- portBounds = toCommonRect(port->_bounds);
-#endif
-
- item_nr = -1;
-
- /* Default to menu 0, unless the mouse was used to generate this effect */
- if (mouse_down)
- s->_menubar->mapPointer(cursorPos, menu_nr, item_nr, portBounds);
- else
- menu_nr = 0;
-
-#ifdef INCLUDE_OLDGFX
- sciw_set_menubar(s, s->titlebar_port, s->_menubar, menu_nr);
-#endif
+ reg_t eventObject = argv[0];
+ bool pauseSound = argc > 1 ? (argv[1].isNull() ? false : true) : false;
- FULL_REDRAW;
-
- old_item = -1;
- old_menu = -1;
-
- while (menu_mode) {
- sci_event_t ev = gfxop_get_event(s->gfx_state, SCI_EVT_ANY);
-
- claimed = false;
-
- switch (ev.type) {
- case SCI_EVT_QUIT:
- quit_vm();
- return NULL_REG;
-
- case SCI_EVT_KEYBOARD:
- switch (ev.data) {
-
- case SCI_K_ESC:
- menu_mode = 0;
- break;
-
- case SCI_K_ENTER:
- menu_mode = 0;
- if ((item_nr >= 0) && (menu_nr >= 0))
- claimed = true;
- break;
-
- case SCI_K_LEFT:
- if (menu_nr > 0)
- --menu_nr;
- else
- menu_nr = s->_menubar->_menus.size() - 1;
-
- item_nr = _menu_go_down(s->_menubar, menu_nr, -1);
- break;
-
- case SCI_K_RIGHT:
- if (menu_nr < ((int)s->_menubar->_menus.size() - 1))
- ++menu_nr;
- else
- menu_nr = 0;
-
- item_nr = _menu_go_down(s->_menubar, menu_nr, -1);
- break;
-
- case SCI_K_UP:
- if (item_nr > -1) {
-
- do { --item_nr; }
- while ((item_nr > -1) && !s->_menubar->itemValid(menu_nr, item_nr));
- }
- break;
-
- case SCI_K_DOWN: {
- item_nr = _menu_go_down(s->_menubar, menu_nr, item_nr);
- }
- break;
-
- }
- break;
-
- case SCI_EVT_MOUSE_RELEASE:
- {
- Common::Point curMousePos = s->_cursor->getPosition();
- menu_mode = (curMousePos.y < 10);
- claimed = !menu_mode && !s->_menubar->mapPointer(curMousePos, menu_nr, item_nr, portBounds);
- mouse_down = 0;
- }
- break;
-
- case SCI_EVT_MOUSE_PRESS:
- mouse_down = 1;
- break;
-
- case SCI_EVT_NONE:
- gfxop_sleep(s->gfx_state, 2500 / 1000);
- break;
- }
-
- if (mouse_down)
- s->_menubar->mapPointer(s->_cursor->getPosition(), menu_nr, item_nr, portBounds);
-
- if ((item_nr > -1 && old_item == -1) || (menu_nr != old_menu)) { /* Update menu */
-
-#ifdef INCLUDE_OLDGFX
- sciw_set_menubar(s, s->titlebar_port, s->_menubar, menu_nr);
-
- delete port;
-
- port = sciw_new_menu(s, s->titlebar_port, s->_menubar, menu_nr);
- s->wm_port->add((GfxContainer *)s->wm_port, port);
-#endif
-
- if (item_nr > -1)
- old_item = -42; /* Enforce redraw in next step */
- else {
- FULL_REDRAW;
- }
- } /* ...if the menu changed. */
-
- /* Remove the active menu item, if neccessary */
- if (item_nr != old_item) {
-#ifdef INCLUDE_OLDGFX
- port = sciw_toggle_item(port, &(s->_menubar->_menus[menu_nr]), old_item, false);
- port = sciw_toggle_item(port, &(s->_menubar->_menus[menu_nr]), item_nr, true);
-#endif
- FULL_REDRAW;
- }
-
- old_item = item_nr;
- old_menu = menu_nr;
-
- } /* while (menu_mode) */
-
- // Clear the menu
-#ifdef INCLUDE_OLDGFX
- if (port) {
- delete port;
- port = NULL;
- }
-#endif
-
- s->_gui->clearMenuBar();
-
- FULL_REDRAW;
- }
-
- if (claimed) {
- PUT_SEL32(segMan, event, claimed, make_reg(0, 1));
-
- if (menu_nr > -1) {
- s->r_acc = make_reg(0, ((menu_nr + 1) << 8) | (item_nr + 1));
- } else
- s->r_acc = NULL_REG;
-
- debugC(2, kDebugLevelMenu, "Menu: Claim -> %04x\n", s->r_acc.offset);
- } else
- s->r_acc = NULL_REG; /* Not claimed */
-
- return s->r_acc;
+ // TODO: pauseSound implementation
+ return s->_gui->menuSelect(eventObject);
}
} // End of namespace Sci
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp
index 633340335b..ccfaecd960 100644
--- a/engines/sci/gui/gui.cpp
+++ b/engines/sci/gui/gui.cpp
@@ -37,6 +37,7 @@
#include "sci/gui/gui_windowmgr.h"
#include "sci/gui/gui_animate.h"
#include "sci/gui/gui_controls.h"
+#include "sci/gui/gui_menu.h"
#include "sci/gui/gui_text.h"
#include "sci/gui/gui_transitions.h"
#include "sci/gui/gui_view.h"
@@ -61,6 +62,7 @@ SciGui::SciGui(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette,
_text = new SciGuiText(_s->resMan, _gfx, _screen);
_windowMgr = new SciGuiWindowMgr(this, _screen, _gfx, _text);
_controls = new SciGuiControls(_s->_segMan, _gfx, _text);
+ _menu = new SciGuiMenu(_gfx, _text, _screen);
// _gui32 = new SciGui32(_s, _screen, _palette, _cursor); // for debug purposes
}
@@ -301,13 +303,27 @@ void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
_gfx->SetPort(oldPort);
}
-void SciGui::drawMenuBar() {
- // TODO: Implement menubar
- warning("TODO: drawMenuBar()");
+void SciGui::drawMenuBar(bool clear) {
+ if (!clear) {
+ warning("TODO: drawMenuBar()");
+ } else {
+ drawStatus("", 0, 0);
+ }
+}
+
+void SciGui::menuAdd(Common::String title, Common::String content, reg_t entriesBase) {
+ warning("menuAdd");
+}
+
+void SciGui::menuSet(int argc, reg_t *argv) {
}
-void SciGui::clearMenuBar() {
- drawStatus("", 0, 0);
+reg_t SciGui::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {
+ return NULL_REG;
+}
+
+reg_t SciGui::menuSelect(reg_t eventObject) {
+ return NULL_REG;
}
void SciGui::drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) {
diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h
index ca0073bc7c..9208562f25 100644
--- a/engines/sci/gui/gui.h
+++ b/engines/sci/gui/gui.h
@@ -48,6 +48,7 @@ class SciGuiGfx;
class SciGuiWindowMgr;
class SciGuiAnimate;
class SciGuiControls;
+class SciGuiMenu;
class SciGuiText;
class SciGuiTransitions;
class SciGui32; // for debug purposes
@@ -79,8 +80,12 @@ public:
virtual void textColors(int argc, reg_t *argv);
virtual void drawStatus(const char *text, int16 colorPen, int16 colorBack);
- virtual void drawMenuBar();
- virtual void clearMenuBar();
+ virtual void drawMenuBar(bool clear);
+ virtual void menuAdd(Common::String title, Common::String content, reg_t entriesBase);
+ virtual void menuSet(int argc, reg_t *argv);
+ virtual reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
+ virtual reg_t menuSelect(reg_t eventObject);
+
virtual void drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo);
virtual void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight = -1);
virtual void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite);
@@ -159,6 +164,7 @@ private:
SciGuiWindowMgr *_windowMgr;
SciGuiAnimate *_animate;
SciGuiControls *_controls;
+ SciGuiMenu *_menu;
SciGuiText *_text;
SciGuiTransitions *_transitions;
// SciGui32 *_gui32; // for debug purposes
diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp
new file mode 100644
index 0000000000..89a5fefa9c
--- /dev/null
+++ b/engines/sci/gui/gui_menu.cpp
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/util.h"
+#include "common/stack.h"
+#include "graphics/primitives.h"
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/gui/gui_gfx.h"
+#include "sci/gui/gui_font.h"
+#include "sci/gui/gui_text.h"
+#include "sci/gui/gui_screen.h"
+#include "sci/gui/gui_menu.h"
+
+namespace Sci {
+
+SciGuiMenu::SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen)
+ : _gfx(gfx), _text(text), _screen(screen) {
+ init();
+}
+
+SciGuiMenu::~SciGuiMenu() {
+}
+
+void SciGuiMenu::init() {
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h
new file mode 100644
index 0000000000..d3119f2084
--- /dev/null
+++ b/engines/sci/gui/gui_menu.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SCI_GUI_MENU_H
+#define SCI_GUI_MENU_H
+
+namespace Sci {
+
+class SciGuiMenu {
+public:
+ SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen);
+ ~SciGuiMenu();
+
+
+private:
+ void init(void);
+
+ SciGuiGfx *_gfx;
+ SciGuiText *_text;
+ SciGuiScreen *_screen;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp
index 60652163f3..23f4209b0f 100644
--- a/engines/sci/gui32/gui32.cpp
+++ b/engines/sci/gui32/gui32.cpp
@@ -37,6 +37,7 @@
#include "sci/gfx/gfx_gui.h"
#include "sci/gfx/gfx_widgets.h"
#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual
+#include "sci/gfx/menubar.h"
#include "sci/gui32/gui32.h"
#include "sci/gui/gui_animate.h"
#include "sci/gui/gui_cursor.h"
@@ -814,16 +815,287 @@ void SciGui32::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
gfxop_update(_s->gfx_state);
}
-void SciGui32::drawMenuBar() {
- sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, -1);
+void SciGui32::drawMenuBar(bool clear) {
+ if (!clear) {
+ sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, -1);
+ } else {
+ sciw_set_status_bar(_s, _s->titlebar_port, "", 0, 0);
+ }
_s->titlebar_port->draw(Common::Point(0, 0));
gfxop_update(_s->gfx_state);
}
-void SciGui32::clearMenuBar() {
- sciw_set_status_bar(_s, _s->titlebar_port, "", 0, 0);
- _s->titlebar_port->draw(Common::Point(0, 0));
+void SciGui32::menuAdd(Common::String title, Common::String content, reg_t entriesBase) {
+ int titlebarFont = _s->titlebar_port->_font;
+
+ _s->_menubar->addMenu(_s->gfx_state, title, content, titlebarFont, entriesBase);
+}
+
+void SciGui32::menuSet(int argc, reg_t *argv) {
+ int index = argv[0].toUint16();
+ int i = 2;
+
+ while (i < argc) {
+ _s->_menubar->setAttribute(_s, (index >> 8) - 1, (index & 0xff) - 1, argv[i - 1].toUint16(), argv[i]);
+ i += 2;
+ }
+}
+
+reg_t SciGui32::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {
+ return _s->_menubar->getAttribute(menuId - 1, itemId - 1, attributeId);
+}
+
+int _menu_go_down(Menubar *menubar, int menu_nr, int item_nr) {
+ int seeker;
+ const int max = menubar->_menus[menu_nr]._items.size();
+ seeker = item_nr + 1;
+
+ while ((seeker < max) && !menubar->itemValid(menu_nr, seeker))
+ ++seeker;
+
+ if (seeker != max)
+ return seeker;
+ else
+ return item_nr;
+}
+
+#define MENU_FULL_REDRAW \
+ _s->visual->draw(Common::Point(0, 0)); \
gfxop_update(_s->gfx_state);
+
+reg_t SciGui32::menuSelect(reg_t eventObject) {
+ SegManager *segMan = _s->_segMan;
+ /*int pause_sound = (argc > 1) ? argv[1].toUint16() : 1;*/ /* FIXME: Do this eventually */
+ bool claimed = false;
+ int type = GET_SEL32V(segMan, eventObject, type);
+ int message = GET_SEL32V(segMan, eventObject, message);
+ int modifiers = GET_SEL32V(segMan, eventObject, modifiers);
+ int menu_nr = -1, item_nr = 0;
+ MenuItem *item;
+ int menu_mode = 0; /* Menu is active */
+ int mouse_down = 0;
+
+#ifdef DEBUG_PARSER
+ const int debug_parser = 1;
+#else
+ const int debug_parser = 0;
+#endif
+
+#ifdef INCLUDE_OLDGFX
+ gfxop_set_clip_zone(_s->gfx_state, gfx_rect_fullscreen);
+#endif
+
+ /* Check whether we can claim the event directly as a keyboard or said event */
+ if (type & (SCI_EVT_KEYBOARD | SCI_EVT_SAID)) {
+ int menuc, itemc;
+
+ if ((type == SCI_EVT_KEYBOARD)
+ && (message == SCI_K_ESC))
+ menu_mode = 1;
+
+ else if ((type == SCI_EVT_SAID) || message) { /* Don't claim 0 keyboard event */
+ debugC(2, kDebugLevelMenu, "Menu: Got %s event: %04x/%04x\n",
+ ((type == SCI_EVT_SAID) ? "SAID" : "KBD"), message, modifiers);
+
+ for (menuc = 0; menuc < (int)_s->_menubar->_menus.size(); menuc++)
+ for (itemc = 0; itemc < (int)_s->_menubar->_menus[menuc]._items.size(); itemc++) {
+ item = &_s->_menubar->_menus[menuc]._items[itemc];
+
+ debugC(2, kDebugLevelMenu, "Menu: Checking against %s: %04x/%04x (type %d, %s)\n",
+ !item->_text.empty() ? item->_text.c_str() : "--bar--", item->_key, item->_modifiers,
+ item->_type, item->_enabled ? "enabled" : "disabled");
+
+ if ((item->_type == MENU_TYPE_NORMAL && item->_enabled)
+ && ((type == SCI_EVT_KEYBOARD
+ && item->matchKey(message, modifiers)
+ )
+ ||
+ (type == SCI_EVT_SAID
+ && (item->_flags & MENU_ATTRIBUTE_FLAGS_SAID)
+ && said(_s, item->_said, debug_parser) != SAID_NO_MATCH
+ )
+ )
+ ) {
+ /* Claim the event */
+ debugC(2, kDebugLevelMenu, "Menu: Event CLAIMED for %d/%d\n", menuc, itemc);
+ claimed = true;
+ menu_nr = menuc;
+ item_nr = itemc;
+ }
+ }
+ }
+ }
+
+ Common::Point cursorPos = _s->_cursor->getPosition();
+
+ if ((type == SCI_EVT_MOUSE_PRESS) && (cursorPos.y < 10)) {
+ menu_mode = 1;
+ mouse_down = 1;
+ }
+
+ if (menu_mode) {
+ int old_item;
+ int old_menu;
+ Common::Rect portBounds = Common::Rect(4, 9, 200, 50);
+
+#ifdef INCLUDE_OLDGFX
+ GfxPort *port = sciw_new_menu(_s, _s->titlebar_port, _s->_menubar, 0);
+ portBounds = toCommonRect(port->_bounds);
+#endif
+
+ item_nr = -1;
+
+ /* Default to menu 0, unless the mouse was used to generate this effect */
+ if (mouse_down)
+ _s->_menubar->mapPointer(cursorPos, menu_nr, item_nr, portBounds);
+ else
+ menu_nr = 0;
+
+#ifdef INCLUDE_OLDGFX
+ sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, menu_nr);
+#endif
+
+ MENU_FULL_REDRAW;
+
+ old_item = -1;
+ old_menu = -1;
+
+ while (menu_mode) {
+ sci_event_t ev = gfxop_get_event(_s->gfx_state, SCI_EVT_ANY);
+
+ claimed = false;
+
+ switch (ev.type) {
+ case SCI_EVT_QUIT:
+ quit_vm();
+ return NULL_REG;
+
+ case SCI_EVT_KEYBOARD:
+ switch (ev.data) {
+
+ case SCI_K_ESC:
+ menu_mode = 0;
+ break;
+
+ case SCI_K_ENTER:
+ menu_mode = 0;
+ if ((item_nr >= 0) && (menu_nr >= 0))
+ claimed = true;
+ break;
+
+ case SCI_K_LEFT:
+ if (menu_nr > 0)
+ --menu_nr;
+ else
+ menu_nr = _s->_menubar->_menus.size() - 1;
+
+ item_nr = _menu_go_down(_s->_menubar, menu_nr, -1);
+ break;
+
+ case SCI_K_RIGHT:
+ if (menu_nr < ((int)_s->_menubar->_menus.size() - 1))
+ ++menu_nr;
+ else
+ menu_nr = 0;
+
+ item_nr = _menu_go_down(_s->_menubar, menu_nr, -1);
+ break;
+
+ case SCI_K_UP:
+ if (item_nr > -1) {
+
+ do { --item_nr; }
+ while ((item_nr > -1) && !_s->_menubar->itemValid(menu_nr, item_nr));
+ }
+ break;
+
+ case SCI_K_DOWN: {
+ item_nr = _menu_go_down(_s->_menubar, menu_nr, item_nr);
+ }
+ break;
+
+ }
+ break;
+
+ case SCI_EVT_MOUSE_RELEASE:
+ {
+ Common::Point curMousePos = _s->_cursor->getPosition();
+ menu_mode = (curMousePos.y < 10);
+ claimed = !menu_mode && !_s->_menubar->mapPointer(curMousePos, menu_nr, item_nr, portBounds);
+ mouse_down = 0;
+ }
+ break;
+
+ case SCI_EVT_MOUSE_PRESS:
+ mouse_down = 1;
+ break;
+
+ case SCI_EVT_NONE:
+ gfxop_sleep(_s->gfx_state, 2500 / 1000);
+ break;
+ }
+
+ if (mouse_down)
+ _s->_menubar->mapPointer(_s->_cursor->getPosition(), menu_nr, item_nr, portBounds);
+
+ if ((item_nr > -1 && old_item == -1) || (menu_nr != old_menu)) { /* Update menu */
+
+#ifdef INCLUDE_OLDGFX
+ sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, menu_nr);
+
+ delete port;
+
+ port = sciw_new_menu(_s, _s->titlebar_port, _s->_menubar, menu_nr);
+ _s->wm_port->add((GfxContainer *)_s->wm_port, port);
+#endif
+
+ if (item_nr > -1)
+ old_item = -42; /* Enforce redraw in next step */
+ else {
+ MENU_FULL_REDRAW;
+ }
+ } /* ...if the menu changed. */
+
+ /* Remove the active menu item, if neccessary */
+ if (item_nr != old_item) {
+#ifdef INCLUDE_OLDGFX
+ port = sciw_toggle_item(port, &(_s->_menubar->_menus[menu_nr]), old_item, false);
+ port = sciw_toggle_item(port, &(_s->_menubar->_menus[menu_nr]), item_nr, true);
+#endif
+ MENU_FULL_REDRAW;
+ }
+
+ old_item = item_nr;
+ old_menu = menu_nr;
+
+ } /* while (menu_mode) */
+
+ // Clear the menu
+#ifdef INCLUDE_OLDGFX
+ if (port) {
+ delete port;
+ port = NULL;
+ }
+#endif
+
+ _s->_gui->drawMenuBar(true);
+
+ MENU_FULL_REDRAW;
+ }
+
+ if (claimed) {
+ PUT_SEL32(segMan, eventObject, claimed, make_reg(0, 1));
+
+ if (menu_nr > -1) {
+ _s->r_acc = make_reg(0, ((menu_nr + 1) << 8) | (item_nr + 1));
+ } else
+ _s->r_acc = NULL_REG;
+
+ debugC(2, kDebugLevelMenu, "Menu: Claim -> %04x\n", _s->r_acc.offset);
+ } else
+ _s->r_acc = NULL_REG; /* Not claimed */
+
+ return _s->r_acc;
}
void SciGui32::drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) {
diff --git a/engines/sci/gui32/gui32.h b/engines/sci/gui32/gui32.h
index e7a5fb0908..3c70a0bae0 100644
--- a/engines/sci/gui32/gui32.h
+++ b/engines/sci/gui32/gui32.h
@@ -59,8 +59,12 @@ public:
void textColors(int argc, reg_t *argv);
void drawStatus(const char *text, int16 colorPen, int16 colorBack);
- void drawMenuBar();
- void clearMenuBar();
+ void drawMenuBar(bool clear);
+ void menuAdd(Common::String title, Common::String content, reg_t entriesBase);
+ void menuSet(int argc, reg_t *argv);
+ reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
+ reg_t menuSelect(reg_t eventObject);
+
void drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo);
void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight = -1);
void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite);
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 8b05ed3709..b651dcd9bc 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -52,6 +52,7 @@ MODULE_OBJS := \
gui/gui_cursor.o \
gui/gui_font.o \
gui/gui_gfx.o \
+ gui/gui_menu.o \
gui/gui_palette.o \
gui/gui_picture.o \
gui/gui_portrait.o \