aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2008-04-20 02:11:10 +0000
committerJohannes Schickel2008-04-20 02:11:10 +0000
commit2db899d1c70ddb703b39555ca59d6402fb3a96ae (patch)
treeec8e56225bd613ecc9190bc635674c0a52f573b7 /engines/kyra
parent24e3ba7154d498adcd59ff69809b93768bc38b10 (diff)
downloadscummvm-rg350-2db899d1c70ddb703b39555ca59d6402fb3a96ae.tar.gz
scummvm-rg350-2db899d1c70ddb703b39555ca59d6402fb3a96ae.tar.bz2
scummvm-rg350-2db899d1c70ddb703b39555ca59d6402fb3a96ae.zip
- fixed various glitches
- implemented some input code for kyra3 svn-id: r31588
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/animator_v3.cpp14
-rw-r--r--engines/kyra/kyra_v3.cpp149
-rw-r--r--engines/kyra/kyra_v3.h15
-rw-r--r--engines/kyra/scene_v3.cpp161
4 files changed, 321 insertions, 18 deletions
diff --git a/engines/kyra/animator_v3.cpp b/engines/kyra/animator_v3.cpp
index 6ba5d29003..e28d6ab8ec 100644
--- a/engines/kyra/animator_v3.cpp
+++ b/engines/kyra/animator_v3.cpp
@@ -224,7 +224,7 @@ void KyraEngine_v3::drawCharacterAnimObject(AnimObj *obj, int x, int y, int laye
if (obj->shapeIndex == 0xFFFF || _mainCharacter.animFrame == 87)
return;
- _screen->drawShape(2, getShapePtr(421), _mainCharacter.x3, _mainCharacter.y3, 2, obj->flags | 304, _paletteOverlay, 3, layer, _charScale, _charScale);
+ _screen->drawShape(2, getShapePtr(421), _mainCharacter.x3, _mainCharacter.y3, 2, obj->flags | 0x304, _paletteOverlay, 3, layer, _charScale, _charScale);
uint8 *shape = getShapePtr(_mainCharacter.animFrame);
if (shape)
_screen->drawShape(2, shape, x, y, 2, obj->flags | 4, layer, _charScale, _charScale);
@@ -307,11 +307,13 @@ void KyraEngine_v3::updateCharacterAnim(int charId) {
obj->shapeIndex = obj->shapeIndex2 = _mainCharacter.animFrame;
int shapeOffsetX = 0, shapeOffsetY = 0;
- //XXX if (_mainCharacter.animFrame >= 50 && _mainCharacter.animFrame <= 87) {
+ if (_mainCharacter.animFrame >= 50 && _mainCharacter.animFrame <= 87) {
shapeOffsetX = _malcolmShapeXOffset;
shapeOffsetY = _malcolmShapeYOffset;
- //} else {
- //}
+ } else {
+ shapeOffsetX = _newShapeXAdd;
+ shapeOffsetY = _newShapeYAdd;
+ }
obj->xPos2 = _mainCharacter.x1;
obj->yPos2 = _mainCharacter.y1;
@@ -320,10 +322,10 @@ void KyraEngine_v3::updateCharacterAnim(int charId) {
obj->yPos2 += (shapeOffsetY * _charScale) >> 8;
_mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1;
_mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1;
- //if (_charSpecialWidth2 == -1) {
+ if (_charBackUpWidth2 == -1) {
obj->width2 = 4;
obj->height2 = 10;
- //}
+ }
for (int i = 1; i <= 16; ++i) {
if (_animObjects[i].enabled && _animObjects[i].unk8)
diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp
index dc59d1966f..b87cd8b9a2 100644
--- a/engines/kyra/kyra_v3.cpp
+++ b/engines/kyra/kyra_v3.cpp
@@ -108,6 +108,9 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi
_curStudioSFX = 283;
_badConscienceShown = false;
_curChapter = 1;
+ _deathHandler = -1;
+ _moveFacingTable = 0;
+ _unkHandleSceneChangeFlag = false;
}
KyraEngine_v3::~KyraEngine_v3() {
@@ -151,6 +154,7 @@ KyraEngine_v3::~KyraEngine_v3() {
delete [] _sceneStrings;
delete [] _talkObjectList;
+ delete [] _moveFacingTable;
}
int KyraEngine_v3::init() {
@@ -219,6 +223,7 @@ int KyraEngine_v3::go() {
fadeOutMusic(60);
_screen->fadeToBlack();
+ _musicSoundChannel = -1;
startup();
runLoop();
running = false;
@@ -499,7 +504,7 @@ void KyraEngine_v3::startup() {
//XXX
musicUpdate(0);
- //XXX
+ _moveFacingTable = new int[600];
_costPalBuffer = new uint8[864];
//XXX
_animObjects = new AnimObj[67];
@@ -840,18 +845,19 @@ void KyraEngine_v3::updateCharPosWithUpdate() {
update();
}
-void KyraEngine_v3::updateCharPos(uint8 *table, int force) {
- debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%p, %d)", table, force);
- if (!force || (_updateCharPosNextUpdate > _system->getMillis()))
- return;
+int KyraEngine_v3::updateCharPos(int *table, int force) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%p, %d)", (const void*)table, force);
+ if (_updateCharPosNextUpdate > _system->getMillis() && !force)
+ return 0;
_mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing];
_mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing];
updateCharAnimFrame(0, table);
_updateCharPosNextUpdate = _system->getMillis() + _mainCharacter.walkspeed * _tickLength;
+ return 1;
}
-void KyraEngine_v3::updateCharAnimFrame(int character, uint8 *table) {
- debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%d, %p)", character, table);
+void KyraEngine_v3::updateCharAnimFrame(int character, int *table) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%d, %p)", character, (const void*)table);
++_mainCharacter.animFrame;
int facing = _mainCharacter.facing;
@@ -952,6 +958,23 @@ void KyraEngine_v3::updateCharPal(int unk1) {
}
}
+bool KyraEngine_v3::checkCharCollision(int x, int y) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::checkCharCollision(%d, %d)", x, y);
+
+ int scale = getScale(_mainCharacter.x1, _mainCharacter.y1);
+ int width = (scale * 37) >> 8;
+ int height = (scale * 76) >> 8;
+
+ int x1 = _mainCharacter.x1 - width/2;
+ int x2 = _mainCharacter.x2 + width/2;
+ int y1 = _mainCharacter.y1 - height;
+ int y2 = _mainCharacter.y2;
+
+ if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
+ return true;
+ return false;
+}
+
#pragma mark -
void KyraEngine_v3::runLoop() {
@@ -979,6 +1002,118 @@ void KyraEngine_v3::runLoop() {
void KyraEngine_v3::handleInput(int x, int y) {
debugC(9, kDebugLevelMain, "KyraEngine_v3::handleInput(%d, %d)", x, y);
+ if (_inventoryState)
+ return;
+ //setNextIdleAnimTimer();
+
+ if (_unk5) {
+ _unk5 = 0;
+ return;
+ }
+
+ if (!_screen->isMouseVisible())
+ return;
+
+ if (_unk3 == -3) {
+ playSoundEffect(0x0D, 0x80);
+ return;
+ }
+
+ //setNextIdleAnimTimer();
+
+ int skip = 0;
+
+ if (checkCharCollision(x, y) && _unk3 >= -1 && runSceneScript2()) {
+ return;
+ } else if (_itemInHand == 27) {
+ return;
+ } else if (checkItemCollision(x, y) == -1) {
+ resetGameFlag(1);
+ skip = runSceneScript1(x, y);
+
+ if (queryGameFlag(1)) {
+ resetGameFlag(1);
+ return;
+ } else if (_unk5) {
+ _unk5 = 0;
+ return;
+ }
+ }
+
+ if (_deathHandler >= 0)
+ skip = 1;
+
+ if (skip)
+ return;
+
+ if (checkCharCollision(x, y)) {
+ if (runSceneScript2())
+ return;
+ } else if (_itemInHand >= 0 && _unk3 >= 0) {
+ //XXX
+ return;
+ } else if (_unk3 != -3) {
+ if (y > 187 && _unk3 > -4)
+ return;
+ if (_unk5) {
+ _unk5 = 0;
+ return;
+ }
+ }
+
+ inputSceneChange(x, y, 1, 1);
+}
+
+int KyraEngine_v3::inputSceneChange(int x, int y, int unk1, int unk2) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::inputSceneChange(%d, %d, %d, %d)", x, y, unk1, unk2);
+ uint16 curScene = _mainCharacter.sceneId;
+ _pathfinderFlag = 15;
+
+ if (!_unkHandleSceneChangeFlag) {
+ if (_unk3 == -4) {
+ if (_sceneList[curScene].exit4 != 0xFFFF) {
+ x = 4;
+ y = _sceneEnterY4;
+ _pathfinderFlag = 7;
+ }
+ } else if (_unk3 == -6) {
+ if (_sceneList[curScene].exit2 != 0xFFFF) {
+ x = 316;
+ y = _sceneEnterY2;
+ _pathfinderFlag = 7;
+ }
+ } else if (_unk3 == -7) {
+ if (_sceneList[curScene].exit1 != 0xFFFF) {
+ x = _sceneEnterX1;
+ y = _sceneEnterY1 - 2;
+ _pathfinderFlag = 14;
+ }
+ } else if (_unk3 == -5) {
+ if (_sceneList[curScene].exit3 != 0xFFFF) {
+ x = _sceneEnterX3;
+ y = 191;
+ _pathfinderFlag = 11;
+ }
+ }
+ }
+
+ if (ABS(_mainCharacter.x1 - x) < 4 && ABS(_mainCharacter.y1 - y) < 2) {
+ _pathfinderFlag = 0;
+ return 0;
+ }
+
+ int x1 = _mainCharacter.x1 & (~3);
+ int y1 = _mainCharacter.y1 & (~1);
+ x &= ~3;
+ y &= ~1;
+
+ int size = findWay(x1, y1, x, y, _moveFacingTable, 600);
+ _pathfinderFlag = 0;
+
+ if (!size || size == 0x7D00)
+ return 0;
+
+ return trySceneChange(_moveFacingTable, unk1, unk2);
}
void KyraEngine_v3::update() {
diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h
index 7f6e556d7a..1ce2cbe47e 100644
--- a/engines/kyra/kyra_v3.h
+++ b/engines/kyra/kyra_v3.h
@@ -71,9 +71,12 @@ private:
// run
bool _runFlag;
+ int _deathHandler;
void runLoop();
void handleInput(int x, int y);
+ bool _unkHandleSceneChangeFlag;
+ int inputSceneChange(int x, int y, int unk1, int unk2);
void update();
void updateWithText();
@@ -158,8 +161,10 @@ private:
void timerFleaDeath(int arg);
// pathfinder
+ int *_moveFacingTable;
int _pathfinderFlag;
+ int findWay(int x1, int y1, int x2, int y2, int *moveTable, int moveTableSize);
bool lineIsPassable(int x, int y);
private:
@@ -360,6 +365,8 @@ private:
void initSceneAnims(int unk1);
void initSceneScreen(int unk1);
+ int runSceneScript1(int x, int y);
+ int runSceneScript2();
bool _noStartupChat;
void runSceneScript4(int unk1);
void runSceneScript8();
@@ -379,6 +386,9 @@ private:
void updateSpecialSceneScripts();
+ int trySceneChange(int *moveTable, int unk1, int unk2);
+ int checkSceneChange();
+
int8 _sceneDatPalette[45];
int8 _sceneDatLayerTable[15];
@@ -411,13 +421,13 @@ private:
void moveCharacter(int facing, int x, int y);
void updateCharPosWithUpdate();
- void updateCharPos(uint8 *table, int force);
+ int updateCharPos(int *table, int force);
uint32 _updateCharPosNextUpdate;
static const int8 _updateCharPosXTable[];
static const int8 _updateCharPosYTable[];
- void updateCharAnimFrame(int character, uint8 *table);
+ void updateCharAnimFrame(int character, int *table);
int8 _characterAnimTable[2];
static const uint8 _characterFrameTable[];
@@ -427,6 +437,7 @@ private:
int _lastCharPalLayer;
bool _charPalUpdate;
+ bool checkCharCollision(int x, int y);
// talk object
struct TalkObject {
diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp
index ee4c2ecd6d..e08b3e2bf6 100644
--- a/engines/kyra/scene_v3.cpp
+++ b/engines/kyra/scene_v3.cpp
@@ -116,7 +116,7 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
//XXX resetMaskPage();
for (int i = 0; i < 4; ++i) {
- if (i == _musicSoundChannel || i == _fadeOutMusicChannel)
+ if (i != _musicSoundChannel && i != _fadeOutMusicChannel)
_soundDigital->stopSound(i);
}
_fadeOutMusicChannel = -1;
@@ -136,9 +136,11 @@ void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
_sceneExit3 = _sceneList[sceneId].exit3;
_sceneExit4 = _sceneList[sceneId].exit4;
- while (_system->getMillis() > waitUntilTimer)
+
+ while (_system->getMillis() < waitUntilTimer)
_system->delayMillis(10);
+
musicUpdate(0);
initSceneScript(unk3);
musicUpdate(0);
@@ -658,6 +660,151 @@ void KyraEngine_v3::updateSpecialSceneScripts() {
}
}
+int KyraEngine_v3::trySceneChange(int *moveTable, int unk1, int updateChar) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::trySceneChange(%p, %d, %d)", (const void*)moveTable, unk1, updateChar);
+ bool running = true;
+ bool unkFlag = false;
+ int changedScene = 0;
+ const int *moveTableStart = moveTable;
+ _unk4 = 0;
+
+ while (running && !_quitFlag) {
+ if (*moveTable >= 0 && *moveTable <= 7) {
+ _mainCharacter.facing = getOppositeFacingDirection(*moveTable);
+ unkFlag = true;
+ } else {
+ if (*moveTable == 8) {
+ running = false;
+ } else {
+ ++moveTable;
+ unkFlag = false;
+ }
+ }
+
+ if (checkSceneChange()) {
+ running = false;
+ changedScene = 1;
+ }
+
+ if (unk1) {
+ if (skipFlag()) {
+ resetSkipFlag(false);
+ running = false;
+ _unk4 = 1;
+ }
+ }
+
+ if (!unkFlag || !running)
+ continue;
+
+ int ret = 0;
+ if (moveTable == moveTableStart || moveTable[1] == 8)
+ ret = updateCharPos(0, 0);
+ else
+ ret = updateCharPos(moveTable, 0);
+
+ if (ret)
+ ++moveTable;
+
+ update();
+ }
+
+ if (updateChar)
+ _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+
+ updateCharacterAnim(0);
+ refreshAnimObjectsIfNeed();
+
+ return changedScene;
+}
+
+int KyraEngine_v3::checkSceneChange() {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::checkSceneChange()");
+ const SceneDesc &curScene = _sceneList[_mainCharacter.sceneId];
+ int charX = _mainCharacter.x1, charY = _mainCharacter.y1;
+ int facing = 0;
+ int process = 0;
+
+ if (_screen->getLayer(charX, charY) == 1 && _unk3 == -7) {
+ facing = 0;
+ process = 1;
+ } else if (charX >= 316 && _unk3 == -6) {
+ facing = 2;
+ process = 1;
+ } else if (charY >= 186 && _unk3 == -5) {
+ facing = 4;
+ process = 1;
+ } else if (charX <= 4 && _unk3 == -4) {
+ facing = 6;
+ process = 1;
+ }
+
+ if (!process)
+ return 0;
+
+ uint16 newScene = 0xFFFF;
+ switch (facing) {
+ case 0:
+ newScene = curScene.exit1;
+ break;
+
+ case 2:
+ newScene = curScene.exit2;
+ break;
+
+ case 4:
+ newScene = curScene.exit3;
+ break;
+
+ case 6:
+ newScene = curScene.exit4;
+ break;
+
+ default:
+ newScene = _mainCharacter.sceneId;
+ break;
+ }
+
+ if (newScene == 0xFFFF)
+ return 0;
+
+ enterNewScene(newScene, facing, 1, 1, 0);
+ return 1;
+}
+int KyraEngine_v3::runSceneScript1(int x, int y) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript1(%d, %d)", x, y);
+ if (y > 187 && _unk3 > -4)
+ return 0;
+ if (_deathHandler >= 0)
+ return 0;
+
+ _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData);
+ _sceneScriptState.regs[1] = x;
+ _sceneScriptState.regs[2] = y;
+ _sceneScriptState.regs[3] = 0;
+ _sceneScriptState.regs[4] = _itemInHand;
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 1);
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+
+ return _sceneScriptState.regs[3];
+}
+
+int KyraEngine_v3::runSceneScript2() {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript2()");
+ _sceneScriptState.regs[1] = _mouseX;
+ _sceneScriptState.regs[2] = _mouseY;
+ _sceneScriptState.regs[3] = 0;
+ _sceneScriptState.regs[4] = _itemInHand;
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 2);
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+
+ return _sceneScriptState.regs[3];
+}
+
void KyraEngine_v3::runSceneScript4(int unk1) {
debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript4(%d)", unk1);
_sceneScriptState.regs[4] = _itemInHand;
@@ -691,6 +838,14 @@ bool KyraEngine_v3::checkSpecialSceneExit(int index, int x, int y) {
return false;
}
+int KyraEngine_v3::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v3::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize);
+ int ret = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize);
+ if (ret == 0x7D00)
+ return 0;
+ return getMoveTableSize(moveTable);
+}
+
bool KyraEngine_v3::lineIsPassable(int x, int y) {
debugC(9, kDebugLevelMain, "KyraEngine_v3::lineIsPassable(%d, %d)", x, y);
static const uint8 widthTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 };
@@ -716,7 +871,7 @@ bool KyraEngine_v3::lineIsPassable(int x, int y) {
x2 = 320;
for (; x < x2; ++x) {
- if (y < _maskPageMinY || y > _maskPageMinY)
+ if (y < _maskPageMinY || y > _maskPageMaxY)
return false;
if (!_screen->getShapeFlag1(x, y))