/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "kyra/kyra_lok.h" #include "kyra/animator_lok.h" #include "common/system.h" namespace Kyra { int KyraEngine_LoK::findDuplicateItemShape(int shape) { static const uint8 dupTable[] = { 0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47, 0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a, 0x5d, 0x5a, 0x5e, 0x5a, 0xFF, 0xFF }; int i = 0; while (dupTable[i] != 0xFF) { if (dupTable[i] == shape) return dupTable[i+1]; i += 2; } return -1; } void KyraEngine_LoK::addToNoDropRects(int x, int y, int w, int h) { for (int rect = 0; rect < ARRAYSIZE(_noDropRects); ++rect) { if (_noDropRects[rect].top == -1) { _noDropRects[rect].left = x; _noDropRects[rect].top = y; _noDropRects[rect].right = x + w; _noDropRects[rect].bottom = y + h; break; } } } void KyraEngine_LoK::clearNoDropRects() { memset(_noDropRects, -1, sizeof(_noDropRects)); } byte KyraEngine_LoK::findFreeItemInScene(int scene) { assert(scene < _roomTableSize); Room *room = &_roomTable[scene]; for (int i = 0; i < 12; ++i) { if (room->itemsTable[i] == kItemNone) return i; } return 0xFF; } byte KyraEngine_LoK::findItemAtPos(int x, int y) { assert(_currentCharacter->sceneId < _roomTableSize); const int8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable; const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos; const uint8 *yposOffset = _roomTable[_currentCharacter->sceneId].itemsYPos; int highestYPos = -1; Item returnValue = kItemNone; for (int i = 0; i < 12; ++i) { if (*itemsTable != kItemNone) { int xpos = *xposOffset - 11; int xpos2 = *xposOffset + 10; if (x > xpos && x < xpos2) { assert(*itemsTable >= 0); int itemHeight = _itemHtDat[*itemsTable]; int ypos = *yposOffset + 3; int ypos2 = ypos - itemHeight - 3; if (y > ypos2 && ypos > y) { if (highestYPos <= ypos) { returnValue = i; highestYPos = ypos; } } } } ++xposOffset; ++yposOffset; ++itemsTable; } return returnValue; } void KyraEngine_LoK::placeItemInGenericMapScene(int item, int index) { static const uint16 itemMapSceneMinTable[] = { 0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000 }; static const uint16 itemMapSceneMaxTable[] = { 0x0010, 0x0024, 0x00C6, 0x006C, 0x00F5, 0x0000 }; int minValue = itemMapSceneMinTable[index]; int maxValue = itemMapSceneMaxTable[index]; while (true) { int room = _rnd.getRandomNumberRng(minValue, maxValue); assert(room < _roomTableSize); int nameIndex = _roomTable[room].nameIndex; bool placeItem = false; switch (nameIndex) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 11: case 12: case 16: case 17: case 20: case 22: case 23: case 25: case 26: case 27: case 31: case 33: case 34: case 36: case 37: case 58: case 59: case 60: case 61: case 83: case 84: case 85: case 104: case 105: case 106: placeItem = true; break; case 51: if (room != 46) placeItem = true; break; default: break; } if (placeItem) { Room *roomPtr = &_roomTable[room]; if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) placeItem = false; else if (_currentCharacter->sceneId == room) placeItem = false; } if (placeItem) { if (!processItemDrop(room, item, -1, -1, 2, 0)) continue; break; } } } void KyraEngine_LoK::setHandItem(Item item) { _screen->hideMouse(); setMouseItem(item); _itemInHand = item; _screen->showMouse(); } void KyraEngine_LoK::removeHandItem() { _screen->hideMouse(); _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = kItemNone; _screen->showMouse(); } void KyraEngine_LoK::setMouseItem(Item item) { if (item == kItemNone) _screen->setMouseCursor(1, 1, _shapes[6]); else _screen->setMouseCursor(8, 15, _shapes[216+item]); } void KyraEngine_LoK::wipeDownMouseItem(int xpos, int ypos) { if (_itemInHand == kItemNone) return; xpos -= 8; ypos -= 15; _screen->hideMouse(); backUpItemRect1(xpos, ypos); int y = ypos; int height = 16; while (height >= 0) { restoreItemRect1(xpos, ypos); _screen->setNewShapeHeight(_shapes[216+_itemInHand], height); uint32 nextTime = _system->getMillis() + 1 * _tickLength; _screen->drawShape(0, _shapes[216+_itemInHand], xpos, y, 0, 0); _screen->updateScreen(); y += 2; height -= 2; delayUntil(nextTime); } restoreItemRect1(xpos, ypos); _screen->resetShapeHeight(_shapes[216+_itemInHand]); removeHandItem(); _screen->showMouse(); } void KyraEngine_LoK::setupSceneItems() { uint16 sceneId = _currentCharacter->sceneId; assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; for (int i = 0; i < 12; ++i) { uint8 item = currentRoom->itemsTable[i]; if (item == 0xFF || !currentRoom->needInit[i]) continue; int xpos = 0; int ypos = 0; if (currentRoom->itemsXPos[i] == 0xFFFF) { xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); } else { xpos = currentRoom->itemsXPos[i]; ypos = currentRoom->itemsYPos[i]; } _lastProcessedItem = i; int stop = 0; while (!stop) { stop = processItemDrop(sceneId, item, xpos, ypos, 3, 0); if (!stop) { xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); if (countItemsInScene(sceneId) >= 12) break; } else { currentRoom->needInit[i] = 0; } } } } int KyraEngine_LoK::countItemsInScene(uint16 sceneId) { assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; int items = 0; for (int i = 0; i < 12; ++i) { if (currentRoom->itemsTable[i] != kItemNone) ++items; } return items; } int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) { int freeItem = -1; uint8 itemIndex = findItemAtPos(x, y); if (unk1) itemIndex = 0xFF; if (itemIndex != 0xFF) { exchangeItemWithMouseItem(sceneId, itemIndex); return 0; } assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; if (unk1 != 3) { for (int i = 0; i < 12; ++i) { if (currentRoom->itemsTable[i] == kItemNone) { freeItem = i; break; } } } else { freeItem = _lastProcessedItem; } if (freeItem == -1) return 0; if (sceneId != _currentCharacter->sceneId) { addItemToRoom(sceneId, item, freeItem, x, y); return 1; } int itemHeight = _itemHtDat[item]; _lastProcessedItemHeight = itemHeight; if (x == -1) x = _rnd.getRandomNumberRng(16, 304); if (y == -1) y = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 135); int xpos = x; int ypos = y; int destY = -1; int destX = -1; int running = 1; while (running) { if ((_northExitHeight & 0xFF) <= ypos) { bool running2 = true; if (_screen->getDrawLayer(xpos, ypos) > 1) { if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; } if (_screen->getDrawLayer2(xpos, ypos, itemHeight) > 1) { if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; } if (!isDropable(xpos, ypos)) { if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; } int xpos2 = xpos; int xpos3 = xpos; while (running2) { if (isDropable(xpos2, ypos)) { if (_screen->getDrawLayer2(xpos2, ypos, itemHeight) < 7) { if (findItemAtPos(xpos2, ypos) == 0xFF) { destX = xpos2; destY = ypos; running = 0; running2 = false; } } } if (isDropable(xpos3, ypos)) { if (_screen->getDrawLayer2(xpos3, ypos, itemHeight) < 7) { if (findItemAtPos(xpos3, ypos) == 0xFF) { destX = xpos3; destY = ypos; running = 0; running2 = false; } } } if (!running2) continue; xpos2 -= 2; if (xpos2 < 16) xpos2 = 16; xpos3 += 2; if (xpos3 > 304) xpos3 = 304; if (xpos2 > 16) continue; if (xpos3 < 304) continue; running2 = false; } } if (((_northExitHeight >> 8) & 0xFF) == ypos) { running = 0; destY -= _rnd.getRandomNumberRng(0, 3); if ((_northExitHeight & 0xFF) < destY) continue; destY = (_northExitHeight & 0xFF) + 1; continue; } ypos += 2; if (((_northExitHeight >> 8) & 0xFF) >= ypos) continue; ypos = (_northExitHeight >> 8) & 0xFF; } if (destX == -1 || destY == -1) return 0; if (unk1 == 3) { currentRoom->itemsXPos[freeItem] = destX; currentRoom->itemsYPos[freeItem] = destY; return 1; } if (unk1 == 2) itemSpecialFX(x, y, item); if (unk1 == 0) removeHandItem(); itemDropDown(x, y, destX, destY, freeItem, item); if (unk1 == 0 && unk2 != 0) { assert(_itemList && _droppedList); updateSentenceCommand(_itemList[getItemListIndex(item)], _droppedList[0], 179); } return 1; } void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { _screen->hideMouse(); _animator->animRemoveGameItem(itemIndex); assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; int item = currentRoom->itemsTable[itemIndex]; currentRoom->itemsTable[itemIndex] = _itemInHand; _itemInHand = item; _animator->animAddGameItem(itemIndex, sceneId); snd_playSoundEffect(53); setMouseItem(_itemInHand); assert(_itemList && _takenList); if (_flags.platform == Common::kPlatformAmiga) updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[0], 179); else updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179); _screen->showMouse(); clickEventHandler2(); } void KyraEngine_LoK::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) { assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; currentRoom->itemsTable[itemIndex] = item; currentRoom->itemsXPos[itemIndex] = x; currentRoom->itemsYPos[itemIndex] = y; currentRoom->needInit[itemIndex] = 1; } int KyraEngine_LoK::checkNoDropRects(int x, int y) { if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) _lastProcessedItemHeight = 16; if (_noDropRects[0].left == -1) return 0; for (int i = 0; i < ARRAYSIZE(_noDropRects); ++i) { if (_noDropRects[i].left == -1) break; int xpos = _noDropRects[i].left; int ypos = _noDropRects[i].top; int xpos2 = _noDropRects[i].right; int ypos2 = _noDropRects[i].bottom; if (xpos > x + 16) continue; if (xpos2 <= x) continue; if (y < ypos) continue; if (ypos2 <= y - _lastProcessedItemHeight) continue; return 1; } return 0; } int KyraEngine_LoK::isDropable(int x, int y) { x -= 8; y -= 1; if (checkNoDropRects(x, y)) return 0; for (int xpos = x; xpos < x + 16; ++xpos) { if (_screen->getShapeFlag1(xpos, y) == 0) return 0; } return 1; } void KyraEngine_LoK::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) { assert(_currentCharacter->sceneId < _roomTableSize); Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; if (x == destX && y == destY) { currentRoom->itemsXPos[freeItem] = destX; currentRoom->itemsYPos[freeItem] = destY; currentRoom->itemsTable[freeItem] = item; snd_playSoundEffect(0x32); _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); return; } _screen->hideMouse(); if (y <= destY) { int tempY = y; int addY = 2; int drawX = x - 8; int drawY = 0; backUpItemRect0(drawX, y - 16); while (tempY < destY) { restoreItemRect0(drawX, tempY - 16); tempY += addY; if (tempY > destY) tempY = destY; ++addY; drawY = tempY - 16; backUpItemRect0(drawX, drawY); uint32 nextTime = _system->getMillis() + 1 * _tickLength; _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } bool skip = false; if (x == destX) { if (destY - y <= 16) skip = true; } if (!skip) { snd_playSoundEffect(0x47); if (addY < 6) addY = 6; int xDiff = (destX - x) << 4; xDiff /= addY; int startAddY = addY; addY >>= 1; if (destY - y <= 8) addY >>= 1; addY = -addY; int unkX = x << 4; while (--startAddY) { drawX = (unkX >> 4) - 8; drawY = tempY - 16; restoreItemRect0(drawX, drawY); tempY += addY; unkX += xDiff; if (tempY > destY) tempY = destY; ++addY; drawX = (unkX >> 4) - 8; drawY = tempY - 16; backUpItemRect0(drawX, drawY); uint32 nextTime = _system->getMillis() + 1 * _tickLength; _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } restoreItemRect0(drawX, drawY); } else { restoreItemRect0(drawX, tempY - 16); } } currentRoom->itemsXPos[freeItem] = destX; currentRoom->itemsYPos[freeItem] = destY; currentRoom->itemsTable[freeItem] = item; snd_playSoundEffect(0x32); _animator->animAddGameItem(freeItem, _currentCharacter->sceneId); _screen->showMouse(); } void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) { if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) return; snd_playSoundEffect(54); assert(_noDropList); if (12 == countItemsInScene(_currentCharacter->sceneId)) drawSentenceCommand(_noDropList[0], 6); else drawSentenceCommand(_noDropList[1], 6); } void KyraEngine_LoK::itemSpecialFX(int x, int y, int item) { if (item == 41) itemSpecialFX1(x, y, item); else itemSpecialFX2(x, y, item); } void KyraEngine_LoK::itemSpecialFX1(int x, int y, int item) { uint8 *shape = _shapes[216+item]; x -= 8; int startY = y; y -= 15; _screen->hideMouse(); backUpItemRect0(x, y); for (int i = 1; i <= 16; ++i) { _screen->setNewShapeHeight(shape, i); --startY; restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 1 * _tickLength; _screen->drawShape(0, shape, x, startY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } restoreItemRect0(x, y); _screen->showMouse(); } void KyraEngine_LoK::itemSpecialFX2(int x, int y, int item) { x -= 8; y -= 15; int yAdd = (int8)(((16 - _itemHtDat[item]) >> 1) & 0xFF); backUpItemRect0(x, y); if (item >= 80 && item <= 89) snd_playSoundEffect(55); for (int i = 201; i <= 205; ++i) { restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 3 * _tickLength; _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } for (int i = 204; i >= 201; --i) { restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 3 * _tickLength; _screen->drawShape(0, _shapes[216+item], x, y, 0, 0); _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } restoreItemRect0(x, y); } void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { int videoPageBackUp = _screen->_curPage; _screen->_curPage = 0; int x = 0, y = 0; if (itemPos == kItemNone) { Common::Point mouse = getMousePos(); x = mouse.x - 12; y = mouse.y - 18; } else { x = _itemPosX[itemPos] - 4; y = _itemPosY[itemPos] - 3; } if (_itemInHand == kItemNone && 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_playSoundEffect(0x5E); else snd_playSoundEffect(0x37); _screen->hideMouse(); backUpItemRect1(x, y); for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); if (tableIndex == -1) _screen->drawShape(0, _shapes[shape], x, y, 0, 0); else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); _screen->updateScreen(); delayUntil(nextTime); } if (itemPos != -1) { restoreItemRect1(x, y); _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); backUpItemRect1(x, y); } for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); if (tableIndex == -1) _screen->drawShape(0, _shapes[shape], x, y, 0, 0); else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); _screen->updateScreen(); delayUntil(nextTime); } restoreItemRect1(x, y); if (itemPos == -1) { _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = kItemNone; } else { _characterList[0].inventoryItems[itemPos] = kItemNone; _screen->hideMouse(); _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); _screen->showMouse(); } _screen->showMouse(); _screen->_curPage = videoPageBackUp; } void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) { int videoPageBackUp = _screen->_curPage; _screen->_curPage = 0; int x = 0, y = 0; if (itemPos == -1) { Common::Point mouse = getMousePos(); x = mouse.x - 12; y = mouse.y - 18; } else { x = _itemPosX[itemPos] - 4; y = _itemPosX[itemPos] - 3; } if (item < 0) return; int tableIndex = -1, 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; } _screen->hideMouse(); backUpItemRect1(x, y); if (animIndex == 2) snd_playSoundEffect(0x5E); else snd_playSoundEffect(0x37); for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; if (tableIndex == -1) _screen->drawShape(0, _shapes[shape], x, y, 0, 0); else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); _screen->updateScreen(); delayUntil(nextTime); } for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; if (tableIndex == -1) _screen->drawShape(0, _shapes[shape], x, y, 0, 0); else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); _screen->updateScreen(); delayUntil(nextTime); } restoreItemRect1(x, y); if (itemPos == -1) { _screen->setMouseCursor(8, 15, _shapes[216+item]); _itemInHand = item; } else { _characterList[0].inventoryItems[itemPos] = item; _screen->hideMouse(); _screen->drawShape(0, _shapes[216+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); _screen->showMouse(); } _screen->showMouse(); _screen->_curPage = videoPageBackUp; } void KyraEngine_LoK::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int 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_LoK::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { uint8 shapeColorTable[16]; uint8 *shapePtr = _shapes[shape] + 10; if (_flags.useAltShapeHeader) 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[shape], x, y, 0, 0x8000, shapeColorTable); } void KyraEngine_LoK::updatePlayerItemsForScene() { if (_itemInHand >= 29 && _itemInHand < 33) { ++_itemInHand; if (_itemInHand > 33) _itemInHand = 33; _screen->hideMouse(); _screen->setMouseCursor(8, 15, _shapes[216+_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_LoK::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, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page); if (_currentCharacter->inventoryItems[i] != kItemNone) { uint8 item = _currentCharacter->inventoryItems[i]; _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0); } } _screen->showMouse(); _screen->_curPage = videoPageBackUp; _screen->updateScreen(); } void KyraEngine_LoK::backUpItemRect0(int xpos, int ypos) { _screen->rectClip(xpos, ypos, 3<<3, 24); _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); } void KyraEngine_LoK::restoreItemRect0(int xpos, int ypos) { _screen->rectClip(xpos, ypos, 3<<3, 24); _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); } void KyraEngine_LoK::backUpItemRect1(int xpos, int ypos) { _screen->rectClip(xpos, ypos, 4<<3, 32); _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); } void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) { _screen->rectClip(xpos, ypos, 4<<3, 32); _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); } int KyraEngine_LoK::getItemListIndex(Item item) { if (_flags.platform != Common::kPlatformAmiga) return item; // "Unknown item" is at 81. if (item == kItemNone) return 81; // The first item names are mapped directly else if (item <= 28) return item; // There's only one string for "Fireberries" else if (item >= 29 && item <= 33) return 29; // Correct offsets else if (item >= 34 && item <= 59) return item - 4; // There's only one string for "Red Potion" else if (item >= 60 && item <= 61) return 56; // There's only one string for "Blue Potion" else if (item >= 62 && item <= 63) return 57; // There's only one string for "Yellow Potion" else if (item >= 64 && item <= 65) return 58; // Correct offsets else if (item >= 66 && item <= 69) return item - 7; // There's only one string for "Fresh Water" else if (item >= 70 && item <= 71) return 63; // There's only one string for "Salt Water" else if (item >= 72 && item <= 73) return 64; // There's only one string for "Mineral Water" else if (item >= 74 && item <= 75) return 65; // There's only one string for "Magical Water" else if (item >= 76 && item <= 77) return 66; // There's only one string for "Empty Flask" else if (item >= 78 && item <= 79) return 67; // There's only one string for "Scroll" else if (item >= 80 && item <= 89) return 68; // There's only one string for "Parchment scrap" else if (item >= 90 && item <= 94) return 69; // Correct offsets else if (item >= 95) return item - 25; // This should never happen, but still GCC warns about it. return 81; } } // End of namespace Kyra