[Scummvm-git-logs] scummvm master -> 21e1c4ee9563c3f584e31d7a4207b16e903d20fd

antoniou79 antoniou at cti.gr
Fri May 3 15:24:45 CEST 2019


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:
21e1c4ee95 BLADERUNNER: object, item and region commands


Commit: 21e1c4ee9563c3f584e31d7a4207b16e903d20fd
    https://github.com/scummvm/scummvm/commit/21e1c4ee9563c3f584e31d7a4207b16e903d20fd
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2019-05-03T16:08:07+03:00

Commit Message:
BLADERUNNER: object, item and region commands

New commands to debug bound boxes and properties for obj, items, regions

Changed paths:
    engines/bladerunner/debugger.cpp
    engines/bladerunner/debugger.h
    engines/bladerunner/item.cpp
    engines/bladerunner/item.h
    engines/bladerunner/items.cpp
    engines/bladerunner/items.h
    engines/bladerunner/regions.h


diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 4421a57..aa09469 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -37,6 +37,7 @@
 #include "bladerunner/savefile.h"
 #include "bladerunner/scene.h"
 #include "bladerunner/scene_objects.h"
+#include "bladerunner/items.h"
 #include "bladerunner/screen_effects.h"
 #include "bladerunner/settings.h"
 #include "bladerunner/set.h"
@@ -106,8 +107,9 @@ Debugger::Debugger(BladeRunnerEngine *vm) : GUI::Debugger() {
 	registerCmd("subtitle", WRAP_METHOD(Debugger, cmdSubtitle));
 	registerCmd("vk", WRAP_METHOD(Debugger, cmdVk));
 	registerCmd("mazescore", WRAP_METHOD(Debugger, cmdMazeScore));
-	registerCmd("boundbox", WRAP_METHOD(Debugger, cmdBoundBox));
-	registerCmd("obstacle", WRAP_METHOD(Debugger, cmdObstacle));
+	registerCmd("object", WRAP_METHOD(Debugger, cmdObject));
+	registerCmd("item", WRAP_METHOD(Debugger, cmdItem));
+	registerCmd("region", WRAP_METHOD(Debugger, cmdRegion));
 }
 
 Debugger::~Debugger() {
@@ -1083,7 +1085,7 @@ bool Debugger::cmdSubtitle(int argc, const char **argv) {
 * Toggle showing Maze score on the fly as subtitle during the Police Maze Course
 */
 bool Debugger::cmdMazeScore(int argc, const char **argv) {
-bool invalidSyntax = false;
+	bool invalidSyntax = false;
 
 	if (argc != 2) {
 		invalidSyntax = true;
@@ -1107,25 +1109,399 @@ bool invalidSyntax = false;
 
 	if (invalidSyntax) {
 		debugPrintf("Toggle showing the Maze Score as a subtitle during the Shooting Grounds Course\n");
-		debugPrintf("Usage: %s toggle", argv[0]);
+		debugPrintf("Usage: %s toggle\n", argv[0]);
 	}
 	return true;
 }
 
+
 /**
-* Change Bound box for objects to debug click box optimization
+* Add, remove or edit flags or bounding box for an object to debug some issues whereby existing obstacle layout does not prevent
+* characters from walking where they shouldn't
+*
+* Notes: with regard to Bound box / the clickable area for an object, item or region
+* 1. The code for what a mouse click will refer to is in BladeRunnerEngine::handleMouseAction() -- under if (mainButton) clause
+*    Clickable 3d areas for boxes are determined based on scene information that translates the 2d mouse position into
+*    a "3d" position in the view. (see: Mouse::getXYZ)
+*    This 3d position must be within the bounding box of the 3d object
+*
+* 2. For items, the mouse-over (Item::isUnderMouse) depends on the screenRectangle dimensions (Common::Rect) and specifies the
+*    targetable area for the item. The screenRectangle is calculated at every tick() of the item and depends on the item's animation,
+*    current frame and thus facing angle.
+*    The item's bounding box still determines the clickable area for the item. It is calculated at item's setup() or setXYZ()
+*    and depends on the item's position (vector), height and width.
 */
-bool Debugger::cmdBoundBox(int argc, const char **argv) {
-	// TODO
+bool Debugger::cmdObject(int argc, const char **argv) {
+	bool invalidSyntax = false;
+
+	if (argc < 3) {
+		invalidSyntax = true;
+	} else {
+		Common::String modeName = argv[1];
+		modeName.toLowercase();
+		if (modeName == "add" && argc == 9) {
+			// add object mode
+			// first add to set and then to scene
+			Common::String custObjName = "CUSTOMOBJ";
+			Common::String custObjNameSuffix = argv[2];
+			custObjName = custObjName + custObjNameSuffix;
+			//
+			// plain 3d objects (non-items) are added to the Set by reading the specific data for that Set
+			// Their count is also stored in the Set's data,
+			// if there's a need for a permanent extra obstacle in the Set, the code in set.cpp will have to be overridden (hard coded patch)
+			//
+			// For the debugger's purposes it should be harmless to add custom objects to test blocking pathways or other functions
+			// they will persist in Save/Load but should go away when exiting a Set
+			if (_vm->_scene->_set->_objectCount > 85) { //85 is the size of the _objects array in set.cpp
+				debugPrintf("Unable to add more objects in the set\n");
+			} else {
+				_vm->_scene->_set->_objectCount++;
+				int objectId = _vm->_scene->_set->_objectCount;
+				_vm->_scene->_set->_objects[objectId].name = custObjName.c_str();
+
+				float x0, y0, z0, x1, y1, z1;
+				x0 = atof(argv[3]);
+				y0 = atof(argv[4]);
+				z0 = atof(argv[5]);
+				x1 = atof(argv[6]);
+				y1 = atof(argv[7]);
+				z1 = atof(argv[8]);
+
+				_vm->_scene->_set->_objects[objectId].bbox = BoundingBox(x0, y0, z0, x1, y1, z1);
+				_vm->_scene->_set->_objects[objectId].isObstacle = 0; // init as false
+				_vm->_scene->_set->_objects[objectId].isClickable = 0;// init as false
+				_vm->_scene->_set->_objects[objectId].isHotMouse = 0;
+				_vm->_scene->_set->_objects[objectId].unknown1 = 0;
+				_vm->_scene->_set->_objects[objectId].isTarget = 0;   // init as false
+				//
+				if (_vm->_sceneObjects->addObject(objectId + kSceneObjectOffsetObjects,
+				                                  _vm->_scene->_set->_objects[objectId].bbox,
+				                                  false,
+				                                  false,
+				                                  _vm->_scene->_set->_objects[objectId].unknown1,
+				                                  false)
+				) {
+					debugPrintf("Object: %d: %s was added to set and scene\n", objectId, custObjName.c_str());
+				} else {
+					debugPrintf("Failed to add object: %d: %s to the scene\n", objectId, custObjName.c_str());
+				}
+				return true;
+			}
+		} else if ((modeName == "remove" && argc == 3)
+		            || (modeName == "flags" && argc == 6)
+					|| (modeName == "bounds" && argc == 9)
+		            || (modeName == "list" && argc == 3)
+		) {
+			// remove object mode, show properties or edit flags
+			int objectId = atoi(argv[2]);
+			if (objectId >= 0 && objectId < _vm->_scene->_set->_objectCount) {
+				Common::String objName = _vm->_scene->objectGetName(objectId);
+				if (modeName == "list") {
+					// list properties
+					const BoundingBox &bbox = _vm->_scene->_set->_objects[objectId].bbox;
+					Vector3 a, b;
+					bbox.getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
+					Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
+					// Intentional? When loading a game, in the loaded Scene:
+					// an object can be an non-obstacle as a sceneObject but an obstacle as a Set object.
+					// and this seems to be considered as a non-obstacle by the game in that Scene.
+					// These are objects that the Unobstacle_Object() is called for when a scene is loaded (SceneLoaded())
+					// So the sceneObject property overrides the Set object property in these cases
+					// Eg. in PS01 BOX38 (object id: 19)
+					// This inconsistency is fixed if you exit and re-enter the scene.
+					debugPrintf("%d: %s (Clk: %s, Trg: %s, Obs: %s), Pos(%02.2f,%02.2f,%02.2f)\n     Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
+					            objectId, objName.c_str(),
+					            _vm->_scene->_set->_objects[objectId].isClickable? "T" : "F",
+					            _vm->_scene->_set->_objects[objectId].isTarget?    "T" : "F",
+					            _vm->_scene->_set->_objects[objectId].isObstacle?  "T" : "F",
+					            pos.x, pos.y, pos.z,
+					            a.x, a.y, a.z, b.x, b.y, b.z);
+				} else if (modeName == "remove") {
+					// scene's objectSetIsObstacle will update obstacle and walkpath
+					_vm->_scene->objectSetIsObstacle(objectId, false, !_vm->_sceneIsLoading, true);
+					// remove only from scene objects (keep in Set)
+					if (!_vm->_sceneIsLoading && _vm->_sceneObjects->remove(objectId + kSceneObjectOffsetObjects)) {
+						debugPrintf("Object: %d: %s was removed\n", objectId, objName.c_str());
+					} else {
+						debugPrintf("Failed to remove object: %d: %s\n", objectId, objName.c_str());
+					}
+				} else if (modeName == "bounds") {
+					Vector3 positionBottomRight(atof(argv[3]), atof(argv[4]), atof(argv[5]));
+					Vector3 positionTopLeft(atof(argv[6]), atof(argv[7]), atof(argv[8]));
+					_vm->_scene->_set->_objects[objectId].bbox.setXYZ(positionBottomRight.x, positionBottomRight.y, positionBottomRight.z, positionTopLeft.x, positionTopLeft.y, positionTopLeft.z);
+					if (!_vm->_sceneIsLoading && _vm->_sceneObjects->remove(objectId + kSceneObjectOffsetObjects)){
+						_vm->_sceneObjects->addObject(objectId + kSceneObjectOffsetObjects,
+						                               _vm->_scene->_set->_objects[objectId].bbox,
+						                               _vm->_scene->_set->_objects[objectId].isClickable,
+						                               _vm->_scene->_set->_objects[objectId].isObstacle,
+						                               _vm->_scene->_set->_objects[objectId].unknown1,
+						                               _vm->_scene->_set->_objects[objectId].isTarget);
+						// scene's objectSetIsObstacle will update obstacle and walkpath
+						_vm->_scene->objectSetIsObstacle(objectId, _vm->_scene->_set->_objects[objectId].isObstacle, !_vm->_sceneIsLoading, true);
+						debugPrintf("New bounds: (%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
+						             positionBottomRight.x, positionBottomRight.y, positionBottomRight.z,
+						             positionTopLeft.x,   positionTopLeft.y,   positionTopLeft.z);
+					}
+				} else {
+					// edit flags
+					bool newClickable = atoi(argv[3])? true : false;
+					bool newTarget    = atoi(argv[4])? true : false;
+					bool newObstacle  = atoi(argv[5])? true : false;
+					// scene's objectSetIsObstacle will update obstacle and walkpath
+					_vm->_scene->objectSetIsObstacle(objectId, newObstacle, !_vm->_sceneIsLoading, true);
+					_vm->_scene->objectSetIsClickable(objectId, newClickable, !_vm->_sceneIsLoading);
+					_vm->_scene->objectSetIsTarget(objectId, newTarget, !_vm->_sceneIsLoading);
+
+					debugPrintf("Setting obj %d: %s as clickable: %s, target: %s, obstacle: %s\n", objectId, objName.c_str(), newClickable? "T":"F", newTarget? "T":"F", newObstacle? "T":"F");
+				}
+				return true;
+			} else {
+				debugPrintf("Invalid object id %d was specified\n", objectId);
+				return true;
+			}
+		} else {
+			invalidSyntax = true;
+		}
+	}
+
+	if (invalidSyntax) {
+		debugPrintf("Add, edit flags, bounds or remove a 3d object obstacle in the current scene\n");
+		debugPrintf("Use debugger command List with \"obj\" argument to view available targets for this command\n");
+		debugPrintf("Floats:   brX, brY, brZ, tlX, tlY, tlZ, posX, posY, posZ\n");
+		debugPrintf("Integers: id, incId\n");
+		debugPrintf("Boolean (1: true, 0: false): isObstacle, isClickable, isTarget\n");
+		debugPrintf("Usage 1: %s add    <incId> <brX> <brY> <brZ>  <tlX> <tlY> <tlZ>\n", argv[0]);
+		debugPrintf("Usage 2: %s list   <id>\n", argv[0]);
+		debugPrintf("Usage 3: %s flags  <id> <isClickable> <isTarget> <isObstacle>\n", argv[0]);
+		debugPrintf("Usage 4: %s bounds <id> <brX> <brY> <brZ>  <tlX> <tlY> <tlZ>\n", argv[0]);
+		debugPrintf("Usage 5: %s remove <id>\n", argv[0]);
+	}
 	return true;
 }
 
 /**
-* Add or remove obstacle to debug some issues whereby existing obstacle layout does not prevent
-* characters from walking where they shouldn't
+* Add a new, remove or edit flags and bounds for an existing item
 */
-bool Debugger::cmdObstacle(int argc, const char **argv) {
-	// TODO
+bool Debugger::cmdItem(int argc, const char **argv) {
+	bool invalidSyntax = false;
+
+	if (argc < 3) {
+		invalidSyntax = true;
+	} else {
+		Common::String modeName = argv[1];
+		modeName.toLowercase();
+		int itemId = atoi(argv[2]);
+		if (itemId < 0) {
+			debugPrintf("Invalid item id: %d specified. Item id must be an integer >=0\n", itemId);
+			return true;
+		}
+
+		if (modeName == "add" && argc == 10) {
+			// add item mode
+			if (_vm->_sceneObjects->findById(itemId + kSceneObjectOffsetItems) == -1) {
+				Vector3 itemPosition(atof(argv[3]), atof(argv[4]), atof(argv[5]));
+				int itemFacing = atoi(argv[6]);
+				int itemHeight = atoi(argv[7]);
+				int itemWidth = atoi(argv[8]);
+				int itemAnimationId = atoi(argv[9]);
+				if (_vm->_items->addToWorld(itemId, itemAnimationId, _vm->_scene->_setId, itemPosition, itemFacing, itemHeight, itemWidth, false, true, false, true)) {
+					debugPrintf("Item: %d was added to set and scene\n", itemId);
+				} else {
+					debugPrintf("Failed to add item: %d to the scene\n", itemId);
+				}
+				return true;
+			} else {
+				debugPrintf("Item: %d is already in the scene\n", itemId);
+			}
+		} else if ((modeName == "remove" && argc == 3)
+		            || (modeName == "flags" && argc == 5)
+		            || (modeName == "bounds" && argc == 9)
+		            || (modeName == "list" && argc == 3)
+		) {
+			// remove item mode, show properties or edit flags
+			if (_vm->_sceneObjects->findById(itemId + kSceneObjectOffsetItems) != -1) {
+				if (modeName == "list") {
+					// list properties
+					float xpos_curr, ypos_curr, zpos_curr, x0_curr, y0_curr, z0_curr, x1_curr, y1_curr, z1_curr;
+					int currHeight, currWidth;
+					int itemAnimationId;
+					int facing_curr = _vm->_items->getFacing(itemId);
+					_vm->_items->getWidthHeight(itemId, &currWidth, &currHeight);
+					_vm->_items->getXYZ(itemId, &xpos_curr, &ypos_curr, &zpos_curr );
+					_vm->_items->getBoundingBox(itemId).getXYZ(&x0_curr, &y0_curr, &z0_curr, &x1_curr, &y1_curr, &z1_curr);
+					_vm->_items->getAnimationId(itemId, &itemAnimationId);
+					const Common::Rect &screenRect = _vm->_items->getScreenRectangle(itemId);
+					debugPrintf("Item %d (Trg: %s, Vis/Clk: %s) Pos(%02.2f,%02.2f,%02.2f), Face: %d, Height: %d, Width: %d AnimId: %d\n ScrRct(%d,%d,%d,%d) Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
+					            itemId,
+					            _vm->_items->isTarget(itemId)?  "T" : "F",
+					            _vm->_items->isVisible(itemId)? "T" : "F",
+					            xpos_curr, ypos_curr, zpos_curr,
+					            facing_curr, currWidth, currHeight, itemAnimationId,
+					            screenRect.top, screenRect.left, screenRect.bottom, screenRect.right,
+					            x0_curr, y0_curr, z0_curr, x1_curr, y1_curr, z1_curr);
+				} else if (modeName == "remove") {
+					if (_vm->_sceneObjects->remove(itemId + kSceneObjectOffsetItems)) {
+						debugPrintf("Item: %d was removed\n", itemId);
+					} else {
+						debugPrintf("Failed to remove item: %d\n", itemId);
+					}
+				} else if (modeName == "bounds") {
+					// change position and facing to affect the screen rectangle
+					Vector3 newPosition(atof(argv[3]), atof(argv[4]), atof(argv[5]));
+					int newFacing = atoi(argv[6]);
+					int newHeight = atoi(argv[7]);
+					int newWidth =  atoi(argv[8]);
+					//// setXYZ recalculates the item's bounding box
+					//_vm->_items->setXYZ(itemId, newPosition);
+					//// facing affects the angle and thus the screenRect in the next tick()
+					_vm->_items->setFacing(itemId, newFacing);
+					if (_vm->_sceneObjects->remove(itemId + kSceneObjectOffsetItems)) {
+						float x0_new, y0_new, z0_new, x1_new, y1_new, z1_new;
+						bool targetable = _vm->_items->isTarget(itemId);
+						bool obstacle = _vm->_items->isVisible(itemId);
+						bool polizeMazeEnemy = _vm->_items->isPoliceMazeEnemy(itemId);
+						int itemAnimationId = -1;
+						_vm->_items->getAnimationId(itemId, &itemAnimationId);
+						_vm->_items->addToWorld(itemId, itemAnimationId, _vm->_scene->_setId, newPosition, newFacing, newHeight, newWidth, targetable, obstacle, polizeMazeEnemy, true);
+						_vm->_items->getBoundingBox(itemId).getXYZ(&x0_new, &y0_new, &z0_new, &x1_new, &y1_new, &z1_new);
+						debugPrintf("New Pos(%02.2f,%02.2f,%02.2f), Face: %d, Height: %d, Width: %d\n Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
+						            newPosition.x, newPosition.y, newPosition.z,
+						            newFacing, newHeight, newWidth,
+						            x0_new, y0_new, z0_new, x1_new, y1_new, z1_new);
+					}
+				} else {
+					// edit flags
+					bool newObstacle  = (atoi(argv[3]) != 0);
+					bool newTarget    = (atoi(argv[4]) != 0);
+					_vm->_items->setIsObstacle(itemId, newObstacle);
+					_vm->_items->setIsTarget(itemId, newTarget);
+					debugPrintf("Setting item %d as visible/clickable: %s and target: %s\n", itemId, newObstacle? "T":"F", newTarget? "T":"F");
+				}
+				return true;
+			} else {
+				debugPrintf("No item was found with the specified id: %d\n", itemId);
+				return true;
+			}
+		} else {
+			invalidSyntax = true;
+		}
+	}
+
+	if (invalidSyntax) {
+		debugPrintf("Add, edit flags, bounds or remove an item in the current scene\n");
+		debugPrintf("Use debugger command List with \"items\" argument to view available targets for this command\n");
+		debugPrintf("Floats:   posX, posY, posZ\n");
+		debugPrintf("Integers: id, facing, height, width, animationId\n");
+		debugPrintf("Boolean (1: true, 0: false): isVisible, isTarget\n");
+		debugPrintf("Usage 1: %s add    <id> <posX> <posY> <posZ> <facing> <height> <width> <animationId>\n", argv[0]);
+		debugPrintf("Usage 2: %s list   <id>\n", argv[0]);
+		debugPrintf("Usage 3: %s flags  <id> <isVisible> <isTarget>\n", argv[0]);
+		debugPrintf("Usage 4: %s bounds <id> <posX> <posY> <posZ>  <facing> <height> <width>\n", argv[0]);
+		debugPrintf("Usage 5: %s remove <id>\n", argv[0]);
+	}
+	return true;
+}
+
+/**
+* Add a new or remove an existing region (plain or exit) into/from a specified slot in the _regions or _exits arrays respectively
+*/
+bool Debugger::cmdRegion(int argc, const char **argv) {
+	bool invalidSyntax = false;
+
+	if (argc < 4) {
+		invalidSyntax = true;
+	} else {
+		Common::String regionTypeName = argv[1];
+		regionTypeName.toLowercase();
+
+		Regions *regions = nullptr;
+		if (regionTypeName == "reg") {
+			regions = _vm->_scene->_regions;
+		} else if (regionTypeName == "exit") {
+			regions = _vm->_scene->_exits;
+		} else {
+			debugPrintf("Invalid region name type was specified: %s\n", regionTypeName.c_str());
+			return true;
+		}
+
+		Common::String modeName = argv[2];
+		modeName.toLowercase();
+		int regionID = atoi(argv[3]);
+		if (regionID < 0 || regionID >= 10) {
+			debugPrintf("A region id has to be an integer within [0, 9]\n");
+			return true;
+		}
+		if (modeName == "add" && ((regionTypeName == "reg" && argc == 8) || (regionTypeName == "exit" && argc == 9)) ){
+			// add region mode
+			if (!regions->_regions[regionID].present) {
+				int type = 0;
+				int topY    = atoi(argv[4]);
+				int leftX   = atoi(argv[5]);
+				int bottomY = atoi(argv[6]);
+				int rightX  = atoi(argv[7]);
+				if (regionTypeName == "exit") {
+					type = atoi(argv[8]);
+				}
+				Common::Rect newRect(topY, leftX, bottomY, rightX);
+				regions->add(regionID, newRect, type);
+				debugPrintf("Adding %s: %d (t:%d l:%d b:%d r:%d) of type %d\n", regionTypeName.c_str(), regionID, newRect.top, newRect.left, newRect.bottom, newRect.right, type);
+				return true;
+			} else {
+				debugPrintf("There already is an %s with the specified id: %d. Please select another slot id\n", regionTypeName.c_str(), regionID);
+				return true;
+			}
+		} else if ((modeName == "remove" && argc == 4)
+		           || (modeName == "list" && argc == 4)
+		           || (modeName == "bounds" && argc == 8)) {
+			if (regions->_regions[regionID].present) {
+				Common::Rect origRect = regions->_regions[regionID].rectangle;
+				int type = regions->_regions[regionID].type;
+				if (modeName == "remove") {
+					if (regions->remove(regionID)) {
+						debugPrintf("Removed %s: %d (t:%d l:%d b:%d r:%d) of type: %d\n", regionTypeName.c_str(), regionID, origRect.top, origRect.left, origRect.bottom, origRect.right, type);
+					} else {
+						debugPrintf("Unable to remove %s: %d for unexpected reasons\n", regionTypeName.c_str(), regionID);
+					}
+				} else if (modeName == "bounds") {
+					int topY, leftX, bottomY, rightX = 0;
+					topY    = atoi(argv[4]);
+					leftX   = atoi(argv[5]);
+					bottomY = atoi(argv[6]);
+					rightX  = atoi(argv[7]);
+
+					if (regions->remove(regionID)) {
+						Common::Rect newRect(topY, leftX, bottomY, rightX);
+						regions->add(regionID, newRect, type);
+						debugPrintf("Bounds %s: %d (t:%d l:%d b:%d r:%d)\n", modeName.c_str(), regionID, newRect.top, newRect.left, newRect.bottom, newRect.right);
+					}
+				} else {
+					// list properties
+					debugPrintf("%s: %d (t:%d l:%d b:%d r:%d) of type: %d\n", regionTypeName.c_str(), regionID, origRect.top, origRect.left, origRect.bottom, origRect.right, type);
+				}
+				return true;
+			} else {
+				debugPrintf("The %s id %d specified does not exist in the scene\n", regionTypeName.c_str(), regionID);
+				return true;
+			}
+		} else {
+			invalidSyntax = true;
+		}
+	}
+
+	if (invalidSyntax) {
+		debugPrintf("Add, edit bounds or remove a region (\"reg\": for plain region, \"exit\": for exit) in the current scene\n");
+		debugPrintf("Use debugger command List with \"reg\" argument to view available targets for this command\n");
+		debugPrintf("An exit type can be in [0, 3] and determines the type of arrow icon on mouse-over\n0: Upward , 1: Right, 2: Downward, 3: Left\n");
+		debugPrintf("Integers: id, topY, leftX, bottomY, rightX, type\n");
+		debugPrintf("Usage 1: %s reg  add    <id> <topY> <leftX> <bottomY> <rightX>\n", argv[0]);
+		debugPrintf("Usage 2: %s reg  remove <id>\n", argv[0]);
+		debugPrintf("Usage 3: %s reg  list   <id>\n", argv[0]);
+		debugPrintf("Usage 4: %s reg  bounds <id> <topY> <leftX> <bottomY> <rightX>\n", argv[0]);
+		debugPrintf("Usage 5: %s exit add    <id> <topY> <leftX> <bottomY> <rightX> <type>\n", argv[0]);
+		debugPrintf("Usage 6: %s exit remove <id>\n", argv[0]);
+		debugPrintf("Usage 7: %s exit list   <id>\n", argv[0]);
+		debugPrintf("Usage 8: %s exit bounds <id> <topY> <leftX> <bottomY> <rightX>\n", argv[0]);
+	}
 	return true;
 }
 
@@ -1168,10 +1544,6 @@ bool Debugger::cmdVk(int argc, const char **argv) {
 *
 * Similar to draw but only list items instead of drawing
 * Maybe keep this separate from the draw command, even though some code gets repeated here
-* DONE: Provide more info (bbox or position)
-* DONE: For actors show current goal too.
-* TODO: For items provide friendly name (enum in constants!)
-* DONE: Split items in items, actors and objects?
 */
 bool Debugger::cmdList(int argc, const char **argv) {
 	if (argc != 2) {
@@ -1188,8 +1560,9 @@ bool Debugger::cmdList(int argc, const char **argv) {
 			SceneObjects::SceneObject *sceneObject = &_vm->_sceneObjects->_sceneObjects[_vm->_sceneObjects->_sceneObjectsSortedByDistance[i]];
 
 			if (sceneObject->type == kSceneObjectTypeActor) {
-				debugPrintf("%02d. %s (Clk: %s, Trg: %s, Prs: %s, Obs: %s, Mvg: %s), Goal: %d, Pos(%02.2f,%02.2f,%02.2f)\n",
-				             count, _vm->_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors),
+				debugPrintf("%d: %s (Clk: %s, Trg: %s, Prs: %s, Obs: %s, Mvg: %s), Goal: %d, Pos(%02.2f,%02.2f,%02.2f)\n",
+				             sceneObject->id - kSceneObjectOffsetActors,
+				             _vm->_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors),
 				             sceneObject->isClickable? "T" : "F",
 				             sceneObject->isTarget?    "T" : "F",
 				             sceneObject->isPresent?   "T" : "F",
@@ -1217,8 +1590,9 @@ bool Debugger::cmdList(int argc, const char **argv) {
 				debugPrintf("%02d. Unknown object type\n", count);
 				++count;
 			} else if (sceneObject->type == kSceneObjectTypeObject) {
-				debugPrintf("%02d. %s (Clk: %s, Trg: %s, Prs: %s, Obs: %s, Mvg: %s), Pos(%02.2f,%02.2f,%02.2f)\n     Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
-				             count, _vm->_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects).c_str(),
+				debugPrintf("%d: %s (Clk: %s, Trg: %s, Prs: %s, Obs: %s, Mvg: %s), Pos(%02.2f,%02.2f,%02.2f)\n     Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
+				             sceneObject->id - kSceneObjectOffsetObjects,
+				             _vm->_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects).c_str(),
 				             sceneObject->isClickable? "T" : "F",
 				             sceneObject->isTarget?    "T" : "F",
 				             sceneObject->isPresent?   "T" : "F",
@@ -1240,41 +1614,49 @@ bool Debugger::cmdList(int argc, const char **argv) {
 				const BoundingBox &bbox = sceneObject->boundingBox;
 				Vector3 a, b;
 				bbox.getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
-				Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
-				char itemText[40];
-				sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems);
-				debugPrintf("%02d. %s (Clk: %s, Trg: %s, Prs: %s, Obs: %s, Mvg: %s), Pos(%02.2f,%02.2f,%02.2f)\n    Bbox(%02.2f,%02.2f,%02.2f) ~ (%02.2f,%02.2f,%02.2f)\n",
-				             count, itemText,
+				//Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
+				Vector3 pos;
+				int currHeight, currWidth;
+				_vm->_items->getXYZ(sceneObject->id - kSceneObjectOffsetItems, &pos.x, &pos.y, &pos.z);
+				_vm->_items->getWidthHeight(sceneObject->id - kSceneObjectOffsetItems, &currWidth, &currHeight);
+				const Common::Rect &screenRect = _vm->_items->getScreenRectangle(sceneObject->id - kSceneObjectOffsetItems);
+				debugPrintf("Id %i, Pos(%02.2f,%02.2f,%02.2f), Face: %d, Height: %d, Width: %d, ScrRct(%d,%d,%d,%d)\n Clk: %s, Trg: %s, Prs: %s, Vis: %s, Mvg: %s Bbox(%02.2f,%02.2f,%02.2f)~(%02.2f,%02.2f,%02.2f)\n",
+				             sceneObject->id - kSceneObjectOffsetItems,
+				             pos.x, pos.y, pos.z,
+				             _vm->_items->getFacing(sceneObject->id - kSceneObjectOffsetItems), currHeight, currWidth,
+				             screenRect.top, screenRect.left, screenRect.bottom, screenRect.right,
 				             sceneObject->isClickable? "T" : "F",
 				             sceneObject->isTarget?    "T" : "F",
 				             sceneObject->isPresent?   "T" : "F",
 				             sceneObject->isObstacle?  "T" : "F",
 				             sceneObject->isMoving?    "T" : "F",
-				             pos.x, pos.y, pos.z,
 				             a.x, a.y, a.z, b.x, b.y, b.z);
 				++count;
 			}
 		}
 		debugPrintf("%d items were found in scene.\n", count);
 	} else if (arg == "reg") {
-		debugPrintf("Listing regions: \n");
+		debugPrintf("Listing plain regions: \n");
 		int count = 0;
 		//list regions
 		for (int i = 0; i < 10; i++) {
 			Regions::Region *region = &_vm->_scene->_regions->_regions[i];
 			if (!region->present) continue;
-			debugPrintf("%02d. Region slot: %d\n", count, i);
+			Common::Rect r = region->rectangle;
+			debugPrintf("Region slot: %d (t:%d l:%d b:%d r:%d)\n", i, r.top, r.left, r.bottom, r.right);
 			++count;
 		}
 
+		debugPrintf("Listing exits: \n");
 		//list exits
 		for (int i = 0; i < 10; i++) {
 			Regions::Region *region = &_vm->_scene->_exits->_regions[i];
 			if (!region->present) continue;
-			debugPrintf("%02d. Exit slot: %d\n", count, i);
+			Common::Rect r = region->rectangle;
+			debugPrintf("Exit slot: %d (t:%d l:%d b:%d r:%d)\n", i, r.top, r.left, r.bottom, r.right);
 			++count;
 		}
-		debugPrintf("%d regions were found in scene.\n", count);
+		debugPrintf("%d regions (plain and exits) were found in scene.\n", count);
 	} else if (arg == "way") {
 		debugPrintf("Listing waypoints: \n");
 		int count = 0;
@@ -1284,7 +1666,8 @@ bool Debugger::cmdList(int argc, const char **argv) {
 				continue;
 			}
 			char waypointText[40];
-			sprintf(waypointText, "waypoint %i", i);
+			Vector3 a = waypoint->position;
+			sprintf(waypointText, "Waypoint %i, Pos(%02.2f,%02.2f,%02.2f)", i, a.x, a.y, a.z);
 			debugPrintf("%02d. %s\n", count, waypointText);
 			++count;
 		}
@@ -1296,7 +1679,8 @@ bool Debugger::cmdList(int argc, const char **argv) {
 				continue;
 			}
 			char coverText[40];
-			sprintf(coverText, "cover %i", i);
+			Vector3 a = cover->position;
+			sprintf(coverText, "Cover %i, Pos(%02.2f,%02.2f,%02.2f)", i, a.x, a.y, a.z);
 			debugPrintf("%02d. %s\n", count, coverText);
 			++count;
 		}
@@ -1308,7 +1692,8 @@ bool Debugger::cmdList(int argc, const char **argv) {
 				continue;
 			}
 			char fleeText[40];
-			sprintf(fleeText, "flee %i", i);
+			Vector3 a = flee->position;
+			sprintf(fleeText, "Flee %i, Pos(%02.2f,%02.2f,%02.2f)", i, a.x, a.y, a.z);
 			debugPrintf("%02d. %s\n", count, fleeText);
 			++count;
 		}
diff --git a/engines/bladerunner/debugger.h b/engines/bladerunner/debugger.h
index 2beee69..7b0a0e0 100644
--- a/engines/bladerunner/debugger.h
+++ b/engines/bladerunner/debugger.h
@@ -77,8 +77,9 @@ public:
 	bool cmdOverlay(int argc, const char **argv);
 	bool cmdSubtitle(int argc, const char **argv);
 	bool cmdMazeScore(int argc, const char **argv);
-	bool cmdBoundBox(int argc, const char **argv);
-	bool cmdObstacle(int argc, const char **argv);
+	bool cmdObject(int argc, const char **argv);
+	bool cmdItem(int argc, const char **argv);
+	bool cmdRegion(int argc, const char **argv);
 	bool cmdList(int argc, const char **argv);
 	bool cmdVk(int argc, const char **argv);
 
diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp
index 0508dbc..fc7f35b 100644
--- a/engines/bladerunner/item.cpp
+++ b/engines/bladerunner/item.cpp
@@ -70,6 +70,10 @@ void Item::getWidthHeight(int *width, int *height) const {
 	*height = _height;
 }
 
+void Item::getAnimationId(int *animationId) const {
+	*animationId = _animationId;
+}
+
 void Item::setFacing(int facing) {
 	_facing = facing;
 	_angle = _facing * (M_PI / 512.0f);
@@ -125,6 +129,9 @@ bool Item::tick(Common::Rect *screenRect, bool special) {
 	return isVisibleFlag;
 }
 
+// setXYZ() recalculates the item's bounding box,
+// but in addition to the item's (Vector3) position
+// it takes into account the item's width and height
 void Item::setXYZ(Vector3 position) {
 	_position = position;
 	int halfWidth = _width / 2;
diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h
index 74bddc5..f25a121 100644
--- a/engines/bladerunner/item.h
+++ b/engines/bladerunner/item.h
@@ -66,6 +66,7 @@ public:
 	void getXYZ(float *x, float *y, float *z) const;
 	void setXYZ(Vector3 position);
 	void getWidthHeight(int *width, int *height) const;
+	void getAnimationId(int *animationId) const;
 
 	const BoundingBox &getBoundingBox() { return _boundingBox; }
 	const Common::Rect &getScreenRectangle() { return _screenRectangle; }
diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp
index 9192b38..e5b894a 100644
--- a/engines/bladerunner/items.cpp
+++ b/engines/bladerunner/items.cpp
@@ -65,6 +65,13 @@ void Items::getWidthHeight(int itemId, int *width, int *height) const {
 	_items[itemIndex]->getWidthHeight(width, height);
 }
 
+void Items::getAnimationId(int itemId, int *animationId) const {
+	int itemIndex = findItem(itemId);
+	assert(itemIndex != -1);
+
+	_items[itemIndex]->getAnimationId(animationId);
+}
+
 void Items::tick() {
 	int setId = _vm->_scene->getSetId();
 	for (int i = 0; i < (int)_items.size(); i++) {
diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h
index a2c7720..61f8d55 100644
--- a/engines/bladerunner/items.h
+++ b/engines/bladerunner/items.h
@@ -47,6 +47,7 @@ public:
 	void getXYZ(int itemId, float *x, float *y, float *z) const;
 	void setXYZ(int itemId, Vector3 position);
 	void getWidthHeight(int itemId, int *width, int *height) const;
+	void getAnimationId(int itemId, int *animationId) const;
 
 	void tick();
 	bool addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag, bool addToSetFlag);
diff --git a/engines/bladerunner/regions.h b/engines/bladerunner/regions.h
index aae3627..00f59e7 100644
--- a/engines/bladerunner/regions.h
+++ b/engines/bladerunner/regions.h
@@ -38,7 +38,7 @@ class Regions {
 
 	struct Region {
 		Common::Rect rectangle;
-		int          type;
+		int          type;     // Arrow Icon on mouse-over (has meaning only for Exits) 0: Upward , 1: Right, 2: Downward, 3: Left
 		int          present;
 	};
 





More information about the Scummvm-git-logs mailing list