From 6181499b1c4a4f586f60d305cec89f8e3ec3cb86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Thu, 12 Jun 2014 16:54:33 +0200 Subject: [PATCH 01/15] Don't rotate the logo on the loadscreen. That was some test code committed by mistake. --- src/loadscreen.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/loadscreen.cpp b/src/loadscreen.cpp index 337ed8ab148e..1257b265899c 100644 --- a/src/loadscreen.cpp +++ b/src/loadscreen.cpp @@ -136,8 +136,7 @@ void loadscreen::draw_screen(const std::string &text) // Draw logo if it was successfully loaded. #if SDL_VERSION_ATLEAST(2,0,0) - static int angle = 0; - if (!logo_texture_.null() /*&& !logo_drawn_*/) { + if (!logo_texture_.null() && !logo_drawn_) { int x = (screen_.getx () - logo_texture_.width()) / 2; int y = ((scry - logo_texture_.height()) / 2) - pbh; @@ -151,7 +150,6 @@ void loadscreen::draw_screen(const std::string &text) } } logo_drawn_ = true; - logo_texture_.set_rotation(angle+=3); } #else if (logo_surface_ && !logo_drawn_) { From 561cb5bc7de361fe2fc94b31d807cdc5a0f72c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Sat, 14 Jun 2014 21:29:01 +0200 Subject: [PATCH 02/15] Add a separate cache for brightened images. --- src/image.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/image.cpp b/src/image.cpp index a91b6ab78b7e..a033c8a9abb0 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -128,7 +128,8 @@ image::image_cache images_, #if SDL_VERSION_ATLEAST(2,0,0) /** Rexture caches */ image::texture_cache txt_images_, - txt_hexed_images_; + txt_hexed_images_, + txt_brightened_images_; #endif // cache storing if each image fit in a hex @@ -910,16 +911,31 @@ sdl::ttexture get_texture(const locator& loc, TYPE type) texture_cache *cache; - if (type == UNSCALED || type == SCALED_TO_ZOOM) { - cache = &txt_images_; - } else { + switch (type) { + case UNSCALED: + case SCALED_TO_ZOOM: + cache = &txt_hexed_images_; + break; + case BRIGHTENED: + cache = &txt_brightened_images_; + break; + case HEXED: + case SCALED_TO_HEX: + case TOD_COLORED: cache = &txt_hexed_images_; + break; + default: + return sdl::ttexture(); } if (!loc.in_cache(*cache)) { if (type == UNSCALED || type == SCALED_TO_ZOOM) { sdl::ttexture txt = load_texture(loc); loc.add_to_cache(*cache, txt); + } else if (type == BRIGHTENED) { + surface surf = get_brightened(loc); + sdl::ttexture txt = CVideo::get_window()->create_texture(SDL_TEXTUREACCESS_STATIC, surf); + loc.add_to_cache(*cache, txt); } else { surface surf = get_hexed(loc); sdl::ttexture txt = CVideo::get_window()->create_texture(SDL_TEXTUREACCESS_STATIC, surf); @@ -932,9 +948,8 @@ sdl::ttexture get_texture(const locator& loc, TYPE type) switch (type) { case UNSCALED: case HEXED: - break; case BRIGHTENED: - //TODO: brighten + break; case TOD_COLORED: result.set_color_mod(red_adjust, green_adjust, blue_adjust); case SCALED_TO_ZOOM: From 10af944c1d5dc66eb264c3c41fd6d69403e033c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Sun, 15 Jun 2014 08:20:29 +0200 Subject: [PATCH 03/15] Do set the color mod on the actual texture. --- src/sdl/texture.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index 3f8a7a482ce0..d5de197240f6 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -348,6 +348,8 @@ void ttexture::set_color_mod(Uint8 r, Uint8 g, Uint8 b) mod_r_ = r; mod_g_ = g; mod_b_ = b; + + SDL_SetTextureColorMod(texture_, r, g, b); } Uint8 ttexture::red_mod() const From 752b42c02e5dd9ae5f0c74618baf088ba0f655ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Sun, 15 Jun 2014 09:47:56 +0200 Subject: [PATCH 04/15] Use the correct cache for non-hexed images. --- src/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/image.cpp b/src/image.cpp index a033c8a9abb0..c25fe36ef8a1 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -914,7 +914,7 @@ sdl::ttexture get_texture(const locator& loc, TYPE type) switch (type) { case UNSCALED: case SCALED_TO_ZOOM: - cache = &txt_hexed_images_; + cache = &txt_images_; break; case BRIGHTENED: cache = &txt_brightened_images_; From 616ab5f656ab2a733a26dbf5b4c19e4fda92e9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Sun, 15 Jun 2014 20:13:43 +0200 Subject: [PATCH 05/15] Store alpha value in ttexture and set it before drawing. Several ttexture instances may share a single SDL_Texture, so having everyone store their alpha mod directly in the SDL_Texture object is not viable. --- src/sdl/texture.cpp | 13 +++++++++---- src/sdl/texture.hpp | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index d5de197240f6..1743c9aa9a26 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -43,6 +43,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) + , alpha_(0) , source_surface_(NULL) { if(!texture_) { @@ -64,6 +65,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) + , alpha_(0) , source_surface_(IMG_Load(file.c_str())) { if(source_surface_ == NULL) { @@ -86,6 +88,7 @@ ttexture::ttexture() , mod_r_(0) , mod_g_(0) , mod_b_(0) + , alpha_(0) , source_surface_(NULL) {} @@ -117,6 +120,7 @@ ttexture::ttexture(const ttexture& texture) , mod_r_(texture.mod_r_) , mod_g_(texture.mod_g_) , mod_b_(texture.mod_b_) + , alpha_(texture.alpha_) , source_surface_(texture.source_surface_) { assert(reference_count_); @@ -140,6 +144,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) + , alpha_(0) , source_surface_(source_surface__) { if(source_surface_ == NULL) { @@ -165,6 +170,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) + , alpha_(0) , source_surface_( SDL_ConvertSurface(surface, surface->format, surface->flags)) { @@ -191,6 +197,7 @@ void ttexture::draw(SDL_Renderer& renderer, const int x, const int y) { SDL_Rect dstrect = create_rect(x, y, clip_.w * hscale_, clip_.h * vscale_); + SDL_SetTextureAlphaMod(texture_, alpha_); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, smooth_scaling_ ? "linear" : "nearest"); SDL_RenderCopyEx(&renderer, texture_, &clip_, &dstrect, rotation_, NULL, flip_); @@ -321,14 +328,12 @@ Uint32 ttexture::format() const void ttexture::set_alpha(Uint8 alpha) { - SDL_SetTextureAlphaMod(texture_, alpha); + alpha_ = alpha; } Uint8 ttexture::alpha() const { - Uint8 res; - SDL_GetTextureAlphaMod(texture_, &res); - return res; + return alpha_; } void ttexture::set_blend_mode(SDL_BlendMode mode) diff --git a/src/sdl/texture.hpp b/src/sdl/texture.hpp index 3791f780b6d9..6457784648f5 100644 --- a/src/sdl/texture.hpp +++ b/src/sdl/texture.hpp @@ -345,6 +345,9 @@ class ttexture /** Color modulation. */ Uint8 mod_r_, mod_g_, mod_b_; + /** Alpha. */ + Uint8 alpha_; + /** * The SDL_Surface source of the @ref texture_. * From f698ddabdc4893967eded5d3e3132dbbeec2e4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Sun, 15 Jun 2014 23:38:37 +0200 Subject: [PATCH 06/15] Remove set_blend_mode from ttexture. I can't think of any use case when we would use anything else than SDL_BLENDMODE_BLEND. If anyone can, they can re-add it. --- src/sdl/texture.cpp | 14 ++------------ src/sdl/texture.hpp | 12 ------------ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index 1743c9aa9a26..1bd6d4ff35a7 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -46,6 +46,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , alpha_(0) , source_surface_(NULL) { + SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); if(!texture_) { throw texception("Failed to create a SDL_Texture object.", true); } @@ -336,18 +337,6 @@ Uint8 ttexture::alpha() const return alpha_; } -void ttexture::set_blend_mode(SDL_BlendMode mode) -{ - SDL_SetTextureBlendMode(texture_, mode); -} - -SDL_BlendMode ttexture::blend_mode() const -{ - SDL_BlendMode res; - SDL_GetTextureBlendMode(texture_, &res); - return res; -} - void ttexture::set_color_mod(Uint8 r, Uint8 g, Uint8 b) { mod_r_ = r; @@ -431,6 +420,7 @@ void ttexture::initialise_from_surface(SDL_Renderer& renderer, const int access) } else { throw texception("Unknown texture access mode.", false); } + SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); } } // namespace sdl diff --git a/src/sdl/texture.hpp b/src/sdl/texture.hpp index 6457784648f5..73d29fee3219 100644 --- a/src/sdl/texture.hpp +++ b/src/sdl/texture.hpp @@ -259,18 +259,6 @@ class ttexture */ Uint8 alpha() const; - /** - * Sets the blend mode of the texture. - * - * @param mode One of the values enumerated in SDL_BlendMode. - */ - void set_blend_mode(SDL_BlendMode mode); - - /** - * Returns the blend mode of the texture. - */ - SDL_BlendMode blend_mode() const; - /** * Sets the color modulation of the texture. * From 20b0ea6ab31db6f7866fe4f94c77810c4a1eae72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 09:24:02 +0200 Subject: [PATCH 07/15] Initialize texture alpha mod to 255 instead of 0. --- src/sdl/texture.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index 1bd6d4ff35a7..b9c4c009e4d4 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -43,7 +43,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) - , alpha_(0) + , alpha_(255) , source_surface_(NULL) { SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); @@ -66,7 +66,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) - , alpha_(0) + , alpha_(255) , source_surface_(IMG_Load(file.c_str())) { if(source_surface_ == NULL) { @@ -89,7 +89,7 @@ ttexture::ttexture() , mod_r_(0) , mod_g_(0) , mod_b_(0) - , alpha_(0) + , alpha_(255) , source_surface_(NULL) {} @@ -145,7 +145,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) - , alpha_(0) + , alpha_(255) , source_surface_(source_surface__) { if(source_surface_ == NULL) { @@ -171,7 +171,7 @@ ttexture::ttexture(SDL_Renderer& renderer, , mod_r_(0) , mod_g_(0) , mod_b_(0) - , alpha_(0) + , alpha_(255) , source_surface_( SDL_ConvertSurface(surface, surface->format, surface->flags)) { From d6ea2e02909ca85e35fb51dcac52b834af77714d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 10:20:17 +0200 Subject: [PATCH 08/15] Set the color mod before rendering. --- src/sdl/texture.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index b9c4c009e4d4..fceb74b0876f 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -199,6 +199,7 @@ void ttexture::draw(SDL_Renderer& renderer, const int x, const int y) SDL_Rect dstrect = create_rect(x, y, clip_.w * hscale_, clip_.h * vscale_); SDL_SetTextureAlphaMod(texture_, alpha_); + SDL_SetTextureColorMod(texture_, r, g, b); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, smooth_scaling_ ? "linear" : "nearest"); SDL_RenderCopyEx(&renderer, texture_, &clip_, &dstrect, rotation_, NULL, flip_); @@ -342,8 +343,6 @@ void ttexture::set_color_mod(Uint8 r, Uint8 g, Uint8 b) mod_r_ = r; mod_g_ = g; mod_b_ = b; - - SDL_SetTextureColorMod(texture_, r, g, b); } Uint8 ttexture::red_mod() const From 4bbdc09af689da477aff825d0c16919a479e55e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 13:03:15 +0200 Subject: [PATCH 09/15] Return an int for the width/height of ttexture. SDL (and all of our own functions) use ints, so having these functions return an unsigned value can lead to all kinds of two's complement troubles. --- src/sdl/texture.cpp | 36 ++++++++++++++++++------------------ src/sdl/texture.hpp | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index fceb74b0876f..4c0cf573279c 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -40,9 +40,9 @@ ttexture::ttexture(SDL_Renderer& renderer, , smooth_scaling_(false) , flip_(SDL_FLIP_NONE) , clip_(create_rect(0, 0, w, h)) - , mod_r_(0) - , mod_g_(0) - , mod_b_(0) + , mod_r_(255) + , mod_g_(255) + , mod_b_(255) , alpha_(255) , source_surface_(NULL) { @@ -63,9 +63,9 @@ ttexture::ttexture(SDL_Renderer& renderer, , smooth_scaling_(false) , flip_(SDL_FLIP_NONE) , clip_() - , mod_r_(0) - , mod_g_(0) - , mod_b_(0) + , mod_r_(255) + , mod_g_(255) + , mod_b_(255) , alpha_(255) , source_surface_(IMG_Load(file.c_str())) { @@ -86,9 +86,9 @@ ttexture::ttexture() , smooth_scaling_(false) , flip_(SDL_FLIP_NONE) , clip_() - , mod_r_(0) - , mod_g_(0) - , mod_b_(0) + , mod_r_(255) + , mod_g_(255) + , mod_b_(255) , alpha_(255) , source_surface_(NULL) {} @@ -142,9 +142,9 @@ ttexture::ttexture(SDL_Renderer& renderer, , smooth_scaling_(false) , flip_(SDL_FLIP_NONE) , clip_() - , mod_r_(0) - , mod_g_(0) - , mod_b_(0) + , mod_r_(255) + , mod_g_(255) + , mod_b_(255) , alpha_(255) , source_surface_(source_surface__) { @@ -168,9 +168,9 @@ ttexture::ttexture(SDL_Renderer& renderer, , smooth_scaling_(false) , flip_(SDL_FLIP_NONE) , clip_() - , mod_r_(0) - , mod_g_(0) - , mod_b_(0) + , mod_r_(255) + , mod_g_(255) + , mod_b_(255) , alpha_(255) , source_surface_( SDL_ConvertSurface(surface, surface->format, surface->flags)) @@ -199,7 +199,7 @@ void ttexture::draw(SDL_Renderer& renderer, const int x, const int y) SDL_Rect dstrect = create_rect(x, y, clip_.w * hscale_, clip_.h * vscale_); SDL_SetTextureAlphaMod(texture_, alpha_); - SDL_SetTextureColorMod(texture_, r, g, b); + SDL_SetTextureColorMod(texture_, mod_r_, mod_g_, mod_b_); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, smooth_scaling_ ? "linear" : "nearest"); SDL_RenderCopyEx(&renderer, texture_, &clip_, &dstrect, rotation_, NULL, flip_); @@ -284,7 +284,7 @@ bool ttexture::flopped() const return flip_ & SDL_FLIP_VERTICAL; } -unsigned ttexture::width() const +int ttexture::width() const { int w; SDL_QueryTexture(texture_,NULL, NULL, &w, NULL); @@ -292,7 +292,7 @@ unsigned ttexture::width() const return w; } -unsigned ttexture::height() const +int ttexture::height() const { int h; SDL_QueryTexture(texture_,NULL, NULL, NULL, &h); diff --git a/src/sdl/texture.hpp b/src/sdl/texture.hpp index 73d29fee3219..6e57a300667f 100644 --- a/src/sdl/texture.hpp +++ b/src/sdl/texture.hpp @@ -218,12 +218,12 @@ class ttexture /** * Returns the width of the texture. */ - unsigned width() const; + int width() const; /** * Returns the height of the texture. */ - unsigned height() const; + int height() const; /** * Returns the frame of the texture. From c69b5a3bb64afd684d818532f7e0979919cf498c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 14:24:25 +0200 Subject: [PATCH 10/15] When retrieving dimensions, return the scaled size of the texture. --- src/sdl/texture.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index 4c0cf573279c..e3bb389177a7 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -289,7 +289,7 @@ int ttexture::width() const int w; SDL_QueryTexture(texture_,NULL, NULL, &w, NULL); - return w; + return w*hscale_; } int ttexture::height() const @@ -297,7 +297,7 @@ int ttexture::height() const int h; SDL_QueryTexture(texture_,NULL, NULL, NULL, &h); - return h; + return h*vscale_; } SDL_Rect ttexture::dimensions() const @@ -307,6 +307,8 @@ SDL_Rect ttexture::dimensions() const dim.y = 0; SDL_QueryTexture(texture_, NULL, NULL, &dim.w, &dim.h); + dim.w *= hscale_; + dim.h *= vscale_; return dim; } From 26d40c15c9b34b64917eaeebdc733f30e9e809f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 15:21:33 +0200 Subject: [PATCH 11/15] Render background layers as textures on the storyscreen. --- src/storyscreen/render.cpp | 77 ++++++++++++++++++++++++++++++++++++++ src/storyscreen/render.hpp | 9 +++++ 2 files changed, 86 insertions(+) diff --git a/src/storyscreen/render.cpp b/src/storyscreen/render.cpp index d0bed2051350..9ac92e496dfa 100644 --- a/src/storyscreen/render.cpp +++ b/src/storyscreen/render.cpp @@ -34,6 +34,10 @@ #include +#if SDL_VERSION_ATLEAST(2,0,0) +#include "sdl/texture.hpp" +#endif + static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) #define WARN_NG LOG_STREAM(warn, log_engine) @@ -90,7 +94,12 @@ part_ui::part_ui(part &p, display &disp, gui::button &next_button, , x_scale_factor_(1.0) , y_scale_factor_(1.0) , base_rect_() +#if SDL_VERSION_ATLEAST(2,0,0) + , background_images_() + , background_positions_() +#else , background_(NULL) +#endif , imgs_() , has_background_(false) , text_x_(200) @@ -105,6 +114,62 @@ part_ui::part_ui(part &p, display &disp, gui::button &next_button, void part_ui::prepare_background() { +#if SDL_VERSION_ATLEAST(2,0,0) + base_rect_.w = video_.getx(); + base_rect_.h = video_.gety(); + has_background_ = false; + bool no_base_yet = true; + + BOOST_FOREACH(const background_layer& bl, p_.get_background_layers()) { + sdl::ttexture layer; + + if (!bl.file().empty()) { + layer = image::get_texture(bl.file()); + } + has_background_ = has_background_ || !layer.null(); + if(layer.null() || layer.width() * layer.height() == 0) { + continue; + } + + const double xscale = 1.0 * video_.getx() / layer.width(); + const double yscale = 1.0 * video_.gety() / layer.height(); + const bool scalev = bl.scale_vertically(); + const bool scaleh = bl.scale_horizontally(); + const bool keep_ratio = bl.keep_aspect_ratio(); + + double x_scale_factor = scaleh ? xscale : 1.0; + double y_scale_factor = scalev ? yscale : 1.0; + + if (scalev && scaleh && keep_ratio) { + x_scale_factor = y_scale_factor = std::min(xscale, yscale); + } else if (keep_ratio && scaleh) { + x_scale_factor = y_scale_factor = xscale; + } else if (keep_ratio && scalev) { + x_scale_factor = y_scale_factor = yscale; + } + + layer.set_smooth_scaling(true); + layer.set_scale(x_scale_factor, y_scale_factor); + //TODO: tiling + + SDL_Rect base_rect = sdl::create_rect( + (video_.getx() - layer.width()) / 2 + , (video_.gety() - layer.height()) / 2 + , layer.width() + , layer.height()); + + background_images_.push_back(layer); + background_positions_.push_back(std::pair(base_rect.x, base_rect.y)); + + if (bl.is_base_layer() || no_base_yet) { + x_scale_factor_ = x_scale_factor; + y_scale_factor_ = y_scale_factor; + base_rect_ = base_rect; + no_base_yet = false; + } + } + +#else background_.assign( create_neutral_surface(video_.getx(), video_.gety()) ); base_rect_.w = video_.getx(); base_rect_.h = video_.gety(); @@ -183,6 +248,7 @@ void part_ui::prepare_background() no_base_yet = false; } } +#endif } void part_ui::prepare_geometry() @@ -231,11 +297,22 @@ void part_ui::prepare_floating_images() void part_ui::render_background() { +#if SDL_VERSION_ATLEAST(2,0,0) + sdl::twindow *wnd = CVideo::get_window(); + wnd->fill(0, 0, 0); + for (size_t i = 0; idraw(background_images_[i], x, y); + } +#else sdl::draw_solid_tinted_rectangle( 0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0, video_.getSurface() ); sdl_blit(background_, NULL, video_.getSurface(), NULL); +#endif } bool part_ui::render_floating_images() diff --git a/src/storyscreen/render.hpp b/src/storyscreen/render.hpp index a9512b5bf17e..953702b5769f 100644 --- a/src/storyscreen/render.hpp +++ b/src/storyscreen/render.hpp @@ -25,6 +25,10 @@ #include "storyscreen/part.hpp" // #include "widgets/button.hpp" +#if SDL_VERSION_ATLEAST(2,0,0) +#include "sdl/texture.hpp" +#endif + class display; class CVideo; @@ -83,7 +87,12 @@ class part_ui // (the background layer we align the images to) SDL_Rect base_rect_; +#if SDL_VERSION_ATLEAST(2,0,0) + std::vector< sdl::ttexture > background_images_; + std::vector< std::pair > background_positions_; +#else surface background_; +#endif std::vector< floating_image::render_input > imgs_; bool has_background_; From fac9ea5617b26405e726767b71850d7260b6e1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 15:41:36 +0200 Subject: [PATCH 12/15] Render floating images as textures on the storyscreen. --- src/storyscreen/part.cpp | 24 ++++++++++++++++++++++++ src/storyscreen/part.hpp | 5 +++++ src/storyscreen/render.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/storyscreen/part.cpp b/src/storyscreen/part.cpp index 84b28f84c4e3..2e3c211f63ea 100644 --- a/src/storyscreen/part.cpp +++ b/src/storyscreen/part.cpp @@ -67,6 +67,29 @@ void floating_image::assign(const floating_image& fi) floating_image::render_input floating_image::get_render_input(double xscale, double yscale, SDL_Rect& dst_rect) const { +#if SDL_VERSION_ATLEAST(2,0,0) + render_input ri = { + {0,0,0,0}, + file_.empty() ? sdl::ttexture() : image::get_texture(file_) + }; + + if(!ri.image.null()) { + if(autoscaled_) { + ri.image.set_scale(xscale, yscale); + } + + ri.rect.x = static_cast(x_*xscale) + dst_rect.x; + ri.rect.y = static_cast(y_*yscale) + dst_rect.y; + ri.rect.w = ri.image.width(); + ri.rect.h = ri.image.height(); + + if(centered_) { + ri.rect.x -= ri.rect.w / 2; + ri.rect.y -= ri.rect.h / 2; + } + } + return ri; +#else render_input ri = { {0,0,0,0}, file_.empty() ? NULL : image::get_image(file_) @@ -92,6 +115,7 @@ floating_image::render_input floating_image::get_render_input(double xscale, dou } } return ri; +#endif } background_layer::background_layer() diff --git a/src/storyscreen/part.hpp b/src/storyscreen/part.hpp index fffa670cee40..780417986ef2 100644 --- a/src/storyscreen/part.hpp +++ b/src/storyscreen/part.hpp @@ -25,6 +25,7 @@ #include #include "sdl/utils.hpp" +#include "sdl/texture.hpp" class config; class vconfig; @@ -42,7 +43,11 @@ class floating_image struct render_input { SDL_Rect rect; /**< Corrected rectangle for rendering surf. */ +#if SDL_VERSION_ATLEAST(2,0,0) + sdl::ttexture image; +#else surface image; /**< Surface, scaled if required. */ +#endif }; /** diff --git a/src/storyscreen/render.cpp b/src/storyscreen/render.cpp index 9ac92e496dfa..ebda438ec7e4 100644 --- a/src/storyscreen/render.cpp +++ b/src/storyscreen/render.cpp @@ -36,6 +36,7 @@ #if SDL_VERSION_ATLEAST(2,0,0) #include "sdl/texture.hpp" +#include "sdl/window.hpp" #endif static lg::log_domain log_engine("engine"); @@ -317,6 +318,37 @@ void part_ui::render_background() bool part_ui::render_floating_images() { +#if SDL_VERSION_ATLEAST(2,0,0) + sdl::twindow *wnd = CVideo::get_window(); + + skip_ = false; + last_key_ = true; + + size_t fi_n = 0; + BOOST_FOREACH(floating_image::render_input& ri, imgs_) { + const floating_image& fi = p_.get_floating_images()[fi_n]; + + if(!ri.image.null()) { + wnd->draw(ri.image, ri.rect.x, ri.rect.y); + wnd->render(); + } + + if (!skip_) + { + int delay = fi.display_delay(), delay_step = 20; + for (int i = 0; i != (delay + delay_step - 1) / delay_step; ++i) + { + if (handle_interface()) return false; + if (skip_) break; + disp_.delay(std::min(delay_step, delay - i * delay_step)); + } + } + + ++fi_n; + } + + return true; +#else events::raise_draw_event(); update_whole_screen(); @@ -347,6 +379,7 @@ bool part_ui::render_floating_images() } return true; +#endif } void part_ui::render_title_box() From 976e439d977b3d2599e433ca24327762083a1d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Mon, 16 Jun 2014 17:21:28 +0200 Subject: [PATCH 13/15] Match function declarations with definitions. --- src/sdl/rect.cpp | 8 ++++---- src/sdl/rect.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sdl/rect.cpp b/src/sdl/rect.cpp index 109d912b8de1..a51a2bcfeefe 100644 --- a/src/sdl/rect.cpp +++ b/src/sdl/rect.cpp @@ -112,15 +112,15 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h, #if SDL_VERSION_ATLEAST(2,0,0) -void fill_rect(SDL_Renderer *rnd, SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b, - Uint8 a) +void fill_rect(SDL_Renderer *rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, + Uint8 b, Uint8 a) { SDL_SetRenderDrawColor(rnd, r, g, b, a); SDL_RenderFillRect(rnd, rect); } -void draw_rect(SDL_Renderer *rnd, SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b, - Uint8 a) +void draw_rect(SDL_Renderer *rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, + Uint8 b, Uint8 a) { SDL_SetRenderDrawColor(rnd, r, g, b, a); SDL_RenderDrawRect(rnd, rect); diff --git a/src/sdl/rect.hpp b/src/sdl/rect.hpp index 913ac10c7c80..b3db68fd1551 100644 --- a/src/sdl/rect.hpp +++ b/src/sdl/rect.hpp @@ -142,10 +142,10 @@ inline void fill_rect(surface& dst, SDL_Rect* dst_rect, const Uint32 color) } #if SDL_VERSION_ATLEAST(2,0,0) -void fill_rect(SDL_Renderer &rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, +void fill_rect(SDL_Renderer *rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -void draw_rect(SDL_Renderer &rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, +void draw_rect(SDL_Renderer *rnd, const SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b, Uint8 a); #endif } // namespace sdl From c59414b121d0d4c7fbba0b08ba6304df2d2b5607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Tue, 17 Jun 2014 14:11:44 +0200 Subject: [PATCH 14/15] Enable rendering text as a texture. --- src/text.cpp | 16 ++++++++++++++++ src/text.hpp | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/text.cpp b/src/text.cpp index b95d0c19c66f..cb2ba2824447 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -29,6 +29,10 @@ #include #include +#if SDL_VERSION_ATLEAST(2,0,0) +#include "video.hpp" +#endif + namespace font { namespace { @@ -155,6 +159,14 @@ surface ttext::render() const return surface_; } +#if SDL_VERSION_ATLEAST(2,0,0) +sdl::ttexture ttext::render_as_texture() const +{ + rerender(); + return texture_; +} +#endif + int ttext::get_width() const { return get_size().x; @@ -684,6 +696,10 @@ void ttext::rerender(const bool force) const surface_.assign(SDL_CreateRGBSurfaceFrom( surface_buffer_, width, height, 32, stride, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000)); +#if SDL_VERSION_ATLEAST(2,0,0) + texture_ = CVideo::get_window()->create_texture + (SDL_TEXTUREACCESS_STATIC, surface_); +#endif cairo_destroy(cr); cairo_surface_destroy(cairo_surface); } diff --git a/src/text.hpp b/src/text.hpp index 488c1f4f2d10..81a2abc93d2e 100644 --- a/src/text.hpp +++ b/src/text.hpp @@ -25,6 +25,10 @@ #include +#if SDL_VERSION_ATLEAST(2,0,0) +#include "sdl/texture.hpp" +#endif + struct language_def; namespace gui2 { @@ -72,6 +76,16 @@ class ttext */ surface render() const; +#if SDL_VERSION_ATLEAST(2,0,0) + /** + * Returns the rendered text as a texture. + * + * Before rendering it tests whether a redraw is needed and if so it first + * redraws the texture before returning it. + */ + sdl::ttexture render_as_texture() const; +#endif + /** Returns the width needed for the text. */ int get_width() const; @@ -208,6 +222,11 @@ class ttext /** The surface to render upon used as a cache. */ mutable surface surface_; +#if SDL_VERSION_ATLEAST(2,0,0) + /** The texture to render upon used as a cache. */ + mutable sdl::ttexture texture_; +#endif + /** The text to draw (stored as UTF-8). */ std::string text_; From 050235c4393151f38a6af824e56ba12a6eb6023a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boldizs=C3=A1r=20Lipka?= Date: Tue, 17 Jun 2014 14:13:36 +0200 Subject: [PATCH 15/15] Render everything on the loadscreen using the renderer API. Only when building against SDL2, obviously. --- src/loadscreen.cpp | 85 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/src/loadscreen.cpp b/src/loadscreen.cpp index 1257b265899c..2c9dfe1a00a1 100644 --- a/src/loadscreen.cpp +++ b/src/loadscreen.cpp @@ -28,6 +28,10 @@ #include "video.hpp" #include "image.hpp" +#if SDL_VERSION_ATLEAST(2,0,0) +#include "text.hpp" +#endif + #include #include @@ -116,26 +120,24 @@ void loadscreen::draw_screen(const std::string &text) // Height of the lighting line. int lightning_thickness = 2; - surface gdis = screen_.getSurface(); +#if SDL_VERSION_ATLEAST(2,0,0) + sdl::twindow *wnd = CVideo::get_window(); + SDL_Renderer *rnd = SDL_GetRenderer(*wnd); + SDL_Rect area; // Pump events and make sure to redraw the logo if there's a chance that it's been obscured SDL_Event ev; while(SDL_PollEvent(&ev)) { -#if SDL_VERSION_ATLEAST(2, 0, 0) if(ev.type == SDL_WINDOWEVENT && (ev.window.event == SDL_WINDOWEVENT_RESIZED || ev.window.event == SDL_WINDOWEVENT_EXPOSED)) -#else - if(ev.type == SDL_VIDEORESIZE || ev.type == SDL_VIDEOEXPOSE) -#endif { logo_drawn_ = false; } } // Draw logo if it was successfully loaded. -#if SDL_VERSION_ATLEAST(2,0,0) if (!logo_texture_.null() && !logo_drawn_) { int x = (screen_.getx () - logo_texture_.width()) / 2; int y = ((scry - logo_texture_.height()) / 2) - pbh; @@ -143,7 +145,7 @@ void loadscreen::draw_screen(const std::string &text) // Check if we have enough pixels to display it. if (x > 0 && y > 0) { pby_offset_ = (pbh + logo_texture_.height())/2; - CVideo::get_window()->draw(logo_texture_, x, y); + wnd->draw(logo_texture_, x, y); } else { if (!screen_.faked()) { // Avoid error if --nogui is used. ERR_DP << "loadscreen: Logo image is too big." << std::endl; @@ -151,7 +153,73 @@ void loadscreen::draw_screen(const std::string &text) } logo_drawn_ = true; } + int pbx = (scrx - pbw)/2; // Horizontal location. + int pby = (scry - pbh)/2 + pby_offset_; // Vertical location. + + // Draw top border. + area.x = pbx; area.y = pby; + area.w = pbw + 2*(bw+bispw); area.h = bw; + sdl::fill_rect(rnd,&area,bcr,bcg,bcb,255); + // Draw bottom border. + area.x = pbx; area.y = pby + pbh + bw + 2*bispw; + area.w = pbw + 2*(bw+bispw); area.h = bw; + sdl::fill_rect(rnd,&area,bcr,bcg,bcb,255); + // Draw left border. + area.x = pbx; area.y = pby + bw; + area.w = bw; area.h = pbh + 2*bispw; + sdl::fill_rect(rnd,&area,bcr,bcg,bcb,255); + // Draw right border. + area.x = pbx + pbw + bw + 2*bispw; area.y = pby + bw; + area.w = bw; area.h = pbh + 2*bispw; + sdl::fill_rect(rnd,&area,bcr,bcg,bcb,255); + // Draw the finished bar area. + area.x = pbx + bw + bispw; area.y = pby + bw + bispw; + area.w = (prcnt_ * pbw) / 100; area.h = pbh; + sdl::fill_rect(rnd,&area,fcr,fcg,fcb,255); + + SDL_Rect lightning = area; + lightning.h = lightning_thickness; + //we add 25% of white to the color of the bar to simulate a light effect + sdl::fill_rect(rnd,&lightning,(fcr*3+255)/4,(fcg*3+255)/4,(fcb*3+255)/4,255); + lightning.y = area.y+area.h-lightning.h; + //remove 50% of color to simulate a shadow effect + sdl::fill_rect(rnd,&lightning,fcr/2,fcg/2,fcb/2,255); + + // Draw the leftover bar area. + area.x = pbx + bw + bispw + (prcnt_ * pbw) / 100; area.y = pby + bw + bispw; + area.w = ((100 - prcnt_) * pbw) / 100; area.h = pbh; + sdl::fill_rect(rnd, &area, lcr, lcg, lcb, 255); + + // Clear the last text and draw new if text is provided. + if (!text.empty()) + { + sdl::fill_rect(rnd, &textarea_, 0, 0, 0, 255); + + font::ttext txt; + txt.set_text(text, false); + // A text-ure... haha, get it? + sdl::ttexture texture = txt.render_as_texture(); + textarea_.h = texture.height(); + textarea_.w = texture.width(); + textarea_.x = scrx/2 + bw + bispw - textarea_.w / 2; + textarea_.y = pby + pbh + 4*(bw + bispw); + wnd->draw(texture, textarea_.x, textarea_.y); + } + CVideo::get_window()->render(); #else + surface gdis = screen_.getSurface(); + SDL_Rect area; + + // Pump events and make sure to redraw the logo if there's a chance that it's been obscured + SDL_Event ev; + while(SDL_PollEvent(&ev)) { + if(ev.type == SDL_VIDEORESIZE || ev.type == SDL_VIDEOEXPOSE) + { + logo_drawn_ = false; + } + } + + // Draw logo if it was successfully loaded. if (logo_surface_ && !logo_drawn_) { area.x = (screen_.getx () - logo_surface_->w) / 2; area.y = ((scry - logo_surface_->h) / 2) - pbh; @@ -169,7 +237,6 @@ void loadscreen::draw_screen(const std::string &text) logo_drawn_ = true; update_rect(area.x, area.y, area.w, area.h); } -#endif int pbx = (scrx - pbw)/2; // Horizontal location. int pby = (scry - pbh)/2 + pby_offset_; // Vertical location. @@ -222,8 +289,6 @@ void loadscreen::draw_screen(const std::string &text) // Update the rectangle. update_rect(pbx, pby, pbw + 2*(bw + bispw), pbh + 2*(bw + bispw)); screen_.flip(); -#if SDL_VERSION_ATLEAST(2,0,0) - CVideo::get_window()->render(); #endif }