diff options
author | Johannes Schickel | 2007-10-07 00:35:22 +0000 |
---|---|---|
committer | Johannes Schickel | 2007-10-07 00:35:22 +0000 |
commit | 5ad7870775ef8eb1122e22fa5f12383536e7a01d (patch) | |
tree | da9686d09b9a299d27a3d310bcb420feb1801a73 | |
parent | aba30d7ea8541f7260ec7b96a8d33dd7dc06ed74 (diff) | |
download | scummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.tar.gz scummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.tar.bz2 scummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.zip |
- little bit more input handling
- implemented item pickup
svn-id: r29160
-rw-r--r-- | engines/kyra/animator_v2.cpp | 48 | ||||
-rw-r--r-- | engines/kyra/items_v2.cpp | 175 | ||||
-rw-r--r-- | engines/kyra/kyra_v2.cpp | 88 | ||||
-rw-r--r-- | engines/kyra/kyra_v2.h | 20 | ||||
-rw-r--r-- | engines/kyra/scene_v2.cpp | 13 |
5 files changed, 334 insertions, 10 deletions
diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp index 179bdd140d..9f0cefe9fa 100644 --- a/engines/kyra/animator_v2.cpp +++ b/engines/kyra/animator_v2.cpp @@ -310,4 +310,52 @@ void KyraEngine_v2::drawCharacterAnimObject(AnimObj *obj, int x, int y, int laye _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, _charScaleX, _charScaleY); } +void KyraEngine_v2::addItemToAnimList(int item) { + restorePage3(); + + AnimObj *animObj = &_animObjects[11+item]; + + animObj->enabled = 1; + animObj->needRefresh = 1; + animObj->unk8 = 1; + + int itemId = _itemList[item].id; + + animObj->xPos2 = animObj->xPos1 = _itemList[item].x; + animObj->yPos2 = animObj->yPos1 = _itemList[item].y; + + animObj->shapePtr = _defaultShapeTable[64+itemId]; + animObj->shapeIndex2 = animObj->shapeIndex1 = 64+itemId; + + int scaleY, scaleX; + scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1); + + uint8 *shapePtr = getShapePtr(64+itemId); + animObj->xPos3 = (animObj->xPos2 -= _screen->getShapeScaledWidth(shapePtr, scaleX) >> 1); + animObj->yPos3 = (animObj->yPos2 -= _screen->getShapeScaledHeight(shapePtr, scaleY)); + + animObj->width2 = animObj->height2 = 0; + + _animList = addToAnimListSorted(_animList, animObj); + animObj->needRefresh = 1; + animObj->unk8 = 1; +} + +void KyraEngine_v2::deleteItemAnimEntry(int item) { + AnimObj *animObj = &_animObjects[11+item]; + + restorePage3(); + + animObj->shapePtr = 0; + animObj->shapeIndex1 = 0xFFFF; + animObj->shapeIndex2 = 0xFFFF; + animObj->needRefresh = 1; + animObj->unk8 = 1; + + refreshAnimObjectsIfNeed(); + + animObj->enabled = 0; + _animList = deleteAnimListEntry(_animList, animObj); +} + } // end of namespace Kyra diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp index fd4c7a5fab..d6eb05f9fa 100644 --- a/engines/kyra/items_v2.cpp +++ b/engines/kyra/items_v2.cpp @@ -35,7 +35,16 @@ int KyraEngine_v2::findFreeItem() { return -1; } -int KyraEngine_v2::findItem(uint16 sceneId, int id) { +int KyraEngine_v2::countAllItems() { + int num = 0; + for (int i = 0; i < 30; ++i) { + if (_itemList[i].id != 0xFFFF) + ++num; + } + return num; +} + +int KyraEngine_v2::findItem(uint16 sceneId, uint16 id) { for (int i = 0; i < 30; ++i) { if (_itemList[i].id == id && _itemList[i].sceneId == sceneId) return i; @@ -43,6 +52,36 @@ int KyraEngine_v2::findItem(uint16 sceneId, int id) { return -1; } +int KyraEngine_v2::checkItemCollision(int x, int y) { + int itemPos = -1, yPos = -1; + + for (int i = 0; i < 30; ++i) { + const Item &curItem = _itemList[i]; + + if (curItem.id == 0xFFFF || curItem.sceneId != _mainCharacter.sceneId) + continue; + + int itemX1 = curItem.x - 8 - 3; + int itemX2 = curItem.x + 7 + 3; + + if (x < itemX1 || x > itemX2) + continue; + + int itemY1 = curItem.y - _itemHtDat[curItem.id] - 3; + int itemY2 = curItem.y + 3; + + if (y < itemY1 || y > itemY2) + continue; + + if (curItem.y >= yPos) { + itemPos = i; + yPos = curItem.y; + } + } + + return itemPos; +} + void KyraEngine_v2::resetItemList() { for (int i = 0; i < 30; ++i) { _itemList[i].id = 0xFFFF; @@ -53,4 +92,138 @@ void KyraEngine_v2::resetItemList() { } } +bool KyraEngine_v2::dropItem(int unk1, uint16 item, int x, int y, int unk2) { + if (_handItemSet <= -1) + return false; + + bool success = processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2); + if (!success) { + //snd_playSfx(0x0d); + if (countAllItems() >= 30) + showMessageFromCCode(5, 0x84, 0); + } + + return success; +} + +bool KyraEngine_v2::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) { + int itemPos = checkItemCollision(x, y); + + if (unk1) + itemPos = -1; + + if (itemPos >= 0) { + exchangeMouseItem(itemPos); + return false; + } + + //XXX + return false; +} + +void KyraEngine_v2::exchangeMouseItem(int itemPos) { + _screen->hideMouse(); + + deleteItemAnimEntry(itemPos); + + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = _itemInHand; + _itemInHand = itemId; + + addItemToAnimList(itemPos); + //snd_playSfx(0x0b); + setMouseCursor(_itemInHand); + int str2 = 7; + + if (_lang == 1) + str2 = getItemCommandString(itemId); + + updateCommandLineEx(itemId + 54, str2, 0xD6); + _screen->showMouse(); + + runSceneScript6(); +} + +bool KyraEngine_v2::pickUpItem(int x, int y) { + int itemPos = checkItemCollision(x, y); + + if (itemPos <= -1) + return false; + + if (_itemInHand >= 0) { + exchangeMouseItem(itemPos); + } else { + _screen->hideMouse(); + deleteItemAnimEntry(itemPos); + int itemId = _itemList[itemPos].id; + _itemList[itemPos].id = 0xFFFF; + //snd_playSfx(0x0b); + setMouseCursor(itemId); + int str2 = 7; + + if (_lang == 1) + str2 = getItemCommandString(itemId); + + updateCommandLineEx(itemId + 54, str2, 0xD6); + _itemInHand = itemId; + _screen->showMouse(); + + runSceneScript6(); + } + + return true; +} + +int KyraEngine_v2::getItemCommandString(uint16 item) { + // This is just needed for French version + static const uint8 index[] = { + 2, 2, 0, 0, 2, 2, 2, 0, + 2, 2, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 1, 0, 2, 2, 2, 2, 0, + 3, 0, 3, 2, 2, 2, 3, 2, + 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 0, 0, 1, 3, 2, + 2, 2, 2, 2, 2, 0, 0, 0, + 0, 2, 2, 1, 0, 1, 2, 0, + 0, 0, 0, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 0, 2, 2, 2, + 2, 3, 2, 0, 0, 0, 0, 1, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 0, 0, 0, 0, 0, 2, + 0, 2, 0, 0, 0, 0, 0, 0 + }; + + assert(item < ARRAYSIZE(index)); + + static const int stringId[] = { + 0x02B, 0x102, 0x007, 0x105, 0x02D, 0x103, + 0x003, 0x106, 0x02C, 0x104, 0x008, 0x107 + }; + + assert(index[item] < ARRAYSIZE(index)); + return stringId[index[item]]; +} + +void KyraEngine_v2::setMouseCursor(uint16 item) { + int shape = 0; + int hotX = 1; + int hotY = 1; + + if (item != 0xFFFF) { + hotX = 8; + hotY = 15; + shape = item+64; + } + + _screen->setMouseCursor(hotX, hotY, getShapePtr(shape)); +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 38b79bc233..853067349d 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -62,6 +62,7 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi memset(_animObjects, 0, sizeof(_animObjects)); _unkHandleSceneChangeFlag = false; _pathfinderFlag = 0; + _mouseX = _mouseY = 0; memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); } @@ -288,8 +289,7 @@ void KyraEngine_v2::runLoop() { if (inputFlag == 198 || inputFlag == 199) { _unk3 = _handItemSet; - Common::Point mouse = getMousePos(); - handleInput(mouse.x, mouse.y); + handleInput(_mouseX, _mouseY); } //XXX @@ -350,13 +350,54 @@ void KyraEngine_v2::handleInput(int x, int y) { if (checkCharCollision(x, y) >= 0 && _unk3 >= -1) { runSceneScript2(); return; + } else if (pickUpItem(x, y)) { + return; } else { - //XXX + int skipHandling = 0; + + if (checkItemCollision(x, y) == -1) { + resetGameFlag(0x1EF); + //skipHandling = sub_153D6(x, y); + + if (queryGameFlag(0x1EF)) { + resetGameFlag(0x1EF); + return; + } + + if (_unk5) { + _unk5 = 0; + return; + } + } + + //if (_unk1 <= -1) + // skipHandling = 1; + + if (skipHandling) + return; + + if (checkCharCollision(x, y) >= 0) { + runSceneScript2(); + return; + } + + /*if (_itemInHand >= 0) { + if (y > 136) + return; + + dropItem(0, _itemInHand, x, y, 1); + } else {*/ + if (_unk3 == -2 || y > 135) + return; + + if (!_unk5) { + inputSceneChange(x, y, 1, 1); + return; + } + + _unk5 = 0; + //} } - - //XXX - - inputSceneChange(x, y, 1, 1); } int KyraEngine_v2::update() { @@ -502,8 +543,14 @@ int KyraEngine_v2::checkInput(void *p) { switch (event.type) { case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == Common::KEYCODE_RETURN) + if (event.kbd.keycode == Common::KEYCODE_RETURN) { + // this doesn't make sure the mouse position is the same + // as when RETURN was pressed, but it *should* work for now + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; keys = 199; + } if (event.kbd.flags == Common::KBD_CTRL) { if (event.kbd.keycode == 'd') @@ -513,6 +560,8 @@ int KyraEngine_v2::checkInput(void *p) { break; case Common::EVENT_LBUTTONUP: + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; keys = 198; breakLoop = true; break; @@ -728,6 +777,29 @@ void KyraEngine_v2::showChapterMessage(int id, int16 palIndex) { showMessage(getChapterString(id), palIndex); } +void KyraEngine_v2::updateCommandLineEx(int str1, int str2, int16 palIndex) { + char buffer[0x51]; + char *src = buffer; + + strcpy(src, getTableString(str1, _cCodeBuffer, 1)); + + while (*src != 0x20) + ++src; + ++src; + + *src = toupper(*src); + strcpy((char*)_unkBuf500Bytes, src); + + if (str2 > 0) { + strcat((char*)_unkBuf500Bytes, " "); + strcat((char*)_unkBuf500Bytes, getTableString(str2, _cCodeBuffer, 1)); + } + + showMessage((char*)_unkBuf500Bytes, palIndex); +} + +#pragma mark - + void KyraEngine_v2::loadMouseShapes() { _screen->loadBitmap("_MOUSE.CSH", 3, 3, 0); diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index 2397378fd1..6412b0609a 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -175,6 +175,7 @@ protected: // - Input void updateInput(); + int _mouseX, _mouseY; Common::List<Common::Event> _eventList; // gfx/animation specific @@ -283,6 +284,9 @@ protected: void updateCharacterAnim(int); void updateSceneAnim(int anim, int newFrame); + + void addItemToAnimList(int item); + void deleteItemAnimEntry(int item); // scene struct SceneDesc { @@ -317,6 +321,7 @@ protected: void startSceneScript(int unk1); void runSceneScript2(); void runSceneScript4(int unk1); + void runSceneScript6(); void runSceneScript7(); void initSceneAnims(int unk1); @@ -353,11 +358,22 @@ protected: Item *_itemList; int findFreeItem(); - int findItem(uint16 sceneId, int id); + int countAllItems(); + int findItem(uint16 sceneId, uint16 id); + int checkItemCollision(int x, int y); void resetItemList(); int _itemInHand; int _handItemSet; + + bool dropItem(int unk1, uint16 item, int x, int y, int unk2); + bool processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2); + void exchangeMouseItem(int itemPos); + bool pickUpItem(int x, int y); + + int getItemCommandString(uint16 item); + + void setMouseCursor(uint16 item); // inventroy static int _inventoryX[]; @@ -423,6 +439,8 @@ protected: void showMessageFromCCode(int id, int16 palIndex, int); void showMessage(const char *string, int16 palIndex); void showChapterMessage(int id, int16 palIndex); + + void updateCommandLineEx(int str1, int str2, int16 palIndex); const char *_shownMessage; diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp index dfa0c7f0b8..862441fe89 100644 --- a/engines/kyra/scene_v2.cpp +++ b/engines/kyra/scene_v2.cpp @@ -457,6 +457,19 @@ void KyraEngine_v2::runSceneScript4(int unk1) { _scriptInterpreter->runScript(&_sceneScriptState); } +void KyraEngine_v2::runSceneScript6() { + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[1] = _mouseX; + _sceneScriptState.regs[2] = _mouseY; + _sceneScriptState.regs[4] = _itemInHand; + + _scriptInterpreter->startScript(&_sceneScriptState, 6); + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); +} + void KyraEngine_v2::runSceneScript7() { int oldPage = _screen->_curPage; _screen->_curPage = 2; |