2013-08-16 05:29:56 +02:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* 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 "backends/graphics/opengl/opengl-graphics.h"
|
|
|
|
#include "backends/graphics/opengl/texture.h"
|
2016-02-28 18:15:00 +01:00
|
|
|
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
|
|
|
#include "backends/graphics/opengl/pipelines/fixed.h"
|
|
|
|
#include "backends/graphics/opengl/pipelines/shader.h"
|
2015-12-20 05:42:54 +01:00
|
|
|
#include "backends/graphics/opengl/shader.h"
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2017-05-12 12:44:44 -05:00
|
|
|
#include "common/array.h"
|
2013-08-16 05:29:56 +02:00
|
|
|
#include "common/textconsole.h"
|
|
|
|
#include "common/translation.h"
|
|
|
|
#include "common/algorithm.h"
|
2013-10-19 20:39:01 +02:00
|
|
|
#include "common/file.h"
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
|
|
|
#include "common/tokenizer.h"
|
|
|
|
#include "common/rect.h"
|
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
|
|
|
|
#include "graphics/conversion.h"
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
|
|
|
#include "graphics/fontman.h"
|
|
|
|
#include "graphics/font.h"
|
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2017-05-12 12:44:44 -05:00
|
|
|
#ifdef USE_PNG
|
|
|
|
#include "image/png.h"
|
2019-03-01 00:15:43 +00:00
|
|
|
#else
|
|
|
|
#include "image/bmp.h"
|
2017-05-12 12:44:44 -05:00
|
|
|
#endif
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
namespace OpenGL {
|
|
|
|
|
|
|
|
OpenGLGraphicsManager::OpenGLGraphicsManager()
|
|
|
|
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
|
2016-01-04 06:41:10 +01:00
|
|
|
_pipeline(nullptr),
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
_defaultFormat(), _defaultFormatAlpha(),
|
2013-08-16 05:29:56 +02:00
|
|
|
_gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
_cursor(nullptr),
|
|
|
|
_cursorHotspotX(0), _cursorHotspotY(0),
|
2015-01-07 20:02:10 +01:00
|
|
|
_cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
|
2017-09-13 00:43:56 -05:00
|
|
|
_cursorKeyColor(0), _cursorDontScale(false), _cursorPaletteEnabled(false)
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
, _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
|
2016-09-18 13:20:25 +02:00
|
|
|
_osdIconSurface(nullptr)
|
2013-08-19 00:44:55 +02:00
|
|
|
#endif
|
|
|
|
{
|
2013-08-16 05:29:56 +02:00
|
|
|
memset(_gamePalette, 0, sizeof(_gamePalette));
|
2015-12-21 04:49:25 +01:00
|
|
|
g_context.reset();
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
|
|
|
delete _gameScreen;
|
|
|
|
delete _overlay;
|
|
|
|
delete _cursor;
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
delete _osdMessageSurface;
|
|
|
|
delete _osdIconSurface;
|
2013-08-19 00:44:55 +02:00
|
|
|
#endif
|
2015-12-20 09:30:11 +01:00
|
|
|
#if !USE_FORCED_GLES
|
2016-01-04 07:07:37 +01:00
|
|
|
ShaderManager::destroy();
|
2015-12-20 05:42:54 +01:00
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
|
2013-08-16 05:29:56 +02:00
|
|
|
switch (f) {
|
|
|
|
case OSystem::kFeatureAspectRatioCorrection:
|
|
|
|
case OSystem::kFeatureCursorPalette:
|
2016-10-12 22:36:16 +01:00
|
|
|
case OSystem::kFeatureFilteringMode:
|
2013-08-16 05:29:56 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case OSystem::kFeatureOverlaySupportsAlpha:
|
|
|
|
return _defaultFormatAlpha.aBits() > 3;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
|
|
|
|
switch (f) {
|
|
|
|
case OSystem::kFeatureAspectRatioCorrection:
|
|
|
|
assert(_transactionMode != kTransactionNone);
|
|
|
|
_currentState.aspectRatioCorrection = enable;
|
|
|
|
break;
|
|
|
|
|
2016-10-12 22:36:16 +01:00
|
|
|
case OSystem::kFeatureFilteringMode:
|
|
|
|
assert(_transactionMode != kTransactionNone);
|
|
|
|
_currentState.filtering = enable;
|
|
|
|
|
|
|
|
if (_gameScreen) {
|
|
|
|
_gameScreen->enableLinearFiltering(enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_cursor) {
|
|
|
|
_cursor->enableLinearFiltering(enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
case OSystem::kFeatureCursorPalette:
|
|
|
|
_cursorPaletteEnabled = enable;
|
|
|
|
updateCursorPalette();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) const {
|
2013-08-16 05:29:56 +02:00
|
|
|
switch (f) {
|
|
|
|
case OSystem::kFeatureAspectRatioCorrection:
|
|
|
|
return _currentState.aspectRatioCorrection;
|
|
|
|
|
2016-10-12 22:36:16 +01:00
|
|
|
case OSystem::kFeatureFilteringMode:
|
|
|
|
return _currentState.filtering;
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
case OSystem::kFeatureCursorPalette:
|
|
|
|
return _cursorPaletteEnabled;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
const OSystem::GraphicsMode glGraphicsModes[] = {
|
2016-10-12 22:36:16 +01:00
|
|
|
{ "opengl", _s("OpenGL"), GFX_OPENGL },
|
2013-08-16 05:29:56 +02:00
|
|
|
{ nullptr, nullptr, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
} // End of anonymous namespace
|
|
|
|
|
|
|
|
const OSystem::GraphicsMode *OpenGLGraphicsManager::getSupportedGraphicsModes() const {
|
|
|
|
return glGraphicsModes;
|
|
|
|
}
|
|
|
|
|
|
|
|
int OpenGLGraphicsManager::getDefaultGraphicsMode() const {
|
2016-10-12 22:36:16 +01:00
|
|
|
return GFX_OPENGL;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenGLGraphicsManager::setGraphicsMode(int mode) {
|
|
|
|
assert(_transactionMode != kTransactionNone);
|
|
|
|
|
|
|
|
switch (mode) {
|
2016-10-12 22:36:16 +01:00
|
|
|
case GFX_OPENGL:
|
2013-08-16 05:29:56 +02:00
|
|
|
_currentState.graphicsMode = mode;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
warning("OpenGLGraphicsManager::setGraphicsMode(%d): Unknown graphics mode", mode);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int OpenGLGraphicsManager::getGraphicsMode() const {
|
|
|
|
return _currentState.graphicsMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
Graphics::PixelFormat OpenGLGraphicsManager::getScreenFormat() const {
|
|
|
|
return _currentState.gameFormat;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::beginGFXTransaction() {
|
|
|
|
assert(_transactionMode == kTransactionNone);
|
|
|
|
|
|
|
|
// Start a transaction.
|
|
|
|
_oldState = _currentState;
|
|
|
|
_transactionMode = kTransactionActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
|
|
|
|
assert(_transactionMode == kTransactionActive);
|
|
|
|
|
|
|
|
uint transactionError = OSystem::kTransactionSuccess;
|
|
|
|
|
|
|
|
bool setupNewGameScreen = false;
|
|
|
|
if ( _oldState.gameWidth != _currentState.gameWidth
|
|
|
|
|| _oldState.gameHeight != _currentState.gameHeight) {
|
|
|
|
setupNewGameScreen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
if (_oldState.gameFormat != _currentState.gameFormat) {
|
|
|
|
setupNewGameScreen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check whether the requested format can actually be used.
|
|
|
|
Common::List<Graphics::PixelFormat> supportedFormats = getSupportedFormats();
|
|
|
|
// In case the requested format is not usable we will fall back to CLUT8.
|
|
|
|
if (Common::find(supportedFormats.begin(), supportedFormats.end(), _currentState.gameFormat) == supportedFormats.end()) {
|
|
|
|
_currentState.gameFormat = Graphics::PixelFormat::createFormatCLUT8();
|
|
|
|
transactionError |= OSystem::kTransactionFormatNotSupported;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
do {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const uint desiredAspect = getDesiredGameAspectRatio();
|
|
|
|
const uint requestedWidth = _currentState.gameWidth;
|
|
|
|
const uint requestedHeight = intToFrac(requestedWidth) / desiredAspect;
|
2013-08-16 05:29:56 +02:00
|
|
|
|
|
|
|
if (!loadVideoMode(requestedWidth, requestedHeight,
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
_currentState.gameFormat
|
|
|
|
#else
|
|
|
|
Graphics::PixelFormat::createFormatCLUT8()
|
|
|
|
#endif
|
2013-10-18 00:17:46 +02:00
|
|
|
)
|
|
|
|
// HACK: This is really nasty but we don't have any guarantees of
|
|
|
|
// a context existing before, which means we don't know the maximum
|
|
|
|
// supported texture size before this. Thus, we check whether the
|
|
|
|
// requested game resolution is supported over here.
|
2016-01-04 11:00:58 +01:00
|
|
|
|| ( _currentState.gameWidth > (uint)g_context.maxTextureSize
|
|
|
|
|| _currentState.gameHeight > (uint)g_context.maxTextureSize)) {
|
2013-08-16 05:29:56 +02:00
|
|
|
if (_transactionMode == kTransactionActive) {
|
|
|
|
// Try to setup the old state in case its valid and is
|
|
|
|
// actually different from the new one.
|
|
|
|
if (_oldState.valid && _oldState != _currentState) {
|
|
|
|
// Give some hints on what failed to set up.
|
|
|
|
if ( _oldState.gameWidth != _currentState.gameWidth
|
|
|
|
|| _oldState.gameHeight != _currentState.gameHeight) {
|
|
|
|
transactionError |= OSystem::kTransactionSizeChangeFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
if (_oldState.gameFormat != _currentState.gameFormat) {
|
|
|
|
transactionError |= OSystem::kTransactionFormatNotSupported;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (_oldState.aspectRatioCorrection != _currentState.aspectRatioCorrection) {
|
|
|
|
transactionError |= OSystem::kTransactionAspectRatioFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_oldState.graphicsMode != _currentState.graphicsMode) {
|
|
|
|
transactionError |= OSystem::kTransactionModeSwitchFailed;
|
|
|
|
}
|
|
|
|
|
2016-10-12 22:36:16 +01:00
|
|
|
if (_oldState.filtering != _currentState.filtering) {
|
|
|
|
transactionError |= OSystem::kTransactionFilteringFailed;
|
|
|
|
}
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// Roll back to the old state.
|
|
|
|
_currentState = _oldState;
|
|
|
|
_transactionMode = kTransactionRollback;
|
|
|
|
|
|
|
|
// Try to set up the old state.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// DON'T use error(), as this tries to bring up the debug
|
|
|
|
// console, which WON'T WORK now that we might no have a
|
|
|
|
// proper screen.
|
|
|
|
warning("OpenGLGraphicsManager::endGFXTransaction: Could not load any graphics mode!");
|
|
|
|
g_system->quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
// In case we reach this we have a valid state, yay.
|
|
|
|
_transactionMode = kTransactionNone;
|
|
|
|
_currentState.valid = true;
|
|
|
|
} while (_transactionMode == kTransactionRollback);
|
|
|
|
|
|
|
|
if (setupNewGameScreen) {
|
|
|
|
delete _gameScreen;
|
|
|
|
_gameScreen = nullptr;
|
|
|
|
|
|
|
|
#ifdef USE_RGB_COLOR
|
2016-01-02 05:54:08 +01:00
|
|
|
_gameScreen = createSurface(_currentState.gameFormat);
|
2014-02-11 11:07:38 +01:00
|
|
|
#else
|
2016-01-02 05:54:08 +01:00
|
|
|
_gameScreen = createSurface(Graphics::PixelFormat::createFormatCLUT8());
|
2013-08-16 05:29:56 +02:00
|
|
|
#endif
|
2014-02-11 11:07:38 +01:00
|
|
|
assert(_gameScreen);
|
|
|
|
if (_gameScreen->hasPalette()) {
|
2014-02-11 11:07:38 +01:00
|
|
|
_gameScreen->setPalette(0, 256, _gamePalette);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_gameScreen->allocate(_currentState.gameWidth, _currentState.gameHeight);
|
2016-10-12 22:36:16 +01:00
|
|
|
_gameScreen->enableLinearFiltering(_currentState.filtering);
|
2013-08-16 05:29:56 +02:00
|
|
|
// We fill the screen to all black or index 0 for CLUT8.
|
2014-02-25 00:09:16 +01:00
|
|
|
#ifdef USE_RGB_COLOR
|
2013-08-16 05:29:56 +02:00
|
|
|
if (_currentState.gameFormat.bytesPerPixel == 1) {
|
|
|
|
_gameScreen->fill(0);
|
|
|
|
} else {
|
|
|
|
_gameScreen->fill(_gameScreen->getSurface()->format.RGBToColor(0, 0, 0));
|
|
|
|
}
|
2014-02-25 00:09:16 +01:00
|
|
|
#else
|
|
|
|
_gameScreen->fill(0);
|
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update our display area and cursor scaling. This makes sure we pick up
|
|
|
|
// aspect ratio correction and game screen changes correctly.
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
recalculateDisplayAreas();
|
2013-08-16 05:29:56 +02:00
|
|
|
recalculateCursorScaling();
|
|
|
|
|
|
|
|
// Something changed, so update the screen change ID.
|
|
|
|
++_screenChangeID;
|
|
|
|
|
|
|
|
// Since transactionError is a ORd list of TransactionErrors this is
|
|
|
|
// clearly wrong. But our API is simply broken.
|
|
|
|
return (OSystem::TransactionError)transactionError;
|
|
|
|
}
|
|
|
|
|
|
|
|
int OpenGLGraphicsManager::getScreenChangeID() const {
|
|
|
|
return _screenChangeID;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
|
|
|
|
Graphics::PixelFormat requestedFormat;
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
if (!format) {
|
|
|
|
requestedFormat = Graphics::PixelFormat::createFormatCLUT8();
|
|
|
|
} else {
|
|
|
|
requestedFormat = *format;
|
|
|
|
}
|
|
|
|
_currentState.gameFormat = requestedFormat;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
_currentState.gameWidth = width;
|
|
|
|
_currentState.gameHeight = height;
|
2017-12-01 11:41:49 -06:00
|
|
|
_gameScreenShakeOffset = 0;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int16 OpenGLGraphicsManager::getWidth() const {
|
2013-08-16 05:29:56 +02:00
|
|
|
return _currentState.gameWidth;
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int16 OpenGLGraphicsManager::getHeight() const {
|
2013-08-16 05:29:56 +02:00
|
|
|
return _currentState.gameHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
|
|
|
|
_gameScreen->copyRectToTexture(x, y, w, h, buf, pitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::fillScreen(uint32 col) {
|
|
|
|
// FIXME: This does not conform to the OSystem specs because fillScreen
|
|
|
|
// is always taking CLUT8 color values and use color indexed mode. This is,
|
|
|
|
// however, plain odd and probably was a forgotten when we introduced
|
|
|
|
// RGB support. Thus, we simply do the "sane" thing here and hope OSystem
|
|
|
|
// gets fixed one day.
|
|
|
|
_gameScreen->fill(col);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::setShakePos(int shakeOffset) {
|
2015-12-11 19:54:47 +01:00
|
|
|
if (_gameScreenShakeOffset != shakeOffset) {
|
|
|
|
_gameScreenShakeOffset = shakeOffset;
|
|
|
|
_forceRedraw = true;
|
|
|
|
}
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::updateScreen() {
|
|
|
|
if (!_gameScreen) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
#ifdef USE_OSD
|
2017-08-04 10:25:22 +02:00
|
|
|
if (_osdMessageChangeRequest) {
|
|
|
|
osdMessageUpdateSurface();
|
2016-09-18 13:20:25 +02:00
|
|
|
}
|
2016-09-13 20:35:05 +02:00
|
|
|
|
2016-09-18 13:20:25 +02:00
|
|
|
if (_osdIconSurface) {
|
|
|
|
_osdIconSurface->updateGLTexture();
|
2016-09-13 20:35:05 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-12-11 19:54:47 +01:00
|
|
|
// We only update the screen when there actually have been any changes.
|
|
|
|
if ( !_forceRedraw
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
&& !_cursorNeedsRedraw
|
2015-12-11 19:54:47 +01:00
|
|
|
&& !_gameScreen->isDirty()
|
|
|
|
&& !(_overlayVisible && _overlay->isDirty())
|
|
|
|
&& !(_cursorVisible && _cursor && _cursor->isDirty())
|
2016-09-05 20:56:09 +01:00
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
&& !_osdMessageSurface && !_osdIconSurface
|
2016-09-05 20:56:09 +01:00
|
|
|
#endif
|
|
|
|
) {
|
2015-12-11 19:54:47 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-06 16:52:03 +01:00
|
|
|
// Update changes to textures.
|
|
|
|
_gameScreen->updateGLTexture();
|
2017-05-07 18:08:03 +02:00
|
|
|
if (_cursorVisible && _cursor) {
|
2016-01-06 16:52:03 +01:00
|
|
|
_cursor->updateGLTexture();
|
|
|
|
}
|
|
|
|
_overlay->updateGLTexture();
|
|
|
|
|
2015-01-07 20:02:10 +01:00
|
|
|
// Clear the screen buffer.
|
2017-08-04 10:25:22 +02:00
|
|
|
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
|
2015-12-11 21:22:42 +01:00
|
|
|
|
2017-08-04 10:25:22 +02:00
|
|
|
if (!_overlayVisible) {
|
|
|
|
// The scissor test is enabled to:
|
|
|
|
// - Clip the cursor to the game screen
|
|
|
|
// - Clip the game screen when the shake offset is non-zero
|
|
|
|
_backBuffer.enableScissorTest(true);
|
2015-12-11 21:22:42 +01:00
|
|
|
}
|
2013-08-16 05:29:56 +02:00
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_gameDrawRect.height() / _gameScreen->getHeight();
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2018-08-23 07:19:12 +02:00
|
|
|
// Alpha blending is disabled when drawing the screen
|
|
|
|
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// First step: Draw the (virtual) game screen.
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top + shakeOffset, _gameDrawRect.width(), _gameDrawRect.height());
|
2013-08-16 05:29:56 +02:00
|
|
|
|
|
|
|
// Second step: Draw the overlay if visible.
|
|
|
|
if (_overlayVisible) {
|
2018-08-23 07:19:12 +02:00
|
|
|
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _overlayDrawRect.width(), _overlayDrawRect.height());
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Third step: Draw the cursor if visible.
|
|
|
|
if (_cursorVisible && _cursor) {
|
2018-08-23 07:19:12 +02:00
|
|
|
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// Adjust game screen shake position, but only when the overlay is not
|
|
|
|
// visible.
|
2014-02-12 17:15:07 +01:00
|
|
|
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2016-02-28 17:02:19 +01:00
|
|
|
g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
_cursorX - _cursorHotspotXScaled,
|
|
|
|
_cursorY - _cursorHotspotYScaled + cursorOffset,
|
2016-01-06 16:52:03 +01:00
|
|
|
_cursorWidthScaled, _cursorHeightScaled);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
2013-08-19 00:44:55 +02:00
|
|
|
|
2017-08-04 10:25:22 +02:00
|
|
|
if (!_overlayVisible) {
|
|
|
|
_backBuffer.enableScissorTest(false);
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
2015-12-11 21:22:42 +01:00
|
|
|
// Fourth step: Draw the OSD.
|
2018-08-23 07:19:12 +02:00
|
|
|
if (_osdMessageSurface || _osdIconSurface) {
|
|
|
|
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
|
|
|
|
}
|
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
if (_osdMessageSurface) {
|
2013-08-19 00:44:55 +02:00
|
|
|
// Update alpha value.
|
2016-09-13 20:35:05 +02:00
|
|
|
const int diff = g_system->getMillis(false) - _osdMessageFadeStartTime;
|
2013-08-19 00:44:55 +02:00
|
|
|
if (diff > 0) {
|
2016-09-13 20:35:05 +02:00
|
|
|
if (diff >= kOSDMessageFadeOutDuration) {
|
2013-08-19 00:44:55 +02:00
|
|
|
// Back to full transparency.
|
2016-09-13 20:35:05 +02:00
|
|
|
_osdMessageAlpha = 0;
|
2013-08-19 00:44:55 +02:00
|
|
|
} else {
|
|
|
|
// Do a fade out.
|
2016-09-13 20:35:05 +02:00
|
|
|
_osdMessageAlpha = kOSDMessageInitialAlpha - diff * kOSDMessageInitialAlpha / kOSDMessageFadeOutDuration;
|
2013-08-19 00:44:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the OSD transparency.
|
2016-09-13 20:35:05 +02:00
|
|
|
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
|
|
|
|
int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
|
2013-08-19 00:44:55 +02:00
|
|
|
|
|
|
|
// Draw the OSD texture.
|
2016-09-13 20:35:05 +02:00
|
|
|
g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
|
|
|
|
dstX, dstY, _osdMessageSurface->getWidth(), _osdMessageSurface->getHeight());
|
2013-08-19 00:44:55 +02:00
|
|
|
|
|
|
|
// Reset color.
|
2016-02-28 17:02:19 +01:00
|
|
|
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2016-09-13 20:35:05 +02:00
|
|
|
|
|
|
|
if (_osdMessageAlpha <= 0) {
|
|
|
|
delete _osdMessageSurface;
|
|
|
|
_osdMessageSurface = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_osdIconSurface) {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int dstX = _windowWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
|
2016-09-13 20:35:05 +02:00
|
|
|
int dstY = kOSDIconTopMargin;
|
|
|
|
|
|
|
|
// Draw the OSD icon texture.
|
|
|
|
g_context.getActivePipeline()->drawTexture(_osdIconSurface->getGLTexture(),
|
|
|
|
dstX, dstY, _osdIconSurface->getWidth(), _osdIconSurface->getHeight());
|
2013-08-19 00:44:55 +02:00
|
|
|
}
|
|
|
|
#endif
|
2015-12-11 19:23:41 +01:00
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
_cursorNeedsRedraw = false;
|
|
|
|
_forceRedraw = false;
|
2015-12-11 19:23:41 +01:00
|
|
|
refreshScreen();
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Graphics::Surface *OpenGLGraphicsManager::lockScreen() {
|
|
|
|
return _gameScreen->getSurface();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::unlockScreen() {
|
|
|
|
_gameScreen->flagDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::clearFocusRectangle() {
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int16 OpenGLGraphicsManager::getOverlayWidth() const {
|
2013-08-16 05:29:56 +02:00
|
|
|
if (_overlay) {
|
|
|
|
return _overlay->getWidth();
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
int16 OpenGLGraphicsManager::getOverlayHeight() const {
|
2013-08-16 05:29:56 +02:00
|
|
|
if (_overlay) {
|
|
|
|
return _overlay->getHeight();
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
|
|
|
|
return _overlay->getFormat();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
|
|
|
|
_overlay->copyRectToTexture(x, y, w, h, buf, pitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::clearOverlay() {
|
|
|
|
_overlay->fill(0);
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) const {
|
2013-08-16 05:29:56 +02:00
|
|
|
const Graphics::Surface *overlayData = _overlay->getSurface();
|
|
|
|
|
|
|
|
const byte *src = (const byte *)overlayData->getPixels();
|
|
|
|
byte *dst = (byte *)buf;
|
|
|
|
|
|
|
|
for (uint h = overlayData->h; h > 0; --h) {
|
|
|
|
memcpy(dst, src, overlayData->w * overlayData->format.bytesPerPixel);
|
|
|
|
dst += pitch;
|
|
|
|
src += overlayData->pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
2018-08-23 07:19:12 +02:00
|
|
|
template<typename SrcColor, typename DstColor>
|
|
|
|
void multiplyColorWithAlpha(const byte *src, byte *dst, const uint w, const uint h,
|
|
|
|
const Graphics::PixelFormat &srcFmt, const Graphics::PixelFormat &dstFmt,
|
|
|
|
const uint srcPitch, const uint dstPitch, const SrcColor keyColor) {
|
|
|
|
for (uint y = 0; y < h; ++y) {
|
|
|
|
for (uint x = 0; x < w; ++x) {
|
|
|
|
const uint32 color = *(const SrcColor *)src;
|
|
|
|
|
|
|
|
if (color == keyColor) {
|
|
|
|
*(DstColor *)dst = 0;
|
|
|
|
} else {
|
|
|
|
byte a, r, g, b;
|
|
|
|
srcFmt.colorToARGB(color, a, r, g, b);
|
|
|
|
|
|
|
|
if (a != 0xFF) {
|
|
|
|
r = (int) r * a / 255;
|
|
|
|
g = (int) g * a / 255;
|
|
|
|
b = (int) b * a / 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(DstColor *)dst = dstFmt.ARGBToColor(a, r, g, b);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
2018-08-23 07:19:12 +02:00
|
|
|
|
|
|
|
src += sizeof(SrcColor);
|
|
|
|
dst += sizeof(DstColor);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
2018-08-23 07:19:12 +02:00
|
|
|
src += srcPitch - w * srcFmt.bytesPerPixel;
|
|
|
|
dst += dstPitch - w * dstFmt.bytesPerPixel;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // End of anonymous namespace
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
2017-09-13 00:47:44 -05:00
|
|
|
|
|
|
|
_cursorKeyColor = keycolor;
|
|
|
|
_cursorHotspotX = hotspotX;
|
|
|
|
_cursorHotspotY = hotspotY;
|
|
|
|
_cursorDontScale = dontScale;
|
|
|
|
|
|
|
|
if (!w || !h) {
|
|
|
|
delete _cursor;
|
|
|
|
_cursor = nullptr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
Graphics::PixelFormat inputFormat;
|
|
|
|
#ifdef USE_RGB_COLOR
|
|
|
|
if (format) {
|
|
|
|
inputFormat = *format;
|
|
|
|
} else {
|
|
|
|
inputFormat = Graphics::PixelFormat::createFormatCLUT8();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
inputFormat = Graphics::PixelFormat::createFormatCLUT8();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// In case the color format has changed we will need to create the texture.
|
|
|
|
if (!_cursor || _cursor->getFormat() != inputFormat) {
|
|
|
|
delete _cursor;
|
|
|
|
_cursor = nullptr;
|
|
|
|
|
|
|
|
GLenum glIntFormat, glFormat, glType;
|
|
|
|
|
2014-02-11 11:07:38 +01:00
|
|
|
Graphics::PixelFormat textureFormat;
|
|
|
|
if (inputFormat.bytesPerPixel == 1 || (inputFormat.aBits() && getGLPixelFormat(inputFormat, glIntFormat, glFormat, glType))) {
|
|
|
|
// There is two cases when we can use the cursor format directly.
|
|
|
|
// The first is when it's CLUT8, here color key handling can
|
|
|
|
// always be applied because we use the alpha channel of
|
|
|
|
// _defaultFormatAlpha for that.
|
|
|
|
// The other is when the input format has alpha bits and
|
|
|
|
// furthermore is directly supported.
|
|
|
|
textureFormat = inputFormat;
|
2013-08-16 05:29:56 +02:00
|
|
|
} else {
|
2014-02-11 11:07:38 +01:00
|
|
|
textureFormat = _defaultFormatAlpha;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
2016-01-02 05:54:08 +01:00
|
|
|
_cursor = createSurface(textureFormat, true);
|
2013-08-16 05:29:56 +02:00
|
|
|
assert(_cursor);
|
2016-10-12 22:36:16 +01:00
|
|
|
_cursor->enableLinearFiltering(_currentState.filtering);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_cursor->allocate(w, h);
|
|
|
|
if (inputFormat.bytesPerPixel == 1) {
|
|
|
|
// For CLUT8 cursors we can simply copy the input data into the
|
|
|
|
// texture.
|
|
|
|
_cursor->copyRectToTexture(0, 0, w, h, buf, w * inputFormat.bytesPerPixel);
|
|
|
|
} else {
|
|
|
|
// Otherwise it is a bit more ugly because we have to handle a key
|
|
|
|
// color properly.
|
|
|
|
|
|
|
|
Graphics::Surface *dst = _cursor->getSurface();
|
|
|
|
const uint srcPitch = w * inputFormat.bytesPerPixel;
|
|
|
|
|
2013-11-17 20:28:16 +01:00
|
|
|
// Copy the cursor data to the actual texture surface. This will make
|
|
|
|
// sure that the data is also converted to the expected format.
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2018-08-23 07:19:12 +02:00
|
|
|
// Also multiply the color values with the alpha channel.
|
|
|
|
// The pre-multiplication allows using a blend mode that prevents
|
|
|
|
// color fringes due to filtering.
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
if (dst->format.bytesPerPixel == 2) {
|
|
|
|
if (inputFormat.bytesPerPixel == 2) {
|
2018-08-23 07:19:12 +02:00
|
|
|
multiplyColorWithAlpha<uint16, uint16>((const byte *) buf, (byte *) dst->getPixels(), w, h,
|
|
|
|
inputFormat, dst->format, srcPitch, dst->pitch, keycolor);
|
2013-08-16 05:29:56 +02:00
|
|
|
} else if (inputFormat.bytesPerPixel == 4) {
|
2018-08-23 07:19:12 +02:00
|
|
|
multiplyColorWithAlpha<uint32, uint16>((const byte *) buf, (byte *) dst->getPixels(), w, h,
|
|
|
|
inputFormat, dst->format, srcPitch, dst->pitch, keycolor);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (inputFormat.bytesPerPixel == 2) {
|
2018-08-23 07:19:12 +02:00
|
|
|
multiplyColorWithAlpha<uint16, uint32>((const byte *) buf, (byte *) dst->getPixels(), w, h,
|
|
|
|
inputFormat, dst->format, srcPitch, dst->pitch, keycolor);
|
2013-08-16 05:29:56 +02:00
|
|
|
} else if (inputFormat.bytesPerPixel == 4) {
|
2018-08-23 07:19:12 +02:00
|
|
|
multiplyColorWithAlpha<uint32, uint32>((const byte *) buf, (byte *) dst->getPixels(), w, h,
|
|
|
|
inputFormat, dst->format, srcPitch, dst->pitch, keycolor);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flag the texture as dirty.
|
|
|
|
_cursor->flagDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
// In case we actually use a palette set that up properly.
|
|
|
|
if (inputFormat.bytesPerPixel == 1) {
|
|
|
|
updateCursorPalette();
|
|
|
|
}
|
|
|
|
|
|
|
|
recalculateCursorScaling();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::setCursorPalette(const byte *colors, uint start, uint num) {
|
|
|
|
// FIXME: For some reason client code assumes that usage of this function
|
|
|
|
// automatically enables the cursor palette.
|
|
|
|
_cursorPaletteEnabled = true;
|
|
|
|
|
|
|
|
memcpy(_cursorPalette + start * 3, colors, num * 3);
|
|
|
|
updateCursorPalette();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) {
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
_osdMessageChangeRequest = true;
|
|
|
|
|
|
|
|
_osdMessageNextData = msg;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_OSD
|
|
|
|
void OpenGLGraphicsManager::osdMessageUpdateSurface() {
|
|
|
|
// Split up the lines.
|
2013-08-19 00:44:55 +02:00
|
|
|
Common::Array<Common::String> osdLines;
|
2016-09-13 20:35:05 +02:00
|
|
|
Common::StringTokenizer tokenizer(_osdMessageNextData, "\n");
|
2013-08-19 00:44:55 +02:00
|
|
|
while (!tokenizer.empty()) {
|
|
|
|
osdLines.push_back(tokenizer.nextToken());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do the actual drawing like the SDL backend.
|
|
|
|
const Graphics::Font *font = getFontOSD();
|
|
|
|
|
|
|
|
// Determine a rect which would contain the message string (clipped to the
|
|
|
|
// screen dimensions).
|
|
|
|
const int vOffset = 6;
|
|
|
|
const int lineSpacing = 1;
|
|
|
|
const int lineHeight = font->getFontHeight() + 2 * lineSpacing;
|
2016-09-13 20:35:05 +02:00
|
|
|
uint width = 0;
|
|
|
|
uint height = lineHeight * osdLines.size() + 2 * vOffset;
|
2013-08-19 00:44:55 +02:00
|
|
|
for (uint i = 0; i < osdLines.size(); i++) {
|
2016-09-13 20:35:05 +02:00
|
|
|
width = MAX<uint>(width, font->getStringWidth(osdLines[i]) + 14);
|
2013-08-19 00:44:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clip the rect
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
width = MIN<uint>(width, _gameDrawRect.width());
|
|
|
|
height = MIN<uint>(height, _gameDrawRect.height());
|
2016-09-13 20:35:05 +02:00
|
|
|
|
|
|
|
delete _osdMessageSurface;
|
|
|
|
_osdMessageSurface = nullptr;
|
|
|
|
|
|
|
|
_osdMessageSurface = createSurface(_defaultFormatAlpha);
|
|
|
|
assert(_osdMessageSurface);
|
|
|
|
// We always filter the osd with GL_LINEAR. This assures it's
|
|
|
|
// readable in case it needs to be scaled and does not affect it
|
|
|
|
// otherwise.
|
|
|
|
_osdMessageSurface->enableLinearFiltering(true);
|
|
|
|
|
|
|
|
_osdMessageSurface->allocate(width, height);
|
2013-08-19 00:44:55 +02:00
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
Graphics::Surface *dst = _osdMessageSurface->getSurface();
|
2013-08-19 00:44:55 +02:00
|
|
|
|
|
|
|
// Draw a dark gray rect.
|
|
|
|
const uint32 color = dst->format.RGBToColor(40, 40, 40);
|
2016-09-13 20:35:05 +02:00
|
|
|
dst->fillRect(Common::Rect(0, 0, width, height), color);
|
2013-08-19 00:44:55 +02:00
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
// Render the message in white
|
2013-08-19 00:44:55 +02:00
|
|
|
const uint32 white = dst->format.RGBToColor(255, 255, 255);
|
|
|
|
for (uint i = 0; i < osdLines.size(); ++i) {
|
|
|
|
font->drawString(dst, osdLines[i],
|
2016-09-13 20:35:05 +02:00
|
|
|
0, i * lineHeight + vOffset + lineSpacing, width,
|
2013-08-19 00:44:55 +02:00
|
|
|
white, Graphics::kTextAlignCenter);
|
|
|
|
}
|
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
_osdMessageSurface->updateGLTexture();
|
|
|
|
|
2013-08-19 00:44:55 +02:00
|
|
|
// Init the OSD display parameters.
|
2016-09-13 20:35:05 +02:00
|
|
|
_osdMessageAlpha = kOSDMessageInitialAlpha;
|
|
|
|
_osdMessageFadeStartTime = g_system->getMillis() + kOSDMessageFadeOutDelay;
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
// Clear the text update request
|
|
|
|
_osdMessageNextData.clear();
|
|
|
|
_osdMessageChangeRequest = false;
|
2016-06-03 17:44:26 +06:00
|
|
|
}
|
2016-09-13 20:35:05 +02:00
|
|
|
#endif
|
2016-06-03 17:44:26 +06:00
|
|
|
|
2016-09-13 20:35:05 +02:00
|
|
|
void OpenGLGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface *icon) {
|
2016-06-03 19:18:01 +06:00
|
|
|
#ifdef USE_OSD
|
2016-09-18 13:45:07 +02:00
|
|
|
if (_osdIconSurface) {
|
|
|
|
delete _osdIconSurface;
|
|
|
|
_osdIconSurface = nullptr;
|
|
|
|
|
|
|
|
// Make sure the icon is cleared on the next update
|
|
|
|
_forceRedraw = true;
|
|
|
|
}
|
2016-09-13 20:35:05 +02:00
|
|
|
|
2016-09-18 13:20:25 +02:00
|
|
|
if (icon) {
|
|
|
|
Graphics::Surface *converted = icon->convertTo(_defaultFormatAlpha);
|
2016-09-13 20:35:05 +02:00
|
|
|
|
|
|
|
_osdIconSurface = createSurface(_defaultFormatAlpha);
|
|
|
|
assert(_osdIconSurface);
|
|
|
|
// We always filter the osd with GL_LINEAR. This assures it's
|
|
|
|
// readable in case it needs to be scaled and does not affect it
|
|
|
|
// otherwise.
|
|
|
|
_osdIconSurface->enableLinearFiltering(true);
|
|
|
|
|
|
|
|
_osdIconSurface->allocate(converted->w, converted->h);
|
|
|
|
|
|
|
|
Graphics::Surface *dst = _osdIconSurface->getSurface();
|
|
|
|
|
|
|
|
// Copy the icon to the texture
|
|
|
|
dst->copyRectToSurface(*converted, 0, 0, Common::Rect(0, 0, converted->w, converted->h));
|
|
|
|
|
|
|
|
converted->free();
|
|
|
|
delete converted;
|
|
|
|
}
|
|
|
|
#endif
|
2016-09-18 13:20:25 +02:00
|
|
|
}
|
2016-06-04 15:56:15 +06:00
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
|
|
|
|
assert(_gameScreen->hasPalette());
|
|
|
|
|
|
|
|
memcpy(_gamePalette + start * 3, colors, num * 3);
|
|
|
|
_gameScreen->setPalette(start, num, colors);
|
|
|
|
|
|
|
|
// We might need to update the cursor palette here.
|
|
|
|
updateCursorPalette();
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
|
2013-08-16 05:29:56 +02:00
|
|
|
assert(_gameScreen->hasPalette());
|
|
|
|
|
|
|
|
memcpy(colors, _gamePalette + start * 3, num * 3);
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
|
2016-01-04 10:18:15 +01:00
|
|
|
// Setup backbuffer size.
|
|
|
|
_backBuffer.setDimensions(width, height);
|
2015-12-19 18:06:10 +01:00
|
|
|
|
2013-10-18 00:17:46 +02:00
|
|
|
uint overlayWidth = width;
|
|
|
|
uint overlayHeight = height;
|
|
|
|
|
|
|
|
// WORKAROUND: We can only support surfaces up to the maximum supported
|
|
|
|
// texture size. Thus, in case we encounter a physical size bigger than
|
|
|
|
// this maximum texture size we will simply use an overlay as big as
|
|
|
|
// possible and then scale it to the physical display size. This sounds
|
|
|
|
// bad but actually all recent chips should support full HD resolution
|
|
|
|
// anyway. Thus, it should not be a real issue for modern hardware.
|
2016-01-04 11:00:58 +01:00
|
|
|
if ( overlayWidth > (uint)g_context.maxTextureSize
|
|
|
|
|| overlayHeight > (uint)g_context.maxTextureSize) {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
|
2013-10-18 00:17:46 +02:00
|
|
|
|
|
|
|
if (outputAspect > (frac_t)FRAC_ONE) {
|
2016-01-04 11:00:58 +01:00
|
|
|
overlayWidth = g_context.maxTextureSize;
|
2013-10-18 00:17:46 +02:00
|
|
|
overlayHeight = intToFrac(overlayWidth) / outputAspect;
|
|
|
|
} else {
|
2016-01-04 11:00:58 +01:00
|
|
|
overlayHeight = g_context.maxTextureSize;
|
2013-10-18 00:17:46 +02:00
|
|
|
overlayWidth = fracToInt(overlayHeight * outputAspect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// HACK: We limit the minimal overlay size to 256x200, which is the
|
|
|
|
// minimum of the dimensions of the two resolutions 256x240 (NES) and
|
|
|
|
// 320x200 (many DOS games use this). This hopefully assure that our
|
|
|
|
// GUI has working layouts.
|
2013-10-18 00:17:46 +02:00
|
|
|
overlayWidth = MAX<uint>(overlayWidth, 256);
|
|
|
|
overlayHeight = MAX<uint>(overlayHeight, 200);
|
2013-08-16 05:29:56 +02:00
|
|
|
|
|
|
|
if (!_overlay || _overlay->getFormat() != _defaultFormatAlpha) {
|
|
|
|
delete _overlay;
|
|
|
|
_overlay = nullptr;
|
|
|
|
|
2016-01-02 05:54:08 +01:00
|
|
|
_overlay = createSurface(_defaultFormatAlpha);
|
2014-02-11 11:07:38 +01:00
|
|
|
assert(_overlay);
|
2013-10-18 00:17:46 +02:00
|
|
|
// We always filter the overlay with GL_LINEAR. This assures it's
|
|
|
|
// readable in case it needs to be scaled and does not affect it
|
|
|
|
// otherwise.
|
|
|
|
_overlay->enableLinearFiltering(true);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
_overlay->allocate(overlayWidth, overlayHeight);
|
|
|
|
_overlay->fill(0);
|
|
|
|
|
|
|
|
// Re-setup the scaling for the screen and cursor
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
recalculateDisplayAreas();
|
2013-08-16 05:29:56 +02:00
|
|
|
recalculateCursorScaling();
|
|
|
|
|
|
|
|
// Something changed, so update the screen change ID.
|
|
|
|
++_screenChangeID;
|
|
|
|
}
|
|
|
|
|
2015-12-18 21:14:48 +01:00
|
|
|
void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
|
2015-12-12 01:18:46 +01:00
|
|
|
// Initialize context for use.
|
2015-12-18 21:14:48 +01:00
|
|
|
initializeGLContext();
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2016-01-04 06:41:10 +01:00
|
|
|
// Initialize pipeline.
|
|
|
|
delete _pipeline;
|
|
|
|
_pipeline = nullptr;
|
|
|
|
|
|
|
|
#if !USE_FORCED_GLES
|
|
|
|
if (g_context.shadersSupported) {
|
2016-02-29 00:04:33 +01:00
|
|
|
ShaderMan.notifyCreate();
|
|
|
|
_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
|
2016-01-04 06:41:10 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !USE_FORCED_GLES2
|
|
|
|
if (_pipeline == nullptr) {
|
|
|
|
_pipeline = new FixedPipeline();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_context.setPipeline(_pipeline);
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// Disable 3D properties.
|
2015-12-12 03:22:51 +01:00
|
|
|
GL_CALL(glDisable(GL_CULL_FACE));
|
|
|
|
GL_CALL(glDisable(GL_DEPTH_TEST));
|
|
|
|
GL_CALL(glDisable(GL_DITHER));
|
2015-12-20 05:42:54 +01:00
|
|
|
|
2016-02-28 17:02:19 +01:00
|
|
|
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2016-01-04 10:18:15 +01:00
|
|
|
// Setup backbuffer state.
|
|
|
|
|
|
|
|
// Default to black as clear color.
|
|
|
|
_backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
|
2016-02-28 17:02:19 +01:00
|
|
|
g_context.getActivePipeline()->setFramebuffer(&_backBuffer);
|
2016-01-04 10:18:15 +01:00
|
|
|
|
2013-10-19 20:39:01 +02:00
|
|
|
// We use a "pack" alignment (when reading from textures) to 4 here,
|
|
|
|
// since the only place where we really use it is the BMP screenshot
|
|
|
|
// code and that requires the same alignment too.
|
2015-12-12 03:22:51 +01:00
|
|
|
GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
|
2013-10-19 20:39:01 +02:00
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// Refresh the output screen dimensions if some are set up.
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
if (_windowWidth != 0 && _windowHeight != 0) {
|
|
|
|
handleResize(_windowWidth, _windowHeight);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Should we try to convert textures into one of those formats if
|
|
|
|
// possible? For example, when _gameScreen is CLUT8 we might want to use
|
|
|
|
// defaultFormat now.
|
|
|
|
_defaultFormat = defaultFormat;
|
|
|
|
_defaultFormatAlpha = defaultFormatAlpha;
|
|
|
|
|
|
|
|
if (_gameScreen) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_gameScreen->recreate();
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_overlay) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_overlay->recreate();
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_cursor) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_cursor->recreate();
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
2013-08-19 00:44:55 +02:00
|
|
|
|
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
if (_osdMessageSurface) {
|
|
|
|
_osdMessageSurface->recreate();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_osdIconSurface) {
|
|
|
|
_osdIconSurface->recreate();
|
2013-08-19 00:44:55 +02:00
|
|
|
}
|
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
2014-02-11 11:07:37 +01:00
|
|
|
void OpenGLGraphicsManager::notifyContextDestroy() {
|
|
|
|
if (_gameScreen) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_gameScreen->destroy();
|
2014-02-11 11:07:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_overlay) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_overlay->destroy();
|
2014-02-11 11:07:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_cursor) {
|
2016-01-02 05:54:08 +01:00
|
|
|
_cursor->destroy();
|
2014-02-11 11:07:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_OSD
|
2016-09-13 20:35:05 +02:00
|
|
|
if (_osdMessageSurface) {
|
|
|
|
_osdMessageSurface->destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_osdIconSurface) {
|
|
|
|
_osdIconSurface->destroy();
|
2014-02-11 11:07:37 +01:00
|
|
|
}
|
|
|
|
#endif
|
2015-12-20 05:42:54 +01:00
|
|
|
|
2015-12-20 09:30:11 +01:00
|
|
|
#if !USE_FORCED_GLES
|
2016-01-04 07:07:37 +01:00
|
|
|
if (g_context.shadersSupported) {
|
|
|
|
ShaderMan.notifyDestroy();
|
2015-12-20 05:42:54 +01:00
|
|
|
}
|
|
|
|
#endif
|
2015-12-20 05:55:20 +01:00
|
|
|
|
2016-01-04 06:41:10 +01:00
|
|
|
// Destroy rendering pipeline.
|
|
|
|
g_context.setPipeline(nullptr);
|
|
|
|
delete _pipeline;
|
|
|
|
_pipeline = nullptr;
|
|
|
|
|
2015-12-20 05:55:20 +01:00
|
|
|
// Rest our context description since the context is gone soon.
|
|
|
|
g_context.reset();
|
2014-02-11 11:07:37 +01:00
|
|
|
}
|
|
|
|
|
2016-01-02 05:54:08 +01:00
|
|
|
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
|
2014-02-11 11:07:38 +01:00
|
|
|
GLenum glIntFormat, glFormat, glType;
|
|
|
|
if (format.bytesPerPixel == 1) {
|
2016-01-03 14:06:02 +01:00
|
|
|
#if !USE_FORCED_GLES
|
2016-01-02 14:09:41 +01:00
|
|
|
if (TextureCLUT8GPU::isSupportedByContext()) {
|
|
|
|
return new TextureCLUT8GPU();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-02-11 12:19:30 +01:00
|
|
|
const Graphics::PixelFormat &virtFormat = wantAlpha ? _defaultFormatAlpha : _defaultFormat;
|
|
|
|
const bool supported = getGLPixelFormat(virtFormat, glIntFormat, glFormat, glType);
|
2014-02-11 11:07:38 +01:00
|
|
|
if (!supported) {
|
|
|
|
return nullptr;
|
|
|
|
} else {
|
2014-02-11 12:19:30 +01:00
|
|
|
return new TextureCLUT8(glIntFormat, glFormat, glType, virtFormat);
|
2014-02-11 11:07:38 +01:00
|
|
|
}
|
2015-12-15 02:48:42 +01:00
|
|
|
#if !USE_FORCED_GL
|
|
|
|
} else if (isGLESContext() && format == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) {
|
|
|
|
// OpenGL ES does not support a texture format usable for RGB555.
|
|
|
|
// Since SCUMM uses this pixel format for some games (and there is no
|
|
|
|
// hope for this to change anytime soon) we use pixel format
|
|
|
|
// conversion to a supported texture format. However, this is a one
|
|
|
|
// time exception.
|
|
|
|
return new TextureRGB555();
|
|
|
|
#endif // !USE_FORCED_GL
|
2014-02-11 11:07:38 +01:00
|
|
|
} else {
|
|
|
|
const bool supported = getGLPixelFormat(format, glIntFormat, glFormat, glType);
|
|
|
|
if (!supported) {
|
|
|
|
return nullptr;
|
|
|
|
} else {
|
|
|
|
return new Texture(glIntFormat, glFormat, glType, format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const {
|
2014-02-12 18:06:29 +01:00
|
|
|
#ifdef SCUMM_LITTLE_ENDIAN
|
|
|
|
if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
|
|
|
|
#else
|
|
|
|
if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
|
|
|
|
#endif
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_BYTE;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
|
2013-08-16 05:29:56 +02:00
|
|
|
glIntFormat = GL_RGB;
|
|
|
|
glFormat = GL_RGB;
|
|
|
|
glType = GL_UNSIGNED_SHORT_5_6_5;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)) { // RGBA5551
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_4_4_4_4;
|
|
|
|
return true;
|
2015-12-20 05:42:54 +01:00
|
|
|
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
2015-12-12 22:08:33 +01:00
|
|
|
// The formats below are not supported by every GLES implementation.
|
|
|
|
// Thus, we do not mark them as supported when a GLES context is setup.
|
|
|
|
} else if (isGLESContext()) {
|
|
|
|
return false;
|
2014-02-12 18:06:29 +01:00
|
|
|
#ifdef SCUMM_LITTLE_ENDIAN
|
2014-02-12 18:06:29 +01:00
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_INT_8_8_8_8;
|
|
|
|
return true;
|
2014-02-12 18:06:29 +01:00
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555
|
|
|
|
glIntFormat = GL_RGB;
|
|
|
|
glFormat = GL_BGRA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)) { // ARGB4444
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_BGRA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
|
|
|
return true;
|
2014-02-12 18:06:29 +01:00
|
|
|
#ifdef SCUMM_BIG_ENDIAN
|
2013-08-16 05:29:56 +02:00
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
|
|
return true;
|
2014-02-12 18:06:29 +01:00
|
|
|
#endif
|
2013-08-16 05:29:56 +02:00
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) { // BGRA8888
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_BGRA;
|
|
|
|
glType = GL_UNSIGNED_INT_8_8_8_8;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0)) { // BGR565
|
|
|
|
glIntFormat = GL_RGB;
|
2016-01-02 02:22:09 +01:00
|
|
|
glFormat = GL_RGB;
|
|
|
|
glType = GL_UNSIGNED_SHORT_5_6_5_REV;
|
2013-08-16 05:29:56 +02:00
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0)) { // BGRA5551
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_BGRA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12)) { // ABGR4444
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_RGBA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
|
|
|
return true;
|
|
|
|
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)) { // BGRA4444
|
|
|
|
glIntFormat = GL_RGBA;
|
|
|
|
glFormat = GL_BGRA;
|
|
|
|
glType = GL_UNSIGNED_SHORT_4_4_4_4;
|
|
|
|
return true;
|
2015-12-20 05:42:54 +01:00
|
|
|
#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
|
2013-08-16 05:29:56 +02:00
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
bool OpenGLGraphicsManager::gameNeedsAspectRatioCorrection() const {
|
2013-08-16 05:29:56 +02:00
|
|
|
if (_currentState.aspectRatioCorrection) {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const uint width = getWidth();
|
|
|
|
const uint height = getHeight();
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
// In case we enable aspect ratio correction we force a 4/3 ratio.
|
|
|
|
// But just for 320x200 and 640x400 games, since other games do not need
|
|
|
|
// this.
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
return (width == 320 && height == 200) || (width == 640 && height == 400);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
return false;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
void OpenGLGraphicsManager::recalculateDisplayAreas() {
|
|
|
|
if (!_gameScreen) {
|
2013-08-16 05:29:56 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
WindowedGraphicsManager::recalculateDisplayAreas();
|
2015-01-07 20:02:10 +01:00
|
|
|
|
2015-12-11 21:22:42 +01:00
|
|
|
// Setup drawing limitation for game graphics.
|
2017-08-04 10:25:22 +02:00
|
|
|
// This involves some trickery because OpenGL's viewport coordinate system
|
2015-12-11 21:22:42 +01:00
|
|
|
// is upside down compared to ours.
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
_backBuffer.setScissorBox(_gameDrawRect.left,
|
|
|
|
_windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
|
|
|
|
_gameDrawRect.width(),
|
|
|
|
_gameDrawRect.height());
|
2015-12-11 21:22:42 +01:00
|
|
|
|
2015-01-07 20:02:10 +01:00
|
|
|
// Update the cursor position to adjust for new display area.
|
|
|
|
setMousePosition(_cursorX, _cursorY);
|
2015-12-11 19:54:47 +01:00
|
|
|
|
|
|
|
// Force a redraw to assure screen is properly redrawn.
|
|
|
|
_forceRedraw = true;
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::updateCursorPalette() {
|
|
|
|
if (!_cursor || !_cursor->hasPalette()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_cursorPaletteEnabled) {
|
|
|
|
_cursor->setPalette(0, 256, _cursorPalette);
|
|
|
|
} else {
|
|
|
|
_cursor->setPalette(0, 256, _gamePalette);
|
|
|
|
}
|
|
|
|
|
2016-01-02 05:06:32 +01:00
|
|
|
_cursor->setColorKey(_cursorKeyColor);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLGraphicsManager::recalculateCursorScaling() {
|
|
|
|
if (!_cursor || !_gameScreen) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// By default we use the unscaled versions.
|
|
|
|
_cursorHotspotXScaled = _cursorHotspotX;
|
|
|
|
_cursorHotspotYScaled = _cursorHotspotY;
|
|
|
|
_cursorWidthScaled = _cursor->getWidth();
|
|
|
|
_cursorHeightScaled = _cursor->getHeight();
|
|
|
|
|
|
|
|
// In case scaling is actually enabled we will scale the cursor according
|
|
|
|
// to the game screen.
|
|
|
|
if (!_cursorDontScale) {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const frac_t screenScaleFactorX = intToFrac(_gameDrawRect.width()) / _gameScreen->getWidth();
|
|
|
|
const frac_t screenScaleFactorY = intToFrac(_gameDrawRect.height()) / _gameScreen->getHeight();
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2014-02-12 17:15:07 +01:00
|
|
|
_cursorHotspotXScaled = fracToInt(_cursorHotspotXScaled * screenScaleFactorX);
|
|
|
|
_cursorWidthScaled = fracToInt(_cursorWidthScaled * screenScaleFactorX);
|
2013-08-16 05:29:56 +02:00
|
|
|
|
2014-02-12 17:15:07 +01:00
|
|
|
_cursorHotspotYScaled = fracToInt(_cursorHotspotYScaled * screenScaleFactorY);
|
|
|
|
_cursorHeightScaled = fracToInt(_cursorHeightScaled * screenScaleFactorY);
|
2013-08-16 05:29:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:44:55 +02:00
|
|
|
#ifdef USE_OSD
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const Graphics::Font *OpenGLGraphicsManager::getFontOSD() const {
|
2013-08-19 00:44:55 +02:00
|
|
|
return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-04-24 01:06:03 +01:00
|
|
|
bool OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
|
BACKENDS: Refactor OpenGL & SDL graphics backends
This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.
Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.
The biggest behavioral change here is with the coordinate
system mapping:
Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.
Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.
This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:
* Nullipotent operations (getWidth, getHeight, etc.) of the
PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
been de-virtualized
* Extra unnecessary calculations of hardware height in
SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
(setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
overridden virtual methods in subclasses (primarily to avoid
myself accidentally creating new methods in the subclasses
by changing types/names during refactoring)
Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.
2017-07-19 19:15:12 -05:00
|
|
|
const uint width = _windowWidth;
|
|
|
|
const uint height = _windowHeight;
|
2013-10-19 20:39:01 +02:00
|
|
|
|
|
|
|
// A line of a BMP image must have a size divisible by 4.
|
|
|
|
// We calculate the padding bytes needed here.
|
|
|
|
// Since we use a 3 byte per pixel mode, we can use width % 4 here, since
|
|
|
|
// it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
|
|
|
|
// usual way of computing the padding bytes required).
|
2017-05-12 12:44:44 -05:00
|
|
|
// GL_PACK_ALIGNMENT is 4, so this line padding is required for PNG too
|
2013-10-19 20:39:01 +02:00
|
|
|
const uint linePaddingSize = width % 4;
|
|
|
|
const uint lineSize = width * 3 + linePaddingSize;
|
|
|
|
|
2017-05-12 12:44:44 -05:00
|
|
|
Common::DumpFile out;
|
|
|
|
if (!out.open(filename)) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-10-19 20:39:01 +02:00
|
|
|
|
2017-05-12 12:44:44 -05:00
|
|
|
Common::Array<uint8> pixels;
|
|
|
|
pixels.resize(lineSize * height);
|
|
|
|
GL_CALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixels.front()));
|
2013-10-19 20:39:01 +02:00
|
|
|
|
2017-05-12 12:44:44 -05:00
|
|
|
const Graphics::PixelFormat format(3, 8, 8, 8, 0, 16, 8, 0, 0);
|
|
|
|
Graphics::Surface data;
|
|
|
|
data.init(width, height, lineSize, &pixels.front(), format);
|
2019-03-01 00:15:43 +00:00
|
|
|
#ifdef USE_PNG
|
2017-05-12 12:44:44 -05:00
|
|
|
return Image::writePNG(out, data, true);
|
|
|
|
#else
|
2019-03-01 00:15:43 +00:00
|
|
|
return Image::writeBMP(out, data, true);
|
2017-05-12 12:44:44 -05:00
|
|
|
#endif
|
2013-10-19 20:39:01 +02:00
|
|
|
}
|
|
|
|
|
2013-08-16 05:29:56 +02:00
|
|
|
} // End of namespace OpenGL
|