mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-22 01:39:57 +00:00
MYST3: Make the engine resolution-agnostic
This commit is contained in:
parent
ed7a4355e9
commit
7a33ec4a00
@ -57,7 +57,7 @@ static CursorData availableCursors[13] = {
|
||||
|
||||
Cursor::Cursor(Myst3Engine *vm) :
|
||||
_vm(vm),
|
||||
_position(320, 210),
|
||||
_position(vm->_gfx->frameCenter()),
|
||||
_hideLevel(0),
|
||||
_lockedAtCenter(false) {
|
||||
|
||||
@ -127,25 +127,37 @@ void Cursor::lockPosition(bool lock) {
|
||||
|
||||
g_system->lockMouse(lock);
|
||||
|
||||
Common::Point center = _vm->_gfx->frameCenter();
|
||||
if (_lockedAtCenter) {
|
||||
// Locking, just mouve the cursor at the center of the screen
|
||||
_position.x = 320;
|
||||
_position.y = 210;
|
||||
_position = center;
|
||||
} else {
|
||||
// Unlocking, warp the actual mouse position to the cursor
|
||||
g_system->warpMouse(320, 210);
|
||||
g_system->warpMouse(center.x, center.y);
|
||||
}
|
||||
}
|
||||
|
||||
void Cursor::updatePosition(Common::Point &mouse) {
|
||||
if (!_lockedAtCenter) {
|
||||
_position = mouse;
|
||||
|
||||
_position.x = CLIP<int16>(_position.x, 0, Renderer::kOriginalWidth);
|
||||
_position.y = CLIP<int16>(_position.y, 0, Renderer::kOriginalHeight);
|
||||
}
|
||||
}
|
||||
|
||||
Common::Point Cursor::getPosition() {
|
||||
Common::Rect viewport = _vm->_gfx->viewport();
|
||||
|
||||
// The rest of the engine expects 640x480 coordinates
|
||||
Common::Point scaledPosition = _position;
|
||||
scaledPosition.x -= viewport.left;
|
||||
scaledPosition.y -= viewport.top;
|
||||
scaledPosition.x = CLIP<int16>(scaledPosition.x, 0, viewport.width());
|
||||
scaledPosition.y = CLIP<int16>(scaledPosition.y, 0, viewport.height());
|
||||
scaledPosition.x *= Renderer::kOriginalWidth / (float)viewport.width();
|
||||
scaledPosition.y *= Renderer::kOriginalHeight / (float)viewport.height();
|
||||
|
||||
return scaledPosition;
|
||||
}
|
||||
|
||||
void Cursor::draw() {
|
||||
CursorData &cursor = availableCursors[_currentCursorID];
|
||||
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
bool isPositionLocked() { return _lockedAtCenter; }
|
||||
void lockPosition(bool lock);
|
||||
|
||||
Common::Point getPosition() { return _position; }
|
||||
Common::Point getPosition();
|
||||
void updatePosition(Common::Point &mouse);
|
||||
|
||||
void getDirection(float &pitch, float &heading);
|
||||
|
@ -67,4 +67,37 @@ Common::Rect BaseRenderer::getFontCharacterRect(uint8 character) {
|
||||
return Common::Rect(16 * index, 0, 16 * (index + 1), 32);
|
||||
}
|
||||
|
||||
Common::Rect BaseRenderer::viewport() const {
|
||||
return _screenViewport;
|
||||
}
|
||||
|
||||
Common::Rect BaseRenderer::frameViewport() const {
|
||||
Common::Rect screen = viewport();
|
||||
|
||||
Common::Rect frame = Common::Rect(screen.width(), screen.height() * kFrameHeight / kOriginalHeight);
|
||||
frame.translate(screen.left, screen.top + screen.height() * kBottomBorderHeight / kOriginalHeight);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
void BaseRenderer::computeScreenViewport() {
|
||||
int32 screenWidth = _system->getWidth();
|
||||
int32 screenHeight = _system->getHeight();
|
||||
|
||||
// Aspect ratio correction
|
||||
int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
|
||||
int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
|
||||
_screenViewport = Common::Rect(viewportWidth, viewportHeight);
|
||||
|
||||
// Pillarboxing
|
||||
_screenViewport.translate((screenWidth - viewportWidth) / 2,
|
||||
(screenHeight - viewportHeight) / 2);
|
||||
}
|
||||
|
||||
Common::Point BaseRenderer::frameCenter() const {
|
||||
Common::Rect screen = viewport();
|
||||
Common::Rect frame = frameViewport();
|
||||
return Common::Point((frame.left + frame.right) / 2, screen.top + screen.bottom - (frame.top + frame.bottom) / 2);
|
||||
}
|
||||
|
||||
} // End of namespace Myst3
|
||||
|
@ -51,11 +51,11 @@ protected:
|
||||
class Renderer {
|
||||
public:
|
||||
virtual ~Renderer() {}
|
||||
virtual void init(Graphics::PixelBuffer &screenBuffer) = 0;
|
||||
virtual void init() = 0;
|
||||
virtual void initFont(const Graphics::Surface *surface) = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
virtual void setupCameraOrtho2D() = 0;
|
||||
virtual void setupCameraOrtho2D(bool noScaling) = 0;
|
||||
virtual void setupCameraPerspective(float pitch, float heading, float fov) = 0;
|
||||
|
||||
virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
|
||||
@ -75,6 +75,10 @@ class Renderer {
|
||||
|
||||
virtual void screenPosToDirection(const Common::Point screen, float &pitch, float &heading) = 0;
|
||||
|
||||
virtual Common::Rect viewport() const = 0;
|
||||
virtual Common::Rect frameViewport() const = 0;
|
||||
virtual Common::Point frameCenter() const = 0;
|
||||
|
||||
/**
|
||||
* Swap the buffers, making the drawn screen visible
|
||||
*/
|
||||
@ -98,11 +102,18 @@ public:
|
||||
virtual void init(Graphics::PixelBuffer &screenBuffer);
|
||||
virtual void initFont(const Graphics::Surface *surface);
|
||||
|
||||
Common::Rect viewport() const override;
|
||||
Common::Rect frameViewport() const override;
|
||||
Common::Point frameCenter() const override;
|
||||
|
||||
protected:
|
||||
OSystem *_system;
|
||||
Texture *_font;
|
||||
|
||||
Common::Rect _screenViewport;
|
||||
|
||||
Common::Rect getFontCharacterRect(uint8 character);
|
||||
void computeScreenViewport();
|
||||
};
|
||||
|
||||
Renderer *CreateGfxOpenGL(OSystem *system);
|
||||
|
@ -26,12 +26,14 @@
|
||||
#undef ARRAYSIZE
|
||||
#endif
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#if defined(USE_OPENGL) && !defined(USE_GLES2) && !defined(USE_OPENGL_SHADERS)
|
||||
|
||||
#include "graphics/colormasks.h"
|
||||
#include "graphics/pixelbuffer.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "math/vector2d.h"
|
||||
@ -105,9 +107,13 @@ void OpenGLRenderer::freeTexture(Texture *texture) {
|
||||
delete glTexture;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::init(Graphics::PixelBuffer &screenBuffer) {
|
||||
void OpenGLRenderer::init() {
|
||||
debug("Initializing OpenGL Renderer");
|
||||
|
||||
bool fullscreen = ConfMan.getBool("fullscreen");
|
||||
_system->setupScreen(kOriginalWidth, kOriginalHeight, fullscreen, true);
|
||||
computeScreenViewport();
|
||||
|
||||
// Check the available OpenGL extensions
|
||||
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
if (strstr(extensions, "GL_ARB_texture_non_power_of_two"))
|
||||
@ -131,11 +137,21 @@ void OpenGLRenderer::clear() {
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setupCameraOrtho2D() {
|
||||
glViewport(0, 0, kOriginalWidth, kOriginalHeight);
|
||||
void OpenGLRenderer::setupCameraOrtho2D(bool noScaling) {
|
||||
if (noScaling) {
|
||||
glViewport(0, 0, _system->getWidth(), _system->getHeight());
|
||||
} else {
|
||||
glViewport(_screenViewport.left, _screenViewport.top, _screenViewport.width(), _screenViewport.height());
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
|
||||
|
||||
if (noScaling) {
|
||||
glOrtho(0.0, _system->getWidth(), _system->getHeight(), 0.0, -1.0, 1.0);
|
||||
} else {
|
||||
glOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
@ -149,7 +165,8 @@ void OpenGLRenderer::setupCameraPerspective(float pitch, float heading, float fo
|
||||
else if (fov > 59.0 && fov < 61.0)
|
||||
glFOV = 36.0; // Somewhat good value for fov == 60
|
||||
|
||||
glViewport(0, kBottomBorderHeight, kOriginalWidth, kFrameHeight);
|
||||
Common::Rect frame = frameViewport();
|
||||
glViewport(frame.left, frame.top, frame.width(), frame.height());
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
Math::Matrix4 m = Math::makePerspectiveMatrix(glFOV, (GLfloat)kOriginalWidth / (GLfloat)kFrameHeight, 1.0, 10000.0);
|
||||
@ -346,10 +363,12 @@ void OpenGLRenderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Mat
|
||||
}
|
||||
|
||||
Graphics::Surface *OpenGLRenderer::getScreenshot() {
|
||||
Graphics::Surface *s = new Graphics::Surface();
|
||||
s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
Common::Rect screen = viewport();
|
||||
|
||||
glReadPixels(0, 0, kOriginalWidth, kOriginalHeight, GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
|
||||
Graphics::Surface *s = new Graphics::Surface();
|
||||
s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
|
||||
glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -357,7 +376,7 @@ Graphics::Surface *OpenGLRenderer::getScreenshot() {
|
||||
void OpenGLRenderer::screenPosToDirection(const Common::Point screen, float &pitch, float &heading) {
|
||||
// Screen coords to 3D coords
|
||||
Math::Vector3d obj;
|
||||
Math::gluMathUnProject<double, int>(Math::Vector3d(screen.x, kOriginalHeight - screen.y, 0.9),
|
||||
Math::gluMathUnProject<double, int>(Math::Vector3d(screen.x, _system->getHeight() - screen.y, 0.9),
|
||||
_cubeModelViewMatrix, _cubeProjectionMatrix, _cubeViewport, obj);
|
||||
|
||||
// 3D coords to polar coords
|
||||
|
@ -36,10 +36,10 @@ public:
|
||||
OpenGLRenderer(OSystem *_system);
|
||||
virtual ~OpenGLRenderer();
|
||||
|
||||
virtual void init(Graphics::PixelBuffer &screenBuffer) override;
|
||||
virtual void init() override;
|
||||
|
||||
virtual void clear() override;
|
||||
virtual void setupCameraOrtho2D() override;
|
||||
virtual void setupCameraOrtho2D(bool noScaling) override;
|
||||
virtual void setupCameraPerspective(float pitch, float heading, float fov) override;
|
||||
|
||||
Texture *createTexture(const Graphics::Surface *surface) override;
|
||||
|
@ -42,14 +42,17 @@
|
||||
#undef ARRAYSIZE
|
||||
#endif
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
|
||||
|
||||
#include "graphics/colormasks.h"
|
||||
#include "graphics/pixelbuffer.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "math/glmath.h"
|
||||
#include "math/vector2d.h"
|
||||
#include "math/rect2d.h"
|
||||
#include "math/quat.h"
|
||||
@ -116,15 +119,15 @@ void ShaderRenderer::setupQuadEBO() {
|
||||
_quadEBO = Graphics::Shader::createBuffer(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_indices), quad_indices, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
static Math::Vector2d scaled(float x, float y) {
|
||||
return Math::Vector2d(x / Renderer::kOriginalWidth, y / Renderer::kOriginalHeight);
|
||||
Math::Vector2d ShaderRenderer::scaled(float x, float y) const {
|
||||
return Math::Vector2d(x / _currentViewport.getWidth(), y / _currentViewport.getHeight());
|
||||
}
|
||||
|
||||
ShaderRenderer::ShaderRenderer(OSystem *system) :
|
||||
BaseRenderer(system),
|
||||
_prevText(""),
|
||||
_prevTextPosition(0,0),
|
||||
_viewport(Math::Vector2d(0.0, 0.0), Math::Vector2d(kOriginalWidth, kOriginalHeight)),
|
||||
_currentViewport(Math::Vector2d(0.0, 0.0), Math::Vector2d(kOriginalWidth, kOriginalHeight)),
|
||||
_box_shader(nullptr),
|
||||
_cube_shader(nullptr),
|
||||
_rect3d_shader(nullptr),
|
||||
@ -158,9 +161,13 @@ void ShaderRenderer::freeTexture(Texture *texture) {
|
||||
delete glTexture;
|
||||
}
|
||||
|
||||
void ShaderRenderer::init(Graphics::PixelBuffer &screenBuffer) {
|
||||
void ShaderRenderer::init() {
|
||||
debug("Initializing OpenGL Renderer with shaders");
|
||||
|
||||
bool fullscreen = ConfMan.getBool("fullscreen");
|
||||
_system->setupScreen(kOriginalWidth, kOriginalHeight, fullscreen, true);
|
||||
computeScreenViewport();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
@ -192,9 +199,14 @@ void ShaderRenderer::clear() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void ShaderRenderer::setupCameraOrtho2D() {
|
||||
glViewport(0, 0, kOriginalWidth, kOriginalHeight);
|
||||
_viewport = Math::Rect2d(Math::Vector2d(0, 0), Math::Vector2d(kOriginalWidth, kOriginalHeight));
|
||||
void ShaderRenderer::setupCameraOrtho2D(bool noScaling) {
|
||||
if (noScaling) {
|
||||
glViewport(0, 0, _system->getWidth(), _system->getHeight());
|
||||
_currentViewport = Math::Rect2d(Math::Vector2d(0, 0), Math::Vector2d(_system->getWidth(), _system->getHeight()));
|
||||
} else {
|
||||
glViewport(_screenViewport.left, _screenViewport.top, _screenViewport.width(), _screenViewport.height());
|
||||
_currentViewport = Math::Rect2d(Math::Vector2d(0, 0), Math::Vector2d(kOriginalWidth, kOriginalHeight));
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderRenderer::setupCameraPerspective(float pitch, float heading, float fov) {
|
||||
@ -205,30 +217,10 @@ void ShaderRenderer::setupCameraPerspective(float pitch, float heading, float fo
|
||||
else if (fov > 59.0 && fov < 61.0)
|
||||
glFOV = 36.0; // Somewhat good value for fov == 60
|
||||
|
||||
glViewport(0, kBottomBorderHeight, kOriginalWidth, kFrameHeight);
|
||||
Common::Rect frame = frameViewport();
|
||||
glViewport(frame.left, frame.top, frame.width(), frame.height());
|
||||
|
||||
const Math::Vector2d topLeft = Math::Vector2d(0, kBottomBorderHeight + kFrameHeight);
|
||||
const Math::Vector2d bottomRight = Math::Vector2d(kOriginalWidth, kBottomBorderHeight);
|
||||
_viewport = Math::Rect2d(topLeft, bottomRight);
|
||||
|
||||
float nclip = 1.0, fclip = 10000.0;
|
||||
float aspect = _viewport.getWidth() / _viewport.getHeight();
|
||||
|
||||
float range = nclip * tan(glFOV / 2 * (LOCAL_PI / 180));
|
||||
float left = -range * aspect;
|
||||
float right = range * aspect;
|
||||
float bottom = -range;
|
||||
float top = range;
|
||||
|
||||
Math::Matrix4 proj;
|
||||
proj(0,0) = (2.0f * nclip) / (right - left);
|
||||
proj(1,1) = (2.0f * nclip) / (top - bottom);
|
||||
proj(2,0) = (right + left) / (right - left);
|
||||
proj(2,1) = 0.0f; // (top + bottom) / (top - bottom);
|
||||
proj(2,2) = -(fclip + nclip) / (fclip - nclip);
|
||||
proj(2,3) = -1.0f;
|
||||
proj(3,2) = -(2.0f * fclip * nclip) / (fclip - nclip);
|
||||
proj(3,3) = 0.0f;
|
||||
Math::Matrix4 proj = Math::makePerspectiveMatrix(glFOV, kOriginalWidth / (double)kFrameHeight, 1.0, 10000.0);
|
||||
proj.transpose();
|
||||
|
||||
Math::Matrix4 model(180.0f - heading, pitch, 0.0f, Math::EO_YXZ);
|
||||
@ -325,16 +317,16 @@ void ShaderRenderer::draw2DText(const Common::String &text, const Common::Point
|
||||
_prevText = textToDraw;
|
||||
_prevTextPosition = position;
|
||||
|
||||
float x = position.x / _viewport.getWidth();
|
||||
float y = position.y / _viewport.getHeight();
|
||||
float x = position.x / _currentViewport.getWidth();
|
||||
float y = position.y / _currentViewport.getHeight();
|
||||
|
||||
float *bufData = new float[16 * textToDraw.size()];
|
||||
float *cur = bufData;
|
||||
|
||||
for (uint i = 0; i < textToDraw.size(); i++) {
|
||||
Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
|
||||
float w = textureRect.width() / _viewport.getWidth();
|
||||
float h = textureRect.height() / _viewport.getHeight();
|
||||
float w = textureRect.width() / _currentViewport.getWidth();
|
||||
float h = textureRect.height() / _currentViewport.getHeight();
|
||||
|
||||
float cw = textureRect.width() / (float)glFont->internalWidth;
|
||||
float ch = textureRect.height() / (float)glFont->internalHeight;
|
||||
@ -351,7 +343,7 @@ void ShaderRenderer::draw2DText(const Common::String &text, const Common::Point
|
||||
memcpy(cur, charData, 16 * sizeof(float));
|
||||
cur += 16;
|
||||
|
||||
x += (textureRect.width() - 3) / _viewport.getWidth();
|
||||
x += (textureRect.width() - 3) / _currentViewport.getWidth();
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _textVBO);
|
||||
@ -440,10 +432,12 @@ void ShaderRenderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Mat
|
||||
}
|
||||
|
||||
Graphics::Surface *ShaderRenderer::getScreenshot() {
|
||||
Graphics::Surface *s = new Graphics::Surface();
|
||||
s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
Common::Rect screen = viewport();
|
||||
|
||||
glReadPixels(0, 0, kOriginalWidth, kOriginalHeight, GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
|
||||
Graphics::Surface *s = new Graphics::Surface();
|
||||
s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
|
||||
glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -452,12 +446,13 @@ void ShaderRenderer::screenPosToDirection(const Common::Point screen, float &pit
|
||||
double x, y, z;
|
||||
|
||||
x = screen.x;
|
||||
y = kOriginalHeight - screen.y;
|
||||
y = _system->getHeight() - screen.y;
|
||||
z = 0.9f;
|
||||
|
||||
const Math::Vector2d tl = _viewport.getTopLeft();
|
||||
x = 2 * double(x - tl.getX()) / _viewport.getWidth() - 1.0f;
|
||||
y = 2 * double(y - tl.getY()) / _viewport.getHeight() - 1.0f;
|
||||
Common::Rect frame = frameViewport();
|
||||
|
||||
x = 2 * double(x - frame.left) / frame.width() - 1.0f;
|
||||
y = 2 * double(y - frame.top) / frame.height() - 1.0f;
|
||||
z = 2 * z - 1.0f;
|
||||
|
||||
// Screen coords to 3D coords
|
||||
|
@ -37,10 +37,10 @@ public:
|
||||
ShaderRenderer(OSystem *_system);
|
||||
virtual ~ShaderRenderer();
|
||||
|
||||
virtual void init(Graphics::PixelBuffer &screenBuffer) override;
|
||||
virtual void init() override;
|
||||
|
||||
virtual void clear() override;
|
||||
virtual void setupCameraOrtho2D() override;
|
||||
virtual void setupCameraOrtho2D(bool noScaling) override;
|
||||
virtual void setupCameraPerspective(float pitch, float heading, float fov) override;
|
||||
|
||||
virtual Texture *createTexture(const Graphics::Surface *surface) override;
|
||||
@ -62,6 +62,7 @@ public:
|
||||
|
||||
private:
|
||||
void setupQuadEBO();
|
||||
Math::Vector2d scaled(float x, float y) const;
|
||||
|
||||
Graphics::Shader *_box_shader;
|
||||
Graphics::Shader *_cube_shader;
|
||||
@ -75,7 +76,7 @@ private:
|
||||
GLuint _quadEBO;
|
||||
|
||||
Math::Matrix4 _mvpMatrix;
|
||||
Math::Rect2d _viewport;
|
||||
Math::Rect2d _currentViewport;
|
||||
|
||||
Common::String _prevText;
|
||||
Common::Point _prevTextPosition;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#undef ARRAYSIZE
|
||||
#endif
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
@ -105,9 +106,13 @@ void TinyGLRenderer::freeTexture(Texture *texture) {
|
||||
delete glTexture;
|
||||
}
|
||||
|
||||
void TinyGLRenderer::init(Graphics::PixelBuffer &screenBuffer) {
|
||||
void TinyGLRenderer::init() {
|
||||
debug("Initializing Software 3D Renderer");
|
||||
|
||||
bool fullscreen = ConfMan.getBool("fullscreen");
|
||||
Graphics::PixelBuffer screenBuffer = _system->setupScreen(kOriginalWidth, kOriginalHeight, fullscreen, false);
|
||||
computeScreenViewport();
|
||||
|
||||
_nonPowerOfTwoTexSupport = true;
|
||||
|
||||
_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, screenBuffer);
|
||||
@ -129,7 +134,7 @@ void TinyGLRenderer::clear() {
|
||||
tglColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void TinyGLRenderer::setupCameraOrtho2D() {
|
||||
void TinyGLRenderer::setupCameraOrtho2D(bool noScaling) {
|
||||
tglViewport(0, 0, kOriginalWidth, kOriginalHeight);
|
||||
tglMatrixMode(TGL_PROJECTION);
|
||||
tglLoadIdentity();
|
||||
|
@ -37,10 +37,10 @@ public:
|
||||
TinyGLRenderer(OSystem *_system);
|
||||
virtual ~TinyGLRenderer();
|
||||
|
||||
virtual void init(Graphics::PixelBuffer &screenBuffer) override;
|
||||
virtual void init() override;
|
||||
|
||||
virtual void clear() override;
|
||||
virtual void setupCameraOrtho2D() override;
|
||||
virtual void setupCameraOrtho2D(bool noScaling) override;
|
||||
virtual void setupCameraPerspective(float pitch, float heading, float fov) override;
|
||||
|
||||
Texture *createTexture(const Graphics::Surface *surface) override;
|
||||
|
@ -582,14 +582,14 @@ Graphics::Surface *Menu::createThumbnail(Graphics::Surface *big) {
|
||||
small->create(GameState::kThumbnailWidth, GameState::kThumbnailHeight,
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
|
||||
uint bigHeight = big->h - Renderer::kTopBorderHeight - Renderer::kBottomBorderHeight;
|
||||
uint bigYOffset = Renderer::kBottomBorderHeight;
|
||||
// The portion of the screenshot to keep
|
||||
Common::Rect frame = _vm->_gfx->frameViewport();
|
||||
|
||||
uint32 *dst = (uint32 *)small->getPixels();
|
||||
for (uint i = 0; i < small->h; i++) {
|
||||
for (uint j = 0; j < small->w; j++) {
|
||||
uint32 srcX = big->w * j / small->w;
|
||||
uint32 srcY = bigYOffset + bigHeight - bigHeight * i / small->h;
|
||||
uint32 srcY = frame.top + frame.height() - frame.height() * i / small->h;
|
||||
uint32 *src = (uint32 *)big->getBasePtr(srcX, srcY - 1);
|
||||
|
||||
// Copy RGBA pixel
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "image/jpeg.h"
|
||||
|
||||
#include "graphics/conversion.h"
|
||||
#include "graphics/pixelbuffer.h"
|
||||
#include "graphics/yuv_to_rgb.h"
|
||||
|
||||
#include "math/vector2d.h"
|
||||
@ -141,9 +140,6 @@ bool Myst3Engine::hasFeature(EngineFeature f) const {
|
||||
}
|
||||
|
||||
Common::Error Myst3Engine::run() {
|
||||
const int w = 640;
|
||||
const int h = 480;
|
||||
|
||||
if (!checkDatafiles()) {
|
||||
// An error message has already been displayed
|
||||
return Common::kUserCanceled;
|
||||
@ -173,13 +169,11 @@ Common::Error Myst3Engine::run() {
|
||||
_menu = new Menu(this);
|
||||
_archiveNode = new Archive();
|
||||
|
||||
bool fullscreen = ConfMan.getBool("fullscreen");
|
||||
Graphics::PixelBuffer screenBuffer = _system->setupScreen(w, h, fullscreen, softRenderer == false);
|
||||
_system->showMouse(false);
|
||||
|
||||
openArchives();
|
||||
|
||||
_gfx->init(screenBuffer);
|
||||
_gfx->init();
|
||||
|
||||
_cursor = new Cursor(this);
|
||||
_inventory = new Inventory(this);
|
||||
@ -365,22 +359,14 @@ HotSpot *Myst3Engine::getHoveredHotspot(NodePtr nodeData, uint16 var) {
|
||||
}
|
||||
} else {
|
||||
Common::Point mouse = _cursor->getPosition();
|
||||
Common::Point scaledMouse;
|
||||
|
||||
if (_state->getViewType() == kMenu) {
|
||||
scaledMouse = Common::Point(
|
||||
mouse.x * Renderer::kOriginalWidth / _system->getWidth(),
|
||||
CLIP<uint>(mouse.y * Renderer::kOriginalHeight / _system->getHeight(),
|
||||
0, Renderer::kOriginalHeight));
|
||||
} else {
|
||||
scaledMouse = Common::Point(
|
||||
mouse.x * Renderer::kOriginalWidth / _system->getWidth(),
|
||||
CLIP<uint>(mouse.y * Renderer::kOriginalHeight / _system->getHeight()
|
||||
- Renderer::kTopBorderHeight, 0, Renderer::kFrameHeight));
|
||||
if (_state->getViewType() == kFrame) {
|
||||
mouse.y -= Renderer::kTopBorderHeight;
|
||||
mouse.y = CLIP<uint>(mouse.y, 0, Renderer::kFrameHeight);
|
||||
}
|
||||
|
||||
for (uint j = 0; j < nodeData->hotspots.size(); j++) {
|
||||
int32 hitRect = nodeData->hotspots[j].isPointInRectsFrame(_state, scaledMouse);
|
||||
int32 hitRect = nodeData->hotspots[j].isPointInRectsFrame(_state, mouse);
|
||||
if (hitRect >= 0 && nodeData->hotspots[j].isEnabled(_state, var)) {
|
||||
if (nodeData->hotspots[j].rects.size() > 1) {
|
||||
_state->setHotspotHovered(true);
|
||||
@ -545,7 +531,7 @@ void Myst3Engine::drawFrame(bool noSwap) {
|
||||
|
||||
_gfx->setupCameraPerspective(pitch, heading, fov);
|
||||
} else {
|
||||
_gfx->setupCameraOrtho2D();
|
||||
_gfx->setupCameraOrtho2D(false);
|
||||
}
|
||||
|
||||
if (_node) {
|
||||
@ -567,7 +553,7 @@ void Myst3Engine::drawFrame(bool noSwap) {
|
||||
}
|
||||
|
||||
if (_state->getViewType() == kCube) {
|
||||
_gfx->setupCameraOrtho2D();
|
||||
_gfx->setupCameraOrtho2D(false);
|
||||
}
|
||||
|
||||
if (_state->getViewType() != kMenu) {
|
||||
@ -597,6 +583,8 @@ void Myst3Engine::drawFrame(bool noSwap) {
|
||||
_node->drawOverlay();
|
||||
}
|
||||
|
||||
// The cursor is drawn unscaled
|
||||
_gfx->setupCameraOrtho2D(true);
|
||||
if (_cursor->isVisible())
|
||||
_cursor->draw();
|
||||
|
||||
|
@ -42,9 +42,14 @@ void Scene::updateCamera(Common::Point &mouse) {
|
||||
float heading = _vm->_state->getLookAtHeading();
|
||||
|
||||
if (!_vm->_state->getCursorLocked()) {
|
||||
float speed = (200 - _mouseSpeed) / 25.0;
|
||||
pitch -= mouse.y / speed;
|
||||
heading += mouse.x / speed;
|
||||
float speed = 25 / (float)(200 - _mouseSpeed);
|
||||
|
||||
// Adjust the speed according to the resolution
|
||||
Common::Rect screen = _vm->_gfx->viewport();
|
||||
speed *= Renderer::kOriginalHeight / (float) screen.height();
|
||||
|
||||
pitch -= mouse.y * speed;
|
||||
heading += mouse.x * speed;
|
||||
}
|
||||
|
||||
// Keep heading within allowed values
|
||||
|
@ -85,7 +85,8 @@ void Transition::draw() {
|
||||
// Create the temporary surface and texture for the transition
|
||||
Graphics::Surface *frame = new Graphics::Surface();
|
||||
frame->create(target->w, target->h, target->format);
|
||||
Common::Rect frameRect = Common::Rect(frame->w, frame->h);
|
||||
Common::Rect textureRect = Common::Rect(frame->w, frame->h);
|
||||
Common::Rect screenRect = _vm->_gfx->viewport();
|
||||
|
||||
Texture *frameTexture = _vm->_gfx->createTexture(frame);
|
||||
|
||||
@ -105,7 +106,7 @@ void Transition::draw() {
|
||||
drawStep(targetPtr, target->pitch, sourcePtr, _sourceScreenshot->pitch, framePtr, frame->pitch, frame->h, completion);
|
||||
|
||||
frameTexture->update(frame);
|
||||
_vm->_gfx->drawTexturedRect2D(frameRect, frameRect, frameTexture);
|
||||
_vm->_gfx->drawTexturedRect2D(screenRect, textureRect, frameTexture);
|
||||
|
||||
_vm->_gfx->flipBuffer();
|
||||
g_system->updateScreen();
|
||||
@ -123,6 +124,8 @@ void Transition::draw() {
|
||||
}
|
||||
|
||||
void Transition::drawStep(uint32 *target, uint targetPitch, uint32 *source, uint sourcePitch, uint32 *destination, uint destinationPitch, uint destinationHeight, uint completion) {
|
||||
Common::Rect viewport = _vm->_gfx->viewport();
|
||||
|
||||
switch (_type) {
|
||||
case kTransitionNone:
|
||||
break;
|
||||
@ -135,7 +138,7 @@ void Transition::drawStep(uint32 *target, uint targetPitch, uint32 *source, uint
|
||||
uint32 *targetPtr = target + (destinationHeight - y - 1) * (targetPitch / 4);
|
||||
uint32 *destinationPtr = destination;
|
||||
|
||||
for (uint x = 0; x < 640; x++) {
|
||||
for (int16 x = 0; x < viewport.width(); x++) {
|
||||
byte sourceR, sourceG, sourceB;
|
||||
byte targetR, targetG, targetB;
|
||||
byte destR, destG, destB;
|
||||
@ -157,19 +160,19 @@ void Transition::drawStep(uint32 *target, uint targetPitch, uint32 *source, uint
|
||||
break;
|
||||
|
||||
case kTransitionLeftToRight: {
|
||||
uint transitionX = (640 * 100 - 640 * completion) / 100;
|
||||
int16 transitionX = (viewport.width() * 100 - viewport.width() * completion) / 100;
|
||||
for (uint y = 0; y < destinationHeight; y++) {
|
||||
uint32 *sourcePtr = source + (destinationHeight - y - 1) * (sourcePitch / 4);
|
||||
uint32 *destinationPtr = destination;
|
||||
|
||||
for (uint x = 0; x < transitionX; x++) {
|
||||
for (int16 x = 0; x < transitionX; x++) {
|
||||
*destinationPtr = *sourcePtr;
|
||||
destinationPtr++;
|
||||
sourcePtr++;
|
||||
}
|
||||
|
||||
uint32 *targetPtr = target + (destinationHeight - y - 1) * (targetPitch / 4) + transitionX;
|
||||
for (uint x = transitionX; x < 640; x++) {
|
||||
for (int16 x = transitionX; x < viewport.width(); x++) {
|
||||
*destinationPtr = *targetPtr;
|
||||
destinationPtr++;
|
||||
targetPtr++;
|
||||
@ -181,19 +184,19 @@ void Transition::drawStep(uint32 *target, uint targetPitch, uint32 *source, uint
|
||||
break;
|
||||
|
||||
case kTransitionRightToLeft: {
|
||||
uint transitionX = 640 * completion / 100;
|
||||
int16 transitionX = viewport.width() * completion / 100;
|
||||
for (uint y = 0; y < destinationHeight; y++) {
|
||||
uint32 *targetPtr = target + (destinationHeight - y - 1) * (targetPitch / 4);
|
||||
uint32 *destinationPtr = destination;
|
||||
|
||||
for (uint x = 0; x < transitionX; x++) {
|
||||
for (int16 x = 0; x < transitionX; x++) {
|
||||
*destinationPtr = *targetPtr;
|
||||
destinationPtr++;
|
||||
targetPtr++;
|
||||
}
|
||||
|
||||
uint32 *sourcePtr = source + (destinationHeight - y - 1) * (sourcePitch / 4) + transitionX;
|
||||
for (uint x = transitionX; x < 640; x++) {
|
||||
for (int16 x = transitionX; x < viewport.width(); x++) {
|
||||
*destinationPtr = *sourcePtr;
|
||||
destinationPtr++;
|
||||
sourcePtr++;
|
||||
|
Loading…
Reference in New Issue
Block a user