MYST3: Implement script driven camera movement
This commit is contained in:
parent
0ecc03f28f
commit
656c342af6
6 changed files with 79 additions and 0 deletions
|
@ -809,4 +809,61 @@ Common::Error Myst3Engine::loadGameState(int slot) {
|
|||
return Common::kUnknownError;
|
||||
}
|
||||
|
||||
void Myst3Engine::animateDirectionChange(float targetPitch, float targetHeading, uint16 scriptFrames) {
|
||||
float startPitch = _state->getLookAtPitch();
|
||||
float startHeading = _state->getLookAtHeading();
|
||||
|
||||
if (startPitch == targetPitch && startHeading == targetHeading)
|
||||
return; // Fast path
|
||||
|
||||
float pitchDistance = targetPitch - startPitch;
|
||||
float headingDistance = targetHeading - startHeading;
|
||||
|
||||
// Compute animation duration in frames
|
||||
float numFrames;
|
||||
if (scriptFrames) {
|
||||
numFrames = scriptFrames;
|
||||
} else {
|
||||
numFrames = sqrt(pitchDistance * pitchDistance + headingDistance * headingDistance)
|
||||
* 30.0f / _state->getCameraMoveSpeed();
|
||||
|
||||
if (numFrames > 0.0f)
|
||||
numFrames += 10.0f;
|
||||
}
|
||||
|
||||
uint startFrame = _state->getFrameCount();
|
||||
|
||||
// Draw animation
|
||||
if (numFrames != 0.0f) {
|
||||
while (1) {
|
||||
uint elapsedFrames = _state->getFrameCount() - startFrame;
|
||||
if (elapsedFrames >= numFrames)
|
||||
break;
|
||||
|
||||
float step;
|
||||
if (numFrames >= 15) {
|
||||
// Fast then slow movement
|
||||
if (elapsedFrames > numFrames / 2.0f)
|
||||
step = 1.0f - (numFrames - elapsedFrames) * (numFrames - elapsedFrames)
|
||||
/ (numFrames / 2.0f * numFrames / 2.0f) / 2.0f;
|
||||
else
|
||||
step = elapsedFrames * elapsedFrames / (numFrames / 2.0f * numFrames / 2.0f) / 2.0f;
|
||||
|
||||
} else {
|
||||
// Constant speed movement
|
||||
step = elapsedFrames / numFrames;
|
||||
}
|
||||
|
||||
float nextPitch = startPitch + pitchDistance * step;
|
||||
float nextHeading = startHeading + headingDistance * step;
|
||||
|
||||
_state->lookAt(nextPitch, nextHeading);
|
||||
drawFrame();
|
||||
}
|
||||
}
|
||||
|
||||
_state->lookAt(targetPitch, targetHeading);
|
||||
drawFrame();
|
||||
}
|
||||
|
||||
} // end of namespace Myst3
|
||||
|
|
|
@ -117,6 +117,8 @@ public:
|
|||
void setMenuAction(uint16 action) { _menuAction = action; }
|
||||
void setShouldQuit() { _shouldQuit = true; }
|
||||
|
||||
void animateDirectionChange(float pitch, float heading, uint16 speed);
|
||||
|
||||
void processInput(bool lookOnly);
|
||||
void drawFrame();
|
||||
private:
|
||||
|
|
|
@ -174,6 +174,8 @@ Script::Script(Myst3Engine *vm):
|
|||
OP_2(141, zipToRoomNode, kValue, kValue );
|
||||
OP_1(147, moviePlay, kEvalValue );
|
||||
OP_1(148, moviePlaySynchronized, kEvalValue );
|
||||
OP_2(153, lootAt, kValue, kValue );
|
||||
OP_3(154, lootAtInXFrames, kValue, kValue, kValue );
|
||||
OP_4(157, cameraLimitMovement, kValue, kValue, kValue, kValue );
|
||||
OP_0(158, cameraFreeMovement );
|
||||
OP_2(159, cameraLookAt, kValue, kValue );
|
||||
|
@ -1889,6 +1891,18 @@ void Script::runScriptWhileCondEachXFrames(Context &c, const Opcode &cmd) {
|
|||
_vm->drawFrame();
|
||||
}
|
||||
|
||||
void Script::lootAt(Context &c, const Opcode &cmd) {
|
||||
debugC(kDebugScript, "Opcode %d: Look at %d, %d", cmd.op, cmd.args[0], cmd.args[1]);
|
||||
|
||||
_vm->animateDirectionChange(cmd.args[0], cmd.args[1], 0);
|
||||
}
|
||||
|
||||
void Script::lootAtInXFrames(Context &c, const Opcode &cmd) {
|
||||
debugC(kDebugScript, "Opcode %d: Look at %d, %d in %d frames", cmd.op, cmd.args[0], cmd.args[1], cmd.args[2]);
|
||||
|
||||
_vm->animateDirectionChange(cmd.args[0], cmd.args[1], cmd.args[2]);
|
||||
}
|
||||
|
||||
void Script::runScriptForVarDrawFramesHelper(uint16 var, int32 startValue, int32 endValue, uint16 script, int32 numFrames) {
|
||||
if (numFrames < 0) {
|
||||
numFrames = -numFrames;
|
||||
|
|
|
@ -224,6 +224,8 @@ private:
|
|||
DECLARE_OPCODE(zipToRoomNode);
|
||||
DECLARE_OPCODE(moviePlay);
|
||||
DECLARE_OPCODE(moviePlaySynchronized);
|
||||
DECLARE_OPCODE(lootAt);
|
||||
DECLARE_OPCODE(lootAtInXFrames);
|
||||
DECLARE_OPCODE(cameraLimitMovement);
|
||||
DECLARE_OPCODE(cameraFreeMovement);
|
||||
DECLARE_OPCODE(cameraLookAt);
|
||||
|
|
|
@ -97,6 +97,8 @@ GameState::GameState(Myst3Engine *vm):
|
|||
|
||||
VAR(178, MovieUseBackground, false)
|
||||
|
||||
VAR(185, CameraMoveSpeed, false)
|
||||
|
||||
VAR(189, LocationNextNode, false)
|
||||
VAR(190, LocationNextRoom, false)
|
||||
VAR(191, LocationNextAge, false)
|
||||
|
|
|
@ -111,6 +111,8 @@ public:
|
|||
|
||||
DECLARE_VAR(178, MovieUseBackground)
|
||||
|
||||
DECLARE_VAR(185, CameraMoveSpeed)
|
||||
|
||||
DECLARE_VAR(189, LocationNextNode)
|
||||
DECLARE_VAR(190, LocationNextRoom)
|
||||
DECLARE_VAR(191, LocationNextAge)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue