1 | // SuperTux |
2 | // Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com> |
3 | // |
4 | // This program is free software: you can redistribute it and/or modify |
5 | // it under the terms of the GNU General Public License as published by |
6 | // the Free Software Foundation, either version 3 of the License, or |
7 | // (at your option) any later version. |
8 | // |
9 | // This program is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | // GNU General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU General Public License |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | |
17 | #include "video/sdl/sdl_video_system.hpp" |
18 | |
19 | #include <sstream> |
20 | |
21 | #include "math/rect.hpp" |
22 | #include "supertux/gameconfig.hpp" |
23 | #include "supertux/globals.hpp" |
24 | #include "util/log.hpp" |
25 | #include "video/renderer.hpp" |
26 | #include "video/sdl/sdl_screen_renderer.hpp" |
27 | #include "video/sdl/sdl_texture.hpp" |
28 | #include "video/sdl/sdl_texture_renderer.hpp" |
29 | #include "video/sdl_surface.hpp" |
30 | #include "video/texture_manager.hpp" |
31 | |
32 | SDLVideoSystem::SDLVideoSystem() : |
33 | m_sdl_renderer(nullptr, &SDL_DestroyRenderer), |
34 | m_viewport(), |
35 | m_renderer(), |
36 | m_lightmap(), |
37 | m_texture_manager() |
38 | { |
39 | create_window(); |
40 | |
41 | m_renderer.reset(new SDLScreenRenderer(*this, m_sdl_renderer.get())); |
42 | m_texture_manager.reset(new TextureManager); |
43 | |
44 | apply_config(); |
45 | } |
46 | |
47 | SDLVideoSystem::~SDLVideoSystem() |
48 | { |
49 | } |
50 | |
51 | std::string |
52 | SDLVideoSystem::get_name() const |
53 | { |
54 | SDL_version version; |
55 | SDL_GetVersion(&version); |
56 | std::ostringstream out; |
57 | out << "SDL " |
58 | << static_cast<int>(version.major) |
59 | << "." << static_cast<int>(version.minor) |
60 | << "." << static_cast<int>(version.patch); |
61 | return out.str(); |
62 | } |
63 | |
64 | void |
65 | SDLVideoSystem::create_window() |
66 | { |
67 | log_info << "Creating SDLVideoSystem" << std::endl; |
68 | |
69 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2" ); |
70 | |
71 | create_sdl_window(0); |
72 | |
73 | m_sdl_renderer.reset(SDL_CreateRenderer(m_sdl_window.get(), -1, 0)); |
74 | if (!m_sdl_renderer) |
75 | { |
76 | std::stringstream msg; |
77 | msg << "Couldn't create SDL_Renderer: " << SDL_GetError(); |
78 | throw std::runtime_error(msg.str()); |
79 | } |
80 | } |
81 | |
82 | void |
83 | SDLVideoSystem::apply_config() |
84 | { |
85 | apply_video_mode(); |
86 | |
87 | { // apply_viewport |
88 | Size target_size = (g_config->use_fullscreen && g_config->fullscreen_size != Size(0, 0)) ? |
89 | g_config->fullscreen_size : |
90 | g_config->window_size; |
91 | |
92 | m_viewport = Viewport::from_size(target_size, m_desktop_size); |
93 | } |
94 | |
95 | m_lightmap.reset(new SDLTextureRenderer(*this, m_sdl_renderer.get(), m_viewport.get_screen_size(), 5)); |
96 | } |
97 | |
98 | Renderer& |
99 | SDLVideoSystem::get_renderer() const |
100 | { |
101 | return *m_renderer; |
102 | } |
103 | |
104 | Renderer& |
105 | SDLVideoSystem::get_lightmap() const |
106 | { |
107 | return *m_lightmap; |
108 | } |
109 | |
110 | TexturePtr |
111 | SDLVideoSystem::new_texture(const SDL_Surface& image, const Sampler& sampler) |
112 | { |
113 | return TexturePtr(new SDLTexture(image, sampler)); |
114 | } |
115 | |
116 | void |
117 | SDLVideoSystem::set_vsync(int mode) |
118 | { |
119 | log_warning << "Setting vsync not supported by SDL renderer" << std::endl; |
120 | } |
121 | |
122 | int |
123 | SDLVideoSystem::get_vsync() const |
124 | { |
125 | return 0; |
126 | } |
127 | |
128 | void |
129 | SDLVideoSystem::flip() |
130 | { |
131 | m_renderer->flip(); |
132 | } |
133 | |
134 | SDLSurfacePtr |
135 | SDLVideoSystem::make_screenshot() |
136 | { |
137 | int width; |
138 | int height; |
139 | if (SDL_GetRendererOutputSize(m_renderer->get_sdl_renderer(), &width, &height) != 0) |
140 | { |
141 | log_warning << "SDL_GetRenderOutputSize failed: " << SDL_GetError() << std::endl; |
142 | return {}; |
143 | } |
144 | else |
145 | { |
146 | SDLSurfacePtr surface = SDLSurface::create_rgba(width, height); |
147 | |
148 | SDL_LockSurface(surface.get()); |
149 | int ret = SDL_RenderReadPixels(m_renderer->get_sdl_renderer(), nullptr, |
150 | SDL_PIXELFORMAT_ABGR8888, |
151 | surface->pixels, |
152 | surface->pitch); |
153 | SDL_UnlockSurface(surface.get()); |
154 | |
155 | if (ret != 0) |
156 | { |
157 | log_warning << "SDL_RenderReadPixels failed: " << SDL_GetError() << std::endl; |
158 | return {}; |
159 | } |
160 | else |
161 | { |
162 | return surface; |
163 | } |
164 | } |
165 | } |
166 | |
167 | /* EOF */ |
168 | |