1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "engines/stark/gfx/driver.h"
24 #include "engines/stark/gfx/opengls.h"
25
26 #include "common/config-manager.h"
27
28 #include "graphics/surface.h"
29 #ifdef USE_OPENGL
30 #include "graphics/opengl/context.h"
31 #endif
32
33 namespace Stark {
34 namespace Gfx {
35
create()36 Driver *Driver::create() {
37 #if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
38 bool fullscreen = ConfMan.getBool("fullscreen");
39 g_system->setupScreen(kOriginalWidth, kOriginalHeight, fullscreen, true);
40
41 if (OpenGLContext.shadersSupported) {
42 return new OpenGLSDriver();
43 } else {
44 error("Your system does not have the required OpenGL capabilities");
45 }
46 #endif // defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
47
48 error("No renderers have been found for this game");
49 }
50
getRGBAPixelFormat()51 const Graphics::PixelFormat Driver::getRGBAPixelFormat() {
52 #ifdef SCUMM_BIG_ENDIAN
53 return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
54 #else
55 return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
56 #endif
57 }
58
toggleFullscreen() const59 void Driver::toggleFullscreen() const {
60 if (!g_system->hasFeature(OSystem::kFeatureFullscreenToggleKeepsContext)) {
61 warning("Unable to toggle the fullscreen state because the current backend would destroy the graphics context");
62 return;
63 }
64
65 bool oldFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
66 g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !oldFullscreen);
67 }
68
computeScreenViewport()69 void Driver::computeScreenViewport() {
70 int32 screenWidth = g_system->getWidth();
71 int32 screenHeight = g_system->getHeight();
72
73 if (g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection)) {
74 // Aspect ratio correction
75 int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
76 int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
77 _screenViewport = Common::Rect(viewportWidth, viewportHeight);
78
79 // Pillarboxing
80 _screenViewport.translate((screenWidth - viewportWidth) / 2,
81 (screenHeight - viewportHeight) / 2);
82 } else {
83 // Aspect ratio correction disabled, just stretch
84 _screenViewport = Common::Rect(screenWidth, screenHeight);
85 }
86 }
87
gameViewport() const88 Common::Rect Driver::gameViewport() const {
89 Common::Rect game = Common::Rect(_screenViewport.width(), _screenViewport.height() * kGameViewportHeight / kOriginalHeight);
90 game.translate(_screenViewport.left, _screenViewport.top + _screenViewport.height() * kBottomBorderHeight / kOriginalHeight);
91
92 return game;
93 }
94
getScreenPosBounded(const Common::Point & point) const95 Common::Point Driver::getScreenPosBounded(const Common::Point &point) const {
96 Common::Point boundedPos = point;
97 boundedPos.x = CLIP<int16>(boundedPos.x, _screenViewport.left, _screenViewport.right);
98
99 return boundedPos;
100 }
101
convertCoordinateCurrentToOriginal(const Common::Point & point) const102 Common::Point Driver::convertCoordinateCurrentToOriginal(const Common::Point &point) const {
103 // Most of the engine expects 640x480 coordinates
104 Common::Point scaledPosition = point;
105 scaledPosition.x -= _screenViewport.left;
106 scaledPosition.y -= _screenViewport.top;
107 scaledPosition.x = CLIP<int16>(scaledPosition.x, 0, _screenViewport.width());
108 scaledPosition.y = CLIP<int16>(scaledPosition.y, 0, _screenViewport.height());
109 scaledPosition.x *= kOriginalWidth / (float)_screenViewport.width();
110 scaledPosition.y *= kOriginalHeight / (float)_screenViewport.height();
111
112 return scaledPosition;
113 }
114
scaleWidthOriginalToCurrent(uint width) const115 uint Driver::scaleWidthOriginalToCurrent(uint width) const {
116 return _screenViewport.width() * width / kOriginalWidth;
117 }
118
scaleHeightOriginalToCurrent(uint height) const119 uint Driver::scaleHeightOriginalToCurrent(uint height) const {
120 return _screenViewport.height() * height / kOriginalHeight;
121 }
122
flipVertical(Graphics::Surface * s)123 void Driver::flipVertical(Graphics::Surface *s) {
124 for (int y = 0; y < s->h / 2; ++y) {
125 // Flip the lines
126 byte *line1P = (byte *)s->getBasePtr(0, y);
127 byte *line2P = (byte *)s->getBasePtr(0, s->h - y - 1);
128
129 for (int x = 0; x < s->pitch; ++x)
130 SWAP(line1P[x], line2P[x]);
131 }
132 }
133
134 } // End of namespace Gfx
135 } // End of namespace Stark
136