diff options
author | Filippos Karapetis | 2009-05-31 14:55:32 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-05-31 14:55:32 +0000 |
commit | 4441ca4b3e39ed1613c826f7b46b1e7076fcbe14 (patch) | |
tree | b540763429cefd43f33d209fd3a2a2a8e5307bda /engines/sci | |
parent | be224386484793c519840cff0b752e9fd2a430b1 (diff) | |
download | scummvm-rg350-4441ca4b3e39ed1613c826f7b46b1e7076fcbe14.tar.gz scummvm-rg350-4441ca4b3e39ed1613c826f7b46b1e7076fcbe14.tar.bz2 scummvm-rg350-4441ca4b3e39ed1613c826f7b46b1e7076fcbe14.zip |
- Further objectification of the SCI vocabulary functions
- Rewrote the sci_opcodes enum so that it's easier to read
- Made the engine error out if data is sent to an invalid selector (which is a fatal condition)
svn-id: r41069
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/console.cpp | 16 | ||||
-rw-r--r-- | engines/sci/engine/kernel.cpp | 17 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/script.cpp | 41 | ||||
-rw-r--r-- | engines/sci/engine/script.h | 260 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 22 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 16 | ||||
-rw-r--r-- | engines/sci/vocabulary.cpp | 29 | ||||
-rw-r--r-- | engines/sci/vocabulary.h | 52 |
12 files changed, 251 insertions, 220 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 96f000d9c0..0ac71d3fb8 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -134,8 +134,8 @@ bool Console::cmdGetVersion(int argc, const char **argv) { bool Console::cmdOpcodes(int argc, const char **argv) { DebugPrintf("Opcode names in numeric order [index: type name]:\n"); - for (uint seeker = 0; seeker < g_EngineState->_vocabulary->_opcodes.size(); seeker++) { - opcode &op = g_EngineState->_vocabulary->_opcodes[seeker]; + for (uint seeker = 0; seeker < g_EngineState->_vocabulary->getOpcodesSize(); seeker++) { + opcode op = g_EngineState->_vocabulary->getOpcode(seeker); DebugPrintf("%03x: %03x %20s | ", seeker, op.type, op.name.c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); @@ -148,8 +148,8 @@ bool Console::cmdOpcodes(int argc, const char **argv) { bool Console::cmdSelectors(int argc, const char **argv) { DebugPrintf("Selector names in numeric order:\n"); - for (uint seeker = 0; seeker < g_EngineState->_vocabulary->_selectorNames.size(); seeker++) { - DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->_selectorNames[seeker].c_str()); + for (uint seeker = 0; seeker < g_EngineState->_vocabulary->getSelectorNamesSize(); seeker++) { + DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->getSelectorName(seeker).c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); } @@ -161,8 +161,8 @@ bool Console::cmdSelectors(int argc, const char **argv) { bool Console::cmdKernelNames(int argc, const char **argv) { DebugPrintf("Selector names in numeric order:\n"); - for (uint seeker = 0; seeker < g_EngineState->_vocabulary->_kernelNames.size(); seeker++) { - DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->_kernelNames[seeker].c_str()); + for (uint seeker = 0; seeker < g_EngineState->_vocabulary->getKernelNamesSize(); seeker++) { + DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->getKernelName(seeker).c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); } @@ -215,15 +215,13 @@ bool Console::cmdHexDump(int argc, const char **argv) { } bool Console::cmdDissectScript(int argc, const char **argv) { - Common::StringList selectorNames; - if (argc != 2) { DebugPrintf("Examines a script\n"); DebugPrintf("Usage: %s <script number>\n", argv[0]); return true; } - script_dissect(_vm->getResMgr(), atoi(argv[1]), g_EngineState->_vocabulary); + g_EngineState->_vocabulary->dissectScript(atoi(argv[1])); return true; } diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index b205a706e1..54df45b47f 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -502,13 +502,6 @@ reg_t kalloc(EngineState *s, const char *type, int space) { return reg; } -bool has_kernel_function(EngineState *s, const char *kname) { - Common::StringList::const_iterator it - = Common::find(s->_vocabulary->_kernelNames.begin(), s->_vocabulary->_kernelNames.end(), kname); - - return (it != s->_vocabulary->_kernelNames.end()); -} - // Returns a pointer to the memory indicated by the specified handle byte *kmem(EngineState *s, reg_t handle) { HunkTable *ht = (HunkTable *)GET_SEGMENT(*s->seg_manager, handle.segment, MEM_OBJ_HUNK); @@ -610,7 +603,7 @@ void kernel_compile_signature(const char **s) { int script_map_kernel(EngineState *s) { int mapped = 0; int ignored = 0; - uint functions_nr = s->_vocabulary->_kernelNames.size(); + uint functions_nr = s->_vocabulary->getKernelNamesSize(); uint max_functions_nr = sci_max_allowed_unknown_kernel_functions[s->resmgr->_sciVersion]; if (functions_nr < max_functions_nr) { @@ -627,8 +620,8 @@ int script_map_kernel(EngineState *s) { int seeker, found = -1; Common::String sought_name; - if (functnr < s->_vocabulary->_kernelNames.size()) - sought_name = s->_vocabulary->_kernelNames[functnr]; + if (functnr < s->_vocabulary->getKernelNamesSize()) + sought_name = s->_vocabulary->getKernelName(functnr); if (!sought_name.empty()) for (seeker = 0; (found == -1) && kfunct_mappers[seeker].type != KF_TERMINATOR; seeker++) @@ -637,7 +630,7 @@ int script_map_kernel(EngineState *s) { if (found == -1) { if (!sought_name.empty()) { - warning("Kernel function %s[%x] unmapped", s->_vocabulary->_kernelNames[functnr].c_str(), functnr); + warning("Kernel function %s[%x] unmapped", s->_vocabulary->getKernelName(functnr).c_str(), functnr); s->_kfuncTable[functnr].fun = kNOP; } else { warning("Flagging kernel function %x as unknown", functnr); @@ -667,7 +660,7 @@ int script_map_kernel(EngineState *s) { } // for all functions requesting to be mapped - sciprintf("Handled %d/%d kernel functions, mapping %d", mapped + ignored, s->_vocabulary->_kernelNames.size(), mapped); + sciprintf("Handled %d/%d kernel functions, mapping %d", mapped + ignored, s->_vocabulary->getKernelNamesSize(), mapped); if (ignored) sciprintf(" and ignoring %d", ignored); sciprintf(".\n"); diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 6c3447e21b..839dbc5b46 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -238,7 +238,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kstub(EngineState *s, int funct_nr, int argc, reg_t *argv) { - sciprintf("Unimplemented syscall: %s[%x](", s->_vocabulary->_kernelNames[funct_nr].c_str(), funct_nr); + sciprintf("Unimplemented syscall: %s[%x](", s->_vocabulary->getKernelName(funct_nr).c_str(), funct_nr); for (int i = 0; i < argc; i++) { sciprintf("%04x:%04x", PRINT_REG(argv[i])); diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index b1fc2d4816..93fbd7aa40 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -43,7 +43,7 @@ reg_t read_selector(EngineState *s, reg_t object, Selector selector_id, const ch void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t value, const char *fname, int line) { reg_t *address; - if ((selector_id < 0) || (selector_id > (int)s->_vocabulary->_selectorNames.size())) { + if ((selector_id < 0) || (selector_id > (int)s->_vocabulary->getSelectorNamesSize())) { warning("Attempt to write to invalid selector %d of" " object at %04x:%04x (%s L%d).", selector_id, PRINT_REG(object), fname, line); return; @@ -51,7 +51,7 @@ void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t va if (lookup_selector(s, object, selector_id, &address, NULL) != kSelectorVariable) warning("Selector '%s' of object at %04x:%04x could not be" - " written to (%s L%d)", s->_vocabulary->_selectorNames[selector_id].c_str(), PRINT_REG(object), fname, line); + " written to (%s L%d)", s->_vocabulary->getSelectorName(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 == kSelectorNone) { error("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)", - s->_vocabulary->_selectorNames[selector_id].c_str(), PRINT_REG(object), fname, line); + s->_vocabulary->getSelectorName(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.cpp b/engines/sci/engine/savegame.cpp index a25915622b..6fa75ffa66 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -826,10 +826,8 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->_vocabulary->copyParserListsFrom(s->_vocabulary); // static VM/Kernel information: - retval->_vocabulary->_selectorNames = s->_vocabulary->_selectorNames; - retval->_vocabulary->_kernelNames = s->_vocabulary->_kernelNames; + retval->_vocabulary->copyKernelListsFrom(s->_vocabulary); retval->_kfuncTable = s->_kfuncTable; - retval->_vocabulary->_opcodes = s->_vocabulary->_opcodes; memcpy(&(retval->_vocabulary->_selectorMap), &(s->_vocabulary->_selectorMap), sizeof(selector_map_t)); diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 34e4cf05b7..a111c7e84a 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -108,21 +108,10 @@ void script_adjust_opcode_formats(int res_version) { } } -int script_find_selector(Common::StringList *selectorNames, const char *selectorname) { - for (uint pos = 0; pos < selectorNames->size(); ++pos) { - if ((*selectorNames)[pos] == selectorname) - return pos; - } - - warning("Could not map '%s' to any selector", selectorname); - - return -1; -} - -#define FIND_SELECTOR(_slc_) map->_slc_ = script_find_selector(selectorNames, #_slc_) -#define FIND_SELECTOR2(_slc_, _slcstr_) map->_slc_ = script_find_selector(selectorNames, _slcstr_) +#define FIND_SELECTOR(_slc_) _selectorMap._slc_ = findSelector(#_slc_) +#define FIND_SELECTOR2(_slc_, _slcstr_) _selectorMap._slc_ = findSelector(_slcstr_) -void script_map_selectors(Common::StringList *selectorNames, selector_map_t *map) { +void Vocabulary::mapSelectors() { FIND_SELECTOR(init); FIND_SELECTOR(play); FIND_SELECTOR(replay); @@ -213,7 +202,7 @@ void script_map_selectors(Common::StringList *selectorNames, selector_map_t *map FIND_SELECTOR(syncTime); } -static void script_dump_object(char *data, int seeker, int objsize, const Common::StringList &selectorNames) { +void Vocabulary::dumpScriptObject(char *data, int seeker, int objsize) { int selectors, overloads, selectorsize; int species = (int16)READ_LE_UINT16((unsigned char *) data + 8 + seeker); int superclass = (int16)READ_LE_UINT16((unsigned char *) data + 10 + seeker); @@ -249,14 +238,14 @@ static void script_dump_object(char *data, int seeker, int objsize, const Common while (overloads--) { int selector = (int16)READ_LE_UINT16((unsigned char *) data + (seeker)); - sciprintf(" [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)selectorNames.size()) ? selectorNames[selector].c_str() : "<?>"); + sciprintf(" [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)_selectorNames.size()) ? _selectorNames[selector].c_str() : "<?>"); sciprintf("%04x\n", (int16)READ_LE_UINT16((unsigned char *)data + seeker + selectors*2 + 2) & 0xffff); seeker += 2; } } -static void script_dump_class(char *data, int seeker, int objsize, const Common::StringList &selectorNames) { +void Vocabulary::dumpScriptClass(char *data, int seeker, int objsize) { int selectors, overloads, selectorsize; int species = (int16)READ_LE_UINT16((unsigned char *) data + 8 + seeker); int superclass = (int16)READ_LE_UINT16((unsigned char *) data + 10 + seeker); @@ -280,7 +269,7 @@ static void script_dump_class(char *data, int seeker, int objsize, const Common: while (selectors--) { int selector = (int16)READ_LE_UINT16((unsigned char *) data + (seeker) + selectorsize); - sciprintf(" [%03x] %s = 0x%x\n", 0xffff & selector, (selector >= 0 && selector < (int)selectorNames.size()) ? selectorNames[selector].c_str() : "<?>", + sciprintf(" [%03x] %s = 0x%x\n", 0xffff & selector, (selector >= 0 && selector < (int)_selectorNames.size()) ? _selectorNames[selector].c_str() : "<?>", (int16)READ_LE_UINT16((unsigned char *)data + seeker) & 0xffff); seeker += 2; @@ -294,19 +283,19 @@ static void script_dump_class(char *data, int seeker, int objsize, const Common: while (overloads--) { int selector = (int16)READ_LE_UINT16((unsigned char *)data + (seeker)); - 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() : "<?>"); + 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", (int16)READ_LE_UINT16((unsigned char *)data + seeker + selectors * 2 + 2) & 0xffff); seeker += 2; } } -void script_dissect(ResourceManager *resmgr, int res_no, Vocabulary *vocab) { +void Vocabulary::dissectScript(int scriptNumber) { int objectctr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int _seeker = 0; - Resource *script = resmgr->findResource(kResourceTypeScript, res_no, 0); + Resource *script = _resmgr->findResource(kResourceTypeScript, scriptNumber, 0); if (!script) { sciprintf("Script not found!\n"); @@ -337,7 +326,7 @@ void script_dissect(ResourceManager *resmgr, int res_no, Vocabulary *vocab) { switch (objtype) { case SCI_OBJ_OBJECT: - script_dump_object((char *)script->data, seeker, objsize, vocab->_selectorNames); + dumpScriptObject((char *)script->data, seeker, objsize); break; case SCI_OBJ_CODE: { @@ -396,7 +385,7 @@ void script_dissect(ResourceManager *resmgr, int res_no, Vocabulary *vocab) { } } else { nextitem = nextitem << 8 | script->data [seeker++]; - sciprintf("%s[%03x] ", vocab->getAnyWordFromGroup(nextitem), nextitem); + sciprintf("%s[%03x] ", getAnyWordFromGroup(nextitem), nextitem); } } sciprintf("\n"); @@ -414,7 +403,7 @@ void script_dissect(ResourceManager *resmgr, int res_no, Vocabulary *vocab) { break; case SCI_OBJ_CLASS: - script_dump_class((char *)script->data, seeker, objsize, vocab->_selectorNames); + dumpScriptClass((char *)script->data, seeker, objsize); break; case SCI_OBJ_EXPORTS: { diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index ab7ba7af80..5b8dbe1869 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -51,8 +51,6 @@ enum ScriptObjectTypes { SCI_OBJ_LOCALVARS }; -void script_dissect(ResourceManager *resmgr, int res_no, Vocabulary *vocab); - /* Opcode formats as used by script.c */ enum opcode_format { Script_Invalid = -1, @@ -74,142 +72,140 @@ enum opcode_format { }; enum sci_opcodes { /* FIXME */ - op_bnot = 0, - op_add, - op_sub, - op_mul, - op_div, - op_mod, - op_shr, - op_shl, - op_xor, - op_and, - op_or, - op_neg, - op_not, - op_eq, - op_ne_, - op_gt_, - op_ge_, - op_lt_, - op_le_, - op_ugt_, - op_uge_, - op_ult_, - op_ule_, - op_bt, - op_bnt, - op_jmp, - op_ldi, - op_push, - op_pushi, - op_toss, - op_dup, - op_link, - op_call = 0x20, - op_callk, - op_callb, - op_calle, - op_ret, - op_send, - op_class = 0x28, - op_self = 0x2a, - op_super, - op_rest, - op_lea, - op_selfID, - op_pprev = 0x30, - op_pToa, - op_aTop, - op_pTos, - op_sTop, - op_ipToa, - op_dpToa, - op_ipTos, - op_dpTos, - op_lofsa, - op_lofss, - op_push0, - op_push1, - op_push2, - op_pushSelf, - op_lag = 0x40, - op_lal, - op_lat, - op_lap, - op_lagi, - op_lali, - op_lati, - op_lapi, - op_lsg, - op_lsl, - op_lst, - op_lsp, - op_lsgi, - op_lsli, - op_lsti, - op_lspi, - op_sag, - op_sal, - op_sat, - op_sap, - op_sagi, - op_sali, - op_sati, - op_sapi, - op_ssg, - op_ssl, - op_sst, - op_ssp, - op_ssgi, - op_ssli, - op_ssti, - op_sspi, - op_plusag, - op_plusal, - op_plusat, - op_plusap, - op_plusagi, - op_plusali, - op_plusati, - op_plusapi, - op_plussg, - op_plussl, - op_plusst, - op_plussp, - op_plussgi, - op_plussli, - op_plussti, - op_plusspi, - op_minusag, - op_minusal, - op_minusat, - op_minusap, - op_minusagi, - op_minusali, - op_minusati, - op_minusapi, - op_minussg, - op_minussl, - op_minusst, - op_minussp, - op_minussgi, - op_minussli, - op_minussti, - op_minusspi + op_bnot = 0x00, // 000 + op_add = 0x01, // 001 + op_sub = 0x02, // 002 + op_mul = 0x03, // 003 + op_div = 0x04, // 004 + op_mod = 0x05, // 005 + op_shr = 0x06, // 006 + op_shl = 0x07, // 007 + op_xor = 0x08, // 008 + op_and = 0x09, // 009 + op_or = 0x0a, // 010 + op_neg = 0x0b, // 011 + op_not = 0x0c, // 012 + op_eq = 0x0d, // 013 + op_ne_ = 0x0e, // 014 + op_gt_ = 0x0f, // 015 + op_ge_ = 0x10, // 016 + op_lt_ = 0x11, // 017 + op_le_ = 0x12, // 018 + op_ugt_ = 0x13, // 019 + op_uge_ = 0x14, // 020 + op_ult_ = 0x15, // 021 + op_ule_ = 0x16, // 022 + op_bt = 0x17, // 023 + op_bnt = 0x18, // 024 + op_jmp = 0x19, // 025 + op_ldi = 0x1a, // 026 + op_push = 0x1b, // 027 + op_pushi = 0x1c, // 028 + op_toss = 0x1d, // 029 + op_dup = 0x1e, // 030 + op_link = 0x1f, // 031 + op_call = 0x20, // 032 + op_callk = 0x21, // 033 + op_callb = 0x22, // 034 + op_calle = 0x23, // 035 + op_ret = 0x24, // 036 + op_send = 0x25, // 037 + // dummy 0x26, // 038 + // dummy 0x27, // 039 + op_class = 0x28, // 040 + // dummy 0x29, // 041 + op_self = 0x2a, // 042 + op_super = 0x2b, // 043 + op_rest = 0x2c, // 044 + op_lea = 0x2d, // 045 + op_selfID = 0x2e, // 046 + // dummy 0x2f // 047 + op_pprev = 0x30, // 048 + op_pToa = 0x31, // 049 + op_aTop = 0x32, // 050 + op_pTos = 0x33, // 051 + op_sTop = 0x34, // 052 + op_ipToa = 0x35, // 053 + op_dpToa = 0x36, // 054 + op_ipTos = 0x37, // 055 + op_dpTos = 0x38, // 056 + op_lofsa = 0x39, // 057 + op_lofss = 0x3a, // 058 + op_push0 = 0x3b, // 059 + op_push1 = 0x3c, // 060 + op_push2 = 0x3d, // 061 + op_pushSelf = 0x3e, // 062 + // dummy 0x3f, // 063 + op_lag = 0x40, // 064 + op_lal = 0x41, // 065 + op_lat = 0x42, // 066 + op_lap = 0x43, // 067 + op_lagi = 0x44, // 068 + op_lali = 0x45, // 069 + op_lati = 0x46, // 070 + op_lapi = 0x47, // 071 + op_lsg = 0x48, // 072 + op_lsl = 0x49, // 073 + op_lst = 0x4a, // 074 + op_lsp = 0x4b, // 075 + op_lsgi = 0x4c, // 076 + op_lsli = 0x4d, // 077 + op_lsti = 0x4e, // 078 + op_lspi = 0x4f, // 079 + op_sag = 0x50, // 080 + op_sal = 0x51, // 081 + op_sat = 0x52, // 082 + op_sap = 0x53, // 083 + op_sagi = 0x54, // 084 + op_sali = 0x55, // 085 + op_sati = 0x56, // 086 + op_sapi = 0x57, // 087 + op_ssg = 0x58, // 088 + op_ssl = 0x59, // 089 + op_sst = 0x5a, // 090 + op_ssp = 0x5b, // 091 + op_ssgi = 0x5c, // 092 + op_ssli = 0x5d, // 093 + op_ssti = 0x5e, // 094 + op_sspi = 0x5f, // 095 + op_plusag = 0x60, // 096 + op_plusal = 0x61, // 097 + op_plusat = 0x62, // 098 + op_plusap = 0x63, // 099 + op_plusagi = 0x64, // 100 + op_plusali = 0x65, // 101 + op_plusati = 0x66, // 102 + op_plusapi = 0x67, // 103 + op_plussg = 0x68, // 104 + op_plussl = 0x69, // 105 + op_plusst = 0x6a, // 106 + op_plussp = 0x6b, // 107 + op_plussgi = 0x6c, // 108 + op_plussli = 0x6d, // 109 + op_plussti = 0x6e, // 110 + op_plusspi = 0x6f, // 111 + op_minusag = 0x70, // 112 + op_minusal = 0x71, // 113 + op_minusat = 0x72, // 114 + op_minusap = 0x73, // 115 + op_minusagi = 0x74, // 116 + op_minusali = 0x75, // 117 + op_minusati = 0x76, // 118 + op_minusapi = 0x77, // 119 + op_minussg = 0x78, // 120 + op_minussl = 0x79, // 121 + op_minusst = 0x7a, // 122 + op_minussp = 0x7b, // 123 + op_minussgi = 0x7c, // 124 + op_minussli = 0x7d, // 125 + op_minussti = 0x7e, // 126 + op_minusspi = 0x7f // 127 }; extern opcode_format g_opcode_formats[128][4]; void script_adjust_opcode_formats(int res_version); -int script_find_selector(Common::StringList *selectorNames, const char *selector_name); -/* Determines the selector ID of a selector by its name -** Parameters: (state_t *) s: VM state -** (char *) selector_name: Name of the selector to look up -** Returns : (int) The appropriate selector ID, or -1 on error -*/ - void script_free_breakpoints(EngineState *s); } // End of namespace Sci diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 68808ee14b..ecbcc680aa 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -699,8 +699,8 @@ int c_stack(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { } const char *selector_name(EngineState *s, int selector) { - if (selector >= 0 && selector < (int)s->_vocabulary->_selectorNames.size()) - return s->_vocabulary->_selectorNames[selector].c_str(); + if (selector >= 0 && selector < (int)s->_vocabulary->getSelectorNamesSize()) + return s->_vocabulary->getSelectorName(selector).c_str(); else return "--INVALID--"; } @@ -822,7 +822,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if (print_bw_tag) sciprintf("[%c] ", opsize ? 'B' : 'W'); - sciprintf("%s", opcode < s->_vocabulary->_opcodes.size() ? s->_vocabulary->_opcodes[opcode].name.c_str() : "undefined"); + sciprintf("%s", s->_vocabulary->getOpcode(opcode).name.c_str()); i = 0; while (g_opcode_formats[opcode][i]) { @@ -858,7 +858,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if (opcode == op_callk) sciprintf(" %s[%x]", (param_value < s->_kfuncTable.size()) ? - ((param_value < s->_vocabulary->_kernelNames.size()) ? s->_vocabulary->_kernelNames[param_value].c_str() : "[Unknown(postulated)]") + ((param_value < s->_vocabulary->getKernelNamesSize()) ? s->_vocabulary->getKernelName(param_value).c_str() : "[Unknown(postulated)]") : "<invalid>", param_value); else sciprintf(opsize ? " %02x" : " %04x", param_value); @@ -948,7 +948,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->_vocabulary->_selectorNames.size()) ? "<invalid>" : selector_name(s, selector)); + sciprintf(" %s::%s[", name, (selector > s->_vocabulary->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector)); switch (lookup_selector(s, called_obj_addr, selector, &val_ref, &fun_ref)) { case kSelectorMethod: @@ -1058,12 +1058,12 @@ static int c_backtrace(EngineState *s, const Common::Array<cmd_param_t> &cmdPara break; case EXEC_STACK_TYPE_KERNEL: // Kernel function - sciprintf(" %x:[%x] k%s(", i, call.origin, s->_vocabulary->_kernelNames[-(call.selector)-42].c_str()); + sciprintf(" %x:[%x] k%s(", i, call.origin, s->_vocabulary->getKernelName(-(call.selector) - 42).c_str()); break; case EXEC_STACK_TYPE_VARSELECTOR: sciprintf(" %x:[%x] vs%s %s::%s (", i, call.origin, (call.argc) ? "write" : "read", - objname,s->_vocabulary->_selectorNames[call.selector].c_str()); + objname,s->_vocabulary->getSelectorName(call.selector).c_str()); break; } @@ -1318,7 +1318,7 @@ static int c_disasm_addr(EngineState *s, const Common::Array<cmd_param_t> &cmdPa static int c_disasm(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { Object *obj = obj_get(s, cmdParams[0].reg); - int selector_id = script_find_selector(&s->_vocabulary->_selectorNames, cmdParams[1].str); + int selector_id = s->_vocabulary->findSelector(cmdParams[1].str); reg_t addr; if (!obj) { @@ -1367,8 +1367,8 @@ static int c_snk(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { callk_index = strtoul(cmdParams [0].str, &endptr, 0); if (*endptr != '\0') { callk_index = -1; - for (uint i = 0; i < s->_vocabulary->_kernelNames.size(); i++) - if (cmdParams [0].str == s->_vocabulary->_kernelNames[i]) { + for (uint i = 0; i < s->_vocabulary->getKernelNamesSize(); i++) + if (cmdParams [0].str == s->_vocabulary->getKernelName(i)) { callk_index = i; break; } @@ -1420,7 +1420,7 @@ static int c_send(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { reg_t *vptr; reg_t fptr; - selector_id = script_find_selector(&s->_vocabulary->_selectorNames, selector_name); + selector_id = s->_vocabulary->findSelector(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 e47993cfea..c146eaefbf 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -322,7 +322,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt Breakpoint *bp; char method_name [256]; - sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->_vocabulary->_selectorNames[selector].c_str()); + sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->_vocabulary->getSelectorName(selector).c_str()); bp = s->bp_list; while (bp) { @@ -346,8 +346,6 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt switch (lookup_selector(s, send_obj, selector, &varp, &funcp)) { case kSelectorNone: - sciprintf("Send to invalid selector 0x%x of object at %04x:%04x\n", 0xffff & selector, PRINT_REG(send_obj)); - // WORKAROUND: LSL6 tries to access the invalid 'keep' selector of the game object. // FIXME: Find out if this is a game bug. if ((s->_gameName == "LSL6") && (selector == 0x18c)) { @@ -357,6 +355,8 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt script_error_flag = script_debug_flag = 1; + error("Send to invalid selector 0x%x of object at %04x:%04x\n", 0xffff & selector, PRINT_REG(send_obj)); + break; case kSelectorVariable: diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index b4a2de4d23..bf649bcc05 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -1076,14 +1076,6 @@ void quit_vm(); ** Returns : (void) */ -void script_map_selectors(Common::StringList *selectorNames, selector_map_t *map); -/* Maps special selectors -** Parameters: (Common::StringList *) selectorNames: The selector information -** (selector_map_t *) map: Pointer to the selector map to map -** Returns : (void) -** Called by script_run(); -*/ - int script_map_kernel(EngineState *s); /* Maps kernel functions ** Parameters: (EngineState *) s: The state which the _kernelNames are retrieved from @@ -1099,14 +1091,6 @@ reg_t kalloc(EngineState *s, const char *type, int space); ** Returns : (reg_t) The handle */ -bool has_kernel_function(EngineState *s, const char *kname); -/* Detects whether a particular kernel function is required in the game -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (const char *) kname: The name of the desired kernel function -** Returns : (bool) 1 if the kernel function is listed in the kernel table, -** 0 otherwise -*/ - byte *kmem(EngineState *s, reg_t handle); /* Returns a pointer to "kernel" memory based on the handle ** Parameters: (EngineState *) s: Pointer to the EngineState to operate on diff --git a/engines/sci/vocabulary.cpp b/engines/sci/vocabulary.cpp index 6f3a13b6de..01d237a780 100644 --- a/engines/sci/vocabulary.cpp +++ b/engines/sci/vocabulary.cpp @@ -109,7 +109,7 @@ Vocabulary::Vocabulary(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr } // Map a few special selectors for later use - script_map_selectors(&_selectorNames, &_selectorMap); + mapSelectors(); getKernelNames(); } @@ -548,6 +548,33 @@ void Vocabulary::copyParserListsTo(SuffixList &parserSuffixes, parse_rule_list_t parserWords = _parserWords; } +void Vocabulary::copyKernelListsFrom(Vocabulary *voc) { + voc->copyKernelListsTo(_opcodes, _selectorNames, _kernelNames); +} + +void Vocabulary::copyKernelListsTo(Common::Array<opcode> &opcodes, Common::StringList &selectorNames, + Common::StringList &kernelNames) { + _opcodes = opcodes; + _selectorNames = selectorNames; + _kernelNames = kernelNames; +} + +int Vocabulary::findSelector(const char *selectorName) { + for (uint pos = 0; pos < _selectorNames.size(); ++pos) { + if (_selectorNames[pos] == selectorName) + return pos; + } + + warning("Could not map '%s' to any selector", selectorName); + + return -1; +} + +bool Vocabulary::hasKernelFunction(const char *functionName) { + Common::StringList::const_iterator it = Common::find(_kernelNames.begin(), _kernelNames.end(), functionName); + return (it != _kernelNames.end()); +} + void _vocab_recursive_ptree_dump_treelike(parse_tree_node_t *nodes, int nr, int prevnr) { if ((nr > VOCAB_TREE_NODES)/* || (nr < prevnr)*/) { sciprintf("Error(%04x)", nr); diff --git a/engines/sci/vocabulary.h b/engines/sci/vocabulary.h index 153317185f..f1b2ef867b 100644 --- a/engines/sci/vocabulary.h +++ b/engines/sci/vocabulary.h @@ -267,12 +267,46 @@ public: void copyParserListsTo(SuffixList &parserSuffixes, parse_rule_list_t &parserRules, Common::Array<parse_tree_branch_t> &parserBranches, WordMap &parserWords); + /** + * Copies the kernel lists from another vocabulary + */ + void copyKernelListsFrom(Vocabulary *voc); + + /** + * Gets the internal kernel lists, for vocabulary copying + */ + void copyKernelListsTo(Common::Array<opcode> &opcodes, Common::StringList &selectorNames, + Common::StringList &kernelNames); + uint getParserBranchesSize() { return _parserBranches.size(); } parse_tree_branch_t getParseTreeBranch(int number) { return _parserBranches[number]; } - Common::StringList _selectorNames; - Common::Array<opcode> _opcodes; - Common::StringList _kernelNames; + uint getOpcodesSize() { return _opcodes.size(); } + opcode getOpcode(uint opcode) { return _opcodes[opcode]; } + + uint getSelectorNamesSize() { return _selectorNames.size(); } + Common::String getSelectorName(uint selector) { return _selectorNames[selector]; } + + /* Determines the selector ID of a selector by its name + ** (const char *) selectorName: Name of the selector to look up + ** Returns : (int) The appropriate selector ID, or -1 on error + */ + int findSelector(const char *selectorName); + + /* Detects whether a particular kernel function is required in the game + ** (const char *) functionName: The name of the desired kernel function + ** Returns : (bool) true if the kernel function is listed in the kernel table, + ** false otherwise + */ + bool hasKernelFunction(const char *functionName); + + uint getKernelNamesSize() { return _kernelNames.size(); } + Common::String getKernelName(uint number) { return _kernelNames[number]; } + + // Script dissection/dumping functions + void dissectScript(int scriptNumber); + void dumpScriptObject(char *data, int seeker, int objsize); + void dumpScriptClass(char *data, int seeker, int objsize); selector_map_t _selectorMap; /**< Shortcut list for important selectors */ @@ -283,6 +317,11 @@ private: */ bool getSelectorNames(); + /* Maps special selectors + ** Returns : (void) + */ + void mapSelectors(); + /** * Fills the given Array with opcodes. * @return true on success, false on failure @@ -334,6 +373,13 @@ private: bool _isOldSci0; VocabularyVersions _vocabVersion; + // Kernel-related lists + // List of opcodes, loaded from vocab.998. This list is only used for debugging + // purposes, as we hardcode the list of opcodes in the sci_opcodes enum (script.h) + Common::Array<opcode> _opcodes; + Common::StringList _selectorNames; + Common::StringList _kernelNames; + // Parser-related lists SuffixList _parserSuffixes; parse_rule_list_t *_parserRules; /**< GNF rules used in the parser algorithm */ |