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
32SDLVideoSystem::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
47SDLVideoSystem::~SDLVideoSystem()
48{
49}
50
51std::string
52SDLVideoSystem::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
64void
65SDLVideoSystem::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
82void
83SDLVideoSystem::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
98Renderer&
99SDLVideoSystem::get_renderer() const
100{
101 return *m_renderer;
102}
103
104Renderer&
105SDLVideoSystem::get_lightmap() const
106{
107 return *m_lightmap;
108}
109
110TexturePtr
111SDLVideoSystem::new_texture(const SDL_Surface& image, const Sampler& sampler)
112{
113 return TexturePtr(new SDLTexture(image, sampler));
114}
115
116void
117SDLVideoSystem::set_vsync(int mode)
118{
119 log_warning << "Setting vsync not supported by SDL renderer" << std::endl;
120}
121
122int
123SDLVideoSystem::get_vsync() const
124{
125 return 0;
126}
127
128void
129SDLVideoSystem::flip()
130{
131 m_renderer->flip();
132}
133
134SDLSurfacePtr
135SDLVideoSystem::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