diff options
Diffstat (limited to 'kyra/kyra.cpp')
| -rw-r--r-- | kyra/kyra.cpp | 355 | 
1 files changed, 315 insertions, 40 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 2f864f9ec2..feee9bb32b 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -337,6 +337,10 @@ int KyraEngine::init(GameDetector &detector) {  	_movFacingTable[0] = 8;  	_configTalkspeed = 1; +	 +	_marbleVaseItem = -1; +	_mouseState = _itemInHand = -1; +	_handleInput = false;  	return 0;  } @@ -490,10 +494,6 @@ void KyraEngine::delay(uint32 amount) {  			case OSystem::EVENT_KEYDOWN:  				if (event.kbd.keycode == 'q' || event.kbd.keycode == 27) {  					_quitFlag = true; -				} else { -					++_currentRoom; -					if (_currentRoom > ARRAYSIZE(_shapes)) -						_currentRoom = 3;  				}  				break;  			case OSystem::EVENT_MOUSEMOVE: @@ -503,6 +503,15 @@ void KyraEngine::delay(uint32 amount) {  			case OSystem::EVENT_QUIT:  				quitGame();  				break; +			case OSystem::EVENT_LBUTTONDOWN: +				if (_handleInput) { +					_mouseX = event.mouse.x; +					_mouseY = event.mouse.y; +					_handleInput = false; +					processInput(_mouseX, _mouseY); +					_handleInput = true; +				} +				break;  			default:  				break;  			} @@ -526,9 +535,15 @@ void KyraEngine::mainLoop() {  	while (!_quitFlag) {  		int32 frameTime = (int32)_system->getMillis(); +		updateMousePointer();  		updateGameTimers(); +		_sprites->updateSceneAnims(); +		updateAllObjectShapes(); +		// XXX call processPalette +		_handleInput = true;  		delay((frameTime + _gameSpeed) - _system->getMillis()); +		_handleInput = false;  	}  } @@ -1223,28 +1238,37 @@ void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypo  	disableTimer(19);  	disableTimer(14);  	disableTimer(18); +	uint32 nextFrame = 0;  	switch (facing) {  		case 0:  			while (ypos < ch->y1) { +				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();  				setCharacterPositionWithUpdate(character); +				while (_system->getMillis() < nextFrame) { updateGameTimers(); }  			}  			break;  		case 2:	  			while (ch->x1 < xpos) { +				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();  				setCharacterPositionWithUpdate(character); +				while (_system->getMillis() < nextFrame) { updateGameTimers(); }  			}  			break;  		case 4:  			while (ypos > ch->y1) { +				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();  				setCharacterPositionWithUpdate(character); +				while (_system->getMillis() < nextFrame) { updateGameTimers(); }  			}  			break;  		case 6:  			while (ch->x1 > xpos) { +				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();  				setCharacterPositionWithUpdate(character); +				while (_system->getMillis() < nextFrame) { updateGameTimers(); }  			}  			break; @@ -1659,8 +1683,7 @@ void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) {  		moveCharacterToPos(0, facing, xpos2, ypos2);  	} -	// XXX _mousePointerFlag -	_scriptClick->variables[4] = -1; +	_scriptClick->variables[4] = _itemInHand;  	_scriptClick->variables[7] = brandonAlive;  	_scriptInterpreter->startScript(_scriptClick, 3);  	while (_scriptInterpreter->validScript(_scriptClick)) { @@ -2513,6 +2536,58 @@ void KyraEngine::placeItemInGenericMapScene(int item, int index) {  	}  } +void KyraEngine::createMouseItem(int item) { +	debug(9, "createMouseItem(%d)", item); +	_screen->hideMouse(); +	setMouseItem(item); +	_itemInHand = item; +	_screen->showMouse(); +} + +void KyraEngine::destroyMouseItem() { +	debug(9, "destroyMouseItem()"); +	_screen->hideMouse(); +	_screen->setMouseCursor(1, 1, _shapes[4]); +	_itemInHand = -1; +	_screen->showMouse(); +} + +void KyraEngine::setMouseItem(int item) { +	debug(9, "setMouseItem(%d)", item); +	if (item == -1) { +		_screen->setMouseCursor(1, 1, _shapes[10]); +	} else { +		_screen->setMouseCursor(8, 15, _shapes[220+item]); +	} +} + +void KyraEngine::wipeDownMouseItem(int xpos, int ypos) { +	debug(9, "wipeDownMouseItem(%d, %d)", xpos, ypos); +	if (_itemInHand == -1) +		return; +	xpos -= 8; +	ypos -= 15; +	_screen->hideMouse(); +	backUpRect1(xpos, ypos); +	int y = ypos; +	int height = 16; +	 +	while (height >= 0) { +		restoreRect1(xpos, ypos); +		_screen->setNewShapeHeight(_shapes[220+_itemInHand], height); +		_screen->drawShape(0, _shapes[220+_itemInHand], xpos, y, 0, 0); +		_screen->updateScreen(); +		y += 2; +		height -= 2; +		// XXX +		waitTicks(1); +	}	 +	restoreRect1(xpos, ypos); +	_screen->resetShapeHeight(_shapes[220+_itemInHand]); +	destroyMouseItem(); +	_screen->showMouse(); +} +  #pragma mark -  #pragma mark - Animation specific code  #pragma mark - @@ -2634,14 +2709,13 @@ void KyraEngine::prepDrawAllObjects() {  			int xpos = curObject->x1;  			int ypos = curObject->y1; -			int temp = 0; -			if (curObject->flags & 0x800) { -				temp = 7; -			} else if (!curObject->unk1) { -				temp = 0; +			int drawLayer = 0; +			if (!(curObject->flags & 0x800)) { +				drawLayer = 7; +			} else if (curObject->unk1) { +				drawLayer = 0;  			} else { -				// XXX temp = sub_13368(curObject->drawY) -				temp = 0; +				drawLayer = _sprites->getDrawLayer(curObject->drawY);  			}  			// talking head functionallity @@ -2714,7 +2788,7 @@ void KyraEngine::prepDrawAllObjects() {  									tempFlags = 1;  								}  								tempFlags |= 0x900 | flagUnk1 | 0x4000; -								_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, 0/*XXX*/, temp, _brandonScaleX, _brandonScaleY); +								_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, 0/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);  							} else {  								if (!(flagUnk2 & 0x4000)) {  									tempFlags = 0; @@ -2724,7 +2798,7 @@ void KyraEngine::prepDrawAllObjects() {  									tempFlags |= 0x900 | flagUnk1;  								} -								_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, temp, _brandonScaleX, _brandonScaleY); +								_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, drawLayer, _brandonScaleX, _brandonScaleY);  							}  						}  					} else { @@ -2733,7 +2807,7 @@ void KyraEngine::prepDrawAllObjects() {  							if (curObject->flags & 1) {  								tempFlags = 1;  							} -							_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 0x800, temp); 							 +							_screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer); 							  						}  					}  				} @@ -2756,30 +2830,30 @@ void KyraEngine::prepDrawAllObjects() {  				if (!_scaleMode) {  					if (flagUnk3 & 0x100) { -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_unkBrandonPoisonFlags, 1, temp); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_unkBrandonPoisonFlags, 1, drawLayer);  					} else if (flagUnk3 & 0x4000) {  						// XXX  						int hackVar = 0; -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, hackVar, 0); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, hackVar, drawLayer);  					} else { -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, temp); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer);  					}  				} else {  					if (flagUnk3 & 0x100) { -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_unkBrandonPoisonFlags, 1, temp, _brandonScaleX, _brandonScaleY); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_unkBrandonPoisonFlags, 1, drawLayer, _brandonScaleX, _brandonScaleY);  					} else if (flagUnk3 & 0x4000) {  						// XXX  						int hackVar = 0; -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, 0, temp, hackVar, _brandonScaleX, _brandonScaleY); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, 0, drawLayer, hackVar, _brandonScaleX, _brandonScaleY);  					} else { -						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, temp, _brandonScaleX, _brandonScaleY); +						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY);  					}  				}  			} else {  				if (curObject->index >= 16 && curObject->index <= 27) { -					_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, temp, (int)_scaleTable[curObject->drawY], (int)_scaleTable[curObject->drawY]); +					_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_scaleTable[curObject->drawY], (int)_scaleTable[curObject->drawY]);  				} else { -					_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, temp); +					_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer);  				}  			}  		} @@ -2976,6 +3050,16 @@ int8 KyraEngine::fetchAnimHeight(const uint8 *shape, int8 mult) {  	return ((int8)*(shape+2)) * mult;  } +void KyraEngine::backUpRect1(int xpos, int ypos) { +	debug(9, "backUpRect1(%d, %d)", xpos, ypos); +	_screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _shapes[1]); +} + +void KyraEngine::restoreRect1(int xpos, int ypos) { +	debug(9, "restoreRect1(%d, %d)", xpos, ypos); +	_screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _shapes[1]); +} +  #pragma mark -  #pragma mark - Pathfinder  #pragma mark - @@ -3272,6 +3356,7 @@ bool KyraEngine::lineIsPassable(int x, int y) {  }  int KyraEngine::getMoveTableSize(int *moveTable) { +	debug(9, "getMoveTableSize(0x%X)", moveTable);  	int retValue = 0;  	if (moveTable[0] == 8)  		return 0; @@ -3295,7 +3380,7 @@ int KyraEngine::getMoveTableSize(int *moveTable) {  	int *curPosition = &moveTable[1];  	while (*curPosition != 8) { -		if (*curPosition == facingTable[*oldPosition]) { +		if (*oldPosition == facingTable[*curPosition]) {  			retValue -= 2;  			*oldPosition = 9;  			*curPosition = 9; @@ -3307,7 +3392,7 @@ int KyraEngine::getMoveTableSize(int *moveTable) {  			}  			if (tempPosition == moveTable && *tempPosition == 9) { -				while (*tempPosition == 8 || *tempPosition != 9) { +				while (*tempPosition != 8 && *tempPosition == 9) {  					++tempPosition;  				}  				if (*tempPosition == 8) { @@ -3315,14 +3400,17 @@ int KyraEngine::getMoveTableSize(int *moveTable) {  				}  			} -			while (*curPosition == 8 || *curPosition != 9) { +			oldPosition = tempPosition; +			curPosition = oldPosition+1; +			while (*curPosition != 8 && *curPosition == 9) {  				++curPosition;  			} +			continue;  		} -		if (unkTable[*curPosition+(*oldPosition*8)] != -1) { +		if (unkTable[*curPosition+((*oldPosition)*8)] != -1) {  			--retValue; -			*oldPosition = unkTable[*curPosition+(*oldPosition*8)]; +			*oldPosition = unkTable[*curPosition+((*oldPosition)*8)];  			*curPosition = 9;  			if (tempPosition != oldPosition) { @@ -3427,6 +3515,7 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {  	_loopFlag2 = 0;  	bool running = true;  	int returnValue = 0; +	uint32 nextFrame;  	while (running) {  		// XXX  		bool forceContinue = false; @@ -3455,6 +3544,7 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {  		if (unk1) {  			// XXX +			_sceneChangeState = 1;  		}  		if (forceContinue || !running) { @@ -3467,19 +3557,25 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {  		} else {  			temp = setCharacterPosition(0, table);  		} -		if (!temp) +		if (!temp) {  			continue; +		} +		  		++table; -		_sprites->updateSceneAnims(); -		waitTicks(10); -		// XXX updateMousePointer -		updateGameTimers(); -		updateAllObjectShapes(); -		// XXX processPalette -		if (_currentCharacter->sceneId == 210) { -			// XXX updateKyragemFading -			// XXX playEnd -			// XXX +		nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis(); +		while (_system->getMillis() < nextFrame) { +			_sprites->updateSceneAnims(); +			updateMousePointer(); +			updateGameTimers(); +			updateAllObjectShapes(); +			// XXX processPalette +			if (_currentCharacter->sceneId == 210) { +				// XXX updateKyragemFading +				// XXX playEnd +				// XXX +			} +			if ((nextFrame - _system->getMillis()) >= 10) +				delay(10);  		}  	} @@ -3664,7 +3760,17 @@ void KyraEngine::setupTimers() {  	_timers[31].countdown = -1;  	_timers[32].countdown = 9;  	_timers[33].countdown = 3; +} +void KyraEngine::setTimer19() { +	debug(9, "KyraEngine::setTimer19()"); +	if (_brandonStatusBit & 2) { +		// XXX call sub_3F9C +		setTimerCountdown(19, 300); +	} else if (_brandonStatusBit & 0x20) { +		// XXX call sub_4110 +		setTimerCountdown(19, 300); +	}  }  void KyraEngine::updateGameTimers() { @@ -3833,4 +3939,173 @@ void KyraEngine::drawAmulet() {  	_screen->showMouse();  } +#pragma mark - +#pragma mark - Input +#pragma mark - + +void KyraEngine::processInput(int xpos, int ypos) { +	debug(9, "processInput(%d, %d)", xpos, ypos); +	if (processInputHelper(xpos, ypos)) { +		return; +	} +	uint8 item = findItemAtPos(xpos, ypos); +	if (item == 0xFF) { +		if (clickEventHandler(xpos, ypos)) +			return; +	}  +	 +	// XXX _deathHandler specific +	if (ypos <= 158) { +		uint16 exit = 0xFFFF; +		if (xpos < 12) { +			exit = _walkBlockWest; +		} else if (xpos >= 308) { +			exit = _walkBlockEast; +		} else if (ypos >= 136) { +			exit = _walkBlockSouth; +		} else if (ypos < 12) { +			exit = _walkBlockNorth; +		} +		 +		if (exit != 0xFFFF) { +			handleSceneChange(xpos, ypos, 1, 1); +			return; +		} +	} +	 +	 +} + +int KyraEngine::processInputHelper(int xpos, int ypos) { +	debug(9, "processInputHelper(%d, %d)", xpos, ypos); +	return 0; +} + +int KyraEngine::clickEventHandler(int xpos, int ypos) { +	debug(9, "clickEventHandler(%d, %d)", xpos, ypos); +	_scriptInterpreter->initScript(_scriptClick, _scriptClickData); +	_scriptClick->variables[1] = xpos; +	_scriptClick->variables[2] = ypos; +	_scriptClick->variables[3] = 0; +	_scriptClick->variables[4] = _itemInHand; +	_scriptInterpreter->startScript(_scriptClick, 1); +	 +	while (_scriptInterpreter->validScript(_scriptClick)) { +		_scriptInterpreter->runScript(_scriptClick); +	} +	return _scriptClick->variables[3]; +} + +void KyraEngine::updateMousePointer() { +	int shape = 0; +	 +	int newMouseState = 0; +	int newX = 0; // si +	int newY = 0; // bx +	if (_mouseY <= 158) { +		if (_mouseX >= 12) { +			if (_mouseX >= 308) { +				if (_walkBlockEast == 0xFFFF) { +					newMouseState = -2; +				} else { +					newMouseState = -5; +					shape = 3; +					newX = 7; +					newY = 5; +				} +			} else if (_mouseY >= 136) { +				if (_walkBlockSouth == 0xFFFF) { +					newMouseState = -2; +				} else { +					newMouseState = -4; +					shape = 4; +					newX = 5; +					newY = 7; +				} +			} else if (_mouseY < 12) { +				if (_walkBlockNorth == 0xFFFF) { +					newMouseState = -2; +				} else { +					newMouseState = -6; +					shape = 2; +					newX = 5; +					newY = 1; +				} +			} +		} else { +			if (_walkBlockWest == 0xFFFF) { +				newMouseState = -2; +			} else { +				newMouseState = -3; +				newX = 1; +				newY = shape = 5; +			} +		} +	} +	 +	if (_mouseX >= _entranceMouseCursorTracks[0] && _mouseY >= _entranceMouseCursorTracks[1] +		&& _mouseX <= _entranceMouseCursorTracks[2] && _mouseY <= _entranceMouseCursorTracks[3]) { +		switch (_entranceMouseCursorTracks[4]) { +			case 0: +				newMouseState = -6; +				shape = 2; +				newX = 5; +				newY = 1; +				break; +			 +			case 2: +				newMouseState = -5; +				shape = 3; +				newX = 7; +				newY = 5; +				break; +			 +			case 4: +				newMouseState = -4; +				shape = 4; +				newX = 5; +				newY = 7; +				break; +			 +			case 6: +				newMouseState = -3; +				shape = 5; +				newX = 1; +				newY = 5; +				break; +			 +			default: +				break; +		} +	} +	 +	if (newMouseState == -2) { +		shape = 6; +		newX = 4; +		newY = 4; +	} +	 +	if (newMouseState && _mouseState != newMouseState) { +		_mouseState = newMouseState; +		_screen->hideMouse(); +		_screen->setMouseCursor(newX, newY, _shapes[4+shape]); +		_screen->showMouse(); +	} +	 +	if (!newMouseState) { +		if (_mouseState != _itemInHand) { +			if (_mouseY > 158 || (_mouseX >= 12 && _mouseX < 308 && _mouseY < 136 && _mouseY >= 12)) { +				_mouseState = _itemInHand; +				_screen->hideMouse(); +				if (_itemInHand == -1) { +					_screen->setMouseCursor(1, 1, _shapes[4]); +				} else { +					_screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]); +				} +				_screen->showMouse(); +			} +		} +	} +} +  } // End of namespace Kyra  | 
