diff options
| author | johndoe123 | 2014-04-15 13:21:00 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 | 
| commit | 1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6 (patch) | |
| tree | d8a58e89f20839b2853551bf41b28a9623a0e2af | |
| parent | b1927ca30458226ad7ed52cc85d37416261d444d (diff) | |
| download | scummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.tar.gz scummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.tar.bz2 scummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.zip | |
ILLUSIONS: More work on Duckman
- Implement palette fader
- Add more inventory functions
- Add more script opcodes
| -rw-r--r-- | engines/illusions/illusions.cpp | 26 | ||||
| -rw-r--r-- | engines/illusions/illusions.h | 7 | ||||
| -rw-r--r-- | engines/illusions/illusions_bbdou.cpp | 4 | ||||
| -rw-r--r-- | engines/illusions/illusions_duckman.cpp | 76 | ||||
| -rw-r--r-- | engines/illusions/illusions_duckman.h | 9 | ||||
| -rw-r--r-- | engines/illusions/screen.cpp | 46 | ||||
| -rw-r--r-- | engines/illusions/screen.h | 20 | ||||
| -rw-r--r-- | engines/illusions/scriptopcodes_duckman.cpp | 31 | ||||
| -rw-r--r-- | engines/illusions/scriptopcodes_duckman.h | 2 | 
9 files changed, 197 insertions, 24 deletions
| diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index 8a350961e2..afaaa00a3a 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -141,6 +141,7 @@ int IllusionsEngine::updateGraphics() {  	uint32 currTime = getCurrentTime();  	_camera->update(currTime); +	updateFader();  	// TODO Move to BackgroundItems class  	BackgroundItem *backgroundItem = _backgroundItems->findActiveBackground(); @@ -177,8 +178,6 @@ int IllusionsEngine::updateGraphics() {  			*/  			if (actor->_surfInfo._dimensions._width && actor->_surfInfo._dimensions._height) {  				uint32 priority = control->getPriority(); -//if (control->_objectId == 0x0004001B) continue; -//debug("objectId: %08X; priority: %d (%d)", control->_objectId, priority, control->_priority);				  				_screen->_drawQueue->insertSprite(&actor->_drawFlags, actor->_surface,  					actor->_surfInfo._dimensions, drawPosition, control->_position,  					priority, actor->_scale, actor->_spriteFlags); @@ -268,6 +267,29 @@ bool IllusionsEngine::isVoicePlaying() {  	return false;  } +void IllusionsEngine::updateFader() { +	if (_fader && !_fader->_paused && _fader->_active) { +		int32 currTime = getCurrentTime(); +		int32 currDuration = currTime - _fader->_startTime; +		if (currDuration) { +			int newValue; +			if (currDuration >= _fader->_duration) { +				newValue = _fader->_maxValue; +			} else { +				newValue = (currDuration * (_fader->_maxValue - _fader->_minValue) / _fader->_duration) + _fader->_minValue; +			} +			if (_fader->_currValue != newValue) { +				_fader->_currValue = newValue; +				_screen->setFader(newValue, _fader->_firstIndex, _fader->_lastIndex); +			} +			if (_fader->_currValue == _fader->_maxValue) { +				_fader->_active = false; +				notifyThreadId(_fader->_notifyThreadId); +			} +		} +	} +} +  void IllusionsEngine::setCurrFontId(uint32 fontId) {  	_fontId = fontId;  } diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h index 63fb3f6d3e..4ef193156d 100644 --- a/engines/illusions/illusions.h +++ b/engines/illusions/illusions.h @@ -61,6 +61,7 @@ class Control;  class Controls;  class Cursor;  class Dictionary; +struct Fader;  class FramesList;  class Input;  class Screen; @@ -111,7 +112,9 @@ public:  	ThreadList *_threads;  	ScriptResource *_scriptResource; -	 + +	Fader *_fader; +  	int _resGetCtr;  	uint32 _resGetTime;  	bool _unpauseControlActorFlag; @@ -146,6 +149,8 @@ public:  	void stopVoice();  	bool isVoicePlaying(); +	void updateFader(); +  	void setCurrFontId(uint32 fontId);  	bool checkActiveTalkThreads();  	uint32 clipTextDuration(uint32 duration); diff --git a/engines/illusions/illusions_bbdou.cpp b/engines/illusions/illusions_bbdou.cpp index 931db5c2ee..3b78e1ab7f 100644 --- a/engines/illusions/illusions_bbdou.cpp +++ b/engines/illusions/illusions_bbdou.cpp @@ -214,6 +214,8 @@ Common::Error IllusionsEngine_BBDOU::run() {  	_triggerFunctions = new TriggerFunctions();  	_threads = new ThreadList(this); +	_fader = 0; +  	_scriptOpcodes = new ScriptOpcodes_BBDOU(this);  	_stack = new ScriptStack(); @@ -229,7 +231,7 @@ Common::Error IllusionsEngine_BBDOU::run() {  	_globalSceneId = 0x00010003;	 -    setDefaultTextCoords(); +	setDefaultTextCoords();  	_resSys->loadResource(0x000D0001, 0, 0); diff --git a/engines/illusions/illusions_duckman.cpp b/engines/illusions/illusions_duckman.cpp index 9f67d6bb93..1c9d30a535 100644 --- a/engines/illusions/illusions_duckman.cpp +++ b/engines/illusions/illusions_duckman.cpp @@ -105,6 +105,8 @@ Common::Error IllusionsEngine_Duckman::run() {  	_talkItems = new TalkItems(this);  	_threads = new ThreadList(this); +	_fader = new Fader(); +  	_scriptOpcodes = new ScriptOpcodes_Duckman(this);  	_stack = new ScriptStack(); @@ -150,6 +152,8 @@ Common::Error IllusionsEngine_Duckman::run() {  	delete _stack;  	delete _scriptOpcodes; +	delete _fader; +  	delete _threads;  	delete _talkItems;  	delete _controls; @@ -177,6 +181,19 @@ bool IllusionsEngine_Duckman::hasFeature(EngineFeature f) const {  		*/  } + +void IllusionsEngine_Duckman::startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId) { +	_fader->_active = true; +	_fader->_currValue = minValue; +	_fader->_minValue = minValue; +	_fader->_maxValue = maxValue; +	_fader->_firstIndex = firstIndex; +	_fader->_lastIndex = lastIndex; +	_fader->_startTime = getCurrentTime(); +	_fader->_duration = duration; +	_fader->_notifyThreadId = threadId; +} +  void IllusionsEngine_Duckman::setDefaultTextCoords() {  	WidthHeight dimensions;  	dimensions._width = 300; @@ -1038,6 +1055,34 @@ void IllusionsEngine_Duckman::addInventoryItem(uint32 objectId) {  	control->appearActor();  } +void IllusionsEngine_Duckman::clearInventorySlot(uint32 objectId) { +	for (uint i = 0; i < _inventorySlots.size(); ++i) +		if (_inventorySlots[i]._objectId == objectId) +			_inventorySlots[i]._objectId = 0; +} + +void IllusionsEngine_Duckman::putBackInventoryItem() { +	Common::Point mousePos = _input->getCursorPosition(); +	if (_cursor._objectId) { +		DMInventorySlot *inventorySlot = findInventorySlot(_cursor._objectId); +		if (inventorySlot) +			inventorySlot->_objectId = 0; +		inventorySlot = findClosestInventorySlot(mousePos); +		inventorySlot->_objectId = _cursor._objectId; +		Control *control = getObjectControl(_cursor._objectId); +		control->setActorPosition(inventorySlot->_position); +		control->appearActor(); +		_cursor._actorIndex = 7; +		stopCursorHoldingObject(); +		_cursor._actorIndex = 2; +		_cursor._control->startSequenceActor(_cursor._sequenceId1, 2, 0); +		if (_cursor._currOverlappedControl) +			setCursorActorIndex(_cursor._actorIndex, 2, 0); +		else +			setCursorActorIndex(_cursor._actorIndex, 1, 0); +	} +} +  DMInventorySlot *IllusionsEngine_Duckman::findInventorySlot(uint32 objectId) {  	for (uint i = 0; i < _inventorySlots.size(); ++i)  		if (_inventorySlots[i]._objectId == objectId) @@ -1052,6 +1097,24 @@ DMInventoryItem *IllusionsEngine_Duckman::findInventoryItem(uint32 objectId) {  	return 0;  } +DMInventorySlot *IllusionsEngine_Duckman::findClosestInventorySlot(Common::Point pos) { +	int minDistance = 0xFFFFFF; +	DMInventorySlot *minInventorySlot = 0; +	for (uint i = 0; i < _inventorySlots.size(); ++i) { +		DMInventorySlot *inventorySlot = &_inventorySlots[i]; +		if (inventorySlot->_objectId == 0) { +			int16 deltaX = ABS(inventorySlot->_position.x - pos.x); +			int16 deltaY = ABS(inventorySlot->_position.y - pos.y); +			int distance = deltaX * deltaX + deltaY * deltaY; +			if (inventorySlot->_objectId == 0 && distance < minDistance) { +				minDistance = distance; +				minInventorySlot = inventorySlot; +			} +		} +	} +	return minInventorySlot; +} +  // Special code  typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeFunctionDM; @@ -1060,6 +1123,8 @@ typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeF  void IllusionsEngine_Duckman::initSpecialCode() {  	SPECIAL(0x00160002, spcSetCursorHandMode);  	SPECIAL(0x00160005, spcOpenInventory); +	SPECIAL(0x00160007, spcPutBackInventoryItem); +	SPECIAL(0x00160008, spcClearInventorySlot);  	SPECIAL(0x00160010, spcCenterNewspaper);  	SPECIAL(0x00160014, spcUpdateObject272Sequence);  	SPECIAL(0x0016001C, spcSetCursorInventoryMode); @@ -1086,6 +1151,17 @@ void IllusionsEngine_Duckman::spcOpenInventory(OpCall &opCall) {  	notifyThreadId(opCall._threadId);  } +void IllusionsEngine_Duckman::spcPutBackInventoryItem(OpCall &opCall) { +	putBackInventoryItem(); +	notifyThreadId(opCall._threadId); +} + +void IllusionsEngine_Duckman::spcClearInventorySlot(OpCall &opCall) { +	ARG_UINT32(objectId); +	clearInventorySlot(objectId); +	notifyThreadId(opCall._threadId); +} +  void IllusionsEngine_Duckman::spcCenterNewspaper(OpCall &opCall) {  	Control *control = getObjectControl(0x40017);  	control->_flags |= 8; diff --git a/engines/illusions/illusions_duckman.h b/engines/illusions/illusions_duckman.h index 3b369b9b75..0502089479 100644 --- a/engines/illusions/illusions_duckman.h +++ b/engines/illusions/illusions_duckman.h @@ -109,6 +109,8 @@ public:  	Common::Array<DMInventoryItem> _inventoyItems;  	SpecialCodeMap _specialCodeMap; +	 +	void startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId);  	void setDefaultTextCoords(); @@ -185,15 +187,20 @@ public:  	void initInventory();  	void openInventory(); +	void addInventoryItem(uint32 objectId); +	void clearInventorySlot(uint32 objectId); +	void putBackInventoryItem();  	DMInventorySlot *findInventorySlot(uint32 objectId);  	DMInventoryItem *findInventoryItem(uint32 objectId); -	void addInventoryItem(uint32 objectId); +	DMInventorySlot *findClosestInventorySlot(Common::Point pos);  	// Special code  	void initSpecialCode();  	void runSpecialCode(uint32 specialCodeId, OpCall &opCall);  	void spcSetCursorHandMode(OpCall &opCall);  	void spcOpenInventory(OpCall &opCall); +	void spcPutBackInventoryItem(OpCall &opCall); +	void spcClearInventorySlot(OpCall &opCall);  	void spcCenterNewspaper(OpCall &opCall);  	void spcSetCursorInventoryMode(OpCall &opCall);  	void spcUpdateObject272Sequence(OpCall &opCall); diff --git a/engines/illusions/screen.cpp b/engines/illusions/screen.cpp index 35e8b59271..2ac1a44eaf 100644 --- a/engines/illusions/screen.cpp +++ b/engines/illusions/screen.cpp @@ -237,6 +237,8 @@ Screen::Screen(IllusionsEngine *vm, int16 width, int16 height, int bpp)  	_needRefreshPalette = false;  	memset(_mainPalette, 0, sizeof(_mainPalette)); +	_isFaderActive = false; +  }  Screen::~Screen() { @@ -372,12 +374,52 @@ void Screen::shiftPalette(int16 fromIndex, int16 toIndex) {  void Screen::updatePalette() {  	if (_needRefreshPalette) { -		// TODO Update fader palette -		setSystemPalette(_mainPalette); +		if (_isFaderActive) { +			updateFaderPalette(); +			setSystemPalette(_faderPalette); +		} else { +			setSystemPalette(_mainPalette); +		}  		_needRefreshPalette = false;  	}  } +void Screen::updateFaderPalette() { +	if (_newFaderValue >= 255) { +		_newFaderValue -= 256; +		for (int i = _firstFaderIndex; i <= _lastFaderIndex; ++i) { +			byte r = _mainPalette[i * 3 + 0]; +			byte g = _mainPalette[i * 3 + 1]; +			byte b = _mainPalette[i * 3 + 2]; +			_faderPalette[i * 3 + 0] = r - (((_newFaderValue * (255 - r)) >> 8) & 0xFF); +			_faderPalette[i * 3 + 1] = g - (((_newFaderValue * (255 - g)) >> 8) & 0xFF); +			_faderPalette[i * 3 + 2] = b - (((_newFaderValue * (255 - b)) >> 8) & 0xFF); +		} +	} else { +		for (int i = _firstFaderIndex; i <= _lastFaderIndex; ++i) { +			byte r = _mainPalette[i * 3 + 0]; +			byte g = _mainPalette[i * 3 + 1]; +			byte b = _mainPalette[i * 3 + 2]; +			_faderPalette[i * 3 + 0] = _newFaderValue * r / 255; +			_faderPalette[i * 3 + 1] = _newFaderValue * g / 255; +			_faderPalette[i * 3 + 2] = _newFaderValue * b / 255; +		} +	} +} + +void Screen::setFader(int newValue, int firstIndex, int lastIndex) { +	if (newValue == 255) { +		_isFaderActive = false; +		_needRefreshPalette = true; +	} else { +		_isFaderActive = true; +		_needRefreshPalette = true; +		_newFaderValue = newValue; +		_firstFaderIndex = firstIndex - 1; +		_lastFaderIndex = lastIndex; +	} +} +  void Screen::buildColorTransTbl() {  	const int cr = _mainPalette[3 * 1 + 0];  	const int cg = _mainPalette[3 * 1 + 1]; diff --git a/engines/illusions/screen.h b/engines/illusions/screen.h index bdecda48a5..15a703c46c 100644 --- a/engines/illusions/screen.h +++ b/engines/illusions/screen.h @@ -97,6 +97,20 @@ protected:  	bool calcItemRect(SpriteDrawQueueItem *item, Common::Rect &srcRect, Common::Rect &dstRect);  }; +struct Fader { +	bool _active; +	int _currValue; +	bool _paused; +	int _minValue; +	int _maxValue; +	int _firstIndex; +	int _lastIndex; +	uint32 _startTime; +	int _duration; +	uint32 _notifyThreadId; +	Fader() : _active(false), _paused(false) {} +}; +  // TODO Split into two classes (8bit and 16bit)?  class Screen { @@ -116,6 +130,8 @@ public:  	void getPalette(byte *colors);  	void shiftPalette(int16 fromIndex, int16 toIndex);  	void updatePalette(); +	void updateFaderPalette(); +	void setFader(int newValue, int firstIndex, int lastIndex);  	void drawText(FontResource *font, Graphics::Surface *surface, int16 x, int16 y, uint16 *text, uint count);  	int16 drawChar(FontResource *font, Graphics::Surface *surface, int16 x, int16 y, uint16 c);  	int16 getScreenWidth() const { return _backSurface->w; } @@ -133,6 +149,10 @@ public:  	byte _mainPalette[768];  	byte _colorTransTbl[256]; +	bool _isFaderActive; +	byte _faderPalette[768]; +	int _newFaderValue, _firstFaderIndex, _lastFaderIndex; +  	void setSystemPalette(byte *palette);  	void buildColorTransTbl(); diff --git a/engines/illusions/scriptopcodes_duckman.cpp b/engines/illusions/scriptopcodes_duckman.cpp index b932037f00..3b90e0c5e3 100644 --- a/engines/illusions/scriptopcodes_duckman.cpp +++ b/engines/illusions/scriptopcodes_duckman.cpp @@ -74,6 +74,7 @@ void ScriptOpcodes_Duckman::initOpcodes() {  	OPCODE(32, opPanCenterObject);  	OPCODE(33, opPanTrackObject);  	OPCODE(34, opPanToObject); +	OPCODE(35, opPanToNamedPoint);  	OPCODE(36, opPanToPoint);  	OPCODE(37, opPanStop);  	OPCODE(38, opStartFade); @@ -134,7 +135,6 @@ void ScriptOpcodes_Duckman::initOpcodes() {  	OPCODE(20, opEnterScene);  	OPCODE(30, opEnterCloseUpScene);  	OPCODE(31, opExitCloseUpScene); -	OPCODE(35, opPanToNamedPoint);  	OPCODE(53, opSetActorToNamedPoint);  	OPCODE(63, opSetSelectSfx);  	OPCODE(64, opSetMoveSfx); @@ -336,6 +336,13 @@ void ScriptOpcodes_Duckman::opPanToObject(ScriptThread *scriptThread, OpCall &op  	_vm->_camera->panToPoint(pos, speed, opCall._threadId);  } +void ScriptOpcodes_Duckman::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { +	ARG_INT16(speed); +	ARG_UINT32(namedPointId); +	Common::Point pos = _vm->getNamedPointPosition(namedPointId); +	_vm->_camera->panToPoint(pos, speed, opCall._threadId); +} +  void ScriptOpcodes_Duckman::opPanToPoint(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_INT16(speed);  	ARG_INT16(x); @@ -348,15 +355,14 @@ void ScriptOpcodes_Duckman::opPanStop(ScriptThread *scriptThread, OpCall &opCall  }  void ScriptOpcodes_Duckman::opStartFade(ScriptThread *scriptThread, OpCall &opCall) { -	ARG_INT16(arg1); -	ARG_INT16(arg2); -	ARG_INT16(arg3); -	ARG_INT16(arg4); -	ARG_INT16(arg5); -	// TODO - +	ARG_INT16(duration); +	ARG_INT16(minValue); +	ARG_INT16(maxValue); +	ARG_INT16(firstIndex); +	ARG_INT16(lastIndex); +	_vm->startFader(duration, minValue, maxValue, firstIndex, lastIndex, opCall._threadId);  	//DEBUG Resume calling thread, later done when the fading is finished -	_vm->notifyThreadId(opCall._threadId); +	//_vm->notifyThreadId(opCall._threadId);  }  void ScriptOpcodes_Duckman::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) { @@ -794,13 +800,6 @@ void ScriptOpcodes_Duckman::opExitCloseUpScene(ScriptThread *scriptThread, OpCal  	opCall._result = kTSYield;  } -void ScriptOpcodes_Duckman::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { -	ARG_INT16(speed);	 -	ARG_UINT32(namedPointId); -	Common::Point pos = _vm->getNamedPointPosition(namedPointId); -	_vm->_camera->panToPoint(pos, speed, opCall._threadId); -} -  void ScriptOpcodes_Duckman::opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2);  	ARG_UINT32(objectId); diff --git a/engines/illusions/scriptopcodes_duckman.h b/engines/illusions/scriptopcodes_duckman.h index 4c66d346d9..77050deb3f 100644 --- a/engines/illusions/scriptopcodes_duckman.h +++ b/engines/illusions/scriptopcodes_duckman.h @@ -61,6 +61,7 @@ protected:  	void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall);  	void opPanTrackObject(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 opStartFade(ScriptThread *scriptThread, OpCall &opCall); @@ -121,7 +122,6 @@ protected:  	void opEnterScene(ScriptThread *scriptThread, OpCall &opCall);  	void opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);  	void opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCall); -	void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);  	void opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);  	void opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall);  	void opSetMoveSfx(ScriptThread *scriptThread, OpCall &opCall); | 
