diff options
-rw-r--r-- | kyra/kyra.cpp | 209 | ||||
-rw-r--r-- | kyra/kyra.h | 16 | ||||
-rw-r--r-- | kyra/script_v1.cpp | 3 | ||||
-rw-r--r-- | kyra/staticres.cpp | 24 |
4 files changed, 247 insertions, 5 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 7abcf00f42..b150121309 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -1324,7 +1324,7 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int } if (!brandonAlive) { - // XXX + updatePlayerItemsForScene(); } startSceneScript(brandonAlive); @@ -2074,8 +2074,16 @@ void KyraEngine::initSceneScreen(int brandonAlive) { _scriptInterpreter->runScript(_scriptClick); setTextFadeTimerCountdown(-1); - if (_currentCharacter->sceneId == 0xD2) { - // XXX + if (_currentCharacter->sceneId == 210) { + if (_itemInHand != -1) + magicOutMouseItem(2, -1); + + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + if (_currentCharacter->inventoryItems[i] != 0xFF) + magicOutMouseItem(2, i); + } + _screen->showMouse(); } } @@ -3268,6 +3276,201 @@ void KyraEngine::itemSpecialFX2(int x, int y, int item) { restoreRect0(x, y); } +void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) { + debug(9, "magicOutMouseItem(%d, %d)", animIndex, itemPos); + int videoPageBackUp = _screen->_curPage; + _screen->_curPage = 0; + int x = 0, y = 0; + if (itemPos == -1) { + x = _mouseX - 12; + y = _mouseY - 18; + } else { + x = _itemPosX[itemPos] - 4; + y = _itemPosY[itemPos] - 3; + } + + if (_itemInHand == -1 && itemPos == -1) { + return; + } + + int tableIndex = 0, loopStart = 0, maxLoops = 0; + if (animIndex == 0) { + tableIndex = _rnd.getRandomNumberRng(0, 5); + loopStart = 35; + maxLoops = 9; + } else if (animIndex == 1) { + tableIndex = _rnd.getRandomNumberRng(0, 11); + loopStart = 115; + maxLoops = 8; + } else if (animIndex == 2) { + tableIndex = 0; + loopStart = 124; + maxLoops = 4; + } else { + tableIndex = -1; + } + + if (animIndex == 2) { + // snd_kyraPlaySound(0x5E); + } else { + // snd_kyraPlaySound(0x37); + } + _screen->hideMouse(); + backUpRect1(x, y); + + for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { + restoreRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + _screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) { + _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); + } else { + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + } + _screen->updateScreen(); + while (_system->getMillis() < nextTime) { + if (nextTime - _system->getMillis() >= 10) + delay(10); + } + } + + if (itemPos != -1) { + restoreRect1(x, y); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + backUpRect1(x, y); + } + + for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { + restoreRect1(x, y); + uint32 nextTime = _system->getMillis() + 4 * _tickLength; + _screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) { + _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); + } else { + specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + } + _screen->updateScreen(); + while (_system->getMillis() < nextTime) { + if (nextTime - _system->getMillis() >= 10) + delay(10); + } + } + restoreRect1(x, y); + if (itemPos == -1) { + _screen->setMouseCursor(1, 1, _shapes[4]); + _itemInHand = -1; + } else { + _characterList[0].inventoryItems[itemPos] = 0xFF; + _screen->hideMouse(); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + _screen->showMouse(); + } + _screen->showMouse(); + _screen->_curPage = videoPageBackUp; +} + +void KyraEngine::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) { + debug(9, "specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops); + static const uint8 table1[] = { + 0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00 + }; + static const uint8 table2[] = { + 0x73, 0xB5, 0x80, 0x21, 0x13, 0x39, 0x45, 0x55, 0x62, 0xB4, 0xCF, 0xD8 + }; + static const uint8 table3[] = { + 0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00 + }; + int tableValue = 0; + if (animIndex == 0) { + tableValue = table1[tableIndex]; + } else if (animIndex == 1) { + tableValue = table2[tableIndex]; + } else if (animIndex == 2) { + tableValue = table3[tableIndex]; + } else { + return; + } + processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops); +} + +void KyraEngine::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { + debug(9, "processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); + uint8 shapeColorTable[16]; + uint8 *shapePtr = _shapes[4+shape] + 10; + if (_features & GF_TALKIE) + shapePtr += 2; + for (int i = 0; i < 16; ++i) { + shapeColorTable[i] = shapePtr[i]; + } + for (int i = loopStart; i < loopStart + maxLoops; ++i) { + for (int i2 = 0; i2 < 16; ++i2) { + if (shapePtr[i2] == i) { + shapeColorTable[i2] = (i + tableValue) - loopStart; + } + } + } + _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0x8000, shapeColorTable); +} + +void KyraEngine::updatePlayerItemsForScene() { + debug(9, "updatePlayerItemsForScene()"); + if (_itemInHand >= 29 && _itemInHand < 33) { + ++_itemInHand; + if (_itemInHand > 33) + _itemInHand = 33; + _screen->hideMouse(); + _screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]); + _screen->showMouse(); + } + + bool redraw = false; + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item >= 29 && item < 33) { + ++item; + if (item > 33) + item = 33; + _currentCharacter->inventoryItems[i] = item; + redraw = true; + } + } + + if (redraw) { + _screen->hideMouse(); + redrawInventory(0); + _screen->showMouse(); + } + + if (_itemInHand == 33) { + magicOutMouseItem(2, -1); + } + + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + uint8 item = _currentCharacter->inventoryItems[i]; + if (item == 33) { + magicOutMouseItem(2, i); + } + } + _screen->showMouse(); +} + +void KyraEngine::redrawInventory(int page) { + int videoPageBackUp = _screen->_curPage; + _screen->_curPage = page; + _screen->hideMouse(); + for (int i = 0; i < 10; ++i) { + _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page); + if (_currentCharacter->inventoryItems[i] != 0xFF) { + uint8 item = _currentCharacter->inventoryItems[i]; + _screen->drawShape(page, _shapes[220+item], _itemPosX[i], _itemPosY[i], 0, 0); + } + } + _screen->showMouse(); + _screen->_curPage = videoPageBackUp; + _screen->updateScreen(); +} + #pragma mark - #pragma mark - Animation specific code #pragma mark - diff --git a/kyra/kyra.h b/kyra/kyra.h index 07c12793b3..df93c76ca2 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -475,7 +475,7 @@ protected: void restoreRect1(int xpos, int ypos); void copyBackgroundBlock(int x, int page, int flag); void copyBackgroundBlock2(int x); - + void processInput(int xpos, int ypos); int processInputHelper(int xpos, int ypos); int clickEventHandler(int xpos, int ypos); @@ -498,6 +498,11 @@ protected: void itemSpecialFX(int x, int y, int item); void itemSpecialFX1(int x, int y, int item); void itemSpecialFX2(int x, int y, int item); + void magicOutMouseItem(int animIndex, int itemPos); + void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); + void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); + void updatePlayerItemsForScene(); + void redrawInventory(int page); void animRemoveGameItem(int index); void animAddGameItem(int index, uint16 sceneId); @@ -733,6 +738,15 @@ protected: static const int8 _charYPosTable[]; static const int8 _addYPosTable[]; + // positions of the inventory + static const int16 _itemPosX[]; + static const int8 _itemPosY[]; + + static const uint8 _magicMouseItemStartFrame[]; + static const uint8 _magicMouseItemEndFrame[]; + static const uint8 _magicMouseItemStartFrame2[]; + static const uint8 _magicMouseItemEndFrame2[]; + static const uint16 _amuletX[]; static const uint16 _amuletY[]; }; diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp index 57db9d2b96..7bbef65157 100644 --- a/kyra/script_v1.cpp +++ b/kyra/script_v1.cpp @@ -592,7 +592,8 @@ int KyraEngine::cmd_runNPCSubscript(ScriptState *script) { } int KyraEngine::cmd_magicOutMouseItem(ScriptState *script) { - warning("STUB: cmd_magicOutMouseItem"); + debug(3, "cmd_magicOutMouseItem(0x%X) (%d)", script, stackPos(0)); + magicOutMouseItem(stackPos(0), -1); return 0; } diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp index 6e22845a8a..60bd198048 100644 --- a/kyra/staticres.cpp +++ b/kyra/staticres.cpp @@ -653,6 +653,30 @@ const int8 KyraEngine::_addYPosTable[] = { 0, -2, -2, -2, 0, 2, 2, 2 }; +const int16 KyraEngine::_itemPosX[] = { + 95, 115, 135, 155, 175, 95, 115, 135, 155, 175 +}; + +const int8 KyraEngine::_itemPosY[] = { + 160, 160, 160, 160, 160, 181, 181, 181, 181, 181 +}; + +const uint8 KyraEngine::_magicMouseItemStartFrame[] = { + 0xAD, 0xB7, 0xBE, 0x00 +}; + +const uint8 KyraEngine::_magicMouseItemEndFrame[] = { + 0xB1, 0xB9, 0xC2, 0x00 +}; + +const uint8 KyraEngine::_magicMouseItemStartFrame2[] = { + 0xB2, 0xBA, 0xC3, 0x00 +}; + +const uint8 KyraEngine::_magicMouseItemEndFrame2[] = { + 0xB6, 0xBD, 0xC8, 0x00 +}; + const uint16 KyraEngine::_amuletX[] = { 231, 275, 253, 253 }; const uint16 KyraEngine::_amuletY[] = { 170, 170, 159, 181 }; } // End of namespace Kyra |