diff options
| author | johndoe123 | 2014-04-15 19:35:51 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 | 
| commit | 44c566b51e661ef5751b947aed071660cc628547 (patch) | |
| tree | 4267df6ff7e71347826ae5283279e1789147c58d /engines | |
| parent | 60600191a07fe8e7f4945b5dab63b5b374111ed4 (diff) | |
| download | scummvm-rg350-44c566b51e661ef5751b947aed071660cc628547.tar.gz scummvm-rg350-44c566b51e661ef5751b947aed071660cc628547.tar.bz2 scummvm-rg350-44c566b51e661ef5751b947aed071660cc628547.zip  | |
ILLUSIONS: Add screen shaking effect
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/illusions/illusions.h | 6 | ||||
| -rw-r--r-- | engines/illusions/illusions_bbdou.h | 6 | ||||
| -rw-r--r-- | engines/illusions/illusions_duckman.cpp | 81 | ||||
| -rw-r--r-- | engines/illusions/illusions_duckman.h | 34 | ||||
| -rw-r--r-- | engines/illusions/screen.cpp | 46 | ||||
| -rw-r--r-- | engines/illusions/screen.h | 5 | ||||
| -rw-r--r-- | engines/illusions/scriptopcodes_duckman.cpp | 6 | ||||
| -rw-r--r-- | engines/illusions/updatefunctions.cpp | 3 | 
8 files changed, 150 insertions, 37 deletions
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h index ae7b4af7b1..7ea49fd5ca 100644 --- a/engines/illusions/illusions.h +++ b/engines/illusions/illusions.h @@ -68,6 +68,7 @@ class Screen;  class ScreenText;  class ScriptOpcodes;  class ScriptResource; +class ScriptStack;  class Sequence;  class SpecialCode;  class TalkItems; @@ -113,10 +114,15 @@ public:  	SpecialCode *_specialCode;  	ThreadList *_threads; +	uint32 _nextTempThreadId; +	bool _doScriptThreadInit; +	ScriptStack *_stack;  	ScriptResource *_scriptResource;  	Fader *_fader; +	int _pauseCtr; +  	int _resGetCtr;  	uint32 _resGetTime;  	bool _unpauseControlActorFlag; diff --git a/engines/illusions/illusions_bbdou.h b/engines/illusions/illusions_bbdou.h index ea46fb949a..fccfb59bf5 100644 --- a/engines/illusions/illusions_bbdou.h +++ b/engines/illusions/illusions_bbdou.h @@ -98,12 +98,6 @@ public:  	uint32 _theThreadId;  	uint32 _globalSceneId; -	int _pauseCtr; -	ScriptStack *_stack; -	bool _doScriptThreadInit; - -	uint32 _nextTempThreadId; -  	void initUpdateFunctions();  	int updateScript(uint flags); diff --git a/engines/illusions/illusions_duckman.cpp b/engines/illusions/illusions_duckman.cpp index f9d0360792..48db89d26a 100644 --- a/engines/illusions/illusions_duckman.cpp +++ b/engines/illusions/illusions_duckman.cpp @@ -200,6 +200,56 @@ int IllusionsEngine_Duckman::updateScript(uint flags) {  	return 1;  } +void IllusionsEngine_Duckman::startScreenShaker(uint pointsCount, uint32 duration, const ScreenShakerPoint *points, uint32 threadId) { +	_screenShaker = new ScreenShaker(); +	_screenShaker->_pointsIndex = 0; +	_screenShaker->_pointsCount = pointsCount; +	_screenShaker->_finished = false; +	_screenShaker->_duration = duration; +	_screenShaker->_nextTime = duration + getCurrentTime(); +	_screenShaker->_points = points; +	_screenShaker->_notifyThreadId = threadId; +	_updateFunctions->add(71, getCurrentScene(), new Common::Functor1Mem<uint, int, IllusionsEngine_Duckman> +		(this, &IllusionsEngine_Duckman::updateScreenShaker)); +} + +int IllusionsEngine_Duckman::updateScreenShaker(uint flags) { +	if (_pauseCtr > 0 || getCurrentScene() == 0x10038) { +		_screenShaker->_nextTime = getCurrentTime(); +		return 1; +	} + +	if (flags & 1) +		_screenShaker->_finished = true; + +	if (!_screenShaker->_finished) { +		if (getCurrentTime() >= _screenShaker->_nextTime) { +			++_screenShaker->_pointsIndex; +			if (_screenShaker->_pointsIndex <= _screenShaker->_pointsCount) { +				ScreenShakerPoint shakePt = _screenShaker->_points[_screenShaker->_pointsIndex - 1]; +				if (shakePt.x == (int16)0x8000) { +					// Loop +					_screenShaker->_pointsIndex = 1; +					shakePt = _screenShaker->_points[_screenShaker->_pointsIndex - 1]; +				} +				_screenShaker->_nextTime = getCurrentTime() + _screenShaker->_duration; +				_screen->setScreenOffset(Common::Point(shakePt.x, shakePt.y)); +			} else +				_screenShaker->_finished = true; +		} +	} + +    if (_screenShaker->_finished) { +		notifyThreadId(_screenShaker->_notifyThreadId); +		delete _screenShaker; +		_screenShaker = 0; +		_screen->setScreenOffset(Common::Point(0, 0)); +		return 2; +	} + +	return 1; +} +  void IllusionsEngine_Duckman::startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId) {  	_fader->_active = true;  	_fader->_currValue = minValue; @@ -553,13 +603,6 @@ void IllusionsEngine_Duckman::newScriptThread(uint32 threadId, uint32 callingThr  	ScriptThread *scriptThread = new ScriptThread(this, threadId, callingThreadId, notifyFlags,  		scriptCodeIp, 0, 0, 0);  	_threads->startThread(scriptThread); -	if (_pauseCtr > 0) -		scriptThread->pause(); -	if (_doScriptThreadInit) { -		int updateResult = kTSRun; -		while (scriptThread->_pauseCtr <= 0 && updateResult != kTSTerminate && updateResult != kTSYield) -			updateResult = scriptThread->update(); -	}  }  uint32 IllusionsEngine_Duckman::newTimerThread(uint32 duration, uint32 callingThreadId, bool isAbortable) { @@ -980,7 +1023,6 @@ void IllusionsEngine_Duckman::updateDialogState() {  			_controls->destroyDialogItems();  			Control *control = _dict->getObjectControl(0x40148);  			_controls->destroyControl(control); -			debug("_cursor._notifyThreadId30: %08X", _cursor._notifyThreadId30);  			notifyThreadId(_cursor._notifyThreadId30);  			_cursor._notifyThreadId30 = 0;  			_cursor._gameState = 2; @@ -1139,6 +1181,7 @@ typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeF  #define SPECIAL(id, func) _specialCodeMap[id] = new SpecialCodeFunctionDM(this, &IllusionsEngine_Duckman::func);  void IllusionsEngine_Duckman::initSpecialCode() { +	SPECIAL(0x00160001, spcStartScreenShaker);  	SPECIAL(0x00160002, spcSetCursorHandMode);  	SPECIAL(0x00160005, spcOpenInventory);  	SPECIAL(0x00160007, spcPutBackInventoryItem); @@ -1148,6 +1191,8 @@ void IllusionsEngine_Duckman::initSpecialCode() {  	SPECIAL(0x0016001C, spcSetCursorInventoryMode);  } +#undef SPECIAL +  void IllusionsEngine_Duckman::runSpecialCode(uint32 specialCodeId, OpCall &opCall) {  	SpecialCodeMapIterator it = _specialCodeMap.find(specialCodeId);  	if (it != _specialCodeMap.end()) { @@ -1158,6 +1203,26 @@ void IllusionsEngine_Duckman::runSpecialCode(uint32 specialCodeId, OpCall &opCal  	}  } +static const ScreenShakerPoint kShakerPoints0[] = { +	{0, -2}, {0, -4}, {0, -3}, {0, -1}, {0, 1} +}; + +static const ScreenShakeEffect kShakerEffect0 = { +	6, 5, kShakerPoints0 +}; + +static const ScreenShakeEffect *kShakerEffects = { +	&kShakerEffect0 +}; + +void IllusionsEngine_Duckman::spcStartScreenShaker(OpCall &opCall) { +	// TODO Add more effects +	ARG_BYTE(effect); +	debug("### effect: %d", effect); +	const ScreenShakeEffect *shakerEffect = &kShakerEffects[effect]; +	startScreenShaker(shakerEffect->_pointsCount, shakerEffect->_duration, shakerEffect->_points, opCall._threadId); +} +  void IllusionsEngine_Duckman::spcSetCursorHandMode(OpCall &opCall) {  	ARG_BYTE(mode);  	setCursorHandMode(mode); diff --git a/engines/illusions/illusions_duckman.h b/engines/illusions/illusions_duckman.h index ca48bc676b..da3036f348 100644 --- a/engines/illusions/illusions_duckman.h +++ b/engines/illusions/illusions_duckman.h @@ -71,6 +71,26 @@ struct DMInventoryItem {  		: _objectId(objectId), _propertyId(propertyId) {}  }; +struct ScreenShakerPoint { +	int16 x, y; +}; + +struct ScreenShakeEffect { +	uint32 _duration; +	uint _pointsCount; +	const ScreenShakerPoint *_points; +}; + +struct ScreenShaker { +	uint _pointsIndex; +	uint _pointsCount; +	bool _finished; +	uint32 _duration; +	uint32 _nextTime; +	uint32 _notifyThreadId; +	const ScreenShakerPoint *_points; +}; +  struct OpCall;  typedef Common::Functor1<OpCall&, void> SpecialCodeFunction; @@ -91,12 +111,6 @@ public:  	uint32 _theThreadId;  	uint32 _globalSceneId; -	int _pauseCtr; -	ScriptStack *_stack; -	bool _doScriptThreadInit; - -	uint32 _nextTempThreadId; -	  	uint _activeScenesCount;  	uint32 _activeScenes[6]; @@ -108,11 +122,16 @@ public:  	Common::Array<DMInventorySlot> _inventorySlots;  	Common::Array<DMInventoryItem> _inventoyItems; +	ScreenShaker *_screenShaker; +  	SpecialCodeMap _specialCodeMap;  	void initUpdateFunctions();  	int updateScript(uint flags); -	 + +	void startScreenShaker(uint pointsCount, uint32 duration, const ScreenShakerPoint *points, uint32 threadId); +	int updateScreenShaker(uint flags); +  	void startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId);  	void setDefaultTextCoords(); @@ -200,6 +219,7 @@ public:  	// Special code  	void initSpecialCode();  	void runSpecialCode(uint32 specialCodeId, OpCall &opCall); +	void spcStartScreenShaker(OpCall &opCall);  	void spcSetCursorHandMode(OpCall &opCall);  	void spcOpenInventory(OpCall &opCall);  	void spcPutBackInventoryItem(OpCall &opCall); diff --git a/engines/illusions/screen.cpp b/engines/illusions/screen.cpp index 2ac1a44eaf..cd5ca683df 100644 --- a/engines/illusions/screen.cpp +++ b/engines/illusions/screen.cpp @@ -178,15 +178,12 @@ bool SpriteDrawQueue::calcItemRect(SpriteDrawQueueItem *item, Common::Rect &srcR  	dstRect.right = item->_drawPosition.x + item->_scale * (item->_dimensions._width - item->_controlPosition.x) / 100;  	dstRect.bottom = item->_drawPosition.y + item->_scale * (item->_dimensions._height - item->_controlPosition.y) / 100; -	/* CHECKME This seems to be unused basically and only called from debug code -		Left here just in case... -	if (gfx_seemsAlways0) { -		dstRect.left += screenOffsetPt.x; -		dstRect.right = screenOffsetPt.x + dstRect.right; -		dstRect.top = screenOffsetPt.y + dstRect.top; -		dstRect.bottom = screenOffsetPt.y + dstRect.bottom; +	if (_screen->_isScreenOffsetActive) { +		dstRect.left += _screen->_screenOffsetPt.x; +		dstRect.right += _screen->_screenOffsetPt.x; +		dstRect.top += _screen->_screenOffsetPt.y; +		dstRect.bottom += _screen->_screenOffsetPt.y;  	} -	*/  	// Check if the sprite is on-screen  	if (dstRect.left >= _screen->getScreenWidth() || dstRect.right <= 0 || dstRect.top >= _screen->getScreenHeight() || dstRect.bottom <= 0) @@ -238,6 +235,7 @@ Screen::Screen(IllusionsEngine *vm, int16 width, int16 height, int bpp)  	memset(_mainPalette, 0, sizeof(_mainPalette));  	_isFaderActive = false; +	_isScreenOffsetActive = false;  } @@ -267,6 +265,15 @@ void Screen::setDisplayOn(bool isOn) {  	// TODO Clear screen when off  } +void Screen::setScreenOffset(Common::Point offsPt) { +	if (offsPt.x != 0 || offsPt.y != 0) { +		_isScreenOffsetActive = true; +		_screenOffsetPt = offsPt; +	} else { +		_isScreenOffsetActive = false; +	} +} +  uint16 Screen::getColorKey2() {  	return _colorKey2;  } @@ -275,11 +282,33 @@ void Screen::updateSprites() {  	_decompressQueue->decompressAll();  	// NOTE Skipped doShiftBrightness and related as it seems to be unused  	_drawQueue->drawAll(); +	if (_isScreenOffsetActive) +		clearScreenOffsetAreas();  	if (!_displayOn) // TODO Check if a video is playing then don't do it  		_backSurface->fillRect(Common::Rect(_backSurface->w, _backSurface->h), 0);  	g_system->copyRectToScreen((byte*)_backSurface->getBasePtr(0, 0), _backSurface->pitch, 0, 0, _backSurface->w, _backSurface->h);  } +void Screen::clearScreenOffsetAreas() { +	int16 x1 = 0, y1 = 0, x2 = 0, y2 = 0; +	if (_screenOffsetPt.x < 0) { +		x1 = _backSurface->w + _screenOffsetPt.x; +		x2 = _backSurface->w; +	} else if (_screenOffsetPt.x > 0) { +		x1 = 0; +		x2 = _screenOffsetPt.x; +	} +	if (_screenOffsetPt.y < 0) { +		y1 = _backSurface->h + _screenOffsetPt.y; +		y2 = _backSurface->h; +	} else if (_screenOffsetPt.y > 0) { +		y1 = 0; +		y2 = _screenOffsetPt.y; +	} +	_backSurface->fillRect(Common::Rect(0, y1, _backSurface->w, y2), 0); +	_backSurface->fillRect(Common::Rect(x1, 0, x2, _backSurface->h), 0); +} +  void Screen::decompressSprite(SpriteDecompressQueueItem *item) {  	switch (_backSurface->format.bytesPerPixel) {  	case 1: @@ -337,7 +366,6 @@ void Screen::getPalette(byte *colors) {  }  void Screen::shiftPalette(int16 fromIndex, int16 toIndex) { -	//debug("shiftPalette(%d, %d)", fromIndex, toIndex);  	byte r, g, b;  	if (toIndex > fromIndex) {  		r = _mainPalette[3 * toIndex + 0]; diff --git a/engines/illusions/screen.h b/engines/illusions/screen.h index 15a703c46c..1eef207513 100644 --- a/engines/illusions/screen.h +++ b/engines/illusions/screen.h @@ -121,8 +121,10 @@ public:  	Graphics::Surface *allocSurface(SurfInfo &surfInfo);  	bool isDisplayOn();  	void setDisplayOn(bool isOn); +	void setScreenOffset(Common::Point offsPt);  	uint16 getColorKey2();  	void updateSprites(); +	void clearScreenOffsetAreas();  	void decompressSprite(SpriteDecompressQueueItem *item);  	void drawSurface(Common::Rect &dstRect, Graphics::Surface *surface, Common::Rect &srcRect, int16 scale, uint32 flags);  	void setPalette(byte *colors, uint start, uint count); @@ -153,6 +155,9 @@ public:  	byte _faderPalette[768];  	int _newFaderValue, _firstFaderIndex, _lastFaderIndex; +	bool _isScreenOffsetActive; +	Common::Point _screenOffsetPt; +  	void setSystemPalette(byte *palette);  	void buildColorTransTbl(); diff --git a/engines/illusions/scriptopcodes_duckman.cpp b/engines/illusions/scriptopcodes_duckman.cpp index 3b90e0c5e3..1caf3b8bca 100644 --- a/engines/illusions/scriptopcodes_duckman.cpp +++ b/engines/illusions/scriptopcodes_duckman.cpp @@ -244,7 +244,7 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o  //static uint dsceneId = 0, dthreadId = 0;  //static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac -//static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount +static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount  //static uint dsceneId = 0x00010039, dthreadId = 0x00020089;//Map  //static uint dsceneId = 0x00010033, dthreadId = 0x000201A4;//Chinese  //static uint dsceneId = 0x00010020, dthreadId = 0x00020112;//Xmas @@ -253,7 +253,7 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o  //static uint dsceneId = 0x0001004B, dthreadId = 0x0002029B;  //static uint dsceneId = 0x00010021, dthreadId = 0x00020113;  //static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front -static uint dsceneId = 0x0001000E, dthreadId = 0x0002007C; +//static uint dsceneId = 0x0001000E, dthreadId = 0x0002007C;  void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {  	ARG_SKIP(2); @@ -547,8 +547,6 @@ void ScriptOpcodes_Duckman::opRunSpecialCode(ScriptThread *scriptThread, OpCall  	ARG_SKIP(2);  	ARG_UINT32(specialCodeId);  	_vm->runSpecialCode(specialCodeId, opCall); -	//DEBUG Resume calling thread, later done by the special code -	_vm->notifyThreadId(opCall._threadId);  }  void ScriptOpcodes_Duckman::opStartSound(ScriptThread *scriptThread, OpCall &opCall) { diff --git a/engines/illusions/updatefunctions.cpp b/engines/illusions/updatefunctions.cpp index e0cc775eb9..6e6cf52ae7 100644 --- a/engines/illusions/updatefunctions.cpp +++ b/engines/illusions/updatefunctions.cpp @@ -49,12 +49,10 @@ void UpdateFunctions::add(int priority, uint32 tag, UpdateFunctionCallback *call  }  void UpdateFunctions::update() { -  	// Avoid running updates multiple times in the current time slice  	while (_lastTimerUpdateTime == getCurrentTime())  		g_system->delayMillis(10); // CHECKME Timer resolution  	_lastTimerUpdateTime = getCurrentTime(); -  	UpdateFunctionListIterator it = _updateFunctions.begin();  	while (it != _updateFunctions.end()) {  		int r = (*it)->run(); @@ -70,7 +68,6 @@ void UpdateFunctions::update() {  			break;  		}  	} -  }  void UpdateFunctions::terminateByScene(uint32 sceneId) {  | 
