aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/game.cpp4
-rw-r--r--engines/sci/engine/kmenu.cpp76
-rw-r--r--engines/sci/engine/savegame.cpp87
-rw-r--r--engines/sci/engine/state.cpp2
-rw-r--r--engines/sci/engine/state.h4
5 files changed, 100 insertions, 73 deletions
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index d7c5249ca8..11f90c962b 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -649,7 +649,7 @@ int game_init(EngineState *s) {
s->parser_nodes[0].type = PARSE_TREE_NODE_LEAF;
s->parser_nodes[0].content.value = 0;
- s->menubar = menubar_new(); // Create menu bar
+ s->_menubar = new Menubar(); // Create menu bar
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
game_init_sound(s, 0);
@@ -680,7 +680,7 @@ int game_exit(EngineState *s) {
// TODO Free scripts here
- menubar_free(s->menubar);
+ delete s->_menubar;
_free_graphics_input(s);
diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp
index e878d6f6d6..601011eff3 100644
--- a/engines/sci/engine/kmenu.cpp
+++ b/engines/sci/engine/kmenu.cpp
@@ -36,7 +36,7 @@ reg_t kAddMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) {
char *name = kernel_dereference_char_pointer(s, argv[0], 0);
char *contents = kernel_dereference_char_pointer(s, argv[1], 0);
- menubar_add_menu(s->gfx_state, s->menubar, name,
+ s->_menubar->addMenu(s->gfx_state, name,
contents, s->titlebar_port->font_nr, argv[1]);
return s->r_acc;
@@ -49,7 +49,7 @@ reg_t kSetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int i = 2;
while (i < argc) {
- menubar_set_attribute(s, (index >> 8) - 1, (index & 0xff) - 1, UKPV(i - 1), argv[i]);
+ s->_menubar->setAttribute(s, (index >> 8) - 1, (index & 0xff) - 1, UKPV(i - 1), argv[i]);
i += 2;
}
@@ -59,7 +59,7 @@ reg_t kSetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t kGetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int index = UKPV(0);
- return menubar_get_attribute(s, (index >> 8) - 1, (index & 0xff) - 1, UKPV(1));
+ return s->_menubar->getAttribute((index >> 8) - 1, (index & 0xff) - 1, UKPV(1));
}
@@ -95,7 +95,7 @@ reg_t kDrawStatus(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t kDrawMenuBar(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if (SKPV(0))
- sciw_set_menubar(s, s->titlebar_port, s->menubar, -1);
+ sciw_set_menubar(s, s->titlebar_port, s->_menubar, -1);
else
sciw_set_status_bar(s, s->titlebar_port, NULL, 0, 0);
@@ -106,11 +106,12 @@ reg_t kDrawMenuBar(EngineState *s, int funct_nr, int argc, reg_t *argv) {
}
-static int _menu_go_down(EngineState *s, int menu_nr, int item_nr) {
- int seeker, max = s->menubar->menus[menu_nr].items_nr;
+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_item_valid(s, menu_nr, seeker))
+ while ((seeker < max) && !menubar->itemValid(menu_nr, seeker))
++seeker;
if (seeker != max)
@@ -127,12 +128,12 @@ static int _menu_go_down(EngineState *s, int menu_nr, int item_nr) {
reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t event = argv[0];
/*int pause_sound = UKPV_OR_ALT(1, 1);*/ /* FIXME: Do this eventually */
- int claimed = 0;
+ bool claimed = false;
int type = GET_SEL32V(event, type);
int message = GET_SEL32V(event, message);
int modifiers = GET_SEL32V(event, modifiers);
int menu_nr = -1, item_nr = 0;
- menu_item_t *item;
+ MenuItem *item;
int menu_mode = 0; /* Menu is active */
int mouse_down = 0;
@@ -150,27 +151,27 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
SCIkdebug(SCIkMENU, "Menu: Got %s event: %04x/%04x\n",
((type == SCI_EVT_SAID) ? "SAID" : "KBD"), message, modifiers);
- for (menuc = 0; menuc < s->menubar->menus_nr; menuc++)
- for (itemc = 0; itemc < s->menubar->menus[menuc].items_nr; itemc++) {
- item = s->menubar->menus[menuc].items + itemc;
+ 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];
SCIkdebug(SCIkMENU, "Menu: Checking against %s: %04x/%04x (type %d, %s)\n",
- item->text ? item->text : "--bar--", item->key, item->modifiers,
- item->type, item->enabled ? "enabled" : "disabled");
+ !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))
+ if (((item->_type == MENU_TYPE_NORMAL)
+ && (item->_enabled))
&& (((type == SCI_EVT_KEYBOARD) /* keyboard event */
- && menubar_match_key(item, message, modifiers))
+ && item->matchKey(message, modifiers))
|| ((type == SCI_EVT_SAID) /* Said event */
- && (item->flags & MENU_ATTRIBUTE_FLAGS_SAID)
- && (said(s, item->said, (s->debug_mode & (1 << SCIkPARSER_NR))) != SAID_NO_MATCH)
+ && (item->_flags & MENU_ATTRIBUTE_FLAGS_SAID)
+ && (said(s, item->_said, (s->debug_mode & (1 << SCIkPARSER_NR))) != SAID_NO_MATCH)
)
)
) {
/* Claim the event */
SCIkdebug(SCIkMENU, "Menu: Event CLAIMED for %d/%d\n", menuc, itemc);
- claimed = 1;
+ claimed = true;
menu_nr = menuc;
item_nr = itemc;
}
@@ -192,11 +193,11 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
/* Default to menu 0, unless the mouse was used to generate this effect */
if (mouse_down)
- menubar_map_pointer(s, &menu_nr, &item_nr, port);
+ s->_menubar->mapPointer(s->gfx_state, &menu_nr, &item_nr, port);
else
menu_nr = 0;
- sciw_set_menubar(s, s->titlebar_port, s->menubar, menu_nr);
+ sciw_set_menubar(s, s->titlebar_port, s->_menubar, menu_nr);
FULL_REDRAW;
old_item = -1;
@@ -205,7 +206,7 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
while (menu_mode) {
sci_event_t ev = gfxop_get_event(s->gfx_state, SCI_EVT_ANY);
- claimed = 0;
+ claimed = false;
switch (ev.type) {
case SCI_EVT_QUIT:
@@ -227,37 +228,37 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case SCI_K_ENTER:
menu_mode = 0;
if ((item_nr >= 0) && (menu_nr >= 0))
- claimed = 1;
+ claimed = true;
break;
case SCI_K_LEFT:
if (menu_nr > 0)
--menu_nr;
else
- menu_nr = s->menubar->menus_nr - 1;
+ menu_nr = s->_menubar->_menus.size() - 1;
- item_nr = _menu_go_down(s, menu_nr, -1);
+ item_nr = _menu_go_down(s->_menubar, menu_nr, -1);
break;
case SCI_K_RIGHT:
- if (menu_nr < (s->menubar->menus_nr - 1))
+ if (menu_nr < ((int)s->_menubar->_menus.size() - 1))
++menu_nr;
else
menu_nr = 0;
- item_nr = _menu_go_down(s, menu_nr, -1);
+ 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) && !menubar_item_valid(s, menu_nr, item_nr));
+ while ((item_nr > -1) && !s->_menubar->itemValid(menu_nr, item_nr));
}
break;
case SCI_K_DOWN: {
- item_nr = _menu_go_down(s, menu_nr, item_nr);
+ item_nr = _menu_go_down(s->_menubar, menu_nr, item_nr);
}
break;
@@ -266,7 +267,7 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case SCI_EVT_MOUSE_RELEASE:
menu_mode = (s->gfx_state->pointer_pos.y < 10);
- claimed = !menu_mode && !menubar_map_pointer(s, &menu_nr, &item_nr, port);
+ claimed = !menu_mode && !s->_menubar->mapPointer(s->gfx_state, &menu_nr, &item_nr, port);
mouse_down = 0;
break;
@@ -280,16 +281,16 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
}
if (mouse_down)
- menubar_map_pointer(s, &menu_nr, &item_nr, port);
+ s->_menubar->mapPointer(s->gfx_state, &menu_nr, &item_nr, port);
if ((item_nr > -1 && old_item == -1) || (menu_nr != old_menu)) { /* Update menu */
- sciw_set_menubar(s, s->titlebar_port, s->menubar, menu_nr);
+ sciw_set_menubar(s, s->titlebar_port, s->_menubar, menu_nr);
if (port)
port->widfree(GFXW(port));
- port = sciw_new_menu(s, s->titlebar_port, s->menubar, menu_nr);
+ port = sciw_new_menu(s, s->titlebar_port, s->_menubar, menu_nr);
s->wm_port->add(GFXWC(s->wm_port), GFXW(port));
if (item_nr > -1)
@@ -302,8 +303,8 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
/* Remove the active menu item, if neccessary */
if (item_nr != old_item) {
- port = sciw_unselect_item(s, port, s->menubar->menus + menu_nr, old_item);
- port = sciw_select_item(s, port, s->menubar->menus + menu_nr, item_nr);
+ port = sciw_unselect_item(s, port, &(s->_menubar->_menus[menu_nr]), old_item);
+ port = sciw_select_item(s, port, &(s->_menubar->_menus[menu_nr]), item_nr);
FULL_REDRAW;
}
@@ -331,7 +332,8 @@ reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) {
s->r_acc = NULL_REG;
SCIkdebug(SCIkMENU, "Menu: Claim -> %04x\n", s->r_acc.offset);
- } else s->r_acc = NULL_REG; /* Not claimed */
+ } else
+ s->r_acc = NULL_REG; /* Not claimed */
return s->r_acc;
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 43125e7450..901e160b67 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -95,42 +95,67 @@ static void sync_IntMapper(Common::Serializer &s, IntMapper &obj) {
obj.saveLoadWithSerializer(s);
}
-static void sync_menu_item_t(Common::Serializer &s, menu_item_t &obj) {
- s.syncAsSint32LE(obj.type);
- syncCStr(s, &obj.keytext);
- s.syncAsSint32LE(obj.keytext_size);
- s.syncAsSint32LE(obj.flags);
- s.syncBytes(obj.said, MENU_SAID_SPEC_SIZE);
- sync_reg_t(s, obj.said_pos);
- syncCStr(s, &obj.text);
- sync_reg_t(s, obj.text_pos);
- s.syncAsSint32LE(obj.modifiers);
- s.syncAsSint32LE(obj.key);
- s.syncAsSint32LE(obj.enabled);
- s.syncAsSint32LE(obj.tag);
+/**
+ * Sync a Common::Array using a Common::Serializer.
+ * When saving, this writes the length of the array, then syncs (writes) all entries.
+ * When loading, it loads the length of the array, then resizes it accordingly, before
+ * syncing all entries.
+ *
+ * TODO: Right now, this can only sync arrays containing objects which subclass Serializable.
+ * To sync arrays containing e.g. ints, we have to tell it how to sync those. There are
+ * ways to do that, I just haven't decided yet how to approach it. One way would be to use
+ * the same preprocessors tricks as in common/serializer.h. Another is to rely on template
+ * specialization (that one could be rather elegant, in fact).
+ *
+ *
+ * Note: I didn't add this as a member method to Common::Array (and subclass that from Serializable)
+ * on purpose, as not all code using Common::Array wants to do deal with serializers...
+ *
+ * TODO: Add something like this for lists, queues....
+ */
+template<typename T>
+void syncArray(Common::Serializer &s, Common::Array<T> &arr) {
+ uint len = arr.size();
+ s.syncAsUint32LE(len);
+
+ // Resize the array if loading.
+ if (s.isLoading())
+ arr.resize(len);
+
+ typename Common::Array<T>::iterator i;
+ for (i = arr.begin(); i != arr.end(); ++i) {
+ i->saveLoadWithSerializer(s);
+ }
}
-static void sync_menu_t(Common::Serializer &s, menu_t &obj) {
- syncCStr(s, &obj.title);
- s.syncAsSint32LE(obj.title_width);
- s.syncAsSint32LE(obj.width);
+void MenuItem::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsSint32LE(_type);
+ s.syncString(_keytext);
+ s.skip(4); // Used to be keytext_size (an already unused field)
+
+ s.syncAsSint32LE(_flags);
+ s.syncBytes(_said, MENU_SAID_SPEC_SIZE);
+ sync_reg_t(s, _saidPos);
+ s.syncString(_text);
+ sync_reg_t(s, _textPos);
+ s.syncAsSint32LE(_modifiers);
+ s.syncAsSint32LE(_key);
+ s.syncAsSint32LE(_enabled);
+ s.syncAsSint32LE(_tag);
+}
- s.syncAsSint32LE(obj.items_nr);
+void Menu::saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncString(_title);
+ s.syncAsSint32LE(_titleWidth);
+ s.syncAsSint32LE(_width);
- if (!obj.items && obj.items_nr)
- obj.items = (menu_item_t *)sci_calloc(obj.items_nr, sizeof(menu_item_t));
- for (int i = 0; i < obj.items_nr; ++i)
- sync_menu_item_t(s, obj.items[i]);
+ syncArray<MenuItem>(s, _items);
}
-static void sync_menubar_t(Common::Serializer &s, menubar_t &obj) {
- s.syncAsSint32LE(obj.menus_nr);
- if (!obj.menus && obj.menus_nr)
- obj.menus = (menu_t *)sci_calloc(obj.menus_nr, sizeof(menu_t));
- for (int i = 0; i < obj.menus_nr; ++i)
- sync_menu_t(s, obj.menus[i]);
+void Menubar::saveLoadWithSerializer(Common::Serializer &s) {
+ syncArray<Menu>(s, _menus);
}
static void sync_SegManager(Common::Serializer &s, SegManager &obj) {
@@ -205,10 +230,10 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
// FIXME: Do in-place loading at some point, instead of creating a new EngineState instance from scratch.
if (s.isLoading()) {
//free(menubar);
- menubar = (menubar_t *)sci_calloc(1, sizeof(menubar_t));
+ _menubar = new Menubar();
} else
- assert(menubar);
- sync_menubar_t(s, *menubar);
+ assert(_menubar);
+ _menubar->saveLoadWithSerializer(s);
s.syncAsSint32LE(status_bar_foreground);
s.syncAsSint32LE(status_bar_background);
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index a56a0e7f57..414e9d6892 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -97,7 +97,7 @@ EngineState::EngineState() : _dirseeker(this) {
animation_delay = 0;
animation_granularity = 0;
- menubar = 0;
+ _menubar = 0;
priority_first = 0;
priority_last = 0;
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index 5cc624c50c..b01f6539c5 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -46,7 +46,7 @@ namespace Common {
namespace Sci {
-struct menubar_t;
+class Menubar;
struct kfunct_sig_pair_t; // from kernel.h
struct gfx_state_t;
@@ -183,7 +183,7 @@ public:
long animation_delay; /* A delay factor for pic opening animations. Defaults to 500. */
int animation_granularity; /* Number of animation steps to perform betwen updates for transition animations */
- menubar_t *menubar; /* The menu bar */
+ Menubar *_menubar; /* The menu bar */
int priority_first; /* The line where priority zone 0 ends */
int priority_last; /* The line where the highest priority zone starts */