aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2007-10-07 00:35:22 +0000
committerJohannes Schickel2007-10-07 00:35:22 +0000
commit5ad7870775ef8eb1122e22fa5f12383536e7a01d (patch)
treeda9686d09b9a299d27a3d310bcb420feb1801a73 /engines/kyra
parentaba30d7ea8541f7260ec7b96a8d33dd7dc06ed74 (diff)
downloadscummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.tar.gz
scummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.tar.bz2
scummvm-rg350-5ad7870775ef8eb1122e22fa5f12383536e7a01d.zip
- little bit more input handling
- implemented item pickup svn-id: r29160
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/animator_v2.cpp48
-rw-r--r--engines/kyra/items_v2.cpp175
-rw-r--r--engines/kyra/kyra_v2.cpp88
-rw-r--r--engines/kyra/kyra_v2.h20
-rw-r--r--engines/kyra/scene_v2.cpp13
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;