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

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Tue Mar 3 23:32:40 CET 2009


Revision: 39097
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39097&view=rev
Author:   athrxx
Date:     2009-03-03 22:32:39 +0000 (Tue, 03 Mar 2009)

Log Message:
-----------
LOL: implemented some walking code for the monsters

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/gui_lol.cpp
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/scene_lol.cpp
    scummvm/trunk/engines/kyra/script_lol.cpp
    scummvm/trunk/engines/kyra/sprites_lol.cpp
    scummvm/trunk/engines/kyra/timer_lol.cpp

Modified: scummvm/trunk/engines/kyra/gui_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/gui_lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -1084,7 +1084,7 @@
 }
 
 int LoLEngine::clickedPortraitLeft(Button *button) {
-	removeUnkFlags(2);
+	disableSysTimer(2);
 
 	if (!_weaponsDisabled) {
 		_screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
@@ -1184,7 +1184,7 @@
 
 	_lastCharInventory = -1;
 	updateSceneWindow();
-	setUnkFlags(2);
+	enableSysTimer(2);
 	
 	return 1;
 }

Modified: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -33,6 +33,7 @@
 #include "sound/voc.h"
 #include "sound/audiostream.h"
 
+#include "common/config-manager.h"
 #include "common/endian.h"
 #include "base/version.h"
 
@@ -147,6 +148,8 @@
 	_monsters = 0;
 	_unkGameFlag = 0;
 	_lastMouseRegion = 0;
+	_monsterUnkDir = _monsterCountUnk = _monsterShiftAlt = 0;
+	_monsterCurBlock = 0;
 	//_preSeq_X1 = _preSeq_Y1 = _preSeq_X2 = _preSeq_Y2 = 0;
 
 	_dscUnk1 = 0;
@@ -174,12 +177,12 @@
 	_curMusicTheme = -1;
 	_curMusicFileExt = 0;
 	_curMusicFileIndex = -1;
+	_environmentSfx = _environmentSfxVol = _environmentSfxDistThreshold = 0;
 
 	_sceneDrawVar1 = _sceneDrawVar2 = _sceneDrawVar3 = _wllProcessFlag = 0;
 	_partyPosX = _partyPosY = 0;
 	_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
 
-	_intFlag3 = 3;
 	_floatingMouseArrowControl = 0;
 
 	memset(_activeTim, 0, 10 * sizeof(TIM*));
@@ -335,6 +338,8 @@
 	KyraEngine_v1::init();
 	initStaticResource();
 
+	_environmentSfxDistThreshold = (MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB) == MD_ADLIB || ConfMan.getBool("multi_midi")) ? 15 : 3;
+
 	_gui = new GUI_LoL(this);
 	assert(_gui);
 
@@ -506,7 +511,7 @@
 	if (!shouldQuit() && (processSelection == 0 || processSelection == 3)) {
 		_screen->_fadeFlag = 3;
 		_sceneUpdateRequired = true;
-		setUnkFlags(1);
+		enableSysTimer(1);
 		runLoop();
 	}
 
@@ -746,28 +751,18 @@
 	_screen->showMouse();
 }
 
-int LoLEngine::setUnkFlags(int unk) {
-	if (unk < 1 || unk > 14)
-		return 0;
-
-	int r = (_intFlag3 & (2 << unk)) ? 1 : 0;
-	_intFlag3 |= (2 << unk);
-
-	return r;
+void LoLEngine::enableSysTimer(int sysTimer) {
+	if (sysTimer == 2)
+		_timer->pause(false);
 }
 
-int LoLEngine::removeUnkFlags(int unk) {
-	if (unk < 1 || unk > 14)
-		return 0;
-
-	int r = (_intFlag3 & (2 << unk)) ? 1 : 0;
-	_intFlag3 &= ~(2 << unk);
-
-	return r;
+void LoLEngine::disableSysTimer(int sysTimer) {
+	if (sysTimer == 2)
+		_timer->pause(true);
 }
 
 void LoLEngine::runLoop() {
-	setUnkFlags(2);
+	enableSysTimer(2);
 
 	bool _runFlag = true;
 	_unkFlag |= 0x800;
@@ -788,7 +783,7 @@
 		if (_sceneUpdateRequired)
 			gui_drawScene(0);
 		else
-			runLoopSub4(0);
+			updateEnvironmentalSfx(0);
 
 		/*if (_partyDeathFlag != -1) {
 			checkForPartyDeath(_partyDeathFlag);
@@ -1179,7 +1174,7 @@
 	if (!textEnabled() || (!(_hideControls & 2)))
 		timerUpdatePortraitAnimations(1);
 
-	removeUnkFlags(2);		
+	disableSysTimer(2);		
 }
 
 void LoLEngine::fadeText() {
@@ -1331,6 +1326,7 @@
 		volume = -volIndex;
 
 	// volume TODO
+	volume = 254 - volume;
 
 	int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]);
 	if (vocIndex != -1) {
@@ -1340,8 +1336,6 @@
 			track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1;
 		else if (_sound->getSfxType() == Sound::kMidiGM)
 			track = track < _ingameGMSoundIndexSize ? _ingameGMSoundIndex[track] - 1: -1;
-		//else if (_sound->getSfxType() == Sound::kAdlib)
-		//	track = track < _ingameADLSoundIndexSize ? _ingameADLSoundIndex[track] - 1: -1;
 
 		if (track == 168)
 			track = 167;
@@ -1351,6 +1345,45 @@
 	}
 }
 
+void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
+	if (!(_unkGameFlag & 1))
+		return;
+
+	if (_environmentSfx)
+		snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
+
+	int dist = 0;
+	if (block) {
+		dist = getMonsterDistance(_currentBlock, block);
+		if (dist > _environmentSfxDistThreshold) {
+			_environmentSfx = 0;
+			return;
+		}
+	}
+
+	_environmentSfx = soundId;
+	_environmentSfxVol = (15 - ((block || dist < 2) ? dist : 0)) << 4;
+
+	if (block != _currentBlock) {
+		static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 };
+		uint16 cbl = _currentBlock;
+		
+		for (int i = 3; i > 0; i--) {
+			int dir = calcMonsterDirection(cbl & 0x1f, cbl >> 5, block & 0x1f, block >> 5);
+			cbl += blockShiftTable[dir];
+			if (cbl != block) {
+				if (testWallFlag(cbl, 0, 1))
+					_environmentSfxVol >>= 1;
+			}
+		}
+	}
+
+	if (!soundId || _sceneUpdateRequired)
+		return;
+
+	snd_processEnvironmentalSoundEffect(0, 0);
+}
+
 void LoLEngine::snd_loadSoundFile(int track) {
 	if (_unkGameFlag & 2) {
 		char filename[13];
@@ -1501,13 +1534,6 @@
 	return 1;
 }
 
-void LoLEngine::cmzS7(int a, int block) {
-	if (!(_unkGameFlag & 1))
-		return;
-
-	// TODO
-}
-
 void LoLEngine::giveItemToMonster(MonsterInPlay *monster, uint16 item) {
 	uint16 *c = &monster->assignedItems;	
 	while (*c)
@@ -1529,8 +1555,8 @@
 	}
 }
 
-void LoLEngine::runLoopSub4(int a) {
-	cmzS7(a, _currentBlock);
+void LoLEngine::updateEnvironmentalSfx(int soundId) {
+	snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
 }
 
 bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) {

Modified: scummvm/trunk/engines/kyra/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/lol.h	2009-03-03 22:32:39 UTC (rev 39097)
@@ -115,7 +115,7 @@
 	uint16 unk5;
 	uint16 unk6[5];
 	uint8 unk7[4];
-	uint8 unk8[3];
+	uint8 sounds[3];
 };
 
 struct MonsterInPlay {
@@ -126,9 +126,9 @@
 	uint16 x;
 	uint16 y;
 	int8 level;
-	uint16 itemPosX;
-	uint16 itemPosY;
-	uint8 field10;
+	uint16 destX;
+	uint16 destY;
+	uint8 destDirection;
 	uint8 anon8;
 	uint8 anonh;
 	uint8 anon9;
@@ -136,7 +136,7 @@
 	uint8 mode;
 	uint8 field_15;
 	uint8 id;
-	uint8 field_17;
+	uint8 direction;
 	uint8 facing;
 	uint16 flags;
 	uint8 field_1B;
@@ -162,7 +162,7 @@
 	int8 level;
 	uint16 itemPropertyIndex;
 	uint16 shpCurFrame_flg;
-	uint8 field10;
+	uint8 destDirection;
 	uint8 anon8;
 	uint8 anonh;
 	uint8 anon9;
@@ -241,12 +241,8 @@
 	// main loop
 	void runLoop();
 	void update();
+	void updateEnvironmentalSfx(int soundId);
 
-	int setUnkFlags(int unk);
-	int removeUnkFlags(int unk);
-
-	int _intFlag3;
-
 	// mouse
 	void setMouseCursorToIcon(int icon);
 	void setMouseCursorToItemInHand();
@@ -325,6 +321,7 @@
 	int snd_characterSpeaking();
 	void snd_stopSpeech(bool setFlag);
 	void snd_playSoundEffect(int track, int volume);
+	void snd_processEnvironmentalSoundEffect(int soundId, int block);
 	void snd_loadSoundFile(int track);
 	int snd_playTrack(int track);
 	int snd_stopMusic();
@@ -336,6 +333,9 @@
 	int _lastMusicTrack;
 	int _curMusicFileIndex;
 	char _curMusicFileExt;
+	int _environmentSfx;
+	int _environmentSfxVol;
+	int _environmentSfxDistThreshold;
 
 	int _curTlkFile;
 	int _speechFlag;
@@ -517,7 +517,7 @@
 	int olol_resetBlockShapeAssignment(EMCState *script);
 	int olol_initMonster(EMCState *script);
 	int olol_loadMonsterProperties(EMCState *script);
-	int olol_68(EMCState *script);
+	int olol_moveMonster(EMCState *script);
 	int olol_setScriptTimer(EMCState *script);
 	int olol_loadTimScript(EMCState *script);
 	int olol_runTimScript(EMCState *script);
@@ -538,7 +538,7 @@
 	int olol_setDoorState(EMCState *script);
 	int olol_assignCustomSfx(EMCState *script);
 	int olol_resetPortraitsArea(EMCState *script);
-	int olol_setUnkFlags(EMCState *script);
+	int olol_enableSysTimer(EMCState *script);
 
 	// tim scripts
 	TIM *_activeTim[10];
@@ -907,17 +907,16 @@
 	int placeMonstersUnk(int block);
 	void setMonsterMode(MonsterInPlay *monster, int a);
 	void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
-	int cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
-	void cmzS2(MonsterInPlay *monster, int a);
+	int calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+	void setMonsterDirection(MonsterInPlay *monster, int dir);
 	void cmzS3(MonsterInPlay *monster);
 	void removeItemOrMonsterFromBlock(uint16 *blockItemIndex, int id);
 	void assignItemOrMonsterToBlock(uint16 *blockItemIndex, int id);
-	void cmzS7(int a, int block);
-	void giveItemToMonster(MonsterInPlay *monster, uint16 a);
-	int checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int p1, int p2);
+	void giveItemToMonster(MonsterInPlay *monster, uint16 item);
+	int checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int testFlag, int wallFlag);
 	int calcMonsterSkillLevel(int id, int a);
-	int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int p1, int p2);
-	bool checkBlockOccupiedByParty(int x, int y, int p1);
+	int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int testFlag, int wallFlag);
+	bool checkBlockOccupiedByParty(int x, int y, int testFlag);
 	const uint16 *getCharacterOrMonsterStats(int id);
 	void drawMonstersAndItems(int block);	
 	void drawMonster(uint16 id);
@@ -932,7 +931,12 @@
 	
 	void updateMonster(MonsterInPlay *monster);
 	void moveMonster(MonsterInPlay *monster);
-	void shiftMonster(MonsterInPlay *monster);
+	void walkMonster(MonsterInPlay *monster);
+	int walkMonsterCalcNextStep(MonsterInPlay *monster);
+	int getMonsterDistance(uint16 block1, uint16 block2);
+	int walkMonster_s3(uint16 monsterBlock, int unk1, int unk2, uint16 curBlock);
+	int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
+	void walkMonsterGetNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 unk);
 
 	MonsterInPlay *_monsters;
 	MonsterProperty *_monsterProperties;
@@ -940,6 +944,10 @@
 	uint8 **_monsterPalettes;
 	uint8 **_monsterShapesEx;
 	uint8 _monsterUnk[3];
+	uint16 _monsterCurBlock;
+	int _monsterUnkDir;
+	int _monsterCountUnk;
+	int _monsterShiftAlt;
 
 	const uint16 *_monsterModifiers;
 	int _monsterModifiersSize;
@@ -956,7 +964,8 @@
 
 	// misc
 	void delay(uint32 millis, bool cUpdate = false, bool isMainLoop = false);
-	void runLoopSub4(int a);
+	void enableSysTimer(int sysTimer);
+	void disableSysTimer(int sysTimer);
 
 	uint8 *_pageBuffer1;
 	uint8 *_pageBuffer2;

Modified: scummvm/trunk/engines/kyra/scene_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/scene_lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -1066,7 +1066,7 @@
 		SWAP(_sceneDrawPage1, _sceneDrawPage2);
 	}
 
-	runLoopSub4(0);
+	updateEnvironmentalSfx(0);
 	gui_drawCompass();
 
 	_sceneUpdateRequired = false;

Modified: scummvm/trunk/engines/kyra/script_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/script_lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -489,9 +489,9 @@
 		if (b == 1) {
 			if (!textEnabled() || (!(_hideControls & 2)))
 				timerUpdatePortraitAnimations(1);
-			removeUnkFlags(2);
+			disableSysTimer(2);
 		} else {
-			setUnkFlags(2);
+			enableSysTimer(2);
 		}
 		break;
 
@@ -553,7 +553,7 @@
 		l->facing = stackPos(3);
 		l->type = stackPos(4);
 		l->properties = &_monsterProperties[l->type];
-		l->field_17 = l->facing << 1;
+		l->direction = l->facing << 1;
 		l->might = (l->properties->might * _monsterModifiers[((_unkGameFlag & 0x30) >> 4)]) >> 8;
 
 		if (_currentLevel == 12 && l->type == 2)
@@ -568,9 +568,9 @@
 		setMonsterMode(l, stackPos(6));
 		placeMonster(l, l->x, l->y);
 
-		l->itemPosX = l->x;
-		l->itemPosY = l->y;
-		l->field10 = l->field_17;
+		l->destX = l->x;
+		l->destY = l->y;
+		l->destDirection = l->direction;
 
 		for (int ii = 0; ii < 4; ii++)
 			l->field_2A[ii] = stackPos(7 + ii);
@@ -638,21 +638,21 @@
 	}
 
 	for (int i = 0; i < 3; i++)
-		l->unk8[i] = stackPos(39 + i);
+		l->sounds[i] = stackPos(39 + i);
 
 	return 1;
 }
 
-int LoLEngine::olol_68(EMCState *script) {
-
+int LoLEngine::olol_moveMonster(EMCState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
 	MonsterInPlay *m = &_monsters[stackPos(0)];
 	
 	if (m->mode == 1 || m->mode == 2) {
-		calcCoordinates(m->itemPosX, m->itemPosY, stackPos(1), stackPos(2), stackPos(3));
-		m->field10 = stackPos(4);
+		calcCoordinates(m->destX, m->destY, stackPos(1), stackPos(2), stackPos(3));
+		m->destDirection = stackPos(4) << 1;
 
-		if (m->x != m->itemPosX || m->y != m->itemPosY)
-			cmzS2(m, cmzS1(m->x, m->y, m->itemPosX, m->itemPosY));
+		if (m->x != m->destX || m->y != m->destY)
+			setMonsterDirection(m, calcMonsterDirection(m->x, m->y, m->destX, m->destY));
 	}
 
 	return 1;
@@ -810,10 +810,11 @@
 	if (!c || i > 250)
 		return 0;
 
-	if (_ingameSoundIndex[i] == 0xffff)
+	uint16 t = READ_LE_UINT16(&_ingameSoundIndex[i << 1]);
+	if (t == 0xffff)
 		return 0;
 
-	strcpy(_ingameSoundList[_ingameSoundIndex[i]], c);
+	strcpy(_ingameSoundList[t], c);
 
 	return 0;
 }
@@ -823,9 +824,9 @@
 	return 1;
 }
 
-int LoLEngine::olol_setUnkFlags(EMCState *script) {
+int LoLEngine::olol_enableSysTimer(EMCState *script) {
 	_hideInventory = 0;
-	setUnkFlags(2);
+	enableSysTimer(2);
 	return 1;
 }
 
@@ -891,7 +892,7 @@
 
 int LoLEngine::tlol_initDialogueSequence(const TIM *tim, const uint16 *param) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_initDialogueSequence(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
-	this->initDialogueSequence(param[0]);
+	initDialogueSequence(param[0]);
 	return 1;
 }
 
@@ -1077,7 +1078,7 @@
 	OpcodeUnImpl();
 
 	// 0x44
-	Opcode(olol_68);
+	Opcode(olol_moveMonster);
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	OpcodeUnImpl();
@@ -1206,7 +1207,7 @@
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	Opcode(olol_resetPortraitsArea);
-	Opcode(olol_setUnkFlags);
+	Opcode(olol_enableSysTimer);
 
 	// 0x9C
 	OpcodeUnImpl();

Modified: scummvm/trunk/engines/kyra/sprites_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sprites_lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/sprites_lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -161,8 +161,8 @@
 	if (monster->mode == 13 && mode != 14)
 		return;
 	if (mode == 7) {
-		monster->itemPosX = _partyPosX;
-		monster->itemPosY = _partyPosX;
+		monster->destX = _partyPosX;
+		monster->destY = _partyPosX;
 	}
 
 	if (monster->mode == 1 && mode == 7) {
@@ -171,9 +171,9 @@
 				continue;
 			monster->mode = mode;
 			monster->field_15 = 0;
-			monster->itemPosX = _partyPosX;
-			monster->itemPosY = _partyPosY;
-			cmzS2(monster, cmzS1(monster->x, monster->y, monster->itemPosX, monster->itemPosY));
+			monster->destX = _partyPosX;
+			monster->destY = _partyPosY;
+			setMonsterDirection(monster, calcMonsterDirection(monster->x, monster->y, monster->destX, monster->destY));
 		}
 	} else {
 		monster->mode = mode;
@@ -197,9 +197,9 @@
 	bool cont = true;
 	int t = monster->blockPropertyIndex;
 	if (monster->blockPropertyIndex) {
-		removeItemOrMonsterFromBlock(&_levelBlockProperties[monster->blockPropertyIndex].itemMonsterIndex, ((uint16)monster->id) | 0x8000);
-		_levelBlockProperties[monster->blockPropertyIndex].direction = 5;
-		checkSceneUpdateNeed(monster->blockPropertyIndex);
+		removeItemOrMonsterFromBlock(&_levelBlockProperties[t].itemMonsterIndex, ((uint16)monster->id) | 0x8000);
+		_levelBlockProperties[t].direction = 5;
+		checkSceneUpdateNeed(t);
 	} else {
 		cont = false;
 	}
@@ -219,7 +219,7 @@
 	_levelBlockProperties[monster->blockPropertyIndex].direction = 5;
 	checkSceneUpdateNeed(monster->blockPropertyIndex);
 
-	if (monster->properties->unk8[0] == 0 || cont == false)
+	if (monster->properties->sounds[0] == 0 || cont == false)
 		return;
 
 	if ((!(monster->properties->flags & 0x100) || ((monster->anon9 & 1) == 0)) && monster->blockPropertyIndex == t)
@@ -231,10 +231,10 @@
 	if (_updateFlags & 1)
 		return;
 
-	cmzS7(monster->properties->unk3[5], monster->blockPropertyIndex);
+	snd_processEnvironmentalSoundEffect(monster->properties->sounds[0], monster->blockPropertyIndex);
 }
 
-int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
 	int16 r = 0;
 	int16 t1 = y1 - y2;
 	if (t1 < 0) {
@@ -251,11 +251,11 @@
 		t2 = -t2;
 	}
 
-	uint8 f = 0;
+	uint8 f = 1;
 
 	if (t2 >= t1) {
 		if (t2 > t1)
-			f = 1;
+			f = 0;
 		SWAP(t1, t2);
 	}
 
@@ -263,19 +263,18 @@
 
 	t1 = (t1 + 1) >> 1;
 
-	f = 0;
-	f = (t2 > t1) ? 1 : 0;
+	f = (t1 > t2) ? 1 : 0;
 	r = (r << 1) | f;
 
 	static const uint8 retVal[] = { 1, 2, 1, 0, 7, 6, 7, 0, 3, 2, 3, 4, 5, 6, 5, 4};
 	return retVal[r];
 }
 
-void LoLEngine::cmzS2(MonsterInPlay *monster, int a) {
-	monster->field_17 = a;
+void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
+	monster->direction = dir;
 
-	if (!(a & 1) || ((monster->field_17 - (monster->facing << 1)) < 2))
-		monster->facing = monster->field_17 >> 1;
+	if (!(dir & 1) || ((monster->direction - (monster->facing << 1)) >= 2))
+		monster->facing = monster->direction >> 1;
 
 	checkSceneUpdateNeed(monster->blockPropertyIndex);
 }
@@ -288,7 +287,7 @@
 	while (*blockItemIndex) {
 		if (*blockItemIndex == id) {
 			ItemInPlay *t = findItem(id);
-			blockItemIndex = &t->next;
+			*blockItemIndex = t->next;
 			t->next = 0;
 			return;
 		} else {
@@ -304,33 +303,33 @@
 	*blockItemIndex = id;
 }
 
-int LoLEngine::checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int p1, int p2) {
-	int monsterUnk_ = 0;
+int LoLEngine::checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int testFlag, int wallFlag) {
+	_monsterUnkDir = 0;
 	int x2 = 0;
 	int y2 = 0;
 	int xOffs = 0;
 	int yOffs = 0;
 	int flag = 0;
 	
-	int r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y), x, y, monsterWidth, p1, p2);
+	int r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y), x, y, monsterWidth, testFlag, wallFlag);
 	if (r)
 		return r;
 
-	r = checkBlockOccupiedByParty(x, y, p1);
+	r = checkBlockOccupiedByParty(x, y, testFlag);
 	if (r)
 		return 4;
 
 	if (x & 0x80) {
 		if (((x & 0xff) + monsterWidth) & 0xff00) {
 			xOffs = 1;
-			monsterUnk_ = 2;
+			_monsterUnkDir = 2;
 			x2 = x + monsterWidth;
 
-			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, p1, p2);
+			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, testFlag, wallFlag);
 			if (r)
 				return r;
 
-			r = checkBlockOccupiedByParty(x + xOffs, y, p1);
+			r = checkBlockOccupiedByParty(x + xOffs, y, testFlag);
 			if (r)
 				return 4;
 
@@ -339,14 +338,14 @@
 	} else {
 		if (((x & 0xff) - monsterWidth) & 0xff00) {
 			xOffs = -1;
-			monsterUnk_ = 6;
+			_monsterUnkDir = 6;
 			x2 = x - monsterWidth;
 
-			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, p1, p2);
+			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, testFlag, wallFlag);
 			if (r)
 				return r;
 
-			r = checkBlockOccupiedByParty(x + xOffs, y, p1);
+			r = checkBlockOccupiedByParty(x + xOffs, y, testFlag);
 			if (r)
 				return 4;
 
@@ -357,14 +356,14 @@
 	if (y & 0x80) {
 		if (((y & 0xff) + monsterWidth) & 0xff00) {
 			yOffs = 1;
-			monsterUnk_ = 4;
+			_monsterUnkDir = 4;
 			y2 = y + monsterWidth;
 
-			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, p1, p2);
+			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, testFlag, wallFlag);
 			if (r)
 				return r;
 
-			r = checkBlockOccupiedByParty(x, y + yOffs, p1);
+			r = checkBlockOccupiedByParty(x, y + yOffs, testFlag);
 			if (r)
 				return 4;
 		} else {
@@ -373,14 +372,14 @@
 	} else {
 		if (((y & 0xff) - monsterWidth) & 0xff00) {
 			yOffs = -1;
-			monsterUnk_ = 0;
+			_monsterUnkDir = 0;
 			y2 = y - monsterWidth;
 
-			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, p1, p2);
+			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, testFlag, wallFlag);
 			if (r)
 				return r;
 
-			r = checkBlockOccupiedByParty(x, y + yOffs, p1);
+			r = checkBlockOccupiedByParty(x, y + yOffs, testFlag);
 			if (r)
 				return 4;
 		} else {
@@ -391,11 +390,11 @@
 	if (!flag)
 		return 0;
 
-	r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y2), x, y, monsterWidth, p1, p2);
+	r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y2), x, y, monsterWidth, testFlag, wallFlag);
 	if (r)
 		return r;
 
-	r = checkBlockOccupiedByParty(x + xOffs, y + yOffs, p1);
+	r = checkBlockOccupiedByParty(x + xOffs, y + yOffs, testFlag);
 	if (r)
 		return 4;
 
@@ -419,21 +418,19 @@
 	return (r- (r >> 1));
 }
 
-int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int p1, int p2) {
+int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int testFlag, int wallFlag) {
 	if (block == _currentBlock)
-		p1 &= 0xfffe;
+		testFlag &= 0xfffe;
 
-	int _monsterBlock = 0;
-
-	if (p1 & 1) {
-		_monsterBlock = block;
-		if (testWallFlag(block, -1, p2))
+	if (testFlag & 1) {
+		_monsterCurBlock = block;
+		if (testWallFlag(block, -1, wallFlag))
 			return 1;
 	}
 
-	_monsterBlock = 0;
+	_monsterCurBlock = 0;
 
-	if (!(p1 & 2))
+	if (!(testFlag & 2))
 		return 0;
 
 	uint16 b = _levelBlockProperties[block].itemMonsterIndex;
@@ -452,8 +449,8 @@
 	return 0;
 }
 
-bool LoLEngine::checkBlockOccupiedByParty(int x, int y, int p1) {
-	if ((p1 & 4) && (_currentBlock == calcBlockIndex(x, y)))
+bool LoLEngine::checkBlockOccupiedByParty(int x, int y, int testFlag) {
+	if ((testFlag & 4) && (_currentBlock == calcBlockIndex(x, y)))
 		return true;
 
 	return false;
@@ -627,7 +624,7 @@
 	uint16 *b = &l->field_6;
 	ItemInPlay *i2 = 0;
 
-	while (b) {
+	while (*b) {
 		i2 = findItem(itemIndex);
 
 		if (flag) {
@@ -856,8 +853,8 @@
 	}
 
 	if (monster->flags & 8) {
-		monster->itemPosX = _partyPosX;
-		monster->itemPosY = _partyPosY;
+		monster->destX = _partyPosX;
+		monster->destY = _partyPosY;
 	}
 
 	if (s & 2) {
@@ -922,20 +919,136 @@
 }
 
 void LoLEngine::moveMonster(MonsterInPlay *monster) {
-	static const int8 pos[] = { 0, 1, 3, 3, 0, 1, 2, 2, 1, 1, 2, 3, 0, 0, 2, 3, 0 };
-	if (monster->x != monster->itemPosX || monster->y != monster->itemPosY) {
-		shiftMonster(monster);		
-	} else if (monster->field_17 != monster->field10) {
-		int i = (monster->facing << 2) + (monster->field10 >> 1);
-		cmzS2(monster, pos[i]);
+	static const int8 turnPos[] = { 0, 2, 6, 6, 0, 2, 4, 4, 2, 2, 4, 6, 0, 0, 4, 6, 0 };
+	if (monster->x != monster->destX || monster->y != monster->destY) {
+		walkMonster(monster);		
+	} else if (monster->direction != monster->destDirection) {
+		int i = (monster->facing << 2) + (monster->destDirection >> 1);
+		setMonsterDirection(monster, turnPos[i]);
 	}
 }
 
-void LoLEngine::shiftMonster(MonsterInPlay *monster) {
+void LoLEngine::walkMonster(MonsterInPlay *monster) {
 	if (monster->properties->flags & 0x400)
 		return;
 
+	int s = walkMonsterCalcNextStep(monster);
+	
+	if (s == -1) {
+		if (walkMonsterCheckDest(monster->x, monster->y, monster, 4) != 1)
+			return;
+
+		_monsterUnkDir ^= 4;
+		setMonsterDirection(monster, _monsterUnkDir);
+	} else {
+		setMonsterDirection(monster, s);
+		if (monster->field_25) {
+			if (getMonsterDistance(monster->blockPropertyIndex, _currentBlock) >= 2) {
+				if (walkMonster_s3(monster->blockPropertyIndex, monster->direction, 3, _currentBlock) != 5) {
+					if (monster->field_27)
+						return;
+				}
+			}
+		}		
+	}
+
+	int fx = 0;
+	int fy = 0;
+
+	walkMonsterGetNextStepCoords(monster->x, monster->y, fx, fy, (s == -1) ? _monsterUnkDir : s);
+	placeMonster(monster, fx, fy);
 }
 
+int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
+	static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
+	static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
+
+	if (++_monsterCountUnk > 10) {
+		_monsterCountUnk = 0;
+		_monsterShiftAlt ^= 1;
+	}
+
+	const int8 *tbl = _monsterShiftAlt ? walkMonsterTable2 : walkMonsterTable1;
+
+	int sx = monster->x;
+	int sy = monster->y;	
+	int s = monster->direction;
+	int d = calcMonsterDirection(monster->x, monster->y, monster->destX, monster->destY);
+
+	if (monster->flags & 8)
+		d ^= 4;
+
+	d = (d - s) & 7;
+
+	if (d >= 5)
+		s = (s - 1) & 7;
+	else if (d)
+		s = (s + 1) & 7;
+
+	for (int i = 7; i > -1; i--) {
+		s = (s + tbl[i]) & 7;
+
+		int fx = 0;
+		int fy = 0;
+		walkMonsterGetNextStepCoords(sx, sy, fx, fy, s);
+		d = walkMonsterCheckDest(fx, fy, monster, 4);
+
+		if (!d)
+			return s;
+
+		if ((d != 1) || (s & 1) || (!(monster->properties->flags & 0x80)))
+			continue;
+
+		uint8 w = _levelBlockProperties[_monsterCurBlock].walls[(s >> 1) ^ 2];
+		
+		if (_wllWallFlags[w] & 0x20) {
+			if (_wllBuffer3[w] == 5)
+				openDoorSub2(_monsterCurBlock, 1);
+		}
+
+		if (_wllWallFlags[w] & 8)
+			return -1;
+	}
+
+	return -1;
+}
+
+int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
+	int8 b1x = block1 & 0x1f;
+	int8 b1y = (block1 >> 8) & 0x1f;
+	int8 b2x = block2 & 0x1f;
+	int8 b2y = (block2 >> 8) & 0x1f;
+
+	uint8 dy = ABS(b2y - b1y);
+	uint8 dx = ABS(b2x - b1x);
+
+	if (dx > dy)
+		SWAP(dx, dy);
+
+	return (dx << 1) + dy;
+}
+
+int LoLEngine::walkMonster_s3(uint16 monsterBlock, int unk1, int unk2, uint16 curBlock) {
+	return 0;
+}
+
+int LoLEngine::walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk) {
+	uint8 m = monster->mode;
+	monster->mode = 15;
+
+	int res = checkBlockBeforeMonsterPlacement(x, y, monster->properties->maxWidth, 7, monster->properties->flags & 0x1000 ? 32 : unk);
+
+	monster->mode = m;
+	return res;
+}
+
+void LoLEngine::walkMonsterGetNextStepCoords(int16 srcX, int16 srcY, int &newX, int &newY, uint16 unk) {
+	static const int8 shiftTableX[] = { 0, 32, 32, 32, 0, -32, -32, -32 };
+	static const int8 shiftTableY[] = { -32, -32, 0, 32, 32, 32, 0, -32 };
+
+	newX = (srcX + shiftTableX[unk]) & 0x1fff;
+	newY = (srcY + shiftTableY[unk]) & 0x1fff;
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/timer_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/timer_lol.cpp	2009-03-03 21:33:45 UTC (rev 39096)
+++ scummvm/trunk/engines/kyra/timer_lol.cpp	2009-03-03 22:32:39 UTC (rev 39097)
@@ -37,7 +37,7 @@
 	_timer->addTimer(0, TimerV2(timerProcessOpenDoor), 15, true);	
 	_timer->addTimer(0x10, TimerV2(timerProcessMonsters), 6, true);
 	_timer->addTimer(0x11, TimerV2(timerProcessMonsters), 6, true);
-	_timer->setNextRun(0x11, 3);
+	_timer->setNextRun(0x11, _system->getMillis() + 3 * _tickLength);
 	_timer->addTimer(3, TimerV2(timerSub3), 15, true);
 	_timer->addTimer(4, TimerV2(timerSub4), 1, true);
 	_timer->addTimer(0x50, TimerV2(timerSub5), 0, false);


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