[Scummvm-cvs-logs] SF.net SVN: scummvm:[41101] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Jun 1 16:12:43 CEST 2009


Revision: 41101
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41101&view=rev
Author:   thebluegr
Date:     2009-06-01 14:12:43 +0000 (Mon, 01 Jun 2009)

Log Message:
-----------
Split the kernel functions away from the vocabulary functions (WIP, saving/loading is broken)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/engine/game.cpp
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kernel.h
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/kmisc.cpp
    scummvm/trunk/engines/sci/engine/kmovement.cpp
    scummvm/trunk/engines/sci/engine/kscripts.cpp
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/vocabulary.cpp
    scummvm/trunk/engines/sci/vocabulary.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/console.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -134,8 +134,8 @@
 
 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->getOpcodesSize(); seeker++) {
-		opcode op = g_EngineState->_vocabulary->getOpcode(seeker);
+	for (uint seeker = 0; seeker < g_EngineState->_kernel->getOpcodesSize(); seeker++) {
+		opcode op = g_EngineState->_kernel->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::cmdSelectors(int argc, const char **argv) {
 	DebugPrintf("Selector names in numeric order:\n");
-	for (uint seeker = 0; seeker < g_EngineState->_vocabulary->getSelectorNamesSize(); seeker++) {
-		DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->getSelectorName(seeker).c_str());
+	for (uint seeker = 0; seeker < g_EngineState->_kernel->getSelectorNamesSize(); seeker++) {
+		DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_kernel->getSelectorName(seeker).c_str());
 		if ((seeker % 3) == 2)
 			DebugPrintf("\n");
 	}
@@ -161,8 +161,8 @@
 
 bool Console::cmdKernelNames(int argc, const char **argv) {
 	DebugPrintf("Selector names in numeric order:\n");
-	for (uint seeker = 0; seeker <  g_EngineState->_vocabulary->getKernelNamesSize(); seeker++) {
-		DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_vocabulary->getKernelName(seeker).c_str());
+	for (uint seeker = 0; seeker <  g_EngineState->_kernel->getKernelNamesSize(); seeker++) {
+		DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_kernel->getKernelName(seeker).c_str());
 		if ((seeker % 3) == 2)
 			DebugPrintf("\n");
 	}
@@ -221,7 +221,7 @@
 		return true;
 	}
 
-	g_EngineState->_vocabulary->dissectScript(atoi(argv[1]));
+	g_EngineState->_kernel->dissectScript(atoi(argv[1]), g_EngineState->_vocabulary);
 
 	return true;
 }

Modified: scummvm/trunk/engines/sci/engine/game.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/game.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/game.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -372,7 +372,8 @@
 
 	s->parser_lastmatch_word = SAID_NO_MATCH;
 
-	s->_vocabulary = new Vocabulary(s->resmgr, (s->flags & GF_SCI0_OLD));
+	s->_kernel = new Kernel(s->resmgr, (s->flags & GF_SCI0_OLD));
+	s->_vocabulary = new Vocabulary(s->resmgr);
 
 	script_map_kernel(s);
 	// Maps the kernel functions
@@ -423,6 +424,7 @@
 	s->_kfuncTable.clear();
 
 	delete s->_vocabulary;
+	delete s->_kernel;
 }
 
 void script_free_breakpoints(EngineState *s) {

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -469,8 +469,81 @@
 	{KF_TERMINATOR, NULL, NULL, NULL} // Terminator
 };
 
-static const char *argtype_description[] = { "Undetermined (WTF?)", "List", "Node", "Object", "Reference", "Arithmetic" };
+static const char *argtype_description[] = { "Undetermined", "List", "Node", "Object", "Reference", "Arithmetic" };
 
+Kernel::Kernel(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr) {
+	memset(&_selectorMap, 0, sizeof(_selectorMap));	// FIXME: Remove this once/if we C++ify selector_map_t
+
+	loadKernelNames();
+
+	loadOpcodes();
+
+	if (!loadSelectorNames(isOldSci0)) {
+		error("Kernel: Could not retrieve selector names");
+	}
+
+	// Map a few special selectors for later use
+	mapSelectors();
+}
+
+Kernel::~Kernel() {
+	_selectorNames.clear();
+	_opcodes.clear();
+	_kernelNames.clear();
+}
+
+bool Kernel::loadSelectorNames(bool isOldSci0) {
+	int count;
+
+	Resource *r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES, 0);
+
+	if (!r) // No such resource?
+		return false;
+
+	count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
+
+	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);
+
+		Common::String tmp((const char *)r->data + offset + 2, len);
+		_selectorNames.push_back(tmp);
+
+		// Early SCI versions used the LSB in the selector ID as a read/write
+		// toggle. To compensate for that, we add every selector name twice.
+		if (isOldSci0)
+			_selectorNames.push_back(tmp);
+	}
+
+	return true;
+}
+
+bool Kernel::loadOpcodes() {
+	int count, i = 0;
+	Resource* r = _resmgr->findResource(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(EngineState *s, const char *type, int space) {
 	reg_t reg;
@@ -582,7 +655,7 @@
 int script_map_kernel(EngineState *s) {
 	int mapped = 0;
 	int ignored = 0;
-	uint functions_nr = s->_vocabulary->getKernelNamesSize();
+	uint functions_nr = s->_kernel->getKernelNamesSize();
 	uint max_functions_nr = (s->resmgr->_sciVersion == SCI_VERSION_0) ? 0x72 : 0x7b;
 
 	if (functions_nr < max_functions_nr) {
@@ -599,8 +672,8 @@
 		int seeker, found = -1;
 		Common::String sought_name;
 
-		if (functnr < s->_vocabulary->getKernelNamesSize())
-			sought_name = s->_vocabulary->getKernelName(functnr);
+		if (functnr < s->_kernel->getKernelNamesSize())
+			sought_name = s->_kernel->getKernelName(functnr);
 
 		if (!sought_name.empty())
 			for (seeker = 0; (found == -1) && kfunct_mappers[seeker].type != KF_TERMINATOR; seeker++)
@@ -609,7 +682,7 @@
 
 		if (found == -1) {
 			if (!sought_name.empty()) {
-				warning("Kernel function %s[%x] unmapped", s->_vocabulary->getKernelName(functnr).c_str(), functnr);
+				warning("Kernel function %s[%x] unmapped", s->_kernel->getKernelName(functnr).c_str(), functnr);
 				s->_kfuncTable[functnr].fun = kNOP;
 			} else {
 				warning("Flagging kernel function %x as unknown", functnr);
@@ -639,7 +712,7 @@
 
 	} // for all functions requesting to be mapped
 
-	sciprintf("Handled %d/%d kernel functions, mapping %d", mapped + ignored, s->_vocabulary->getKernelNamesSize(), mapped);
+	sciprintf("Handled %d/%d kernel functions, mapping %d", mapped + ignored, s->_kernel->getKernelNamesSize(), mapped);
 	if (ignored)
 		sciprintf(" and ignoring %d", ignored);
 	sciprintf(".\n");
@@ -885,7 +958,7 @@
 }
 #endif
 
-bool Vocabulary::loadKernelNames() {
+bool Kernel::loadKernelNames() {
 	_kernelNames.clear();
 
 	switch (_resmgr->_sciVersion) {

Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kernel.h	2009-06-01 14:12:43 UTC (rev 41101)
@@ -31,6 +31,7 @@
 #include "common/rect.h"
 
 #include "sci/uinput.h"
+#include "sci/vocabulary.h"
 
 namespace Sci {
 
@@ -45,8 +46,83 @@
 #define AVOIDPATH_DYNMEM_STRING "AvoidPath polyline"
 //#define DEBUG_PARSER	// enable for parser debugging
 
-/* Formerly, the heap macros were here; they have been deprecated, however. */
+struct opcode {
+	int type;
+	Common::String name;
+};
 
+class Kernel {
+public:
+	Kernel(ResourceManager *resmgr, bool isOldSci0);
+	~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]; }
+
+	uint getKernelNamesSize() const { return _kernelNames.size(); }
+	const Common::String &getKernelName(uint number) const { return _kernelNames[number]; }
+
+	/* 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) const;
+
+	/* 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) const;
+
+	// Script dissection/dumping functions
+	void dissectScript(int scriptNumber, Vocabulary *vocab);
+	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 */
+private:
+	/**
+	 * Loads the kernel function names.
+	 *
+	 * This function reads the kernel function name table from resource_map,
+	 * and fills the _kernelNames array with them.
+	 * The resulting list has the same format regardless of the format of the
+	 * name table of the resource (the format changed between version 0 and 1).
+	 * @return true on success, false on failure
+	 */
+	bool loadKernelNames();
+
+	/**
+	* Loads the kernel selector names.
+	* Returns true upon success, false otherwise.
+	*/
+	bool loadSelectorNames(bool isOldSci0);
+
+	/* Maps special selectors
+	** Returns   : (void)
+	*/
+	void mapSelectors();
+
+	/**
+	 * Loads the opcode names (only used for debugging).
+	 * @return true on success, false on failure
+	 */
+	bool loadOpcodes();
+
+	ResourceManager *_resmgr;
+
+	// 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;
+};
+
 /******************** Selector functionality ********************/
 
 enum SelectorInvocation {
@@ -54,7 +130,7 @@
 	kContinueOnInvalidSelector = 1
 };
 
-#define GET_SEL32(_o_, _slc_) read_selector(s, _o_, s->_vocabulary->_selectorMap._slc_, __FILE__, __LINE__)
+#define GET_SEL32(_o_, _slc_) read_selector(s, _o_, s->_kernel->_selectorMap._slc_, __FILE__, __LINE__)
 #define GET_SEL32V(_o_, _slc_) (GET_SEL32(_o_, _slc_).offset)
 #define GET_SEL32SV(_o_, _slc_) ((int16)(GET_SEL32(_o_, _slc_).offset))
 /* Retrieves a selector from an object
@@ -65,8 +141,8 @@
 ** selector_map_t and mapped in script.c.
 */
 
-#define PUT_SEL32(_o_, _slc_, _val_) write_selector(s, _o_, s->_vocabulary->_selectorMap._slc_, _val_, __FILE__, __LINE__)
-#define PUT_SEL32V(_o_, _slc_, _val_) write_selector(s, _o_, s->_vocabulary->_selectorMap._slc_, make_reg(0, _val_), __FILE__, __LINE__)
+#define PUT_SEL32(_o_, _slc_, _val_) write_selector(s, _o_, s->_kernel->_selectorMap._slc_, _val_, __FILE__, __LINE__)
+#define PUT_SEL32V(_o_, _slc_, _val_) write_selector(s, _o_, s->_kernel->_selectorMap._slc_, make_reg(0, _val_), __FILE__, __LINE__)
 /* Writes a selector value to an object
 ** Parameters: (reg_t) object: The address of the object which the selector should be written to
 **             (selector_name) selector: The selector to read
@@ -78,7 +154,7 @@
 
 
 #define INV_SEL(_object_, _selector_, _noinvalid_) \
-	s, _object_,  s->_vocabulary->_selectorMap._selector_, _noinvalid_, funct_nr, argv, argc, __FILE__, __LINE__
+	s, _object_,  s->_kernel->_selectorMap._selector_, _noinvalid_, funct_nr, argv, argc, __FILE__, __LINE__
 /* Kludge for use with invoke_selector(). Used for compatibility with compilers that can't
 ** handle vararg macros.
 */

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -1076,7 +1076,7 @@
 	x = GET_SEL32SV(object, x);
 	original_y = y = GET_SEL32SV(object, y);
 
-	if (s->_vocabulary->_selectorMap.z > -1)
+	if (s->_kernel->_selectorMap.z > -1)
 		z = GET_SEL32SV(object, z);
 	else
 		z = 0;
@@ -1130,7 +1130,7 @@
 void _k_base_setter(EngineState *s, reg_t object) {
 	Common::Rect absrect = set_base(s, object);
 
-	if (lookup_selector(s, object, s->_vocabulary->_selectorMap.brLeft, NULL, NULL) != kSelectorVariable)
+	if (lookup_selector(s, object, s->_kernel->_selectorMap.brLeft, NULL, NULL) != kSelectorVariable)
 		return; // non-fatal
 
 	// Note: there was a check here for a very old version of SCI, which supposedly needed
@@ -1211,7 +1211,7 @@
 	x = GET_SEL32SV(object, x);
 	y = GET_SEL32SV(object, y);
 
-	if (s->_vocabulary->_selectorMap.z > -1)
+	if (s->_kernel->_selectorMap.z > -1)
 		z = GET_SEL32SV(object, z);
 	else
 		z = 0;
@@ -1235,7 +1235,7 @@
 static void _k_set_now_seen(EngineState *s, reg_t object) {
 	Common::Rect absrect = get_nsrect(s, object, 0);
 
-	if (lookup_selector(s, object, s->_vocabulary->_selectorMap.nsTop, NULL, NULL) != kSelectorVariable) {
+	if (lookup_selector(s, object, s->_kernel->_selectorMap.nsTop, NULL, NULL) != kSelectorVariable) {
 		return;
 	} // This isn't fatal
 
@@ -1720,7 +1720,7 @@
 		 * if ((widget->signal & (_K_VIEW_SIG_FLAG_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == _K_VIEW_SIG_FLAG_PRIVATE) {
 		 */
 		if ((widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == 0) {
-			int has_nsrect = lookup_selector(s, obj, s->_vocabulary->_selectorMap.nsBottom, NULL, NULL) == kSelectorVariable;
+			int has_nsrect = lookup_selector(s, obj, s->_kernel->_selectorMap.nsBottom, NULL, NULL) == kSelectorVariable;
 
 			if (has_nsrect) {
 				int temp;
@@ -1742,7 +1742,7 @@
 			}
 #ifdef DEBUG_LSRECT
 			else
-				fprintf(stderr, "Not lsRecting %04x:%04x because %d\n", PRINT_REG(obj), lookup_selector(s, obj, s->_vocabulary->_selectorMap.nsBottom, NULL, NULL));
+				fprintf(stderr, "Not lsRecting %04x:%04x because %d\n", PRINT_REG(obj), lookup_selector(s, obj, s->_kernel->_selectorMap.nsBottom, NULL, NULL));
 #endif
 
 			if (widget->signal & _K_VIEW_SIG_FLAG_HIDDEN)
@@ -1894,7 +1894,7 @@
 	loop = oldloop = sign_extend_byte(GET_SEL32V(obj, loop));
 	cel = oldcel = sign_extend_byte(GET_SEL32V(obj, cel));
 
-	if (s->_vocabulary->_selectorMap.palette)
+	if (s->_kernel->_selectorMap.palette)
 		palette = GET_SEL32V(obj, palette);
 	else
 		palette = 0;
@@ -1916,14 +1916,14 @@
 		PUT_SEL32V(obj, cel, cel);
 	}
 
-	if (lookup_selector(s, obj, s->_vocabulary->_selectorMap.underBits, &(under_bitsp), NULL) != kSelectorVariable) {
+	if (lookup_selector(s, obj, s->_kernel->_selectorMap.underBits, &(under_bitsp), NULL) != kSelectorVariable) {
 		under_bitsp = NULL;
 		under_bits = NULL_REG;
 		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no underBits\n", PRINT_REG(obj));
 	} else
 		under_bits = *((reg_t *)under_bitsp);
 
-	if (lookup_selector(s, obj, s->_vocabulary->_selectorMap.signal, &(signalp), NULL) != kSelectorVariable) {
+	if (lookup_selector(s, obj, s->_kernel->_selectorMap.signal, &(signalp), NULL) != kSelectorVariable) {
 		signalp = NULL;
 		signal = 0;
 		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no signal selector\n", PRINT_REG(obj));
@@ -2015,7 +2015,7 @@
 	while (view) {
 		reg_t obj = make_reg(view->_ID, view->_subID);
 		int priority, _priority;
-		int has_nsrect = (view->_ID <= 0) ? 0 : lookup_selector(s, obj, s->_vocabulary->_selectorMap.nsBottom, NULL, NULL) == kSelectorVariable;
+		int has_nsrect = (view->_ID <= 0) ? 0 : lookup_selector(s, obj, s->_kernel->_selectorMap.nsBottom, NULL, NULL) == kSelectorVariable;
 		int oldsignal = view->signal;
 
 		_k_set_now_seen(s, obj);

Modified: scummvm/trunk/engines/sci/engine/kmisc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmisc.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kmisc.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -236,7 +236,7 @@
 }
 
 reg_t kstub(EngineState *s, int funct_nr, int argc, reg_t *argv) {
-	sciprintf("Unimplemented syscall: %s[%x](", s->_vocabulary->getKernelName(funct_nr).c_str(), funct_nr);
+	sciprintf("Unimplemented syscall: %s[%x](", s->_kernel->getKernelName(funct_nr).c_str(), funct_nr);
 
 	for (int i = 0; i < argc; i++) {
 		sciprintf("%04x:%04x", PRINT_REG(argv[i]));

Modified: scummvm/trunk/engines/sci/engine/kmovement.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmovement.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kmovement.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -462,7 +462,7 @@
 			return;
 		}
 
-		if (lookup_selector(s, motion_class, s->_vocabulary->_selectorMap.doit, NULL, &fptr) != kSelectorMethod) {
+		if (lookup_selector(s, motion_class, s->_kernel->_selectorMap.doit, NULL, &fptr) != kSelectorMethod) {
 			warning("bresenham_autodetect failed");
 			handle_movecnt = INCREMENT_MOVECNT; // Most games do this, so best guess
 			return;
@@ -557,7 +557,7 @@
 
 	debugC(2, kDebugLevelBresen, "New data: (x,y)=(%d,%d), di=%d\n", x, y, bdi);
 
-	if (s->_vocabulary->_selectorMap.cantBeHere != -1)
+	if (s->_kernel->_selectorMap.cantBeHere != -1)
 		invoke_selector(INV_SEL(client, cantBeHere, kStopOnInvalidSelector), 0);
 	else
 		invoke_selector(INV_SEL(client, canBeHere, kStopOnInvalidSelector), 0);

Modified: scummvm/trunk/engines/sci/engine/kscripts.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -43,7 +43,7 @@
 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->getSelectorNamesSize())) {
+	if ((selector_id < 0) || (selector_id > (int)s->_kernel->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 @@
 
 	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->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
+		         " written to (%s L%d)", s->_kernel->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
 	else
 		*address = value;
 }
@@ -72,7 +72,7 @@
 
 	if (slc_type == kSelectorNone) {
 		warning("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)",
-		         s->_vocabulary->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
+		         s->_kernel->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
 		if (noinvalid == kStopOnInvalidSelector)
 			error("[Kernel] Not recoverable: VM was halted\n");
 		return 1;

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -827,13 +827,16 @@
 	retval->_vocabulary = s->_vocabulary;
 //	s->_vocabulary = 0;	// FIXME: We should set s->_vocabulary to 0 here,
 // else it could be freed when the old EngineState is freed. Luckily, this freeing currently
-// never happens, so we don't need to. This is lucky, because the fact that the kernel function
-// and selector tables are stored in the Vocabulary (????) makes it impossible for us to
-// free the vocabulary here.
+// never happens, so we don't need to. 
 
 	retval->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE);
 
 	// static VM/Kernel information:
+	retval->_kernel = s->_kernel;
+	assert(0 == retval->_kernel);
+//	s->_kernel = 0;	// FIXME: We should set s->_kernel to 0 here,
+// else it could be freed when the old EngineState is freed. Luckily, this freeing currently
+// never happens, so we don't need to. 
 	retval->_kfuncTable = s->_kfuncTable;
 
 	// Copy breakpoint information from current game instance

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -111,7 +111,7 @@
 #define FIND_SELECTOR(_slc_) _selectorMap._slc_ = findSelector(#_slc_)
 #define FIND_SELECTOR2(_slc_, _slcstr_) _selectorMap._slc_ = findSelector(_slcstr_)
 
-void Vocabulary::mapSelectors() {
+void Kernel::mapSelectors() {
 	FIND_SELECTOR(init);
 	FIND_SELECTOR(play);
 	FIND_SELECTOR(replay);
@@ -202,7 +202,7 @@
 	FIND_SELECTOR(syncTime);
 }
 
-void Vocabulary::dumpScriptObject(char *data, int seeker, int objsize) {
+void Kernel::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);
@@ -245,7 +245,7 @@
 		}
 }
 
-void Vocabulary::dumpScriptClass(char *data, int seeker, int objsize) {
+void Kernel::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);
@@ -292,7 +292,7 @@
 	}
 }
 
-void Vocabulary::dissectScript(int scriptNumber) {
+void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) {
 	int objectctr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 	unsigned int _seeker = 0;
 	Resource *script = _resmgr->findResource(kResourceTypeScript, scriptNumber, 0);
@@ -385,7 +385,7 @@
 					}
 				} else {
 					nextitem = nextitem << 8 | script->data [seeker++];
-					sciprintf("%s[%03x] ", getAnyWordFromGroup(nextitem), nextitem);
+					sciprintf("%s[%03x] ", vocab->getAnyWordFromGroup(nextitem), nextitem);
 				}
 			}
 			sciprintf("\n");

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -699,8 +699,8 @@
 }
 
 const char *selector_name(EngineState *s, int selector) {
-	if (selector >= 0 && selector < (int)s->_vocabulary->getSelectorNamesSize())
-		return s->_vocabulary->getSelectorName(selector).c_str();
+	if (selector >= 0 && selector < (int)s->_kernel->getSelectorNamesSize())
+		return s->_kernel->getSelectorName(selector).c_str();
 	else
 		return "--INVALID--";
 }
@@ -822,7 +822,7 @@
 
 	if (print_bw_tag)
 		sciprintf("[%c] ", opsize ? 'B' : 'W');
-	sciprintf("%s", s->_vocabulary->getOpcode(opcode).name.c_str());
+	sciprintf("%s", s->_kernel->getOpcode(opcode).name.c_str());
 
 	i = 0;
 	while (g_opcode_formats[opcode][i]) {
@@ -858,7 +858,7 @@
 
 			if (opcode == op_callk)
 				sciprintf(" %s[%x]", (param_value < s->_kfuncTable.size()) ?
-							((param_value < s->_vocabulary->getKernelNamesSize()) ? s->_vocabulary->getKernelName(param_value).c_str() : "[Unknown(postulated)]")
+							((param_value < s->_kernel->getKernelNamesSize()) ? s->_kernel->getKernelName(param_value).c_str() : "[Unknown(postulated)]")
 							: "<invalid>", param_value);
 			else
 				sciprintf(opsize ? " %02x" : " %04x", param_value);
@@ -948,7 +948,7 @@
 				if (!name)
 					name = "<invalid>";
 
-				sciprintf("  %s::%s[", name, (selector > s->_vocabulary->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector));
+				sciprintf("  %s::%s[", name, (selector > s->_kernel->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector));
 
 				switch (lookup_selector(s, called_obj_addr, selector, &val_ref, &fun_ref)) {
 				case kSelectorMethod:
@@ -1058,12 +1058,12 @@
 		break;
 
 		case EXEC_STACK_TYPE_KERNEL: // Kernel function
-			sciprintf(" %x:[%x]  k%s(", i, call.origin, s->_vocabulary->getKernelName(-(call.selector) - 42).c_str());
+			sciprintf(" %x:[%x]  k%s(", i, call.origin, s->_kernel->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->getSelectorName(call.selector).c_str());
+			          objname,s->_kernel->getSelectorName(call.selector).c_str());
 			break;
 		}
 
@@ -1232,10 +1232,10 @@
 	}
 
 
-	is_view = (lookup_selector(s, pos, s->_vocabulary->_selectorMap.x, NULL) == kSelectorVariable) &&
-	    (lookup_selector(s, pos, s->_vocabulary->_selectorMap.brLeft, NULL) == kSelectorVariable) &&
-	    (lookup_selector(s, pos, s->_vocabulary->_selectorMap.signal, NULL) == kSelectorVariable) &&
-	    (lookup_selector(s, pos, s->_vocabulary->_selectorMap.nsTop, NULL) == kSelectorVariable);
+	is_view = (lookup_selector(s, pos, s->_kernel->_selectorMap.x, NULL) == kSelectorVariable) &&
+	    (lookup_selector(s, pos, s->_kernel->_selectorMap.brLeft, NULL) == kSelectorVariable) &&
+	    (lookup_selector(s, pos, s->_kernel->_selectorMap.signal, NULL) == kSelectorVariable) &&
+	    (lookup_selector(s, pos, s->_kernel->_selectorMap.nsTop, NULL) == kSelectorVariable);
 
 	if (!is_view) {
 		sciprintf("Not a dynamic View object.\n");
@@ -1318,7 +1318,7 @@
 
 static int c_disasm(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
 	Object *obj = obj_get(s, cmdParams[0].reg);
-	int selector_id = s->_vocabulary->findSelector(cmdParams[1].str);
+	int selector_id = s->_kernel->findSelector(cmdParams[1].str);
 	reg_t addr;
 
 	if (!obj) {
@@ -1367,8 +1367,8 @@
 		callk_index = strtoul(cmdParams [0].str, &endptr, 0);
 		if (*endptr != '\0') {
 			callk_index = -1;
-			for (uint i = 0; i < s->_vocabulary->getKernelNamesSize(); i++)
-				if (cmdParams [0].str == s->_vocabulary->getKernelName(i)) {
+			for (uint i = 0; i < s->_kernel->getKernelNamesSize(); i++)
+				if (cmdParams [0].str == s->_kernel->getKernelName(i)) {
 					callk_index = i;
 					break;
 				}
@@ -1419,7 +1419,7 @@
 	reg_t *vptr;
 	reg_t fptr;
 
-	selector_id = s->_vocabulary->findSelector(selector_name);
+	selector_id = s->_kernel->findSelector(selector_name);
 
 	if (selector_id < 0) {
 		sciprintf("Unknown selector: \"%s\"\n", selector_name);
@@ -1566,7 +1566,7 @@
 	int have_rects = 0;
 	Common::Rect nsrect, nsrect_clipped, brrect;
 
-	if (lookup_selector(s, pos, s->_vocabulary->_selectorMap.nsBottom, NULL) == kSelectorVariable) {
+	if (lookup_selector(s, pos, s->_kernel->_selectorMap.nsBottom, NULL) == kSelectorVariable) {
 		GETRECT(nsLeft, nsRight, nsBottom, nsTop);
 		GETRECT(lsLeft, lsRight, lsBottom, lsTop);
 		GETRECT(brLeft, brRight, brBottom, brTop);
@@ -1580,7 +1580,7 @@
 	x = GET_SELECTOR(pos, x);
 	y = GET_SELECTOR(pos, y);
 	priority = GET_SELECTOR(pos, priority);
-	if (s->_vocabulary->_selectorMap.z > 0) {
+	if (s->_kernel->_selectorMap.z > 0) {
 		z = GET_SELECTOR(pos, z);
 		sciprintf("(%d,%d,%d)\n", x, y, z);
 	} else

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -121,6 +121,7 @@
 	gc_countdown = 0;
 
 	_vocabulary = 0;
+	_kernel = 0;
 
 	successor = 0;
 }

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-06-01 14:12:43 UTC (rev 41101)
@@ -244,6 +244,7 @@
 	MessageState _msgState;
 
 	Vocabulary *_vocabulary;
+	Kernel *_kernel;
 
 	EngineState *successor; /**< Successor of this state: Used for restoring */
 };
@@ -257,7 +258,7 @@
 PaletteEntry get_pic_color(EngineState *s, int color);
 
 static inline reg_t not_register(EngineState *s, reg_t r) {
-	if (s->_vocabulary->_selectorMap.cantBeHere != -1)
+	if (s->_kernel->_selectorMap.cantBeHere != -1)
 		return make_reg(0, !r.offset);
 	else
 		return r;

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -315,7 +315,7 @@
 			Breakpoint *bp;
 			char method_name [256];
 
-			sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->_vocabulary->getSelectorName(selector).c_str());
+			sprintf(method_name, "%s::%s", obj_get_name(s, send_obj), s->_kernel->getSelectorName(selector).c_str());
 
 			bp = s->bp_list;
 			while (bp) {
@@ -1959,7 +1959,7 @@
 			script_init_engine(s, s->version);
 			game_init(s);
 			sfx_reset_player();
-			_init_stack_base_with_selector(s, s->_vocabulary->_selectorMap.play);
+			_init_stack_base_with_selector(s, s->_kernel->_selectorMap.play);
 
 			send_selector(s, s->game_obj, s->game_obj, s->stack_base, 2, s->stack_base);
 
@@ -1979,7 +1979,7 @@
 					sciprintf("Restarting with replay()\n");
 					s->_executionStack.clear(); // Restart with replay
 
-					_init_stack_base_with_selector(s, s->_vocabulary->_selectorMap.replay);
+					_init_stack_base_with_selector(s, s->_kernel->_selectorMap.replay);
 
 					send_selector(s, s->game_obj, s->game_obj, s->stack_base, 2, s->stack_base);
 				}
@@ -2000,7 +2000,7 @@
 	EngineState *s = *_s;
 
 	sciprintf(" Calling %s::play()\n", s->_gameName.c_str());
-	_init_stack_base_with_selector(s, s->_vocabulary->_selectorMap.play); // Call the play selector
+	_init_stack_base_with_selector(s, s->_kernel->_selectorMap.play); // Call the play selector
 
 	// Now: Register the first element on the execution stack-
 	if (!send_selector(s, s->game_obj, s->game_obj, s->stack_base, 2, s->stack_base)) {

Modified: scummvm/trunk/engines/sci/vocabulary.cpp
===================================================================
--- scummvm/trunk/engines/sci/vocabulary.cpp	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/vocabulary.cpp	2009-06-01 14:12:43 UTC (rev 41101)
@@ -85,10 +85,9 @@
 
 #endif
 
-Vocabulary::Vocabulary(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr), _isOldSci0(isOldSci0) {
+Vocabulary::Vocabulary(ResourceManager *resmgr) : _resmgr(resmgr) {
 	_parserRules = NULL;
 	_vocabVersion = kVocabularySCI0;
-	memset(&_selectorMap, 0, sizeof(_selectorMap));	// FIXME: Remove this once/if we C++ify selector_map_t
 
 	debug(2, "Initializing vocabulary");
 
@@ -101,81 +100,15 @@
 		debug(2, "Assuming that this game does not use a parser.");
 		_parserRules = NULL;
 	}
-
-	loadOpcodes();
-
-	if (!loadSelectorNames()) {
-		error("Vocabulary: Could not retrieve selector names");
-	}
-
-	// Map a few special selectors for later use
-	mapSelectors();
-
-	loadKernelNames();
 }
 
 Vocabulary::~Vocabulary() {
 	freeRuleList(_parserRules);
 	_parserWords.clear();
-	_selectorNames.clear();
-	_opcodes.clear();
-	_kernelNames.clear();
 	_parserBranches.clear();
 	freeSuffixes();
 }
 
-bool Vocabulary::loadSelectorNames() {
-	int count;
-
-	Resource *r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES, 0);
-
-	if (!r) // No such resource?
-		return false;
-
-	count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
-
-	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);
-
-		Common::String tmp((const char *)r->data + offset + 2, len);
-		_selectorNames.push_back(tmp);
-
-		// Early SCI versions used the LSB in the selector ID as a read/write
-		// toggle. To compensate for that, we add every selector name twice.
-		if (_isOldSci0)
-			_selectorNames.push_back(tmp);
-	}
-
-	return true;
-}
-
-bool Vocabulary::loadOpcodes() {
-	int count, i = 0;
-	Resource* r = _resmgr->findResource(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;
-}
-
 bool Vocabulary::loadParserWords() {
 
 	char currentword[256] = ""; // They're not going to use words longer than 255 ;-)
@@ -533,7 +466,7 @@
 	con->DebugPrintf("\n");
 }
 
-int Vocabulary::findSelector(const char *selectorName) const {
+int Kernel::findSelector(const char *selectorName) const {
 	for (uint pos = 0; pos < _selectorNames.size(); ++pos) {
 		if (_selectorNames[pos] == selectorName)
 			return pos;
@@ -544,7 +477,7 @@
 	return -1;
 }
 
-bool Vocabulary::hasKernelFunction(const char *functionName) const {
+bool Kernel::hasKernelFunction(const char *functionName) const {
 	Common::StringList::const_iterator it = Common::find(_kernelNames.begin(), _kernelNames.end(), functionName);
 	return (it != _kernelNames.end());
 }

Modified: scummvm/trunk/engines/sci/vocabulary.h
===================================================================
--- scummvm/trunk/engines/sci/vocabulary.h	2009-06-01 13:37:51 UTC (rev 41100)
+++ scummvm/trunk/engines/sci/vocabulary.h	2009-06-01 14:12:43 UTC (rev 41101)
@@ -42,12 +42,6 @@
 /** Number of bytes allocated on the heap to store bad words if parsing fails */
 #define PARSE_HEAP_SIZE 64
 
-
-struct opcode {
-	int type;
-	Common::String name;
-};
-
 enum {
 	VOCAB_RESOURCE_CLASSES = 996,
 	VOCAB_RESOURCE_SNAMES = 997,
@@ -185,7 +179,7 @@
 
 class Vocabulary {
 public:
-	Vocabulary(ResourceManager *resmgr, bool isOldSci0);
+	Vocabulary(ResourceManager *resmgr);
 	~Vocabulary();
 
 	/**
@@ -260,65 +254,8 @@
 	uint getParserBranchesSize() const { return _parserBranches.size(); }
 	const parse_tree_branch_t &getParseTreeBranch(int number) const { return _parserBranches[number]; }
 
-	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]; }
-
-	/* 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) const;
-
-	/* 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) const;
-
-	uint getKernelNamesSize() const { return _kernelNames.size(); }
-	const Common::String &getKernelName(uint number) const { 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 */
-
 private:
 	/**
-	* Loads the vocabulary selector names.
-	* Returns true upon success, false otherwise.
-	*/
-	bool loadSelectorNames();
-
-	/* Maps special selectors
-	** Returns   : (void)
-	*/
-	void mapSelectors();
-
-	/**
-	 * Loads the opcode names (only used for debugging).
-	 * @return true on success, false on failure
-	 */
-	bool loadOpcodes();
-
-	/**
-	 * Loads the kernel function names.
-	 *
-	 * This function reads the kernel function name table from resource_map,
-	 * and fills the _kernelNames array with them.
-	 * The resulting list has the same format regardless of the format of the
-	 * name table of the resource (the format changed between version 0 and 1).
-	 * @return true on success, false on failure
-	 */
-	bool loadKernelNames();
-
-	/**
 	 * Loads all words from the main vocabulary.
 	 * @return true on success, false on failure
 	 */
@@ -349,16 +286,8 @@
 	void freeRuleList(parse_rule_list_t *rule_list);
 
 	ResourceManager *_resmgr;
-	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 */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list