[Scummvm-cvs-logs] scummvm master -> 969a96622d59937458ed560110927cb3a275cfee

bluegr md5 at scummvm.org
Mon Feb 21 04:23:09 CET 2011


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
601e8c0de1 SCI: Added a custom modulo reg_t operator
969a96622d SCI: SCI1.1 script also compare pointers with integers (e.g. QFG3, room 440)


Commit: 601e8c0de128899d78353a6b1ee49181c92f55f1
    https://github.com/scummvm/scummvm/commit/601e8c0de128899d78353a6b1ee49181c92f55f1
Author: md5 (md5 at scummvm.org)
Date: 2011-02-20T19:18:21-08:00

Commit Message:
SCI: Added a custom modulo reg_t operator

This version only handles signed integers. The modulo operator was changed in
SCI0 late (Iceman, and perhaps all SCI0 0.000.685 and later) so that it handles
negative numbers as well. We need to see if there really is a need to keep two
different modulo operators (which will only be necessary if any SCI0 game asks
for the modulo of a negative number by mistake, or a number larger than 32767).
Thus, error out in such a case for SCI0, so that this can be investigated
properly

Changed paths:
    engines/sci/engine/vm.cpp
    engines/sci/engine/vm_types.cpp
    engines/sci/engine/vm_types.h



diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index a6677ee..69d046d 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -961,28 +961,10 @@ void run_vm(EngineState *s) {
 			s->r_acc = POP32() / s->r_acc;
 			break;
 
-		case op_mod: { // 0x05 (05)
-			if (getSciVersion() <= SCI_VERSION_0_LATE) {
-				uint16 modulo = s->r_acc.requireUint16();
-				uint16 value = POP32().requireUint16();
-				uint16 result = (modulo != 0 ? value % modulo : 0);
-				s->r_acc = make_reg(0, result);
-			} else {
-				// In Iceman (and perhaps from SCI0 0.000.685 onwards in general),
-				// handling for negative numbers was added. Since Iceman doesn't
-				// seem to have issues with the older code, we exclude it for now
-				// for simplicity's sake and use the new code for SCI01 and newer
-				// games. Fixes the battlecruiser mini game in SQ5 (room 850),
-				// bug #3035755
-				int16 modulo = ABS(s->r_acc.requireSint16());
-				int16 value = POP32().requireSint16();
-				int16 result = (modulo != 0 ? value % modulo : 0);
-				if (result < 0)
-					result += modulo;
-				s->r_acc = make_reg(0, result);
-			}
+		case op_mod: // 0x05 (05)
+			// we check for division by 0 inside the custom reg_t modulo operator
+			s->r_acc = POP32() % s->r_acc;
 			break;
-		}
 
 		case op_shr: // 0x06 (06)
 			// Shift right logical
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index a165bf7..c5b106d 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -113,6 +113,29 @@ reg_t reg_t::operator/(const reg_t right) const {
 		return lookForWorkaround(right);
 }
 
+reg_t reg_t::operator%(const reg_t right) const {
+	if (isNumber() && right.isNumber()) {
+		// Support for negative numbers was added in Iceman, and perhaps in 
+		// SCI0 0.000.685 and later. Theoretically, this wasn't really used
+		// in SCI0, so if we do find such a case, error out on purpose here,
+		// so that we address it properly, as the result is probably
+		// unpredictable. Such a case would indicate either a script bug, or
+		// a modulo on an unsigned integer larger than 32767. In any case,
+		// such a case should be investigated, instead of being silently
+		// accepted.
+		if (getSciVersion() <= SCI_VERSION_0_LATE && (toSint16() < 0 || right.toSint16() < 0))
+			error("Modulo of a negative number has been requested for SCI0. "
+				  "Please report this error to the ScummVM team");
+		int16 value = toSint16();
+		int16 modulo = ABS(right.toSint16());
+		int16 result = (modulo != 0 ? value % modulo : 0);
+		if (result < 0)
+			result += modulo;
+		return make_reg(0, result);
+	} else
+		return lookForWorkaround(right);
+}
+
 reg_t reg_t::operator>>(const reg_t right) const {
 	if (isNumber() && right.isNumber())
 		return make_reg(0, toUint16() >> right.toUint16());
diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index 0187906..ac23bbe 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -108,6 +108,7 @@ struct reg_t {
 	reg_t operator-(const reg_t right) const;
 	reg_t operator*(const reg_t right) const;
 	reg_t operator/(const reg_t right) const;
+	reg_t operator%(const reg_t right) const;
 	reg_t operator>>(const reg_t right) const;
 	reg_t operator<<(const reg_t right) const;
 


Commit: 969a96622d59937458ed560110927cb3a275cfee
    https://github.com/scummvm/scummvm/commit/969a96622d59937458ed560110927cb3a275cfee
Author: md5 (md5 at scummvm.org)
Date: 2011-02-20T19:22:08-08:00

Commit Message:
SCI: SCI1.1 script also compare pointers with integers (e.g. QFG3, room 440)

Changed paths:
    engines/sci/engine/vm_types.cpp



diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index c5b106d..58ac7f0 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -246,14 +246,12 @@ bool reg_t::ltU(const reg_t right) const {
 }
 
 bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
-	// SCI0/SCI1 scripts use this to check whether a
-	// parameter is a pointer or a far text
-	// reference. It is used e.g. by the standard library
-	// Print function to distinguish two ways of calling it:
+	// SCI0 - SCI1.1 scripts use this to check whether a parameter is a pointer
+	// or a far text reference. It is used e.g. by the standard library Print
+	// function to distinguish two ways of calling it:
 	//
 	// (Print "foo") // Pointer to a string
 	// (Print 420 5) // Reference to the fifth message in text resource 420
-
 	// It works because in those games, the maximum resource number is 999,
 	// so any parameter value above that threshold must be a pointer.
 	// PQ2 japanese compares pointers to 2000 to find out if its a pointer
@@ -263,8 +261,9 @@ bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
 	// Hoyle 3, Pachisi, when any opponent is about to talk
 	// SQ1, room 28, when throwing water at the Orat
 	// SQ1, room 58, when giving the ID card to the robot
+	// QFG3, room 440, when talking to Uhura
 	// Thus we check for all integers <= 2000
-	return (isPointer() && right.isNumber() && right.offset <= 2000 && getSciVersion() <= SCI_VERSION_1_LATE);
+	return (isPointer() && right.isNumber() && right.offset <= 2000 && getSciVersion() <= SCI_VERSION_1_1);
 }
 
 } // End of namespace Sci






More information about the Scummvm-git-logs mailing list