Beispiel #1
0
/**
 * Return the position of an object.
 * Returns X, Y and direction in angles
 */
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
	int idx = getObjectIndex(object);
	assert(idx >= 0);
	ObjectData &od = _objs[idx];
	int state;
	const byte *ptr;
	const ImageHeader *imhd;

	if (_game.version >= 6) {
		state = getState(object) - 1;
		if (state < 0)
			state = 0;

		ptr = getOBIMFromObjectData(od);
		if (!ptr) {
			// FIXME: We used to assert here, but it seems that in the nexus
			// in The Dig, this can happen, at least with old savegames, and
			// it's safe to continue...
			debug(0, "getObjectXYPos: Can't find object %d", object);
			return;
		}
		imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr);
		assert(imhd);
		if (_game.version == 8) {
			switch (FROM_LE_32(imhd->v8.version)) {
			case 800:
				x = od.x_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x44);
				y = od.y_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x48);
				break;
			case 801:
				x = od.x_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].x);
				y = od.y_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].y);
				break;
			default:
				error("Unsupported image header version %d", FROM_LE_32(imhd->v8.version));
			}
		} else if (_game.version == 7) {
			x = od.x_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].x);
			y = od.y_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].y);
		} else {
			x = od.x_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].x);
			y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
		}
	} else if (_game.version <= 2) {
		x = od.walk_x;
		y = od.walk_y;

		// Adjust x, y when no actor direction is set, but only perform this
		// adjustment for V0 games (e.g. MM C64), otherwise certain scenes in
		// newer games are affected as well (e.g. the interior of the Shuttle
		// Bus scene in Zak V2, where no actor is present). Refer to bug #3526089.
		if (!od.actordir && _game.version == 0) {
			x = od.x_pos + od.width / 2;
			y = od.y_pos + od.height / 2;
		}
		x = x >> V12_X_SHIFT;
		y = y >> V12_Y_SHIFT;
	} else {
Beispiel #2
0
MObject3d * MScene::getObjectByName(const char * name)
{
	unsigned int id;
	if(getObjectIndex(name, &id)){
		return m_objects[id];
	}

	return NULL;
}
Beispiel #3
0
void View::removeObject(const QString &name, ObjectType obj_type)
{
	try
	{
		removeObject(getObjectIndex(name, obj_type), obj_type);
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
	}
}
Beispiel #4
0
void View::removeObject(BaseObject *obj)
{
	try
	{
		removeObject(getObjectIndex(obj), obj->getObjectType());
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
	}
}
Beispiel #5
0
void objlink::makeNode(HWND hwnd, const char *heading, int level, int index)
{
  if (index == -1)
    index = getObjectIndex(obj);

  char dataString[20];
  sprintf(dataString, "%s %i", heading, index+1);

  HTREEITEM item_parent = parent ? parent->treeitem : 0;
  HTREEITEM item_prev = prev ? prev->treeitem : 0;
  treeitem = AddItemToTreeAfter(hwnd, dataString, level, obj, item_parent, item_prev);
}
Beispiel #6
0
void View::addObject(BaseObject *obj, int obj_idx)
{
	if(!obj)
		throw Exception(ERR_ASG_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);
	else
	{
		try
		{
			vector<TableObject *> *obj_list = getObjectList(obj->getObjectType());
			TableObject *tab_obj=dynamic_cast<TableObject *>(obj);

			//Raises an error if already exists a object with the same name and type
			if(getObjectIndex(obj->getName(), tab_obj->getObjectType()) >= 0)
			{
				throw Exception(QString(Exception::getErrorMessage(ERR_ASG_DUPLIC_OBJECT))
												.arg(obj->getName(true))
												.arg(obj->getTypeName())
												.arg(this->getName(true))
												.arg(this->getTypeName()),
												ERR_ASG_DUPLIC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);
			}

			//Validates the object definition
			tab_obj->setParentTable(this);
			tab_obj->getCodeDefinition(SchemaParser::SQL_DEFINITION);

			//Make a additional validation if the object is a trigger
			if(tab_obj->getObjectType()==OBJ_TRIGGER)
				dynamic_cast<Trigger *>(tab_obj)->validateTrigger();

			//Inserts the object at specified position
			if(obj_idx < 0 || obj_idx >= static_cast<int>(obj_list->size()))
				obj_list->push_back(tab_obj);
			else
				obj_list->insert(obj_list->begin() + obj_idx, tab_obj);

			setCodeInvalidated(true);
		}
		catch(Exception &e)
		{
			if(e.getErrorType()==ERR_UNDEF_ATTRIB_VALUE)
				throw Exception(Exception::getErrorMessage(ERR_ASG_OBJ_INV_DEFINITION)
                        .arg(obj->getName())
                        .arg(obj->getTypeName()),
												ERR_ASG_OBJ_INV_DEFINITION,__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
			else
				throw Exception(e.getErrorMessage(),e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
		}
	}
}
Beispiel #7
0
TableObject *View::getObject(const QString &name, ObjectType obj_type)
{
	try
	{
		int idx=getObjectIndex(name, obj_type);

		if(idx >= 0)
			return(getObject(idx, obj_type));
		else
			return(nullptr);
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
	}
}
Beispiel #8
0
QString Table::getInitialDataCommands(void)
{
	QStringList buffer=initial_data.split(DATA_LINE_BREAK);

	if(!buffer.isEmpty() && !buffer.at(0).isEmpty())
	{
		QStringList	col_names, col_values, commands, selected_cols;
		int curr_col=0;
		QList<int> ignored_cols;

		col_names=(buffer.at(0)).split(DATA_SEPARATOR);
		col_names.removeDuplicates();
		buffer.removeFirst();

		//Separating valid columns (selected) from the invalids (ignored)
		for(QString col_name : col_names)
		{
			if(getObjectIndex(col_name, OBJ_COLUMN) >= 0)
				selected_cols.append(col_name);
			else
				ignored_cols.append(curr_col);

			curr_col++;
		}

		for(QString buf_row : buffer)
		{
			curr_col=0;

			//Filtering the invalid columns' values
			for(QString value : buf_row.split(DATA_SEPARATOR))
			{
				if(ignored_cols.contains(curr_col))
					continue;

				col_values.append(value);
			}

			commands.append(createInsertCommand(selected_cols, col_values));
			col_values.clear();
		}

		return(commands.join('\n'));
	}

	return(QString());
}
Beispiel #9
0
/**
 * Return the position of an object.
 * Returns X, Y and direction in angles
 */
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
	int idx = (_v0ObjectIndex) ? object : getObjectIndex(object);
	assert(idx >= 0);
	ObjectData &od = _objs[idx];
	int state;
	const byte *ptr;
	const ImageHeader *imhd;

	if (_game.version >= 6) {
		state = getState(object) - 1;
		if (state < 0)
			state = 0;

		ptr = getOBIMFromObjectData(od);
		if (!ptr) {
			// FIXME: We used to assert here, but it seems that in the nexus
			// in The Dig, this can happen, at least with old savegames, and
			// it's safe to continue...
			debug(0, "getObjectXYPos: Can't find object %d", object);
			return;
		}
		imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr);
		assert(imhd);
		if (_game.version == 8) {
			switch (FROM_LE_32(imhd->v8.version)) {
			case 800:
				x = od.x_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x44);
				y = od.y_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x48);
				break;
			case 801:
				x = od.x_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].x);
				y = od.y_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].y);
				break;
			default:
				error("Unsupported image header version %d", FROM_LE_32(imhd->v8.version));
			}
		} else if (_game.version == 7) {
			x = od.x_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].x);
			y = od.y_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].y);
		} else {
			x = od.x_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].x);
			y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
		}
	} else if (_game.version <= 2) {
		x = od.walk_x >> V12_X_SHIFT;
		y = od.walk_y >> V12_Y_SHIFT;
	} else {
Beispiel #10
0
void Table::removeObject(BaseObject *obj)
{
	try
	{
		if(obj)
		{
			TableObject *tab_obj=dynamic_cast<TableObject *>(obj);

			if(tab_obj)
				removeObject(getObjectIndex(tab_obj), obj->getObjectType());
			else
				removeObject(obj->getName(true), OBJ_TABLE);
		}
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
	}
}
Beispiel #11
0
void Table::moveObjectToIndex(TableObject *tab_obj, unsigned idx)
{
	unsigned curr_idx;

	try
	{
		if(!tab_obj)
			throw Exception(ERR_OPR_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);

		curr_idx=getObjectIndex(tab_obj);

		if(curr_idx!=idx)
			swapObjectsIndexes(tab_obj->getObjectType(), curr_idx, idx);
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e);
	}
}
Beispiel #12
0
void ScummEngine_v4::o4_pickupObject() {
	int obj = getVarOrDirectWord(PARAM_1);

	if (obj < 1) {
		error("pickupObjectOld received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
	}

	if (getObjectIndex(obj) == -1)
		return;

	if (whereIsObject(obj) == WIO_INVENTORY)	// Don't take an object twice
		return;

	// debug(0, "adding %d from %d to inventoryOld", obj, _currentRoom);
	addObjectToInventory(obj, _roomResource);
	markObjectRectAsDirty(obj);
	putOwner(obj, VAR(VAR_EGO));
	putClass(obj, kObjectClassUntouchable, 1);
	putState(obj, 1);
	clearDrawObjectQueue();
	runInventoryScript(1);
}
Beispiel #13
0
void ScummEngine_v70he::o70_resourceRoutines() {
	int objidx, resid;

	byte subOp = fetchScriptByte();

	switch (subOp) {
	case 100:		// SO_LOAD_SCRIPT
		resid = pop();
		ensureResourceLoaded(rtScript, resid);
		break;
	case 101:		// SO_LOAD_SOUND
		resid = pop();
		ensureResourceLoaded(rtSound, resid);
		break;
	case 102:		// SO_LOAD_COSTUME
		resid = pop();
		ensureResourceLoaded(rtCostume, resid);
		break;
	case 103:		// SO_LOAD_ROOM
		resid = pop();
		ensureResourceLoaded(rtRoomImage, resid);
		ensureResourceLoaded(rtRoom, resid);
		break;
	case 104:		// SO_NUKE_SCRIPT
		resid = pop();
		_res->nukeResource(rtScript, resid);
		break;
	case 105:		// SO_NUKE_SOUND
		resid = pop();
		_res->nukeResource(rtSound, resid);
		break;
	case 106:		// SO_NUKE_COSTUME
		resid = pop();
		_res->nukeResource(rtCostume, resid);
		break;
	case 107:		// SO_NUKE_ROOM
		resid = pop();
		_res->nukeResource(rtRoom, resid);
		_res->nukeResource(rtRoomImage, resid);
		break;
	case 108:		// SO_LOCK_SCRIPT
		resid = pop();
		if (resid >= _numGlobalScripts)
			break;
		_res->lock(rtScript, resid);
		break;
	case 109:		// SO_LOCK_SOUND
		resid = pop();
		_res->lock(rtSound, resid);
		break;
	case 110:		// SO_LOCK_COSTUME
		resid = pop();
		_res->lock(rtCostume, resid);
		break;
	case 111:		// SO_LOCK_ROOM
		resid = pop();
		if (_game.heversion <= 71 && resid > 0x7F)
			resid = _resourceMapper[resid & 0x7F];
		_res->lock(rtRoom, resid);
		_res->lock(rtRoomImage, resid);
		break;
	case 112:		// SO_UNLOCK_SCRIPT
		resid = pop();
		if (resid >= _numGlobalScripts)
			break;
		_res->unlock(rtScript, resid);
		break;
	case 113:		// SO_UNLOCK_SOUND
		resid = pop();
		_res->unlock(rtSound, resid);
		break;
	case 114:		// SO_UNLOCK_COSTUME
		resid = pop();
		_res->unlock(rtCostume, resid);
		break;
	case 115:		// SO_UNLOCK_ROOM
		resid = pop();
		if (_game.heversion <= 71 && resid > 0x7F)
			resid = _resourceMapper[resid & 0x7F];
		_res->unlock(rtRoom, resid);
		_res->unlock(rtRoomImage, resid);
		break;
	case 116:
		// TODO: Clear Heap
		break;
	case 117:		// SO_LOAD_CHARSET
		resid = pop();
		loadCharset(resid);
		break;
	case 118:		// SO_NUKE_CHARSET
		resid = pop();
		nukeCharset(resid);
		break;
	case 119:		// SO_LOAD_OBJECT
		{
			int obj = pop();
			int room = getObjectRoom(obj);
			loadFlObject(obj, room);
			break;
		}
	case 120:
		resid = pop();
		if (resid >= _numGlobalScripts)
			break;
		//queueLoadResource(rtScript, resid);
		break;
	case 121:
		resid = pop();
		//queueLoadResource(rtSound, resid);
		break;
	case 122:
		resid = pop();
		//queueLoadResource(rtCostume, resid);
		break;
	case 123:
		resid = pop();
		//queueLoadResource(rtRoomImage, resid);
		break;
	case 159:
		resid = pop();
		_res->unlock(rtImage, resid);
		break;
	case 192:
		resid = pop();
		_res->nukeResource(rtImage, resid);
		break;
	case 201:
		resid = pop();
		ensureResourceLoaded(rtImage, resid);
		break;
	case 202:
		resid = pop();
		_res->lock(rtImage, resid);
		break;
	case 203:
		resid = pop();
		//queueLoadResource(rtImage, resid);
		break;
	case 233:
		resid = pop();
		objidx = getObjectIndex(resid);
		if (objidx == -1)
			break;
		_res->lock(rtFlObject, _objs[objidx].fl_object_index);
		break;
	case 235:
		resid = pop();
		objidx = getObjectIndex(resid);
		if (objidx == -1)
			break;
		_res->unlock(rtFlObject, _objs[objidx].fl_object_index);
		break;
	case 239:
		// Used in airport
		break;
	default:
		error("o70_resourceRoutines: default case %d", subOp);
	}
}