aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsluicebox2020-01-09 17:53:11 -0800
committersluicebox2020-01-09 18:04:03 -0800
commita804afc57192a5ca5db0ce408d658300ceb2651f (patch)
tree3b9f34eebf8a6abbb5badfc03fcdfd8e31785d52
parent485e8bee17230ed8e17a27eaf148a3330f305a6f (diff)
downloadscummvm-rg350-a804afc57192a5ca5db0ce408d658300ceb2651f.tar.gz
scummvm-rg350-a804afc57192a5ca5db0ce408d658300ceb2651f.tar.bz2
scummvm-rg350-a804afc57192a5ca5db0ce408d658300ceb2651f.zip
SCI: Trigger bpr/bpw breakpoints within kernel calls
Trac #9835
-rw-r--r--engines/sci/engine/scriptdebug.cpp28
-rw-r--r--engines/sci/engine/scriptdebug.h2
-rw-r--r--engines/sci/engine/selector.cpp17
-rw-r--r--engines/sci/engine/vm.cpp12
4 files changed, 37 insertions, 22 deletions
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 7a1fe66d35..05d9ade3ba 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -945,32 +945,34 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg
} // switch
}
-void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType) {
+void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, Selector selector, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType) {
const Object *var_container = obj;
if (!obj->isClass() && getSciVersion() != SCI_VERSION_3)
var_container = segMan->getObject(obj->getSuperClassSelector());
- uint16 varSelector;
- if (getSciVersion() == SCI_VERSION_3) {
- varSelector = index;
- } else {
- index >>= 1;
-
- if (index >= var_container->getVarCount()) {
- // TODO: error, warning, debug?
- return;
+ if (selector == NULL_SELECTOR) {
+ if (getSciVersion() == SCI_VERSION_3) {
+ selector = index;
}
+ else {
+ index >>= 1;
- varSelector = var_container->getVarSelector(index);
+ if (index >= var_container->getVarCount()) {
+ // TODO: error, warning, debug?
+ return;
+ }
+
+ selector = var_container->getVarSelector(index);
+ }
}
- if (g_sci->checkSelectorBreakpoint(breakpointType, objp, varSelector)) {
+ if (g_sci->checkSelectorBreakpoint(breakpointType, objp, selector)) {
// checkSelectorBreakpoint has already triggered the breakpoint.
// We just output the relevant data here.
Console *con = g_sci->getSciDebugger();
const char *objectName = segMan->getObjectName(objp);
- const char *selectorName = g_sci->getKernel()->getSelectorName(varSelector).c_str();
+ const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();
if (breakpointType == BREAK_SELECTORWRITE) {
con->debugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
objectName, selectorName,
diff --git a/engines/sci/engine/scriptdebug.h b/engines/sci/engine/scriptdebug.h
index 5e927efaf1..7b176aed4e 100644
--- a/engines/sci/engine/scriptdebug.h
+++ b/engines/sci/engine/scriptdebug.h
@@ -31,7 +31,7 @@ extern const char *opcodeNames[];
void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType);
-void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType);
+void debugPropertyAccess(Object *obj, reg_t objp, unsigned int index, Selector selector, reg_t curValue, reg_t newValue, SegManager *segMan, BreakpointType breakpointType);
void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result);
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 6196495954..1a63b4dee1 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -23,6 +23,7 @@
#include "sci/sci.h"
#include "sci/engine/features.h"
#include "sci/engine/kernel.h"
+#include "sci/engine/scriptdebug.h"
#include "sci/engine/state.h"
#include "sci/engine/selector.h"
@@ -246,8 +247,14 @@ reg_t readSelector(SegManager *segMan, reg_t object, Selector selectorId) {
if (lookupSelector(segMan, object, selectorId, &address, NULL) != kSelectorVariable)
return NULL_REG;
- else
- return *address.getPointer(segMan);
+
+ if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) {
+ reg_t curValue = *address.getPointer(segMan);
+ debugPropertyAccess(segMan->getObject(object), object, 0, selectorId,
+ curValue, NULL_REG, segMan, BREAK_SELECTORREAD);
+ }
+
+ return *address.getPointer(segMan);
}
#ifdef ENABLE_SCI32
@@ -271,6 +278,12 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t
error("Selector '%s' of object could not be written to. Address %04x:%04x, %s", g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object), origin.toString().c_str());
}
+ if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) {
+ reg_t curValue = *address.getPointer(segMan);
+ debugPropertyAccess(segMan->getObject(object), object, 0, selectorId,
+ curValue, value, segMan, BREAK_SELECTORWRITE);
+ }
+
*address.getPointer(segMan) = value;
#ifdef ENABLE_SCI32
updateInfoFlagViewVisible(segMan->getObject(object), address.varindex);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index d5bcb63ce4..b4221eb28c 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1133,7 +1133,7 @@ void run_vm(EngineState *s) {
case op_pToa: // 0x31 (49)
// Property To Accumulator
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
validate_property(s, obj, opparams[0]), NULL_REG,
s->_segMan, BREAK_SELECTORREAD);
}
@@ -1145,7 +1145,7 @@ void run_vm(EngineState *s) {
// Accumulator To Property
reg_t &opProperty = validate_property(s, obj, opparams[0]);
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
opProperty, s->r_acc,
s->_segMan, BREAK_SELECTORWRITE);
}
@@ -1162,7 +1162,7 @@ void run_vm(EngineState *s) {
// Property To Stack
reg_t value = validate_property(s, obj, opparams[0]);
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
value, NULL_REG,
s->_segMan, BREAK_SELECTORREAD);
}
@@ -1176,7 +1176,7 @@ void run_vm(EngineState *s) {
reg_t newValue = POP32();
reg_t &opProperty = validate_property(s, obj, opparams[0]);
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
opProperty, newValue,
s->_segMan, BREAK_SELECTORWRITE);
}
@@ -1198,7 +1198,7 @@ void run_vm(EngineState *s) {
reg_t oldValue = opProperty;
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORREAD) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
oldValue, NULL_REG,
s->_segMan, BREAK_SELECTORREAD);
}
@@ -1209,7 +1209,7 @@ void run_vm(EngineState *s) {
opProperty -= 1;
if (g_sci->_debugState._activeBreakpointTypes & BREAK_SELECTORWRITE) {
- debugPropertyAccess(obj, s->xs->objp, opparams[0],
+ debugPropertyAccess(obj, s->xs->objp, opparams[0], NULL_SELECTOR,
oldValue, opProperty,
s->_segMan, BREAK_SELECTORWRITE);
}