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