diff options
-rw-r--r-- | dists/msvc8/sci.vcproj | 2 | ||||
-rw-r--r-- | dists/msvc9/sci.vcproj | 2 | ||||
-rw-r--r-- | engines/sci/engine/kmenu.cpp | 300 | ||||
-rw-r--r-- | engines/sci/gui/gui.cpp | 26 | ||||
-rw-r--r-- | engines/sci/gui/gui.h | 10 | ||||
-rw-r--r-- | engines/sci/gui/gui_menu.cpp | 51 | ||||
-rw-r--r-- | engines/sci/gui/gui_menu.h | 47 | ||||
-rw-r--r-- | engines/sci/gui32/gui32.cpp | 282 | ||||
-rw-r--r-- | engines/sci/gui32/gui32.h | 8 | ||||
-rw-r--r-- | engines/sci/module.mk | 1 |
10 files changed, 430 insertions, 299 deletions
diff --git a/dists/msvc8/sci.vcproj b/dists/msvc8/sci.vcproj index 52b3f46050..e2a6690056 100644 --- a/dists/msvc8/sci.vcproj +++ b/dists/msvc8/sci.vcproj @@ -97,6 +97,8 @@ <File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" /> <File RelativePath="..\..\engines\sci\gui\gui_gfx.h" /> <File RelativePath="..\..\engines\sci\gui\gui_helpers.h" /> + <File RelativePath="..\..\engines\sci\gui\gui_menu.cpp" /> + <File RelativePath="..\..\engines\sci\gui\gui_menu.h" /> <File RelativePath="..\..\engines\sci\gui\gui_palette.cpp" /> <File RelativePath="..\..\engines\sci\gui\gui_palette.h" /> <File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" /> diff --git a/dists/msvc9/sci.vcproj b/dists/msvc9/sci.vcproj index ac00c54780..182d9a4a10 100644 --- a/dists/msvc9/sci.vcproj +++ b/dists/msvc9/sci.vcproj @@ -98,6 +98,8 @@ <File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" /> <File RelativePath="..\..\engines\sci\gui\gui_gfx.h" /> <File RelativePath="..\..\engines\sci\gui\gui_helpers.h" /> + <File RelativePath="..\..\engines\sci\gui\gui_menu.cpp" /> + <File RelativePath="..\..\engines\sci\gui\gui_menu.h" /> <File RelativePath="..\..\engines\sci\gui\gui_palette.cpp" /> <File RelativePath="..\..\engines\sci\gui\gui_palette.h" /> <File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" /> 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 \ |