aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/game.cpp12
-rw-r--r--engines/sci/engine/kscripts.cpp6
-rw-r--r--engines/sci/engine/savegame.cfsml3
-rw-r--r--engines/sci/engine/savegame.cpp5
-rw-r--r--engines/sci/engine/scriptconsole.cpp16
-rw-r--r--engines/sci/engine/scriptdebug.cpp10
-rw-r--r--engines/sci/engine/vm.cpp4
-rw-r--r--engines/sci/include/engine.h3
-rw-r--r--engines/sci/include/script.h2
-rw-r--r--engines/sci/include/vocabulary.h12
-rw-r--r--engines/sci/scicore/script.cpp32
-rw-r--r--engines/sci/scicore/vocab_debug.cpp56
12 files changed, 55 insertions, 106 deletions
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 1afc2ffe51..9c5a23ed2e 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -59,14 +59,11 @@ static int _init_vocabulary(EngineState *s) { // initialize vocabulary and relat
s->opcodes = vocabulary_get_opcodes(s->resmgr);
- if (!(s->selector_names = vocabulary_get_snames(s->resmgr, NULL, s->version))) {
+ if (!vocabulary_get_snames(s->resmgr, s->version, s->_selectorNames)) {
sciprintf("_init_vocabulary(): Could not retrieve selector names (vocab.997)!\n");
return 1;
}
- for (s->selector_names_nr = 0; s->selector_names[s->selector_names_nr]; s->selector_names_nr++);
- // Counts the number of selector names
-
script_map_selectors(s, &(s->selector_map));
// Maps a few special selectors for later use
@@ -85,12 +82,11 @@ static void _free_vocabulary(EngineState *s) {
vocab_free_rule_list(s->parser_rules);
}
- vocabulary_free_snames(s->selector_names);
+ s->_selectorNames.clear();
vocabulary_free_knames(s->kernel_names);
vocabulary_free_opcodes(s->opcodes);
s->opcodes = NULL;
- s->selector_names = NULL;
s->kernel_names = NULL;
s->opcodes = NULL;
}
@@ -586,8 +582,6 @@ EngineState::EngineState() {
seg_manager = 0;
gc_countdown = 0;
- selector_names_nr = 0;
- selector_names = 0;
kernel_names_nr = 0;
kernel_names = 0;
@@ -781,7 +775,7 @@ int game_init(EngineState *s) {
srand(g_system->getMillis()); // Initialize random number generator
-// script_dissect(0, s->selector_names, s->selector_names_nr);
+// script_dissect(0, s->_selectorNames);
game_obj = script_lookup_export(s, 0, 0);
// The first entry in the export table of script 0 points to the game object
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index e231a213da..ce1ffec63b 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -41,7 +41,7 @@ reg_t read_selector(EngineState *s, reg_t object, selector_t selector_id, const
void write_selector(EngineState *s, reg_t object, selector_t selector_id, reg_t value, const char *fname, int line) {
reg_t *address;
- if ((selector_id < 0) || (selector_id > s->selector_names_nr)) {
+ if ((selector_id < 0) || (selector_id > (int)s->_selectorNames.size())) {
warning("Attempt to write to invalid selector %d of"
" object at "PREG" (%s L%d).", selector_id, PRINT_REG(object), fname, line);
return;
@@ -49,7 +49,7 @@ void write_selector(EngineState *s, reg_t object, selector_t selector_id, reg_t
if (lookup_selector(s, object, selector_id, &address, NULL) != SELECTOR_VARIABLE)
warning("Selector '%s' of object at "PREG" could not be"
- " written to (%s L%d)", s->selector_names[selector_id], PRINT_REG(object), fname, line);
+ " written to (%s L%d)", s->_selectorNames[selector_id].c_str(), PRINT_REG(object), fname, line);
else
*address = value;
}
@@ -72,7 +72,7 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, int noinvalid
if (slc_type == SELECTOR_NONE) {
SCIkwarn(SCIkERROR, "Selector '%s' of object at "PREG" could not be invoked (%s L%d)\n",
- s->selector_names[selector_id], PRINT_REG(object), fname, line);
+ s->_selectorNames[selector_id].c_str(), PRINT_REG(object), fname, line);
if (noinvalid == 0)
KERNEL_OOPS("Not recoverable: VM was halted\n");
return 1;
diff --git a/engines/sci/engine/savegame.cfsml b/engines/sci/engine/savegame.cfsml
index 274b1a63db..8475bbd279 100644
--- a/engines/sci/engine/savegame.cfsml
+++ b/engines/sci/engine/savegame.cfsml
@@ -1124,8 +1124,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->parser_branches = s->parser_branches;
// static VM/Kernel information:
- retval->selector_names_nr = s->selector_names_nr;
- retval->selector_names = s->selector_names;
+ retval->_selectorNames = s->_selectorNames;
retval->kernel_names_nr = s->kernel_names_nr;
retval->kernel_names = s->kernel_names;
retval->kfunct_table = s->kfunct_table;
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 96526f995f..6d48bbcf96 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -5253,8 +5253,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->parser_branches = s->parser_branches;
// static VM/Kernel information:
- retval->selector_names_nr = s->selector_names_nr;
- retval->selector_names = s->selector_names;
+ retval->_selectorNames = s->_selectorNames;
retval->kernel_names_nr = s->kernel_names_nr;
retval->kernel_names = s->kernel_names;
retval->kfunct_table = s->kfunct_table;
@@ -5327,7 +5326,7 @@ bool get_savegame_metadata(Common::SeekableReadStream* stream, SavegameMetadata*
}
}
// End of auto-generated CFSML data reader code
-#line 1170 "engines/sci/engine/savegame.cfsml"
+#line 1169 "engines/sci/engine/savegame.cfsml"
if (read_eof)
return false;
diff --git a/engines/sci/engine/scriptconsole.cpp b/engines/sci/engine/scriptconsole.cpp
index c352f2ae9d..b81b2794d3 100644
--- a/engines/sci/engine/scriptconsole.cpp
+++ b/engines/sci/engine/scriptconsole.cpp
@@ -1010,28 +1010,22 @@ static int c_hexgrep(EngineState *s) {
}
static int c_selectornames(EngineState * s) {
- int namectr;
- char **snames = NULL;
- int seeker = 0;
+ Common::StringList selectorNames;
if (NULL == s) {
sciprintf("console.c: c_selectornames(): NULL passed for parameter s\n");
return -1;
}
- snames = vocabulary_get_snames(s->resmgr, &namectr, s ? s->version : 0);
-
- if (!snames) {
+ if (!vocabulary_get_snames(s->resmgr, s ? s->version : 0, selectorNames)) {
sciprintf("No selector name table found!\n");
return 1;
}
sciprintf("Selector names in numeric order:\n");
- while (snames[seeker]) {
- sciprintf("%03x: %s\n", seeker, snames[seeker]);
- seeker++;
+ for (uint seeker = 0; seeker < selectorNames.size(); seeker++) {
+ sciprintf("%03x: %s\n", seeker, selectorNames[seeker].c_str());
}
- vocabulary_free_snames(snames);
return 0;
}
@@ -1066,7 +1060,7 @@ static int c_dissectscript(EngineState * s) {
return -1;
}
- script_dissect(s->resmgr, cmd_params[0].val, s->selector_names, s->selector_names_nr);
+ script_dissect(s->resmgr, cmd_params[0].val, s->_selectorNames);
return 0;
}
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index eaa39f777c..6de049f84e 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -1173,8 +1173,8 @@ int c_stack(EngineState *s) {
}
const char *selector_name(EngineState *s, int selector) {
- if (selector >= 0 && selector < s->selector_names_nr)
- return s->selector_names[selector];
+ if (selector >= 0 && selector < (int)s->_selectorNames.size())
+ return s->_selectorNames[selector].c_str();
else
return "--INVALID--";
}
@@ -1422,7 +1422,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
if (!name)
name = "<invalid>";
- sciprintf(" %s::%s[", name, (selector > s->selector_names_nr) ? "<invalid>" : selector_name(s, selector));
+ sciprintf(" %s::%s[", name, (selector > s->_selectorNames.size()) ? "<invalid>" : selector_name(s, selector));
switch (lookup_selector(s, called_obj_addr, selector, &val_ref, &fun_ref)) {
case SELECTOR_METHOD:
@@ -1557,7 +1557,7 @@ static int c_backtrace(EngineState *s) {
case EXEC_STACK_TYPE_VARSELECTOR:
sciprintf(" %x:[%x] vs%s %s::%s (", i, call->origin, (call->argc) ? "write" : "read",
- objname, s->selector_names[call->selector]);
+ objname, s->_selectorNames[call->selector].c_str());
break;
}
@@ -2155,7 +2155,7 @@ static int c_send(EngineState *s) {
reg_t *vptr;
reg_t fptr;
- selector_id = vocabulary_lookup_sname(s->selector_names, selector_name);
+ selector_id = vocabulary_lookup_sname(s->_selectorNames, selector_name);
if (selector_id < 0) {
sciprintf("Unknown selector: \"%s\"\n", selector_name);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 29ac898abb..8669178abf 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -346,7 +346,7 @@ exec_stack_t *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, stac
breakpoint_t *bp;
char method_name [256];
- sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->selector_names [selector]);
+ sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->_selectorNames[selector].c_str());
bp = s->bp_list;
while (bp) {
@@ -365,7 +365,7 @@ exec_stack_t *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, stac
}
#ifdef VM_DEBUG_SEND
- sciprintf("Send to "PREG", selector %04x (%s):", PRINT_REG(send_obj), selector, s->selector_names[selector]);
+ sciprintf("Send to "PREG", selector %04x (%s):", PRINT_REG(send_obj), selector, s->_selectorNames[selector].c_str());
#endif // VM_DEBUG_SEND
if (++send_calls_nr == (send_calls_allocated - 1)) {
diff --git a/engines/sci/include/engine.h b/engines/sci/include/engine.h
index a7d1c49cd9..b8d8ff5b65 100644
--- a/engines/sci/include/engine.h
+++ b/engines/sci/include/engine.h
@@ -253,8 +253,7 @@ struct EngineState {
SegManager *seg_manager;
int gc_countdown; /* Number of kernel calls until next gc */
- int selector_names_nr; /* Number of selector names */
- char **selector_names; /* Zero-terminated selector name list */
+ Common::StringList _selectorNames;
int kernel_names_nr; /* Number of kernel function names */
char **kernel_names; /* List of kernel names */
diff --git a/engines/sci/include/script.h b/engines/sci/include/script.h
index eb53e1d5aa..5871eea67c 100644
--- a/engines/sci/include/script.h
+++ b/engines/sci/include/script.h
@@ -58,7 +58,7 @@ enum script_object_types {
sci_obj_localvars
};
-void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snames_nr);
+void script_dissect(ResourceManager *resmgr, int res_no, const Common::StringList &selectorNames);
/* Opcode formats as used by script.c */
enum opcode_format {
diff --git a/engines/sci/include/vocabulary.h b/engines/sci/include/vocabulary.h
index 9f9c3367bc..aac00f5319 100644
--- a/engines/sci/include/vocabulary.h
+++ b/engines/sci/include/vocabulary.h
@@ -198,17 +198,13 @@ int *vocabulary_get_classes(ResourceManager *resmgr, int *count);
int vocabulary_get_class_count(ResourceManager *resmgr);
/**
- * Returns a null terminated array of selector names.
+ * Fills the given StringList with selector names.
+ * Returns true upon success, false oterwise.
*/
-char **vocabulary_get_snames(ResourceManager *resmgr, int *pcount, sci_version_t version);
-
-/**
- * Frees the aforementioned array
- */
-void vocabulary_free_snames(char **snames_list);
+bool vocabulary_get_snames(ResourceManager *resmgr, sci_version_t version, Common::StringList &selectorNames);
/* Look up a selector name in an array, return the index */
-int vocabulary_lookup_sname(char **snames_list, char *sname);
+int vocabulary_lookup_sname(const Common::StringList &selectorNames, const char *sname);
/**
diff --git a/engines/sci/scicore/script.cpp b/engines/sci/scicore/script.cpp
index e0907b32c3..8f8aee23bd 100644
--- a/engines/sci/scicore/script.cpp
+++ b/engines/sci/scicore/script.cpp
@@ -108,11 +108,10 @@ void script_adjust_opcode_formats(int res_version) {
}
int script_find_selector(EngineState *s, const char *selectorname) {
- int i;
-
- for (i = 0; i < s->selector_names_nr; i++)
- if (strcmp(selectorname, s->selector_names[i]) == 0)
- return i;
+ for (uint pos = 0; pos < s->_selectorNames.size(); ++pos) {
+ if (s->_selectorNames[pos] == selectorname)
+ return pos;
+ }
sciprintf("Warning: Could not map '%s' to any selector!\n", selectorname);
@@ -237,7 +236,7 @@ int sci_hexdump(byte *data, int length, int offsetplus) {
return 0;
}
-static void script_dump_object(char *data, int seeker, int objsize, char **snames, int snames_nr) {
+static void script_dump_object(char *data, int seeker, int objsize, const Common::StringList &selectorNames) {
int selectors, overloads, selectorsize;
int species = getInt16((unsigned char *) data + 8 + seeker);
int superclass = getInt16((unsigned char *) data + 10 + seeker);
@@ -273,14 +272,14 @@ static void script_dump_object(char *data, int seeker, int objsize, char **sname
while (overloads--) {
int selector = getInt16((unsigned char *) data + (seeker));
- sciprintf(" [%03x] %s: @", selector & 0xffff, (snames && selector >= 0 && selector < snames_nr) ? snames[selector] : "<?>");
+ sciprintf(" [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)selectorNames.size()) ? selectorNames[selector].c_str() : "<?>");
sciprintf("%04x\n", getInt16((unsigned char *)data + seeker + selectors*2 + 2) & 0xffff);
seeker += 2;
}
}
-static void script_dump_class(char *data, int seeker, int objsize, char **snames, int snames_nr) {
+static void script_dump_class(char *data, int seeker, int objsize, const Common::StringList &selectorNames) {
int selectors, overloads, selectorsize;
int species = getInt16((unsigned char *) data + 8 + seeker);
int superclass = getInt16((unsigned char *) data + 10 + seeker);
@@ -304,7 +303,7 @@ static void script_dump_class(char *data, int seeker, int objsize, char **snames
while (selectors--) {
int selector = getInt16((unsigned char *) data + (seeker) + selectorsize);
- sciprintf(" [%03x] %s = 0x%x\n", 0xffff & selector, (snames && selector >= 0 && selector < snames_nr) ? snames[selector] : "<?>",
+ sciprintf(" [%03x] %s = 0x%x\n", 0xffff & selector, (selector >= 0 && selector < (int)selectorNames.size()) ? selectorNames[selector].c_str() : "<?>",
getInt16((unsigned char *)data + seeker) & 0xffff);
seeker += 2;
@@ -318,16 +317,16 @@ static void script_dump_class(char *data, int seeker, int objsize, char **snames
while (overloads--) {
int selector = getInt16((unsigned char *)data + (seeker));
- fprintf(stderr, "selector=%d; snames_nr =%d\n", selector, snames_nr);
- sciprintf(" [%03x] %s: @", selector & 0xffff, (snames && selector >= 0 && selector < snames_nr) ?
- snames[selector] : "<?>");
+ fprintf(stderr, "selector=%d; selectorNames.size() =%d\n", selector, selectorNames.size());
+ sciprintf(" [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)selectorNames.size()) ?
+ selectorNames[selector].c_str() : "<?>");
sciprintf("%04x\n", getInt16((unsigned char *)data + seeker + selectors * 2 + 2) & 0xffff);
seeker += 2;
}
}
-void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snames_nr) {
+void script_dissect(ResourceManager *resmgr, int res_no, const Common::StringList &selectorNames) {
int objectctr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int _seeker = 0;
resource_t *script = scir_find_resource(resmgr, sci_script, res_no, 0);
@@ -350,7 +349,6 @@ void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snam
sciprintf("End of script object (#0) encountered.\n");
sciprintf("Classes: %i, Objects: %i, Export: %i,\n Var: %i (all base 10)",
objectctr[6], objectctr[1], objectctr[7], objectctr[10]);
- //vocabulary_free_snames(snames);
vocab_free_words(words, word_count);
return;
}
@@ -367,7 +365,7 @@ void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snam
switch (objtype) {
case sci_obj_object:
- script_dump_object((char *)script->data, seeker, objsize, snames, snames_nr);
+ script_dump_object((char *)script->data, seeker, objsize, selectorNames);
break;
case sci_obj_code: {
@@ -444,7 +442,7 @@ void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snam
break;
case sci_obj_class:
- script_dump_class((char *)script->data, seeker, objsize, snames, snames_nr);
+ script_dump_class((char *)script->data, seeker, objsize, selectorNames);
break;
case sci_obj_exports: {
@@ -479,8 +477,6 @@ void script_dissect(ResourceManager *resmgr, int res_no, char **snames, int snam
}
sciprintf("Script ends without terminator\n");
-
- //vocabulary_free_snames(snames);
}
} // End of namespace Sci
diff --git a/engines/sci/scicore/vocab_debug.cpp b/engines/sci/scicore/vocab_debug.cpp
index 90ab18a79a..81b8a19928 100644
--- a/engines/sci/scicore/vocab_debug.cpp
+++ b/engines/sci/scicore/vocab_debug.cpp
@@ -180,69 +180,41 @@ int vocabulary_get_class_count(ResourceManager *resmgr) {
return r->size / 4;
}
-char** vocabulary_get_snames(ResourceManager *resmgr, int* pcount, sci_version_t version) {
- char** t;
+bool vocabulary_get_snames(ResourceManager *resmgr, sci_version_t version, Common::StringList &selectorNames) {
int count;
- int i, j;
- int magic;
- resource_t* r = scir_find_resource(resmgr, sci_vocab, 997, 0);
+ resource_t *r = scir_find_resource(resmgr, sci_vocab, 997, 0);
if (!r) // No such resource?
- return NULL;
+ return false;
count = getInt(r->data) + 1; // Counter is slightly off
- magic = ((version == 0) || (version >= SCI_VERSION_FTU_NEW_SCRIPT_HEADER)) ? 1 : 2;
-
- t = (char **)sci_malloc(sizeof(char*) * magic * (count + 1));
-
- j = 0;
-
- for (i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
int offset = getInt(r->data + 2 + i * 2);
int len = getInt(r->data + offset);
- t[j] = (char *)sci_malloc(len + 1);
- memcpy(t[j], r->data + offset + 2, len);
- t[j][len] = '\0';
- j++;
+
+ Common::String tmp((const char *)r->data + offset + 2, len);
+ selectorNames.push_back(tmp);
if ((version != 0) && (version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER)) {
- t[j] = (char *)sci_malloc(len + 1);
- memcpy(t[j], r->data + offset + 2, len);
- t[j][len] = '\0';
- j++;
+ // Early SCI versions used the LSB in the selector ID as a read/write
+ // toggle. To compensate for that, we add every selector name twice.
+ selectorNames.push_back(tmp);
}
}
- t[j] = 0;
-
- if (pcount != NULL)
- *pcount = magic * count;
-
- return t;
+ return true;
}
-int vocabulary_lookup_sname(char **snames_list, char *sname) {
- int pos = 0;
-
- while (snames_list[pos]) {
- if (!scumm_stricmp(sname, snames_list[pos]))
+int vocabulary_lookup_sname(const Common::StringList &selectorNames, const char *sname) {
+ for (uint pos = 0; pos < selectorNames.size(); ++pos) {
+ if (selectorNames[pos] == sname)
return pos;
- pos++;
}
return -1;
}
-void vocabulary_free_snames(char **snames_list) {
- int pos = 0;
-
- while (snames_list[pos])
- free(snames_list[pos++]);
-
- free(snames_list);
-}
-
opcode* vocabulary_get_opcodes(ResourceManager *resmgr) {
opcode* o;
int count, i = 0;