aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2009-11-03 19:33:31 +0000
committerMartin Kiewitz2009-11-03 19:33:31 +0000
commitd758538eaa6a4c6651d4b5b1aabe18228997a25f (patch)
tree31b8696e906765c6aa2791afbd98d1bd5cde4887
parent34aaac37fc565624abb0e52bcc07d7bfed5f5c67 (diff)
downloadscummvm-rg350-d758538eaa6a4c6651d4b5b1aabe18228997a25f.tar.gz
scummvm-rg350-d758538eaa6a4c6651d4b5b1aabe18228997a25f.tar.bz2
scummvm-rg350-d758538eaa6a4c6651d4b5b1aabe18228997a25f.zip
SCI/newgui: SciGuiMenu partially implemented
svn-id: r45634
-rw-r--r--engines/sci/engine/kmenu.cpp13
-rw-r--r--engines/sci/gui/gui.cpp11
-rw-r--r--engines/sci/gui/gui.h2
-rw-r--r--engines/sci/gui/gui_menu.cpp172
-rw-r--r--engines/sci/gui/gui_menu.h51
-rw-r--r--engines/sci/gui32/gui32.cpp10
-rw-r--r--engines/sci/gui32/gui32.h2
7 files changed, 243 insertions, 18 deletions
diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp
index 94cc4b1749..b0af284305 100644
--- a/engines/sci/engine/kmenu.cpp
+++ b/engines/sci/engine/kmenu.cpp
@@ -47,7 +47,18 @@ reg_t kAddMenu(EngineState *s, int argc, reg_t *argv) {
reg_t kSetMenu(EngineState *s, int argc, reg_t *argv) {
- s->_gui->menuSet(argc, argv);
+ uint16 menuId = argv[0].toUint16() >> 8;
+ uint16 itemId = argv[0].toUint16() & 0xFF;
+ uint16 attributeId;
+ int argPos = 1;
+
+ while (argPos < argc) {
+ attributeId = argv[argPos].toUint16();
+ if ((argPos + 1) >= argc)
+ error("Too few parameters for kSetMenu");
+ s->_gui->menuSet(menuId, itemId, attributeId, argv[argPos + 1]);
+ argPos += 2;
+ }
return s->r_acc;
}
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp
index e3b05c6cd0..62dfbd0d89 100644
--- a/engines/sci/gui/gui.cpp
+++ b/engines/sci/gui/gui.cpp
@@ -306,21 +306,24 @@ void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
void SciGui::drawMenuBar(bool clear) {
if (!clear) {
- warning("TODO: drawMenuBar()");
+ GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort);
+ _menu->drawBar();
+ _gfx->SetPort(oldPort);
} else {
drawStatus("", 0, 0);
}
}
void SciGui::menuAdd(Common::String title, Common::String content, reg_t entriesBase) {
- warning("menuAdd");
+ _menu->add(title, content);
}
-void SciGui::menuSet(int argc, reg_t *argv) {
+void SciGui::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
+ _menu->setAttribute(menuId, itemId, attributeId, value);
}
reg_t SciGui::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {
- return NULL_REG;
+ return _menu->getAttribute(menuId, itemId, attributeId);
}
reg_t SciGui::menuSelect(reg_t eventObject) {
diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h
index 9208562f25..cb3ff189a9 100644
--- a/engines/sci/gui/gui.h
+++ b/engines/sci/gui/gui.h
@@ -82,7 +82,7 @@ public:
virtual void drawStatus(const char *text, int16 colorPen, int16 colorBack);
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 void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
virtual reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
virtual reg_t menuSelect(reg_t eventObject);
diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp
index 89a5fefa9c..737e90f35e 100644
--- a/engines/sci/gui/gui_menu.cpp
+++ b/engines/sci/gui/gui_menu.cpp
@@ -39,13 +39,181 @@ namespace Sci {
SciGuiMenu::SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen)
: _gfx(gfx), _text(text), _screen(screen) {
- init();
}
SciGuiMenu::~SciGuiMenu() {
}
-void SciGuiMenu::init() {
+void SciGuiMenu::add(Common::String title, Common::String content) {
+ GuiMenuEntry *menuEntry;
+ uint16 itemCount = 0;
+ GuiMenuItemEntry *itemEntry;
+ int contentSize = content.size();
+ int separatorCount;
+ int curPos, beginPos, endPos, tempPos;
+ int tagPos, rightAlignedPos, functionPos, altPos, controlPos;
+
+ // Sierra SCI starts with id 1, so we do so as well
+ _listCount++;
+ menuEntry = new GuiMenuEntry(_listCount);
+ menuEntry->text = title;
+ _list.push_back(menuEntry);
+
+ curPos = 0;
+ do {
+ itemCount++;
+ itemEntry = new GuiMenuItemEntry(_listCount, itemCount);
+
+ beginPos = curPos;
+
+ // Now go through the content till we find end-marker and collect data about it
+ // ':' is an end-marker for each item
+ tagPos = 0; rightAlignedPos = 0;
+ controlPos = 0; altPos = 0; functionPos = 0;
+ while ((curPos < contentSize) && (content[curPos] != ':')) {
+ switch (content[curPos]) {
+ case '=': // Set tag
+ if (tagPos)
+ error("multiple tag markers within one menu-item");
+ tagPos = curPos;
+ break;
+ case '`': // Right-aligned
+ if (rightAlignedPos)
+ error("multiple right-aligned markers within one menu-item");
+ rightAlignedPos = curPos;
+ break;
+ case '^': // Ctrl-prefix
+ if (controlPos)
+ error("multiple control markers within one menu-item");
+ controlPos = curPos;
+ break;
+ case '@': // Alt-prefix
+ if (altPos)
+ error("multiple alt markers within one menu-item");
+ altPos = curPos;
+ break;
+ case '#': // Function-prefix
+ if (functionPos)
+ error("multiple function markers within one menu-item");
+ functionPos = curPos;
+ break;
+ }
+ curPos++;
+ }
+ endPos = curPos;
+
+ // Control/Alt/Function key mapping...
+ if (controlPos) {
+ content.setChar(SCI_MENU_REPLACE_ONCONTROL, controlPos);
+ itemEntry->keyModifier = SCI_EVM_CTRL;
+ tempPos = controlPos + 1;
+ if (tempPos >= contentSize)
+ error("control marker at end of item");
+ itemEntry->keyPress = tolower(content[tempPos]);
+ content.setChar(toupper(content[tempPos]), tempPos);
+ }
+ if (altPos) {
+ content.setChar(SCI_MENU_REPLACE_ONALT, altPos);
+ itemEntry->keyModifier = SCI_EVM_ALT;
+ tempPos = altPos + 1;
+ if (tempPos >= contentSize)
+ error("alt marker at end of item");
+ itemEntry->keyPress = tolower(content[tempPos]);
+ content.setChar(toupper(content[tempPos]), tempPos);
+ }
+ if (functionPos) {
+ content.setChar(SCI_MENU_REPLACE_ONFUNCTION, functionPos);
+ tempPos = functionPos + 1;
+ if (tempPos >= contentSize)
+ error("function marker at end of item");
+ itemEntry->keyPress = content[tempPos];
+ switch (content[functionPos + 1]) {
+ case '1': itemEntry->keyPress = SCI_K_F1; break;
+ case '2': itemEntry->keyPress = SCI_K_F2; break;
+ case '3': itemEntry->keyPress = SCI_K_F3; break;
+ case '4': itemEntry->keyPress = SCI_K_F4; break;
+ case '5': itemEntry->keyPress = SCI_K_F5; break;
+ case '6': itemEntry->keyPress = SCI_K_F6; break;
+ case '7': itemEntry->keyPress = SCI_K_F7; break;
+ case '8': itemEntry->keyPress = SCI_K_F8; break;
+ case '9': itemEntry->keyPress = SCI_K_F9; break;
+ case '0': itemEntry->keyPress = SCI_K_F10; break;
+ default:
+ error("illegal function key specified");
+ }
+ }
+
+ // Now get all strings
+ tempPos = endPos;
+ if (rightAlignedPos) {
+ tempPos = rightAlignedPos;
+ } else if (tagPos) {
+ tempPos = tagPos;
+ }
+ curPos = beginPos;
+ separatorCount = 0;
+ while (curPos < tempPos) {
+ switch (content[curPos]) {
+ case '!':
+ case '-':
+ case ' ':
+ separatorCount++;
+ }
+ curPos++;
+ }
+ if (separatorCount == tempPos - beginPos) {
+ itemEntry->separatorLine = true;
+ } else {
+ itemEntry->text = Common::String(content.c_str() + beginPos, tempPos - beginPos);
+ }
+
+ if (rightAlignedPos) {
+ rightAlignedPos++;
+ tempPos = endPos;
+ if (tagPos)
+ tempPos = tagPos;
+ itemEntry->textRightAligned = Common::String(content.c_str() + rightAlignedPos, tempPos - rightAlignedPos);
+ }
+
+ if (tagPos) {
+ tempPos = functionPos + 1;
+ if (tempPos >= contentSize)
+ error("tag marker at end of item");
+ itemEntry->tag = atoi(content.c_str() + tempPos);
+ }
+
+ curPos = endPos + 1;
+
+ _itemList.push_back(itemEntry);
+ } while (curPos < contentSize);
+}
+
+void SciGuiMenu::setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
+ warning("setAttr: %d %d %d", menuId, itemId, attributeId);
+}
+
+reg_t SciGuiMenu::getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId) {
+ return NULL_REG;
+}
+
+void SciGuiMenu::drawBar() {
+ GuiMenuEntry *listEntry;
+ GuiMenuList::iterator listIterator;
+ GuiMenuList::iterator listEnd = _list.end();
+
+ // Hardcoded black on white
+ _gfx->FillRect(_gfx->_menuRect, 1, _screen->_colorWhite);
+ _gfx->PenColor(0);
+ _gfx->MoveTo(8, 1);
+
+ listIterator = _list.begin();
+ while (listIterator != listEnd) {
+ listEntry = *listIterator;
+ _text->Draw_String(listEntry->text.c_str());
+
+ listIterator++;
+ }
+ _gfx->BitsShow(_gfx->_menuRect);
}
} // End of namespace Sci
diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h
index d3119f2084..919cc39dca 100644
--- a/engines/sci/gui/gui_menu.h
+++ b/engines/sci/gui/gui_menu.h
@@ -28,18 +28,67 @@
namespace Sci {
+enum {
+ SCI_MENU_ATTRIBUTE_SAID = 0x6d,
+ SCI_MENU_ATTRIBUTE_TEXT = 0x6e,
+ SCI_MENU_ATTRIBUTE_KEY = 0x6f,
+ SCI_MENU_ATTRIBUTE_ENABLED = 0x70,
+ SCI_MENU_ATTRIBUTE_TAG = 0x71
+};
+
+enum {
+ SCI_MENU_REPLACE_ONCONTROL = 0x03,
+ SCI_MENU_REPLACE_ONALT = 0x02,
+ SCI_MENU_REPLACE_ONFUNCTION = 'F'
+};
+
+struct GuiMenuEntry {
+ uint16 id;
+ Common::String text;
+
+ GuiMenuEntry(uint16 id)
+ : id(id) { }
+};
+typedef Common::List<GuiMenuEntry *> GuiMenuList;
+
+struct GuiMenuItemEntry {
+ uint16 menuId;
+ uint16 id;
+ bool enabled;
+ uint16 tag;
+ uint16 keyPress;
+ uint16 keyModifier;
+ bool separatorLine;
+ Common::String said;
+ Common::String text;
+ Common::String textRightAligned;
+
+ GuiMenuItemEntry(uint16 menuId, uint16 id)
+ : menuId(menuId), id(id),
+ enabled(true), tag(0), keyPress(0), keyModifier(0), separatorLine(false) { }
+};
+typedef Common::List<GuiMenuItemEntry *> GuiMenuItemList;
+
class SciGuiMenu {
public:
SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen);
~SciGuiMenu();
+ void add(Common::String title, Common::String content);
+ void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
+ reg_t getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId);
+
+ void drawBar();
private:
- void init(void);
SciGuiGfx *_gfx;
SciGuiText *_text;
SciGuiScreen *_screen;
+
+ uint16 _listCount;
+ GuiMenuList _list;
+ GuiMenuItemList _itemList;
};
} // End of namespace Sci
diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp
index 3a51f92aa9..5b6900f6eb 100644
--- a/engines/sci/gui32/gui32.cpp
+++ b/engines/sci/gui32/gui32.cpp
@@ -834,14 +834,8 @@ void SciGui32::menuAdd(Common::String title, Common::String content, reg_t entri
_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;
- }
+void SciGui32::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
+ _s->_menubar->setAttribute(_s, menuId - 1, itemId - 1, attributeId, value);
}
reg_t SciGui32::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {
diff --git a/engines/sci/gui32/gui32.h b/engines/sci/gui32/gui32.h
index 6256ee15ff..a0dae12f0e 100644
--- a/engines/sci/gui32/gui32.h
+++ b/engines/sci/gui32/gui32.h
@@ -61,7 +61,7 @@ public:
void drawStatus(const char *text, int16 colorPen, int16 colorBack);
void drawMenuBar(bool clear);
void menuAdd(Common::String title, Common::String content, reg_t entriesBase);
- void menuSet(int argc, reg_t *argv);
+ void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
reg_t menuSelect(reg_t eventObject);