Cleaned up handling of basic alpha setting

This does a few things:
* Refactored adjust_surface_alpha to use SDL_SetSurfaceAlphaMod
* Made all uses of the legacy SDL_SetAlpha use adjust_surface_alpha
* Made adjust_surface_alpha now take a non-const reference and perform the operation on the surface directly.
This commit is contained in:
Charles Dang 2016-09-13 09:20:10 +11:00
parent 5857098ab7
commit 55ba8c95bc
22 changed files with 69 additions and 159 deletions

View file

@ -957,8 +957,6 @@
<Unit filename="../../src/scripting/plugins/context.hpp" />
<Unit filename="../../src/scripting/plugins/manager.cpp" />
<Unit filename="../../src/scripting/plugins/manager.hpp" />
<Unit filename="../../src/sdl/alpha.cpp" />
<Unit filename="../../src/sdl/alpha.hpp" />
<Unit filename="../../src/sdl/exception.cpp" />
<Unit filename="../../src/sdl/exception.hpp" />
<Unit filename="../../src/sdl/image.cpp" />

View file

@ -389,7 +389,6 @@ set_target_properties(wesnoth-lua
########### Helper libraries ###############
set(wesnoth-sdl_SRC
sdl/alpha.cpp
sdl/exception.cpp
sdl/rect.cpp
sdl/image.cpp

View file

@ -158,7 +158,6 @@ libcampaignd_sources = Split("""
libcampaignd = env.Library("campaignd", libcampaignd_sources, OBJPREFIX = "campaignd_")
libwesnoth_sdl_sources = Split("""
sdl/alpha.cpp
sdl/exception.cpp
sdl/image.cpp
sdl/rect.cpp
@ -690,7 +689,6 @@ test_utils_sources = Split("""
""")
wesmage_sources = Split("""
sdl/alpha.cpp
sdl/utils.cpp
sdl/window.cpp
tools/dummy_video.cpp
@ -742,7 +740,6 @@ test_sources.extend(test_env.Object("tests/test_config_cache.cpp"))
test = test_env.WesnothProgram("test", test_sources + [libtest_utils, libwesnoth_extras, libwesnoth_core, libwesnoth, libwesnoth_sdl, libwesnoth_extras], have_test_prereqs)
create_images_sources = Split("""
sdl/alpha.cpp
sdl/utils.cpp
sdl/window.cpp
tests/create_images.cpp

View file

@ -23,7 +23,6 @@
#include "language.hpp"
#include "marked-up_text.hpp"
#include "resources.hpp"
#include "sdl/alpha.hpp"
#include "units/unit.hpp"
#include "units/abilities.hpp"
@ -431,7 +430,7 @@ void battle_prediction_pane::get_hp_distrib_surface(const std::vector<std::pair<
surf = create_neutral_surface(width, height);
// Disable alpha channel to avoid problem with sdl_blit
SDL_SetAlpha(surf, 0, SDL_ALPHA_OPAQUE);
adjust_surface_alpha(surf, SDL_ALPHA_OPAQUE);
SDL_Rect clip_rect = sdl::create_rect(0, 0, width, height);
Uint32 grey_color = SDL_MapRGBA(surf->format, 0xb7, 0xc1, 0xc1, SDL_ALPHA_OPAQUE);

View file

@ -1758,7 +1758,7 @@ void display::render_image(int x, int y, const display::tdrawing_layer drawing_l
//} else if(alpha != 1.0 && blendto != 0) {
// surf.assign(blend_surface(surf,1.0-alpha,blendto));
} else if(alpha != ftofxp(1.0)) {
surf = adjust_surface_alpha(surf, alpha, false);
adjust_surface_alpha(surf, alpha);
}
if(surf == nullptr) {

View file

@ -183,7 +183,7 @@ void mouse_action::set_terrain_mouse_overlay(editor_display& disp, const t_trans
image = mask_surface(image, image::get_hexmask());
// Add the alpha factor
image = adjust_surface_alpha(image, alpha);
adjust_surface_alpha(image, alpha);
// scale the image
const int zoom = disp.hex_size();
@ -344,7 +344,8 @@ void mouse_action_paste::set_mouse_overlay(editor_display& disp)
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}
@ -399,7 +400,7 @@ editor_action* mouse_action_starting_position::up_left(editor_display& disp, int
return nullptr;
}
auto player_starting_at_hex = disp.map().is_starting_position(hex);
if (has_ctrl_modifier()) {
if (player_starting_at_hex) {
location_palette_.add_item(*player_starting_at_hex);
@ -461,7 +462,8 @@ void mouse_action_starting_position::set_mouse_overlay(editor_display& disp)
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -244,7 +244,8 @@ void mouse_action_item::set_item_mouse_overlay(editor_display& disp, const overl
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -121,7 +121,8 @@ void mouse_action_map_label::set_mouse_overlay(editor_display& disp)
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -70,7 +70,8 @@ void mouse_action_select::set_mouse_overlay(editor_display& disp)
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -244,7 +244,8 @@ void mouse_action_unit::set_unit_mouse_overlay(editor_display& disp, const unit_
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -52,7 +52,8 @@ void mouse_action_village::set_mouse_overlay(editor_display& disp)
int zoom = static_cast<int>(size * disp.get_zoom_factor());
// Add the alpha factor and scale the image
image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);
adjust_surface_alpha(image, alpha);
image = scale_surface(image, zoom, zoom);
disp.set_mouseover_hex_overlay(image);
}

View file

@ -24,7 +24,6 @@
#include "log.hpp"
#include "marked-up_text.hpp"
#include "serialization/string_utils.hpp"
#include "sdl/alpha.hpp"
#include "sound.hpp"
#include "video.hpp"
#include "wml_separators.hpp"
@ -252,8 +251,8 @@ void tristate_button::draw_contents() {
}
// TODO for later reference
// SDL_SetAlpha(nbase, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
// SDL_SetAlpha(image, 0, 0);
// adjust_surface_alpha(nbase, SDL_ALPHA_OPAQUE);
// adjust_surface_alpha(image, SDL_ALPHA_TRANSPARENT);
//
// TODO might be needed.
bg_restore();

View file

@ -23,8 +23,6 @@
#include <set>
#include <stack>
#include "sdl/alpha.hpp"
static lg::log_domain log_font("font");
#define DBG_FT LOG_STREAM(debug, log_font)
#define LOG_FT LOG_STREAM(info, log_font)
@ -119,10 +117,10 @@ sdl::timage floating_label::create_image()
// dark background will darken the anti-aliased part.
// This 1.13 value seems to restore the brightness of version 1.4
// (where the text was blitted directly on screen)
foreground = adjust_surface_alpha(foreground, ftofxp(1.13), false);
adjust_surface_alpha(foreground, ftofxp(1.13));
SDL_Rect r = sdl::create_rect( border_, border_, 0, 0);
SDL_SetAlpha(foreground,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
blit_surface(foreground, nullptr, background, &r);
img_ = sdl::timage(background);
@ -141,7 +139,7 @@ sdl::timage floating_label::create_image()
img_ = sdl::timage(foreground);
return img_;
}
SDL_SetAlpha(foreground,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
blit_surface(foreground, nullptr, background, &r);
img_ = sdl::timage(background);
}
@ -192,16 +190,16 @@ surface floating_label::create_surface()
// dark background will darken the anti-aliased part.
// This 1.13 value seems to restore the brightness of version 1.4
// (where the text was blitted directly on screen)
foreground = adjust_surface_alpha(foreground, ftofxp(1.13), false);
adjust_surface_alpha(foreground, ftofxp(1.13));
SDL_Rect r = sdl::create_rect( border_, border_, 0, 0);
SDL_SetAlpha(foreground,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
blit_surface(foreground, nullptr, background, &r);
surf_ = create_optimized_surface(background);
// RLE compression seems less efficient for big semi-transparent area
// so, remove it for this case, but keep the optimized display format
SDL_SetAlpha(surf_,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(surf_, SDL_ALPHA_OPAQUE);
}
else {
// background is blurred shadow of the text
@ -217,7 +215,7 @@ surface floating_label::create_surface()
surf_ = create_optimized_surface(foreground);
return surf_;
}
SDL_SetAlpha(foreground,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
blit_surface(foreground, nullptr, background, &r);
surf_ = create_optimized_surface(background);
}

View file

@ -25,7 +25,6 @@
#include "marked-up_text.hpp"
#include "text.hpp"
#include "tooltips.hpp"
#include "sdl/alpha.hpp"
#include "sdl/rect.hpp"
#include "serialization/parser.hpp"
#include "serialization/preprocessor.hpp"
@ -853,7 +852,7 @@ static surface render_text(const std::string& text, int fontsize, const SDL_Colo
return surface();
} else if (surfaces.size() == 1 && surfaces.front().size() == 1) {
surface surf = surfaces.front().front();
SDL_SetAlpha(surf, SDL_SRCALPHA | SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
adjust_surface_alpha(surf, SDL_ALPHA_OPAQUE);
return surf;
} else {
@ -862,14 +861,14 @@ static surface render_text(const std::string& text, int fontsize, const SDL_Colo
return res;
size_t ypos = 0;
for(std::vector< std::vector<surface> >::const_iterator i = surfaces.begin(),
for(std::vector< std::vector<surface> >::iterator i = surfaces.begin(),
i_end = surfaces.end(); i != i_end; ++i) {
size_t xpos = 0;
size_t height = 0;
for(std::vector<surface>::const_iterator j = i->begin(),
for(std::vector<surface>::iterator j = i->begin(),
j_end = i->end(); j != j_end; ++j) {
SDL_SetAlpha(*j, 0, 0); // direct blit without alpha blending
adjust_surface_alpha(*j, SDL_ALPHA_TRANSPARENT); // direct blit without alpha blending
SDL_Rect dstrect = sdl::create_rect(xpos, ypos, 0, 0);
sdl_blit(*j, nullptr, res, &dstrect);
xpos += (*j)->w;

View file

@ -118,8 +118,8 @@ void game_display::new_turn()
const time_of_day& old_tod = tod_manager_->get_previous_time_of_day();
if(old_tod.image_mask != tod.image_mask) {
const surface old_mask(image::get_image(old_tod.image_mask,image::SCALED_TO_HEX));
const surface new_mask(image::get_image(tod.image_mask,image::SCALED_TO_HEX));
surface old_mask(image::get_image(old_tod.image_mask,image::SCALED_TO_HEX));
surface new_mask(image::get_image(tod.image_mask,image::SCALED_TO_HEX));
const int niterations = static_cast<int>(10/turbo_speed());
const int frame_time = 30;
@ -139,12 +139,14 @@ void game_display::new_turn()
#else
if(old_mask != nullptr) {
const fixed_t proportion = ftofxp(1.0) - fxpdiv(i,niterations);
tod_hex_mask1.assign(adjust_surface_alpha(old_mask,proportion));
adjust_surface_alpha(old_mask, proportion);
tod_hex_mask1.assign(old_mask);
}
if(new_mask != nullptr) {
const fixed_t proportion = fxpdiv(i,niterations);
tod_hex_mask2.assign(adjust_surface_alpha(new_mask,proportion));
adjust_surface_alpha(new_mask, proportion);
tod_hex_mask2.assign(new_mask);
}
#endif

View file

@ -19,7 +19,6 @@
#include "image.hpp"
#include "image_modifications.hpp"
#include "log.hpp"
#include "sdl/alpha.hpp"
#include "serialization/string_utils.hpp"
#include <map>
@ -224,8 +223,7 @@ surface wipe_alpha_modification::operator()(const surface& src) const
surface adjust_alpha_modification::operator()(const surface & src) const
{
return adjust_surface_alpha_formula(src, formula_);
}
return adjust_surface_alpha_formula(src, formula_);}
surface crop_modification::operator()(const surface& src) const
{
@ -397,7 +395,7 @@ std::pair<int,int> scale_exact_modification::calculate_size(const surface& src)
}
h = old_h;
}
return std::make_pair(w, h);
}
@ -420,7 +418,7 @@ std::pair<int,int> scale_into_modification::calculate_size(const surface& src) c
}
h = old_h;
}
long double ratio = std::min(w / old_w, h / old_h);
return std::make_pair(old_w * ratio, old_h * ratio);
@ -435,9 +433,12 @@ surface xbrz_modification::operator()(const surface& src) const
return scale_surface_xbrz(src, z_);
}
// TODO: make this take a non-const reference and don't construct the temp surface
surface o_modification::operator()(const surface& src) const
{
return adjust_surface_alpha(src, ftofxp(opacity_));
surface temp = src;
adjust_surface_alpha(temp, ftofxp(opacity_));
return temp;
}
float o_modification::get_opacity() const
@ -523,13 +524,15 @@ surface darken_modification::operator()(const surface &src) const
return ret;
}
// TODO: make this take a non-const reference and don't construct the temp surface
surface background_modification::operator()(const surface &src) const
{
surface ret = make_neutral_surface(src);
SDL_FillRect(ret, nullptr, SDL_MapRGBA(ret->format, color_.r, color_.g,
color_.b, color_.a));
SDL_SetAlpha(src, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
blit_surface(src, nullptr, ret, nullptr);
surface temp = src;
adjust_surface_alpha(temp, SDL_ALPHA_OPAQUE);
blit_surface(temp, nullptr, ret, nullptr);
return ret;
}

View file

@ -1,31 +0,0 @@
/*
Copyright (C) 2014 - 2016 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "sdl/alpha.hpp"
int SDL_SetAlpha(SDL_Surface* surface, Uint32 flag, Uint8 alpha)
{
if(flag & SDL_SRCALPHA) {
// Need to specify the alpha blend mode if not setting alpha as opaque
int blendModeResult = SDL_SetSurfaceBlendMode (surface, SDL_BLENDMODE_BLEND);
if (blendModeResult != 0)
return blendModeResult;
return SDL_SetSurfaceAlphaMod(surface, alpha);
} else {
return SDL_SetSurfaceAlphaMod(surface, SDL_ALPHA_OPAQUE);
}
}

View file

@ -1,33 +0,0 @@
/*
Copyright (C) 2014 - 2016 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef SDL_ALPHA_HPP_INCLUDED
#define SDL_ALPHA_HPP_INCLUDED
/**
* @file
* Compatibility layer for using SDL 1.2 and 2.0.
*
* Emulates SDL_SetAlpha.
*/
#include <SDL.h>
#define SDL_SRCALPHA 0x00010000
int SDL_SetAlpha(SDL_Surface* surface, Uint32 flag, Uint8 alpha);
#endif

View file

@ -13,7 +13,6 @@
*/
#include "sdl/rect.hpp"
#include "sdl/alpha.hpp"
#include "sdl/utils.hpp"
#ifdef SDL_GPU
@ -94,9 +93,11 @@ void fill_rect_alpha(SDL_Rect &rect, Uint32 color, Uint8 alpha, surface target)
return;
}
SDL_SetSurfaceBlendMode (tmp, SDL_BLENDMODE_BLEND);
SDL_Rect r = {0,0,rect.w,rect.h};
sdl::fill_rect(tmp,&r,color);
SDL_SetAlpha(tmp,SDL_SRCALPHA,alpha);
adjust_surface_alpha(tmp, alpha);
sdl_blit(tmp,nullptr,target,&rect);
}

View file

@ -21,7 +21,6 @@
#include "color_range.hpp"
#include "sdl/utils.hpp"
#include "sdl/alpha.hpp"
#include "sdl/rect.hpp"
#include "neon.hpp"
@ -141,9 +140,9 @@ surface make_neutral_surface(const surface &surf)
return nullptr;
}
surface const result = SDL_ConvertSurface(surf,&get_neutral_pixel_format(),SDL_SWSURFACE);
surface result = SDL_ConvertSurface(surf,&get_neutral_pixel_format(),SDL_SWSURFACE);
if(result != nullptr) {
SDL_SetAlpha(result,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(result, SDL_ALPHA_OPAQUE);
}
return result;
@ -172,9 +171,11 @@ surface create_optimized_surface(const surface &surf)
if(surf == nullptr)
return nullptr;
SDL_SetAlpha(surf,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
surface temp = surf;
return surf;
adjust_surface_alpha(temp, SDL_ALPHA_OPAQUE);
return temp;
}
surface stretch_surface_horizontal(
@ -1201,43 +1202,13 @@ surface brighten_image(const surface &surf, fixed_t amount, bool optimize)
return optimize ? create_optimized_surface(nsurf) : nsurf;
}
surface adjust_surface_alpha(const surface &surf, fixed_t amount, bool optimize)
void adjust_surface_alpha(surface& surf, fixed_t amount)
{
if(surf== nullptr) {
return nullptr;
if(surf == nullptr) {
return;
}
surface nsurf(make_neutral_surface(surf));
if(nsurf == nullptr) {
std::cerr << "could not make neutral surface...\n";
return nullptr;
}
{
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + nsurf->w*surf->h;
if (amount < 0) amount = 0;
while(beg != end) {
Uint8 alpha = (*beg) >> 24;
if(alpha) {
Uint8 r, g, b;
r = (*beg) >> 16;
g = (*beg) >> 8;
b = (*beg);
alpha = std::min<unsigned>(unsigned(fxpmult(alpha,amount)),255);
*beg = (alpha << 24) + (r << 16) + (g << 8) + b;
}
++beg;
}
}
return optimize ? create_optimized_surface(nsurf) : nsurf;
SDL_SetSurfaceAlphaMod(surf, Uint8(amount));
}
class pixel_callable : public game_logic::formula_callable {
@ -1296,7 +1267,8 @@ surface adjust_surface_alpha_formula(const surface &surf, const std::string& for
return nullptr;
}
SDL_SetAlpha(nsurf.get(),SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
adjust_surface_alpha(nsurf, SDL_ALPHA_OPAQUE);
{
surface_lock lock(nsurf);
Uint32* cur = lock.pixels();

View file

@ -277,7 +277,7 @@ surface brighten_image(const surface &surf, fixed_t amount, bool optimize=true);
*/
surface get_surface_portion(const surface &surf, SDL_Rect &rect);
surface adjust_surface_alpha(const surface &surf, fixed_t amount, bool optimize=true);
void adjust_surface_alpha(surface& surf, fixed_t amount);
surface adjust_surface_alpha_add(const surface &surf, int amount, bool optimize=true);
surface adjust_surface_alpha_formula(const surface &surf, const std::string& formula, bool optimize=true);

View file

@ -19,7 +19,6 @@
#include "widgets/textbox.hpp"
#include "desktop/clipboard.hpp"
#include "log.hpp"
#include "sdl/alpha.hpp"
#include "sdl/rect.hpp"
#include "serialization/string_utils.hpp"
#include "video.hpp"
@ -99,11 +98,11 @@ void textbox::append_text(const std::string& text, bool auto_scroll, const SDL_C
const bool is_at_bottom = get_position() == get_max_position();
const ucs4::string& wtext = unicode_cast<ucs4::string>(text);
const surface new_text = add_text_line(wtext, color);
surface new_text = add_text_line(wtext, color);
surface new_surface = create_compatible_surface(text_image_,std::max<size_t>(text_image_->w,new_text->w),text_image_->h+new_text->h);
SDL_SetAlpha(new_text.get(),0,0);
SDL_SetAlpha(text_image_.get(),0,0);
adjust_surface_alpha(new_text, SDL_ALPHA_TRANSPARENT);
adjust_surface_alpha(text_image_, SDL_ALPHA_TRANSPARENT);
SDL_SetSurfaceBlendMode(text_image_, SDL_BLENDMODE_NONE);
sdl_blit(text_image_,nullptr,new_surface,nullptr);
SDL_SetSurfaceBlendMode(text_image_, SDL_BLENDMODE_BLEND);
@ -240,7 +239,8 @@ void textbox::draw_contents()
// while not changing any applicable non-grayscale AA. Actual colored text will
// not look as good, but this is not currently a concern since GUI1 textboxes
// are not used much nowadays, and they will eventually all go away.
sdl_blit(adjust_surface_alpha(text_image_, ftofxp(0.3)), &src, surf, &dest);
adjust_surface_alpha(text_image_, ftofxp(0.3));
sdl_blit(text_image_, &src, surf, &dest);
}
}