[Scummvm-cvs-logs] SF.net SVN: scummvm: [31681] scummvm/trunk/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Thu Apr 24 00:53:19 CEST 2008


Revision: 31681
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31681&view=rev
Author:   lordhoto
Date:     2008-04-23 15:53:19 -0700 (Wed, 23 Apr 2008)

Log Message:
-----------
Implemented parts of item drop down code for Kyra3.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/animator_v3.cpp
    scummvm/trunk/engines/kyra/items_v3.cpp
    scummvm/trunk/engines/kyra/kyra_v3.cpp
    scummvm/trunk/engines/kyra/kyra_v3.h
    scummvm/trunk/engines/kyra/screen.h
    scummvm/trunk/engines/kyra/screen_v3.cpp
    scummvm/trunk/engines/kyra/screen_v3.h
    scummvm/trunk/engines/kyra/staticres.cpp

Modified: scummvm/trunk/engines/kyra/animator_v3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/animator_v3.cpp	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/animator_v3.cpp	2008-04-23 22:53:19 UTC (rev 31681)
@@ -605,5 +605,36 @@
 	setNextIdleAnimTimer();
 }
 
+void KyraEngine_v3::addItemToAnimList(int item) {
+	debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addItemToAnimList(%d)", item);
+	restorePage3();
+
+	AnimObj *animObj = &_animObjects[17+item];
+
+	animObj->enabled = 1;
+	animObj->needRefresh = 1;
+
+	int itemId = _itemList[item].id;
+
+	animObj->xPos2 = animObj->xPos1 = _itemList[item].x;
+	animObj->yPos2 = animObj->yPos1 = _itemList[item].y;
+
+	animObj->shapePtr = getShapePtr(248+itemId);
+	animSetupPaletteEntry(animObj);
+	animObj->shapeIndex2 = animObj->shapeIndex = 248+itemId;
+
+	int scaleY, scaleX;
+	scaleY = scaleX = getScale(animObj->xPos1, animObj->yPos1);
+
+	uint8 *shapePtr = getShapePtr(248+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;
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/items_v3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/items_v3.cpp	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/items_v3.cpp	2008-04-23 22:53:19 UTC (rev 31681)
@@ -42,6 +42,18 @@
 		resetItem(i);
 }
 
+void KyraEngine_v3::removeTrashItems() {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::removeTrashItems()");
+	for (int i = 0; _trashItemList[i] != 0xFF; ++i) {
+		for (int item = findItem(_trashItemList[i]); item != -1; item = findItem(_trashItemList[i])) {
+			if (_itemList[item].sceneId != _mainCharacter.sceneId)
+				resetItem(item);
+			else
+				break;
+		}
+	}
+}
+
 int KyraEngine_v3::findFreeItem() {
 	debugC(9, kDebugLevelMain, "KyraEngine_v3::findFreeItem()");
 	for (int i = 0; i < 50; ++i) {
@@ -60,6 +72,27 @@
 	return -1;
 }
 
+int KyraEngine_v3::findItem(uint16 item) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::findItem(%u)", item);
+	for (int i = 0; i < 50; ++i) {
+		if (_itemList[i].id == item)
+			return i;
+	}
+	return -1;
+}
+
+int KyraEngine_v3::countAllItems() {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::countAllItems()");
+	int count = 0;
+
+	for (int i = 0; i < 50; ++i) {
+		if (_itemList[i].id != 0xFFFF)
+			++count;
+	}
+
+	return count;
+}
+
 int KyraEngine_v3::checkItemCollision(int x, int y) {
 	debugC(9, kDebugLevelMain, "KyraEngine_v3::checkItemCollision(%d, %d)", x, y);
 	int itemIndex = -1;
@@ -138,5 +171,242 @@
 	_screen->showMouse();
 }
 
+bool KyraEngine_v3::dropItem(int unk1, uint16 item, int x, int y, int unk2) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2);
+
+	if (_handItemSet <= -1)
+		return false;
+
+	if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2))
+		return true;
+
+	playSoundEffect(13, 200);
+
+	if (countAllItems() >= 50) {
+		removeTrashItems();
+		if (processItemDrop(_mainCharacter.sceneId, item, x, y, unk1, unk2))
+			return true;
+
+		//if (countAllItems() >= 50)
+			//showMessageFromCCode(14, 0xB3, 0);
+	}
+
+	if (!_chatText)
+		playSoundEffect(13, 200);
+	return false;
+}
+
+bool KyraEngine_v3::processItemDrop(uint16 sceneId, uint16 item, int x, int y, int unk1, int unk2) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2);
+
+	int itemPos = checkItemCollision(x, y);
+
+	if (unk1)
+		itemPos = -1;
+
+	if (itemPos >= 0) {
+		exchangeMouseItem(itemPos, 1);	
+		return true;
+	}
+
+	int freeItemSlot = -1;
+
+	if (unk2 != 3) {
+		for (int i = 0; i < 50; ++i) {
+			if (_itemList[i].id == 0xFFFF) {
+				freeItemSlot = i;
+				break;
+			}
+		}
+	}
+
+	if (freeItemSlot < 0)
+		return false;
+
+	if (_mainCharacter.sceneId != sceneId) {
+		_itemList[freeItemSlot].x = x;
+		_itemList[freeItemSlot].y = y;
+		_itemList[freeItemSlot].id = item;
+		_itemList[freeItemSlot].unk8 = 1;
+		_itemList[freeItemSlot].sceneId = sceneId;
+		return true;
+	}
+
+	int itemHeight = _itemBuffer1[item];
+
+	// no idea why it's '&&' here and not single checks for x and y
+	if (x == -1 && y == -1) {
+		x = _rnd.getRandomNumberRng(0x18, 0x128);
+		y = _rnd.getRandomNumberRng(0x14, 0x87);
+	}
+
+	int posX = x, posY = y;
+	int itemX = -1, itemY = -1;
+	bool needRepositioning = true;
+
+	while (needRepositioning) {
+		if ((_screen->getDrawLayer(posX, posY) <= 1 && _screen->getDrawLayer2(posX, posY, itemHeight) <= 1 && isDropable(posX, posY)) || posY == 187) {
+			int posX2 = posX, posX3 = posX;
+			bool repositioning = true;
+
+			while (repositioning) {
+				if (isDropable(posX3, posY) && _screen->getDrawLayer2(posX3, posY, itemHeight) < 7 && checkItemCollision(posX3, posY) == -1) {
+					itemX = posX3;
+					itemY = posY;
+					needRepositioning = false;
+					repositioning = false;
+				}
+
+				if (isDropable(posX2, posY) && _screen->getDrawLayer2(posX2, posY, itemHeight) < 7 && checkItemCollision(posX2, posY) == -1) {
+					itemX = posX2;
+					itemY = posY;
+					needRepositioning = false;
+					repositioning = false;
+				}
+
+				if (repositioning) {
+					posX3 = MAX(posX3 - 2, 24);
+					posX2 = MIN(posX2 + 2, 296);
+
+					if (posX3 <= 24 && posX2 >= 296)
+						repositioning = false;
+				}
+			}
+		}
+
+		if (posY == 187)
+			needRepositioning = false;
+		else
+			posY = MIN(posY + 2, 187);
+	}
+
+	if (itemX == -1 || itemY == -1)
+		return false;
+
+	if (unk1 == 3) {
+		_itemList[freeItemSlot].x = itemX;
+		_itemList[freeItemSlot].y = itemY;
+		return true;
+	} else if (unk1 == 2) {
+		itemDropDown(x, y, itemX, itemY, freeItemSlot, item, 0);
+	}
+
+	itemDropDown(x, y, itemX, itemY, freeItemSlot, item, (unk1 == 0) ? 1 : 0);
+
+	if (!unk1 && unk2) {
+		//int itemStr = 1;
+		//if (_lang == 1)
+		//	itemStr = getItemCommandStringDrop(item);
+		//updateCommandLineEx(item+54, itemStr, 0xD6);
+	}
+
+	return true;
+}
+
+void KyraEngine_v3::itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v2::itemDropDown(%d, %d, %d, %d, %d, %u, %d)", startX, startY, dstX, dstY, itemSlot, item, remove);
+	if (startX == dstX && startY == dstY) {
+		_itemList[itemSlot].x = dstX;
+		_itemList[itemSlot].y = dstY;
+		_itemList[itemSlot].id = item;
+		_itemList[itemSlot].sceneId = _mainCharacter.sceneId;
+		playSoundEffect(0x0C, 0xC8);
+		addItemToAnimList(itemSlot);
+	} else {
+		uint8 *itemShape = getShapePtr(item + 248);
+		_screen->hideMouse();
+
+		if (startY <= dstY) {
+			int speed = 2;
+			int curY = startY;
+			int curX = startX - 12;
+
+			backUpGfxRect32x32(curX, curY-16);
+			while (curY < dstY) {
+				restoreGfxRect32x32(curX, curY-16);
+
+				curY = MIN(curY + speed, dstY);
+				++speed;
+
+				backUpGfxRect32x32(curX, curY-16);
+				uint32 endDelay = _system->getMillis() + _tickLength;
+
+				_screen->drawShape(0, itemShape, curX, curY-16, 0, 0);
+				_screen->updateScreen();
+
+				delayUntil(endDelay);
+			}
+			restoreGfxRect32x32(curX, curY-16);
+
+			if (dstX != dstY || (dstY - startY > 16)) {
+				playSoundEffect(0x11, 0xC8);
+				speed = MAX(speed, 6);
+				int speedX = ((dstX - startX) << 4) / speed;
+				int origSpeed = speed;
+				speed >>= 1;
+
+				if (dstY - startY <= 8)
+					speed >>= 1;
+
+				speed = -speed;
+
+				curX = startX << 4;
+
+				int x = 0, y = 0;
+				while (--origSpeed) {
+					curY = MIN(curY + speed, dstY);
+					curX += speedX;
+					++speed;
+
+					x = (curX >> 4) - 8;
+					y = curY - 16;
+					backUpGfxRect32x32(x, y);
+
+					uint16 endDelay = _system->getMillis() + _tickLength;
+					_screen->drawShape(0, itemShape, x, y, 0, 0);
+					_screen->updateScreen();
+
+					restoreGfxRect32x32(x, y);
+
+					delayUntil(endDelay);
+				}
+
+				restoreGfxRect32x32(x, y);
+			} 
+		}
+
+		_itemList[itemSlot].x = dstX;
+		_itemList[itemSlot].y = dstY;
+		_itemList[itemSlot].id = item;
+		_itemList[itemSlot].sceneId = _mainCharacter.sceneId;
+		playSoundEffect(0x0C, 0xC8);
+		addItemToAnimList(itemSlot);
+		_screen->showMouse();
+	}
+
+	if (remove)
+		removeHandItem();
+}
+
+void KyraEngine_v3::exchangeMouseItem(int itemPos, int runScript) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::exchangeMouseItem(%d, %d)", itemPos, runScript);
+	//XXX
+}
+
+bool KyraEngine_v3::isDropable(int x, int y) {
+	debugC(9, kDebugLevelMain, "KyraEngine_v3::isDropable(%d, %d)", x, y);
+	if (y < 14 || y > 187)
+		return false;
+
+	x -= 12;
+
+	for (int xpos = x; xpos < x + 24; ++xpos) {
+		if (_screen->getShapeFlag1(xpos, y) == 0)
+			return false;
+	}
+
+	return true;
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/kyra_v3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v3.cpp	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/kyra_v3.cpp	2008-04-23 22:53:19 UTC (rev 31681)
@@ -1054,7 +1054,14 @@
 		if (runSceneScript2())
 			return;
 	} else if (_itemInHand >= 0 && _unk3 >= 0) {
-		//XXX
+		if (_itemInHand == 27) {
+			makeCharFacingMouse();
+		} else if (y <= 187) {
+			if (_itemInHand == 43)
+				removeHandItem();
+			else
+				dropItem(0, _itemInHand, x, y, 1);
+		}
 		return;
 	} else if (_unk3 == -3) {
 		return;
@@ -1422,6 +1429,17 @@
 	}
 }
 
+void KyraEngine_v3::makeCharFacingMouse() {
+	debugC(9, kDebugLevelAnimator, "KyraEngine_v3::makeCharFacingMouse()");
+	if (_mainCharacter.x1 > _mouseX)
+		_mainCharacter.facing = 5;
+	else
+		_mainCharacter.facing = 3;
+	_mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+	updateCharacterAnim(0);
+	refreshAnimObjectsIfNeed();
+}
+
 #pragma mark -
 
 int KyraEngine_v3::getDrawLayer(int x, int y) {

Modified: scummvm/trunk/engines/kyra/kyra_v3.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v3.h	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/kyra_v3.h	2008-04-23 22:53:19 UTC (rev 31681)
@@ -236,6 +236,8 @@
 	bool _nextIdleType;
 	void showIdleAnim();
 
+	void addItemToAnimList(int item);
+
 	// interface
 	uint8 *_interface;
 	uint8 *_interfaceCommandLine;
@@ -297,17 +299,30 @@
 
 	void resetItem(int index);
 	void resetItemList();
+	static const uint8 _trashItemList[];
+	void removeTrashItems();
 
 	int findFreeItem();
 	int findItem(uint16 item, uint16 scene);
+	int findItem(uint16 item);
+
+	int countAllItems();
 	
 	void initItems();
 
 	int checkItemCollision(int x, int y);
 
+	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 itemDropDown(int startX, int startY, int dstX, int dstY, int itemSlot, uint16 item, int remove);
+	void exchangeMouseItem(int itemPos, int runScript);
+	bool pickUpItem(int x, int y);
+
+	bool isDropable(int x, int y);
+
+	// -> hand item
 	void setMouseCursor(uint16 item);
 
-	// -> hand item
 	void setHandItem(uint16 item);
 	void removeHandItem();
 	void setItemMouseCursor();
@@ -480,6 +495,8 @@
 
 	int _malcolmsMood;
 
+	void makeCharFacingMouse();
+
 	// talk object
 	struct TalkObject {
 		char filename[13];

Modified: scummvm/trunk/engines/kyra/screen.h
===================================================================
--- scummvm/trunk/engines/kyra/screen.h	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/screen.h	2008-04-23 22:53:19 UTC (rev 31681)
@@ -201,11 +201,11 @@
 
 	void setShapePages(int page1, int page2, int minY = -1, int maxY = 201);
 
-	byte getShapeFlag1(int x, int y);
-	byte getShapeFlag2(int x, int y);
+	virtual byte getShapeFlag1(int x, int y);
+	virtual byte getShapeFlag2(int x, int y);
 
-	int getDrawLayer(int x, int y);
-	int getDrawLayer2(int x, int y, int height);
+	virtual int getDrawLayer(int x, int y);
+	virtual int getDrawLayer2(int x, int y, int height);
 
 	void blockInRegion(int x, int y, int width, int height);
 	void blockOutRegion(int x, int y, int width, int height);

Modified: scummvm/trunk/engines/kyra/screen_v3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_v3.cpp	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/screen_v3.cpp	2008-04-23 22:53:19 UTC (rev 31681)
@@ -72,4 +72,67 @@
 	return pixel;
 }
 
+byte Screen_v3::getShapeFlag1(int x, int y) {
+	debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag1(%d, %d)", x, y);
+	if (y < _maskMinY || y > _maskMaxY)
+		return 0;
+
+	uint8 color = _shapePages[0][y * SCREEN_W + x];
+	color &= 0x80;
+	color ^= 0x80;
+
+	if (color & 0x80)
+		return 1;
+	return 0;
+}
+
+byte Screen_v3::getShapeFlag2(int x, int y) {
+	debugC(9, kDebugLevelScreen, "Screen_v3::getShapeFlag2(%d, %d)", x, y);
+	if (y < _maskMinY || y > _maskMaxY)
+		return 0;
+
+	uint8 color = _shapePages[0][y * SCREEN_W + x];
+	color &= 0x7F;
+	color &= 0x87;
+	return color;
+}
+
+int Screen_v3::getDrawLayer(int x, int y) {
+	debugC(9, kDebugLevelScreen, "Screen_v3::getDrawLayer(%d, %d)", x, y);
+	int xpos = x - 8;
+	int ypos = y;
+	int layer = 1;
+
+	for (int curX = xpos; curX < xpos + 24; ++curX) {
+		int tempLayer = getShapeFlag2(curX, ypos);
+
+		if (layer < tempLayer)
+			layer = tempLayer;
+
+		if (layer >= 7)
+			return 7;
+	}
+	return layer;
+}
+
+int Screen_v3::getDrawLayer2(int x, int y, int height) {
+	debugC(9, kDebugLevelScreen, "Screen_v3::getDrawLayer2(%d, %d, %d)", x, y, height);
+	int xpos = x - 8;
+	int ypos = y;
+	int layer = 1;
+
+	for (int useX = xpos; useX < xpos + 24; ++useX) {
+		for (int useY = ypos - height; useY < ypos; ++useY) {
+			int tempLayer = getShapeFlag2(useX, useY);
+
+			if (tempLayer > layer)
+				layer = tempLayer;
+
+			if (tempLayer >= 7)
+				return 7;
+		}
+	}
+	return layer;
+}
+
 } // end of namespace Kyra

Modified: scummvm/trunk/engines/kyra/screen_v3.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_v3.h	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/screen_v3.h	2008-04-23 22:53:19 UTC (rev 31681)
@@ -41,6 +41,12 @@
 	virtual const ScreenDim *getScreenDim(int dim);
 
 	int getLayer(int x, int y);
+
+	byte getShapeFlag1(int x, int y);
+	byte getShapeFlag2(int x, int y);
+
+	int getDrawLayer(int x, int y);
+	int getDrawLayer2(int x, int y, int height);
 private:
 	static const ScreenDim _screenDimTable[];
 	static const int _screenDimTableCount;

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2008-04-23 22:11:05 UTC (rev 31680)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2008-04-23 22:53:19 UTC (rev 31681)
@@ -2336,6 +2336,12 @@
 	0xB2, 0xB2, 0xB2, 0xB2, 0xB2
 };
 
+const uint8 KyraEngine_v3::_trashItemList[] = {
+	0x1E, 0x1D, 0x1C, 0x1F, 0x0F, 0x05, 0x04, 0x00,
+	0x03, 0x22, 0x0B, 0x20, 0x21, 0x10, 0x11, 0x3A,
+	0x39, 0x40, 0x3E, 0x3D, 0x3C, 0x3F, 0xFF
+};
+
 } // End of namespace Kyra
 
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list