aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorFilippos Karapetis2009-08-27 23:39:59 +0000
committerFilippos Karapetis2009-08-27 23:39:59 +0000
commitfaa3c64d1b22c87ef01adb885fba57293fda4aa7 (patch)
treec8c7726d5bf63711fbf8c23ad9b9f13ec22f80b5 /engines/sci/engine
parente8406cc7c3603622cd0dea83683d35902ef72749 (diff)
downloadscummvm-rg350-faa3c64d1b22c87ef01adb885fba57293fda4aa7.tar.gz
scummvm-rg350-faa3c64d1b22c87ef01adb885fba57293fda4aa7.tar.bz2
scummvm-rg350-faa3c64d1b22c87ef01adb885fba57293fda4aa7.zip
Stop loading opcodes from vocab.998. They are the same in all SCI games and are hardcoded anyway (plus, vocab.998 is unreliable in some games, e.g. QFG3, or completely missing in others). Also hardcoded the opcode names for the script debugger, the only place they're actually used. The only place where vocab.998 is loaded on demand is when using the "opcodes" console command (for debug/verification purposes)
svn-id: r43775
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.cpp29
-rw-r--r--engines/sci/engine/kernel.h19
-rw-r--r--engines/sci/engine/scriptdebug.cpp41
3 files changed, 37 insertions, 52 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 38eb375192..19dfd0ada9 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 595816579b..a780d04cf7 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<opcode> _opcodes;
Common::StringList _selectorNames;
Common::StringList _kernelNames;
};
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 28e22cb56e..6e4725d28c 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)]")
: "<invalid>", 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 = "<invalid>";
- printf(" %s::%s[", name, (selector > ((SciEngine*)g_engine)->getKernel()->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector));
+ printf(" %s::%s[", name, (selector > kernel->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector));
switch (lookup_selector(s->segmentManager, called_obj_addr, selector, 0, &fun_ref)) {
case kSelectorMethod: