[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(¤tWidth, ¤tHeight);
- 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