1 // Copyright Timothy Goya 2007.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
8 #include <unison/video/Window.hpp>
9 #include <unison/video/Surface.hpp>
10 #include <unison/video/Texture.hpp>
11 #include <unison/video/Renderers.hpp>
12 #include <unison/video/sdl/Blitters.hpp>
13 #include <unison/video/backend/Renderer.hpp>
14 #include <unison/video/backend/Texture.hpp>
27 Window::Window(const Area &size, const Area &logical_size, bool fullscreen) :
35 unsigned int xratio = size.x * logical_size.y;
36 unsigned int yratio = size.y * logical_size.x;
39 scale_numerator = size.x;
40 scale_denominator = logical_size.x;
44 scale_numerator = size.y;
45 scale_denominator = logical_size.y;
47 offset = (size - logical_size * scale_numerator / scale_denominator) / 2;
48 window = SDL_SetVideoMode(size.x, size.y, 0, SDL_ANYFORMAT | SDL_SWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0));
50 Uint32 black = SDL_MapRGB(window->format, 0, 0, 0);
51 SDL_FillRect(window, 0, black);
58 void Window::take_screenshot(const std::string &filename) const
61 SDL_SaveBMP(window, filename.c_str());
70 void Window::set_title(const std::string &title)
72 SDL_WM_SetCaption(title.c_str(), title.c_str());
75 void Window::set_icon(const Surface &icon)
77 SDL_Surface *icon_surface = Blitters::create_sdl_surface_from(icon);
79 SDL_WM_SetIcon(icon_surface, 0);
80 SDL_FreeSurface(icon_surface);
83 Area Window::get_size() const
85 return Area(window->w, window->h);
88 bool Window::is_fullscreen() const
90 return window->flags & SDL_FULLSCREEN;
93 void Window::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
95 assert(src.get_pixels());
99 if(src_rect.pos == Point() && (src_rect.size == Area() || src_rect.size == src.get_size()))
105 fragment = Surface(src_rect.size);
106 Video::Blitters::blit_blend_none(src, src_rect, fragment, Point());
108 fragment = fragment.scale(scale_numerator, scale_denominator);
111 fragment = fragment.h_flip();
115 fragment = fragment.v_flip();
117 SDL_Surface *src_surface = Blitters::create_sdl_surface_from(fragment.modulate(options.color).modulate(options.alpha));
120 Point scaled_dst_pos(dst_pos);
121 scaled_dst_pos *= scale_numerator;
122 scaled_dst_pos /= scale_denominator;
123 scaled_dst_pos += offset;
125 Blitters::blit_blend(src_surface, Rect(Point(), fragment.get_size()), window, scaled_dst_pos, options.blend);
127 SDL_FreeSurface(src_surface);
130 void Window::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
132 Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
136 Rect scaled_src_rect(src_rect);
139 scaled_src_rect.pos.x = src.get_size().x - src_rect.pos.x - src_rect.size.x;
143 scaled_src_rect.pos.y = src.get_size().y - src_rect.pos.y - src_rect.size.y;
147 if(scaled_src_rect.size.x < (unsigned int) -dst_pos.x)
151 scaled_src_rect.pos.x += -dst_pos.x;
152 scaled_src_rect.size.x += dst_pos.x;
156 if(scaled_src_rect.size.y < (unsigned int) -dst_pos.y)
160 scaled_src_rect.pos.y += -dst_pos.y;
161 scaled_src_rect.size.y += dst_pos.y;
163 scaled_src_rect.pos *= scale_numerator;
164 scaled_src_rect.pos /= scale_denominator;
165 scaled_src_rect.size *= scale_numerator;
166 scaled_src_rect.size /= scale_denominator;
168 Point scaled_dst_pos(dst_pos);
171 scaled_dst_pos.x = 0;
175 scaled_dst_pos.y = 0;
177 scaled_dst_pos *= scale_numerator;
178 scaled_dst_pos /= scale_denominator;
179 scaled_dst_pos += offset;
181 Blitters::blit_blend(texture->get_transform(options, scale_numerator, scale_denominator), scaled_src_rect, window, scaled_dst_pos, options.blend);
184 void Window::fill(const Color &color, const Rect &rect)
188 Uint32 mapped = SDL_MapRGBA(window->format, color.red, color.green, color.blue, color.alpha);
190 Rect scaled_rect(rect);
191 scaled_rect.pos *= scale_numerator;
192 scaled_rect.pos /= scale_denominator;
193 scaled_rect.size *= scale_numerator;
194 scaled_rect.size /= scale_denominator;
195 scaled_rect.pos += offset;
197 SDL_FillRect(window, &scaled_rect, mapped);
200 void Window::fill_blend(const Color &color, const Rect &rect)
204 Uint32 mapped = SDL_MapRGB(window->format, color.red, color.green, color.blue);
206 Rect scaled_rect(rect);
207 scaled_rect.pos *= scale_numerator;
208 scaled_rect.pos /= scale_denominator;
209 scaled_rect.size *= scale_numerator;
210 scaled_rect.size /= scale_denominator;
211 scaled_rect.pos += offset;
213 if(color.alpha == 0xff)
215 SDL_FillRect(window, &scaled_rect, mapped);
217 else if(color.alpha != 0x00)
219 SDL_Surface *temp = SDL_CreateRGBSurface(window->flags, scaled_rect.size.x, scaled_rect.size.y, window->format->BitsPerPixel, window->format->Rmask, window->format->Gmask, window->format->Bmask, window->format->Amask);
221 SDL_FillRect(temp, 0, mapped);
222 SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, color.alpha);
223 SDL_BlitSurface(temp, 0, window, &scaled_rect);
224 SDL_FreeSurface(temp);