[Scummvm-cvs-logs] SF.net SVN: scummvm:[55879] scummvm/trunk/engines/hugo

strangerke at users.sourceforge.net strangerke at users.sourceforge.net
Fri Feb 11 08:12:29 CET 2011


Revision: 55879
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55879&view=rev
Author:   strangerke
Date:     2011-02-11 07:12:29 +0000 (Fri, 11 Feb 2011)

Log Message:
-----------
HUGO: refactoring: move boundaries to object class

Modified Paths:
--------------
    scummvm/trunk/engines/hugo/display.cpp
    scummvm/trunk/engines/hugo/display.h
    scummvm/trunk/engines/hugo/hugo.cpp
    scummvm/trunk/engines/hugo/hugo.h
    scummvm/trunk/engines/hugo/inventory.h
    scummvm/trunk/engines/hugo/object.cpp
    scummvm/trunk/engines/hugo/object.h
    scummvm/trunk/engines/hugo/object_v1d.cpp
    scummvm/trunk/engines/hugo/object_v1w.cpp
    scummvm/trunk/engines/hugo/object_v2d.cpp
    scummvm/trunk/engines/hugo/object_v3d.cpp
    scummvm/trunk/engines/hugo/route.cpp
    scummvm/trunk/engines/hugo/route.h

Modified: scummvm/trunk/engines/hugo/display.cpp
===================================================================
--- scummvm/trunk/engines/hugo/display.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/display.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -199,14 +199,14 @@
 overlayState_t Screen::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
 	debugC(4, kDebugDisplay, "findOvl()");
 
-	for (; y < seq_p->lines; y++) {              // Each line in object
-		image_pt ovb_p = _vm->getBaseBoundaryOverlay() + ((uint16)(dst_p - _frontBuffer) >> 3);  // Ptr into overlay bits
-		if (*ovb_p & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
-			return FG;                              // Found a bit - must be foreground
+	for (; y < seq_p->lines; y++) {                 // Each line in object
+		byte ovb = _vm->_object->getBaseBoundary((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
+		if (ovb & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
+			return kOvlForeground;                  // Found a bit - must be foreground
 		dst_p += kXPix;
 	}
 
-	return BG;                                      // No bits set, must be background
+	return kOvlBackground;                          // No bits set, must be background
 }
 
 /**
@@ -218,19 +218,17 @@
 
 	image_pt image = seq->imagePtr;                 // Ptr to object image data
 	image_pt subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer
-	image_pt overlay = &_vm->getFirstOverlay()[(sy * kXPix + sx) >> 3]; // Ptr to overlay data
 	int16 frontBufferwrap = kXPix - seq->x2 - 1;     // Wraps dest_p after each line
 	int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1;
-
-	overlayState_t overlayState = UNDEF;            // Overlay state of object
+	overlayState_t overlayState = kOvlUndef;        // Overlay state of object
 	for (uint16 y = 0; y < seq->lines; y++) {       // Each line in object
 		for (uint16 x = 0; x <= seq->x2; x++) {
 			if (*image) {                           // Non-transparent
-				overlay = _vm->getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3);       // Ptr into overlay bits
-				if (*overlay & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) {   // Overlay bit is set
-					if (overlayState == UNDEF)      // Overlay defined yet?
+				byte ovlBound = _vm->_object->getFirstOverlay((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
+				if (ovlBound & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set
+					if (overlayState == kOvlUndef)  // Overlay defined yet?
 						overlayState = findOvl(seq, subFrontBuffer, y);// No, find it.
-					if (foreFl || overlayState == FG)   // Object foreground
+					if (foreFl || overlayState == kOvlForeground) // Object foreground
 						*subFrontBuffer = *image;   // Copy pixel
 				} else {                            // No overlay
 					*subFrontBuffer = *image;       // Copy pixel

Modified: scummvm/trunk/engines/hugo/display.h
===================================================================
--- scummvm/trunk/engines/hugo/display.h	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/display.h	2011-02-11 07:12:29 UTC (rev 55879)
@@ -34,14 +34,8 @@
 #define HUGO_DISPLAY_H
 
 namespace Hugo {
-enum overlayState_t {UNDEF, FG, BG};                // Overlay state
+enum overlayState_t {kOvlUndef, kOvlForeground, kOvlBackground}; // Overlay state
 
-static const int kShapeSize = 24;
-static const int kFontLength = 128;                 // Number of chars in font
-static const int kFontSize = 1200;                  // Max size of font data
-static const int kNumFonts = 3;                     // Number of dib fonts
-static const int kCenter = -1;                      // Used to center text in x
-
 struct rect_t {                                     // Rectangle used in Display list
 	int16 x;                                        // Position in dib
 	int16 y;                                        // Position in dib
@@ -49,6 +43,8 @@
 	int16 dy;                                       // height
 };
 
+static const int kCenter = -1;                      // Used to center text in x
+
 /**
  * A black and white Windows-style arrow cursor (12x20).
  * 0 = Black (#000000 in 24-bit RGB).
@@ -56,7 +52,6 @@
  * 15 = White (#FFFFFF in 24-bit RGB).
  * This cursor comes from Mohawk engine.
  */
-
 static const byte stdMouseCursor[] = {
 	0, 0,  1,  1,  1,  1,  1,  1,  1,  1,  1, 1,
 	0, 15, 0,  1,  1,  1,  1,  1,  1,  1,  1, 1,
@@ -79,8 +74,6 @@
 	1, 1,  1,  1,  1,  1,  1,  0,  15, 15, 0, 1,
 	1, 1,  1,  1,  1,  1,  1,  1,  0,  0,  1, 1
 };
-static const byte stdMouseCursorHeight = 20;
-static const byte stdMouseCursorWidth = 12;
 
 class Screen {
 public:
@@ -145,6 +138,12 @@
 
 	static const int kRectListSize = 16;            // Size of add/restore rect lists
 	static const int kBlitListSize = kRectListSize * 2; // Size of dirty rect blit list
+	static const int kShapeSize = 24;
+	static const int kFontLength = 128;             // Number of chars in font
+	static const int kFontSize = 1200;              // Max size of font data
+	static const int kNumFonts = 3;                 // Number of dib fonts
+	static const byte stdMouseCursorHeight = 20;
+	static const byte stdMouseCursorWidth = 12;
 
 	inline bool isInX(const int16 x, const rect_t *rect) const;
 	inline bool isInY(const int16 y, const rect_t *rect) const;

Modified: scummvm/trunk/engines/hugo/hugo.cpp
===================================================================
--- scummvm/trunk/engines/hugo/hugo.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/hugo.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -50,11 +50,6 @@
 
 HugoEngine *HugoEngine::s_Engine = 0;
 
-overlay_t HugoEngine::_boundary;
-overlay_t HugoEngine::_overlay;
-overlay_t HugoEngine::_ovlBase;
-overlay_t HugoEngine::_objBound;
-
 maze_t      _maze;                              // Default to not in maze 
 hugo_boot_t _boot;                              // Boot info structure file
 
@@ -855,150 +850,17 @@
 
 	_file->readBackground(screenNum);               // Scenery file
 	memcpy(_screen->getBackBuffer(), _screen->getFrontBuffer(), sizeof(_screen->getFrontBuffer())); // Make a copy
-	_file->readOverlay(screenNum, _boundary, kOvlBoundary); // Boundary file
-	_file->readOverlay(screenNum, _overlay, kOvlOverlay);   // Overlay file
-	_file->readOverlay(screenNum, _ovlBase, kOvlBase);      // Overlay base file
+	_file->readOverlay(screenNum, _object->_boundary, kOvlBoundary); // Boundary file
+	_file->readOverlay(screenNum, _object->_overlay, kOvlOverlay);   // Overlay file
+	_file->readOverlay(screenNum, _object->_ovlBase, kOvlBase);      // Overlay base file
 
 	// Suppress a boundary used in H3 DOS in 'Crash' screen, which blocks
 	// pathfinding and is useless.
 	if ((screenNum == 0) && (_gameVariant == kGameVariantH3Dos))
-		clearScreenBoundary(50, 311, 152);
+		_object->clearScreenBoundary(50, 311, 152);
 }
 
 /**
-* Return maximum allowed movement (from zero to vx) such that object does
-* not cross a boundary (either background or another object)
-*/
-int HugoEngine::deltaX(const int x1, const int x2, const int vx, int y) const {
-// Explanation of algorithm:  The boundaries are drawn as contiguous
-// lines 1 pixel wide.  Since DX,DY are not necessarily 1, we must
-// detect boundary crossing.  If vx positive, examine each pixel from
-// x1 old to x2 new, else x2 old to x1 new, both at the y2 line.
-// If vx zero, no need to check.  If vy non-zero then examine each
-// pixel on the line segment x1 to x2 from y old to y new.
-// Fix from Hugo I v1.5:
-// Note the diff is munged in the return statement to cater for a special
-// cases arising from differences in image widths from one sequence to
-// another.  The problem occurs reversing direction at a wall where the
-// new image intersects before the object can move away.  This is cured
-// by comparing the intersection with half the object width pos. If the
-// intersection is in the other half wrt the intended direction, use the
-// desired vx, else use the computed delta.  i.e. believe the desired vx
-
-	debugC(3, kDebugEngine, "deltaX(%d, %d, %d, %d)", x1, x2, vx, y);
-
-	if (vx == 0)
-		return 0;                                  // Object stationary
-
-	y *= kCompLineSize;                             // Offset into boundary file
-	if (vx > 0) {
-		// Moving to right
-		for (int i = x1 >> 3; i <= (x2 + vx) >> 3; i++) {// Search by byte
-			int b = Utils::firstBit((byte)(_boundary[y + i] | _objBound[y + i]));
-			if (b < 8) {   // b is index or 8
-				// Compute x of boundary and test if intersection
-				b += i << 3;
-				if ((b >= x1) && (b <= x2 + vx))
-					return (b < x1 + ((x2 - x1) >> 1)) ? vx : b - x2 - 1; // return dx
-			}
-		}
-	} else {
-		// Moving to left
-		for (int i = x2 >> 3; i >= (x1 + vx) >> 3; i--) {// Search by byte
-			int b = Utils::lastBit((byte)(_boundary[y + i] | _objBound[y + i]));
-			if (b < 8) {    // b is index or 8
-				// Compute x of boundary and test if intersection
-				b += i << 3;
-				if ((b >= x1 + vx) && (b <= x2))
-					return (b > x1 + ((x2 - x1) >> 1)) ? vx : b - x1 + 1; // return dx
-			}
-		}
-	}
-	return vx;
-}
-
-/**
-* Similar to Delta_x, but for movement in y direction.  Special case of
-* bytes at end of line segment; must only count boundary bits falling on
-* line segment.
-*/
-int HugoEngine::deltaY(const int x1, const int x2, const int vy, const int y) const {
-	debugC(3, kDebugEngine, "deltaY(%d, %d, %d, %d)", x1, x2, vy, y);
-
-	if (vy == 0)
-		return 0;                                   // Object stationary
-
-	int inc = (vy > 0) ? 1 : -1;
-	for (int j = y + inc; j != (y + vy + inc); j += inc) { //Search by byte
-		for (int i = x1 >> 3; i <= x2 >> 3; i++) {
-			int b = _boundary[j * kCompLineSize + i] | _objBound[j * kCompLineSize + i];
-			if (b != 0) {                           // Any bit set
-				// Make sure boundary bits fall on line segment
-				if (i == (x2 >> 3))                 // Adjust right end
-					b &= 0xff << ((i << 3) + 7 - x2);
-				else if (i == (x1 >> 3))            // Adjust left end
-					b &= 0xff >> (x1 - (i << 3));
-				if (b)
-					return j - y - inc;
-			}
-		}
-	}
-	return vy;
-}
-
-/**
-* Store a horizontal line segment in the object boundary file
-*/
-void HugoEngine::storeBoundary(const int x1, const int x2, const int y) {
-	debugC(5, kDebugEngine, "storeBoundary(%d, %d, %d)", x1, x2, y);
-
-	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
-		byte *b = &_objBound[y * kCompLineSize + i];// get boundary byte
-		if (i == x2 >> 3)                           // Adjust right end
-			*b |= 0xff << ((i << 3) + 7 - x2);
-		else if (i == x1 >> 3)                      // Adjust left end
-			*b |= 0xff >> (x1 - (i << 3));
-		else
-			*b = 0xff;
-	}
-}
-
-/**
-* Clear a horizontal line segment in the object boundary file
-*/
-void HugoEngine::clearBoundary(const int x1, const int x2, const int y) {
-	debugC(5, kDebugEngine, "clearBoundary(%d, %d, %d)", x1, x2, y);
-
-	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
-		byte *b = &_objBound[y * kCompLineSize + i];// get boundary byte
-		if (i == x2 >> 3)                           // Adjust right end
-			*b &= ~(0xff << ((i << 3) + 7 - x2));
-		else if (i == x1 >> 3)                      // Adjust left end
-			*b &= ~(0xff >> (x1 - (i << 3)));
-		else
-			*b = 0;
-	}
-}
-
-/**
-* Clear a horizontal line segment in the screen boundary file
-* Used to fix some data issues
-*/
-void HugoEngine::clearScreenBoundary(const int x1, const int x2, const int y) {
-	debugC(5, kDebugEngine, "clearScreenBoundary(%d, %d, %d)", x1, x2, y);
-
-	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
-		byte *b = &_boundary[y * kCompLineSize + i];// get boundary byte
-		if (i == x2 >> 3)                           // Adjust right end
-			*b &= ~(0xff << ((i << 3) + 7 - x2));
-		else if (i == x1 >> 3)                      // Adjust left end
-			*b &= ~(0xff >> (x1 - (i << 3)));
-		else
-			*b = 0;
-	}
-}
-
-/**
 * Search background command list for this screen for supplied object.
 * Return first associated verb (not "look") or 0 if none found.
 */
@@ -1040,42 +902,6 @@
 }
 
 /**
-* An object has collided with a boundary. See if any actions are required
-*/
-void HugoEngine::boundaryCollision(object_t *obj) {
-	debugC(1, kDebugEngine, "boundaryCollision");
-
-	if (obj == _hero) {
-		// Hotspots only relevant to HERO
-		int x;
-		if (obj->vx > 0)
-			x = obj->x + obj->currImagePtr->x2;
-		else
-			x = obj->x + obj->currImagePtr->x1;
-		int y = obj->y + obj->currImagePtr->y2;
-
-		for (int i = 0; _hotspots[i].screenIndex >= 0; i++) {
-			hotspot_t *hotspot = &_hotspots[i];
-			if (hotspot->screenIndex == obj->screenIndex)
-				if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) {
-					_scheduler->insertActionList(hotspot->actIndex);
-					break;
-				}
-		}
-	} else {
-		// Check whether an object collided with HERO
-		int dx = _hero->x + _hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1;
-		int dy = _hero->y + _hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2;
-		// If object's radius is infinity, use a closer value
-		int8 radius = obj->radius;
-		if (radius < 0)
-			radius = kStepDx * 2;
-		if ((abs(dx) <= radius) && (abs(dy) <= radius))
-			_scheduler->insertActionList(obj->actIndex);
-	}
-}
-
-/**
 * Add up all the object values and all the bonus points
 */
 void HugoEngine::calcMaxScore() {

Modified: scummvm/trunk/engines/hugo/hugo.h
===================================================================
--- scummvm/trunk/engines/hugo/hugo.h	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/hugo.h	2011-02-11 07:12:29 UTC (rev 55879)
@@ -141,11 +141,6 @@
 enum vstate_t {kViewIdle, kViewIntroInit, kViewIntro, kViewPlay, kViewInvent, kViewExit};
 
 /**
-* Purpose of an automatic route
-*/
-enum go_t {kRouteSpace, kRouteExit, kRouteLook, kRouteGet};
-
-/**
 * Enumerate whether object is foreground, background or 'floating'
 * If floating, HERO can collide with it and fore/back ground is determined
 * by relative y-coord of object base.  This is the general case.
@@ -305,37 +300,18 @@
 
 	char *useBG(const char *name);
 
-	int  deltaX(const int x1, const int x2, const int vx, int y) const;
-	int  deltaY(const int x1, const int x2, const int vy, const int y) const;
-
 	int8 getTPS() const;
 
 	void initGame(const HugoGameDescription *gd);
 	void initGamePart(const HugoGameDescription *gd);
-	void boundaryCollision(object_t *obj);
-	void clearBoundary(const int x1, const int x2, const int y);
-	void clearScreenBoundary(const int x1, const int x2, const int y);
 	void endGame();
 	void initStatus();
 	void readScreenFiles(const int screen);
 	void screenActions(const int screen);
 	void setNewScreen(const int screen);
 	void shutdown();
-	void storeBoundary(const int x1, const int x2, const int y);
 	void syncSoundSettings();
 
-	overlay_t &getBoundaryOverlay() {
-		return _boundary;
-	}
-	overlay_t &getObjectBoundaryOverlay() {
-		return _objBound;
-	}
-	overlay_t &getBaseBoundaryOverlay() {
-		return _ovlBase;
-	}
-	overlay_t &getFirstOverlay() {
-		return _overlay;
-	}
 	status_t &getGameStatus() {
 		return _status;
 	}
@@ -407,14 +383,6 @@
 // foreground stationary objects and baselines for those objects (used to
 // determine foreground/background wrt moving objects)
 
-// Vinterstum: These shouldn't be static, but we get weird pathfinding issues (and Valgrind warnings) without.
-// Needs more investigation. Alignment issues?
-
-	static overlay_t _boundary;                     // Boundary overlay file
-	static overlay_t _overlay;                      // First overlay file
-	static overlay_t _ovlBase;                      // First overlay base file
-	static overlay_t _objBound;                     // Boundary file marks object baselines
-
 	GameType _gameType;
 	Common::Platform _platform;
 	bool _packedFl;

Modified: scummvm/trunk/engines/hugo/inventory.h
===================================================================
--- scummvm/trunk/engines/hugo/inventory.h	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/inventory.h	2011-02-11 07:12:29 UTC (rev 55879)
@@ -44,9 +44,9 @@
 	InventoryHandler(HugoEngine *vm);
 
 	void     setInventoryObjId(int16 objId)    { _inventoryObjId = objId; }
-	int16    getInventoryObjId()               { return _inventoryObjId;  }
 	void     setInventoryState(istate_t state) { _inventoryState = state; }
-	istate_t getInventoryState()               { return _inventoryState;  }
+	int16    getInventoryObjId() const         { return _inventoryObjId;  }
+	istate_t getInventoryState() const         { return _inventoryState;  }
 
 	int16 processInventory(const invact_t action, ...);
 	void runInventory();

Modified: scummvm/trunk/engines/hugo/object.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -50,6 +50,10 @@
 ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0) {
 	_numObj = 0;
 	_objCount = 0;
+	memset(_objBound, '\0', sizeof(overlay_t));
+	memset(_boundary, '\0', sizeof(overlay_t));
+	memset(_overlay,  '\0', sizeof(overlay_t));
+	memset(_ovlBase,  '\0', sizeof(overlay_t));
 }
 
 ObjectHandler::~ObjectHandler() {
@@ -591,7 +595,176 @@
 
 bool ObjectHandler::checkBoundary(int16 x, int16 y) {
 	// Check if Boundary bit set
-	return (_vm->getBoundaryOverlay()[y * kCompLineSize + x / 8] & (0x80 >> x % 8)) != 0;
+	return (_boundary[y * kCompLineSize + x / 8] & (0x80 >> x % 8)) != 0;
 }
 
+/**
+* Return maximum allowed movement (from zero to vx) such that object does
+* not cross a boundary (either background or another object)
+*/
+int ObjectHandler::deltaX(const int x1, const int x2, const int vx, int y) const {
+// Explanation of algorithm:  The boundaries are drawn as contiguous
+// lines 1 pixel wide.  Since DX,DY are not necessarily 1, we must
+// detect boundary crossing.  If vx positive, examine each pixel from
+// x1 old to x2 new, else x2 old to x1 new, both at the y2 line.
+// If vx zero, no need to check.  If vy non-zero then examine each
+// pixel on the line segment x1 to x2 from y old to y new.
+// Fix from Hugo I v1.5:
+// Note the diff is munged in the return statement to cater for a special
+// cases arising from differences in image widths from one sequence to
+// another.  The problem occurs reversing direction at a wall where the
+// new image intersects before the object can move away.  This is cured
+// by comparing the intersection with half the object width pos. If the
+// intersection is in the other half wrt the intended direction, use the
+// desired vx, else use the computed delta.  i.e. believe the desired vx
+
+	debugC(3, kDebugEngine, "deltaX(%d, %d, %d, %d)", x1, x2, vx, y);
+
+	if (vx == 0)
+		return 0;                                  // Object stationary
+
+	y *= kCompLineSize;                             // Offset into boundary file
+	if (vx > 0) {
+		// Moving to right
+		for (int i = x1 >> 3; i <= (x2 + vx) >> 3; i++) {// Search by byte
+			int b = Utils::firstBit((byte)(_boundary[y + i] | _objBound[y + i]));
+			if (b < 8) {   // b is index or 8
+				// Compute x of boundary and test if intersection
+				b += i << 3;
+				if ((b >= x1) && (b <= x2 + vx))
+					return (b < x1 + ((x2 - x1) >> 1)) ? vx : b - x2 - 1; // return dx
+			}
+		}
+	} else {
+		// Moving to left
+		for (int i = x2 >> 3; i >= (x1 + vx) >> 3; i--) {// Search by byte
+			int b = Utils::lastBit((byte)(_boundary[y + i] | _objBound[y + i]));
+			if (b < 8) {    // b is index or 8
+				// Compute x of boundary and test if intersection
+				b += i << 3;
+				if ((b >= x1 + vx) && (b <= x2))
+					return (b > x1 + ((x2 - x1) >> 1)) ? vx : b - x1 + 1; // return dx
+			}
+		}
+	}
+	return vx;
+}
+
+/**
+* Similar to Delta_x, but for movement in y direction.  Special case of
+* bytes at end of line segment; must only count boundary bits falling on
+* line segment.
+*/
+int ObjectHandler::deltaY(const int x1, const int x2, const int vy, const int y) const {
+	debugC(3, kDebugEngine, "deltaY(%d, %d, %d, %d)", x1, x2, vy, y);
+
+	if (vy == 0)
+		return 0;                                   // Object stationary
+
+	int inc = (vy > 0) ? 1 : -1;
+	for (int j = y + inc; j != (y + vy + inc); j += inc) { //Search by byte
+		for (int i = x1 >> 3; i <= x2 >> 3; i++) {
+			int b = _boundary[j * kCompLineSize + i] | _objBound[j * kCompLineSize + i];
+			if (b != 0) {                           // Any bit set
+				// Make sure boundary bits fall on line segment
+				if (i == (x2 >> 3))                 // Adjust right end
+					b &= 0xff << ((i << 3) + 7 - x2);
+				else if (i == (x1 >> 3))            // Adjust left end
+					b &= 0xff >> (x1 - (i << 3));
+				if (b)
+					return j - y - inc;
+			}
+		}
+	}
+	return vy;
+}
+
+/**
+* Store a horizontal line segment in the object boundary file
+*/
+void ObjectHandler::storeBoundary(const int x1, const int x2, const int y) {
+	debugC(5, kDebugEngine, "storeBoundary(%d, %d, %d)", x1, x2, y);
+
+	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
+		byte *b = &_objBound[y * kCompLineSize + i];// get boundary byte
+		if (i == x2 >> 3)                           // Adjust right end
+			*b |= 0xff << ((i << 3) + 7 - x2);
+		else if (i == x1 >> 3)                      // Adjust left end
+			*b |= 0xff >> (x1 - (i << 3));
+		else
+			*b = 0xff;
+	}
+}
+
+/**
+* Clear a horizontal line segment in the object boundary file
+*/
+void ObjectHandler::clearBoundary(const int x1, const int x2, const int y) {
+	debugC(5, kDebugEngine, "clearBoundary(%d, %d, %d)", x1, x2, y);
+
+	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
+		byte *b = &_objBound[y * kCompLineSize + i];// get boundary byte
+		if (i == x2 >> 3)                           // Adjust right end
+			*b &= ~(0xff << ((i << 3) + 7 - x2));
+		else if (i == x1 >> 3)                      // Adjust left end
+			*b &= ~(0xff >> (x1 - (i << 3)));
+		else
+			*b = 0;
+	}
+}
+
+/**
+* Clear a horizontal line segment in the screen boundary file
+* Used to fix some data issues
+*/
+void ObjectHandler::clearScreenBoundary(const int x1, const int x2, const int y) {
+	debugC(5, kDebugEngine, "clearScreenBoundary(%d, %d, %d)", x1, x2, y);
+
+	for (int i = x1 >> 3; i <= x2 >> 3; i++) {      // For each byte in line
+		byte *b = &_boundary[y * kCompLineSize + i];// get boundary byte
+		if (i == x2 >> 3)                           // Adjust right end
+			*b &= ~(0xff << ((i << 3) + 7 - x2));
+		else if (i == x1 >> 3)                      // Adjust left end
+			*b &= ~(0xff >> (x1 - (i << 3)));
+		else
+			*b = 0;
+	}
+}
+
+/**
+* An object has collided with a boundary. See if any actions are required
+*/
+void ObjectHandler::boundaryCollision(object_t *obj) {
+	debugC(1, kDebugEngine, "boundaryCollision");
+
+	if (obj == _vm->_hero) {
+		// Hotspots only relevant to HERO
+		int x;
+		if (obj->vx > 0)
+			x = obj->x + obj->currImagePtr->x2;
+		else
+			x = obj->x + obj->currImagePtr->x1;
+		int y = obj->y + obj->currImagePtr->y2;
+
+		for (int i = 0; _vm->_hotspots[i].screenIndex >= 0; i++) {
+			hotspot_t *hotspot = &_vm->_hotspots[i];
+			if (hotspot->screenIndex == obj->screenIndex)
+				if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) {
+					_vm->_scheduler->insertActionList(hotspot->actIndex);
+					break;
+				}
+		}
+	} else {
+		// Check whether an object collided with HERO
+		int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1;
+		int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2;
+		// If object's radius is infinity, use a closer value
+		int8 radius = obj->radius;
+		if (radius < 0)
+			radius = kStepDx * 2;
+		if ((abs(dx) <= radius) && (abs(dy) <= radius))
+			_vm->_scheduler->insertActionList(obj->actIndex);
+	}
+}
+
 } // End of namespace Hugo

Modified: scummvm/trunk/engines/hugo/object.h
===================================================================
--- scummvm/trunk/engines/hugo/object.h	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object.h	2011-02-11 07:12:29 UTC (rev 55879)
@@ -42,9 +42,26 @@
 	ObjectHandler(HugoEngine *vm);
 	virtual ~ObjectHandler();
 
+	overlay_t _objBound;
+	overlay_t _boundary;                            // Boundary overlay file
+	overlay_t _overlay;                             // First overlay file
+	overlay_t _ovlBase;                             // First overlay base file
+
 	object_t  *_objects;
 	uint16    _numObj;
 
+	byte getBoundaryOverlay(uint16 index) const { return _boundary[index]; }
+	byte getObjectBoundary(uint16 index)  const { return _objBound[index]; }
+	byte getBaseBoundary(uint16 index)    const { return _ovlBase[index];  }
+	byte getFirstOverlay(uint16 index)    const { return _overlay[index];  }
+
+	int  deltaX(const int x1, const int x2, const int vx, int y) const;
+	int  deltaY(const int x1, const int x2, const int vy, const int y) const;
+	void boundaryCollision(object_t *obj);
+	void clearBoundary(const int x1, const int x2, const int y);
+	void clearScreenBoundary(const int x1, const int x2, const int y);
+	void storeBoundary(const int x1, const int x2, const int y);
+
 	virtual void homeIn(const int objIndex1, const int objIndex2, const int8 objDx, const int8 objDy) = 0;
 	virtual void moveObjects() = 0;
 	virtual void updateImages() = 0;

Modified: scummvm/trunk/engines/hugo/object_v1d.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object_v1d.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object_v1d.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -224,7 +224,7 @@
 						obj->cycling = kCycleForward;
 				} else {
 					obj->cycling = kCycleNotCycling;
-					_vm->boundaryCollision(obj);    // Must have got hero!
+					boundaryCollision(obj);         // Must have got hero!
 				}
 				obj->oldvx = obj->vx;
 				obj->oldvy = obj->vy;
@@ -267,7 +267,7 @@
 			}
 			// Store boundaries
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+				storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
 		}
 	}
 
@@ -287,25 +287,25 @@
 			int y2 = obj->y + currImage->y2;        // Bottom edge
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->clearBoundary(x1, x2, y2);     // Clear our own boundary
+				clearBoundary(x1, x2, y2);     // Clear our own boundary
 
 			// Allowable motion wrt boundary
-			int dx = _vm->deltaX(x1, x2, obj->vx, y2);
+			int dx = deltaX(x1, x2, obj->vx, y2);
 			if (dx != obj->vx) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vx = 0;
 			}
 
-			int dy = _vm->deltaY(x1, x2, obj->vy, y2);
+			int dy = deltaY(x1, x2, obj->vy, y2);
 			if (dy != obj->vy) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vy = 0;
 			}
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(x1, x2, y2);     // Re-store our own boundary
+				storeBoundary(x1, x2, y2);     // Re-store our own boundary
 
 			obj->x += dx;                           // Update object position
 			obj->y += dy;
@@ -330,7 +330,7 @@
 		object_t *obj = &_objects[i];               // Get pointer to object
 		seq_t *currImage = obj->currImagePtr;       // Get ptr to current image
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-			_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+			clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
 	}
 
 	// If maze mode is enabled, do special maze processing

Modified: scummvm/trunk/engines/hugo/object_v1w.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object_v1w.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object_v1w.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -236,7 +236,7 @@
 					obj->cycling = kCycleForward;
 				} else {
 					obj->cycling = kCycleNotCycling;
-					_vm->boundaryCollision(obj);    // Must have got hero!
+					boundaryCollision(obj);         // Must have got hero!
 				}
 				obj->oldvx = obj->vx;
 				obj->oldvy = obj->vy;
@@ -277,7 +277,7 @@
 			}
 			// Store boundaries
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+				storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
 		}
 	}
 
@@ -297,25 +297,25 @@
 			int y2 = obj->y + currImage->y2;        // Bottom edge
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->clearBoundary(x1, x2, y2);          // Clear our own boundary
+				clearBoundary(x1, x2, y2);          // Clear our own boundary
 
 			// Allowable motion wrt boundary
-			int dx = _vm->deltaX(x1, x2, obj->vx, y2);
+			int dx = deltaX(x1, x2, obj->vx, y2);
 			if (dx != obj->vx) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vx = 0;
 			}
 
-			int dy = _vm->deltaY(x1, x2, obj->vy, y2);
+			int dy = deltaY(x1, x2, obj->vy, y2);
 			if (dy != obj->vy) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vy = 0;
 			}
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(x1, x2, y2);          // Re-store our own boundary
+				storeBoundary(x1, x2, y2);          // Re-store our own boundary
 
 			obj->x += dx;                           // Update object position
 			obj->y += dy;
@@ -340,7 +340,7 @@
 		object_t *obj = &_objects[i];               // Get pointer to object
 		seq_t *currImage = obj->currImagePtr;       // Get ptr to current image
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-			_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+			clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
 	}
 
 	// If maze mode is enabled, do special maze processing

Modified: scummvm/trunk/engines/hugo/object_v2d.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object_v2d.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object_v2d.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -239,7 +239,7 @@
 					obj->cycling = kCycleForward;
 				} else {
 					obj->cycling = kCycleNotCycling;
-					_vm->boundaryCollision(obj);    // Must have got hero!
+					boundaryCollision(obj);         // Must have got hero!
 				}
 				obj->oldvx = obj->vx;
 				obj->oldvy = obj->vy;
@@ -280,7 +280,7 @@
 			}
 			// Store boundaries
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+				storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
 		}
 	}
 
@@ -300,25 +300,25 @@
 			int y2 = obj->y + currImage->y2;        // Bottom edge
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->clearBoundary(x1, x2, y2);     // Clear our own boundary
+				clearBoundary(x1, x2, y2);          // Clear our own boundary
 
 			// Allowable motion wrt boundary
-			int dx = _vm->deltaX(x1, x2, obj->vx, y2);
+			int dx = deltaX(x1, x2, obj->vx, y2);
 			if (dx != obj->vx) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vx = 0;
 			}
 
-			int dy = _vm->deltaY(x1, x2, obj->vy, y2);
+			int dy = deltaY(x1, x2, obj->vy, y2);
 			if (dy != obj->vy) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vy = 0;
 			}
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(x1, x2, y2);     // Re-store our own boundary
+				storeBoundary(x1, x2, y2);          // Re-store our own boundary
 
 			obj->x += dx;                           // Update object position
 			obj->y += dy;
@@ -343,7 +343,7 @@
 		object_t *obj = &_objects[i];                   // Get pointer to object
 		seq_t *currImage = obj->currImagePtr;           // Get ptr to current image
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-			_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+			clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
 	}
 
 	// If maze mode is enabled, do special maze processing

Modified: scummvm/trunk/engines/hugo/object_v3d.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object_v3d.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/object_v3d.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -120,7 +120,7 @@
 					obj->cycling = kCycleForward;
 				} else {
 					obj->cycling = kCycleNotCycling;
-					_vm->boundaryCollision(obj);    // Must have got hero!
+					boundaryCollision(obj);         // Must have got hero!
 				}
 				obj->oldvx = obj->vx;
 				obj->oldvy = obj->vy;
@@ -162,7 +162,7 @@
 			}
 			// Store boundaries
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+				storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
 		}
 	}
 
@@ -182,25 +182,25 @@
 			int y2 = obj->y + currImage->y2;        // Bottom edge
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->clearBoundary(x1, x2, y2);     // Clear our own boundary
+				clearBoundary(x1, x2, y2);          // Clear our own boundary
 
 			// Allowable motion wrt boundary
-			int dx = _vm->deltaX(x1, x2, obj->vx, y2);
+			int dx = deltaX(x1, x2, obj->vx, y2);
 			if (dx != obj->vx) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vx = 0;
 			}
 
-			int dy = _vm->deltaY(x1, x2, obj->vy, y2);
+			int dy = deltaY(x1, x2, obj->vy, y2);
 			if (dy != obj->vy) {
 				// An object boundary collision!
-				_vm->boundaryCollision(obj);
+				boundaryCollision(obj);
 				obj->vy = 0;
 			}
 
 			if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-				_vm->storeBoundary(x1, x2, y2);     // Re-store our own boundary
+				storeBoundary(x1, x2, y2);          // Re-store our own boundary
 
 			obj->x += dx;                           // Update object position
 			obj->y += dy;
@@ -225,7 +225,7 @@
 		object_t *obj = &_objects[i];               // Get pointer to object
 		seq_t *currImage = obj->currImagePtr;       // Get ptr to current image
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
-			_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+			clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
 	}
 
 	// If maze mode is enabled, do special maze processing

Modified: scummvm/trunk/engines/hugo/route.cpp
===================================================================
--- scummvm/trunk/engines/hugo/route.cpp	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/route.cpp	2011-02-11 07:12:29 UTC (rev 55879)
@@ -329,21 +329,22 @@
 	int i;
 	for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_object->_numObj; i++, obj++) {
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating))
-			_vm->storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
+			_vm->_object->storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
 	}
 
 	// Combine objbound and boundary bitmaps to local byte map
-	for (int16 y = 0; y < kYPix; y++) {
-		for (int16 x = 0; x < kCompLineSize; x++) {
+	for (uint16 y = 0; y < kYPix; y++) {
+		for (uint16 x = 0; x < kCompLineSize; x++) {
+			uint16 boundIdx = y * kCompLineSize + x;
 			for (i = 0; i < 8; i++)
-				_boundaryMap[y][x * 8 + i] = ((_vm->getObjectBoundaryOverlay()[y * kCompLineSize + x] | _vm->getBoundaryOverlay()[y * kCompLineSize + x]) & (0x80 >> i)) ? kMapBound : 0;
+				_boundaryMap[y][x * 8 + i] = ((_vm->_object->getObjectBoundary(boundIdx) | _vm->_object->getBoundaryOverlay(boundIdx)) & (0x80 >> i)) ? kMapBound : 0;
 		}
 	}
 
 	// Clear all object baselines from objbound
 	for (i = 0, obj = _vm->_object->_objects; i < _vm->_object->_numObj; i++, obj++) {
 		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating))
-			_vm->clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
+			_vm->_object->clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
 	}
 
 	// Search from hero to destination

Modified: scummvm/trunk/engines/hugo/route.h
===================================================================
--- scummvm/trunk/engines/hugo/route.h	2011-02-11 05:13:37 UTC (rev 55878)
+++ scummvm/trunk/engines/hugo/route.h	2011-02-11 07:12:29 UTC (rev 55879)
@@ -35,6 +35,11 @@
 
 namespace Hugo {
 
+/**
+* Purpose of an automatic route
+*/
+enum go_t {kRouteSpace, kRouteExit, kRouteLook, kRouteGet};
+
 struct Point {
 	int x;
 	int y;
@@ -49,8 +54,8 @@
 public:
 	Route(HugoEngine *vm);
 
-	void resetRoute()     {_routeIndex = -1; }
-	int16 getRouteIndex() {return _routeIndex; }
+	void  resetRoute()          {_routeIndex = -1;   }
+	int16 getRouteIndex() const {return _routeIndex; }
 
 	void processRoute();
 	bool startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy);


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