aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMax Horn2009-05-04 15:23:33 +0000
committerMax Horn2009-05-04 15:23:33 +0000
commitf2da4bc4477ade50f53753e8f7702e072ad3cf8c (patch)
tree90d8e587b4a94f4fdcc21229ac5445fd15b903b1 /engines/sci
parent27b74756d8039fe5aaed61bd4866087c64226faf (diff)
downloadscummvm-rg350-f2da4bc4477ade50f53753e8f7702e072ad3cf8c.tar.gz
scummvm-rg350-f2da4bc4477ade50f53753e8f7702e072ad3cf8c.tar.bz2
scummvm-rg350-f2da4bc4477ade50f53753e8f7702e072ad3cf8c.zip
SCI: Got rid of heapmgr.h; further improve the Table code
svn-id: r40308
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/heapmgr.h42
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/seg_manager.cpp135
-rw-r--r--engines/sci/engine/vm.h69
4 files changed, 105 insertions, 145 deletions
diff --git a/engines/sci/engine/heapmgr.h b/engines/sci/engine/heapmgr.h
deleted file mode 100644
index f8975d428d..0000000000
--- a/engines/sci/engine/heapmgr.h
+++ /dev/null
@@ -1,42 +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$
- *
- */
-
-/* Heap-like managed structure */
-
-#ifndef SCI_ENGINE_HEAPMGR_H
-#define SCI_ENGINE_HEAPMGR_H
-
-namespace Sci {
-
-enum { HEAPENTRY_INVALID = -1 };
-
-// FIXME: We write (i == 0 || i > 0) instead of (i >= 0) to silence certain annoying warnings:
-// generated by GCC: "comparison is always true due to limited range of data type".
-#define ENTRY_IS_VALID(t, i) ((i == 0 || i > 0) && (i) < (t)->max_entry && (t)->table[(i)].next_free == (i))
-
-
-} // End of namespace Sci
-
-#endif // SCI_ENGINE_HEAPMGR_H
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 4130671cc9..7741e802d2 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -551,13 +551,13 @@ static int clone_entry_used(CloneTable *table, int n) {
int seeker = table->first_free;
CloneTable::Entry *entries = table->table;
- if (seeker == HEAPENTRY_INVALID) return 1;
+ if (seeker == CloneTable::HEAPENTRY_INVALID) return 1;
do {
if (seeker == n) return 0;
backup = seeker;
seeker = entries[seeker].next_free;
- } while (entries[backup].next_free != HEAPENTRY_INVALID);
+ } while (entries[backup].next_free != CloneTable::HEAPENTRY_INVALID);
return 1;
}
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 460502827f..20470b8ebc 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -971,15 +971,80 @@ uint16 SegManager::validateExportFunc(int pubfunct, int seg) {
return offset;
}
+template<typename T, int INITIAL, int INCREMENT>
+Table<T, INITIAL, INCREMENT>::Table() {
+ entries_nr = 0;
+ max_entry = 0;
+ entries_used = 0;
+ first_free = HEAPENTRY_INVALID;
+ table = NULL;
+}
+
+template<typename T, int INITIAL, int INCREMENT>
+Table<T, INITIAL, INCREMENT>::~Table() {
+ // FIXME: Shouldn't we make sure that all table entries are disposed
+ // of properly?
+ free(table);
+ table = NULL;
+ entries_nr = max_entry = 0;
+}
+
+template<typename T, int INITIAL, int INCREMENT>
+void Table<T, INITIAL, INCREMENT>::initTable() {
+ entries_nr = INITIAL;
+ max_entry = 0;
+ entries_used = 0;
+ first_free = HEAPENTRY_INVALID;
+ table = (Entry *)calloc(INITIAL, sizeof(Entry));
+}
+
+template<typename T, int INITIAL, int INCREMENT>
+int Table<T, INITIAL, INCREMENT>::allocEntry() {
+ entries_used++;
+ if (first_free != HEAPENTRY_INVALID) {
+ int oldff = first_free;
+ first_free = table[oldff].next_free;
+
+ table[oldff].next_free = oldff;
+ return oldff;
+ } else {
+ if (max_entry == entries_nr) {
+ entries_nr += INCREMENT;
+
+ table = (Entry *)sci_realloc(table, sizeof(Entry) * entries_nr);
+ memset(&table[entries_nr-INCREMENT], 0, INCREMENT * sizeof(Entry));
+ }
+ table[max_entry].next_free = max_entry; /* Tag as 'valid' */
+ return max_entry++;
+ }
+}
+
+template<typename T, int INITIAL, int INCREMENT>
+void Table<T, INITIAL, INCREMENT>::freeEntry(int idx) {
+ if (idx < 0 || idx >= max_entry) {
+ error("Table::freeEntry: Attempt to release invalid table index %d", idx);
+ }
+
+ table[idx].next_free = first_free;
+ first_free = idx;
+ entries_used--;
+}
+
+template<typename T, int INITIAL, int INCREMENT>
+bool Table<T, INITIAL, INCREMENT>::isValidEntry(int idx) {
+ return idx >= 0 && idx < max_entry && table[idx].next_free == idx;
+}
+
+
void SegManager::free_hunk_entry(reg_t addr) {
- MemObject *mobj = GET_SEGMENT(*this, addr.segment, MEM_OBJ_HUNK);
+ HunkTable *ht = (HunkTable *)GET_SEGMENT(*this, addr.segment, MEM_OBJ_HUNK);
- if (!mobj) {
+ if (!ht) {
sciprintf("Attempt to free Hunk from address "PREG": Invalid segment type\n", PRINT_REG(addr));
return;
}
- Sci::free_Hunk_entry((HunkTable *)mobj, addr.offset);
+ ht->freeEntry(addr.offset);
}
Hunk *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg) {
@@ -995,53 +1060,6 @@ Hunk *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg)
return h;
}
-
-void free_List_entry(ListTable *table, int index) {
- if (index < 0 || index >= table->max_entry) {
- error("heapmgr: Attempt to release invalid table index %d", index);
- }
-
- table->table[index].next_free = table->first_free;
- table->first_free = index;
- table->entries_used--;
-}
-
-void free_Node_entry(NodeTable *table, int index) {
- if (index < 0 || index >= table->max_entry) {
- error("heapmgr: Attempt to release invalid table index %d", index);
- }
-
- table->table[index].next_free = table->first_free;
- table->first_free = index;
- table->entries_used--;
-}
-
-void free_Clone_entry(CloneTable *table, int index) {
- if (index < 0 || index >= table->max_entry) {
- error("heapmgr: Attempt to release invalid table index %d", index);
- }
-
- free(table->table[index].variables); // Free the dynamically allocated memory part
-
- table->table[index].next_free = table->first_free;
- table->first_free = index;
- table->entries_used--;
-}
-
-void free_Hunk_entry(HunkTable *table, int index) {
- if (index < 0 || index >= table->max_entry) {
- error("heapmgr: Attempt to release invalid table index %d", index);
- }
-
- free(table->table[index].mem);
-
- table->table[index].next_free = table->first_free;
- table->first_free = index;
- table->entries_used--;
-}
-
-
-
Clone *SegManager::alloc_Clone(reg_t *addr) {
CloneTable *table;
int offset;
@@ -1354,11 +1372,12 @@ void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, v
}
void SegInterfaceClones::freeAtAddress(reg_t addr) {
+ CloneTable *clone_table = (CloneTable *)_mobj;
Object *victim_obj;
assert(addr.segment == _segId);
- victim_obj = &((*(CloneTable *)_mobj).table[addr.offset]);
+ victim_obj = &(clone_table->table[addr.offset]);
#ifdef GC_DEBUG
if (!(victim_obj->flags & OBJECT_FLAG_FREED))
@@ -1374,7 +1393,7 @@ void SegInterfaceClones::freeAtAddress(reg_t addr) {
*/
free(victim_obj->variables);
victim_obj->variables = NULL;
- Sci::free_Clone_entry((CloneTable *)_mobj, addr.offset);
+ clone_table->freeEntry(addr.offset);
}
@@ -1463,7 +1482,8 @@ public:
};
void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
- Sci::free_List_entry((ListTable *)_mobj, sub_addr.offset);
+ ListTable *table = (ListTable *)_mobj;
+ table->freeEntry(sub_addr.offset);
}
void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
@@ -1471,8 +1491,6 @@ void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
-
-
}
void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
@@ -1502,7 +1520,8 @@ public:
};
void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
- Sci::free_Node_entry((NodeTable *)_mobj, sub_addr.offset);
+ NodeTable *table = (NodeTable *)_mobj;
+ table->freeEntry(sub_addr.offset);
}
void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
@@ -1510,8 +1529,6 @@ void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
-
-
}
void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
@@ -1551,8 +1568,6 @@ void SegInterfaceHunk::listAllDeallocatable(void *param, NoteCallback note) {
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
-
-
}
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 791601015d..49422f23d5 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -31,7 +31,6 @@
//#include "common/serializer.h"
#include "sci/scicore/versions.h" // for sci_version_t
#include "sci/engine/vm_types.h" // for reg_t
-#include "sci/engine/heapmgr.h"
namespace Sci {
@@ -398,6 +397,8 @@ struct Table : public MemObject {
struct Entry : public T {
int next_free; /* Only used for free entries */
};
+ enum { HEAPENTRY_INVALID = -1 };
+
int entries_nr; /**< Number of entries allocated */
int first_free; /**< Beginning of a singly linked list for entries */
@@ -407,63 +408,49 @@ struct Table : public MemObject {
Entry *table;
public:
- ~Table() {
- // FIXME: Shouldn't we make sure that all table entries are disposed
- // of properly?
- free(table);
- table = NULL;
- entries_nr = max_entry = 0;
- }
+ Table();
+ ~Table();
+
+ void initTable();
+ int allocEntry();
+ bool isValidEntry(int idx);
+ virtual void freeEntry(int idx);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
+};
- void initTable() {
- entries_nr = INITIAL;
- max_entry = 0;
- entries_used = 0;
- first_free = HEAPENTRY_INVALID;
- table = (Entry *)calloc(INITIAL, sizeof(Entry));
- }
+// FIXME: Replace ENTRY_IS_VALID by a direct method call
+#define ENTRY_IS_VALID(t, i) ((t)->isValidEntry(i))
- int allocEntry() {
- entries_used++;
- if (first_free != HEAPENTRY_INVALID) {
- int oldff = first_free;
- first_free = table[oldff].next_free;
- table[oldff].next_free = oldff;
- return oldff;
- } else {
- if (max_entry == entries_nr) {
- entries_nr += INCREMENT;
+/* CloneTable */
+struct CloneTable : public Table<Clone, 16, 4> {
+ virtual void freeEntry(int idx) {
+ Table<Clone, 16, 4>::freeEntry(idx);
- table = (Entry *)sci_realloc(table, sizeof(Entry) * entries_nr);
- memset(&table[entries_nr-INCREMENT], 0, INCREMENT * sizeof(Entry));
- }
- table[max_entry].next_free = max_entry; /* Tag as 'valid' */
- return max_entry++;
- }
+ free(table[idx].variables); // Free the dynamically allocated memory part
}
};
-/* CloneTable */
-typedef Table<Clone, 16, 4> CloneTable;
-void free_Clone_entry(CloneTable *table, int index);
-
/* NodeTable */
-typedef Table<Node, 32, 16> NodeTable;
-void free_Node_entry(NodeTable *table, int index);
+struct NodeTable : public Table<Node, 32, 16> {
+};
/* ListTable */
-typedef Table<List, 8, 4> ListTable;
-void free_List_entry(ListTable *table, int index);
+struct ListTable : public Table<List, 8, 4> {
+};
/* HunkTable */
-typedef Table<Hunk, 4, 4> HunkTable;
-void free_Hunk_entry(HunkTable *table, int index);
+struct HunkTable : public Table<Hunk, 4, 4> {
+ virtual void freeEntry(int idx) {
+ Table<Hunk, 4, 4>::freeEntry(idx);
+
+ free(table[idx].mem);
+ }
+};
// Free-style memory