[Scummvm-cvs-logs] scummvm master -> 6fe95780d358f2d7854c342448eb61159f267656

wjp wjp at usecode.org
Sat Mar 12 23:48:32 CET 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6fe95780d3 SCI: Continue disasm until no jumps go past the current opcode


Commit: 6fe95780d358f2d7854c342448eb61159f267656
    https://github.com/scummvm/scummvm/commit/6fe95780d358f2d7854c342448eb61159f267656
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2011-03-12T14:46:32-08:00

Commit Message:
SCI: Continue disasm until no jumps go past the current opcode

This should ensure disasm will disassemble an entire function, and
not stop at an intermediate ret opcode.

Changed paths:
    engines/sci/console.cpp
    engines/sci/console.h
    engines/sci/engine/scriptdebug.cpp



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 6a64f19..b11aab0 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2601,7 +2601,6 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 		DebugPrintf("Valid options are:\n");
 		DebugPrintf(" bwt  : Print byte/word tag\n");
 		DebugPrintf(" bc   : Print bytecode\n");
-		DebugPrintf(" rX   : Continue after X ret opcodes before stopping decompilation\n");
 		return true;
 	}
 
@@ -2640,17 +2639,19 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 			printBWTag = true;
 		else if (!scumm_stricmp(argv[i], "bc"))
 			printBytecode = true;
-		else if (argv[i][0] == 'r')
-			ignoreXret = atoi(argv[i] + 1);
 	}
 
+	reg_t farthestTarget = addr;
 	do {
 		reg_t prevAddr = addr;
-		addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
-		if (addr.isNull() && ignoreXret) {
-			addr = prevAddr + 1;	// skip past the ret
-			ignoreXret--;
+		reg_t jumpTarget;
+		if (isJumpOpcode(_engine->_gamestate, addr, jumpTarget)) {
+			if (jumpTarget > farthestTarget)
+				farthestTarget = jumpTarget;
 		}
+		addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
+		if (addr.isNull() && prevAddr < farthestTarget)
+			addr = prevAddr + 1; // skip past the ret
 	} while (addr.offset > 0);
 
 	return true;
diff --git a/engines/sci/console.h b/engines/sci/console.h
index b0a1de6..d454543 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -37,6 +37,7 @@ class SciEngine;
 struct List;
 
 reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode);
+bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpOffset);
 
 class Console : public GUI::Debugger {
 public:
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 184f81b..7649021 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -281,6 +281,35 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
 	return retval;
 }
 
+bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget)
+{
+	SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);
+	if (!mobj)
+		return false;
+	Script *script_entity = (Script *)mobj;
+
+	const byte *scr = script_entity->getBuf();
+	int scr_size = script_entity->getBufSize();
+
+	if (pos.offset >= scr_size)
+		return false;
+
+	int16 opparams[4];
+	byte opsize;
+	int bytecount = readPMachineInstruction(scr + pos.offset, opsize, opparams);
+	const byte opcode = opsize >> 1;
+
+	switch (opcode) {
+	case op_bt:
+	case op_bnt:
+	case op_jmp:
+		jumpTarget = pos + bytecount + opparams[0];
+		return true;
+	default:
+		return false;
+	}
+}
+
 
 void SciEngine::scriptDebug() {
 	EngineState *s = _gamestate;






More information about the Scummvm-git-logs mailing list