[Scummvm-git-logs] scummvm master -> 820caf370e2c24e6aefd8b1b90227ca29564bab6

wjp wjp at usecode.org
Sun Jul 9 22:57:40 CEST 2017


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

Summary:
820caf370e SCI32: Fix kObjectIntersect


Commit: 820caf370e2c24e6aefd8b1b90227ca29564bab6
    https://github.com/scummvm/scummvm/commit/820caf370e2c24e6aefd8b1b90227ca29564bab6
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2017-07-09T22:56:04+02:00

Commit Message:
SCI32: Fix kObjectIntersect

It was using SCI16 calls to get the NowSeenRects.

This fixes #9855.

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/frameout.cpp
    engines/sci/graphics/frameout.h


diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 76ed27a..44a3517 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -102,20 +102,14 @@ reg_t kSetNowSeen32(EngineState *s, int argc, reg_t *argv) {
 	// NOTE: MGDX is assumed to use the older kSetNowSeen since it was
 	// released before SQ6, but this has not been verified since it cannot be
 	// disassembled at the moment (Phar Lap Windows-only release)
+	// (See also getNowSeenRect)
 	if (getSciVersion() <= SCI_VERSION_2_1_EARLY ||
 		g_sci->getGameId() == GID_SQ6 ||
 		g_sci->getGameId() == GID_MOTHERGOOSEHIRES) {
 
-		if (!found) {
-			error("kSetNowSeen: Unable to find screen item %04x:%04x", PRINT_REG(argv[0]));
-		}
 		return s->r_acc;
 	}
 
-	if (!found) {
-		warning("kSetNowSeen: Unable to find screen item %04x:%04x", PRINT_REG(argv[0]));
-	}
-
 	return make_reg(0, found);
 }
 
@@ -245,9 +239,8 @@ reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) {
-	Common::Rect objRect1 = g_sci->_gfxCompare->getNSRect(argv[0]);
-	Common::Rect objRect2 = g_sci->_gfxCompare->getNSRect(argv[1]);
-	return make_reg(0, objRect1.intersects(objRect2));
+	int16 area = g_sci->_gfxFrameout->kernelObjectIntersect(argv[0], argv[1]);
+	return make_reg(0, area);
 }
 
 reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) {
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 7415979..b49332d 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -1253,35 +1253,80 @@ bool GfxFrameout::isOnMe(const ScreenItem &screenItem, const Plane &plane, const
 	return true;
 }
 
-bool GfxFrameout::kernelSetNowSeen(const reg_t screenItemObject) const {
+bool GfxFrameout::getNowSeenRect(const reg_t screenItemObject, Common::Rect &result) const {
 	const reg_t planeObject = readSelector(_segMan, screenItemObject, SELECTOR(plane));
-
-	Plane *plane = _planes.findByObject(planeObject);
+	const Plane *plane = _planes.findByObject(planeObject);
 	if (plane == nullptr) {
-		error("kSetNowSeen: Plane %04x:%04x not found for screen item %04x:%04x", PRINT_REG(planeObject), PRINT_REG(screenItemObject));
+		error("getNowSeenRect: Plane %04x:%04x not found for screen item %04x:%04x", PRINT_REG(planeObject), PRINT_REG(screenItemObject));
 	}
 
-	ScreenItem *screenItem = plane->_screenItemList.findByObject(screenItemObject);
+	const ScreenItem *screenItem = plane->_screenItemList.findByObject(screenItemObject);
 	if (screenItem == nullptr) {
+		// NOTE: MGDX is assumed to use the older getNowSeenRect since it was
+		// released before SQ6, but this has not been verified since it cannot
+		// be disassembled at the moment (Phar Lap Windows-only release)
+		// (See also kSetNowSeen32)
+		if (getSciVersion() <= SCI_VERSION_2_1_EARLY ||
+			g_sci->getGameId() == GID_SQ6 ||
+			g_sci->getGameId() == GID_MOTHERGOOSEHIRES) {
+
+			error("getNowSeenRect: Unable to find screen item %04x:%04x", PRINT_REG(screenItemObject));
+		}
+
+		warning("getNowSeenRect: Unable to find screen item %04x:%04x", PRINT_REG(screenItemObject));
 		return false;
 	}
 
-	Common::Rect result = screenItem->getNowSeenRect(*plane);
+	result = screenItem->getNowSeenRect(*plane);
+
+	return true;
+}
+
+bool GfxFrameout::kernelSetNowSeen(const reg_t screenItemObject) const {
+	Common::Rect nsrect;
+
+	bool found = getNowSeenRect(screenItemObject, nsrect);
+
+	if (!found)
+		return false;
 
 	if (g_sci->_features->usesAlternateSelectors()) {
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(left), result.left);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(top), result.top);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(right), result.right - 1);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(bottom), result.bottom - 1);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(left), nsrect.left);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(top), nsrect.top);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(right), nsrect.right - 1);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(bottom), nsrect.bottom - 1);
 	} else {
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsLeft), result.left);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsTop), result.top);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsRight), result.right - 1);
-		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsBottom), result.bottom - 1);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsLeft), nsrect.left);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsTop), nsrect.top);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsRight), nsrect.right - 1);
+		writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsBottom), nsrect.bottom - 1);
 	}
 	return true;
 }
 
+int16 GfxFrameout::kernelObjectIntersect(const reg_t object1, const reg_t object2) const {
+	Common::Rect nsrect1, nsrect2;
+
+	bool found1 = getNowSeenRect(object1, nsrect1);
+	bool found2 = getNowSeenRect(object2, nsrect2);
+
+	// If both objects were not found, SSCI would probably return an
+	// intersection area of 1 since SSCI's invalid/uninitialized rect has an
+	// area of 1. We (mostly) ignore that corner case here.
+	if (!found1 && !found2)
+		warning("Both objects not found in kObjectIntersect");
+
+	// If one object was not found, SSCI would use its invalid/uninitialized
+	// rect for it, which is at coordinates 0x89ABCDEF. This can't intersect
+	// valid rects, so we return 0.
+	if (!found1 || !found2)
+		return 0;
+
+	const Common::Rect intersection = nsrect1.findIntersectingRect(nsrect2);
+
+	return intersection.width() * intersection.height();
+}
+
 void GfxFrameout::remapMarkRedraw() {
 	for (PlaneList::const_iterator it = _planes.begin(); it != _planes.end(); ++it) {
 		Plane *p = *it;
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index 26732d5..93dc35e 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -66,6 +66,7 @@ public:
 #pragma mark Screen items
 private:
 	void remapMarkRedraw();
+	bool getNowSeenRect(const reg_t screenItemObject, Common::Rect &result) const;
 
 public:
 	/**
@@ -97,6 +98,7 @@ public:
 	void kernelUpdateScreenItem(const reg_t object);
 	void kernelDeleteScreenItem(const reg_t object);
 	bool kernelSetNowSeen(const reg_t screenItemObject) const;
+	int16 kernelObjectIntersect(const reg_t object1, const reg_t object2) const;
 
 #pragma mark -
 #pragma mark Planes





More information about the Scummvm-git-logs mailing list