From b9fa7eeffac4c4e1fd3a4e2da258dd302b82d30c Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sat, 28 Jan 2012 12:37:51 +0100 Subject: [PATCH] MYST3: Implement opcode 163 - Set camera FOV --- engines/myst3/cursor.cpp | 3 +-- engines/myst3/gfx.cpp | 11 +++++++++-- engines/myst3/gfx.h | 2 +- engines/myst3/myst3.cpp | 3 ++- engines/myst3/scene.cpp | 12 ++++++------ engines/myst3/script.cpp | 9 +++++++++ engines/myst3/script.h | 1 + engines/myst3/state.h | 2 ++ 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/engines/myst3/cursor.cpp b/engines/myst3/cursor.cpp index cae69d7ce81..ca1b0299f3c 100644 --- a/engines/myst3/cursor.cpp +++ b/engines/myst3/cursor.cpp @@ -152,8 +152,7 @@ void Cursor::draw() { void Cursor::setVisible(bool show) { if (show) - if (--_hideLevel < 0) - _hideLevel = 0; + _hideLevel = MAX(0, --_hideLevel); else _hideLevel++; } diff --git a/engines/myst3/gfx.cpp b/engines/myst3/gfx.cpp index 4ee1fb1d681..5d8a38b4be3 100644 --- a/engines/myst3/gfx.cpp +++ b/engines/myst3/gfx.cpp @@ -152,11 +152,18 @@ void Renderer::setupCameraOrtho2D() { glLoadIdentity(); } -void Renderer::setupCameraPerspective(float pitch, float heading) { +void Renderer::setupCameraPerspective(float pitch, float heading, float fov) { + // TODO: Find a correct and exact formula for the FOV + GLfloat glFOV = 0.63 * fov; // Approximative and experimental formula + if (fov > 79.0 && fov < 81.0) + glFOV = 50.5; // Somewhat good value for fov == 80 + else if (fov > 59.0 && fov < 61.0) + glFOV = 36.0; // Somewhat good value for fov == 60 + glViewport(0, kBottomBorderHeight, kOriginalWidth, kFrameHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(50.5, (GLfloat)kOriginalWidth / (GLfloat)kFrameHeight, 1.0, 10000.0); + gluPerspective(glFOV, (GLfloat)kOriginalWidth / (GLfloat)kFrameHeight, 1.0, 10000.0); // Rotate the model to simulate the rotation of the camera glMatrixMode(GL_MODELVIEW); diff --git a/engines/myst3/gfx.h b/engines/myst3/gfx.h index 1d6d77996aa..6db9c962af9 100644 --- a/engines/myst3/gfx.h +++ b/engines/myst3/gfx.h @@ -58,7 +58,7 @@ public: void clear(); void setupCameraOrtho2D(); - void setupCameraPerspective(float pitch, float heading); + void setupCameraPerspective(float pitch, float heading, float fov); Texture *createTexture(const Graphics::Surface *surface); void freeTexture(Texture *texture); diff --git a/engines/myst3/myst3.cpp b/engines/myst3/myst3.cpp index 1e358ae12b1..44544d3c862 100644 --- a/engines/myst3/myst3.cpp +++ b/engines/myst3/myst3.cpp @@ -359,7 +359,8 @@ void Myst3Engine::drawFrame() { if (_state->getViewType() == kCube) { float pitch = _state->getLookAtPitch(); float heading = _state->getLookAtHeading(); - _gfx->setupCameraPerspective(pitch, heading); + float fov = _state->getLookAtFOV(); + _gfx->setupCameraPerspective(pitch, heading, fov); } else { _gfx->setupCameraOrtho2D(); } diff --git a/engines/myst3/scene.cpp b/engines/myst3/scene.cpp index 6d6be6dc31c..c80a7ed9526 100644 --- a/engines/myst3/scene.cpp +++ b/engines/myst3/scene.cpp @@ -43,12 +43,6 @@ void Scene::updateCamera(Common::Point &mouse) { heading += mouse.x / 3.0f; } - // Keep heading in 0..360 range - if (heading > 360.0f) - heading -= 360.0f; - else if (heading < 0.0f) - heading += 360.0f; - // Keep heading within allowed values if (_vm->_state->isCameraLimited()) { float minHeading = _vm->_state->getMinHeading(); @@ -68,6 +62,12 @@ void Scene::updateCamera(Common::Point &mouse) { } } + // Keep heading in 0..360 range + if (heading > 360.0f) + heading -= 360.0f; + else if (heading < 0.0f) + heading += 360.0f; + // Keep pitch within allowed values float minPitch = _vm->_state->getCameraMinPitch(); float maxPitch = _vm->_state->getCameraMaxPitch(); diff --git a/engines/myst3/script.cpp b/engines/myst3/script.cpp index cfdfb68d00e..a62db215f9f 100644 --- a/engines/myst3/script.cpp +++ b/engines/myst3/script.cpp @@ -188,6 +188,7 @@ Script::Script(Myst3Engine *vm): OP_1(160, cameraLookAtVar, kVar ); OP_1(161, cameraGetLookAt, kVar ); OP_1(162, lootAtMovieStartImmediate, kEvalValue ); + OP_1(163, cameraSetFOV, kEvalValue ); OP_1(164, changeNode, kValue ); OP_2(165, changeNodeRoom, kValue, kValue ); OP_3(166, changeNodeRoomAge, kValue, kValue, kValue ); @@ -1835,6 +1836,14 @@ void Script::lootAtMovieStartImmediate(Context &c, const Opcode &cmd) { _vm->_state->lookAt(startPitch, startHeading); } +void Script::cameraSetFOV(Context &c, const Opcode &cmd) { + debugC(kDebugScript, "Opcode %d: Set camera fov %d", cmd.op, cmd.args[0]); + + int32 fov = _vm->_state->valueOrVarValue(cmd.args[0]); + + _vm->_state->setLookAtFOV(fov); +} + void Script::changeNode(Context &c, const Opcode &cmd) { debugC(kDebugScript, "Opcode %d: Go to node %d", cmd.op, cmd.args[0]); diff --git a/engines/myst3/script.h b/engines/myst3/script.h index cf854373b15..e66fa2275a5 100644 --- a/engines/myst3/script.h +++ b/engines/myst3/script.h @@ -238,6 +238,7 @@ private: DECLARE_OPCODE(cameraLookAtVar); DECLARE_OPCODE(cameraGetLookAt); DECLARE_OPCODE(lootAtMovieStartImmediate); + DECLARE_OPCODE(cameraSetFOV); DECLARE_OPCODE(changeNode); DECLARE_OPCODE(changeNodeRoom); DECLARE_OPCODE(changeNodeRoomAge); diff --git a/engines/myst3/state.h b/engines/myst3/state.h index 909d0d4d664..5eb9e91c063 100644 --- a/engines/myst3/state.h +++ b/engines/myst3/state.h @@ -166,6 +166,8 @@ public: ViewType getViewType() { return static_cast(_data.currentNodeType); } void setViewType(ViewType t) { _data.currentNodeType = t; } + float getLookAtFOV() { return _data.lookatFOV; } + void setLookAtFOV(float fov) { _data.lookatFOV = fov; } float getLookAtPitch() { return _data.lookatPitch; } float getLookAtHeading() { return _data.lookatHeading; } void lookAt(float pitch, float heading) { _data.lookatPitch = pitch; _data.lookatHeading = heading; }