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); |