mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-30 14:14:43 +00:00
74311906f2
svn-id: r32176
1285 lines
33 KiB
C++
1285 lines
33 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "kyra/kyra_lok.h"
|
|
#include "kyra/seqplayer.h"
|
|
#include "kyra/screen.h"
|
|
#include "kyra/resource.h"
|
|
#include "kyra/sound.h"
|
|
#include "kyra/sprites.h"
|
|
#include "kyra/wsamovie.h"
|
|
#include "kyra/animator_lok.h"
|
|
#include "kyra/text.h"
|
|
#include "kyra/script.h"
|
|
#include "kyra/timer.h"
|
|
|
|
#include "common/system.h"
|
|
#include "common/savefile.h"
|
|
|
|
namespace Kyra {
|
|
|
|
void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive);
|
|
int unkVar1 = 1;
|
|
_screen->hideMouse();
|
|
_handleInput = false;
|
|
_abortWalkFlag = false;
|
|
_abortWalkFlag2 = false;
|
|
|
|
if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) {
|
|
int newSfxFile = -1;
|
|
if (_currentCharacter->sceneId == 7 && sceneId == 24)
|
|
newSfxFile = 2;
|
|
else if (_currentCharacter->sceneId == 25 && sceneId == 109)
|
|
newSfxFile = 3;
|
|
else if (_currentCharacter->sceneId == 120 && sceneId == 37)
|
|
newSfxFile = 4;
|
|
else if (_currentCharacter->sceneId == 52 && sceneId == 199)
|
|
newSfxFile = 5;
|
|
else if (_currentCharacter->sceneId == 37 && sceneId == 120)
|
|
newSfxFile = 3;
|
|
else if (_currentCharacter->sceneId == 109 && sceneId == 25)
|
|
newSfxFile = 2;
|
|
else if (_currentCharacter->sceneId == 24 && sceneId == 7)
|
|
newSfxFile = 1;
|
|
|
|
if (newSfxFile != -1) {
|
|
_curSfxFile = newSfxFile;
|
|
_sound->loadSoundFile(_curSfxFile);
|
|
}
|
|
}
|
|
|
|
switch (_currentCharacter->sceneId) {
|
|
case 1:
|
|
if (sceneId == 0) {
|
|
moveCharacterToPos(0, 0, _currentCharacter->x1, 84);
|
|
unkVar1 = 0;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (sceneId == 2) {
|
|
moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
|
|
unkVar1 = 0;
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
if (sceneId == 27) {
|
|
moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
|
|
unkVar1 = 0;
|
|
}
|
|
break;
|
|
|
|
case 44:
|
|
if (sceneId == 45) {
|
|
moveCharacterToPos(0, 2, 192, _currentCharacter->y1);
|
|
unkVar1 = 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (unkVar1 && unk1) {
|
|
int xpos = _currentCharacter->x1;
|
|
int ypos = _currentCharacter->y1;
|
|
switch (facing) {
|
|
case 0:
|
|
ypos = _currentCharacter->y1 - 6;
|
|
break;
|
|
|
|
case 2:
|
|
xpos = 336;
|
|
break;
|
|
|
|
case 4:
|
|
ypos = 143;
|
|
break;
|
|
|
|
case 6:
|
|
xpos = -16;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
moveCharacterToPos(0, facing, xpos, ypos);
|
|
}
|
|
|
|
for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i)
|
|
_movieObjects[i]->close();
|
|
|
|
if (!brandonAlive) {
|
|
_emc->init(&_scriptClick, &_scriptClickData);
|
|
_emc->start(&_scriptClick, 5);
|
|
while (_emc->isValid(&_scriptClick))
|
|
_emc->run(&_scriptClick);
|
|
}
|
|
|
|
memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4);
|
|
_currentCharacter->sceneId = sceneId;
|
|
|
|
assert(sceneId < _roomTableSize);
|
|
assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize);
|
|
|
|
Room *currentRoom = &_roomTable[sceneId];
|
|
|
|
setupSceneResource(sceneId);
|
|
|
|
_currentRoom = sceneId;
|
|
|
|
int tableId = _roomTable[sceneId].nameIndex;
|
|
char fileNameBuffer[32];
|
|
strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
|
|
strcat(fileNameBuffer, ".DAT");
|
|
_sprites->loadDat(fileNameBuffer, _sceneExits);
|
|
_sprites->setupSceneAnims();
|
|
_emc->unload(&_scriptClickData);
|
|
loadSceneMsc();
|
|
|
|
_walkBlockNorth = currentRoom->northExit;
|
|
_walkBlockEast = currentRoom->eastExit;
|
|
_walkBlockSouth = currentRoom->southExit;
|
|
_walkBlockWest = currentRoom->westExit;
|
|
|
|
if (_walkBlockNorth == 0xFFFF)
|
|
_screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3);
|
|
if (_walkBlockEast == 0xFFFF)
|
|
_screen->blockOutRegion(312, 0, 8, 139);
|
|
if (_walkBlockSouth == 0xFFFF)
|
|
_screen->blockOutRegion(0, 135, 320, 8);
|
|
if (_walkBlockWest == 0xFFFF)
|
|
_screen->blockOutRegion(0, 0, 8, 139);
|
|
|
|
if (!brandonAlive)
|
|
updatePlayerItemsForScene();
|
|
|
|
startSceneScript(brandonAlive);
|
|
setupSceneItems();
|
|
|
|
initSceneData(facing, unk2, brandonAlive);
|
|
|
|
_loopFlag2 = 0;
|
|
_screen->showMouse();
|
|
if (!brandonAlive)
|
|
seq_poisonDeathNow(0);
|
|
updateMousePointer(true);
|
|
_changedScene = true;
|
|
}
|
|
|
|
void KyraEngine_LoK::transcendScenes(int roomIndex, int roomName) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::transcendScenes(%d, %d)", roomIndex, roomName);
|
|
assert(roomIndex < _roomTableSize);
|
|
|
|
if (_flags.isTalkie) {
|
|
char file[32];
|
|
assert(roomIndex < _roomTableSize);
|
|
int tableId = _roomTable[roomIndex].nameIndex;
|
|
assert(tableId < _roomFilenameTableSize);
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".VRM");
|
|
_res->unloadPakFile(file);
|
|
}
|
|
|
|
_roomTable[roomIndex].nameIndex = roomName;
|
|
_unkScreenVar2 = 1;
|
|
_unkScreenVar3 = 1;
|
|
_unkScreenVar1 = 0;
|
|
_brandonPosX = _currentCharacter->x1;
|
|
_brandonPosY = _currentCharacter->y1;
|
|
enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0);
|
|
_unkScreenVar1 = 1;
|
|
_unkScreenVar2 = 0;
|
|
_unkScreenVar3 = 0;
|
|
}
|
|
|
|
void KyraEngine_LoK::setSceneFile(int roomIndex, int roomName) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::setSceneFile(%d, %d)", roomIndex, roomName);
|
|
assert(roomIndex < _roomTableSize);
|
|
_roomTable[roomIndex].nameIndex = roomName;
|
|
}
|
|
|
|
void KyraEngine_LoK::moveCharacterToPos(int character, int facing, int xpos, int ypos) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos);
|
|
Character *ch = &_characterList[character];
|
|
ch->facing = facing;
|
|
_screen->hideMouse();
|
|
xpos = (int16)(xpos & 0xFFFC);
|
|
ypos = (int16)(ypos & 0xFFFE);
|
|
_timer->disable(19);
|
|
_timer->disable(14);
|
|
_timer->disable(18);
|
|
uint32 nextFrame = 0;
|
|
|
|
switch (facing) {
|
|
case 0:
|
|
while (ypos < ch->y1) {
|
|
nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
|
|
setCharacterPositionWithUpdate(character);
|
|
delayUntil(nextFrame, true);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
while (ch->x1 < xpos) {
|
|
nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
|
|
setCharacterPositionWithUpdate(character);
|
|
delayUntil(nextFrame, true);
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
while (ypos > ch->y1) {
|
|
nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
|
|
setCharacterPositionWithUpdate(character);
|
|
delayUntil(nextFrame, true);
|
|
}
|
|
break;
|
|
|
|
case 6:
|
|
while (ch->x1 > xpos) {
|
|
nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
|
|
setCharacterPositionWithUpdate(character);
|
|
delayUntil(nextFrame, true);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
_timer->enable(19);
|
|
_timer->enable(14);
|
|
_timer->enable(18);
|
|
_screen->showMouse();
|
|
}
|
|
|
|
void KyraEngine_LoK::setCharacterPositionWithUpdate(int character) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionWithUpdate(%d)", character);
|
|
setCharacterPosition(character, 0);
|
|
_sprites->updateSceneAnims();
|
|
_timer->update();
|
|
_animator->updateAllObjectShapes();
|
|
updateTextFade();
|
|
|
|
if (_currentCharacter->sceneId == 210)
|
|
updateKyragemFading();
|
|
}
|
|
|
|
int KyraEngine_LoK::setCharacterPosition(int character, int *facingTable) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPosition(%d, %p)", character, (const void *)facingTable);
|
|
|
|
if (character == 0) {
|
|
_currentCharacter->x1 += _charAddXPosTable[_currentCharacter->facing];
|
|
_currentCharacter->y1 += _charAddYPosTable[_currentCharacter->facing];
|
|
setCharacterPositionHelper(0, facingTable);
|
|
return 1;
|
|
} else {
|
|
_characterList[character].x1 += _charAddXPosTable[_characterList[character].facing];
|
|
_characterList[character].y1 += _charAddYPosTable[_characterList[character].facing];
|
|
if (_characterList[character].sceneId == _currentCharacter->sceneId)
|
|
setCharacterPositionHelper(character, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine_LoK::setCharacterPositionHelper(int character, int *facingTable) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::setCharacterPositionHelper(%d, %p)", character, (const void *)facingTable);
|
|
Character *ch = &_characterList[character];
|
|
++ch->currentAnimFrame;
|
|
int facing = ch->facing;
|
|
if (facingTable) {
|
|
if (*facingTable != *(facingTable - 1)) {
|
|
if (*(facingTable - 1) == *(facingTable + 1)) {
|
|
facing = getOppositeFacingDirection(*(facingTable - 1));
|
|
*facingTable = *(facingTable - 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
if (facing == 0) {
|
|
++facingIsZero[character];
|
|
} else {
|
|
bool resetTables = false;
|
|
if (facing != 7) {
|
|
if (facing - 1 != 0) {
|
|
if (facing != 4) {
|
|
if (facing == 3 || facing == 5) {
|
|
if (facingIsFour[character] > 2)
|
|
facing = 4;
|
|
resetTables = true;
|
|
}
|
|
} else {
|
|
++facingIsFour[character];
|
|
}
|
|
} else {
|
|
if (facingIsZero[character] > 2)
|
|
facing = 0;
|
|
resetTables = true;
|
|
}
|
|
} else {
|
|
if (facingIsZero[character] > 2)
|
|
facing = 0;
|
|
resetTables = true;
|
|
}
|
|
|
|
if (resetTables) {
|
|
facingIsZero[character] = 0;
|
|
facingIsFour[character] = 0;
|
|
}
|
|
}
|
|
|
|
static const uint16 maxAnimationFrame[] = {
|
|
0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000,
|
|
0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000,
|
|
0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000,
|
|
0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000,
|
|
0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000,
|
|
0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000,
|
|
0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000
|
|
};
|
|
|
|
if (facing == 0) {
|
|
if (maxAnimationFrame[36+character] > ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[36+character];
|
|
if (maxAnimationFrame[30+character] < ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[36+character];
|
|
} else if (facing == 4) {
|
|
if (maxAnimationFrame[18+character] > ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[18+character];
|
|
if (maxAnimationFrame[12+character] < ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[18+character];
|
|
} else {
|
|
if (maxAnimationFrame[18+character] < ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[30+character];
|
|
if (maxAnimationFrame[character] == ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[6+character];
|
|
if (maxAnimationFrame[character] < ch->currentAnimFrame)
|
|
ch->currentAnimFrame = maxAnimationFrame[6+character]+2;
|
|
}
|
|
|
|
if (character == 0 && (_brandonStatusBit & 0x10))
|
|
ch->currentAnimFrame = 88;
|
|
|
|
_animator->animRefreshNPC(character);
|
|
}
|
|
|
|
void KyraEngine_LoK::loadSceneMsc() {
|
|
assert(_currentCharacter->sceneId < _roomTableSize);
|
|
int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
|
|
assert(tableId < _roomFilenameTableSize);
|
|
char fileNameBuffer[32];
|
|
strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
|
|
strcat(fileNameBuffer, ".MSC");
|
|
_screen->fillRect(0, 0, 319, 199, 0, 5);
|
|
_res->exists(fileNameBuffer, true);
|
|
_screen->loadBitmap(fileNameBuffer, 3, 5, 0);
|
|
}
|
|
|
|
void KyraEngine_LoK::startSceneScript(int brandonAlive) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::startSceneScript(%d)", brandonAlive);
|
|
assert(_currentCharacter->sceneId < _roomTableSize);
|
|
int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
|
|
assert(tableId < _roomFilenameTableSize);
|
|
char fileNameBuffer[32];
|
|
strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
|
|
strcat(fileNameBuffer, ".CPS");
|
|
_screen->clearPage(3);
|
|
_res->exists(fileNameBuffer, true);
|
|
// FIXME: check this hack for amiga version
|
|
_screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0));
|
|
_sprites->loadSceneShapes();
|
|
_exitListPtr = 0;
|
|
|
|
_scaleMode = 1;
|
|
for (int i = 0; i < 145; ++i)
|
|
_scaleTable[i] = 256;
|
|
|
|
clearNoDropRects();
|
|
_emc->init(&_scriptClick, &_scriptClickData);
|
|
strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
|
|
strcat(fileNameBuffer, ".EMC");
|
|
_res->exists(fileNameBuffer, true);
|
|
_emc->unload(&_scriptClickData);
|
|
_emc->load(fileNameBuffer, &_scriptClickData, &_opcodes);
|
|
_emc->start(&_scriptClick, 0);
|
|
_scriptClick.regs[0] = _currentCharacter->sceneId;
|
|
_scriptClick.regs[7] = brandonAlive;
|
|
|
|
while (_emc->isValid(&_scriptClick))
|
|
_emc->run(&_scriptClick);
|
|
}
|
|
|
|
void KyraEngine_LoK::initSceneData(int facing, int unk1, int brandonAlive) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive);
|
|
|
|
int16 xpos2 = 0;
|
|
int setFacing = 1;
|
|
|
|
int16 xpos = 0, ypos = 0;
|
|
|
|
if (_brandonPosX == -1 && _brandonPosY == -1) {
|
|
switch (facing + 1) {
|
|
case 0:
|
|
xpos = ypos = -1;
|
|
break;
|
|
|
|
case 1: case 2: case 8:
|
|
xpos = _sceneExits.southXPos;
|
|
ypos = _sceneExits.southYPos;
|
|
break;
|
|
|
|
case 3:
|
|
xpos = _sceneExits.westXPos;
|
|
ypos = _sceneExits.westYPos;
|
|
break;
|
|
|
|
case 4: case 5: case 6:
|
|
xpos = _sceneExits.northXPos;
|
|
ypos = _sceneExits.northYPos;
|
|
break;
|
|
|
|
case 7:
|
|
xpos = _sceneExits.eastXPos;
|
|
ypos = _sceneExits.eastYPos;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos)
|
|
ypos = (_northExitHeight & 0xFF) + 4;
|
|
if (xpos >= 308)
|
|
xpos = 304;
|
|
if ((uint8)(_northExitHeight >> 8) - 2 <= ypos)
|
|
ypos = (_northExitHeight >> 8) - 4;
|
|
if (xpos <= 12)
|
|
xpos = 16;
|
|
}
|
|
|
|
if (_brandonPosX > -1)
|
|
xpos = _brandonPosX;
|
|
if (_brandonPosY > -1)
|
|
ypos = _brandonPosY;
|
|
|
|
int16 ypos2 = 0;
|
|
if (_brandonPosX > -1 && _brandonPosY > -1) {
|
|
switch (_currentCharacter->sceneId) {
|
|
case 1:
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
facing = 4;
|
|
xpos2 = 192;
|
|
ypos2 = 104;
|
|
setFacing = 0;
|
|
unk1 = 1;
|
|
break;
|
|
|
|
case 3:
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
facing = 2;
|
|
xpos2 = 204;
|
|
ypos2 = 94;
|
|
setFacing = 0;
|
|
unk1 = 1;
|
|
break;
|
|
|
|
case 26:
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
facing = 2;
|
|
xpos2 = 192;
|
|
ypos2 = 128;
|
|
setFacing = 0;
|
|
unk1 = 1;
|
|
break;
|
|
|
|
case 44:
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
facing = 6;
|
|
xpos2 = 156;
|
|
ypos2 = 96;
|
|
setFacing = 0;
|
|
unk1 = 1;
|
|
break;
|
|
|
|
case 37:
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
facing = 2;
|
|
xpos2 = 148;
|
|
ypos2 = 114;
|
|
setFacing = 0;
|
|
unk1 = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
_brandonPosX = _brandonPosY = -1;
|
|
|
|
if (unk1 && setFacing) {
|
|
ypos2 = ypos;
|
|
xpos2 = xpos;
|
|
switch (facing) {
|
|
case 0:
|
|
ypos = 142;
|
|
break;
|
|
|
|
case 2:
|
|
xpos = -16;
|
|
break;
|
|
|
|
case 4:
|
|
ypos = (uint8)(_northExitHeight & 0xFF) - 4;
|
|
break;
|
|
|
|
case 6:
|
|
xpos = 336;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
xpos2 = (int16)(xpos2 & 0xFFFC);
|
|
ypos2 = (int16)(ypos2 & 0xFFFE);
|
|
xpos = (int16)(xpos & 0xFFFC);
|
|
ypos = (int16)(ypos & 0xFFFE);
|
|
_currentCharacter->facing = facing;
|
|
_currentCharacter->x1 = xpos;
|
|
_currentCharacter->x2 = xpos;
|
|
_currentCharacter->y1 = ypos;
|
|
_currentCharacter->y2 = ypos;
|
|
|
|
initSceneObjectList(brandonAlive);
|
|
|
|
if (unk1 && brandonAlive == 0)
|
|
moveCharacterToPos(0, facing, xpos2, ypos2);
|
|
|
|
_scriptClick.regs[4] = _itemInHand;
|
|
_scriptClick.regs[7] = brandonAlive;
|
|
_emc->start(&_scriptClick, 3);
|
|
while (_emc->isValid(&_scriptClick))
|
|
_emc->run(&_scriptClick);
|
|
}
|
|
|
|
void KyraEngine_LoK::initSceneObjectList(int brandonAlive) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::initSceneObjectList(%d)", brandonAlive);
|
|
for (int i = 0; i < 28; ++i)
|
|
_animator->actors()[i].active = 0;
|
|
|
|
int startAnimFrame = 0;
|
|
|
|
Animator_LoK::AnimObject *curAnimState = _animator->actors();
|
|
curAnimState->active = 1;
|
|
curAnimState->drawY = _currentCharacter->y1;
|
|
curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame];
|
|
curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame;
|
|
startAnimFrame = _currentCharacter->currentAnimFrame-7;
|
|
int xOffset = _defaultShapeTable[startAnimFrame].xOffset;
|
|
int yOffset = _defaultShapeTable[startAnimFrame].yOffset;
|
|
|
|
if (_scaleMode) {
|
|
curAnimState->x1 = _currentCharacter->x1;
|
|
curAnimState->y1 = _currentCharacter->y1;
|
|
|
|
_animator->_brandonScaleX = _scaleTable[_currentCharacter->y1];
|
|
_animator->_brandonScaleY = _scaleTable[_currentCharacter->y1];
|
|
|
|
curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8;
|
|
curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8;
|
|
} else {
|
|
curAnimState->x1 = _currentCharacter->x1 + xOffset;
|
|
curAnimState->y1 = _currentCharacter->y1 + yOffset;
|
|
}
|
|
|
|
curAnimState->x2 = curAnimState->x1;
|
|
curAnimState->y2 = curAnimState->y1;
|
|
curAnimState->refreshFlag = 1;
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
_animator->clearQueue();
|
|
_animator->addObjectToQueue(curAnimState);
|
|
|
|
int listAdded = 0;
|
|
int addedObjects = 1;
|
|
|
|
for (int i = 1; i < 5; ++i) {
|
|
Character *ch = &_characterList[i];
|
|
curAnimState = &_animator->actors()[addedObjects];
|
|
if (ch->sceneId != _currentCharacter->sceneId) {
|
|
curAnimState->active = 0;
|
|
curAnimState->refreshFlag = 0;
|
|
curAnimState->bkgdChangeFlag = 0;
|
|
++addedObjects;
|
|
continue;
|
|
}
|
|
|
|
curAnimState->drawY = ch->y1;
|
|
curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame];
|
|
curAnimState->animFrameNumber = ch->currentAnimFrame;
|
|
startAnimFrame = ch->currentAnimFrame-7;
|
|
xOffset = _defaultShapeTable[startAnimFrame].xOffset;
|
|
yOffset = _defaultShapeTable[startAnimFrame].yOffset;
|
|
if (_scaleMode) {
|
|
curAnimState->x1 = ch->x1;
|
|
curAnimState->y1 = ch->y1;
|
|
|
|
_animator->_brandonScaleX = _scaleTable[ch->y1];
|
|
_animator->_brandonScaleY = _scaleTable[ch->y1];
|
|
|
|
curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8;
|
|
curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8;
|
|
} else {
|
|
curAnimState->x1 = ch->x1 + xOffset;
|
|
curAnimState->y1 = ch->y1 + yOffset;
|
|
}
|
|
curAnimState->x2 = curAnimState->x1;
|
|
curAnimState->y2 = curAnimState->y1;
|
|
curAnimState->active = 1;
|
|
curAnimState->refreshFlag = 1;
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
|
|
if (ch->facing >= 1 && ch->facing <= 3)
|
|
curAnimState->flags |= 1;
|
|
else if (ch->facing >= 5 && ch->facing <= 7)
|
|
curAnimState->flags &= 0xFFFFFFFE;
|
|
|
|
_animator->addObjectToQueue(curAnimState);
|
|
|
|
++addedObjects;
|
|
++listAdded;
|
|
if (listAdded < 2)
|
|
i = 5;
|
|
}
|
|
|
|
for (int i = 0; i < 11; ++i) {
|
|
curAnimState = &_animator->sprites()[i];
|
|
|
|
if (_sprites->_anims[i].play) {
|
|
curAnimState->active = 1;
|
|
curAnimState->refreshFlag = 1;
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
} else {
|
|
curAnimState->active = 0;
|
|
curAnimState->refreshFlag = 0;
|
|
curAnimState->bkgdChangeFlag = 0;
|
|
}
|
|
curAnimState->height = _sprites->_anims[i].height;
|
|
curAnimState->height2 = _sprites->_anims[i].height2;
|
|
curAnimState->width = _sprites->_anims[i].width + 1;
|
|
curAnimState->width2 = _sprites->_anims[i].width2;
|
|
curAnimState->drawY = _sprites->_anims[i].drawY;
|
|
curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x;
|
|
curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y;
|
|
curAnimState->background = _sprites->_anims[i].background;
|
|
curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite];
|
|
|
|
curAnimState->disable = _sprites->_anims[i].disable;
|
|
|
|
if (_sprites->_anims[i].unk2)
|
|
curAnimState->flags = 0x800;
|
|
else
|
|
curAnimState->flags = 0;
|
|
|
|
if (_sprites->_anims[i].flipX)
|
|
curAnimState->flags |= 0x1;
|
|
|
|
_animator->addObjectToQueue(curAnimState);
|
|
}
|
|
|
|
for (int i = 0; i < 12; ++i) {
|
|
curAnimState = &_animator->items()[i];
|
|
Room *curRoom = &_roomTable[_currentCharacter->sceneId];
|
|
byte curItem = curRoom->itemsTable[i];
|
|
if (curItem != 0xFF) {
|
|
curAnimState->drawY = curRoom->itemsYPos[i];
|
|
curAnimState->sceneAnimPtr = _shapes[216+curItem];
|
|
curAnimState->animFrameNumber = (int16)0xFFFF;
|
|
curAnimState->y1 = curRoom->itemsYPos[i];
|
|
curAnimState->x1 = curRoom->itemsXPos[i];
|
|
|
|
curAnimState->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1;
|
|
curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]);
|
|
|
|
curAnimState->x2 = curAnimState->x1;
|
|
curAnimState->y2 = curAnimState->y1;
|
|
|
|
curAnimState->active = 1;
|
|
curAnimState->refreshFlag = 1;
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
|
|
_animator->addObjectToQueue(curAnimState);
|
|
} else {
|
|
curAnimState->active = 0;
|
|
curAnimState->refreshFlag = 0;
|
|
curAnimState->bkgdChangeFlag = 0;
|
|
}
|
|
}
|
|
|
|
_animator->preserveAnyChangedBackgrounds();
|
|
curAnimState = _animator->actors();
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
curAnimState->refreshFlag = 1;
|
|
for (int i = 1; i < 28; ++i) {
|
|
curAnimState = &_animator->objects()[i];
|
|
if (curAnimState->active) {
|
|
curAnimState->bkgdChangeFlag = 1;
|
|
curAnimState->refreshFlag = 1;
|
|
}
|
|
}
|
|
_animator->restoreAllObjectBackgrounds();
|
|
_animator->preserveAnyChangedBackgrounds();
|
|
_animator->prepDrawAllObjects();
|
|
initSceneScreen(brandonAlive);
|
|
_animator->copyChangedObjectsForward(0);
|
|
}
|
|
|
|
void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
|
|
if (_flags.platform == Common::kPlatformAmiga) {
|
|
if (_unkScreenVar1 && !queryGameFlag(0xF0)) {
|
|
memset(_screen->getPalette(2), 0, 32*3);
|
|
if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3))
|
|
_screen->setScreenPalette(_screen->getPalette(2));
|
|
}
|
|
|
|
if (_unkScreenVar2 == 1)
|
|
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
|
|
else
|
|
_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
|
|
|
|
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
|
|
if (_currentCharacter->sceneId == 45 && _paletteChanged)
|
|
memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2);
|
|
|
|
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1))
|
|
memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64);
|
|
|
|
_screen->setScreenPalette(_screen->getPalette(0));
|
|
}
|
|
} else {
|
|
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
|
|
for (int i = 0; i < 60; ++i) {
|
|
uint16 col = _screen->getPalette(0)[684+i];
|
|
col += _screen->getPalette(1)[684+i] << 1;
|
|
col >>= 2;
|
|
_screen->getPalette(0)[684+i] = col;
|
|
}
|
|
_screen->setScreenPalette(_screen->getPalette(0));
|
|
}
|
|
|
|
if (_unkScreenVar2 == 1)
|
|
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
|
|
else
|
|
_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
|
|
|
|
if (_unkScreenVar1 && _paletteChanged) {
|
|
if (!queryGameFlag(0xA0)) {
|
|
memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60);
|
|
_screen->setScreenPalette(_screen->getPalette(0));
|
|
} else {
|
|
memset(_screen->getPalette(0), 0, 768);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!_emc->start(&_scriptClick, 2))
|
|
error("Could not start script function 2 of scene script");
|
|
|
|
_scriptClick.regs[7] = brandonAlive;
|
|
|
|
while (_emc->isValid(&_scriptClick))
|
|
_emc->run(&_scriptClick);
|
|
|
|
setTextFadeTimerCountdown(-1);
|
|
if (_currentCharacter->sceneId == 210) {
|
|
if (_itemInHand != -1)
|
|
magicOutMouseItem(2, -1);
|
|
|
|
_screen->hideMouse();
|
|
for (int i = 0; i < 10; ++i) {
|
|
if (_currentCharacter->inventoryItems[i] != 0xFF)
|
|
magicOutMouseItem(2, i);
|
|
}
|
|
_screen->showMouse();
|
|
}
|
|
}
|
|
|
|
int KyraEngine_LoK::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset);
|
|
if (queryGameFlag(0xEF))
|
|
unk1 = 0;
|
|
|
|
int sceneId = _currentCharacter->sceneId;
|
|
_pathfinderFlag = 0;
|
|
|
|
if (xpos < 12) {
|
|
if (_roomTable[sceneId].westExit != 0xFFFF) {
|
|
xpos = 12;
|
|
ypos = _sceneExits.westYPos;
|
|
_pathfinderFlag = 7;
|
|
}
|
|
} else if (xpos >= 308) {
|
|
if (_roomTable[sceneId].eastExit != 0xFFFF) {
|
|
xpos = 307;
|
|
ypos = _sceneExits.eastYPos;
|
|
_pathfinderFlag = 13;
|
|
}
|
|
}
|
|
|
|
if (ypos <= (_northExitHeight&0xFF)+2) {
|
|
if (_roomTable[sceneId].northExit != 0xFFFF) {
|
|
xpos = _sceneExits.northXPos;
|
|
ypos = _northExitHeight & 0xFF;
|
|
_pathfinderFlag = 14;
|
|
}
|
|
} else if (ypos >= 136) {
|
|
if (_roomTable[sceneId].southExit != 0xFFFF) {
|
|
xpos = _sceneExits.southXPos;
|
|
ypos = 136;
|
|
_pathfinderFlag = 11;
|
|
}
|
|
}
|
|
|
|
int temp = xpos - _currentCharacter->x1;
|
|
if (ABS(temp) < 4) {
|
|
temp = ypos - _currentCharacter->y1;
|
|
if (ABS(temp) < 2)
|
|
return 0;
|
|
}
|
|
|
|
int x = (int16)(_currentCharacter->x1 & 0xFFFC);
|
|
int y = (int16)(_currentCharacter->y1 & 0xFFFE);
|
|
xpos = (int16)(xpos & 0xFFFC);
|
|
ypos = (int16)(ypos & 0xFFFE);
|
|
|
|
int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150);
|
|
_pathfinderFlag = 0;
|
|
|
|
if (ret >= _lastFindWayRet)
|
|
_lastFindWayRet = ret;
|
|
|
|
if (ret == 0x7D00 || ret == 0)
|
|
return 0;
|
|
|
|
return processSceneChange(_movFacingTable, unk1, frameReset);
|
|
}
|
|
|
|
int KyraEngine_LoK::processSceneChange(int *table, int unk1, int frameReset) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset);
|
|
if (queryGameFlag(0xEF))
|
|
unk1 = 0;
|
|
|
|
int *tableStart = table;
|
|
_sceneChangeState = 0;
|
|
_loopFlag2 = 0;
|
|
bool running = true;
|
|
int returnValue = 0;
|
|
uint32 nextFrame = 0;
|
|
_abortWalkFlag = false;
|
|
_mousePressFlag = false;
|
|
|
|
while (running) {
|
|
if (_abortWalkFlag) {
|
|
*table = 8;
|
|
_currentCharacter->currentAnimFrame = 7;
|
|
_animator->animRefreshNPC(0);
|
|
_animator->updateAllObjectShapes();
|
|
processInput();
|
|
return 0;
|
|
}
|
|
bool forceContinue = false;
|
|
switch (*table) {
|
|
case 0: case 1: case 2:
|
|
case 3: case 4: case 5:
|
|
case 6: case 7:
|
|
_currentCharacter->facing = getOppositeFacingDirection(*table);
|
|
break;
|
|
|
|
case 8:
|
|
forceContinue = true;
|
|
running = false;
|
|
break;
|
|
|
|
default:
|
|
++table;
|
|
forceContinue = true;
|
|
break;
|
|
}
|
|
|
|
returnValue = changeScene(_currentCharacter->facing);
|
|
if (returnValue) {
|
|
running = false;
|
|
_abortWalkFlag = false;
|
|
}
|
|
|
|
if (unk1) {
|
|
if (_mousePressFlag) {
|
|
running = false;
|
|
_sceneChangeState = 1;
|
|
}
|
|
}
|
|
|
|
if (forceContinue || !running)
|
|
continue;
|
|
|
|
int temp = 0;
|
|
if (table == tableStart || table[1] == 8)
|
|
temp = setCharacterPosition(0, 0);
|
|
else
|
|
temp = setCharacterPosition(0, table);
|
|
|
|
if (temp)
|
|
++table;
|
|
|
|
nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis();
|
|
while (_system->getMillis() < nextFrame) {
|
|
_timer->update();
|
|
|
|
if (_currentCharacter->sceneId == 210) {
|
|
updateKyragemFading();
|
|
if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) {
|
|
*table = 8;
|
|
running = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((nextFrame - _system->getMillis()) >= 10)
|
|
delay(10, true);
|
|
}
|
|
}
|
|
|
|
if (frameReset && !(_brandonStatusBit & 2))
|
|
_currentCharacter->currentAnimFrame = 7;
|
|
|
|
_animator->animRefreshNPC(0);
|
|
_animator->updateAllObjectShapes();
|
|
return returnValue;
|
|
}
|
|
|
|
int KyraEngine_LoK::changeScene(int facing) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::changeScene(%d)", facing);
|
|
if (queryGameFlag(0xEF)) {
|
|
if (_currentCharacter->sceneId == 5)
|
|
return 0;
|
|
}
|
|
|
|
int xpos = _charAddXPosTable[facing] + _currentCharacter->x1;
|
|
int ypos = _charAddYPosTable[facing] + _currentCharacter->y1;
|
|
|
|
if (xpos >= 12 && xpos <= 308) {
|
|
if (!lineIsPassable(xpos, ypos))
|
|
return false;
|
|
}
|
|
|
|
if (_exitListPtr) {
|
|
int16 *ptr = _exitListPtr;
|
|
// this loop should be only entered one time, seems to be some hack in the original
|
|
while (true) {
|
|
if (*ptr == -1)
|
|
break;
|
|
|
|
if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) {
|
|
ptr += 10;
|
|
break;
|
|
}
|
|
|
|
_brandonPosX = ptr[6];
|
|
_brandonPosY = ptr[7];
|
|
uint16 sceneId = ptr[5];
|
|
facing = ptr[4];
|
|
int unk1 = ptr[8];
|
|
int unk2 = ptr[9];
|
|
|
|
if (sceneId == 0xFFFF) {
|
|
switch (facing) {
|
|
case 0:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].northExit;
|
|
break;
|
|
|
|
case 2:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
|
|
break;
|
|
|
|
case 4:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].southExit;
|
|
break;
|
|
|
|
case 6:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].westExit;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
_currentCharacter->facing = facing;
|
|
_animator->animRefreshNPC(0);
|
|
_animator->updateAllObjectShapes();
|
|
enterNewScene(sceneId, facing, unk1, unk2, 0);
|
|
resetGameFlag(0xEE);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int returnValue = 0;
|
|
facing = 0;
|
|
|
|
if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) {
|
|
facing = 0;
|
|
returnValue = 1;
|
|
}
|
|
|
|
if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) {
|
|
facing = 2;
|
|
returnValue = 1;
|
|
}
|
|
|
|
if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) {
|
|
facing = 4;
|
|
returnValue = 1;
|
|
}
|
|
|
|
if (xpos <= 12 || _currentCharacter->y1 <= 12) {
|
|
facing = 6;
|
|
returnValue = 1;
|
|
}
|
|
|
|
if (!returnValue)
|
|
return 0;
|
|
|
|
uint16 sceneId = 0xFFFF;
|
|
switch (facing) {
|
|
case 0:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].northExit;
|
|
break;
|
|
|
|
case 2:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
|
|
break;
|
|
|
|
case 4:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].southExit;
|
|
break;
|
|
|
|
default:
|
|
sceneId = _roomTable[_currentCharacter->sceneId].westExit;
|
|
break;
|
|
}
|
|
|
|
if (sceneId == 0xFFFF)
|
|
return 0;
|
|
|
|
enterNewScene(sceneId, facing, 1, 1, 0);
|
|
return returnValue;
|
|
}
|
|
|
|
void KyraEngine_LoK::setCharactersInDefaultScene() {
|
|
static const uint32 defaultSceneTable[][4] = {
|
|
{ 0xFFFF, 0x0004, 0x0003, 0xFFFF },
|
|
{ 0xFFFF, 0x0022, 0xFFFF, 0x0000 },
|
|
{ 0xFFFF, 0x001D, 0x0021, 0xFFFF },
|
|
{ 0xFFFF, 0x0000, 0x0000, 0xFFFF }
|
|
};
|
|
|
|
for (int i = 1; i < 5; ++i) {
|
|
Character *cur = &_characterList[i];
|
|
//cur->field_20 = 0;
|
|
|
|
const uint32 *curTable = defaultSceneTable[i-1];
|
|
cur->sceneId = curTable[0];
|
|
|
|
if (cur->sceneId == _currentCharacter->sceneId)
|
|
//++cur->field_20;
|
|
cur->sceneId = curTable[1/*cur->field_20*/];
|
|
|
|
//cur->field_23 = curTable[cur->field_20+1];
|
|
}
|
|
}
|
|
|
|
void KyraEngine_LoK::setCharactersPositions(int character) {
|
|
static uint16 initXPosTable[] = {
|
|
0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B,
|
|
0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042
|
|
};
|
|
static uint8 initYPosTable[] = {
|
|
0x00, 0xA2, 0x00, 0x42, 0x00,
|
|
0x67, 0x67, 0x60, 0x5A, 0x71,
|
|
0x76
|
|
};
|
|
|
|
assert(character < ARRAYSIZE(initXPosTable));
|
|
Character *edit = &_characterList[character];
|
|
edit->x1 = edit->x2 = initXPosTable[character];
|
|
edit->y1 = edit->y2 = initYPosTable[character];
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark - Pathfinder
|
|
#pragma mark -
|
|
|
|
int KyraEngine_LoK::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize);
|
|
int ret = KyraEngine_v1::findWay(x, y, toX, toY, moveTable, moveTableSize);
|
|
if (ret == 0x7D00)
|
|
return 0;
|
|
return getMoveTableSize(moveTable);
|
|
}
|
|
|
|
bool KyraEngine_LoK::lineIsPassable(int x, int y) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::lineIsPassable(%d, %d)", x, y);
|
|
if (queryGameFlag(0xEF)) {
|
|
if (_currentCharacter->sceneId == 5)
|
|
return true;
|
|
}
|
|
|
|
if (_pathfinderFlag & 2) {
|
|
if (x >= 312)
|
|
return false;
|
|
}
|
|
|
|
if (_pathfinderFlag & 4) {
|
|
if (y >= 136)
|
|
return false;
|
|
}
|
|
|
|
if (_pathfinderFlag & 8) {
|
|
if (x < 8)
|
|
return false;
|
|
}
|
|
|
|
if (_pathfinderFlag2) {
|
|
if (x <= 8 || x >= 312)
|
|
return true;
|
|
if (y < (_northExitHeight & 0xFF) || y > 135)
|
|
return true;
|
|
}
|
|
|
|
if (y > 137)
|
|
return false;
|
|
|
|
if (y < 0)
|
|
y = 0;
|
|
|
|
int ypos = 8;
|
|
if (_scaleMode) {
|
|
ypos = (_scaleTable[y] >> 5) + 1;
|
|
if (8 < ypos)
|
|
ypos = 8;
|
|
}
|
|
|
|
x -= (ypos >> 1);
|
|
|
|
int xpos = x;
|
|
int xtemp = xpos + ypos - 1;
|
|
if (x < 0)
|
|
xpos = 0;
|
|
|
|
if (xtemp > 319)
|
|
xtemp = 319;
|
|
|
|
for (; xpos < xtemp; ++xpos) {
|
|
if (!_screen->getShapeFlag1(xpos, y))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
void KyraEngine_LoK::setupSceneResource(int sceneId) {
|
|
debugC(9, kDebugLevelMain, "KyraEngine_LoK::setupSceneResource(%d)", sceneId);
|
|
if (!_flags.isTalkie)
|
|
return;
|
|
|
|
if (_currentRoom != 0xFFFF) {
|
|
assert(_currentRoom < _roomTableSize);
|
|
int tableId = _roomTable[_currentRoom].nameIndex;
|
|
assert(tableId < _roomFilenameTableSize);
|
|
|
|
// unload our old room
|
|
char file[64];
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".VRM");
|
|
_res->unloadPakFile(file);
|
|
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".PAK");
|
|
_res->unloadPakFile(file);
|
|
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".APK");
|
|
_res->unloadPakFile(file);
|
|
}
|
|
|
|
assert(sceneId < _roomTableSize);
|
|
int tableId = _roomTable[sceneId].nameIndex;
|
|
assert(tableId < _roomFilenameTableSize);
|
|
|
|
// load our new room
|
|
char file[64];
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".VRM");
|
|
if (_res->exists(file))
|
|
_res->loadPakFile(file);
|
|
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".PAK");
|
|
if (_res->exists(file))
|
|
_res->loadPakFile(file);
|
|
|
|
strcpy(file, _roomFilenameTable[tableId]);
|
|
strcat(file, ".APK");
|
|
if (_res->exists(file))
|
|
_res->loadPakFile(file);
|
|
}
|
|
|
|
} // end of namespace Kyra
|
|
|