diff options
| author | johndoe123 | 2014-03-30 09:31:53 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 | 
| commit | babe997295dbadd95ab497bc6b88e7a0021567e5 (patch) | |
| tree | e61eb739a3d3f92f8d7e731d3684757932f70652 | |
| parent | 3b3f84c764f8cab8f54b06bbafc607cfb6899fdd (diff) | |
| download | scummvm-rg350-babe997295dbadd95ab497bc6b88e7a0021567e5.tar.gz scummvm-rg350-babe997295dbadd95ab497bc6b88e7a0021567e5.tar.bz2 scummvm-rg350-babe997295dbadd95ab497bc6b88e7a0021567e5.zip  | |
ILLUSIONS: Add more script opcodes
- Add support for duplicate keys to the dictionary
- Add trigger functions support
- Improve inventory, now items can be clicked
| -rw-r--r-- | engines/illusions/actor.cpp | 50 | ||||
| -rw-r--r-- | engines/illusions/actor.h | 2 | ||||
| -rw-r--r-- | engines/illusions/actorresource.cpp | 2 | ||||
| -rw-r--r-- | engines/illusions/backgroundresource.cpp | 12 | ||||
| -rw-r--r-- | engines/illusions/bbdou/bbdou_inventory.cpp | 123 | ||||
| -rw-r--r-- | engines/illusions/bbdou/bbdou_inventory.h | 6 | ||||
| -rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.cpp | 60 | ||||
| -rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.h | 5 | ||||
| -rw-r--r-- | engines/illusions/dictionary.h | 36 | ||||
| -rw-r--r-- | engines/illusions/illusions.cpp | 27 | ||||
| -rw-r--r-- | engines/illusions/illusions.h | 8 | ||||
| -rw-r--r-- | engines/illusions/scriptman.cpp | 77 | ||||
| -rw-r--r-- | engines/illusions/scriptman.h | 30 | ||||
| -rw-r--r-- | engines/illusions/scriptopcodes.cpp | 65 | ||||
| -rw-r--r-- | engines/illusions/scriptopcodes.h | 6 | ||||
| -rw-r--r-- | engines/illusions/sequenceopcodes.cpp | 39 | ||||
| -rw-r--r-- | engines/illusions/sequenceopcodes.h | 7 | ||||
| -rw-r--r-- | engines/illusions/talkresource.cpp | 2 | 
18 files changed, 518 insertions, 39 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp index 53190ef97b..d9eb94975f 100644 --- a/engines/illusions/actor.cpp +++ b/engines/illusions/actor.cpp @@ -30,6 +30,8 @@  #include "illusions/scriptman.h"  #include "illusions/scriptopcodes.h"  #include "illusions/sequenceopcodes.h" +#include "illusions/talkthread.h" +#include "illusions/thread.h"  namespace Illusions { @@ -641,6 +643,51 @@ void Control::setActorIndexTo2() {  	_actor->_actorIndex = 2;  } +void Control::startSubSequence(int linkIndex, uint32 sequenceId) { +	Control *linkedControl = _vm->_dict->getObjectControl(_actor->_subobjects[linkIndex - 1]); +	Actor *linkedActor = linkedControl->_actor; +	if (!linkedActor->_entryTblPtr) +		linkedActor->_flags &= ~0x80; +	linkedActor->_flags &= ~0x400; +	linkedActor->_flags |= 0x100; +	linkedActor->_sequenceId = sequenceId; +	linkedActor->_notifyThreadId1 = 0; +	linkedActor->_notifyId3C = 0; +	linkedActor->_path40 = 0; + +	Sequence *sequence = _vm->_dict->findSequence(sequenceId); +	linkedActor->_seqCodeIp = sequence->_sequenceCode; +	linkedActor->_frames = _vm->_actorItems->findSequenceFrames(sequence); +	linkedActor->_seqCodeValue3 = 0; +	linkedActor->_seqCodeValue1 = 0; +	linkedActor->_seqCodeValue2 = 600; +	linkedActor->initSequenceStack(); +	linkedControl->sequenceActor(); +	linkedControl->appearActor(); +} + +void Control::stopSubSequence(int linkIndex) { +	Control *linkedControl = _vm->_dict->getObjectControl(_actor->_subobjects[linkIndex - 1]); +	Actor *linkedActor = linkedControl->_actor; +	uint32 notifySequenceId2 = _actor->_notifyThreadId2; +	_actor->_linkIndex2 = linkIndex; +	if (_actor->_entryTblPtr) { +		linkedActor->_flags |= 0x80; +		linkedActor->_entryTblPtr = _actor->_entryTblPtr; +		linkedActor->_notifyThreadId2 = _actor->_notifyThreadId2; +		linkedActor->_seqCodeValue1 = _actor->_seqCodeValue1; +		linkedActor->_seqCodeValue3 = _actor->_seqCodeValue3; +		_actor->_flags &= ~0x80; +		_actor->_entryTblPtr = 0; +		_actor->_notifyThreadId1 = 0; +		_actor->_notifyThreadId2 = 0; +	} +	if (notifySequenceId2) { +		Thread *talkThread = _vm->_scriptMan->_threads->findThread(notifySequenceId2); +		talkThread->sendMessage(kMsgClearSequenceId2, 0); +	} +} +  void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId) {  	stopActor(); @@ -710,6 +757,7 @@ void Controls::placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequ  	Actor *actor = newActor();  	ActorType *actorType = _vm->_dict->findActorType(actorTypeId); +	  	control->_objectId = objectId;  	control->_flags = actorType->_flags;  	control->_priority = actorType->_priority; @@ -718,11 +766,13 @@ void Controls::placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequ  	control->_actor = actor;  	if (actorTypeId == 0x50001 && objectId == 0x40004)  		actor->setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, Cursor>(_vm->_cursor, &Cursor::cursorControlRoutine)); +		  	if (actorType->_surfInfo._dimensions._width > 0 || actorType->_surfInfo._dimensions._height > 0) {  		actor->createSurface(actorType->_surfInfo);  	} else {  		actor->_flags |= 0x0200;  	} +  	actor->_position = placePt;  	actor->_position2 = placePt;  	Common::Point currPan = _vm->_camera->getCurrentPan(); diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h index 7e3bc7f228..50d3f7c1c8 100644 --- a/engines/illusions/actor.h +++ b/engines/illusions/actor.h @@ -174,6 +174,8 @@ public:  	void sequenceActor();  	void setActorIndexTo1();  	void setActorIndexTo2(); +	void startSubSequence(int linkIndex, uint32 sequenceId); +	void stopSubSequence(int linkIndex);  public:  	IllusionsEngine *_vm;  	uint _flags; diff --git a/engines/illusions/actorresource.cpp b/engines/illusions/actorresource.cpp index affca78879..058b093ac6 100644 --- a/engines/illusions/actorresource.cpp +++ b/engines/illusions/actorresource.cpp @@ -140,7 +140,7 @@ void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) {  		_pathWalkPointsIndex, _scaleLayerIndex, _pathWalkRectIndex);  	debug(5, "ActorType::load() _priorityLayerIndex: %d; _regionLayerIndex: %d; _flags: %04X",  		_priorityLayerIndex, _regionLayerIndex,_flags); - +		  }  // ActorResource diff --git a/engines/illusions/backgroundresource.cpp b/engines/illusions/backgroundresource.cpp index 50a88d284a..754b9d2e80 100644 --- a/engines/illusions/backgroundresource.cpp +++ b/engines/illusions/backgroundresource.cpp @@ -66,6 +66,7 @@ void BackgroundResourceLoader::unload(Resource *resource) {  	delete backgroundItem->_bgRes;  	_vm->_backgroundItems->freeBackgroundItem(backgroundItem);  	// TODO _vm->setDefPointDimensions1(); +	debug("BackgroundResourceLoader::unload() Unloading background %08X OK", resource->_resId);  }  void BackgroundResourceLoader::buildFilename(Resource *resource) { @@ -272,11 +273,12 @@ void BackgroundItem::initSurface() {  }  void BackgroundItem::freeSurface() { -	for (uint i = 0; i < _bgRes->_bgInfosCount; ++i) { -		_surfaces[i]->free(); -		delete _surfaces[i]; -		_surfaces[i] = 0; -	} +	for (uint i = 0; i < _bgRes->_bgInfosCount; ++i) +		if (_surfaces[i]) { +			_surfaces[i]->free(); +			delete _surfaces[i]; +			_surfaces[i] = 0; +		}  }  void BackgroundItem::drawTiles(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels) { diff --git a/engines/illusions/bbdou/bbdou_inventory.cpp b/engines/illusions/bbdou/bbdou_inventory.cpp index 4c5646f5b7..5502616337 100644 --- a/engines/illusions/bbdou/bbdou_inventory.cpp +++ b/engines/illusions/bbdou/bbdou_inventory.cpp @@ -28,9 +28,12 @@  #include "illusions/camera.h"  #include "illusions/dictionary.h"  #include "illusions/input.h" +#include "illusions/scriptman.h"  namespace Illusions { +typedef Common::Functor2Mem<TriggerFunction*, uint32, void, BbdouInventory> InventoryTriggerFunctionCallback; +  // InventoryItem  InventoryItem::InventoryItem(uint32 objectId, uint32 sequenceId) @@ -71,7 +74,9 @@ bool InventoryBag::addInventoryItem(InventoryItem *inventoryItem, InventorySlot  }  void InventoryBag::removeInventoryItem(InventoryItem *inventoryItem) { -	// TODO +	for (InventorySlotsIterator it = _inventorySlots.begin(); it != _inventorySlots.end(); ++it) +		if ((*it)->_inventoryItem && (*it)->_inventoryItem->_objectId == inventoryItem->_objectId) +			(*it)->_inventoryItem = 0;  }  void InventoryBag::buildItems() { @@ -87,12 +92,34 @@ void InventoryBag::buildItems() {  	}  } +InventorySlot *InventoryBag::getInventorySlot(uint32 objectId) { +	for (uint i = 0; i < _inventorySlots.size(); ++i) +		if (_inventorySlots[i]->_objectId == objectId) +			return _inventorySlots[i]; +	return 0; +} + +InventorySlot *InventoryBag::findClosestSlot(Common::Point putPos, int index) { +	uint minDistance = 0xFFFFFFFF; +	InventorySlot *minDistanceSlot = 0; +	for (InventorySlotsIterator it = _inventorySlots.begin(); it != _inventorySlots.end(); ++it) { +		InventorySlot *inventorySlot = *it; +		Common::Point slotPos = _vm->getNamedPointPosition(inventorySlot->_namedPointId); +		uint currDistance = (slotPos.y - putPos.y) * (slotPos.y - putPos.y) + (slotPos.x - putPos.x) * (slotPos.x - putPos.x); +		if (currDistance < minDistance) { +			minDistance = currDistance; +			minDistanceSlot = inventorySlot; +		} +	} +	return minDistanceSlot; +} +  // BbdouInventory  BbdouInventory::BbdouInventory(IllusionsEngine *vm, BbdouSpecialCode *bbdou)  	: _vm(vm), _bbdou(bbdou) {  } -				                                              +  void BbdouInventory::registerInventoryBag(uint32 sceneId) {  	_inventoryBags.push_back(new InventoryBag(_vm, sceneId));  	_activeBagSceneId = sceneId; @@ -158,9 +185,9 @@ void BbdouInventory::open() {  				inventorySlot->_objectId = _vm->_controls->newTempObjectId();  				_vm->_controls->placeActor(0x00050012, slotPos, 0x0006005A, inventorySlot->_objectId, 0);  			} -			// TODO causeDeclare(0x1B0002, 0, inventorySlot->_objectId, Inventory_cause0x1B0002); -			// TODO causeDeclare(0x1B0001, 0, inventorySlot->_objectId, Inventory_cause0x1B0001); -			// TODO causeDeclare(0x1B0008, 0, inventorySlot->_objectId, Inventory_cause0x1B0001); +			_vm->causeDeclare(0x1B0002, 0, inventorySlot->_objectId, new InventoryTriggerFunctionCallback(this, &BbdouInventory::cause0x1B0002)); +			_vm->causeDeclare(0x1B0001, 0, inventorySlot->_objectId, new InventoryTriggerFunctionCallback(this, &BbdouInventory::cause0x1B0001)); +			_vm->causeDeclare(0x1B0008, 0, inventorySlot->_objectId, new InventoryTriggerFunctionCallback(this, &BbdouInventory::cause0x1B0001));  		}  		refresh();  	} @@ -175,7 +202,7 @@ void BbdouInventory::close() {  		InventorySlot *inventorySlot = *it;  		Control *control = _vm->_dict->getObjectControl(inventorySlot->_objectId);  		control->startSequenceActor(0x00060187, 2, 0); -    } +	}      inventoryBag->_isActive = false;      _activeInventorySceneId = 0;  } @@ -225,4 +252,88 @@ void BbdouInventory::buildItems(InventoryBag *inventoryBag) {  	}  } +void BbdouInventory::cause0x1B0001(TriggerFunction *triggerFunction, uint32 callingThreadId) { +	// TODO +	debug("cause0x1B0001"); +	uint32 foundSceneId, foundVerbId, foundObjectId2, foundObjectId; +	bool found; +	InventoryBag *inventoryBag = getInventoryBag(_activeInventorySceneId); +	InventorySlot *inventorySlot = inventoryBag->getInventorySlot(triggerFunction->_objectId); +	uint32 objectId = inventorySlot->_inventoryItem->_objectId; + +	foundSceneId = _activeInventorySceneId; +	foundVerbId = triggerFunction->_verbId; +	foundObjectId2 = 0; + +	if (triggerFunction->_verbId == 0x1B0008) { +		foundVerbId = 0x1B0003; +		foundObjectId2 = _bbdou->_cursor->_data._holdingObjectId; +	} + +	if (_vm->causeIsDeclared(_activeInventorySceneId, foundVerbId, foundObjectId2, objectId)) { +		foundSceneId = _activeInventorySceneId; +		foundObjectId = objectId; +		found = true; +	} else if (foundVerbId == 0x1B0003 && _vm->causeIsDeclared(_activeInventorySceneId, 0x1B0008, 0, objectId)) { +		foundSceneId = _activeInventorySceneId; +		foundVerbId = 0x1B0008; +		foundObjectId2 = 0; +		foundObjectId = objectId; +		found = true; +	} else if (_vm->causeIsDeclared(_activeInventorySceneId, foundVerbId, foundObjectId2, 0x40001)) { +		foundSceneId = _activeInventorySceneId; +		foundObjectId = 0x40001; +		found = true; +	} else if (_vm->causeIsDeclared(0x10003, foundVerbId, foundObjectId2, objectId)) { +		foundSceneId = 0x10003; +		foundObjectId = objectId; +		found = true; +	} else if (foundVerbId == 0x1B0003 && _vm->causeIsDeclared(0x10003, 0x1B0008, 0, objectId)) { +		foundSceneId = 0x10003; +		foundVerbId = 0x1B0008; +		foundObjectId2 = 0; +		foundObjectId = objectId; +		found = true; +	} else if (_vm->causeIsDeclared(0x10003, foundVerbId, foundObjectId2, 0x40001)) { +		foundSceneId = 0x10003; +		foundObjectId = 0x40001; +		found = true; +	} + +	if (found) +		_vm->causeTrigger(foundSceneId, foundVerbId, foundObjectId2, foundObjectId, callingThreadId); +	else +		_vm->notifyThreadId(callingThreadId); + +} + +void BbdouInventory::cause0x1B0002(TriggerFunction *triggerFunction, uint32 callingThreadId) { +	InventoryBag *inventoryBag = getInventoryBag(_activeInventorySceneId); +	InventorySlot *inventorySlot = inventoryBag->getInventorySlot(triggerFunction->_objectId); +	uint32 objectId = inventorySlot->_inventoryItem->_objectId; +	if (_vm->causeIsDeclared(_activeInventorySceneId, triggerFunction->_verbId, 0, objectId)) { +		_vm->causeTrigger(_activeInventorySceneId, triggerFunction->_verbId, 0, objectId, callingThreadId); +	} else { +		_bbdou->startHoldingObjectId(0x4001A, objectId, 0); +		_vm->notifyThreadId(callingThreadId); +	} +} + +void BbdouInventory::putBackInventoryItem(uint32 objectId, Common::Point cursorPosition) { +	InventoryItem *inventoryItem = getInventoryItem(objectId); +	bool flag = inventoryItem->_flag; +	inventoryItem->_flag = false; +	if (!flag && !inventoryItem->_assigned) +		return; +	for (uint i = 0; i < _inventoryBags.size(); ++i) { +		if (_inventoryBags[i]->_sceneId == _activeInventorySceneId) { +			InventorySlot *inventorySlot = _inventoryBags[i]->findClosestSlot(cursorPosition, _index); +			_inventoryBags[i]->addInventoryItem(inventoryItem, inventorySlot); +		} else { +			debug("putBackInventoryItem OTHER STUFF TODO"); +		} +	} +	refresh(); +} +  } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_inventory.h b/engines/illusions/bbdou/bbdou_inventory.h index a983212114..3c211e5340 100644 --- a/engines/illusions/bbdou/bbdou_inventory.h +++ b/engines/illusions/bbdou/bbdou_inventory.h @@ -32,6 +32,7 @@ namespace Illusions {  class IllusionsEngine;  class BbdouSpecialCode;  class Control; +class TriggerFunction;  struct InventoryItem {  	uint32 _objectId; @@ -57,6 +58,8 @@ public:  	bool addInventoryItem(InventoryItem *inventoryItem, InventorySlot *inventorySlot);  	void removeInventoryItem(InventoryItem *inventoryItem);  	void buildItems(); +	InventorySlot *getInventorySlot(uint32 objectId); +	InventorySlot *findClosestSlot(Common::Point putPos, int index);  protected:  public:  	typedef Common::Array<InventorySlot*> InventorySlots; @@ -82,6 +85,9 @@ public:  	InventoryItem *getInventoryItem(uint32 objectId);  	void refresh();  	void buildItems(InventoryBag *inventoryBag); +	void cause0x1B0001(TriggerFunction *triggerFunction, uint32 callingThreadId); +	void cause0x1B0002(TriggerFunction *triggerFunction, uint32 callingThreadId); +	void putBackInventoryItem(uint32 objectId, Common::Point cursorPosition);  protected:  	typedef Common::Array<InventoryItem*> InventoryItems;  	typedef InventoryItems::iterator InventoryItemsIterator; diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp index c74676d168..1547aabf1b 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.cpp +++ b/engines/illusions/bbdou/bbdou_specialcode.cpp @@ -92,6 +92,8 @@ void BbdouSpecialCode::init() {  	SPECIAL(0x00160008, spcEnableCursor);  	SPECIAL(0x00160009, spcDisableCursor);  	SPECIAL(0x0016000A, spcAddCursorSequence); +	SPECIAL(0x0016000B, spcCursorStartHoldingObjectId); +	SPECIAL(0x0016000C, spcCursorStopHoldingObjectId);  	SPECIAL(0x00160013, spcInitBubble);  	SPECIAL(0x00160014, spcSetupBubble);  	SPECIAL(0x00160015, spcSetObjectInteractMode); @@ -100,6 +102,7 @@ void BbdouSpecialCode::init() {  	SPECIAL(0x0016001B, spcRegisterInventoryItem);  	SPECIAL(0x0016001C, spcOpenInventory);  	SPECIAL(0x0016001D, spcAddInventoryItem); +	SPECIAL(0x0016001E, spcRemoveInventoryItem);  	SPECIAL(0x00160025, spcCloseInventory);  } @@ -148,6 +151,22 @@ void BbdouSpecialCode::spcAddCursorSequence(OpCall &opCall) {  	_vm->notifyThreadId(opCall._callerThreadId);  } +void BbdouSpecialCode::spcCursorStartHoldingObjectId(OpCall &opCall) { +	ARG_UINT32(objectId); +	ARG_UINT32(holdingObjectId); +	ARG_INT16(doPlaySound); +	startHoldingObjectId(objectId, holdingObjectId, doPlaySound != 0); +	_vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcCursorStopHoldingObjectId(OpCall &opCall) { +	ARG_UINT32(objectId); +	ARG_INT16(doPlaySound); +	stopHoldingObjectId(objectId, doPlaySound != 0); +	_cursor->_data._mode = 1; +	_vm->notifyThreadId(opCall._callerThreadId); +} +  void BbdouSpecialCode::spcInitBubble(OpCall &opCall) {  	_bubble->init();  	_vm->notifyThreadId(opCall._callerThreadId); @@ -194,10 +213,14 @@ void BbdouSpecialCode::spcOpenInventory(OpCall &opCall) {  void BbdouSpecialCode::spcAddInventoryItem(OpCall &opCall) {  	ARG_UINT32(objectId); -debug("### spcAddInventoryItem %08X", objectId);  	_inventory->addInventoryItem(objectId);  } +void BbdouSpecialCode::spcRemoveInventoryItem(OpCall &opCall) { +	ARG_UINT32(objectId); +	_inventory->removeInventoryItem(objectId); +} +  void BbdouSpecialCode::spcCloseInventory(OpCall &opCall) {  	_inventory->close();  } @@ -531,7 +554,7 @@ bool BbdouSpecialCode::getCause(uint32 sceneId, uint32 verbId, uint32 objectId2,  	}  	if (success) { -		debug("getCause() -> %08X %08X %08X", outVerbId, outObjectId2, outObjectId); +		//debug("getCause() -> %08X %08X %08X", outVerbId, outObjectId2, outObjectId);  	}  	return success; @@ -539,7 +562,7 @@ bool BbdouSpecialCode::getCause(uint32 sceneId, uint32 verbId, uint32 objectId2,  bool BbdouSpecialCode::runCause(Control *cursorControl, CursorData &cursorData,  	uint32 verbId, uint32 objectId2, uint32 objectId, int soundIndex) { -	debug("runCause(%08X, %08X, %08X)", verbId, objectId2, objectId); +	//debug("runCause(%08X, %08X, %08X)", verbId, objectId2, objectId);  	uint32 sceneId = _vm->getCurrentScene();  	uint32 outVerbId, outObjectId2, outObjectId;  	bool success = false; @@ -584,4 +607,35 @@ uint32 BbdouSpecialCode::startCauseThread(uint32 cursorObjectId, uint32 sceneId,  	return tempThreadId;  } +void BbdouSpecialCode::startHoldingObjectId(uint32 objectId1, uint32 holdingObjectId, bool doPlaySound) { +	Control *control = _vm->_dict->getObjectControl(objectId1); +	if (_cursor->_data._holdingObjectId) +		_inventory->putBackInventoryItem(_cursor->_data._holdingObjectId, control->_actor->_position); +	_cursor->_data._holdingObjectId = holdingObjectId; +	_cursor->_data._sequenceId = _cursor->findCursorSequenceId(holdingObjectId); +	if (_cursor->_data._visibleCtr > 0) +		_cursor->show(control); +	_cursor->_data._mode = 2; +	_cursor->_data._item10._verbId = 0x1B0003; +	if (!doPlaySound) +		playSoundEffect(5); +	_inventory->removeInventoryItem(holdingObjectId); +} + +void BbdouSpecialCode::stopHoldingObjectId(uint32 objectId1, bool doPlaySound) { +	Control *control = _vm->_dict->getObjectControl(objectId1); +	uint32 holdingObjectId = _cursor->_data._holdingObjectId; +	_cursor->_data._holdingObjectId = 0; +	_cursor->_data._sequenceId = 0x6000F; +	if (!doPlaySound && holdingObjectId) +		playSoundEffect(6); +	if (_cursor->_data._visibleCtr > 0) +		_cursor->show(control); +	_cursor->_data._item10._verbId = 0x1B0001; +	if (_cursor->_data._mode == 3) +		holdingObjectId = _cursor->_data._holdingObjectId2; +	if (holdingObjectId) +		_inventory->putBackInventoryItem(holdingObjectId, control->_actor->_position); +} +  } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h index dcfb5baf63..d018f3859d 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.h +++ b/engines/illusions/bbdou/bbdou_specialcode.h @@ -81,6 +81,8 @@ public:  	void spcEnableCursor(OpCall &opCall);  	void spcDisableCursor(OpCall &opCall);  	void spcAddCursorSequence(OpCall &opCall); +	void spcCursorStartHoldingObjectId(OpCall &opCall); +	void spcCursorStopHoldingObjectId(OpCall &opCall);  	void spcInitBubble(OpCall &opCall);  	void spcSetupBubble(OpCall &opCall);  	void spcSetObjectInteractMode(OpCall &opCall); @@ -89,10 +91,13 @@ public:  	void spcRegisterInventoryItem(OpCall &opCall);  	void spcOpenInventory(OpCall &opCall);  	void spcAddInventoryItem(OpCall &opCall); +	void spcRemoveInventoryItem(OpCall &opCall);  	void spcCloseInventory(OpCall &opCall);  	void playSoundEffect(int soundIndex);  	void resetItem10(uint32 objectId, Item10 *item10); +	void startHoldingObjectId(uint32 objectId1, uint32 holdingObjectId, bool doPlaySound); +	void stopHoldingObjectId(uint32 objectId1, bool doPlaySound);  protected:  	// Internal functions diff --git a/engines/illusions/dictionary.h b/engines/illusions/dictionary.h index 6bdc539725..11b05a6348 100644 --- a/engines/illusions/dictionary.h +++ b/engines/illusions/dictionary.h @@ -34,25 +34,49 @@ class TalkEntry;  template<class T>  class DictionaryHashMap { +protected: +	typedef Common::List<T*> List; +	typedef typename List::iterator ListIterator; +	typedef Common::HashMap<uint32, List*> Map; +	typedef typename Map::iterator MapIterator; +	Map _map;  public: +	~DictionaryHashMap() { +		for (MapIterator it = _map.begin(); it != _map.end(); ++it) +			delete it->_value; +	} +  	void add(uint32 id, T *value) { -		_map[id] = value; +		MapIterator it = _map.find(id); +		List *list; +		if (it != _map.end()) +			list = it->_value; +		else { +			 list = new List(); +			 _map[id] = list; +		} +		list->push_back(value);  	}  	void remove(uint32 id) { -		_map.erase(id); +		MapIterator it = _map.find(id); +		List *list; +		if (it != _map.end()) { +			list = it->_value; +			list->pop_back(); +			if (list->empty()) +				_map.erase(id); +		}  	}  	T *find(uint32 id) { -		typename Common::HashMap<uint32, T*>::iterator it = _map.find(id); +		MapIterator it = _map.find(id);  		if (it != _map.end()) -			return it->_value; +			return it->_value->back();  		return 0;  	} -protected: -	Common::HashMap<uint32, T*> _map;  };  class Dictionary { diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index 968dc0f583..99b7b19a16 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -107,6 +107,7 @@ Common::Error IllusionsEngine::run() {  	_controls = new Controls(this);  	_cursor = new Cursor(this);  	_talkItems = new TalkItems(this); +	_triggerFunctions = new TriggerFunctions();  	// TODO Move to own class  	_resGetCtr = 0; @@ -117,7 +118,9 @@ Common::Error IllusionsEngine::run() {  	// Actor/graphics/script test  	/* TODO 0x0010000B LinkIndex 0x00060AAB 0x00060556 -	*/	 +	*/ +	 +	_scriptMan->_globalSceneId = 0x00010003;	  	_resSys->loadResource(0x000D0001, 0, 0); @@ -136,6 +139,7 @@ Common::Error IllusionsEngine::run() {  	}  #endif +	delete _triggerFunctions;  	delete _talkItems;  	delete _cursor;  	delete _controls; @@ -276,7 +280,7 @@ int IllusionsEngine::updateGraphics() {  				uint32 priority = control->getPriority();  				_screen->_drawQueue->insertSprite(&actor->_drawFlags, actor->_surface,  					actor->_surfInfo._dimensions, drawPosition, control->_position, -					priority, actor->_scale, actor->_spriteFlags); +					priority, 100/*actor->_scale TODO DEBUG*/, actor->_spriteFlags);  			}  		}  	} @@ -298,19 +302,26 @@ int IllusionsEngine::getRandom(int max) {  bool IllusionsEngine::causeIsDeclared(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId) {  	uint32 codeOffs; -	// TODO Also search for native trigger functions later (findCauseFunc) -	bool r = _scriptMan->findTriggerCause(sceneId, verbId, objectId2, objectId, codeOffs); +	bool r = +		_triggerFunctions->find(sceneId, verbId, objectId2, objectId) || +		_scriptMan->findTriggerCause(sceneId, verbId, objectId2, objectId, codeOffs);  	debug(3, "causeIsDeclared() sceneId: %08X; verbId: %08X; objectId2: %08X; objectId: %08X -> %d",  		sceneId, verbId, objectId2, objectId, r);  	return r;  } +void IllusionsEngine::causeDeclare(uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback) { +	_triggerFunctions->add(getCurrentScene(), verbId, objectId2, objectId, callback); +} +  uint32 IllusionsEngine::causeTrigger(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, uint32 callingThreadId) {  	uint32 codeOffs;  	uint32 causeThreadId = 0; -	// TODO Also search for native trigger functions later and run it (findCauseFunc) -	if (_scriptMan->findTriggerCause(sceneId, verbId, objectId2, objectId, codeOffs)) { -		debug("Run cause at %08X", codeOffs); +	TriggerFunction *triggerFunction = _triggerFunctions->find(sceneId, verbId, objectId2, objectId); +	if (triggerFunction) { +		triggerFunction->run(callingThreadId); +	} else if (_scriptMan->findTriggerCause(sceneId, verbId, objectId2, objectId, codeOffs)) { +		//debug("Run cause at %08X", codeOffs);  		causeThreadId = _scriptMan->startTempScriptThread(_scriptMan->_scriptResource->getCode(codeOffs),  			callingThreadId, verbId, objectId2, objectId);  	} @@ -329,7 +340,7 @@ Common::Point IllusionsEngine::getNamedPointPosition(uint32 namedPointId) {  		_controls->findNamedPoint(namedPointId, pt))      	return pt;  	// TODO -	debug("getNamedPointPosition(%08X) UNKNOWN", namedPointId); +	//debug("getNamedPointPosition(%08X) UNKNOWN", namedPointId);  	return Common::Point(0, 0);  } diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h index 58dc519285..cf3549e8bb 100644 --- a/engines/illusions/illusions.h +++ b/engines/illusions/illusions.h @@ -59,6 +59,7 @@ class Control;  class Controls;  class Cursor;  class Dictionary; +class FramesList;  class Input;  class Screen;  class ScriptResource; @@ -66,7 +67,10 @@ class ScriptMan;  class Sequence;  class SpecialCode;  class TalkItems; -class FramesList; +class TriggerFunctions; +class TriggerFunction; + +typedef Common::Functor2<TriggerFunction*, uint32, void> TriggerFunctionCallback;  class IllusionsEngine : public Engine {  protected: @@ -97,6 +101,7 @@ public:  	Cursor *_cursor;  	TalkItems *_talkItems;  	SpecialCode *_specialCode; +	TriggerFunctions *_triggerFunctions;  	int _resGetCtr;  	uint32 _resGetTime; @@ -115,6 +120,7 @@ public:  	// TODO Move to ScriptMan?  	bool causeIsDeclared(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId); +	void causeDeclare(uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback);  	uint32 causeTrigger(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, uint32 callingThreadId);  	int convertPanXCoord(int16 x); diff --git a/engines/illusions/scriptman.cpp b/engines/illusions/scriptman.cpp index 961ffd4579..20749438d1 100644 --- a/engines/illusions/scriptman.cpp +++ b/engines/illusions/scriptman.cpp @@ -61,15 +61,15 @@ void ActiveScenes::unpauseActiveScene() {  	--_stack.top()._pauseCtr;  } -int ActiveScenes::getActiveScenesCount() { +uint ActiveScenes::getActiveScenesCount() {  	return _stack.size();  }  void ActiveScenes::getActiveSceneInfo(uint index, uint32 *sceneId, int *pauseCtr) {  	if (sceneId) -		*sceneId = _stack[index]._sceneId; +		*sceneId = _stack[index - 1]._sceneId;  	if (pauseCtr) -		*pauseCtr = _stack[index]._pauseCtr; +		*pauseCtr = _stack[index - 1]._pauseCtr;  }  uint32 ActiveScenes::getCurrentScene() { @@ -85,6 +85,60 @@ bool ActiveScenes::isSceneActive(uint32 sceneId) {  	return false;  } +// TriggerFunction + +TriggerFunction::TriggerFunction(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback) +	: _sceneId(sceneId), _verbId(verbId), _objectId2(objectId2), _objectId(objectId), _callback(callback) { +} + +TriggerFunction::~TriggerFunction() { +	delete _callback; +} + +void TriggerFunction::run(uint32 callingThreadId) { +	(*_callback)(this, callingThreadId); +} + +// TriggerFunctions + +void TriggerFunctions::add(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback) { +	ItemsIterator it = findInternal(sceneId, verbId, objectId2, objectId); +	if (it != _triggerFunctions.end()) { +		delete *it; +		_triggerFunctions.erase(it); +	} +	_triggerFunctions.push_back(new TriggerFunction(sceneId, verbId, objectId2, objectId, callback)); +} + +TriggerFunction *TriggerFunctions::find(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId) { +	ItemsIterator it = findInternal(sceneId, verbId, objectId2, objectId); +	if (it != _triggerFunctions.end()) +		return (*it); +	return 0; +} + +void TriggerFunctions::removeBySceneId(uint32 sceneId) { +	ItemsIterator it = _triggerFunctions.begin(); +	while (it != _triggerFunctions.end()) { +		if ((*it)->_sceneId == sceneId) { +			delete *it; +			it = _triggerFunctions.erase(it); +		} else +			++it; +	} +} + +TriggerFunctions::ItemsIterator TriggerFunctions::findInternal(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId) { +	ItemsIterator it = _triggerFunctions.begin(); +	for (; it != _triggerFunctions.end(); ++it) { +		TriggerFunction *triggerFunction = *it; +		if (triggerFunction->_sceneId == sceneId && triggerFunction->_verbId == verbId && +			triggerFunction->_objectId2 == objectId2 && triggerFunction->_objectId == objectId) +			break; +	} +	return it;		 +} +  // ScriptStack  ScriptStack::ScriptStack() { @@ -240,7 +294,7 @@ void ScriptMan::reset() {  bool ScriptMan::enterScene(uint32 sceneId, uint32 threadId) {  	ProgInfo *progInfo = _scriptResource->getProgInfo(sceneId & 0xFFFF);  	if (!progInfo) { -		// TODO dumpActiveScenes(_someSceneId2, threadId); +		// TODO dumpActiveScenes(_globalSceneId, threadId);  		sceneId = _theSceneId;  	}  	_activeScenes.push(sceneId); @@ -253,7 +307,7 @@ void ScriptMan::exitScene(uint32 threadId) {  	// TODO UpdateFunctions_disableByTag__TODO_maybe(sceneId);  	_threads->terminateThreadsByTag(sceneId, threadId);  	_vm->_controls->destroyControlsByTag(sceneId); -	// TODO causeFunc_removeBySceneId(sceneId); +	_vm->_triggerFunctions->removeBySceneId(sceneId);  	_vm->_resSys->unloadResourcesByTag(sceneId);  	_activeScenes.pop();  } @@ -278,6 +332,19 @@ void ScriptMan::leavePause(uint32 threadId) {  	_activeScenes.unpauseActiveScene();  } +void ScriptMan::dumpActiveScenes(uint32 sceneId, uint32 threadId) { +	uint activeScenesCount = _activeScenes.getActiveScenesCount(); +	while (activeScenesCount > 0) { +		uint32 activeSceneId; +		_activeScenes.getActiveSceneInfo(activeScenesCount, &activeSceneId, 0); +		if (activeSceneId == sceneId) +			break; +		exitScene(threadId); +		--activeScenesCount; +	} +	_vm->_camera->clearCameraModeStack(); +} +  void ScriptMan::newScriptThread(uint32 threadId, uint32 callingThreadId, uint notifyFlags,  	byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10) {  	ScriptThread *scriptThread = new ScriptThread(_vm, threadId, callingThreadId, notifyFlags, diff --git a/engines/illusions/scriptman.h b/engines/illusions/scriptman.h index adfc365327..6ea28c8272 100644 --- a/engines/illusions/scriptman.h +++ b/engines/illusions/scriptman.h @@ -23,6 +23,7 @@  #ifndef ILLUSIONS_SCRIPTMAN_H  #define ILLUSIONS_SCRIPTMAN_H +#include "illusions/illusions.h"  #include "illusions/scriptresource.h"  #include "illusions/thread.h"  #include "common/algorithm.h" @@ -46,7 +47,7 @@ public:  	void pop();  	void pauseActiveScene();  	void unpauseActiveScene(); -	int getActiveScenesCount(); +	uint getActiveScenesCount();  	void getActiveSceneInfo(uint index, uint32 *sceneId, int *pauseCtr);  	uint32 getCurrentScene();  	bool isSceneActive(uint32 sceneId); @@ -54,6 +55,31 @@ protected:  	Common::FixedStack<ActiveScene, 16> _stack;  }; +struct TriggerFunction; + +struct TriggerFunction { +	uint32 _sceneId; +	uint32 _verbId; +	uint32 _objectId2; +	uint32 _objectId; +	TriggerFunctionCallback *_callback; +	TriggerFunction(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback); +	~TriggerFunction(); +	void run(uint32 callingThreadId); +}; + +class TriggerFunctions { +public: +	void add(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback); +	TriggerFunction *find(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId); +	void removeBySceneId(uint32 sceneId); +public: +	typedef Common::List<TriggerFunction*> Items; +	typedef Items::iterator ItemsIterator; +	Items _triggerFunctions; +	ItemsIterator findInternal(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId); +}; +  class ScriptStack {  public:  	ScriptStack(); @@ -92,6 +118,7 @@ public:  	void exitScene(uint32 threadId);  	void enterPause(uint32 threadId);  	void leavePause(uint32 threadId); +	void dumpActiveScenes(uint32 sceneId, uint32 threadId);  public:  	IllusionsEngine *_vm; @@ -104,6 +131,7 @@ public:  	uint32 _theSceneId;  	uint32 _theThreadId; +	uint32 _globalSceneId;  	bool _doScriptThreadInit;  	uint32 _nextTempThreadId; diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index fbb9448437..77a7d1f523 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -102,7 +102,9 @@ void ScriptOpcodes::initOpcodes() {  	OPCODE(30, opEnterCloseUpScene);  	OPCODE(31, opExitCloseUpScene);  	OPCODE(32, opPanCenterObject); +	OPCODE(34, opPanToObject);  	OPCODE(35, opPanToNamedPoint); +	OPCODE(36, opPanToPoint);  	OPCODE(37, opPanStop);  	OPCODE(39, opSetDisplay);  	OPCODE(42, opIncBlockCounter); @@ -137,6 +139,9 @@ void ScriptOpcodes::initOpcodes() {  	OPCODE(87, opDeactivateButton);  	OPCODE(88, opActivateButton);  	OPCODE(103, opJumpIf); +	OPCODE(104, opIsPrevSceneId); +	OPCODE(105, opIsCurrentSceneId); +	OPCODE(106, opIsActiveSceneId);  	OPCODE(107, opNot);  	OPCODE(108, opAnd);  	OPCODE(109, opOr); @@ -156,6 +161,7 @@ void ScriptOpcodes::initOpcodes() {  	OPCODE(176, opStackPush0);  	OPCODE(177, opSetFontId);  	OPCODE(178, opAddMenuKey); +	OPCODE(179, opChangeSceneAll);  }  #undef OPCODE @@ -248,17 +254,30 @@ void ScriptOpcodes::opEnterScene(ScriptThread *scriptThread, OpCall &opCall) {  	uint scenesCount = _vm->_scriptMan->_activeScenes.getActiveScenesCount();  	if (scenesCount > 0) {  		uint32 currSceneId; -		_vm->_scriptMan->_activeScenes.getActiveSceneInfo(scenesCount - 1, &currSceneId, 0); +		_vm->_scriptMan->_activeScenes.getActiveSceneInfo(scenesCount, &currSceneId, 0);  		// TODO krnfileDump(currSceneId);  	}  	if (!_vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId))  		opCall._result = kTSTerminate;  } +//DEBUG Scenes +uint32 dsceneId = 0x00010031, dthreadId = 0x00020036;//MAP +//uint32 dsceneId = 0x00010028, dthreadId = 0x000202A1; +//uint32 dsceneId = 0x00010007, dthreadId = 0x0002000C;//Auditorium +//uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010; +  void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(sceneId);  	ARG_UINT32(threadId); +	 +	if (dsceneId) { +		sceneId = dsceneId; +		threadId = dthreadId; +		dsceneId = 0; +	} +	  	// NOTE Skipped checking for stalled resources  	_vm->_input->discardButtons(0xFFFF);  	_vm->_scriptMan->_prevSceneId = _vm->getCurrentScene(); @@ -312,6 +331,14 @@ void ScriptOpcodes::opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall  	_vm->_camera->panCenterObject(objectId, speed);  } +void ScriptOpcodes::opPanToObject(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(speed);	 +	ARG_UINT32(objectId); +	Control *control = _vm->_dict->getObjectControl(objectId); +	Common::Point pos = control->getActorPosition(); +	_vm->_camera->panToPoint(pos, speed, opCall._callerThreadId); +} +  void ScriptOpcodes::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_INT16(speed);	  	ARG_UINT32(namedPointId); @@ -319,6 +346,13 @@ void ScriptOpcodes::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall  	_vm->_camera->panToPoint(pos, speed, opCall._callerThreadId);  } +void ScriptOpcodes::opPanToPoint(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(speed);	 +	ARG_INT16(x);	 +	ARG_INT16(y);	 +	_vm->_camera->panToPoint(Common::Point(x, y), speed, opCall._callerThreadId); +} +  void ScriptOpcodes::opPanStop(ScriptThread *scriptThread, OpCall &opCall) {  	_vm->_camera->stopPan();  } @@ -586,6 +620,21 @@ void ScriptOpcodes::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) {  		opCall._deltaOfs += jumpOffs;  } +void ScriptOpcodes::opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_UINT32(sceneId); +	_vm->_scriptMan->_stack.push(_vm->_scriptMan->_prevSceneId == sceneId ? 1 : 0); +} + +void ScriptOpcodes::opIsCurrentSceneId(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_UINT32(sceneId); +	_vm->_scriptMan->_stack.push(_vm->getCurrentScene() == sceneId ? 1 : 0); +} + +void ScriptOpcodes::opIsActiveSceneId(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_UINT32(sceneId); +	_vm->_scriptMan->_stack.push(_vm->_scriptMan->_activeScenes.isSceneActive(sceneId) ? 1 : 0); +} +  void ScriptOpcodes::opNot(ScriptThread *scriptThread, OpCall &opCall) {  	int16 value = _vm->_scriptMan->_stack.pop();  	_vm->_scriptMan->_stack.push(value != 0 ? 0 : 1); @@ -731,4 +780,18 @@ void ScriptOpcodes::opAddMenuKey(ScriptThread *scriptThread, OpCall &opCall) {  	// TODO _vm->addMenuKey(key, threadId);  } +void ScriptOpcodes::opChangeSceneAll(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->_prevSceneId = _vm->getCurrentScene(); +	_vm->_scriptMan->dumpActiveScenes(_vm->_scriptMan->_globalSceneId, opCall._callerThreadId); +	_vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId); +	// TODO _vm->_gameStates->writeStates(_vm->_scriptMan->_prevSceneId, sceneId, threadId); +	_vm->_scriptMan->startAnonScriptThread(threadId, 0, +		scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10); +} +  } // End of namespace Illusions diff --git a/engines/illusions/scriptopcodes.h b/engines/illusions/scriptopcodes.h index 507d21b5e8..32f23fdff6 100644 --- a/engines/illusions/scriptopcodes.h +++ b/engines/illusions/scriptopcodes.h @@ -77,7 +77,9 @@ protected:  	void opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);  	void opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);  	void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall); +	void opPanToObject(ScriptThread *scriptThread, OpCall &opCall);  	void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall); +	void opPanToPoint(ScriptThread *scriptThread, OpCall &opCall);  	void opPanStop(ScriptThread *scriptThread, OpCall &opCall);  	void opSetDisplay(ScriptThread *scriptThread, OpCall &opCall);	  	void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall); @@ -112,6 +114,9 @@ protected:  	void opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall);  	void opActivateButton(ScriptThread *scriptThread, OpCall &opCall);  	void opJumpIf(ScriptThread *scriptThread, OpCall &opCall); +	void opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall); +	void opIsCurrentSceneId(ScriptThread *scriptThread, OpCall &opCall); +	void opIsActiveSceneId(ScriptThread *scriptThread, OpCall &opCall);  	void opNot(ScriptThread *scriptThread, OpCall &opCall);  	void opAnd(ScriptThread *scriptThread, OpCall &opCall);  	void opOr(ScriptThread *scriptThread, OpCall &opCall); @@ -131,6 +136,7 @@ protected:  	void opStackPush0(ScriptThread *scriptThread, OpCall &opCall);  	void opSetFontId(ScriptThread *scriptThread, OpCall &opCall);  	void opAddMenuKey(ScriptThread *scriptThread, OpCall &opCall); +	void opChangeSceneAll(ScriptThread *scriptThread, OpCall &opCall);  }; diff --git a/engines/illusions/sequenceopcodes.cpp b/engines/illusions/sequenceopcodes.cpp index 7df968df3d..23d1781902 100644 --- a/engines/illusions/sequenceopcodes.cpp +++ b/engines/illusions/sequenceopcodes.cpp @@ -70,9 +70,12 @@ void SequenceOpcodes::initOpcodes() {  	OPCODE(15, opSwitchFacing);  	OPCODE(16, opAppearActor);  	OPCODE(17, opDisappearActor); +	OPCODE(18, opAppearForeignActor); +	OPCODE(19, opDisappearForeignActor);  	OPCODE(28, opNotifyThreadId1);  	OPCODE(29, opSetPathCtrY);  	OPCODE(33, opSetPathWalkPoints); +	OPCODE(35, opSetScale);  	OPCODE(36, opSetScaleLayer);  	OPCODE(38, opSetPathWalkRects);  	OPCODE(39, opSetPriority); @@ -80,6 +83,8 @@ void SequenceOpcodes::initOpcodes() {  	OPCODE(50, opPlaySound);  	OPCODE(51, opStopSound);  	OPCODE(53, opPlaceSubActor); +	OPCODE(54, opStartSubSequence); +	OPCODE(55, opStopSubSequence);  }  #undef OPCODE @@ -219,6 +224,23 @@ void SequenceOpcodes::opDisappearActor(Control *control, OpCall &opCall) {  	control->_actor->_newFrameIndex = 0;  } +void SequenceOpcodes::opAppearForeignActor(Control *control, OpCall &opCall) { +	ARG_INT16(foreignObjectNum); +	Control *foreignControl = _vm->_dict->getObjectControl(foreignObjectNum | 0x40000); +	if (!foreignControl) { +		Common::Point pos = _vm->getNamedPointPosition(0x00070023); +		_vm->_controls->placeActor(0x00050001, pos, 0x00060001, foreignObjectNum | 0x40000, 0); +		foreignControl = _vm->_dict->getObjectControl(foreignObjectNum | 0x40000); +	} +	foreignControl->appearActor(); +} + +void SequenceOpcodes::opDisappearForeignActor(Control *control, OpCall &opCall) { +	ARG_INT16(foreignObjectNum); +	Control *foreignControl = _vm->_dict->getObjectControl(foreignObjectNum | 0x40000); +	foreignControl->disappearActor(); +} +  void SequenceOpcodes::opNotifyThreadId1(Control *control, OpCall &opCall) {  	_vm->notifyThreadId(control->_actor->_notifyThreadId1);  } @@ -235,6 +257,12 @@ void SequenceOpcodes::opSetPathWalkPoints(Control *control, OpCall &opCall) {  	// TODO control->_actor->_pathWalkPoints = bgRes->getPathWalkPoints(pathWalkPointsIndex - 1);  } +void SequenceOpcodes::opSetScale(Control *control, OpCall &opCall) { +	ARG_INT16(scale); +	control->_actor->_flags &= ~4; +	control->setActorScale(scale); +} +  void SequenceOpcodes::opSetScaleLayer(Control *control, OpCall &opCall) {  	ARG_INT16(scaleLayerIndex);  	BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource(); @@ -290,4 +318,15 @@ void SequenceOpcodes::opPlaceSubActor(Control *control, OpCall &opCall) {   	_vm->_controls->placeSubActor(control->_objectId, linkIndex, actorTypeId, sequenceId);  } +void SequenceOpcodes::opStartSubSequence(Control *control, OpCall &opCall) { + 	ARG_INT16(linkIndex); + 	ARG_UINT32(sequenceId); +	control->startSubSequence(linkIndex, sequenceId); +} + +void SequenceOpcodes::opStopSubSequence(Control *control, OpCall &opCall) { + 	ARG_INT16(linkIndex); +	control->stopSubSequence(linkIndex); +} +  } // End of namespace Illusions diff --git a/engines/illusions/sequenceopcodes.h b/engines/illusions/sequenceopcodes.h index abf1987d89..028d567879 100644 --- a/engines/illusions/sequenceopcodes.h +++ b/engines/illusions/sequenceopcodes.h @@ -60,16 +60,21 @@ protected:  	void opSwitchFacing(Control *control, OpCall &opCall);  	void opAppearActor(Control *control, OpCall &opCall);  	void opDisappearActor(Control *control, OpCall &opCall); +	void opAppearForeignActor(Control *control, OpCall &opCall); +	void opDisappearForeignActor(Control *control, OpCall &opCall);  	void opNotifyThreadId1(Control *control, OpCall &opCall);  	void opSetPathCtrY(Control *control, OpCall &opCall);  	void opSetPathWalkPoints(Control *control, OpCall &opCall); +	void opSetScale(Control *control, OpCall &opCall);  	void opSetScaleLayer(Control *control, OpCall &opCall);  	void opSetPathWalkRects(Control *control, OpCall &opCall);  	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 opPlaceSubActor(Control *control, OpCall &opCall);	 +	void opPlaceSubActor(Control *control, OpCall &opCall); +	void opStartSubSequence(Control *control, OpCall &opCall); +	void opStopSubSequence(Control *control, OpCall &opCall);	  }; diff --git a/engines/illusions/talkresource.cpp b/engines/illusions/talkresource.cpp index 1d17408fa8..0c1108ea27 100644 --- a/engines/illusions/talkresource.cpp +++ b/engines/illusions/talkresource.cpp @@ -78,7 +78,7 @@ void TalkEntry::load(byte *dataStart, Common::SeekableReadStream &stream) {  	_tblPtr = dataStart + tblOffs;  	_voiceName = dataStart + voiceNameOffs; -	debug("TalkEntry::load() _talkId: %08X; textOffs: %08X; tblOffs: %08X; voiceNameOffs: %08X", +	debug(0, "TalkEntry::load() _talkId: %08X; textOffs: %08X; tblOffs: %08X; voiceNameOffs: %08X",  		_talkId, textOffs, tblOffs, voiceNameOffs);  }  | 
