aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/gfx
diff options
context:
space:
mode:
authorMax Horn2009-03-24 11:31:16 +0000
committerMax Horn2009-03-24 11:31:16 +0000
commit9ea32d4aa12329d3bfe163664f5d84d7318c01db (patch)
treed1c03e8640f2dc3f4b0361bab317ac09276388f8 /engines/sci/gfx
parent47f9b2eb6d2248e41a58c1e60498c829c41a6317 (diff)
downloadscummvm-rg350-9ea32d4aa12329d3bfe163664f5d84d7318c01db.tar.gz
scummvm-rg350-9ea32d4aa12329d3bfe163664f5d84d7318c01db.tar.bz2
scummvm-rg350-9ea32d4aa12329d3bfe163664f5d84d7318c01db.zip
SCI: C++ify menu code
svn-id: r39659
Diffstat (limited to 'engines/sci/gfx')
-rw-r--r--engines/sci/gfx/menubar.cpp251
-rw-r--r--engines/sci/gfx/menubar.h225
-rw-r--r--engines/sci/gfx/sci_widgets.cpp69
-rw-r--r--engines/sci/gfx/sci_widgets.h22
4 files changed, 271 insertions, 296 deletions
diff --git a/engines/sci/gfx/menubar.cpp b/engines/sci/gfx/menubar.cpp
index f8615a8c69..a586b798e0 100644
--- a/engines/sci/gfx/menubar.cpp
+++ b/engines/sci/gfx/menubar.cpp
@@ -38,87 +38,68 @@ namespace Sci {
#define SIZE_INF 32767
-menubar_t *menubar_new() {
- menubar_t *tmp = (menubar_t*)sci_malloc(sizeof(menubar_t));
- tmp->menus_nr = 0;
-
- return tmp;
+Menu::Menu() {
+ _titleWidth = 0;
+ _width = 0;
}
-void menubar_free(menubar_t *menubar) {
- int i;
-
- for (i = 0; i < menubar->menus_nr; i++) {
- menu_t *menu = &(menubar->menus[i]);
- int j;
-
- for (j = 0; j < menu->items_nr; j++) {
- free(menu->items[j].keytext);
- free(menu->items[j].text);
- }
-
- free(menu->items);
- free(menu->title);
- }
-
- if (menubar->menus_nr)
- free(menubar->menus);
-
- free(menubar);
+MenuItem::MenuItem() {
+ _type = MENU_TYPE_NORMAL;
+ _flags = 0;
+ memset(_said, 0, sizeof(_said));
+ _saidPos = NULL_REG;
+ _textPos = NULL_REG;
+ _modifiers = 0;
+ _key = 0;
+ _enabled = 0;
+ _tag = 0;
}
-int _menubar_add_menu_item(gfx_state_t *state, menu_t *menu, int type, char *left, char *right,
+
+int Menu::addMenuItem(gfx_state_t *state, MenuType type, const char *left, const char *right,
int font, int key, int modifiers, int tag, reg_t text_pos) {
// Returns the total text size, plus MENU_BOX_CENTER_PADDING if (right != NULL)
- menu_item_t *item;
+ MenuItem newItem;
+ MenuItem *item;
int total_left_size = 0;
int width, height;
- if (menu->items_nr == 0) {
- menu->items = (menu_item_t *)sci_malloc(sizeof(menu_item_t));
- menu->items_nr = 1;
- } else
- menu->items = (menu_item_t *)sci_realloc(menu->items, sizeof(menu_item_t) * ++(menu->items_nr));
+ item = &newItem;
+ item->_type = type;
- item = &(menu->items[menu->items_nr - 1]);
-
- memset(item, 0, sizeof(menu_item_t));
-
- if ((item->type = type) == MENU_TYPE_HBAR)
+ if (type == MENU_TYPE_HBAR) {
+ _items.push_back(newItem);
return 0;
+ }
// else assume MENU_TYPE_NORMAL
- item->text = left;
+ item->_text = left;
if (right) {
- int end = strlen(right);
- item->keytext = right;
- while (end && isspace(right[end]))
- right[end--] = 0; // Remove trailing whitespace
- item->flags = MENU_ATTRIBUTE_FLAGS_KEY;
- item->key = key;
- item->modifiers = modifiers;
+ item->_keytext = right;
+ item->_keytext.trim(); // Remove trailing whitespace
+ item->_flags = MENU_ATTRIBUTE_FLAGS_KEY;
+ item->_key = key;
+ item->_modifiers = modifiers;
} else {
- item->keytext = NULL;
- item->flags = 0;
+ item->_flags = 0;
}
if (right) {
- gfxop_get_text_params(state, font, right, SIZE_INF, &width, &height, 0, NULL, NULL, NULL);
- item->keytext_size = width;
+ gfxop_get_text_params(state, font, item->_keytext.c_str(), SIZE_INF, &width, &height, 0, NULL, NULL, NULL);
total_left_size = MENU_BOX_CENTER_PADDING + width;
}
- item->enabled = 1;
- item->tag = tag;
- item->text_pos = text_pos;
+ item->_enabled = 1;
+ item->_tag = tag;
+ item->_textPos = text_pos;
gfxop_get_text_params(state, font, left, SIZE_INF, &width, &height, 0, NULL, NULL, NULL);
+ _items.push_back(newItem);
+
return total_left_size + width;
}
-void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char *entries, int font, reg_t entries_base) {
- int i;
- menu_t *menu;
+void Menubar::addMenu(gfx_state_t *state, const char *title, const char *entries, int font, reg_t entries_base) {
char tracker;
char *left = NULL, *right;
reg_t left_origin = entries_base;
@@ -126,18 +107,11 @@ void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char
int tag = 0, c_width, max_width = 0;
int height;
- if (menubar->menus_nr == 0) {
- menubar->menus = (menu_t *)sci_malloc(sizeof(menu_t));
- menubar->menus_nr = 1;
- } else
- menubar->menus = (menu_t *)sci_realloc(menubar->menus, ++(menubar->menus_nr) * sizeof(menu_t));
+ Menu menu;
- menu = &(menubar->menus[menubar->menus_nr-1]);
- memset(menu, 0, sizeof(menu_t));
- menu->items_nr = 0;
- menu->title = sci_strdup(title);
+ menu._title = title;
- gfxop_get_text_params(state, font, menu->title, SIZE_INF, &(menu->title_width), &height, 0, NULL, NULL, NULL);
+ gfxop_get_text_params(state, font, title, SIZE_INF, &(menu._titleWidth), &height, 0, NULL, NULL, NULL);
do {
tracker = *entries++;
@@ -150,7 +124,7 @@ void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char
tracker = *entries++;
}
if ((tracker == 0 && string_len > 0) || (tracker == '=') || (tracker == ':')) { // End of entry
- int entrytype = MENU_TYPE_NORMAL;
+ MenuType entrytype = MENU_TYPE_NORMAL;
char *inleft;
reg_t beginning;
@@ -171,7 +145,7 @@ void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char
beginning = entries_base;
beginning.offset -= string_len + 1;
- c_width = _menubar_add_menu_item(state, menu, entrytype, left, NULL, font, 0, 0, tag, beginning);
+ c_width = menu.addMenuItem(state, entrytype, left, NULL, font, 0, 0, tag, beginning);
if (c_width > max_width)
max_width = c_width;
@@ -244,12 +218,12 @@ void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char
key = key - 'A' + 'a'; // Lowercase the key
}
- i = strlen(right);
+ int i = strlen(right);
while (i > 0 && right[--i] == ' ')
right[i] = 0; // Cut off chars to the right
- c_width = _menubar_add_menu_item(state, menu, MENU_TYPE_NORMAL, left, right, font, key,
+ c_width = menu.addMenuItem(state, MENU_TYPE_NORMAL, left, right, font, key,
modifiers, tag, left_origin);
tag = 0;
if (c_width > max_width)
@@ -263,78 +237,74 @@ void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char
} // right string finished
} while (tracker);
- menu->width = max_width;
+ menu._width = max_width;
+
+ _menus.push_back(menu);
}
-int menubar_match_key(menu_item_t *item, int message, int modifiers) {
- if ((item->key == message) && ((modifiers & (SCI_EVM_CTRL | SCI_EVM_ALT)) == item->modifiers))
- return 1;
+bool MenuItem::matchKey(int message, int modifiers) {
+ if ((_key == message) && ((modifiers & (SCI_EVM_CTRL | SCI_EVM_ALT)) == _modifiers))
+ return true;
- if (message == '\t' && item->key == 'i' && ((modifiers & (SCI_EVM_CTRL | SCI_EVM_ALT)) == 0) && item->modifiers == SCI_EVM_CTRL)
- return 1; // Match TAB to ^I
+ if (message == '\t' && _key == 'i' && ((modifiers & (SCI_EVM_CTRL | SCI_EVM_ALT)) == 0) && _modifiers == SCI_EVM_CTRL)
+ return true; // Match TAB to ^I
return 0;
}
-int menubar_set_attribute(EngineState *s, int menu_nr, int item_nr, int attribute, reg_t value) {
- menubar_t *menubar = s->menubar;
- menu_item_t *item;
+int Menubar::setAttribute(EngineState *s, int menu_nr, int item_nr, int attribute, reg_t value) {
+ MenuItem *item;
if ((menu_nr < 0) || (item_nr < 0))
return 1;
- if ((menu_nr >= menubar->menus_nr) || (item_nr >= menubar->menus[menu_nr].items_nr))
+ if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size()))
return 1;
- item = menubar->menus[menu_nr].items + item_nr;
+ item = &_menus[menu_nr]._items[item_nr];
switch (attribute) {
case MENU_ATTRIBUTE_SAID:
if (value.segment) {
- item->said_pos = value;
- memcpy(item->said, kernel_dereference_bulk_pointer(s, value, 0), MENU_SAID_SPEC_SIZE); // Copy Said spec
- item->flags |= MENU_ATTRIBUTE_FLAGS_SAID;
+ item->_saidPos = value;
+ memcpy(item->_said, kernel_dereference_bulk_pointer(s, value, 0), MENU_SAID_SPEC_SIZE); // Copy Said spec
+ item->_flags |= MENU_ATTRIBUTE_FLAGS_SAID;
} else
- item->flags &= ~MENU_ATTRIBUTE_FLAGS_SAID;
+ item->_flags &= ~MENU_ATTRIBUTE_FLAGS_SAID;
break;
case MENU_ATTRIBUTE_TEXT:
- free(item->text);
assert(value.segment);
- item->text = sci_strdup(kernel_dereference_char_pointer(s, value, 0));
- item->text_pos = value;
+ item->_text = kernel_dereference_char_pointer(s, value, 0);
+ item->_textPos = value;
break;
case MENU_ATTRIBUTE_KEY:
- free(item->keytext);
- item->keytext = 0;
+ item->_keytext.clear();
if (value.segment) {
// FIXME: What happens here if <value> is an extended key? Potential bug. LS
- item->key = value.offset;
- item->modifiers = 0;
- item->keytext = (char *)sci_malloc(2);
- item->keytext[0] = value.offset;
- item->keytext[1] = 0;
- item->flags |= MENU_ATTRIBUTE_FLAGS_KEY;
- if ((item->key >= 'A') && (item->key <= 'Z'))
- item->key = item->key - 'A' + 'a'; // Lowercase the key
+ item->_key = value.offset;
+ item->_modifiers = 0;
+ item->_keytext = value.offset;
+ item->_flags |= MENU_ATTRIBUTE_FLAGS_KEY;
+ if ((item->_key >= 'A') && (item->_key <= 'Z'))
+ item->_key = item->_key - 'A' + 'a'; // Lowercase the key
} else {
- item->keytext = NULL;
- item->flags &= ~MENU_ATTRIBUTE_FLAGS_KEY;
+ item->_flags &= ~MENU_ATTRIBUTE_FLAGS_KEY;
}
break;
case MENU_ATTRIBUTE_ENABLED:
- item->enabled = value.offset;
+ item->_enabled = value.offset;
break;
case MENU_ATTRIBUTE_TAG:
- item->tag = value.offset;
+ item->_tag = value.offset;
break;
default:
@@ -345,33 +315,30 @@ int menubar_set_attribute(EngineState *s, int menu_nr, int item_nr, int attribut
return 0;
}
-reg_t menubar_get_attribute(EngineState *s, int menu_nr, int item_nr, int attribute) {
- menubar_t *menubar = s->menubar;
- menu_item_t *item;
-
+reg_t Menubar::getAttribute(int menu_nr, int item_nr, int attribute) const {
if ((menu_nr < 0) || (item_nr < 0))
return make_reg(0, -1);
- if ((menu_nr >= menubar->menus_nr) || (item_nr >= menubar->menus[menu_nr].items_nr))
+ if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size()))
return make_reg(0, -1);
- item = menubar->menus[menu_nr].items + item_nr;
+ const MenuItem &item = _menus[menu_nr]._items[item_nr];
switch (attribute) {
case MENU_ATTRIBUTE_SAID:
- return item->said_pos;
+ return item._saidPos;
case MENU_ATTRIBUTE_TEXT:
- return item->text_pos;
+ return item._textPos;
case MENU_ATTRIBUTE_KEY:
- return make_reg(0, item->key);
+ return make_reg(0, item._key);
case MENU_ATTRIBUTE_ENABLED:
- return make_reg(0, item->enabled);
+ return make_reg(0, item._enabled);
case MENU_ATTRIBUTE_TAG:
- return make_reg(0, item->tag);
+ return make_reg(0, item._tag);
default:
sciprintf("Attempt to read invalid attribute from menu %d, item %d: 0x%04x\n", menu_nr, item_nr, attribute);
@@ -379,65 +346,59 @@ reg_t menubar_get_attribute(EngineState *s, int menu_nr, int item_nr, int attrib
}
}
-int menubar_item_valid(EngineState *s, int menu_nr, int item_nr) {
- menubar_t *menubar = s->menubar;
- menu_item_t *item;
-
+bool Menubar::itemValid(int menu_nr, int item_nr) const {
if ((menu_nr < 0) || (item_nr < 0))
- return 0;
+ return false;
- if ((menu_nr >= menubar->menus_nr) || (item_nr >= menubar->menus[menu_nr].items_nr))
- return 0;
+ if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size()))
+ return false;
- item = menubar->menus[menu_nr].items + item_nr;
+ const MenuItem &item = _menus[menu_nr]._items[item_nr];
- if ((item->type == MENU_TYPE_NORMAL) && item->enabled)
- return 1;
+ if ((item._type == MENU_TYPE_NORMAL) && item._enabled)
+ return true;
- return 0; // May not be selected
+ return false; // May not be selected
}
-int menubar_map_pointer(EngineState *s, int *menu_nr, int *item_nr, gfxw_port_t *port) {
- menubar_t *menubar = s->menubar;
- menu_t *menu;
+bool Menubar::mapPointer(gfx_state_t *state, int *menu_nr, int *item_nr, gfxw_port_t *port) const {
- if (s->gfx_state->pointer_pos.y <= 10) { // Re-evaulate menu
+ if (state->pointer_pos.y <= 10) { // Re-evaulate menu
int x = MENU_LEFT_BORDER;
- int i;
- for (i = 0; i < menubar->menus_nr; i++) {
- int newx = x + MENU_BORDER_SIZE * 2 + menubar->menus[i].title_width;
+ for (uint i = 0; i < _menus.size(); i++) {
+ int newx = x + MENU_BORDER_SIZE * 2 + _menus[i]._titleWidth;
- if (s->gfx_state->pointer_pos.x < x)
- return 0;
+ if (state->pointer_pos.x < x)
+ return false;
- if (s->gfx_state->pointer_pos.x < newx) {
+ if (state->pointer_pos.x < newx) {
*menu_nr = i;
*item_nr = -1;
}
x = newx;
}
- return 0;
} else {
- int row = (s->gfx_state->pointer_pos.y / 10) - 1;
+ int row = (state->pointer_pos.y / 10) - 1;
- if ((*menu_nr < 0) || (*menu_nr >= menubar->menus_nr))
- return 1; // No menu
- else
- menu = menubar->menus + *menu_nr; // Menu is valid, assume that it's popped up
+ if ((*menu_nr < 0) || (*menu_nr >= (int)_menus.size()))
+ return true; // No menu
- if (menu->items_nr <= row)
- return 1;
+ const Menu &menu = _menus[*menu_nr]; // Menu is valid, assume that it's popped up
- if ((s->gfx_state->pointer_pos.x < port->bounds.x) || (s->gfx_state->pointer_pos.x > port->bounds.x + port->bounds.width))
- return 1;
+ if ((int)menu._items.size() <= row)
+ return true;
- if (menubar_item_valid(s, *menu_nr, row))
+ if ((state->pointer_pos.x < port->bounds.x) || (state->pointer_pos.x > port->bounds.x + port->bounds.width))
+ return true;
+
+ if (itemValid(*menu_nr, row))
*item_nr = row; // Only modify if we'll be hitting a valid element
- return 0;
}
+
+ return false;
}
} // End of namespace Sci
diff --git a/engines/sci/gfx/menubar.h b/engines/sci/gfx/menubar.h
index d35e9f5fd0..269777e97e 100644
--- a/engines/sci/gfx/menubar.h
+++ b/engines/sci/gfx/menubar.h
@@ -32,6 +32,8 @@
#include "sci/gfx/operations.h"
#include "sci/gfx/gfx_widgets.h"
+#include "common/array.h"
+
namespace Sci {
struct EngineState;
@@ -60,9 +62,6 @@ struct EngineState;
#define MENU_BAR_HEIGHT 10
-#define MENU_TYPE_NORMAL 0
-#define MENU_TYPE_HBAR 1 /* Horizontal bar */
-
/* Special characters used while building the menu bar */
#define SCI_SPECIAL_CHAR_FUNCTION 'F'
#define SCI_SPECIAL_CHAR_CTRL 3
@@ -77,130 +76,142 @@ struct EngineState;
#define MENU_ATTRIBUTE_ENABLED 0x70
#define MENU_ATTRIBUTE_TAG 0x71
-/* Those flags determine whether the corresponding menu_item_t entries are valid */
+/* Those flags determine whether the corresponding MenuItem entries are valid */
#define MENU_ATTRIBUTE_FLAGS_KEY 0x01
#define MENU_ATTRIBUTE_FLAGS_SAID 0x02
-struct menu_item_t {
- int type; /* Normal or hbar */
- char *keytext; /* right-centered part of the text (the key) */
- int keytext_size; // FIXME: Essentially unused
-
- int flags;
- byte said[MENU_SAID_SPEC_SIZE]; /* Said spec for this item */
- reg_t said_pos;
- char *text;
- reg_t text_pos;
- int modifiers, key; /* Hotkey for this item */
- int enabled;
- int tag;
+enum MenuType {
+ MENU_TYPE_NORMAL = 0,
+ MENU_TYPE_HBAR = 1 /* Horizontal bar */
};
-
-struct menu_t {
- char *title;
-
- int title_width; /* Width of the title in pixels */
- int width; /* Pixel width of the menu window */
-
- int items_nr; /* Window height equals to intems_nr * 10 */
- menu_item_t *items; /* Actual entries into the menu */
-
+class MenuItem : public Common::Serializable {
+public:
+ MenuType _type; /* Normal or hbar */
+ Common::String _keytext; /* right-centered part of the text (the key) */
+
+ int _flags;
+ byte _said[MENU_SAID_SPEC_SIZE]; /* Said spec for this item */
+ reg_t _saidPos;
+ Common::String _text;
+ reg_t _textPos;
+ int _modifiers; /* Hotkey for this item */
+ int _key; /* Hotkey for this item */
+ int _enabled;
+ int _tag;
+
+public:
+ MenuItem();
+
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
+
+ /**
+ * Determines whether a message/modifiers key pair matches a menu item's key parameters.
+ * @param message The message to match
+ * @param modifiers The modifier flags to match
+ * @return true on match, false otherwise
+ */
+ bool matchKey(int message, int modifiers);
};
+class Menu : public Common::Serializable {
+public:
+ Common::String _title;
-struct menubar_t {
+ /** Width of the title in pixels */
+ int _titleWidth;
- int menus_nr;
- menu_t *menus; /* The actual menus */
+ /** Pixel width of the menu window */
+ int _width;
-};
-
-struct gfx_port;
-struct gfx_picture; /* forward declarations for graphics.h */
+ /**
+ * Actual entries into the menu.
+ * Window height equals to number of items times 10.
+ */
+ Common::Array<MenuItem> _items;
+public:
+ Menu();
-/********** function definitions *********/
-
-menubar_t *menubar_new();
-/* Creates a new menubar struct
-** Parameters: (void)
-** Returns : (menubar_t *) A pointer to the new menubar entity
-** To free the entity, call menubar_free.
-*/
-
-
-void menubar_free(menubar_t *menubar);
-/* Frees all memory associated with a menubar
-** Parameters: (menubar_t *) menubar: The menubar to free
-** Returns : (void)
-*/
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
-
-void menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char *entries, int font, reg_t entries_base);
-/* Adds a menu to the menubar.
-** Parameters: (gfx_state_t *) state: The state the fonts are stored in
-** (menubar_t *) menubar: The menubar to operate on
-** (char *) title: The menu title
-** (char *) entries: A string of menu entries
-** (int) font: The font which is to be used for drawing
-** (reg_t) entries_base: Segmented VM address of the entries string
-** Returns : (void)
-** The menu entries use the following special characters:
-** '`' : Right justify the following part
-** ':' : End of this entry
-** '#' : Function key (replaced by 'F')
-** '^' : Control key (replaced by \002, which looks like "CTRL")
-** '=' : Initial tag value
-** and the special string "--!", which represents a horizontal bar in the menu.
-*/
-
-
-int menubar_set_attribute(EngineState *s, int menu, int item, int attribute, reg_t value);
-/* Sets the (currently unidentified) foo and bar values.
-** Parameters: (state_t *) s: The current state
-** (int) menu: The menu number to edit
-** (int) item: The menu item to change
-** (int) attribute: The attribute to modify
-** (int) value: The value the attribute should be set to
-** Returns : (int) 0 on success, 1 if either menu or item were invalid
-*/
-
-
-reg_t menubar_get_attribute(EngineState *s, int menu, int item, int attribute);
-/* Sets the (currently unidentified) foo and bar values.
-** Parameters: (state_t *) s: The current state
-** (int) menu: The menu number
-** (int) item: The menu item to read
-** (int) attribute: The attribute to read from
-** Returns : (int) The attribute value, or -1 on error
-*/
+//protected:
+ // FIXME: This should be (partially) turned into a MenuItem constructor
+ int addMenuItem(gfx_state_t *state, MenuType type, const char *left, const char *right,
+ int font, int key, int modifiers, int tag, reg_t text_pos);
+};
-int menubar_item_valid(EngineState *s, int menu, int item);
-/* Determines whether the specified menu entry may be activated
-** Parameters: (state_t *) s: The current state
-** (int x int) (menu, item): The menu item to check
-** Returns : (int) 1 if the menu item may be selected, 0 otherwise
-*/
-int menubar_map_pointer(EngineState *s, int *menu_nr, int *item_nr, gfxw_port_t *port);
-/* Maps the pointer position to a (menu,item) tuple.
-** Parameters: (state_t *) s: The current state
-** ((int *) x (int *)) (menu_nr, item_nr): Pointers to the current menu/item tuple
-** (port_t *) port: The port of the currently active menu (if any)
-** Returns : (int) 1 if the pointer is outside a valid port, 0 otherwise.
-*/
+class Menubar : public Common::Serializable {
+public:
+ /** The actual menus. */
+ Common::Array<Menu> _menus;
+
+public:
+ virtual void saveLoadWithSerializer(Common::Serializer &ser);
+
+ /**
+ * Adds a menu to the menubar.
+ * Parameters: (gfx_state_t *) state: The state the fonts are stored in
+ * (char *) title: The menu title
+ * (char *) entries: A string of menu entries
+ * (int) font: The font which is to be used for drawing
+ * (reg_t) entries_base: Segmented VM address of the entries string
+ * Returns : (void)
+ * The menu entries use the following special characters:
+ * '`' : Right justify the following part
+ * ':' : End of this entry
+ * '#' : Function key (replaced by 'F')
+ * '^' : Control key (replaced by \002, which looks like "CTRL")
+ * '=' : Initial tag value
+ * and the special string "--!", which represents a horizontal bar in the menu.
+ */
+ void addMenu(gfx_state_t *state, const char *title, const char *entries, int font, reg_t entries_base);
+
+
+ /**
+ * Sets the (currently unidentified) foo and bar values.
+ * Parameters: (state_t *) s: The current state
+ * (int) menu: The menu number to edit
+ * (int) item: The menu item to change
+ * (int) attribute: The attribute to modify
+ * (int) value: The value the attribute should be set to
+ * Returns : (int) 0 on success, 1 if either menu or item were invalid
+ */
+ int setAttribute(EngineState *s, int menu, int item, int attribute, reg_t value);
+
+
+ /**
+ * Sets the (currently unidentified) foo and bar values.
+ * Parameters: (int) menu: The menu number
+ * (int) item: The menu item to read
+ * (int) attribute: The attribute to read from
+ * Returns : (int) The attribute value, or -1 on error
+ */
+ reg_t getAttribute(int menu, int item, int attribute) const;
+
+
+ /**
+ * Determines whether the specified menu entry may be activated.
+ * @return true if the menu item may be selected, false otherwise
+ */
+ bool itemValid(int menu, int item) const;
+
+
+ /**
+ * Maps the pointer position to a (menu,item) tuple.
+ * Parameters: (gfx_state_t *) state: The current state
+ * ((int *) x (int *)) (menu_nr, item_nr): Pointers to the current menu/item tuple
+ * (port_t *) port: The port of the currently active menu (if any)
+ * @return true if the pointer is outside a valid port, false otherwise.
+ */
+ bool mapPointer(gfx_state_t *state, int *menu_nr, int *item_nr, gfxw_port_t *port) const;
-int menubar_match_key(menu_item_t *item, int message, int modifiers);
-/* Determines whether a message/modifiers key pair matches a menu item's key parameters
-** Parameters: (menu_item_t *) item: The menu item to match
-** (int x int) message, modifiers: The input to compare
-** Returns : (int) 1 on match, 0 otherwise
-*/
+};
} // End of namespace Sci
diff --git a/engines/sci/gfx/sci_widgets.cpp b/engines/sci/gfx/sci_widgets.cpp
index 2db9e16e3f..d939fdd754 100644
--- a/engines/sci/gfx/sci_widgets.cpp
+++ b/engines/sci/gfx/sci_widgets.cpp
@@ -72,7 +72,7 @@ static gfxw_list_t *finish_titlebar_list(EngineState *s, gfxw_list_t *list, gfxw
return list;
}
-void sciw_set_status_bar(EngineState *s, gfxw_port_t *status_bar, char *text, int fgcolor, int bgcolor) {
+void sciw_set_status_bar(EngineState *s, gfxw_port_t *status_bar, const char *text, int fgcolor, int bgcolor) {
gfx_state_t *state;
gfxw_list_t *list;
gfx_color_t bg = status_bar->bgcolor;
@@ -129,8 +129,11 @@ static void sciw_make_window_fit(rect_t *rect, gfxw_port_t *parent) {
rect->y -= (rect->y + rect->height) - (parent->bounds.y + parent->bounds.height) + 2;
}
-gfxw_port_t *sciw_new_window(EngineState *s, rect_t area, int font, gfx_color_t color, gfx_color_t bgcolor,
- int title_font, gfx_color_t title_color, gfx_color_t title_bgcolor, const char *title, int flags) {
+gfxw_port_t *sciw_new_window(EngineState *s,
+ rect_t area, int font,
+ gfx_color_t color, gfx_color_t bgcolor,
+ int title_font, gfx_color_t title_color, gfx_color_t title_bgcolor,
+ const char *title, int flags) {
gfxw_visual_t *visual = s->visual;
gfx_state_t *state = s->gfx_state;
int shadow_offset = 2;
@@ -525,26 +528,26 @@ gfxw_list_t *sciw_new_list_control(gfxw_port_t *port, reg_t ID, rect_t zone, int
return list;
}
-void sciw_set_menubar(EngineState *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection) {
+void sciw_set_menubar(EngineState *s, gfxw_port_t *status_bar, Menubar *menubar, int selection) {
gfxw_list_t *list = make_titlebar_list(s, status_bar->bounds, status_bar);
int offset = MENU_LEFT_BORDER;
int i;
clear_titlebar(status_bar);
- for (i = 0; i < menubar->menus_nr; i++) {
- menu_t *menu = menubar->menus + i;
- int width = menu->title_width + (MENU_BORDER_SIZE * 2);
+ for (i = 0; i < (int)menubar->_menus.size(); i++) {
+ Menu *menu = &menubar->_menus[i];
+ int width = menu->_titleWidth + (MENU_BORDER_SIZE * 2);
if (i == selection) {
list->add(GFXWC(list), GFXW(gfxw_new_box(status_bar->visual->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT),
status_bar->color, status_bar->color, GFX_BOX_SHADE_FLAT)));
list->add(GFXWC(list), GFXW(gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT),
- status_bar->font_nr, menu->title, ALIGN_CENTER, ALIGN_CENTER,
+ status_bar->font_nr, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER,
status_bar->bgcolor, status_bar->bgcolor, status_bar->color, GFXR_FONT_FLAG_NO_NEWLINES)));
} else
list->add(GFXWC(list), GFXW(gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT),
- status_bar->font_nr, menu->title, ALIGN_CENTER, ALIGN_CENTER,
+ status_bar->font_nr, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER,
status_bar->color, status_bar->color, status_bar->bgcolor, GFXR_FONT_FLAG_NO_NEWLINES)));
offset += width;
}
@@ -553,32 +556,32 @@ void sciw_set_menubar(EngineState *s, gfxw_port_t *status_bar, menubar_t *menuba
finish_titlebar_list(s, list, status_bar);
}
-gfxw_port_t *sciw_new_menu(EngineState *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection) {
+gfxw_port_t *sciw_new_menu(EngineState *s, gfxw_port_t *status_bar, Menubar *menubar, int selection) {
gfxw_port_t *retval;
- menu_t *menu = menubar->menus + selection;
+ Menu *menu = &menubar->_menus[selection];
rect_t area = gfx_rect(MENU_LEFT_BORDER, 10, 0, 0);
int i;
if (selection < -1)
return NULL;
- if (selection >= menubar->menus_nr) {
- GFXERROR("Attempt to make menu #%d of %d\n", selection, menubar->menus_nr);
+ if (selection >= (int)menubar->_menus.size()) {
+ GFXERROR("Attempt to make menu #%d of %d\n", selection, menubar->_menus.size());
return NULL;
}
for (i = 0; i < selection; i++)
- area.x += menubar->menus[i].title_width;
+ area.x += menubar->_menus[i]._titleWidth;
- area.width = menu->width - 1;
- area.height = menu->items_nr * 10;
+ area.width = menu->_width - 1;
+ area.height = menu->_items.size() * 10;
retval = sciw_new_window(s, area, status_bar->font_nr, status_bar->color, status_bar->bgcolor,
0, status_bar->color, status_bar->bgcolor, NULL, WINDOW_FLAG_NO_DROP_SHADOW | WINDOW_FLAG_TRANSPARENT);
retval->set_visual(GFXW(retval), s->visual);
- for (i = 0; i < menu->items_nr; i++)
+ for (i = 0; i < (int)menu->_items.size(); i++)
sciw_unselect_item(s, retval, menu, i);
return retval;
@@ -593,7 +596,7 @@ static gfx_color_t un_prioritize(gfx_color_t col) {
return col;
}
-gfxw_widget_t *_make_menu_entry(menu_item_t *item, int offset, int width, gfxw_port_t *port, gfx_color_t color, gfx_color_t bgcolor, int ID, int gray) {
+gfxw_widget_t *_make_menu_entry(MenuItem *item, int offset, int width, gfxw_port_t *port, gfx_color_t color, gfx_color_t bgcolor, int ID, int gray) {
rect_t area = gfx_rect(MENU_BOX_LEFT_PADDING, 0, width - MENU_BOX_LEFT_PADDING, 10);
rect_t list_area = gfx_rect(port->zone.x, area.y + offset + port->zone.y, width, area.height);
gfxw_list_t *list = (gfxw_list_t *) gfxw_set_id(GFXW(gfxw_new_list(list_area, 0)), ID, GFXW_NO_ID);
@@ -605,12 +608,12 @@ gfxw_widget_t *_make_menu_entry(menu_item_t *item, int offset, int width, gfxw_p
xcolor = gray ? color : bgcolor;
list->add(GFXWC(list), GFXW(gfxw_new_box(port->visual->gfx_state, area, bgcolor, bgcolor, GFX_BOX_SHADE_FLAT)));
- list->add(GFXWC(list), GFXW(gfxw_new_text(port->visual->gfx_state, area, port->font_nr, item->text, ALIGN_LEFT, ALIGN_CENTER,
+ list->add(GFXWC(list), GFXW(gfxw_new_text(port->visual->gfx_state, area, port->font_nr, item->_text.c_str(), ALIGN_LEFT, ALIGN_CENTER,
color, xcolor, bgcolor, GFXR_FONT_FLAG_NO_NEWLINES)));
- if (item->keytext) {
+ if (!item->_keytext.empty()) {
area.width -= MENU_BOX_RIGHT_PADDING;
- list->add(GFXWC(list), GFXW(gfxw_new_text(port->visual->gfx_state, area, port->font_nr, item->keytext, ALIGN_RIGHT, ALIGN_CENTER,
+ list->add(GFXWC(list), GFXW(gfxw_new_text(port->visual->gfx_state, area, port->font_nr, item->_keytext.c_str(), ALIGN_RIGHT, ALIGN_CENTER,
color, xcolor, bgcolor, GFXR_FONT_FLAG_NO_NEWLINES)));
}
@@ -632,16 +635,16 @@ gfxw_widget_t *_make_menu_hbar(int offset, int width, gfxw_port_t *port, gfx_col
return GFXW(list);
}
-gfxw_port_t *sciw_unselect_item(EngineState *s, gfxw_port_t *menu_port, menu_t *menu, int selection) {
- menu_item_t *item = menu->items + selection;
-
- if (selection < 0 || selection >= menu->items_nr)
+gfxw_port_t *sciw_unselect_item(EngineState *s, gfxw_port_t *menu_port, Menu *menu, int selection) {
+ if (selection < 0 || selection >= (int)menu->_items.size())
return menu_port;
- if (item->type == MENU_TYPE_NORMAL)
+ MenuItem *item = &menu->_items[selection];
+
+ if (item->_type == MENU_TYPE_NORMAL)
menu_port->add(GFXWC(menu_port), GFXW(_make_menu_entry(item, selection * 10, menu_port->zone.width + 1,
menu_port, menu_port->color, menu_port->bgcolor, selection + MAGIC_ID_OFFSET,
- item->enabled)));
+ item->_enabled)));
else
menu_port->add(GFXWC(menu_port), GFXW(_make_menu_hbar(selection * 10, menu_port->zone.width + 1,
menu_port, menu_port->color, menu_port->bgcolor, selection + MAGIC_ID_OFFSET)));
@@ -649,16 +652,16 @@ gfxw_port_t *sciw_unselect_item(EngineState *s, gfxw_port_t *menu_port, menu_t *
return menu_port;
}
-gfxw_port_t *sciw_select_item(EngineState *s, gfxw_port_t *menu_port, menu_t *menu, int selection) {
- menu_item_t *item = menu->items + selection;
-
- if (selection < 0 || selection >= menu->items_nr)
+gfxw_port_t *sciw_select_item(EngineState *s, gfxw_port_t *menu_port, Menu *menu, int selection) {
+ if (selection < 0 || selection >= (int)menu->_items.size())
return menu_port;
- if (item->type == MENU_TYPE_NORMAL)
+ MenuItem *item = &menu->_items[selection];
+
+ if (item->_type == MENU_TYPE_NORMAL)
menu_port->add(GFXWC(menu_port), GFXW(_make_menu_entry(item, selection * 10, menu_port->zone.width + 1,
menu_port, menu_port->bgcolor, menu_port->color, selection + MAGIC_ID_OFFSET,
- item->enabled)));
+ item->_enabled)));
else
menu_port->add(GFXWC(menu_port), GFXW(_make_menu_hbar(selection * 10, menu_port->zone.width + 1,
menu_port, menu_port->bgcolor, menu_port->color, selection + MAGIC_ID_OFFSET)));
diff --git a/engines/sci/gfx/sci_widgets.h b/engines/sci/gfx/sci_widgets.h
index 438f1f8ffb..62749d9ce4 100644
--- a/engines/sci/gfx/sci_widgets.h
+++ b/engines/sci/gfx/sci_widgets.h
@@ -32,7 +32,7 @@
namespace Sci {
-struct menu_t;
+class Menu;
/* The following flags are applicable to windows in SCI0: */
#define WINDOW_FLAG_TRANSPARENT 0x01
@@ -62,11 +62,11 @@ struct menu_t;
/* Used by the interpreter to flag buttons that are enabled */
#define CONTROL_STATE_ENABLED 0x0001
-void sciw_set_status_bar(EngineState *s, gfxw_port_t *status_bar, char *text, int fgcolor, int bgcolor);
+void sciw_set_status_bar(EngineState *s, gfxw_port_t *status_bar, const char *text, int fgcolor, int bgcolor);
/* Sets the contents of a port used as status bar
** Parmeters: (EngineState *) s: The affected game state
** (gfxw_port_t *) status_bar: The status bar port
-** (char *) text: The text to draw
+** (const char *) text: The text to draw
** Returns : (void)
*/
@@ -163,39 +163,39 @@ gfxw_list_t *sciw_new_list_control(gfxw_port_t *port, reg_t ID, rect_t zone, int
/*** Menubar widgets ***/
/*---------------------*/
-void sciw_set_menubar(EngineState *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection);
+void sciw_set_menubar(EngineState *s, gfxw_port_t *status_bar, Menubar *menubar, int selection);
/* Draws the menu bar
** Parameters: (EngineState *) s: The state to operate on
** (gfxw_port_t *) status_bar: The status bar port to modify
-** (menubar_t *) menubar: The menu bar to use
+** (Menubar *) menubar: The menu bar to use
** (int) selection: Number of the menu to hightlight, or -1 for 'none'
** Returns : (void)
*/
-gfxw_port_t *sciw_new_menu(EngineState *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection);
+gfxw_port_t *sciw_new_menu(EngineState *s, gfxw_port_t *status_bar, Menubar *menubar, int selection);
/* Creates a menu port
** Parameters: (EngineState *) s: The state to operate on
** (gfxw_port_t *) status_bar: The status bar
-** (menubar_t *) menubar: The menu bar to use
+** (Menubar *) menubar: The menu bar to use
** (int) selection: Number of the menu to interpret
** Returns : (gfxw_port_t *) The result port
*/
-gfxw_port_t *sciw_unselect_item(EngineState *s, gfxw_port_t *menu_port, menu_t *menu, int selection);
+gfxw_port_t *sciw_unselect_item(EngineState *s, gfxw_port_t *menu_port, Menu *menu, int selection);
/* Unselects a previously selected item from a menu port
** Parameters: (EngineState *) s: The state to operate on
** (gfxw_port_t *) menu_port: The port modify
-** (menu_t *) menu: The menu the menu port corresponds to
+** (Menu *) menu: The menu the menu port corresponds to
** (int) selection: Number of the menu entry to unselect, or -1 to do a NOP
** Returns : (gfxw_port_t *) The modified menu
*/
gfxw_port_t *
-sciw_select_item(EngineState *s, gfxw_port_t *menu_port, menu_t *menu, int selection);
+sciw_select_item(EngineState *s, gfxw_port_t *menu_port, Menu *menu, int selection);
/* Selects a menu item from a menu port
** Parameters: (EngineState *) s: The state to operate on
** (gfxw_port_t *) menu_port: The port modify
-** (menu_t *) menu: The menu the menu port corresponds to
+** (Menu *) menu: The menu the menu port corresponds to
** (int) selection: Number of the menu entry to select, or -1 to do a NOP
** Returns : (gfxw_port_t *) The modified menu
*/