aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2010-01-27 01:47:41 +0000
committerWalter van Niftrik2010-01-27 01:47:41 +0000
commit7c0dcf108cf3327525507b7784dbc725bd02b059 (patch)
treeef8861da8f80c8749abe4892718495d49588e3fe
parentd4f08cbe818f2a7d80df10b468b30cc61975b422 (diff)
downloadscummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.tar.gz
scummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.tar.bz2
scummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.zip
SCI: Add pointer comparison support to signed comparison operators.
svn-id: r47585
-rw-r--r--engines/sci/engine/vm.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 974109237c..b993cf84d9 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -848,22 +848,40 @@ void run_vm(EngineState *s, int restoring) {
case 0x0f: // gt?
s->r_prev = s->r_acc;
- s->r_acc = ACC_ARITHMETIC_L((int16)POP() > (int16)/*acc*/);
+ r_temp = POP32();
+ if (r_temp.segment && s->r_acc.segment) {
+ // Signed pointer comparison. We do unsigned comparison instead, as that is probably what was intended.
+ // FIXME: Add a warning when pointers in different segments are compared
+ s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset > s->r_acc.offset);
+ } else
+ s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() > (int16)/*acc*/);
break;
case 0x10: // ge?
s->r_prev = s->r_acc;
- s->r_acc = ACC_ARITHMETIC_L((int16)POP() >= (int16)/*acc*/);
+ r_temp = POP32();
+ if (r_temp.segment && s->r_acc.segment)
+ s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset >= s->r_acc.offset);
+ else
+ s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() >= (int16)/*acc*/);
break;
case 0x11: // lt?
s->r_prev = s->r_acc;
- s->r_acc = ACC_ARITHMETIC_L((int16)POP() < (int16)/*acc*/);
+ r_temp = POP32();
+ if (r_temp.segment && s->r_acc.segment)
+ s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset < s->r_acc.offset);
+ else
+ s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() < (int16)/*acc*/);
break;
case 0x12: // le?
s->r_prev = s->r_acc;
- s->r_acc = ACC_ARITHMETIC_L((int16)POP() <= (int16)/*acc*/);
+ r_temp = POP32();
+ if (r_temp.segment && s->r_acc.segment)
+ s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset <= s->r_acc.offset);
+ else
+ s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() <= (int16)/*acc*/);
break;
case 0x13: // ugt?