diff options
28 files changed, 560 insertions, 186 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp index b2fccb1c89..7f2a054b0f 100644 --- a/engines/illusions/actor.cpp +++ b/engines/illusions/actor.cpp @@ -125,6 +125,10 @@ Actor::Actor(IllusionsEngine *vm)  } +Actor::~Actor() { +	delete _controlRoutine; +} +  void Actor::pause() {  	++_pauseCtr;  } @@ -181,6 +185,15 @@ void Actor::runControlRoutine(Control *control, uint32 deltaTime) {  		(*_controlRoutine)(control, deltaTime);  } +bool Actor::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	if (_namedPoints->findNamedPoint(namedPointId, pt)) { +		pt.x += _position.x; +		pt.y += _position.y; +		return true; +	} +	return false; +} +  // Control  Control::Control(IllusionsEngine *vm) @@ -199,7 +212,6 @@ Control::Control(IllusionsEngine *vm)  	_position.y = 0;  	_actorTypeId = 0;  	_actor = 0; -	// TODO _buf = 0;  	_tag = _vm->_scriptMan->_activeScenes.getCurrentScene();  } @@ -372,7 +384,7 @@ void Control::setPriority(int16 priority) {  	_priority = priority;  } -int Control::getPriority() { +uint32 Control::getPriority() {  	uint32 objectId;  	int16 positionY, priority, priority1;  	if (_actor) { @@ -397,13 +409,13 @@ int Control::getPriority() {  	}  	priority -= 1; -	int p = 50 * priority1 / 100; +	uint32 p = 50 * priority1 / 100;  	if (p)  		--p;  	positionY = CLIP<int16>(positionY, -5000, 5000); -	return p + 50 * ((objectId & 0x3F) + ((10000 * priority + positionY + 5000) << 6)); +	return p + 50 * ((objectId & 0x3F) + ((10000 * priority + positionY + 5000) << 6));;  }  Common::Point Control::calcPosition(Common::Point posDelta) { @@ -644,18 +656,9 @@ void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entry  	_actor->_path40 = 0;  	Sequence *sequence = _vm->_dict->findSequence(sequenceId); -	//debug("sequence: %p", (void*)sequence);  	_actor->_seqCodeIp = sequence->_sequenceCode;  	_actor->_frames = _vm->_actorItems->findSequenceFrames(sequence); -	 -	/* -	for (int i = 0; i < 64; ++i) { -		debugN("%02X ", sequence->_sequenceCode[i]); -	} -	debug("."); -	*/ -	  	_actor->_seqCodeValue3 = 0;  	_actor->_seqCodeValue1 = 0;  	_actor->_seqCodeValue2 = value == 1 ? 350 : 600; @@ -683,6 +686,7 @@ void Control::execSequenceOpcode(OpCall &opCall) {  Controls::Controls(IllusionsEngine *vm)  	: _vm(vm) {  	_sequenceOpcodes = new SequenceOpcodes(_vm); +	_nextTempObjectId = 0;  }  Controls::~Controls() { @@ -721,11 +725,10 @@ void Controls::placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequ  	actor->_position = placePt;  	actor->_position2 = placePt;  	Common::Point currPan = _vm->_camera->getCurrentPan(); -	// TODO if (!artcntrl_calcPointDirection(placePt, panPos, &actor->facing)) -	actor->_facing = 64; +	if (!_vm->calcPointDirection(placePt, currPan, actor->_facing)) +		actor->_facing = 64;  	actor->_scale = actorType->_scale; -	// TODO actor->_namedPointsCount = actorType->_namedPointsCount; -	// TODO actor->_namedPoints = actorType->_namedPoints; +	actor->_namedPoints = &actorType->_namedPoints;  	BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource();  	if (actorType->_pathWalkPointsIndex) { @@ -791,8 +794,7 @@ void Controls::placeSequenceLessActor(uint32 objectId, Common::Point placePt, Wi  	actor->_position2 = placePt;  	actor->_facing = 64;  	actor->_scale = 100; -	// TODO actor->_namedPointsCount = 0; -	// TODO actor->_namedPoints = 0; +	actor->_namedPoints = 0;  	actor->_pathCtrY = 140;  	_controls.push_back(control); @@ -816,6 +818,17 @@ void Controls::placeActorLessObject(uint32 objectId, Common::Point feetPt, Commo  	_vm->_dict->setObjectControl(objectId, control);  } +void Controls::placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId, uint32 sequenceId) { +	Control *parentControl = _vm->_dict->getObjectControl(objectId); +	uint32 tempObjectId = newTempObjectId(); +	placeActor(actorTypeId, Common::Point(0, 0), sequenceId, tempObjectId, 0); +	parentControl->_actor->_subobjects[linkIndex - 1] = tempObjectId; +	Actor *subActor = _vm->_dict->getObjectControl(tempObjectId)->_actor; +	subActor->_flags |= 0x40; +	subActor->_parentObjectId = parentControl->_objectId; +	subActor->_linkIndex = linkIndex; +} +  void Controls::destroyControlsByTag(uint32 tag) {  	ItemsIterator it = _controls.begin();  	while (it != _controls.end()) { @@ -851,8 +864,8 @@ void Controls::unpauseControlsByTag(uint32 tag) {  bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority) {  	Control *foundControl = 0; -	int foundPriority = 0; -	// TODO minPriority = artcntrlGetPriorityFromBase(minPriority); +	uint32 foundPriority = 0; +	uint32 minPriorityExt = _vm->getPriorityFromBase(minPriority);  	for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {  		Control *testControl = *it; @@ -861,14 +874,10 @@ bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control *  			(!testControl->_actor || (testControl->_actor->_flags & 1))) {  			Common::Rect collisionRect;  			testControl->getCollisionRect(collisionRect); -			//debug("collisionRect(%d, %d, %d, %d)", collisionRect.left, collisionRect.top, collisionRect.right, collisionRect.bottom); -			//debug("pt(%d, %d)", pt.x, pt.y);  			if (!collisionRect.isEmpty() && collisionRect.contains(pt)) { -				int testPriority = testControl->getPriority(); -				//debug("testPriority: %d; minPriority: %d", testPriority, minPriority); +				uint32 testPriority = testControl->getPriority();  				if ((!foundControl || foundPriority < testPriority) && -					testPriority >= minPriority) { -					//debug("overlapped() %08X; pauseCtr: %d; flags: %04X", testControl->_objectId, testControl->_pauseCtr, testControl->_flags); +					testPriority >= minPriorityExt) {  					foundControl = testControl;  					foundPriority = testPriority;  				} @@ -887,6 +896,15 @@ bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control *  	return foundControl != 0;  } +bool Controls::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) { +		Control *control = *it; +		if (control->_pauseCtr == 0 && control->_actor && control->_actor->findNamedPoint(namedPointId, pt)) +			return true; +	} +	return false; +} +  void Controls::actorControlRoutine(Control *control, uint32 deltaTime) {  	Actor *actor = control->_actor; @@ -925,6 +943,17 @@ Control *Controls::newControl() {  	return new Control(_vm);  } +uint32 Controls::newTempObjectId() { +	uint32 nextTempObjectId1 = _nextTempObjectId; +	uint32 nextTempObjectId2 = _nextTempObjectId + 0x1000; +	if (nextTempObjectId2 > 0xFFFF) { +		nextTempObjectId1 = 0; +		nextTempObjectId2 = 0x1000; +	} +	_nextTempObjectId = nextTempObjectId1 + 1; +	return nextTempObjectId2 | 0x40000; +} +  void Controls::destroyControl(Control *control) {  	if (control->_pauseCtr <= 0) @@ -947,10 +976,6 @@ void Controls::destroyControl(Control *control) {  		delete control->_actor;  		control->_actor = 0;  	} -	/* TODO -	if (control->_buf) -		free(control->_buf); -	*/  	delete control;  } diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h index 9ddfc9cf16..7e3bc7f228 100644 --- a/engines/illusions/actor.h +++ b/engines/illusions/actor.h @@ -70,6 +70,7 @@ typedef Common::Functor2<Control*, uint32, void> ActorControlRoutine;  class Actor {  public:  	Actor(IllusionsEngine *vm); +	~Actor();  	void pause();  	void unpause();  	void createSurface(SurfInfo &surfInfo); @@ -79,6 +80,7 @@ public:  	int16 popSequenceStack();  	void setControlRoutine(ActorControlRoutine *controlRoutine);  	void runControlRoutine(Control *control, uint32 deltaTime); +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);  public:  	IllusionsEngine *_vm;  	byte _drawFlags; @@ -94,6 +96,7 @@ public:  	Graphics::Surface *_surface;  	FramesList *_frames; +	NamedPoints *_namedPoints;  	ScaleLayer *_scaleLayer;  	PriorityLayer *_priorityLayer; @@ -157,7 +160,7 @@ public:  	void clearNotifyThreadId1();  	void clearNotifyThreadId2();  	void setPriority(int16 priority); -	int getPriority(); +	uint32 getPriority();  	Common::Point calcPosition(Common::Point posDelta);  	uint32 getSubActorParent();  	void getCollisionRectAccurate(Common::Rect &collisionRect); @@ -200,10 +203,12 @@ public:  	void placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequenceId, uint32 objectId, uint32 notifyThreadId);  	void placeSequenceLessActor(uint32 objectId, Common::Point placePt, WidthHeight dimensions, int16 priority);  	void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags); +	void placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId, uint32 sequenceId);  	void destroyControlsByTag(uint32 tag);  	void pauseControlsByTag(uint32 tag);  	void unpauseControlsByTag(uint32 tag);  	bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority); +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);  	void actorControlRoutine(Control *control, uint32 deltaTime);	  public:  	typedef Common::List<Control*> Items; @@ -211,8 +216,10 @@ public:  	IllusionsEngine *_vm;  	Items _controls;  	SequenceOpcodes *_sequenceOpcodes; +	uint32 _nextTempObjectId;  	Actor *newActor();  	Control *newControl(); +	uint32 newTempObjectId();  	void destroyControl(Control *control);  }; diff --git a/engines/illusions/actorresource.cpp b/engines/illusions/actorresource.cpp index bb3cd4debc..affca78879 100644 --- a/engines/illusions/actorresource.cpp +++ b/engines/illusions/actorresource.cpp @@ -108,16 +108,15 @@ void Sequence::load(byte *dataStart, Common::SeekableReadStream &stream) {  	debug(5, "Sequence::load() _sequenceId: %08X; _unk4: %d; sequenceCodeOffs: %08X",  		_sequenceId, _unk4, sequenceCodeOffs); -	debug("_sequenceId: %08X", _sequenceId);  }  void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) {  	_actorTypeId = stream.readUint32LE();  	_surfInfo.load(stream);  	uint32 pointsConfigOffs = stream.readUint32LE(); -	stream.readUint16LE(); // TODO namedPointsCount dw +	uint namedPointsCount = stream.readUint16LE();  	stream.skip(2); // Skip padding -	stream.readUint32LE(); // TODO namedPoints dd +	uint32 namedPointsOffs = stream.readUint32LE();  	_color.r = stream.readByte();  	_color.g = stream.readByte();  	_color.b = stream.readByte(); @@ -132,6 +131,8 @@ void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) {  	_regionLayerIndex = stream.readUint16LE();  	_flags = stream.readUint16LE();  	_pointsConfig = dataStart + pointsConfigOffs; +	stream.seek(namedPointsOffs); +	_namedPoints.load(namedPointsCount, stream);  	debug(5, "ActorType::load() _actorTypeId: %08X; _color(%d,%d,%d); _scale: %d; _priority: %d; _value1E: %d",  		_actorTypeId, _color.r, _color.g, _color.b, _scale, _priority, _value1E); @@ -140,8 +141,6 @@ void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) {  	debug(5, "ActorType::load() _priorityLayerIndex: %d; _regionLayerIndex: %d; _flags: %04X",  		_priorityLayerIndex, _regionLayerIndex,_flags); -	debug("_actorTypeId: %08X; dimensions: (%d, %d)", _actorTypeId, _surfInfo._dimensions._width, _surfInfo._dimensions._height); -  }  // ActorResource @@ -162,10 +161,10 @@ void ActorResource::load(byte *data, uint32 dataSize) {  	uint actorTypesCount = stream.readUint16LE();  	stream.seek(0x10);  	uint32 actorTypesOffs = stream.readUint32LE(); -	stream.seek(actorTypesOffs);  	_actorTypes.reserve(actorTypesCount);  	for (uint i = 0; i < actorTypesCount; ++i) {  		ActorType actorType; +		stream.seek(actorTypesOffs + i * 0x2C);  		actorType.load(data, stream);  		_actorTypes.push_back(actorType);  	} @@ -195,6 +194,12 @@ void ActorResource::load(byte *data, uint32 dataSize) {  		frame.load(data, stream);  		_frames.push_back(frame);  	} +	 +	// Load named points +	// The count isn't stored explicitly so calculate it +	uint namedPointsCount = (actorTypesOffs - 0x20) / 8; +	stream.seek(0x20); +	_namedPoints.load(namedPointsCount, stream);  } @@ -205,6 +210,10 @@ bool ActorResource::containsSequence(Sequence *sequence) {  	return false;  } +bool ActorResource::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	return _namedPoints.findNamedPoint(namedPointId, pt); +} +  // ActorItem  ActorItem::ActorItem(IllusionsEngine *vm) @@ -286,4 +295,13 @@ ActorItem *ActorItems::findActorByResource(ActorResource *actorResource) {  	return 0;  } +bool ActorItems::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	for (ItemsIterator it = _items.begin(); it != _items.end(); ++it) { +		ActorItem *actorItem = *it; +		if (actorItem->_pauseCtr == 0 && actorItem->_actRes->findNamedPoint(namedPointId, pt)) +			return true; +	} +	return false; +} +  } // End of namespace Illusions diff --git a/engines/illusions/actorresource.h b/engines/illusions/actorresource.h index e22ed7ed10..78cfc199a3 100644 --- a/engines/illusions/actorresource.h +++ b/engines/illusions/actorresource.h @@ -62,8 +62,7 @@ struct ActorType {  	uint32 _actorTypeId;  	SurfInfo _surfInfo;  	byte *_pointsConfig; -	// TODO namedPointsCount dw -	// TODO namedPoints dd +	NamedPoints _namedPoints;  	RGB _color;  	byte _scale;  	byte _priority; @@ -86,11 +85,13 @@ public:  	~ActorResource();  	void load(byte *data, uint32 dataSize);  	bool containsSequence(Sequence *sequence); +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);  public:  	uint32 _totalSize;  	Common::Array<ActorType> _actorTypes;  	Common::Array<Sequence> _sequences;  	FramesList _frames; +	NamedPoints _namedPoints;  };  class ActorItem { @@ -116,6 +117,7 @@ public:  	void unpauseByTag(uint32 tag);  	FramesList *findSequenceFrames(Sequence *sequence);  	ActorItem *findActorByResource(ActorResource *actorResource); +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);  protected:  	typedef Common::List<ActorItem*> Items;  	typedef Items::iterator ItemsIterator; diff --git a/engines/illusions/backgroundresource.cpp b/engines/illusions/backgroundresource.cpp index d80a9e2dd9..d2b01fea93 100644 --- a/engines/illusions/backgroundresource.cpp +++ b/engines/illusions/backgroundresource.cpp @@ -86,7 +86,7 @@ void TileMap::load(byte *dataStart, Common::SeekableReadStream &stream) {  	uint32 mapOffs = stream.pos();  	_map = dataStart + mapOffs; -	debug("TileMap::load() _width: %d; _height: %d", +	debug(0, "TileMap::load() _width: %d; _height: %d",  		_width, _height);  } @@ -104,7 +104,7 @@ void BgInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {  	_tileMap.load(dataStart, stream);  	_tilePixels = dataStart + tilePixelsOffs; -	debug("BgInfo::load() _flags: %08X; _priorityBase: %d; tileMapOffs: %08X; tilePixelsOffs: %08X", +	debug(0, "BgInfo::load() _flags: %08X; _priorityBase: %d; tileMapOffs: %08X; tilePixelsOffs: %08X",  		_flags, _priorityBase, tileMapOffs, tilePixelsOffs);  } @@ -121,7 +121,7 @@ void PriorityLayer::load(byte *dataStart, Common::SeekableReadStream &stream) {  	_map += 8;  	_values = dataStart + valuesOffs; -	debug("PriorityLayer::load() _width: %d; _height: %d; mapOffs: %08X; valuesOffs: %08X; _mapWidth: %d; _mapHeight: %d", +	debug(0, "PriorityLayer::load() _width: %d; _height: %d; mapOffs: %08X; valuesOffs: %08X; _mapWidth: %d; _mapHeight: %d",  		_width, _height, mapOffs, valuesOffs, _mapWidth, _mapHeight);  } @@ -140,7 +140,7 @@ void ScaleLayer::load(byte *dataStart, Common::SeekableReadStream &stream) {  	uint32 valuesOffs = stream.readUint32LE();  	_values = dataStart + valuesOffs; -	debug("ScaleLayer::load() _height: %d; valuesOffs: %08X", +	debug(0, "ScaleLayer::load() _height: %d; valuesOffs: %08X",  		_height, valuesOffs);  } @@ -158,7 +158,7 @@ void BackgroundObject::load(byte *dataStart, Common::SeekableReadStream &stream)  	uint32 pointsConfigOffs = stream.readUint32LE();  	_pointsConfig = dataStart + pointsConfigOffs; -	debug("BackgroundObject::load() _objectId: %08X; _flags: %04X; _priority: %d; pointsConfigOffs: %08X", +	debug(0, "BackgroundObject::load() _objectId: %08X; _flags: %04X; _priority: %d; pointsConfigOffs: %08X",  		_objectId, _flags, _priority, pointsConfigOffs);  } @@ -192,7 +192,7 @@ void BackgroundResource::load(byte *data, uint32 dataSize) {  	_scaleLayers = new ScaleLayer[_scaleLayersCount];  	stream.seek(0x2C);  	uint32 scaleLayersOffs = stream.readUint32LE(); -	debug("_scaleLayersCount: %d", _scaleLayersCount); +	debug(0, "_scaleLayersCount: %d", _scaleLayersCount);  	for (uint i = 0; i < _scaleLayersCount; ++i) {  		stream.seek(scaleLayersOffs + i * 8);  		_scaleLayers[i].load(data, stream); @@ -204,7 +204,7 @@ void BackgroundResource::load(byte *data, uint32 dataSize) {  	_priorityLayers = new PriorityLayer[_priorityLayersCount];  	stream.seek(0x34);  	uint32 priorityLayersOffs = stream.readUint32LE(); -	debug("_priorityLayersCount: %d", _priorityLayersCount); +	debug(0, "_priorityLayersCount: %d", _priorityLayersCount);  	for (uint i = 0; i < _priorityLayersCount; ++i) {  		stream.seek(priorityLayersOffs + i * 12);  		_priorityLayers[i].load(data, stream); @@ -216,11 +216,19 @@ void BackgroundResource::load(byte *data, uint32 dataSize) {  	_backgroundObjects = new BackgroundObject[_backgroundObjectsCount];  	stream.seek(0x44);  	uint32 backgroundObjectsOffs = stream.readUint32LE(); -	debug("_backgroundObjectsCount: %d", _backgroundObjectsCount); +	debug(0, "_backgroundObjectsCount: %d", _backgroundObjectsCount);  	for (uint i = 0; i < _backgroundObjectsCount; ++i) {  		stream.seek(backgroundObjectsOffs + i * 12);  		_backgroundObjects[i].load(data, stream);  	} +	 +	// Load named points +	stream.seek(0xC); +	uint namedPointsCount = stream.readUint16LE(); +	stream.seek(0x24); +	uint32 namedPointsOffs = stream.readUint32LE(); +	stream.seek(namedPointsOffs); +	_namedPoints.load(namedPointsCount, stream);  } @@ -239,6 +247,10 @@ ScaleLayer *BackgroundResource::getScaleLayer(uint index) {  	return &_scaleLayers[index];  } +bool BackgroundResource::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	return _namedPoints.findNamedPoint(namedPointId, pt); +} +  // BackgroundItem  BackgroundItem::BackgroundItem(IllusionsEngine *vm) : _vm(vm), _tag(0), _pauseCtr(0), _bgRes(0) { @@ -421,6 +433,11 @@ void BackgroundItems::refreshPan() {  	}  } +bool BackgroundItems::findActiveBackgroundNamedPoint(uint32 namedPointId, Common::Point &pt) { +	BackgroundResource *backgroundResource = getActiveBgResource(); +	return backgroundResource ? backgroundResource->findNamedPoint(namedPointId, pt) : false; +} +  BackgroundItem *BackgroundItems::debugFirst() {  	return *(_items.begin());  } diff --git a/engines/illusions/backgroundresource.h b/engines/illusions/backgroundresource.h index cfb90673da..daf2ffd770 100644 --- a/engines/illusions/backgroundresource.h +++ b/engines/illusions/backgroundresource.h @@ -116,6 +116,7 @@ public:  	int findMasterBgIndex();  	PriorityLayer *getPriorityLayer(uint index);  	ScaleLayer *getScaleLayer(uint index); +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);  public:  	uint _bgInfosCount; @@ -129,6 +130,8 @@ public:  	uint _backgroundObjectsCount;  	BackgroundObject *_backgroundObjects; +	 +	NamedPoints _namedPoints;  }; @@ -168,6 +171,7 @@ public:  	BackgroundResource *getActiveBgResource();  	WidthHeight getMasterBgDimensions();  	void refreshPan(); +	bool findActiveBackgroundNamedPoint(uint32 namedPointId, Common::Point &pt);  	BackgroundItem *debugFirst();  //protected:  public: diff --git a/engines/illusions/bbdou/bbdou_bubble.cpp b/engines/illusions/bbdou/bbdou_bubble.cpp index 3256bc404d..cc6019c835 100644 --- a/engines/illusions/bbdou/bbdou_bubble.cpp +++ b/engines/illusions/bbdou/bbdou_bubble.cpp @@ -60,8 +60,8 @@ void BbdouBubble::init() {  		0x00040037, 0x00040038, 0x00040039, 0x0004003A  	}; -	_field1414 = 0x4005B; -	_field1418 = 0x4005C; +	_objectId1414 = 0x4005B; +	_objectId1418 = 0x4005C;  	for (uint i = 0; i < 32; ++i)  		_objectIds[i] = kObjectIds3[i]; @@ -147,4 +147,40 @@ void BbdouBubble::hide() {  	}  } +void BbdouBubble::setup(int16 minCount, Common::Point pt1, Common::Point pt2, uint32 progResKeywordId) { +	for (uint i = 0; i < 32; ++i) +		_items[i]._enabled = 0; +	int16 maxCount = 32; +	for (uint i = 0; i < _item0s.size(); ++i) { +		Item0 *item0 = &_item0s[i]; +		if (item0->_count < maxCount && item0->_count >= minCount && +			(!progResKeywordId || item0->_progResKeywordId == progResKeywordId)) { +			maxCount = item0->_count; +			_currItem0 = item0;  +		} +	} +	_pt1 = pt1; +	_pt2 = pt2; +	_currItem0->_pt = pt2; +	_currItem0->_objectId = _objectId1414; +	if (_prevItem0 && _prevItem0->_objectId == _currItem0->_objectId) +		_currItem0->_objectId = _objectId1418; +} + +uint32 BbdouBubble::addItem(uint positionIndex, uint32 sequenceId) { +	for (uint i = 0; i < 32; ++i) { +		Item141C *item = &_items[i]; +		if (!item->_enabled) { +			Common::Point itemPos = _vm->getNamedPointPosition(_currItem0->_namedPointIds[positionIndex]); +			Common::Point basePos = _vm->getNamedPointPosition(_currItem0->_baseNamedPointId); +			item->_enabled = 1; +			item->_sequenceId = sequenceId; +			item->_position.x = itemPos.x + _currItem0->_pt.x - basePos.x; +			item->_position.y = itemPos.y + _currItem0->_pt.y - basePos.y; +			return item->_objectId; +		} +	} +	return 0; +} +  } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_bubble.h b/engines/illusions/bbdou/bbdou_bubble.h index 9064acd08c..2426c9e1b8 100644 --- a/engines/illusions/bbdou/bbdou_bubble.h +++ b/engines/illusions/bbdou/bbdou_bubble.h @@ -61,6 +61,8 @@ public:  		uint32 namedPointId, int16 count, uint32 *namedPointIds);  	void show();  	void hide(); +	void setup(int16 minCount, Common::Point pt1, Common::Point pt2, uint32 progResKeywordId); +	uint32 addItem(uint positionIndex, uint32 sequenceId);  protected:  	IllusionsEngine *_vm;  	BbdouSpecialCode *_bbdou; @@ -71,8 +73,8 @@ protected:  	uint32 _objectIds[32];  	Common::Point _pt1;  	Common::Point _pt2; -	int _field1414; -	int _field1418; +	int _objectId1414; +	int _objectId1418;  	Item141C _items[32];  }; diff --git a/engines/illusions/bbdou/bbdou_inventory.cpp b/engines/illusions/bbdou/bbdou_inventory.cpp new file mode 100644 index 0000000000..b1d4f92381 --- /dev/null +++ b/engines/illusions/bbdou/bbdou_inventory.cpp @@ -0,0 +1,32 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "illusions/illusions.h" +#include "illusions/bbdou/bbdou_inventory.h" +#include "illusions/actor.h" +#include "illusions/camera.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" + +namespace Illusions { + +} // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_inventory.h b/engines/illusions/bbdou/bbdou_inventory.h new file mode 100644 index 0000000000..31023c063a --- /dev/null +++ b/engines/illusions/bbdou/bbdou_inventory.h @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef ILLUSIONS_BBDOU_BBDOU_INVENTORY_H +#define ILLUSIONS_BBDOU_BBDOU_INVENTORY_H + +#include "illusions/specialcode.h" +#include "common/rect.h" + +namespace Illusions { + +class IllusionsEngine; +class BbdouSpecialCode; +class Control; + +} // End of namespace Illusions + +#endif // ILLUSIONS_BBDOU_BBDOU_INVENTORY_H diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp index 62b0a7aca1..96e4cb0c11 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.cpp +++ b/engines/illusions/bbdou/bbdou_specialcode.cpp @@ -33,6 +33,22 @@  namespace Illusions { +static const Struct10 kStruct10s[] = { +	{0x1B0000,       0,       0,       0}, +	{0x1B0001, 0x6001A, 0x6001B, 0x6001C}, +	{0x1B0002, 0x6001D, 0x6001E, 0x6001F}, +	{0x1B0003, 0x60020, 0x60021, 0x60022}, +	{0x1B0004, 0x60023, 0x60024, 0x60025}, +	{0x1B0005, 0x60026, 0x60027, 0x60028}, +	{0x1B0006,       0,       0,       0}, +	{0x1B0007,       0,       0,       0}, +	{0x1B0008,       0,       0,       0}, +	{0x1B0009,       0,       0,       0}, +	{0x1B000A,       0,       0,       0}, +	{0x1B000B,       0,       0,       0}, +	{0x1B000C,       0,       0,       0}, +}; +  CauseThread::CauseThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId,  	BbdouSpecialCode *bbdou, uint32 cursorObjectId, uint32 sceneId, uint32 verbId,  	uint32 objectId2, uint32 objectId) @@ -92,8 +108,8 @@ void BbdouSpecialCode::run(uint32 specialCodeId, OpCall &opCall) {  // Convenience macros  #define	ARG_SKIP(x) opCall.skip(x);  -#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name); -#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name); +#define ARG_INT16(name) int16 name = opCall.readSint16(); debug(1, "ARG_INT16(" #name " = %d)", name); +#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug(1, "ARG_UINT32(" #name " = %08X)", name);  void BbdouSpecialCode::spcInitCursor(OpCall &opCall) {  	ARG_UINT32(objectId); @@ -196,7 +212,58 @@ Common::Point BbdouSpecialCode::getBackgroundCursorPos(Common::Point cursorPos)  void BbdouSpecialCode::showBubble(uint32 objectId, uint32 overlappedObjectId, uint32 holdingObjectId,  	Item10 *item10, uint32 progResKeywordId) { -	// TODO +	 +	Common::Rect collisionRect; +	Control *overlappedControl, *control2, *control3; +	Common::Point pt1(320, 240), pt2, currPan; +	 +	overlappedControl = _vm->_dict->getObjectControl(overlappedObjectId); +	overlappedControl->getCollisionRect(collisionRect); + +	currPan = _vm->_camera->getCurrentPan(); +	pt2.x = CLIP((collisionRect.right + collisionRect.left) / 2, currPan.x - 274, currPan.x + 274); +	pt2.y = CLIP(collisionRect.top - (collisionRect.bottom - collisionRect.top) / 8, currPan.y - 204, currPan.y + 204); + +	control2 = _vm->_dict->getObjectControl(0x4000F); +	if (!control2 || (control2->_actor && control2->_actor->_frameIndex == 0)) +		control2 = _vm->_dict->getObjectControl(0x4000E); + +	if (control2 && control2->_actor && control2->_actor->_frameIndex) { +		pt1.x = control2->_actor->_surfInfo._dimensions._width / 2 + pt1.x - control2->_position.x; +		pt1.y = control2->_actor->_position.y - control2->_position.y; +		pt1.y = pt1.y >= 500 ? 500 : pt1.y + 32; +		if (ABS(pt1.x - pt2.x) < ABS(pt1.y - pt2.y) / 2) +			pt1.y += 80; +	} + +	_bubble->setup(1, pt1, pt2, progResKeywordId); + +	item10->_objectIds[0] = _bubble->addItem(0, 0x6005A); +	item10->_objectIds[1] = _bubble->addItem(0, 0x6005A); +	item10->_index = 0; +	 +	int value = _cursor->findStruct8bsValue(overlappedControl->_objectId); +	if (holdingObjectId) { +		item10->_verbId = 0x1B0003; +	} else if (value == 9) { +		item10->_verbId = 0x1B0005; +	} else if (value == 8) { +		item10->_verbId = 0x1B0005; +	} else { +		item10->_verbId = 0x1B0002; +	} +	 +	uint32 sequenceId = kStruct10s[item10->_verbId & 0xFFFF]._sequenceId2; +	_bubble->show(); +	 +	control3 = _vm->_dict->getObjectControl(item10->_objectIds[0]); +	control3->startSequenceActor(sequenceId, 2, 0); +	control3->appearActor(); +	control3->deactivateObject(); +	 +	item10->_playSound48 = 1; +	_vm->_input->discardButtons(0xFFFF); +  }  bool BbdouSpecialCode::findVerbId(Item10 *item10, uint32 currOverlappedObjectId, int always0, uint32 &outVerbId) { @@ -255,13 +322,11 @@ void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint  		}  		if (foundOverlapped) { -			debug("overlappedControl: %p", (void*)overlappedControl);  			if (overlappedControl->_objectId != cursorData._currOverlappedObjectId) {  				if (cursorData._item10._playSound48)  					playSoundEffect(4);  				resetItem10(cursorControl->_objectId, &cursorData._item10);  				int value = _cursor->findStruct8bsValue(overlappedControl->_objectId); -				debug("object value: %d", value);  				if (!testValueRange(value)) {  					if (cursorData._mode == 3)  						_cursor->restoreInfo(); @@ -453,8 +518,6 @@ bool BbdouSpecialCode::runCause(Control *cursorControl, CursorData &cursorData,  		success = true;  	} -	debug("runCause() success: %d", success); -	  	if (!success)  		return false; @@ -479,7 +542,7 @@ bool BbdouSpecialCode::runCause(Control *cursorControl, CursorData &cursorData,  uint32 BbdouSpecialCode::startCauseThread(uint32 cursorObjectId, uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId) {  	uint32 tempThreadId = _vm->_scriptMan->newTempThreadId(); -	debug("staring cause thread %08X...", tempThreadId); +	debug(3, "Starting cause thread %08X...", tempThreadId);  	CauseThread *causeThread = new CauseThread(_vm, tempThreadId, 0, this,  		cursorObjectId, sceneId, verbId, objectId2, objectId);  	_vm->_scriptMan->_threads->startThread(causeThread); diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h index 61f6b703da..9781c6d15d 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.h +++ b/engines/illusions/bbdou/bbdou_specialcode.h @@ -39,6 +39,13 @@ typedef Common::Functor1<OpCall&, void> SpecialCodeFunction;  class BbdouSpecialCode; +struct Struct10 { +	uint32 _verbId; +	uint32 _sequenceId1; +	uint32 _sequenceId2; +	uint32 _sequenceId3; +}; +  class CauseThread : public Thread {  public:  	CauseThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, diff --git a/engines/illusions/camera.cpp b/engines/illusions/camera.cpp index 0aff84ff64..300065a27f 100644 --- a/engines/illusions/camera.cpp +++ b/engines/illusions/camera.cpp @@ -134,7 +134,7 @@ void Camera::panToPoint(Common::Point pt, int16 panSpeed, uint32 panNotifyId) {  	} else {  		_activeState._currPan = _activeState._panTargetPoint;  		stopPan(); -		_vm->notifyThreadId(_activeState._panNotifyId); +		_vm->notifyThreadId(panNotifyId);  	}  } @@ -396,23 +396,14 @@ void Camera::updateMode3(uint32 currTime) {  bool Camera::updatePan(uint32 currTime) {  	if (currTime - _activeState._time28 >= _activeState._time2E) { -debug("#1 updatePan");  		_activeState._panXShl = _activeState._panTargetPoint.x << 16;  		_activeState._panYShl = _activeState._panTargetPoint.y << 16;  	} else { -debug("#2 updatePan"); -debug("_activeState._someX = %d", _activeState._someX); -debug("1) _activeState._panXShl = %08X", _activeState._panXShl); -debug("currTime - _activeState._panStartTime = %d", currTime - _activeState._panStartTime);  		_activeState._panXShl += fixedMul(_activeState._someX, (currTime - _activeState._panStartTime) << 16);  		_activeState._panYShl += fixedMul(_activeState._someY, (currTime - _activeState._panStartTime) << 16); -debug("2) _activeState._panXShl = %08X", _activeState._panXShl);  	}  	_activeState._panStartTime = currTime;  	Common::Point newPan(_activeState._panXShl >> 16, _activeState._panYShl >> 16); -	 -	debug("newPan = %d, %d", newPan.x, newPan.y); -	  	if (_activeState._currPan.x != newPan.x || _activeState._currPan.y != newPan.y) {  		_activeState._currPan = newPan;  		return true; @@ -442,24 +433,13 @@ void Camera::recalcPan(uint32 currTime) {  		FP16 x2 = _activeState._panTargetPoint.x << 16;  		FP16 y2 = _activeState._panTargetPoint.y << 16;  		FP16 distance = fixedDistance(x1, y1, x2, y2); -		 -		debug("(%08X, %08X), (%08X, %08X) %08X", x1, y1, x2, y2, distance); -		  		_activeState._time2E = 60 * fixedTrunc(distance) / _activeState._panSpeed; -		 -		debug("_activeState._time2E = %d", _activeState._time2E); -		  	}  	if (_activeState._time2E != 0) { -debug("#1 recalcPan"); -debug("_activeState._panTargetPoint.x = %d; _activeState._currPan2.x = %d", _activeState._panTargetPoint.x, _activeState._currPan2.x); -debug("_activeState._panTargetPoint.x - _activeState._currPan2.x = %d", _activeState._panTargetPoint.x - _activeState._currPan2.x); -debug("_activeState._time2E = %d", _activeState._time2E);  		_activeState._someX = fixedDiv((_activeState._panTargetPoint.x - _activeState._currPan2.x) << 16, _activeState._time2E << 16);  		_activeState._someY = fixedDiv((_activeState._panTargetPoint.y - _activeState._currPan2.y) << 16, _activeState._time2E << 16);  	} else { -debug("#2 recalcPan");	  		_activeState._someX = (_activeState._panTargetPoint.x - _activeState._currPan2.x) << 16;  		_activeState._someY = (_activeState._panTargetPoint.y - _activeState._currPan2.y) << 16;  	} @@ -486,19 +466,10 @@ bool Camera::calcPointFlags(Common::Point &pt, WRect &rect, uint &outFlags) {  }  void Camera::clipPanTargetPoint() { - -	debug("clip in (%d, %d)", _activeState._panTargetPoint.x, _activeState._panTargetPoint.y); -  	_activeState._panTargetPoint.x = CLIP(_activeState._panTargetPoint.x,  		_activeState._bounds._topLeft.x, _activeState._bounds._bottomRight.x);  	_activeState._panTargetPoint.y = CLIP(_activeState._panTargetPoint.y,  		_activeState._bounds._topLeft.y, _activeState._bounds._bottomRight.y); -		 -	debug("clip rect (%d, %d, %d, %d)", _activeState._bounds._topLeft.x, _activeState._bounds._topLeft.y, -		_activeState._bounds._bottomRight.x, _activeState._bounds._bottomRight.y);		 - -	debug("clip out (%d, %d)", _activeState._panTargetPoint.x, _activeState._panTargetPoint.y); -  }  } // End of namespace Illusions diff --git a/engines/illusions/cursor.cpp b/engines/illusions/cursor.cpp index 36ab97a633..ccbff9540b 100644 --- a/engines/illusions/cursor.cpp +++ b/engines/illusions/cursor.cpp @@ -73,7 +73,7 @@ void Cursor::show() {  void Cursor::hide() {  	--_visibleCtr; -	if (_visibleCtr < 0) { +	if (_visibleCtr <= 0) {  		_control->_flags &= ~1;  		_control->_actor->_flags &= ~1;  	} diff --git a/engines/illusions/graphics.cpp b/engines/illusions/graphics.cpp index 61130988bd..37fe4d547e 100644 --- a/engines/illusions/graphics.cpp +++ b/engines/illusions/graphics.cpp @@ -24,6 +24,8 @@  namespace Illusions { +// WidthHeight +  void WidthHeight::load(Common::SeekableReadStream &stream) {  	_width = stream.readSint16LE();  	_height = stream.readSint16LE(); @@ -32,6 +34,8 @@ void WidthHeight::load(Common::SeekableReadStream &stream) {  		_width, _height);  } +// SurfInfo +  void SurfInfo::load(Common::SeekableReadStream &stream) {  	_pixelSize = stream.readUint32LE();  	_dimensions.load(stream); @@ -40,6 +44,34 @@ void SurfInfo::load(Common::SeekableReadStream &stream) {  		_pixelSize);  } +// NamedPoint + +void NamedPoint::load(Common::SeekableReadStream &stream) { +	_namedPointId = stream.readUint32LE(); +	loadPoint(stream, _pt); +} + +// NamedPoints + +bool NamedPoints::findNamedPoint(uint32 namedPointId, Common::Point &pt) { +	for (ItemsIterator it = _namedPoints.begin(); it != _namedPoints.end(); ++it) +		if ((*it)._namedPointId == namedPointId) { +			pt = (*it)._pt; +			return true; +		} +	return false; +} + +void NamedPoints::load(uint count, Common::SeekableReadStream &stream) { +	_namedPoints.reserve(count); +	for (uint i = 0; i < count; ++i) { +		NamedPoint namedPoint; +		namedPoint.load(stream); +		_namedPoints.push_back(namedPoint); +		debug(0, "namedPoint(%08X, %d, %d)", namedPoint._namedPointId, namedPoint._pt.x, namedPoint._pt.y); +	} +} +  void loadPoint(Common::SeekableReadStream &stream, Common::Point &pt) {  	pt.x = stream.readSint16LE();  	pt.y = stream.readSint16LE(); diff --git a/engines/illusions/graphics.h b/engines/illusions/graphics.h index 4f50f159d1..a2643685bb 100644 --- a/engines/illusions/graphics.h +++ b/engines/illusions/graphics.h @@ -23,6 +23,7 @@  #ifndef ILLUSIONS_GRAPHICS_H  #define ILLUSIONS_GRAPHICS_H +#include "common/array.h"  #include "common/rect.h"  #include "common/stream.h" @@ -48,6 +49,22 @@ struct RGB {  	byte r, g, b;  }; +struct NamedPoint { +	uint32 _namedPointId; +	Common::Point _pt; +	void load(Common::SeekableReadStream &stream); +}; + +class NamedPoints { +public: +	bool findNamedPoint(uint32 namedPointId, Common::Point &pt); +	void load(uint count, Common::SeekableReadStream &stream); +protected: +	typedef Common::Array<NamedPoint> Items; +	typedef Items::iterator ItemsIterator; +	Items _namedPoints; +}; +  void loadPoint(Common::SeekableReadStream &stream, Common::Point &pt);  } // End of namespace Illusions diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index 5f7bb23b79..bd302f8959 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -113,41 +113,6 @@ Common::Error IllusionsEngine::run() {  	_unpauseControlActorFlag = false;  	_lastUpdateTime = 0; -#if 0 -	// ActorResource test -	_resSys->loadResource(0x00100006, 0, 0); -#endif - -#if 0 -	// BackgroundResource test -	_resSys->loadResource(0x00110007, 0, 0); -	BackgroundItem *backgroundItem = _backgroundItems->debugFirst(); -	_system->copyRectToScreen((byte*)backgroundItem->_surfaces[0]->getBasePtr(0, 0), backgroundItem->_surfaces[0]->pitch, 0, 0, 640, 480); -	_system->updateScreen(); -	_camera->panToPoint(Common::Point(800, 0), 500, 0); -	while (!shouldQuit()) { -		//debug("panPoints[0] = %d, %d", backgroundItem->_panPoints[0].x, backgroundItem->_panPoints[0].y); -		uint32 t = getCurrentTime(); -		//debug("t = %d", t); -		_camera->update(t); -		_system->delayMillis(10); -		_system->copyRectToScreen((byte*)backgroundItem->_surfaces[0]->getBasePtr(backgroundItem->_panPoints[0].x, 0), -			backgroundItem->_surfaces[0]->pitch, 0, 0, 640, 480); -		_system->updateScreen(); -		updateEvents(); -	} -#endif -	 -#if 0 -	// ScriptResource test -	_resSys->loadResource(0x000D0001, 0, 0); -	_scriptMan->startScriptThread(0x00020004, 0, 0, 0, 0); -	while (!shouldQuit()) { -		updateEvents(); -		_scriptMan->_threads->updateThreads(); -	} -#endif -  #if 1  	// Actor/graphics/script test @@ -156,23 +121,9 @@ Common::Error IllusionsEngine::run() {  	_resSys->loadResource(0x000D0001, 0, 0); -#if 0	 -	_resSys->loadResource(0x0011000B, 0, 0); -	_resSys->loadResource(0x0010000B, 0, 0); - -#if 0 -	_controls->placeActor(0x00050009, Common::Point(0, 0), 0x00060573, 0x00040001, 0); -	Control *control = *_controls->_controls.begin(); -	control->setActorFrameIndex(1); -	control->appearActor(); -#endif -#endif -  	_scriptMan->startScriptThread(0x00020004, 0, 0, 0, 0);  	_scriptMan->_doScriptThreadInit = true; -	//_camera->panToPoint(Common::Point(800, 0), 500, 0); -  	while (!shouldQuit()) {  		_scriptMan->_threads->updateThreads();  		updateActors(); @@ -262,7 +213,6 @@ uint32 IllusionsEngine::getElapsedUpdateTime() {  int IllusionsEngine::updateActors() {  	// TODO Move to Controls class  	uint32 deltaTime = getElapsedUpdateTime(); -	//debug("deltaTime: %d", deltaTime);  	for (Controls::ItemsIterator it = _controls->_controls.begin(); it != _controls->_controls.end(); ++it) {  		Control *control = *it;  		if (control->_pauseCtr == 0 && control->_actor && control->_actor->_controlRoutine) @@ -294,8 +244,7 @@ int IllusionsEngine::updateGraphics() {  		BackgroundResource *bgRes = backgroundItem->_bgRes;  		for (uint i = 0; i < bgRes->_bgInfosCount; ++i) {  			BgInfo *bgInfo = &bgRes->_bgInfos[i]; -			// TODO int16 priority = artcntrlGetPriorityFromBase(bgInfos[v7].priorityBase); -			int16 priority = -1; +			uint32 priority = getPriorityFromBase(bgInfo->_priorityBase);  			_screen->_drawQueue->insertSurface(backgroundItem->_surfaces[i],  				bgInfo->_surfInfo._dimensions, backgroundItem->_panPoints[i], priority);  			if (bgInfo->_flags & 1) @@ -324,8 +273,7 @@ int IllusionsEngine::updateGraphics() {  			}  			*/  			if (actor->_surfInfo._dimensions._width && actor->_surfInfo._dimensions._height) { -				// TODO int16 priority = control->getPriority(); -				int16 priority = 2; +				uint32 priority = control->getPriority();  				_screen->_drawQueue->insertSprite(&actor->_drawFlags, actor->_surface,  					actor->_surfInfo._dimensions, drawPosition, control->_position,  					priority, actor->_scale, actor->_spriteFlags); @@ -352,7 +300,7 @@ bool IllusionsEngine::causeIsDeclared(uint32 sceneId, uint32 verbId, uint32 obje  	uint32 codeOffs;  	// TODO Also search for native trigger functions later (findCauseFunc)  	bool r = _scriptMan->findTriggerCause(sceneId, verbId, objectId2, objectId, codeOffs); -	debug("causeIsDeclared() sceneId: %08X; verbId: %08X; objectId2: %08X; objectId: %08X -> %d", +	debug(3, "causeIsDeclared() sceneId: %08X; verbId: %08X; objectId2: %08X; objectId: %08X -> %d",  		sceneId, verbId, objectId2, objectId, r);  	return r;  } @@ -374,10 +322,26 @@ int IllusionsEngine::convertPanXCoord(int16 x) {  }  Common::Point IllusionsEngine::getNamedPointPosition(uint32 namedPointId) { +	Common::Point pt; +	if (_backgroundItems->findActiveBackgroundNamedPoint(namedPointId, pt) || +		_actorItems->findNamedPoint(namedPointId, pt) || +		_controls->findNamedPoint(namedPointId, pt)) +    	return pt;  	// TODO +	debug("getNamedPointPosition(%08X) UNKNOWN", namedPointId);  	return Common::Point(0, 0);  } +uint32 IllusionsEngine::getPriorityFromBase(int16 priority) { +	return 32000000 * priority; +} + +bool IllusionsEngine::calcPointDirection(Common::Point &pos1, Common::Point &pos2, uint &facing) { +	// TODO +	facing = 0; +	return false; +} +  void IllusionsEngine::playVideo(uint32 videoId, uint32 objectId, uint32 priority, uint32 threadId) {  	// TODO  } diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h index 71f7a38d2e..58dc519285 100644 --- a/engines/illusions/illusions.h +++ b/engines/illusions/illusions.h @@ -119,6 +119,9 @@ public:  	int convertPanXCoord(int16 x);  	Common::Point getNamedPointPosition(uint32 namedPointId); +	uint32 getPriorityFromBase(int16 priority); +	bool calcPointDirection(Common::Point &pos1, Common::Point &pos2, uint &facing); +  	void playVideo(uint32 videoId, uint32 objectId, uint32 value, uint32 threadId);  	bool isSoundActive(); diff --git a/engines/illusions/input.cpp b/engines/illusions/input.cpp index b9ae53abd1..1a174b1be2 100644 --- a/engines/illusions/input.cpp +++ b/engines/illusions/input.cpp @@ -121,6 +121,7 @@ void Input::initKeys() {  	// NOTE Skipped debugging keys of the original engine, not sure if used  	addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON0, 0x01);  	addKeyMapping(Common::KEYCODE_RETURN, MOUSE_NONE, 0x01); +	addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x02);  	addKeyMapping(Common::KEYCODE_TAB, MOUSE_NONE, 0x04);  	addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x04);  	addKeyMapping(Common::KEYCODE_ESCAPE, MOUSE_NONE, 0x08); @@ -153,15 +154,9 @@ void Input::handleKey(Common::KeyCode key, int mouseButton, bool down) {  		}  	}  	uint prevButtonStates = _buttonStates; - -	debug("_newKeys = %08X", _newKeys); -  	_buttonStates |= _newKeys;  	_newKeys = 0;  	_newButtons = ~prevButtonStates & _buttonStates; -	 -	debug("_buttonStates = %08X", _buttonStates); -	  }  void Input::handleMouseButton(int mouseButton, bool down) { diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk index 762bd4c935..6a31657cba 100644 --- a/engines/illusions/module.mk +++ b/engines/illusions/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \  	backgroundresource.o \  	bbdou/bbdou_bubble.o \  	bbdou/bbdou_cursor.o \ +	bbdou/bbdou_inventory.o \  	bbdou/bbdou_specialcode.o \  	camera.o \  	cursor.o \ diff --git a/engines/illusions/scriptman.cpp b/engines/illusions/scriptman.cpp index 27e570a605..b556c0c1b8 100644 --- a/engines/illusions/scriptman.cpp +++ b/engines/illusions/scriptman.cpp @@ -147,14 +147,14 @@ void ScriptMan::setSceneIdThreadId(uint32 theSceneId, uint32 theThreadId) {  void ScriptMan::startScriptThread(uint32 threadId, uint32 callingThreadId,  	uint32 value8, uint32 valueC, uint32 value10) { -	debug("Starting script thread %08X", threadId); +	debug(2, "Starting script thread %08X", threadId);  	byte *scriptCodeIp = _scriptResource->getThreadCode(threadId);  	newScriptThread(threadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);  }  void ScriptMan::startAnonScriptThread(int32 threadId, uint32 callingThreadId,  	uint32 value8, uint32 valueC, uint32 value10) { -	debug("Starting anonymous script thread %08X", threadId); +	debug(2, "Starting anonymous script thread %08X", threadId);  	uint32 tempThreadId = newTempThreadId();  	byte *scriptCodeIp = _scriptResource->getThreadCode(threadId);  	scriptCodeIp = _scriptResource->getThreadCode(threadId); @@ -164,7 +164,7 @@ void ScriptMan::startAnonScriptThread(int32 threadId, uint32 callingThreadId,  uint32 ScriptMan::startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,  	uint32 value8, uint32 valueC, uint32 value10) {  	uint32 tempThreadId = newTempThreadId(); -	debug("Starting temp script thread %08X", tempThreadId); +	debug(2, "Starting temp script thread %08X", tempThreadId);  	newScriptThread(tempThreadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);  	return tempThreadId;  } @@ -179,7 +179,7 @@ uint32 ScriptMan::startTimerThread(uint32 duration, uint32 threadId) {  uint32 ScriptMan::startAbortableThread(byte *scriptCodeIp1, byte *scriptCodeIp2, uint32 callingThreadId) {  	uint32 tempThreadId = newTempThreadId(); -	debug("Starting abortable thread %08X", tempThreadId); +	debug(2, "Starting abortable thread %08X", tempThreadId);  	uint32 scriptThreadId = startTempScriptThread(scriptCodeIp1, tempThreadId, 0, 0, 0);  	AbortableThread *abortableThread = new AbortableThread(_vm, tempThreadId, callingThreadId, 0,  		scriptThreadId, scriptCodeIp2); @@ -189,7 +189,7 @@ uint32 ScriptMan::startAbortableThread(byte *scriptCodeIp1, byte *scriptCodeIp2,  uint32 ScriptMan::startTalkThread(int16 duration, uint32 objectId, uint32 talkId, uint32 sequenceId1,  	uint32 sequenceId2, uint32 namedPointId, uint32 callingThreadId) { -	debug("Starting talk thread"); +	debug(2, "Starting talk thread");  	uint32 tempThreadId = newTempThreadId();  	// TODO endTalkThreadsNoNotify();  	TalkThread *talkThread = new TalkThread(_vm, tempThreadId, callingThreadId, 0, diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index 8abfa8b63b..abfda679c7 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -23,6 +23,7 @@  #include "illusions/illusions.h"  #include "illusions/scriptopcodes.h"  #include "illusions/actor.h" +#include "illusions/camera.h"  #include "illusions/dictionary.h"  #include "illusions/input.h"  #include "illusions/screen.h" @@ -69,7 +70,7 @@ ScriptOpcodes::~ScriptOpcodes() {  void ScriptOpcodes::execOpcode(ScriptThread *scriptThread, OpCall &opCall) {  	if (!_opcodes[opCall._op])  		error("ScriptOpcodes::execOpcode() Unimplemented opcode %d", opCall._op); -	debug("\nexecOpcode([%08X] %d) %s", opCall._callerThreadId, opCall._op, _opcodeNames[opCall._op].c_str()); +	debug(0, "\nexecOpcode([%08X] %d) %s", opCall._callerThreadId, opCall._op, _opcodeNames[opCall._op].c_str());  	(*_opcodes[opCall._op])(scriptThread, opCall);  } @@ -96,18 +97,27 @@ void ScriptOpcodes::initOpcodes() {  	OPCODE(17, opUnloadResource);  	OPCODE(20, opEnterScene);  	OPCODE(25, opChangeScene); +	OPCODE(26, opStartModalScene);  	OPCODE(30, opEnterCloseUpScene);  	OPCODE(31, opExitCloseUpScene); +	OPCODE(32, opPanCenterObject); +	OPCODE(35, opPanToNamedPoint); +	OPCODE(37, opPanStop);  	OPCODE(39, opSetDisplay);  	OPCODE(42, opIncBlockCounter);  	OPCODE(45, opSetProperty); -	OPCODE(46, opPlaceActor);	 +	OPCODE(46, opPlaceActor); +	OPCODE(47, opFaceActor); +	OPCODE(48, opFaceActorToObject);	  	OPCODE(49, opStartSequenceActor); +	OPCODE(51, opStartMoveActor); +	OPCODE(53, opSetActorToNamedPoint);  	OPCODE(56, opStartTalkThread);  	OPCODE(57, opAppearActor);  	OPCODE(58, opDisappearActor);  	OPCODE(60, opActivateObject);  	OPCODE(61, opDeactivateObject); +	OPCODE(62, opSetDefaultSequence);  	OPCODE(63, opSetSelectSfx);  	OPCODE(64, opSetMoveSfx);  	OPCODE(65, opSetDenySfx); @@ -126,7 +136,9 @@ void ScriptOpcodes::initOpcodes() {  	OPCODE(87, opDeactivateButton);  	OPCODE(88, opActivateButton);  	OPCODE(103, opJumpIf); -	OPCODE(107, opBoolNot); +	OPCODE(107, opNot); +	OPCODE(108, opAnd); +	OPCODE(109, opOr);  	OPCODE(110, opGetProperty);  	OPCODE(111, opCompareBlockCounter);  	OPCODE(126, opDebug126); @@ -156,8 +168,8 @@ void ScriptOpcodes::freeOpcodes() {  // Convenience macros  #define	ARG_SKIP(x) opCall.skip(x);  -#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name); -#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name); +#define ARG_INT16(name) int16 name = opCall.readSint16(); debug(0, "ARG_INT16(" #name " = %d)", name); +#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug(0, "ARG_UINT32(" #name " = %08X)", name);  void ScriptOpcodes::opSuspend(ScriptThread *scriptThread, OpCall &opCall) {  	opCall._result = kTSSuspend; @@ -218,7 +230,7 @@ void ScriptOpcodes::opLoadResource(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(resourceId);  	// NOTE Skipped checking for stalled resources -	uint32 sceneId = _vm->_scriptMan->_activeScenes.getCurrentScene(); +	uint32 sceneId = _vm->getCurrentScene();  	_vm->_resSys->loadResource(resourceId, sceneId, opCall._threadId);  } @@ -248,7 +260,7 @@ void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_UINT32(threadId);  	// NOTE Skipped checking for stalled resources  	_vm->_input->discardButtons(0xFFFF); -	_vm->_scriptMan->_prevSceneId = _vm->_scriptMan->_activeScenes.getCurrentScene(); +	_vm->_scriptMan->_prevSceneId = _vm->getCurrentScene();  	_vm->_scriptMan->exitScene(opCall._callerThreadId);  	_vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId);  	// TODO _vm->_gameStates->writeStates(_vm->_scriptMan->_prevSceneId, sceneId, threadId); @@ -256,6 +268,20 @@ void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {  		scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10);  } +void ScriptOpcodes::opStartModalScene(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_SKIP(2); +	ARG_UINT32(sceneId); +	ARG_UINT32(threadId); +	// NOTE Skipped checking for stalled resources +	_vm->_input->discardButtons(0xFFFF); +	_vm->_scriptMan->enterPause(opCall._callerThreadId); +	// TODO _vm->_talkItems->pauseByTag(_vm->getCurrentScene()); +	_vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId); +	_vm->_scriptMan->startScriptThread(threadId, 0, +		scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10); +	opCall._result = kTSSuspend; +} +  void ScriptOpcodes::opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(sceneId); @@ -271,6 +297,23 @@ void ScriptOpcodes::opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCal  	opCall._result = kTSYield;  } +void ScriptOpcodes::opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(speed);	 +	ARG_UINT32(objectId); +	_vm->_camera->panCenterObject(objectId, speed); +} + +void ScriptOpcodes::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(speed);	 +	ARG_UINT32(namedPointId); +	Common::Point pos = _vm->getNamedPointPosition(namedPointId); +	_vm->_camera->panToPoint(pos, speed, opCall._callerThreadId); +} + +void ScriptOpcodes::opPanStop(ScriptThread *scriptThread, OpCall &opCall) { +	_vm->_camera->stopPan(); +} +  void ScriptOpcodes::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_INT16(flag);  	_vm->_screen->setDisplayOn(flag != 0); @@ -299,16 +342,59 @@ void ScriptOpcodes::opPlaceActor(ScriptThread *scriptThread, OpCall &opCall) {  	_vm->_controls->placeActor(actorTypeId, pos, sequenceId, objectId, opCall._threadId);  } +void ScriptOpcodes::opFaceActor(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(facing); +	ARG_UINT32(objectId); +	Control *control = _vm->_dict->getObjectControl(objectId); +	control->faceActor(facing); +} + +void ScriptOpcodes::opFaceActorToObject(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_SKIP(2); +	ARG_UINT32(objectId1); +	ARG_UINT32(objectId2); +	Control *control1 = _vm->_dict->getObjectControl(objectId1); +	Control *control2 = _vm->_dict->getObjectControl(objectId2); +	Common::Point pos1 = control1->getActorPosition(); +	Common::Point pos2 = control2->getActorPosition(); +	uint facing; +	if (_vm->calcPointDirection(pos1, pos2, facing)) +		control1->faceActor(facing); +} +  void ScriptOpcodes::opStartSequenceActor(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(objectId);  	ARG_UINT32(sequenceId);  	// NOTE Skipped checking for stalled sequence, not sure if needed  	Control *control = _vm->_dict->getObjectControl(objectId); -	debug("control: %p", (void*)control);  	control->startSequenceActor(sequenceId, 2, opCall._threadId);  } +void ScriptOpcodes::opStartMoveActor(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_SKIP(2); +	ARG_UINT32(objectId); +	ARG_UINT32(sequenceId); +	ARG_UINT32(namedPointId); +	// NOTE Skipped checking for stalled sequence, not sure if needed +	Control *control = _vm->_dict->getObjectControl(objectId); +	Common::Point pos = _vm->getNamedPointPosition(namedPointId); +	// TODO _control->startMoveActor(sequenceId, pos, opCall._callerThreadId, opCall._threadId); + +	//DEBUG Resume calling thread, later done by the walking +	_vm->notifyThreadId(opCall._threadId); +} + +void ScriptOpcodes::opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_SKIP(2); +	ARG_UINT32(objectId); +	ARG_UINT32(namedPointId); +	Control *control = _vm->_dict->getObjectControl(objectId); +	Common::Point pos = _vm->getNamedPointPosition(namedPointId); +	control->stopActor(); +	control->setActorPosition(pos); +} +  void ScriptOpcodes::opStartTalkThread(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_INT16(duration);	  	ARG_UINT32(objectId); @@ -358,6 +444,15 @@ void ScriptOpcodes::opDeactivateObject(ScriptThread *scriptThread, OpCall &opCal  	control->deactivateObject();  } +void ScriptOpcodes::opSetDefaultSequence(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_SKIP(2); +	ARG_UINT32(objectId); +	ARG_UINT32(defaultSequenceId); +	ARG_UINT32(sequenceId); +	Control *control = _vm->_dict->getObjectControl(objectId); +	control->_actor->_defaultSequences.set(sequenceId, defaultSequenceId); +} +  void ScriptOpcodes::opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(soundEffectId); @@ -482,11 +577,23 @@ void ScriptOpcodes::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) {  		opCall._deltaOfs += jumpOffs;  } -void ScriptOpcodes::opBoolNot(ScriptThread *scriptThread, OpCall &opCall) { +void ScriptOpcodes::opNot(ScriptThread *scriptThread, OpCall &opCall) {  	int16 value = _vm->_scriptMan->_stack.pop();  	_vm->_scriptMan->_stack.push(value != 0 ? 0 : 1);  } +void ScriptOpcodes::opAnd(ScriptThread *scriptThread, OpCall &opCall) { +	int16 value1 = _vm->_scriptMan->_stack.pop(); +	int16 value2 = _vm->_scriptMan->_stack.pop(); +	_vm->_scriptMan->_stack.push(value1 & value2); +} + +void ScriptOpcodes::opOr(ScriptThread *scriptThread, OpCall &opCall) { +	int16 value1 = _vm->_scriptMan->_stack.pop(); +	int16 value2 = _vm->_scriptMan->_stack.pop(); +	_vm->_scriptMan->_stack.push(value1 | value2); +} +  void ScriptOpcodes::opGetProperty(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(propertyId) diff --git a/engines/illusions/scriptopcodes.h b/engines/illusions/scriptopcodes.h index 0e75f780de..8516c85156 100644 --- a/engines/illusions/scriptopcodes.h +++ b/engines/illusions/scriptopcodes.h @@ -72,18 +72,27 @@ protected:  	void opUnloadResource(ScriptThread *scriptThread, OpCall &opCall);  	void opEnterScene(ScriptThread *scriptThread, OpCall &opCall);  	void opChangeScene(ScriptThread *scriptThread, OpCall &opCall); +	void opStartModalScene(ScriptThread *scriptThread, OpCall &opCall);  	void opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);  	void opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCall); +	void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall); +	void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall); +	void opPanStop(ScriptThread *scriptThread, OpCall &opCall);  	void opSetDisplay(ScriptThread *scriptThread, OpCall &opCall);	  	void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall);  	void opSetProperty(ScriptThread *scriptThread, OpCall &opCall);  	void opPlaceActor(ScriptThread *scriptThread, OpCall &opCall); +	void opFaceActor(ScriptThread *scriptThread, OpCall &opCall); +	void opFaceActorToObject(ScriptThread *scriptThread, OpCall &opCall);  	void opStartSequenceActor(ScriptThread *scriptThread, OpCall &opCall); +	void opStartMoveActor(ScriptThread *scriptThread, OpCall &opCall); +	void opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);  	void opStartTalkThread(ScriptThread *scriptThread, OpCall &opCall);  	void opAppearActor(ScriptThread *scriptThread, OpCall &opCall);  	void opDisappearActor(ScriptThread *scriptThread, OpCall &opCall);  	void opActivateObject(ScriptThread *scriptThread, OpCall &opCall);  	void opDeactivateObject(ScriptThread *scriptThread, OpCall &opCall); +	void opSetDefaultSequence(ScriptThread *scriptThread, OpCall &opCall);  	void opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall);  	void opSetMoveSfx(ScriptThread *scriptThread, OpCall &opCall);  	void opSetDenySfx(ScriptThread *scriptThread, OpCall &opCall); @@ -102,7 +111,9 @@ protected:  	void opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall);  	void opActivateButton(ScriptThread *scriptThread, OpCall &opCall);  	void opJumpIf(ScriptThread *scriptThread, OpCall &opCall); -	void opBoolNot(ScriptThread *scriptThread, OpCall &opCall); +	void opNot(ScriptThread *scriptThread, OpCall &opCall); +	void opAnd(ScriptThread *scriptThread, OpCall &opCall); +	void opOr(ScriptThread *scriptThread, OpCall &opCall);  	void opGetProperty(ScriptThread *scriptThread, OpCall &opCall);  	void opCompareBlockCounter(ScriptThread *scriptThread, OpCall &opCall);  	void opDebug126(ScriptThread *scriptThread, OpCall &opCall); diff --git a/engines/illusions/sequenceopcodes.cpp b/engines/illusions/sequenceopcodes.cpp index 2495bcac7f..409aa15816 100644 --- a/engines/illusions/sequenceopcodes.cpp +++ b/engines/illusions/sequenceopcodes.cpp @@ -24,6 +24,7 @@  #include "illusions/sequenceopcodes.h"  #include "illusions/actor.h"  #include "illusions/actorresource.h" +#include "illusions/dictionary.h"  #include "illusions/scriptopcodes.h"  namespace Illusions { @@ -59,7 +60,9 @@ void SequenceOpcodes::initOpcodes() {  	OPCODE(5, opSetRandomFrameDelay);  	OPCODE(6, opSetFrameSpeed);  	OPCODE(7, opJump); +	OPCODE(8, opJumpRandom);  	OPCODE(9, opGotoSequence); +	OPCODE(10, opStartForeignSequence);  	OPCODE(11, opBeginLoop);  	OPCODE(12, opNextLoop);  	OPCODE(14, opSwitchActorIndex); @@ -74,6 +77,7 @@ void SequenceOpcodes::initOpcodes() {  	OPCODE(40, opSetPriorityLayer);  	OPCODE(50, opPlaySound);  	OPCODE(51, opStopSound); +	OPCODE(53, opPlaceSubActor);  }  #undef OPCODE @@ -142,6 +146,13 @@ void SequenceOpcodes::opJump(Control *control, OpCall &opCall) {  	opCall._deltaOfs += jumpOffs;  } +void SequenceOpcodes::opJumpRandom(Control *control, OpCall &opCall) { +	ARG_INT16(count); +	ARG_SKIP(_vm->getRandom(count) * 2); +	ARG_INT16(jumpOffs); +	opCall._deltaOfs += jumpOffs; +} +  void SequenceOpcodes::opGotoSequence(Control *control, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(nextSequenceId); @@ -155,6 +166,13 @@ void SequenceOpcodes::opGotoSequence(Control *control, OpCall &opCall) {  	opCall._deltaOfs = 0;  } +void SequenceOpcodes::opStartForeignSequence(Control *control, OpCall &opCall) { +	ARG_INT16(foreignObjectNum); +	ARG_UINT32(sequenceId); +	Control *foreignControl = _vm->_dict->getObjectControl(foreignObjectNum | 0x40000); +	foreignControl->startSequenceActor(sequenceId, 2, 0); +} +  void SequenceOpcodes::opBeginLoop(Control *control, OpCall &opCall) {  	ARG_INT16(loopCount);  	control->_actor->pushSequenceStack(loopCount); @@ -252,4 +270,11 @@ void SequenceOpcodes::opStopSound(Control *control, OpCall &opCall) {  	// TODO _vm->stopSound(soundEffectId);  } +void SequenceOpcodes::opPlaceSubActor(Control *control, OpCall &opCall) { + 	ARG_INT16(linkIndex); + 	ARG_UINT32(actorTypeId); + 	ARG_UINT32(sequenceId); + 	_vm->_controls->placeSubActor(control->_objectId, linkIndex, actorTypeId, sequenceId); +} +  } // End of namespace Illusions diff --git a/engines/illusions/sequenceopcodes.h b/engines/illusions/sequenceopcodes.h index dd1302f9e9..849846ffc9 100644 --- a/engines/illusions/sequenceopcodes.h +++ b/engines/illusions/sequenceopcodes.h @@ -50,7 +50,9 @@ protected:  	void opSetRandomFrameDelay(Control *control, OpCall &opCall);  	void opSetFrameSpeed(Control *control, OpCall &opCall);	  	void opJump(Control *control, OpCall &opCall); +	void opJumpRandom(Control *control, OpCall &opCall);  	void opGotoSequence(Control *control, OpCall &opCall); +	void opStartForeignSequence(Control *control, OpCall &opCall);  	void opBeginLoop(Control *control, OpCall &opCall);  	void opNextLoop(Control *control, OpCall &opCall);  	void opSwitchActorIndex(Control *control, OpCall &opCall); @@ -64,7 +66,8 @@ protected:  	void opSetPriority(Control *control, OpCall &opCall);  	void opSetPriorityLayer(Control *control, OpCall &opCall);  	void opPlaySound(Control *control, OpCall &opCall); -	void opStopSound(Control *control, OpCall &opCall);	 +	void opStopSound(Control *control, OpCall &opCall); +	void opPlaceSubActor(Control *control, OpCall &opCall);	  }; diff --git a/engines/illusions/spritedrawqueue.cpp b/engines/illusions/spritedrawqueue.cpp index f39eb5fb76..d5a7394ac5 100644 --- a/engines/illusions/spritedrawqueue.cpp +++ b/engines/illusions/spritedrawqueue.cpp @@ -82,7 +82,7 @@ void SpriteDrawQueue::drawAll() {  }  void SpriteDrawQueue::insertSprite(byte *drawFlags, Graphics::Surface *surface, WidthHeight &dimensions, -	Common::Point &drawPosition, Common::Point &controlPosition, int priority, int16 scale, uint16 flags) { +	Common::Point &drawPosition, Common::Point &controlPosition, uint32 priority, int16 scale, uint16 flags) {  	SpriteDrawQueueItem *item = new SpriteDrawQueueItem();  	item->_drawFlags = drawFlags;  	*item->_drawFlags &= 4; @@ -98,7 +98,7 @@ void SpriteDrawQueue::insertSprite(byte *drawFlags, Graphics::Surface *surface,  }  void SpriteDrawQueue::insertSurface(Graphics::Surface *surface, WidthHeight &dimensions, -	Common::Point &drawPosition, int priority) { +	Common::Point &drawPosition, uint32 priority) {  	SpriteDrawQueueItem *item = new SpriteDrawQueueItem();  	item->_surface = surface;  	item->_dimensions = dimensions; @@ -110,12 +110,12 @@ void SpriteDrawQueue::insertSurface(Graphics::Surface *surface, WidthHeight &dim  	item->_controlPosition.y = 0;  	item->_flags = 0;  	item->_scale = 100; -	item->_priority = priority << 16; +	item->_priority = priority;// << 16;  	insert(item, priority);  }  void SpriteDrawQueue::insertTextSurface(Graphics::Surface *surface, WidthHeight &dimensions, -	Common::Point &drawPosition, int priority) { +	Common::Point &drawPosition, uint32 priority) {  	SpriteDrawQueueItem *item = new SpriteDrawQueueItem();  	item->_surface = surface;  	item->_drawPosition = drawPosition; @@ -130,7 +130,7 @@ void SpriteDrawQueue::insertTextSurface(Graphics::Surface *surface, WidthHeight  	insert(item, priority);  } -void SpriteDrawQueue::insert(SpriteDrawQueueItem *item, int priority) { +void SpriteDrawQueue::insert(SpriteDrawQueueItem *item, uint32 priority) {  	SpriteDrawQueueListIterator insertionPos = Common::find_if(_queue.begin(), _queue.end(),  		FindInsertionPosition(priority));  	_queue.insert(insertionPos, item); @@ -143,9 +143,6 @@ bool SpriteDrawQueue::calcItemRect(SpriteDrawQueueItem *item, Common::Rect &srcR  	srcRect.right = item->_dimensions._width;  	srcRect.bottom = item->_dimensions._height; -	//debug("item->_drawPosition.x: %d; item->_drawPosition.y: %d", item->_drawPosition.x, item->_drawPosition.y); -	//debug("item->_controlPosition.x: %d; item->_controlPosition.y: %d", item->_controlPosition.x, item->_controlPosition.y); -  	dstRect.left = item->_drawPosition.x - item->_scale * item->_controlPosition.x / 100;  	dstRect.top = item->_drawPosition.y - item->_scale * item->_controlPosition.y / 100;  	dstRect.right = item->_drawPosition.x + item->_scale * (item->_dimensions._width - item->_controlPosition.x) / 100; diff --git a/engines/illusions/spritedrawqueue.h b/engines/illusions/spritedrawqueue.h index 30b999a15a..baa421704e 100644 --- a/engines/illusions/spritedrawqueue.h +++ b/engines/illusions/spritedrawqueue.h @@ -39,7 +39,7 @@ struct SpriteDrawQueueItem {  	int16 _scale;  	uint16 _flags;  	//field_A dw -	int _priority; +	uint32 _priority;  	Graphics::Surface *_surface;  	WidthHeight _dimensions;  	Common::Point _drawPosition; @@ -53,18 +53,18 @@ public:  	bool draw(SpriteDrawQueueItem *item);  	void drawAll();  	void insertSprite(byte *drawFlags, Graphics::Surface *surface, WidthHeight &dimensions, -		Common::Point &drawPosition, Common::Point &controlPosition, int priority, int16 scale, uint16 flags); +		Common::Point &drawPosition, Common::Point &controlPosition, uint32 priority, int16 scale, uint16 flags);  	void insertSurface(Graphics::Surface *surface, WidthHeight &dimensions, -		Common::Point &drawPosition, int priority); +		Common::Point &drawPosition, uint32 priority);  	void insertTextSurface(Graphics::Surface *surface, WidthHeight &dimensions, -		Common::Point &drawPosition, int priority); +		Common::Point &drawPosition, uint32 priority);  protected:  	typedef Common::List<SpriteDrawQueueItem*> SpriteDrawQueueList;  	typedef SpriteDrawQueueList::iterator SpriteDrawQueueListIterator;  	struct FindInsertionPosition : public Common::UnaryFunction<const SpriteDrawQueueItem*, bool> { -		int _priority; -		FindInsertionPosition(int priority) : _priority(priority) {} +		uint32 _priority; +		FindInsertionPosition(uint32 priority) : _priority(priority) {}  		bool operator()(const SpriteDrawQueueItem *item) const {  			return item->_priority >= _priority;  		} @@ -72,7 +72,7 @@ protected:  	Screen *_screen;  	SpriteDrawQueueList _queue;	 -	void insert(SpriteDrawQueueItem *item, int priority); +	void insert(SpriteDrawQueueItem *item, uint32 priority);  	bool calcItemRect(SpriteDrawQueueItem *item, Common::Rect &srcRect, Common::Rect &dstRect);  }; diff --git a/engines/illusions/thread.cpp b/engines/illusions/thread.cpp index 0a9b0d90b4..83e0ce5ab4 100644 --- a/engines/illusions/thread.cpp +++ b/engines/illusions/thread.cpp @@ -101,10 +101,8 @@ int Thread::update() {  void Thread::terminate() {  	if (!_terminated) { -		if (!(_notifyFlags & 1)) { -			debug("Thread::terminate() _callingThreadId: %08X", _callingThreadId); +		if (!(_notifyFlags & 1))  			_vm->notifyThreadId(_callingThreadId); -		}  		_callingThreadId = 0;  		onTerminated();  		// TODO _vm->removeThread(_threadId, this);  | 
