diff options
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/game.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/kmenu.cpp | 76 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 87 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 4 |
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 */ |