mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 01:46:42 +00:00
135 lines
4.1 KiB
C++
135 lines
4.1 KiB
C++
/* ResidualVM - A 3D game interpreter
|
|
*
|
|
* ResidualVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the AUTHORS
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#include "common/math.h"
|
|
|
|
#include "engines/myst3/scene.h"
|
|
#include "engines/myst3/myst3.h"
|
|
#include "engines/myst3/state.h"
|
|
|
|
#include "graphics/colormasks.h"
|
|
|
|
namespace Myst3 {
|
|
|
|
Scene::Scene(Myst3Engine *vm) :
|
|
_vm(vm)
|
|
{
|
|
}
|
|
|
|
void Scene::updateCamera(Common::Point &mouse) {
|
|
float pitch = _vm->_state->getLookAtPitch();
|
|
float heading = _vm->_state->getLookAtHeading();
|
|
|
|
if (!_vm->_state->getCursorLocked()) {
|
|
pitch -= mouse.y / 3.0f;
|
|
heading += mouse.x / 3.0f;
|
|
}
|
|
|
|
// Keep heading within allowed values
|
|
if (_vm->_state->isCameraLimited()) {
|
|
float minHeading = _vm->_state->getMinHeading();
|
|
float maxHeading = _vm->_state->getMaxHeading();
|
|
|
|
if (minHeading < maxHeading) {
|
|
heading = CLIP(heading, minHeading, maxHeading);
|
|
} else {
|
|
if (heading < minHeading && heading > maxHeading) {
|
|
uint distToMin = (uint)ABS(heading - minHeading);
|
|
uint distToMax = (uint)ABS(heading - maxHeading);
|
|
if (distToMin > distToMax)
|
|
heading = maxHeading;
|
|
else
|
|
heading = minHeading;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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();
|
|
|
|
if (_vm->_state->isCameraLimited()) {
|
|
minPitch = _vm->_state->getMinPitch();
|
|
maxPitch = _vm->_state->getMaxPitch();
|
|
}
|
|
|
|
pitch = CLIP(pitch, minPitch, maxPitch);
|
|
|
|
_vm->_state->lookAt(pitch, heading);
|
|
_vm->_state->setCameraPitch((int32)pitch);
|
|
_vm->_state->setCameraHeading((int32)heading);
|
|
}
|
|
|
|
void Scene::drawBlackBorders() {
|
|
Common::Rect top = Common::Rect(Renderer::kOriginalWidth, Renderer::kTopBorderHeight);
|
|
|
|
Common::Rect bottom = Common::Rect(Renderer::kOriginalWidth, Renderer::kBottomBorderHeight);
|
|
bottom.translate(0, Renderer::kTopBorderHeight + Renderer::kFrameHeight);
|
|
|
|
uint32 black = Graphics::ARGBToColor< Graphics::ColorMasks<8888> >(255, 0, 0, 0);
|
|
_vm->_gfx->drawRect2D(top, black);
|
|
_vm->_gfx->drawRect2D(bottom, black);
|
|
}
|
|
|
|
void Scene::drawSunspotFlare(const SunSpot &s) {
|
|
Common::Rect frame = Common::Rect(Renderer::kOriginalWidth, Renderer::kFrameHeight);
|
|
frame.translate(0, Renderer::kTopBorderHeight);
|
|
|
|
uint8 a = (uint8)(s.intensity * s.radius);
|
|
uint8 r, g, b;
|
|
Graphics::colorToRGB< Graphics::ColorMasks<888> >(s.color, r, g, b);
|
|
uint32 color = Graphics::ARGBToColor< Graphics::ColorMasks<8888> >(a, r, g, b);
|
|
|
|
_vm->_gfx->drawRect2D(frame, color);
|
|
}
|
|
|
|
|
|
static Math::Vector3d directionToVector(float pitch, float heading) {
|
|
Math::Vector3d v;
|
|
|
|
float radHeading = Common::deg2rad(heading);
|
|
float radPitch = Common::deg2rad(pitch);
|
|
|
|
v.setValue(0, cos(radPitch) * cos(radHeading));
|
|
v.setValue(1, sin(radPitch));
|
|
v.setValue(2, cos(radPitch) * sin(radHeading));
|
|
|
|
return v;
|
|
}
|
|
|
|
float Scene::distanceToZone(float spotHeading, float spotPitch, float spotRadius, float heading, float pitch) {
|
|
Math::Vector3d vLookAt = directionToVector(pitch, heading);
|
|
Math::Vector3d vSun = directionToVector(spotPitch, spotHeading);
|
|
float dotProduct = Math::Vector3d::dotProduct(vLookAt, -vSun);
|
|
|
|
float distance = (0.05 * spotRadius - (dotProduct + 1.0) * 90) / (0.05 * spotRadius);
|
|
return CLIP<float>(distance, 0.0, 1.0);
|
|
}
|
|
|
|
} // end of namespace Myst3
|