[Scummvm-git-logs] scummvm master -> fe8fbf70076a111d41a24423db06cca5c2768a1a

csnover csnover at users.noreply.github.com
Sun Nov 20 23:22:51 CET 2016


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

Summary:
9380b54120 SCI: Add code-address breakpoints to debugger
4814682d5f SCI: Improve disassembly output
22c2f39c00 SCI32: Add recursion code to kListFirstTrue and kListAllTrue
e49cf11275 OPENGLSDL: Fix signed/unsigned comparison
fe8fbf7007 SCI32: Fix reading view, pic, and palette patches


Commit: 9380b541204e2ec446d75627b8fad1b78850f356
    https://github.com/scummvm/scummvm/commit/9380b541204e2ec446d75627b8fad1b78850f356
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-20T12:31:43-06:00

Commit Message:
SCI: Add code-address breakpoints to debugger

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



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 83f1271..4028974 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -201,6 +201,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
 	registerCmd("bp_del",				WRAP_METHOD(Console, cmdBreakpointDelete));
 	registerCmd("bpdel",				WRAP_METHOD(Console, cmdBreakpointDelete));			// alias
 	registerCmd("bc",					WRAP_METHOD(Console, cmdBreakpointDelete));			// alias
+	registerCmd("bp_address",			WRAP_METHOD(Console, cmdBreakpointAddress));
+	registerCmd("bpa",					WRAP_METHOD(Console, cmdBreakpointAddress));		// alias
 	registerCmd("bp_method",			WRAP_METHOD(Console, cmdBreakpointMethod));
 	registerCmd("bpx",				WRAP_METHOD(Console, cmdBreakpointMethod));			// alias
 	registerCmd("bp_read",			WRAP_METHOD(Console, cmdBreakpointRead));
@@ -435,6 +437,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
 	debugPrintf("Breakpoints:\n");
 	debugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
 	debugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
+	debugPrintf(" bp_address / bpa - Sets a breakpoint on a script address\n");
 	debugPrintf(" bp_method / bpx - Sets a breakpoint on the execution of a specified method/selector\n");
 	debugPrintf(" bp_read / bpr - Sets a breakpoint on reading of a specified selector\n");
 	debugPrintf(" bp_write / bpw - Sets a breakpoint on writing to a specified selector\n");
@@ -3738,6 +3741,8 @@ bool Console::cmdBreakpointList(int argc, const char **argv) {
 			bpdata = bp->address;
 			debugPrintf("Execute script %d, export %d\n", bpdata >> 16, bpdata & 0xFFFF);
 			break;
+		case BREAK_ADDRESS:
+			debugPrintf("Execute address %04x:%04x\n", PRINT_REG(bp->regAddress));
 		}
 
 		i++;
@@ -3894,6 +3899,31 @@ bool Console::cmdBreakpointFunction(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::cmdBreakpointAddress(int argc, const char **argv) {
+	if (argc != 2) {
+		debugPrintf("Sets a breakpoint on the execution of the specified code address.\n");
+		debugPrintf("Usage: %s <address>\n", argv[0]);
+		return true;
+	}
+
+	reg_t addr;
+
+	if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
+		debugPrintf("Invalid address passed.\n");
+		debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+		return true;
+	}
+
+	Breakpoint bp;
+	bp.type = BREAK_ADDRESS;
+	bp.regAddress = make_reg32(addr.getSegment(), addr.getOffset());
+
+	_debugState._breakpoints.push_back(bp);
+	_debugState._activeBreakpointTypes |= BREAK_ADDRESS;
+
+	return true;
+}
+
 bool Console::cmdSfx01Header(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("Dumps the header of a SCI01 song\n");
diff --git a/engines/sci/console.h b/engines/sci/console.h
index d4b17ee..7dd1572 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -152,6 +152,7 @@ private:
 	bool cmdBreakpointWrite(int argc, const char **argv);
 	bool cmdBreakpointKernel(int argc, const char **argv);
 	bool cmdBreakpointFunction(int argc, const char **argv);
+	bool cmdBreakpointAddress(int argc, const char **argv);
 	// VM
 	bool cmdScriptSteps(int argc, const char **argv);
 	bool cmdScriptObjects(int argc, const char **argv);
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index 4fcb757..60fad26 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -42,12 +42,16 @@ enum BreakpointType {
 	 * Break when an exported function is called. Data contains
 	 * script_no << 16 | export_no.
 	 */
-	BREAK_EXPORT        = 1 << 3
+	BREAK_EXPORT        = 1 << 3,
+	BREAK_ADDRESS       = 1 << 4  // break when pc is at this address
 };
 
 struct Breakpoint {
 	BreakpointType type;
-	uint32 address;  ///< Breakpoints on exports
+	union {
+		uint32 address;     ///< Breakpoints on exports
+		reg32_t regAddress; ///< Breakpoints on addresses
+	};
 	Common::String name; ///< Breakpoints on selector names
 };
 
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index b017e62..47b360d 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -631,6 +631,22 @@ bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
 	return false;
 }
 
+bool SciEngine::checkAddressBreakpoint(const reg32_t &address) {
+	if (_debugState._activeBreakpointTypes & BREAK_ADDRESS) {
+		Common::List<Breakpoint>::const_iterator bp;
+		for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
+			if (bp->type == BREAK_ADDRESS && bp->regAddress == address) {
+				_console->debugPrintf("Break at %04x:%04x\n", PRINT_REG(address));
+				_debugState.debugging = true;
+				_debugState.breakpointWasHit = true;
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType) {
 	int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
 	const char *objectName = segMan->getObjectName(send_obj);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index ac15aeb..e82128e 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -634,6 +634,8 @@ void run_vm(EngineState *s) {
 		if (s->abortScriptProcessing != kAbortNone)
 			return; // Stop processing
 
+		g_sci->checkAddressBreakpoint(s->xs->addr.pc);
+
 		// Debug if this has been requested:
 		// TODO: re-implement sci_debug_flags
 		if (g_sci->_debugState.debugging /* sci_debug_flags*/) {
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 61dccb4..7d24890 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -334,6 +334,7 @@ public:
 	void scriptDebug();
 	bool checkExportBreakpoint(uint16 script, uint16 pubfunct);
 	bool checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector);
+	bool checkAddressBreakpoint(const reg32_t &address);
 
 	void patchGameSaveRestore();
 


Commit: 4814682d5ff72f0a986e878290394e3517b69da4
    https://github.com/scummvm/scummvm/commit/4814682d5ff72f0a986e878290394e3517b69da4
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-20T12:31:44-06:00

Commit Message:
SCI: Improve disassembly output

1. pushi opcode now displays decimal value and selector value (if
   one exists) in-line
2. lofsa, lofss, and super opcodes now display resolved
   object/class names
3. Opcode arguments are visually aligned

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



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 4028974..cfbc2f3 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -3397,7 +3397,7 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 				farthestTarget = jumpTarget;
 		}
 		// TODO: Use a true 32-bit reg_t for the position (addr)
-		addr = disassemble(_engine->_gamestate, make_reg32(addr.getSegment(), addr.getOffset()), printBWTag, printBytecode);
+		addr = disassemble(_engine->_gamestate, make_reg32(addr.getSegment(), addr.getOffset()), objAddr, printBWTag, printBytecode);
 		if (addr.isNull() && prevAddr < farthestTarget)
 			addr = prevAddr + 1; // skip past the ret
 	} while (addr.getOffset() > 0);
@@ -3446,7 +3446,7 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
 
 	do {
 		// TODO: Use a true 32-bit reg_t for the position (vpc)
-		vpc = disassemble(_engine->_gamestate, make_reg32(vpc.getSegment(), vpc.getOffset()), printBWTag, printBytes);
+		vpc = disassemble(_engine->_gamestate, make_reg32(vpc.getSegment(), vpc.getOffset()), NULL_REG, printBWTag, printBytes);
 	} while ((vpc.getOffset() > 0) && (vpc.getOffset() + 6 < size) && (--opCount));
 
 	return true;
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 7dd1572..4b630da 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -33,7 +33,7 @@ namespace Sci {
 class SciEngine;
 struct List;
 
-reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printBytecode);
+reg_t disassemble(EngineState *s, reg32_t pos, reg_t objAddr, bool printBWTag, bool printBytecode);
 bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpOffset);
 
 class Console : public GUI::Debugger {
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 098c2e5..8a973bd 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -704,7 +704,7 @@ static bool relocateBlock(Common::Array<reg_t> &block, int block_location, Segme
 	return true;
 }
 
-int Script::relocateOffsetSci3(uint32 offset) {
+int Script::relocateOffsetSci3(uint32 offset) const {
 	int relocStart = READ_LE_UINT32(_buf + 8);
 	int relocCount = READ_LE_UINT16(_buf + 18);
 	const byte *seeker = _buf + relocStart;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 31f0a9e..677b367 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -266,7 +266,7 @@ public:
 	 * Resolve a relocation in an SCI3 script
 	 * @param offset        The offset to relocate from
 	 */
-	int relocateOffsetSci3(uint32 offset);
+	int relocateOffsetSci3(uint32 offset) const;
 
 	/**
 	 * Gets an offset to the beginning of the code block in a SCI3 script
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 47b360d..9ed9772 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -68,7 +68,7 @@ const char *opcodeNames[] = {
 #endif	// REDUCE_MEMORY_USAGE
 
 // Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
-reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printBytecode) {
+reg_t disassemble(EngineState *s, reg32_t pos, reg_t objAddr, bool printBWTag, bool printBytecode) {
 	SegmentObj *mobj = s->_segMan->getSegment(pos.getSegment(), SEG_TYPE_SCRIPT);
 	Script *script_entity = NULL;
 	const byte *scr;
@@ -127,9 +127,11 @@ reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printByteco
 		debugN("[%c] ", opsize ? 'B' : 'W');
 
 #ifndef REDUCE_MEMORY_USAGE
-	debugN("%s", opcodeNames[opcode]);
+	debugN("%-5s", opcodeNames[opcode]);
 #endif
 
+	static const char *defaultSeparator = "\t\t; ";
+
 	i = 0;
 	while (g_sci->_opcode_formats[opcode][i]) {
 		switch (g_sci->_opcode_formats[opcode][i++]) {
@@ -140,14 +142,21 @@ reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printByteco
 		case Script_SByte:
 		case Script_Byte:
 			param_value = scr[retval.getOffset()];
-			debugN(" %02x", scr[retval.getOffset()]);
+			debugN("\t%02x", param_value);
+			if (param_value > 9) {
+				debugN("%s%u", defaultSeparator, param_value);
+			}
 			retval.incOffset(1);
 			break;
 
 		case Script_Word:
 		case Script_SWord:
 			param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
-			debugN(" %04x", READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]));
+			debugN("\t%04x", param_value);
+			if (param_value > 9) {
+				debugN("%s%u", defaultSeparator, param_value);
+			}
+
 			retval.incOffset(2);
 			break;
 
@@ -166,12 +175,38 @@ reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printByteco
 				retval.incOffset(2);
 			}
 
-			if (opcode == op_callk)
-				debugN(" %s[%x]", (param_value < kernel->_kernelFuncs.size()) ?
+			if (opcode == op_callk) {
+				debugN("\t%s[%x],", (param_value < kernel->_kernelFuncs.size()) ?
 							((param_value < kernel->getKernelNamesSize()) ? kernel->getKernelName(param_value).c_str() : "[Unknown(postulated)]")
 							: "<invalid>", param_value);
-			else
-				debugN(opsize ? " %02x" : " %04x", param_value);
+			} else if (opcode == op_super) {
+				Object *obj;
+				if (objAddr != NULL_REG && (obj = s->_segMan->getObject(objAddr)) != nullptr) {
+					debugN("\t%s", s->_segMan->getObjectName(obj->getSuperClassSelector()));
+					debugN(opsize ? "[%02x]" : "[%04x]", param_value);
+				} else {
+					debugN(opsize ? "\t%02x" : "\t%04x", param_value);
+				}
+
+				debugN(",");
+			} else {
+				const char *separator = defaultSeparator;
+
+				debugN(opsize ? "\t%02x" : "\t%04x", param_value);
+				if (param_value > 9) {
+					debugN("%s%u", separator, param_value);
+					separator = ", ";
+				}
+
+				if (param_value >= 0x20 && param_value <= 0x7e) {
+					debugN("%s'%c'", separator, param_value);
+					separator = ", ";
+				}
+
+				if (opcode == op_pushi && param_value < kernel->getSelectorNamesSize()) {
+					debugN("%s%s", separator, kernel->getSelectorName(param_value).c_str());
+				}
+			}
 
 			break;
 
@@ -183,19 +218,27 @@ reg_t disassemble(EngineState *s, reg32_t pos, bool printBWTag, bool printByteco
 				param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
 				retval.incOffset(2);
 			}
-			debugN(opsize ? " %02x" : " %04x", param_value);
+
+			if (opcode == op_lofsa || opcode == op_lofss) {
+				reg_t addr = make_reg(pos.getSegment(), findOffset(param_value, script_entity, pos.getOffset()));
+				debugN("\t%s", s->_segMan->getObjectName(addr));
+				debugN(opsize ? "[%02x]" : "[%04x]", param_value);
+			} else {
+				debugN(opsize ? "\t%02x" : "\t%04x", param_value);
+			}
+
 			break;
 
 		case Script_SRelative:
 			if (opsize) {
 				int8 offset = (int8)scr[retval.getOffset()];
 				retval.incOffset(1);
-				debugN(" %02x  [%04x]", 0xff & offset, 0xffff & (retval.getOffset() + offset));
+				debugN("\t%02x  [%04x]", 0xff & offset, 0xffff & (retval.getOffset() + offset));
 			}
 			else {
 				int16 offset = (int16)READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
 				retval.incOffset(2);
-				debugN(" %04x  [%04x]", 0xffff & offset, 0xffff & (retval.getOffset() + offset));
+				debugN("\t%04x  [%04x]", 0xffff & offset, 0xffff & (retval.getOffset() + offset));
 			}
 			break;
 
@@ -396,7 +439,7 @@ void SciEngine::scriptDebug() {
 	}
 
 	debugN("Step #%d\n", s->scriptStepCounter);
-	disassemble(s, s->xs->addr.pc, false, true);
+	disassemble(s, s->xs->addr.pc, s->xs->objp, false, true);
 
 	if (_debugState.runningStep) {
 		_debugState.runningStep--;
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index e82128e..01051eb 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -567,6 +567,31 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])
 	return offset;
 }
 
+uint32 findOffset(const int16 relOffset, const Script *scr, const uint32 pcOffset) {
+	uint32 offset;
+
+	switch (g_sci->_features->detectLofsType()) {
+	case SCI_VERSION_0_EARLY:
+		offset = (uint16)pcOffset + relOffset;
+		break;
+	case SCI_VERSION_1_MIDDLE:
+		offset = relOffset;
+		break;
+	case SCI_VERSION_1_1:
+		offset = relOffset + scr->getScriptSize();
+		break;
+	case SCI_VERSION_3:
+		// In theory this can break if the variant with a one-byte argument is
+		// used. For now, assume it doesn't happen.
+		offset = scr->relocateOffsetSci3(pcOffset - 2);
+		break;
+	default:
+		error("Unknown lofs type");
+	}
+
+	return offset;
+}
+
 void run_vm(EngineState *s) {
 	assert(s);
 
@@ -1169,38 +1194,22 @@ void run_vm(EngineState *s) {
 		}
 
 		case op_lofsa: // 0x39 (57)
-		case op_lofss: // 0x3a (58)
+		case op_lofss: { // 0x3a (58)
 			// Load offset to accumulator or push to stack
-			r_temp.setSegment(s->xs->addr.pc.getSegment());
-
-			switch (g_sci->_features->detectLofsType()) {
-			case SCI_VERSION_0_EARLY:
-				r_temp.setOffset((uint16)s->xs->addr.pc.getOffset() + opparams[0]);
-				break;
-			case SCI_VERSION_1_MIDDLE:
-				r_temp.setOffset(opparams[0]);
-				break;
-			case SCI_VERSION_1_1:
-				r_temp.setOffset(opparams[0] + local_script->getScriptSize());
-				break;
-			case SCI_VERSION_3:
-				// In theory this can break if the variant with a one-byte argument is
-				// used. For now, assume it doesn't happen.
-				r_temp.setOffset(local_script->relocateOffsetSci3(s->xs->addr.pc.getOffset() - 2));
-				break;
-			default:
-				error("Unknown lofs type");
-			}
+			Script *local_script = s->_segMan->getScriptIfLoaded(s->xs->local_segment);
 
+			r_temp.setSegment(s->xs->addr.pc.getSegment());
+			r_temp.setOffset(findOffset(opparams[0], local_script, s->xs->addr.pc.getOffset()));
 			if (r_temp.getOffset() >= scr->getBufSize())
 				error("VM: lofsa/lofss operation overflowed: %04x:%04x beyond end"
-				          " of script (at %04x)", PRINT_REG(r_temp), scr->getBufSize());
+						  " of script (at %04x)", PRINT_REG(r_temp), scr->getBufSize());
 
 			if (opcode == op_lofsa)
 				s->r_acc = r_temp;
 			else
 				PUSH32(r_temp);
 			break;
+		}
 
 		case op_push0: // 0x3b (59)
 			PUSH(0);
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index dd66d9d..cec9e15 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -36,6 +36,7 @@ class SegManager;
 struct EngineState;
 class Object;
 class ResourceManager;
+class Script;
 
 /** Number of bytes to be allocated for the stack */
 #define VM_STACK_SIZE 0x1000
@@ -386,6 +387,16 @@ SelectorType lookupSelector(SegManager *segMan, reg_t obj, Selector selectorid,
  */
 int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]);
 
+/**
+ * Finds the script-absolute offset of a relative object offset.
+ *
+ * @param[in] relOffset the relative object offset
+ * @param[in] scr the owner script object, used by SCI1.1+
+ * @param[in] pcOffset the offset of the program counter, used by SCI0early and
+ *                     SCI3
+ */
+uint32 findOffset(const int16 relOffset, const Script *scr, const uint32 pcOffset);
+
 } // End of namespace Sci
 
 #endif // SCI_ENGINE_VM_H


Commit: 22c2f39c0026a1ba00d7f28a93a0b4f9baa5fbfc
    https://github.com/scummvm/scummvm/commit/22c2f39c0026a1ba00d7f28a93a0b4f9baa5fbfc
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-20T12:31:44-06:00

Commit Message:
SCI32: Add recursion code to kListFirstTrue and kListAllTrue

This change ensures that these kernel calls operate in the same
manner that they did in SSCI.

Changed paths:
    engines/sci/engine/klists.cpp



diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index 5cd9c36..16ce236 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -547,7 +547,6 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) {
 	List *list = s->_segMan->lookupList(argv[0]);
 
 	Node *curNode = s->_segMan->lookupNode(list->first);
-	reg_t curObject;
 	Selector slc = argv[1].toUint16();
 
 	ObjVarRef address;
@@ -564,7 +563,7 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) {
 		// needs to be able to adjust the location of the next node, which is
 		// why it is stored on the list instead of on the stack
 		list->nextNodes[list->numRecursions] = curNode->succ;
-		curObject = curNode->value;
+		reg_t curObject = curNode->value;
 
 		// First, check if the target selector is a variable
 		if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) {
@@ -595,37 +594,51 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) {
 	List *list = s->_segMan->lookupList(argv[0]);
 
 	Node *curNode = s->_segMan->lookupNode(list->first);
-	reg_t curObject;
 	Selector slc = argv[1].toUint16();
 
 	ObjVarRef address;
 
-	s->r_acc = NULL_REG;	// reset the accumulator
+	s->r_acc = NULL_REG;
+
+	++list->numRecursions;
+
+	if (list->numRecursions >= ARRAYSIZE(list->nextNodes)) {
+		error("Too much recursion in kListFirstTrue");
+	}
 
 	while (curNode) {
-		reg_t nextNode = curNode->succ;
-		curObject = curNode->value;
+		// We get the next node here as the current node might be deleted by the
+		// invoke. In the case that the next node is also deleted, kDeleteKey
+		// needs to be able to adjust the location of the next node, which is
+		// why it is stored on the list instead of on the stack
+		list->nextNodes[list->numRecursions] = curNode->succ;
+		reg_t curObject = curNode->value;
 
 		// First, check if the target selector is a variable
 		if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) {
 			// If it's a variable selector, check its value.
 			// Example: script 64893 in Torin, MenuHandler::isHilited checks
 			// all children for variable selector 0x03ba (bHilited).
-			if (!readSelector(s->_segMan, curObject, slc).isNull())
-				return curObject;
+			if (!readSelector(s->_segMan, curObject, slc).isNull()) {
+				s->r_acc = curObject;
+				break;
+			}
 		} else {
 			invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
 
 			// Check if the result is true
-			if (!s->r_acc.isNull())
-				return curObject;
+			if (!s->r_acc.isNull()) {
+				s->r_acc = curObject;
+				break;
+			}
 		}
 
-		curNode = s->_segMan->lookupNode(nextNode);
+		curNode = s->_segMan->lookupNode(list->nextNodes[list->numRecursions]);
 	}
 
-	// No selector returned true
-	return NULL_REG;
+	--list->numRecursions;
+
+	return s->r_acc;
 }
 
 reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) {
@@ -637,10 +650,20 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) {
 
 	ObjVarRef address;
 
-	s->r_acc = make_reg(0, 1);	// reset the accumulator
+	s->r_acc = TRUE_REG;
+
+	++list->numRecursions;
+
+	if (list->numRecursions >= ARRAYSIZE(list->nextNodes)) {
+		error("Too much recursion in kListAllTrue");
+	}
 
 	while (curNode) {
-		reg_t nextNode = curNode->succ;
+		// We get the next node here as the current node might be deleted by the
+		// invoke. In the case that the next node is also deleted, kDeleteKey
+		// needs to be able to adjust the location of the next node, which is
+		// why it is stored on the list instead of on the stack
+		list->nextNodes[list->numRecursions] = curNode->succ;
 		curObject = curNode->value;
 
 		// First, check if the target selector is a variable
@@ -655,9 +678,11 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) {
 		if (s->r_acc.isNull())
 			break;
 
-		curNode = s->_segMan->lookupNode(nextNode);
+		curNode = s->_segMan->lookupNode(list->nextNodes[list->numRecursions]);
 	}
 
+	--list->numRecursions;
+
 	return s->r_acc;
 }
 


Commit: e49cf11275a1dffdb6b6573d2637e60f1e280cac
    https://github.com/scummvm/scummvm/commit/e49cf11275a1dffdb6b6573d2637e60f1e280cac
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-20T16:13:51-06:00

Commit Message:
OPENGLSDL: Fix signed/unsigned comparison

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 8f2ff1b..860173a 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -357,7 +357,7 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
 	// event is processed after recreating the window at the new resolution.
 	int currentWidth, currentHeight;
 	getWindowDimensions(&currentWidth, &currentHeight);
-	if (width != currentWidth || height != currentHeight)
+	if (width != (uint)currentWidth || height != (uint)currentHeight)
 		return;
 	setActualScreenSize(width, height);
 	_eventSource->resetKeyboardEmulation(width - 1, height - 1);


Commit: fe8fbf70076a111d41a24423db06cca5c2768a1a
    https://github.com/scummvm/scummvm/commit/fe8fbf70076a111d41a24423db06cca5c2768a1a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-11-20T16:16:17-06:00

Commit Message:
SCI32: Fix reading view, pic, and palette patches

Unlike SCI16 games, the location of data within SCI32 patch files
is calculated on a per-resource-type basis by the game engine,
instead of by reading byte 1 of the patch file.

Changed paths:
    engines/sci/resource.cpp



diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 5b57eed..31ceb68 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1399,7 +1399,20 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource
 	}
 
 	byte patchType = convertResType(fileStream->readByte());
-	byte patchDataOffset = fileStream->readByte();
+	int32 patchDataOffset;
+	if (_volVersion < kResVersionSci2) {
+		patchDataOffset = fileStream->readByte();
+	} else if (patchType == kResourceTypeView) {
+		fileStream->seek(3, SEEK_SET);
+		patchDataOffset = fileStream->readByte() + 22 + 2;
+	} else if (patchType == kResourceTypePic) {
+		patchDataOffset = 2;
+	} else if (patchType == kResourceTypePalette) {
+		fileStream->seek(3, SEEK_SET);
+		patchDataOffset = fileStream->readByte() + 2;
+	} else {
+		patchDataOffset = 0;
+	}
 
 	delete fileStream;
 





More information about the Scummvm-git-logs mailing list