diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 9ba252166cd..be72cbe9e95 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -388,11 +388,27 @@ bool Console::cmdGetVersion(int argc, const char **argv) { } bool Console::cmdOpcodes(int argc, const char **argv) { + // Load the opcode table from vocab.998 if it exists, to obtain the opcode names + Resource* r = _vm->getresourceManager()->findResource(ResourceId(kResourceTypeVocab, 998), 0); + + // If the resource couldn't be loaded, leave + if (!r) { + DebugPrintf("unable to load vocab.998"); + return true; + } + + int count = READ_LE_UINT16(r->data); + DebugPrintf("Opcode names in numeric order [index: type name]:\n"); - for (uint seeker = 0; seeker < _vm->getKernel()->getOpcodesSize(); seeker++) { - opcode op = _vm->getKernel()->getOpcode(seeker); - DebugPrintf("%03x: %03x %20s | ", seeker, op.type, op.name.c_str()); - if ((seeker % 3) == 2) + + for (int i = 0; i < count; i++) { + int offset = READ_LE_UINT16(r->data + 2 + i * 2); + int len = READ_LE_UINT16(r->data + offset) - 2; + int type = READ_LE_UINT16(r->data + offset + 2); + // QFG3 has empty opcodes + Common::String name = len > 0 ? Common::String((char *)r->data + offset + 4, len) : "Dummy"; + DebugPrintf("%03x: %03x %20s | ", i, type, name.c_str()); + if ((i % 3) == 2) DebugPrintf("\n"); } diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 38eb3751929..19dfd0ada9d 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -379,7 +379,6 @@ Kernel::Kernel(ResourceManager *resourceManager) : _resourceManager(resourceMana detectSciFeatures(); mapSelectors(); // Map a few special selectors for later use - loadOpcodes(); loadKernelNames(); mapFunctions(); // Map the kernel functions } @@ -430,7 +429,7 @@ void Kernel::detectSciFeatures() { } void Kernel::loadSelectorNames() { - Resource *r = _resourceManager->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); + Resource *r = _resourceManager->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0); bool oldScriptHeader = (_resourceManager->sciVersion() == SCI_VERSION_0_EARLY); if (!r) { // No such resource? @@ -467,32 +466,6 @@ void Kernel::loadSelectorNames() { } } -bool Kernel::loadOpcodes() { - int count, i = 0; - Resource* r = _resourceManager->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES), 0); - - _opcodes.clear(); - - // if the resource couldn't be loaded, leave - if (r == NULL) { - warning("unable to load vocab.%03d", VOCAB_RESOURCE_OPCODES); - return false; - } - - count = READ_LE_UINT16(r->data); - - _opcodes.resize(count); - for (i = 0; i < count; i++) { - int offset = READ_LE_UINT16(r->data + 2 + i * 2); - int len = READ_LE_UINT16(r->data + offset) - 2; - _opcodes[i].type = READ_LE_UINT16(r->data + offset + 2); - // QFG3 has empty opcodes - _opcodes[i].name = len > 0 ? Common::String((char *)r->data + offset + 4, len) : "Dummy"; - } - - return true; -} - // Allocates a set amount of memory for a specified use and returns a handle to it. reg_t kalloc(SegManager *segManager, const char *type, int space) { reg_t reg; diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 595816579b4..a780d04cf79 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -43,11 +43,6 @@ struct List; // from vm.h #define AVOIDPATH_DYNMEM_STRING "AvoidPath polyline" //#define DEBUG_PARSER // enable for parser debugging -struct opcode { - int type; - Common::String name; -}; - /* Generic description: */ typedef reg_t KernelFunc(EngineState *s, int funct_nr, int argc, reg_t *argv); @@ -71,9 +66,6 @@ public: Kernel(ResourceManager *resourceManager); ~Kernel(); - uint getOpcodesSize() const { return _opcodes.size(); } - const opcode &getOpcode(uint opcode) const { return _opcodes[opcode]; } - uint getSelectorNamesSize() const { return _selectorNames.size(); } const Common::String &getSelectorName(uint selector) const { return _selectorNames[selector]; } @@ -173,21 +165,10 @@ private: */ void mapFunctions(); - /** - * Loads the opcode names (only used for debugging). - * @return true on success, false on failure - */ - bool loadOpcodes(); - ResourceManager *_resourceManager; uint32 features; // 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 _opcodes; Common::StringList _selectorNames; Common::StringList _kernelNames; }; diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 28e22cb56e6..6e4725d28c0 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -32,6 +32,35 @@ namespace Sci { +const char *opcodeNames[] = { + "op_bnot", "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", "op_callk", "op_callb", + "op_calle", "op_ret", "op_send", "dummy", "dummy", + "op_class", "dummy", "op_self", "op_super", "op_rest", + "op_lea", "op_selfID", "dummy", "op_pprev", "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", "dummy", "op_lag", + "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" +}; + extern const char *selector_name(EngineState *s, int selector); ScriptState scriptState; @@ -68,8 +97,8 @@ int propertyOffsetToId(SegManager *segManager, int prop_ofs, reg_t objp) { return READ_LE_UINT16(selectoroffset + prop_ofs); } -reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) { // Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered. +reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) { MemObject *mobj = GET_SEGMENT(*s->segmentManager, pos.segment, MEM_OBJ_SCRIPT); Script *script_entity = NULL; byte *scr; @@ -80,6 +109,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod uint opcode; int bytecount = 1; int i = 0; + Kernel *kernel = ((SciEngine*)g_engine)->getKernel(); if (!mobj) { warning("Disassembly failed: Segment %04x non-existant or not a script", pos.segment); @@ -149,7 +179,8 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if (print_bw_tag) printf("[%c] ", opsize ? 'B' : 'W'); - printf("%s", ((SciEngine*)g_engine)->getKernel()->getOpcode(opcode).name.c_str()); + + printf("%s", opcodeNames[opcode]); i = 0; while (g_opcode_formats[opcode][i]) { @@ -184,8 +215,8 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod } if (opcode == op_callk) - printf(" %s[%x]", (param_value < ((SciEngine*)g_engine)->getKernel()->_kernelFuncs.size()) ? - ((param_value < ((SciEngine*)g_engine)->getKernel()->getKernelNamesSize()) ? ((SciEngine*)g_engine)->getKernel()->getKernelName(param_value).c_str() : "[Unknown(postulated)]") + printf(" %s[%x]", (param_value < kernel->_kernelFuncs.size()) ? + ((param_value < kernel->getKernelNamesSize()) ? kernel->getKernelName(param_value).c_str() : "[Unknown(postulated)]") : "", param_value); else printf(opsize ? " %02x" : " %04x", param_value); @@ -275,7 +306,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if (!name) name = ""; - printf(" %s::%s[", name, (selector > ((SciEngine*)g_engine)->getKernel()->getSelectorNamesSize()) ? "" : selector_name(s, selector)); + printf(" %s::%s[", name, (selector > kernel->getSelectorNamesSize()) ? "" : selector_name(s, selector)); switch (lookup_selector(s->segmentManager, called_obj_addr, selector, 0, &fun_ref)) { case kSelectorMethod: diff --git a/engines/sci/vocabulary.cpp b/engines/sci/vocabulary.cpp index 517413db4b9..1f69d6fb5d9 100644 --- a/engines/sci/vocabulary.cpp +++ b/engines/sci/vocabulary.cpp @@ -35,6 +35,7 @@ namespace Sci { #if 0 +#define VOCAB_RESOURCE_CLASSES 996 /** * Vocabulary class names. * These strange names were taken from an SCI01 interpreter. diff --git a/engines/sci/vocabulary.h b/engines/sci/vocabulary.h index edb4288387a..d9d5989ee75 100644 --- a/engines/sci/vocabulary.h +++ b/engines/sci/vocabulary.h @@ -43,10 +43,7 @@ class ResourceManager; #define PARSE_HEAP_SIZE 64 enum { - VOCAB_RESOURCE_CLASSES = 996, - VOCAB_RESOURCE_SNAMES = 997, - VOCAB_RESOURCE_OPCODES = 998, - VOCAB_RESOURCE_KNAMES = 999, + VOCAB_RESOURCE_SELECTORS = 997, VOCAB_RESOURCE_SCI0_MAIN_VOCAB = 0, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES = 900, @@ -54,8 +51,7 @@ enum { VOCAB_RESOURCE_SCI1_MAIN_VOCAB = 900, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES = 901, - VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB = 902, - VOCAB_RESOURCE_SCI1_CHAR_TRANSFORMS = 913 + VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB = 902 };