[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