From b5e9d79e157d4460f4b9038d19bfc31cf279c5f0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 27 Apr 2009 12:31:27 +0000 Subject: SCI: Turned classtable into a Common::Array svn-id: r40161 --- engines/sci/engine/game.cpp | 53 ++++++++++++++------------------------ engines/sci/engine/savegame.cpp | 25 +++++++++++++----- engines/sci/engine/scriptdebug.cpp | 12 ++++----- engines/sci/engine/seg_manager.cpp | 10 +++---- engines/sci/engine/state.cpp | 3 --- engines/sci/engine/state.h | 3 +-- engines/sci/engine/vm.cpp | 31 +++++++++++----------- 7 files changed, 65 insertions(+), 72 deletions(-) (limited to 'engines/sci') diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index b44b4dd271..48e70eb801 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -268,11 +268,9 @@ int create_class_table_sci11(EngineState *s) { Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); if (!vocab996) - s->classtable_size = 20; + s->_classtable.resize(20); else - s->classtable_size = vocab996->size >> 2; - - s->classtable = (Class*)sci_calloc(sizeof(Class), s->classtable_size); + s->_classtable.resize(vocab996->size >> 2); for (scriptnr = 0; scriptnr < 1000; scriptnr++) { Resource *heap = s->resmgr->findResource(kResourceTypeHeap, scriptnr, 0); @@ -286,23 +284,19 @@ int create_class_table_sci11(EngineState *s) { while (READ_LE_UINT16((byte*)seeker_ptr) == SCRIPT_OBJECT_MAGIC_NUMBER) { if (READ_LE_UINT16((byte*)seeker_ptr + 14) & SCRIPT_INFO_CLASS) { classnr = READ_LE_UINT16((byte*)seeker_ptr + 10); - if (classnr >= s->classtable_size) { + if (classnr >= (int)s->_classtable.size()) { if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) { - fprintf(stderr, "Invalid class number 0x%x in script.%d(0x%x), offset %04x\n", + warning("Invalid class number 0x%x in script.%d(0x%x), offset %04x\n", classnr, scriptnr, scriptnr, seeker_offset); return 1; } - s->classtable = (Class*)sci_realloc(s->classtable, sizeof(Class) * (classnr + 1)); - // Clear after resize - memset(&(s->classtable[s->classtable_size]), 0, sizeof(Class) * (1 + classnr - s->classtable_size)); - - s->classtable_size = classnr + 1; // Adjust maximum number of entries + s->_classtable.resize(classnr + 1); // Adjust maximum number of entries } - s->classtable[classnr].reg.offset = seeker_offset; - s->classtable[classnr].reg.segment = 0; - s->classtable[classnr].script = scriptnr; + s->_classtable[classnr].reg.offset = seeker_offset; + s->_classtable[classnr].reg.segment = 0; + s->_classtable[classnr].script = scriptnr; } seeker_ptr += READ_LE_UINT16((byte*)seeker_ptr + 2) * 2; @@ -323,11 +317,9 @@ static int create_class_table_sci0(EngineState *s) { Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); if (!vocab996) - s->classtable_size = 20; + s->_classtable.resize(20); else - s->classtable_size = vocab996->size >> 2; - - s->classtable = (Class*)sci_calloc(sizeof(Class), s->classtable_size); + s->_classtable.resize(vocab996->size >> 2); for (scriptnr = 0; scriptnr < 1000; scriptnr++) { int objtype = 0; @@ -347,8 +339,8 @@ static int create_class_table_sci0(EngineState *s) { break; seeker += (int16)READ_LE_UINT16(script->data + seeker + 2); if (seeker <= lastseeker) { - sciprintf("Warning: Script version is invalid.\n"); - free(s->classtable); + warning("Script version is invalid"); + s->_classtable.clear(); return SCI_ERROR_INVALID_SCRIPT_VERSION; } } @@ -359,30 +351,26 @@ static int create_class_table_sci0(EngineState *s) { seeker -= SCRIPT_OBJECT_MAGIC_OFFSET; // Adjust position; script home is base +8 bytes classnr = (int16)READ_LE_UINT16(script->data + seeker + 4 + SCRIPT_SPECIES_OFFSET); - if (classnr >= s->classtable_size) { + if (classnr >= (int)s->_classtable.size()) { if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) { - fprintf(stderr, "Invalid class number 0x%x in script.%d(0x%x), offset %04x\n", + warning("Invalid class number 0x%x in script.%d(0x%x), offset %04x\n", classnr, scriptnr, scriptnr, seeker); return 1; } - s->classtable = (Class*)sci_realloc(s->classtable, sizeof(Class) * (classnr + 1)); - // Clear after resize - memset(&(s->classtable[s->classtable_size]), 0, sizeof(Class) * (1 + classnr - s->classtable_size)); - - s->classtable_size = classnr + 1; // Adjust maximum number of entries + s->_classtable.resize(classnr + 1); // Adjust maximum number of entries } sugg_script = suggested_script(vocab996, classnr); // First, test whether the script hasn't been claimed, or if it's been claimed by the wrong script - if (sugg_script == -1 || scriptnr == sugg_script /*|| !s->classtable[classnr].reg.segment*/) { + if (sugg_script == -1 || scriptnr == sugg_script /*|| !s->_classtable[classnr].reg.segment*/) { // Now set the home script of the class - s->classtable[classnr].reg.offset = seeker + 4 - magic_offset; - s->classtable[classnr].reg.segment = 0; - s->classtable[classnr].script = scriptnr; + s->_classtable[classnr].reg.offset = seeker + 4 - magic_offset; + s->_classtable[classnr].reg.segment = 0; + s->_classtable[classnr].script = scriptnr; } seeker += SCRIPT_OBJECT_MAGIC_OFFSET; // Re-adjust position @@ -513,8 +501,7 @@ void script_free_vm_memory(EngineState *s) { sciprintf("Freeing VM memory\n"); s->save_dir_copy_buf = NULL; - free(s->classtable); - s->classtable = NULL; + s->_classtable.clear(); // Close all opened file handles s->_fileHandles.clear(); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 1396f448c8..042590b33b 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -25,6 +25,7 @@ #include "common/stream.h" #include "common/system.h" +#include "common/func.h" #include "common/serializer.h" #include // FIXME: For struct tm @@ -129,6 +130,22 @@ void syncArray(Common::Serializer &s, Common::Array &arr) { } } +template +void syncArray(Common::Serializer &s, Common::Array &arr, const Common::Functor2 &func) { + uint len = arr.size(); + s.syncAsUint32LE(len); + + // Resize the array if loading. + if (s.isLoading()) + arr.resize(len); + + typename Common::Array::iterator i; + for (i = arr.begin(); i != arr.end(); ++i) { + func(s, *i); + } +} + + void MenuItem::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_type); s.syncString(_keytext); @@ -241,12 +258,8 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { sync_SegManagerPtr(s, seg_manager); - s.syncAsSint32LE(classtable_size); - - if (!classtable && classtable_size) - classtable = (Class *)sci_calloc(classtable_size, sizeof(Class)); - for (int i = 0; i < classtable_size; ++i) - sync_Class(s, classtable[i]); + Common::Functor2Fun tmp(sync_Class); + syncArray(s, _classtable, tmp); sync_sfx_state_t(s, sound); } diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 14fa9d54d0..27c41795ec 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -83,8 +83,8 @@ int _kdebug_cheap_soundcue_hack = -1; char inputbuf[256] = ""; #define LOOKUP_SPECIES(species) (\ - (species >= 1000) ? species : *(s->classtable[species].scriptposp) \ - + s->classtable[species].class_offset) + (species >= 1000) ? species : *(s->_classtable[species].scriptposp) \ + + s->_classtable[species].class_offset) const char *_debug_get_input_default() { char newinpbuf[256]; @@ -830,17 +830,15 @@ int c_sim_parse(EngineState *s) { } int c_classtable(EngineState *s) { - int i; - if (!_debugstate_valid) { sciprintf("Not in debug state\n"); return 1; } sciprintf("Available classes:\n"); - for (i = 0; i < s->classtable_size; i++) - if (s->classtable[i].reg.segment) - sciprintf(" Class 0x%x at "PREG" (script 0x%x)\n", i, PRINT_REG(s->classtable[i].reg), s->classtable[i].script); + for (uint i = 0; i < s->_classtable.size(); i++) + if (s->_classtable[i].reg.segment) + sciprintf(" Class 0x%x at "PREG" (script 0x%x)\n", i, PRINT_REG(s->_classtable[i].reg), s->_classtable[i].script); return 0; } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index f95a3dc42e..8665cf1d8e 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -1127,16 +1127,16 @@ void SegManager::scriptInitialiseObjectsSci11(EngineState *s, int seg) { int classpos = seeker - scr->buf; int species = READ_LE_UINT16(seeker + 10); - if (species < 0 || species >= s->classtable_size) { + if (species < 0 || species >= (int)s->_classtable.size()) { sciprintf("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n", - species, species, s->classtable_size, scr->nr); + species, species, s->_classtable.size(), scr->nr); script_debug_flag = script_error_flag = 1; return; } - s->classtable[species].script = scr->nr; - s->classtable[species].reg.segment = seg; - s->classtable[species].reg.offset = classpos; + s->_classtable[species].script = scr->nr; + s->_classtable[species].reg.segment = seg; + s->_classtable[species].reg.offset = classpos; } seeker += READ_LE_UINT16(seeker + 2) * 2; } diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 2112d070c1..e6266c65a2 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -146,9 +146,6 @@ EngineState::EngineState() : _dirseeker(this) { game_obj = NULL_REG; - classtable_size = 0; - classtable = 0; - seg_manager = 0; gc_countdown = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index d37f107c25..e522176a9b 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -259,8 +259,7 @@ public: reg_t game_obj; /**< Pointer to the game object */ - int classtable_size; /**< Number of classes in the table- for debugging */ - Class *classtable; /**< Table of all classes */ + Common::Array _classtable; /**< Table of all classes */ SegManager *seg_manager; int gc_countdown; /**< Number of kernel calls until next gc */ diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 358a35613a..6f93da093e 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -199,24 +199,24 @@ int script_error(EngineState *s, const char *file, int line, const char *reason) #define CORE_ERROR(area, msg) script_error(s, "[" area "] " __FILE__, __LINE__, msg) reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) { - Class *the_class = s->classtable + classnr; if (NULL == s) { - sciprintf("vm.c: get_class_address(): NULL passed for \"s\"\n"); + warning("vm.c: get_class_address(): NULL passed for \"s\""); return NULL_REG; } - if (classnr < 0 || s->classtable_size <= classnr || the_class->script < 0) { - sciprintf("[VM] Attempt to dereference class %x, which doesn't exist (max %x)\n", classnr, s->classtable_size); + if (classnr < 0 || (int)s->_classtable.size() <= classnr || s->_classtable[classnr].script < 0) { + warning("[VM] Attempt to dereference class %x, which doesn't exist (max %x)", classnr, s->_classtable.size()); script_error_flag = script_debug_flag = 1; return NULL_REG; } else { + Class *the_class = &s->_classtable[classnr]; if (!the_class->reg.segment) { script_get_segment(s, the_class->script, lock); if (!the_class->reg.segment) { - sciprintf("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;" - " Entering debugger.\n", classnr, the_class->script, the_class->script); + warning("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;" + " Entering debugger.", classnr, the_class->script, the_class->script); script_error_flag = script_debug_flag = 1; return NULL_REG; } @@ -1811,18 +1811,18 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { int species; reg_tmp.offset = addr.offset - SCRIPT_OBJECT_MAGIC_OFFSET; species = OBJ_SPECIES(s, reg_tmp); - if (species < 0 || species >= s->classtable_size) { + if (species < 0 || species >= (int)s->_classtable.size()) { sciprintf("Invalid species %d(0x%x) not in interval " "[0,%d) while instantiating script %d\n", - species, species, s->classtable_size, + species, species, s->_classtable.size(), script_nr); script_debug_flag = script_error_flag = 1; return 1; } - s->classtable[species].script = script_nr; - s->classtable[species].reg = addr; - s->classtable[species].reg.offset = classpos; + s->_classtable[species].script = script_nr; + s->_classtable[species].reg = addr; + s->_classtable[species].reg.offset = classpos; // Set technical class position-- into the block allocated for it } break; @@ -1952,7 +1952,7 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { superclass = OBJ_SUPERCLASS(s, reg); // Get superclass... if (superclass >= 0) { - int superclass_script = s->classtable[superclass].script; + int superclass_script = s->_classtable[superclass].script; if (superclass_script == script_nr) { if (s->seg_manager->getLockers(reg.segment, SEG_ID)) @@ -1972,7 +1972,6 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { void script_uninstantiate(EngineState *s, int script_nr) { reg_t reg = make_reg(0, (s->version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER) ? 2 : 0); - int i; reg.segment = s->seg_manager->segGet(script_nr); @@ -1988,9 +1987,9 @@ void script_uninstantiate(EngineState *s, int script_nr) { return; // Free all classtable references to this script - for (i = 0; i < s->classtable_size; i++) - if (s->classtable[i].reg.segment == reg.segment) - s->classtable[i].reg = NULL_REG; + for (uint i = 0; i < s->_classtable.size(); i++) + if (s->_classtable[i].reg.segment == reg.segment) + s->_classtable[i].reg = NULL_REG; if (s->version < SCI_VERSION(1, 001, 000)) script_uninstantiate_sci0(s, script_nr, reg.segment); -- cgit v1.2.3