- 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
This commit is contained in:
parent
be22438648
commit
4441ca4b3e
12 changed files with 251 additions and 220 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
#define FIND_SELECTOR(_slc_) _selectorMap._slc_ = findSelector(#_slc_)
|
||||
#define FIND_SELECTOR2(_slc_, _slcstr_) _selectorMap._slc_ = findSelector(_slcstr_)
|
||||
|
||||
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_)
|
||||
|
||||
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: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue