[Scummvm-cvs-logs] SF.net SVN: scummvm:[47597] scummvm/trunk/engines/sci/engine/vm.cpp
waltervn at users.sourceforge.net
waltervn at users.sourceforge.net
Wed Jan 27 14:14:29 CET 2010
Revision: 47597
http://scummvm.svn.sourceforge.net/scummvm/?rev=47597&view=rev
Author: waltervn
Date: 2010-01-27 13:14:28 +0000 (Wed, 27 Jan 2010)
Log Message:
-----------
SCI: Experimental fix for Longbow outlook crash.
When using a pointer in number arithmetic, substitute a large value instead
of 0 (cf. Hoyle hack in kAbs).
Modified Paths:
--------------
scummvm/trunk/engines/sci/engine/vm.cpp
Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp 2010-01-27 12:20:01 UTC (rev 47596)
+++ scummvm/trunk/engines/sci/engine/vm.cpp 2010-01-27 13:14:28 UTC (rev 47597)
@@ -87,8 +87,10 @@
static int validate_arithmetic(reg_t reg) {
if (reg.segment) {
+ // When using a pointer in number arithmetic, we substitute a large value as
+ // some scripts rely on this (cf. Hoyle hack in kAbs).
warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment);
- return 0;
+ return 0x3e9;
}
return reg.offset;
@@ -97,7 +99,7 @@
static int signed_validate_arithmetic(reg_t reg) {
if (reg.segment) {
warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment);
- return 0;
+ return 0x3e9;
}
if (reg.offset & 0x8000)
@@ -890,25 +892,37 @@
case 0x13: // ugt?
s->r_prev = s->r_acc;
r_temp = POP32();
- s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset > s->r_acc.offset);
+ 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(validate_arithmetic(r_temp) > /*acc*/);
break;
case 0x14: // uge?
s->r_prev = s->r_acc;
r_temp = POP32();
- s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset >= s->r_acc.offset);
+ 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(validate_arithmetic(r_temp) >= /*acc*/);
break;
case 0x15: // ult?
s->r_prev = s->r_acc;
r_temp = POP32();
- s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset < s->r_acc.offset);
+ 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(validate_arithmetic(r_temp) < /*acc*/);
break;
case 0x16: // ule?
s->r_prev = s->r_acc;
r_temp = POP32();
- s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset <= s->r_acc.offset);
+ 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(validate_arithmetic(r_temp) <= /*acc*/);
break;
case 0x17: // bt
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list