diff options
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) { |