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 | |
| 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
| -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 */ | 
