diff options
Diffstat (limited to 'engines/sci/console.cpp')
| -rw-r--r-- | engines/sci/console.cpp | 186 | 
1 files changed, 186 insertions, 0 deletions
| diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 3f5548aac7..1e95393e4d 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -209,6 +209,11 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),  	registerCmd("bpe",				WRAP_METHOD(Console, cmdBreakpointFunction));		// alias  	// VM  	registerCmd("script_steps",		WRAP_METHOD(Console, cmdScriptSteps)); +	registerCmd("script_objects",   WRAP_METHOD(Console, cmdScriptObjects)); +	registerCmd("scro",             WRAP_METHOD(Console, cmdScriptObjects)); +	registerCmd("script_strings",   WRAP_METHOD(Console, cmdScriptStrings)); +	registerCmd("scrs",             WRAP_METHOD(Console, cmdScriptStrings)); +	registerCmd("script_said",      WRAP_METHOD(Console, cmdScriptSaid));  	registerCmd("vm_varlist",			WRAP_METHOD(Console, cmdVMVarlist));  	registerCmd("vmvarlist",			WRAP_METHOD(Console, cmdVMVarlist));				// alias  	registerCmd("vl",					WRAP_METHOD(Console, cmdVMVarlist));				// alias @@ -2828,6 +2833,186 @@ bool Console::cmdScriptSteps(int argc, const char **argv) {  	return true;  } +bool Console::cmdScriptObjects(int argc, const char **argv) { +	int curScriptNr = -1; + +	if (argc < 2) { +		debugPrintf("Shows all objects inside a specified script.\n"); +		debugPrintf("Usage: %s <script number>\n", argv[0]); +		debugPrintf("Example: %s 999\n", argv[0]); +		debugPrintf("<script number> may be * to show objects inside all loaded scripts\n"); +		return true; +	} +	 +	if (strcmp(argv[1], "*") == 0) { +		// get said-strings of all currently loaded scripts +		curScriptNr = -1; +	} else { +		curScriptNr = atoi(argv[1]); +	} + +	printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_OBJECT); +	return true; +} + +bool Console::cmdScriptStrings(int argc, const char **argv) { +	int curScriptNr = -1; + +	if (argc < 2) { +		debugPrintf("Shows all strings inside a specified script.\n"); +		debugPrintf("Usage: %s <script number>\n", argv[0]); +		debugPrintf("Example: %s 999\n", argv[0]); +		debugPrintf("<script number> may be * to show strings inside all loaded scripts\n"); +		return true; +	} +	 +	if (strcmp(argv[1], "*") == 0) { +		// get strings of all currently loaded scripts +		curScriptNr = -1; +	} else { +		curScriptNr = atoi(argv[1]); +	} + +	printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_STRING); +	return true; +} + +bool Console::cmdScriptSaid(int argc, const char **argv) { +	int curScriptNr = -1; + +	if (argc < 2) { +		debugPrintf("Shows all said-strings inside a specified script.\n"); +		debugPrintf("Usage: %s <script number>\n", argv[0]); +		debugPrintf("Example: %s 999\n", argv[0]); +		debugPrintf("<script number> may be * to show said-strings inside all loaded scripts\n"); +		return true; +	} +	 +	if (strcmp(argv[1], "*") == 0) { +		// get said-strings of all currently loaded scripts +		curScriptNr = -1; +	} else { +		curScriptNr = atoi(argv[1]); +	} + +	printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_SAID); +	return true; +} + +void Console::printOffsets(int scriptNr, uint16 showType) { +	SegManager *segMan = _engine->_gamestate->_segMan; +	Vocabulary *vocab = _engine->_vocabulary; +	SegmentId curSegmentNr; +	Common::List<SegmentId> segmentNrList; + +	SegmentType curSegmentType = SEG_TYPE_INVALID; +	SegmentObj *curSegmentObj = NULL; +	Script *curScriptObj = NULL; +	const byte *curScriptData = NULL; + +	segmentNrList.clear(); +	if (scriptNr < 0) { +		// get offsets of all currently loaded scripts +		for (curSegmentNr = 0; curSegmentNr < segMan->_heap.size(); curSegmentNr++) { +			curSegmentObj = segMan->_heap[curSegmentNr]; +			if (curSegmentObj && curSegmentObj->getType() == SEG_TYPE_SCRIPT) { +				segmentNrList.push_back(curSegmentNr); +			} +		} + +	} else { +		curSegmentNr = segMan->getScriptSegment(scriptNr); +		if (!curSegmentNr) { +			debugPrintf("Script %d is currently not loaded/available\n", scriptNr); +			return; +		} +		segmentNrList.push_back(curSegmentNr); +	} + +	const offsetLookupArrayType *scriptOffsetLookupArray; +	offsetLookupArrayType::const_iterator arrayIterator; +	int showTypeCount = 0; + +	reg_t objectPos; +	const char *objectNamePtr = NULL; +	const byte *stringPtr = NULL; +	const byte *saidPtr = NULL; + +	Common::List<SegmentId>::iterator it; +	const Common::List<SegmentId>::iterator end = segmentNrList.end(); + +	for (it = segmentNrList.begin(); it != end; it++) { +		curSegmentNr = *it; +		// get object of this segment +		curSegmentObj = segMan->getSegmentObj(curSegmentNr); +		if (!curSegmentObj) +			continue; + +		curSegmentType = curSegmentObj->getType(); +		if (curSegmentType != SEG_TYPE_SCRIPT) // safety check +			continue; + +		curScriptObj = (Script *)curSegmentObj; +		debugPrintf("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); +		debugN("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); + +		// now print the list +		scriptOffsetLookupArray = curScriptObj->getOffsetArray(); +		curScriptData = curScriptObj->getBuf(); +		showTypeCount = 0; + +		for (arrayIterator = scriptOffsetLookupArray->begin(); arrayIterator != scriptOffsetLookupArray->end(); arrayIterator++) { +			if (arrayIterator->type == showType) { +				switch (showType) { +				case SCI_SCR_OFFSET_TYPE_OBJECT: +					objectPos = make_reg(curSegmentNr, arrayIterator->offset); +					objectNamePtr = segMan->getObjectName(objectPos); +					debugPrintf(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr); +					debugN(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr); +					break; +				case SCI_SCR_OFFSET_TYPE_STRING: +					stringPtr = curScriptData + arrayIterator->offset; +					debugPrintf(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize); +					debugN(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize); +					break; +				case SCI_SCR_OFFSET_TYPE_SAID: +					saidPtr = curScriptData + arrayIterator->offset; +					debugPrintf(" %03d:%04x:\n", arrayIterator->id, arrayIterator->offset); +					debugN(" %03d:%04x: ", arrayIterator->id, arrayIterator->offset); +					vocab->debugDecipherSaidBlock(saidPtr); +					debugN("\n"); +					break; +				default: +					break; +				} +				showTypeCount++; +			} +		} + +		if (showTypeCount == 0) { +			switch (showType) { +			case SCI_SCR_OFFSET_TYPE_OBJECT: +				debugPrintf(" no objects\n"); +				debugN(" no objects\n"); +				break; +			case SCI_SCR_OFFSET_TYPE_STRING: +				debugPrintf(" no strings\n"); +				debugN(" no strings\n"); +				break; +			case SCI_SCR_OFFSET_TYPE_SAID: +				debugPrintf(" no said-strings\n"); +				debugN(" no said-strings\n"); +				break; +			default: +				break; +			} +		} + +		debugPrintf("\n"); +		debugN("\n"); +	} +} +  bool Console::cmdBacktrace(int argc, const char **argv) {  	debugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);  	Common::List<ExecStack>::const_iterator iter; @@ -3307,6 +3492,7 @@ bool Console::cmdSend(int argc, const char **argv) {  		// We call run_engine explictly so we can restore the value of r_acc  		// after execution.  		run_vm(_engine->_gamestate); +		_engine->_gamestate->xs = old_xstack;  	} | 
