aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2009-09-21 21:38:43 +0000
committerMax Horn2009-09-21 21:38:43 +0000
commitd2a6713a8e1bead4a959205419373e828f59bfb4 (patch)
tree5d45de6635075f7fd990d5f41e163f607323a35d
parent7f728af76e6f1ff9b5eda7c5b26b6d2da78bef35 (diff)
downloadscummvm-rg350-d2a6713a8e1bead4a959205419373e828f59bfb4.tar.gz
scummvm-rg350-d2a6713a8e1bead4a959205419373e828f59bfb4.tar.bz2
scummvm-rg350-d2a6713a8e1bead4a959205419373e828f59bfb4.zip
SCI: Replace IntMapper Script::_objIndices and Common::Array Script::_objects by a HashMap -- goodbye, class IntMapper
svn-id: r44240
-rw-r--r--engines/sci/console.cpp64
-rw-r--r--engines/sci/engine/gc.cpp6
-rw-r--r--engines/sci/engine/intmap.cpp173
-rw-r--r--engines/sci/engine/intmap.h115
-rw-r--r--engines/sci/engine/kernel.cpp1
-rw-r--r--engines/sci/engine/savegame.cpp96
-rw-r--r--engines/sci/engine/savegame.h2
-rw-r--r--engines/sci/engine/seg_manager.cpp25
-rw-r--r--engines/sci/engine/segment.cpp19
-rw-r--r--engines/sci/engine/segment.h11
-rw-r--r--engines/sci/engine/vm.cpp1
-rw-r--r--engines/sci/module.mk1
12 files changed, 129 insertions, 385 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 0cee137482..628addc442 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -1398,13 +1398,16 @@ bool Console::segmentInfo(int nr) {
DebugPrintf(" Locals : none\n");
DebugPrintf(" Objects: %4d\n", scr->_objects.size());
- for (uint i = 0; i < scr->_objects.size(); i++) {
+
+ ObjMap::iterator it;
+ const ObjMap::iterator end = scr->_objects.end();
+ for (it = scr->_objects.begin(); it != end; ++it) {
DebugPrintf(" ");
// Object header
- Object *obj = _vm->_gamestate->segMan->getObject(scr->_objects[i]._pos);
+ Object *obj = _vm->_gamestate->segMan->getObject(it->_value._pos);
if (obj)
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(scr->_objects[i]._pos),
- _vm->_gamestate->segMan->getObjectName(scr->_objects[i]._pos),
+ DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value._pos),
+ _vm->_gamestate->segMan->getObjectName(it->_value._pos),
obj->_variables.size(), obj->methods_nr);
}
}
@@ -2884,48 +2887,53 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
SegmentObj *mobj = s->segMan->_heap[i];
int idx = 0;
int max_index = 0;
+ ObjMap::iterator it;
+ Script *scr = 0;
+ CloneTable *ct = 0;
if (mobj) {
- if (mobj->getType() == SEG_TYPE_SCRIPT)
- max_index = (*(Script *)mobj)._objects.size();
- else if (mobj->getType() == SEG_TYPE_CLONES)
- max_index = (*(CloneTable *)mobj)._table.size();
+ if (mobj->getType() == SEG_TYPE_SCRIPT) {
+ scr = (Script *)mobj;
+ max_index = scr->_objects.size();
+ it = scr->_objects.begin();
+ } else if (mobj->getType() == SEG_TYPE_CLONES) {
+ ct = (CloneTable *)mobj;
+ max_index = ct->_table.size();
+ }
}
- while (idx < max_index) {
- int valid = 1;
+ for (; idx < max_index; ++idx) {
Object *obj = NULL;
reg_t objpos;
objpos.offset = 0;
objpos.segment = i;
if (mobj->getType() == SEG_TYPE_SCRIPT) {
- obj = &(*(Script *)mobj)._objects[idx];
+ obj = &(it->_value);
objpos.offset = obj->_pos.offset;
+ ++it;
} else if (mobj->getType() == SEG_TYPE_CLONES) {
- obj = &((*(CloneTable *)mobj)._table[idx]);
+ if (!ct->isValidEntry(idx))
+ continue;
+ obj = &(ct->_table[idx]);
objpos.offset = idx;
- valid = ((CloneTable *)mobj)->isValidEntry(idx);
}
- if (valid) {
- const char *objname = s->segMan->getObjectName(objpos);
- if (!strcmp(objname, str_objname)) {
- // Found a match!
- if ((index < 0) && (times_found > 0)) {
- if (times_found == 1) {
- // First time we realized the ambiguity
- printf("Ambiguous:\n");
- printf(" %3x: [%04x:%04x] %s\n", 0, PRINT_REG(*dest), str_objname);
- }
- printf(" %3x: [%04x:%04x] %s\n", times_found, PRINT_REG(objpos), str_objname);
+ const char *objname = s->segMan->getObjectName(objpos);
+ if (!strcmp(objname, str_objname)) {
+ // Found a match!
+ if ((index < 0) && (times_found > 0)) {
+ if (times_found == 1) {
+ // First time we realized the ambiguity
+ printf("Ambiguous:\n");
+ printf(" %3x: [%04x:%04x] %s\n", 0, PRINT_REG(*dest), str_objname);
}
- if (index < 0 || times_found == index)
- *dest = objpos;
- ++times_found;
+ printf(" %3x: [%04x:%04x] %s\n", times_found, PRINT_REG(objpos), str_objname);
}
+ if (index < 0 || times_found == index)
+ *dest = objpos;
+ ++times_found;
}
- ++idx;
}
}
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 0f5f4a5e57..2a2b3ad19d 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -119,8 +119,10 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
wm.push(make_reg(script->_localsSegment, 0));
// All objects (may be classes, may be indirectly reachable)
- for (uint obj_nr = 0; obj_nr < script->_objects.size(); obj_nr++) {
- wm.push(script->_objects[obj_nr]._pos);
+ ObjMap::iterator it;
+ const ObjMap::iterator end = script->_objects.end();
+ for (it = script->_objects.begin(); it != end; ++it) {
+ wm.push(it->_value._pos);
}
}
}
diff --git a/engines/sci/engine/intmap.cpp b/engines/sci/engine/intmap.cpp
deleted file mode 100644
index 666082713e..0000000000
--- a/engines/sci/engine/intmap.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/* 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 "sci/engine/intmap.h"
-
-namespace Sci {
-
-#define HASH(x) (x & 0xff)
-
-IntMapper::IntMapper() {
- base_value = 0;
- memset(nodes, 0, sizeof(nodes));
- holes = 0;
-}
-
-void IntMapper::free_node_recursive(Node *node) {
- if (node) {
- free_node_recursive(node->next);
- node->next = 0;
- free(node);
- }
-}
-
-
-IntMapper::~IntMapper() {
- clear();
-
- // Trigger problems for people who forget to loose the reference
- base_value = -42000;
-}
-
-void IntMapper::clear() {
- for (int i = 0; i < DCS_INT_HASH_MAX; i++) {
- free_node_recursive(nodes[i]);
- nodes[i] = 0;
- }
-
- free_node_recursive(holes);
- holes = 0;
-}
-
-int IntMapper::checkKey(int key, bool add, bool *was_added) {
- Node **node = &(nodes[HASH(key)]);
-
- while (*node && (key != (*node)->key))
- node = &((*node)->next);
-
- if (was_added)
- *was_added = false;
-
- if (*node)
- return (*node)->idx;
-
- // Not found
-
- if (!add)
- return -1;
-
- if (was_added)
- *was_added = true;
-
- if (holes) { // Re-use old node
- (*node) = holes;
- holes = (*node)->next;
- (*node)->next = NULL;
- (*node)->key = key;
- } else {
- *node = (Node*)malloc(sizeof(Node));
- (*node)->key = key;
- (*node)->idx = base_value++;
- (*node)->next = NULL;
- }
-
- return (*node)->idx;
-}
-
-int IntMapper::lookupKey(int key) const {
- Node *const *node = &(nodes[HASH(key)]);
-
- while (*node && (key != (*node)->key))
- node = &((*node)->next);
-
- if (*node)
- return (*node)->idx;
-
- return -1;
-}
-
-void IntMapper::saveLoadWithSerializer(Common::Serializer &s) {
- s.syncAsSint32LE(base_value);
- if (s.isLoading()) {
- uint32 key = 0, idx = 0;
- clear();
- while (true) {
- s.syncAsSint32LE(key);
- if (key == INTMAPPER_MAGIC_KEY)
- break;
- s.syncAsSint32LE(idx);
- // Insert into the IntMapper
- insert(key, idx);
- }
- } else {
- // Just write out all mapped pairs
- // We terminate by writing 4 times the value 0xFF
- for (int i = 0; i < DCS_INT_HASH_MAX; ++i) {
- Node *node = nodes[i];
-
- while (node) {
- s.syncAsSint32LE(node->key);
- s.syncAsSint32LE(node->idx);
- node = node->next;
- }
- }
- uint32 tmp = INTMAPPER_MAGIC_KEY;
- s.syncAsSint32LE(tmp);
- }
-}
-
-void IntMapper::insert(int key, int idx) {
- Node **node = &(nodes[HASH(key)]);
-
- while (*node && (key != (*node)->key))
- node = &((*node)->next);
-
- assert(0 == *node); // Error out if the key was already present.
-
- *node = (Node*)malloc(sizeof(Node));
- (*node)->key = key;
- (*node)->idx = idx;
- (*node)->next = NULL;
-}
-
-
-int IntMapper::removeKey(int key) {
- Node **node = &(nodes[HASH(key)]);
-
- while (*node && (key != (*node)->key))
- node = &((*node)->next);
-
- if (*node) {
- Node *oldnode = *node;
- *node = (*node)->next;
-
- oldnode->next = holes; // Old node is now a 'hole'
- holes = oldnode;
- return oldnode->key;
- } else
- return -1; // Not found
-}
-
-} // End of namespace Sci
diff --git a/engines/sci/engine/intmap.h b/engines/sci/engine/intmap.h
deleted file mode 100644
index eebaf29d99..0000000000
--- a/engines/sci/engine/intmap.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* 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_ENGINE_INTMAP_H
-#define SCI_ENGINE_INTMAP_H
-
-#include "common/scummsys.h"
-#include "common/serializer.h"
-
-namespace Sci {
-
-
-// Assumes that the ints are relatively evenly distributed
-enum {
- DCS_INT_HASH_MAX = 256
-};
-
-const uint32 INTMAPPER_MAGIC_KEY = 0xDEADBEEF;
-
-/**
- * Defines a map from arbitrary integers to "small" integers, useable as index
- * into small arrays. This class is somewhat like a hashmap, but not quite:
- * Unlike a hashmap, it generates the values associated to each key. It does
- * not try to be very clever about it, either, e.g. using a linked list of
- * values to keep track of what is mapped where.
- * Another important feature is that it reclaims unused values when they
- * are removed.
- *
- * All in all, this implementation is not very elegant, and wastes memory.
- * But it does the job. Any rewrite of this class would have to provide a
- * way to load the old savegames made using the current implementation.
- *
- * One approach to implement a replacement: Combine a Common::HashMap<int,int>
- * with a bitfield which track which low-value integers are in use.
- * That way, lookup just invokes the hashmap, and insertion (which requires
- * finding an unmapped low-value integer) can still be implemented efficiently.
- */
-struct IntMapper : public Common::Serializable {
-
- struct Node {
- int key;
- int idx;
- Node *next;
- };
-
- int base_value; // Starts at zero, counts upwards
- Node *nodes[DCS_INT_HASH_MAX];
- Node *holes; /* List of freed entries to minimize
- ** memory operations and modifications
- ** to base_value */
-
- void free_node_recursive(Node *node);
-protected:
- void insert(int key, int idx); // For loading only
-
-public:
- IntMapper();
- ~IntMapper();
-
- virtual void saveLoadWithSerializer(Common::Serializer &ser);
-
- void clear();
-
- /**
- * Checks whether a key is in the map, adds it if neccessary.
- * @param key The key to check for/add
- * @param add Whether to add the key if it's not in there
- * @param was_added Set to non-zero if and only if the key is new, ignored if NULL.
- * @return The new (or old) index, or -1 if add was zero and
- * the key couldn't be found
- */
- int checkKey(int key, bool add, bool *wasAdded = 0);
-
- /**
- * Looks up a key in the map
- * @parmam key The key to look for
- * @return The value or -1 if not found
- */
- int lookupKey(int key) const;
-
-
- /**
- * Removes a key from the map.
- * @param key The key to remove
- * @return The index of the key, or -1 if it wasn't present
- */
- int removeKey(int key);
-
-};
-
-} // End of namespace Sci
-
-#endif // SCI_ENGINE_INTMAP_H
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 6c148833ff..696b959be2 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -24,7 +24,6 @@
*/
#include "sci/sci.h"
-#include "sci/engine/intmap.h"
#include "sci/engine/kernel.h"
#include "sci/resource.h"
#include "sci/engine/state.h"
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 3fc11be7fa..0c4cdaf9a9 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -38,7 +38,6 @@
#include "sci/sfx/core.h"
#include "sci/sfx/iterator.h"
#include "sci/engine/state.h"
-#include "sci/engine/intmap.h"
#include "sci/engine/savegame.h"
namespace Sci {
@@ -46,6 +45,11 @@ namespace Sci {
#define VER(x) Common::Serializer::Version(x)
+
+// OBSOLETE: This const is used for backward compatibility only.
+const uint32 INTMAPPER_MAGIC_KEY = 0xDEADBEEF;
+
+
// from ksound.cpp:
SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id);
@@ -162,7 +166,7 @@ void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
void MenuItem::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(_type);
s.syncString(_keytext);
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be keytext_size
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be keytext_size
s.syncAsSint32LE(_flags);
s.syncBytes(_said, MENU_SAID_SPEC_SIZE);
@@ -189,17 +193,17 @@ void Menubar::saveLoadWithSerializer(Common::Serializer &s) {
}
void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be reserved_id
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be reserved_id
s.syncAsSint32LE(_exportsAreWide);
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be gc_mark_bits
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be gc_mark_bits
if (s.isLoading()) {
// Reset _scriptSegMap, to be restored below
_scriptSegMap.clear();
if (s.getVersion() <= 9) {
- // Skip over the old id_seg_map when loading (we now regenerate the
- // equivalent data, in _scriptSegMap, from scratch).
+ // OBSOLETE: Skip over the old id_seg_map when loading (we now
+ // regenerate the equivalent data, in _scriptSegMap, from scratch).
s.skip(4); // base_value
while (true) {
@@ -235,7 +239,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
}
assert(mobj);
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be _segManagerId
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be _segManagerId
// Let the object sync custom data
mobj->saveLoadWithSerializer(s);
@@ -289,10 +293,10 @@ static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj)
}
void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be savegame_version
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be savegame_version
syncCStr(s, &game_version);
- s.skip(4, VER(9), VER(9)); // Obsolete: Used to be version
+ s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be version
// FIXME: Do in-place loading at some point, instead of creating a new EngineState instance from scratch.
if (s.isLoading()) {
@@ -384,19 +388,47 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsUint32LE(_scriptSize);
s.syncAsUint32LE(_heapSize);
- // FIXME: revamp _objIndices handling
- if (!_objIndices) {
- assert(s.isLoading());
- _objIndices = new IntMapper();
+ if (s.getVersion() <= 10) {
+ assert((s.isLoading()));
+ // OBSOLETE: Skip over the old _objIndices data when loading
+ s.skip(4); // base_value
+ while (true) {
+ uint32 key = 0;
+ s.syncAsSint32LE(key);
+ if (key == INTMAPPER_MAGIC_KEY)
+ break;
+ s.skip(4); // idx
+ }
}
- _objIndices->saveLoadWithSerializer(s);
-
s.syncAsSint32LE(_numExports);
s.syncAsSint32LE(_numSynonyms);
s.syncAsSint32LE(_lockers);
- syncArray<Object>(s, _objects);
+ // Sync _objects. This is a hashmap, and we use the following on disk format:
+ // First we store the number of items in the hashmap, then we store each
+ // object (which is an 'Object' instance). For loading, we take advantage
+ // of the fact that the key of each Object obj is just obj._pos.offset !
+ // By "chance" this format is identical to the format used to sync Common::Array<>,
+ // hence we can still old savegames with identical code :).
+
+ uint numObjs = _objects.size();
+ s.syncAsUint32LE(numObjs);
+
+ if (s.isLoading()) {
+ _objects.clear();
+ Object tmp;
+ for (uint i = 0; i < numObjs; ++i) {
+ syncWithSerializer<Object>(s, tmp);
+ _objects[tmp._pos.offset] = tmp;
+ }
+ } else {
+ ObjMap::iterator it;
+ const ObjMap::iterator end = _objects.end();
+ for (it = _objects.begin(); it != end; ++it) {
+ syncWithSerializer<Object>(s, it->_value);
+ }
+ }
s.syncAsSint32LE(_localsOffset);
s.syncAsSint32LE(_localsSegment);
@@ -579,10 +611,12 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
}
scr->_codeBlocks.clear();
- for (j = 0; j < scr->_objects.size(); j++) {
- byte *data = scr->_buf + scr->_objects[j]._pos.offset;
- scr->_objects[j].base = scr->_buf;
- scr->_objects[j].base_obj = data;
+ ObjMap::iterator it;
+ const ObjMap::iterator end = scr->_objects.end();
+ for (it = scr->_objects.begin(); it != end; ++it) {
+ byte *data = scr->_buf + it->_value._pos.offset;
+ it->_value.base = scr->_buf;
+ it->_value.base_obj = data;
}
break;
}
@@ -599,31 +633,33 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
case SEG_TYPE_SCRIPT: {
Script *scr = (Script *)mobj;
- for (j = 0; j < scr->_objects.size(); j++) {
- byte *data = scr->_buf + scr->_objects[j]._pos.offset;
+ ObjMap::iterator it;
+ const ObjMap::iterator end = scr->_objects.end();
+ for (it = scr->_objects.begin(); it != end; ++it) {
+ byte *data = scr->_buf + it->_value._pos.offset;
if (s->resMan->sciVersion() >= SCI_VERSION_1_1) {
uint16 *funct_area = (uint16 *) (scr->_buf + READ_LE_UINT16( data + 6 ));
uint16 *prop_area = (uint16 *) (scr->_buf + READ_LE_UINT16( data + 4 ));
- scr->_objects[j].base_method = funct_area;
- scr->_objects[j].base_vars = prop_area;
+ it->_value.base_method = funct_area;
+ it->_value.base_vars = prop_area;
} else {
int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );
Object *base_obj;
- base_obj = s->segMan->getObject(scr->_objects[j].getSpeciesSelector());
+ base_obj = s->segMan->getObject(it->_value.getSpeciesSelector());
if (!base_obj) {
warning("Object without a base class: Script %d, index %d (reg address %04x:%04x",
- scr->_nr, j, PRINT_REG(scr->_objects[j].getSpeciesSelector()));
+ scr->_nr, j, PRINT_REG(it->_value.getSpeciesSelector()));
continue;
}
- scr->_objects[j].variable_names_nr = base_obj->_variables.size();
- scr->_objects[j].base_obj = base_obj->base_obj;
+ it->_value.variable_names_nr = base_obj->_variables.size();
+ it->_value.base_obj = base_obj->base_obj;
- scr->_objects[j].base_method = (uint16 *)(data + funct_area);
- scr->_objects[j].base_vars = (uint16 *)(data + scr->_objects[j].variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
+ it->_value.base_method = (uint16 *)(data + funct_area);
+ it->_value.base_vars = (uint16 *)(data + it->_value.variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
}
}
break;
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 6c9c84ccd5..8de6c236f2 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -36,7 +36,7 @@ namespace Sci {
struct EngineState;
enum {
- CURRENT_SAVEGAME_VERSION = 10,
+ CURRENT_SAVEGAME_VERSION = 11,
MINIMUM_SAVEGAME_VERSION = 9
};
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index f488f38d67..a1c837512b 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -26,7 +26,6 @@
#include "sci/sci.h"
#include "sci/engine/seg_manager.h"
#include "sci/engine/state.h"
-#include "sci/engine/intmap.h"
namespace Sci {
@@ -323,8 +322,8 @@ int Script::relocateLocal(SegmentId segment, int location) {
return 0; // No hands, no cookies
}
-int Script::relocateObject(Object *obj, SegmentId segment, int location) {
- return relocateBlock(obj->_variables, obj->_pos.offset, segment, location);
+int Script::relocateObject(Object &obj, SegmentId segment, int location) {
+ return relocateBlock(obj._variables, obj._pos.offset, segment, location);
}
void Script::scriptAddCodeBlock(reg_t location) {
@@ -349,8 +348,10 @@ void Script::scriptRelocate(reg_t block) {
bool done = false;
uint k;
- for (k = 0; !done && k < _objects.size(); k++) {
- if (relocateObject(&_objects[k], block.segment, pos))
+ ObjMap::iterator it;
+ const ObjMap::iterator end = _objects.end();
+ for (it = _objects.begin(); !done && it != end; ++it) {
+ if (relocateObject(it->_value, block.segment, pos))
done = true;
}
@@ -367,8 +368,8 @@ void Script::scriptRelocate(reg_t block) {
printf("- locals: %d at %04x\n", _localsBlock->_locals.size(), _localsOffset);
else
printf("- No locals\n");
- for (k = 0; k < _objects.size(); k++)
- printf("- obj#%d at %04x w/ %d vars\n", k, _objects[k]._pos.offset, _objects[k]._variables.size());
+ for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
+ printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size());
// SQ3 script 71 has broken relocation entries.
printf("Trying to continue anyway...\n");
}
@@ -392,8 +393,10 @@ void Script::heapRelocate(reg_t block) {
bool done = false;
uint k;
- for (k = 0; !done && k < _objects.size(); k++) {
- if (relocateObject(&_objects[k], block.segment, pos))
+ ObjMap::iterator it;
+ const ObjMap::iterator end = _objects.end();
+ for (it = _objects.begin(); !done && it != end; ++it) {
+ if (relocateObject(it->_value, block.segment, pos))
done = true;
}
@@ -404,8 +407,8 @@ void Script::heapRelocate(reg_t block) {
printf("- locals: %d at %04x\n", _localsBlock->_locals.size(), _localsOffset);
else
printf("- No locals\n");
- for (k = 0; k < _objects.size(); k++)
- printf("- obj#%d at %04x w/ %d vars\n", k, _objects[k]._pos.offset, _objects[k]._variables.size());
+ for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
+ printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size());
error("Breakpoint in %s, line %d", __FILE__, __LINE__);
}
}
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 087505b9df..dddf8169d8 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -27,7 +27,6 @@
#include "sci/sci.h"
#include "sci/engine/segment.h"
-#include "sci/engine/intmap.h"
#include "sci/engine/seg_manager.h"
#include "sci/engine/state.h"
#include "sci/tools.h"
@@ -92,8 +91,6 @@ Script::Script() {
_heapStart = NULL;
_exportTable = NULL;
- _objIndices = NULL;
-
_localsOffset = 0;
_localsSegment = 0;
_localsBlock = NULL;
@@ -112,9 +109,6 @@ void Script::freeScript() {
_bufSize = 0;
_objects.clear();
-
- delete _objIndices;
- _objIndices = 0;
_codeBlocks.clear();
}
@@ -141,8 +135,6 @@ bool Script::init(int script_nr, ResourceManager *resMan) {
_relocated = false;
_markedAsDeleted = false;
- _objIndices = new IntMapper();
-
_nr = script_nr;
if (getSciVersion() >= SCI_VERSION_1_1)
@@ -154,17 +146,12 @@ bool Script::init(int script_nr, ResourceManager *resMan) {
}
Object *Script::allocateObject(uint16 offset) {
- int idx = _objIndices->checkKey(offset, true);
- if ((uint)idx == _objects.size())
- _objects.push_back(Object());
-
- return &_objects[idx];
+ return &_objects[offset];
}
Object *Script::getObject(uint16 offset) {
- int idx = _objIndices->checkKey(offset, false);
- if (idx >= 0 && (uint)idx < _objects.size())
- return &_objects[idx];
+ if (_objects.contains(offset))
+ return &_objects[offset];
else
return 0;
}
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 6f051da7d9..450140b443 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -262,6 +262,8 @@ struct CodeBlock {
int size;
};
+typedef Common::HashMap<uint16, Object> ObjMap;
+
class Script : public SegmentObj {
public:
int _nr; /**< Script number */
@@ -281,15 +283,12 @@ public:
protected:
int _lockers; /**< Number of classes and objects that require this script */
- IntMapper *_objIndices;
-
public:
/**
* Table for objects, contains property variables.
- * Indexed by the value stored at SCRIPT_LOCALVARPTR_OFFSET,
- * see VM_OBJECT_[GS]ET_INDEX()
+ * Indexed by the TODO offset.
*/
- Common::Array<Object> _objects;
+ ObjMap _objects;
int _localsOffset;
SegmentId _localsSegment; /**< The local variable segment */
@@ -349,7 +348,7 @@ public:
private:
int relocateLocal(SegmentId segment, int location);
int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
- int relocateObject(Object *obj, SegmentId segment, int location);
+ int relocateObject(Object &obj, SegmentId segment, int location);
Object *scriptObjInit0(reg_t obj_pos);
Object *scriptObjInit11(reg_t obj_pos);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index c1425977c4..626eae93ff 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -31,7 +31,6 @@
#include "sci/debug.h" // for g_debug_weak_validations
#include "sci/resource.h"
#include "sci/engine/state.h"
-#include "sci/engine/intmap.h"
#include "sci/engine/kernel.h"
#include "sci/engine/kernel_types.h"
#include "sci/engine/seg_manager.h"
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 1c1a930e31..88c60b6c1c 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -11,7 +11,6 @@ MODULE_OBJS = \
engine/game.o \
engine/gc.o \
engine/grammar.o \
- engine/intmap.o \
engine/kernel.o \
engine/kevent.o \
engine/kfile.o \