MYST3: Make the engine resolution-agnostic

This commit is contained in:
Bastien Bouclet 2012-12-26 11:43:52 +01:00
parent ed7a4355e9
commit 7a33ec4a00
14 changed files with 178 additions and 106 deletions

View File

@ -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];

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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++;