apply patch 2633 by automagic : refactoring of the imagepath code
This commit is contained in:
parent
a1c5abdfca
commit
c68a158f37
10 changed files with 1410 additions and 813 deletions
|
@ -1028,6 +1028,9 @@
|
|||
name = "Karl Miller (karlm)"
|
||||
email = "karl_DOT_miller_DOT_km_AT_gmail_DOT_com"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Karol Kozub (automagic)"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Laurent Birtz"
|
||||
[/entry]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
|
@ -448,7 +448,7 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\image_function.cpp"
|
||||
RelativePath="..\..\src\image_modifications.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -7131,7 +7131,7 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\image_function.hpp"
|
||||
RelativePath="..\..\src\image_modifications.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
|
|
@ -585,7 +585,7 @@ set(libwesnoth-game_STAT_SRC
|
|||
font.cpp
|
||||
hotkeys.cpp
|
||||
image.cpp
|
||||
image_function.cpp
|
||||
image_modifications.cpp
|
||||
key.cpp
|
||||
language.cpp
|
||||
loadscreen.cpp
|
||||
|
|
|
@ -83,7 +83,7 @@ libwesnoth_sources = Split("""
|
|||
generic_event.cpp
|
||||
hotkeys.cpp
|
||||
image.cpp
|
||||
image_function.cpp
|
||||
image_modifications.cpp
|
||||
key.cpp
|
||||
language.cpp
|
||||
loadscreen.cpp
|
||||
|
|
379
src/image.cpp
379
src/image.cpp
|
@ -28,7 +28,7 @@
|
|||
#include "foreach.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "image_function.hpp"
|
||||
#include "image_modifications.hpp"
|
||||
#include "log.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
@ -488,375 +488,13 @@ surface locator::load_image_sub_file() const
|
|||
surf = mask_surface(cut, get_hexmask());
|
||||
}
|
||||
|
||||
if(val_.modifications_.size()){
|
||||
// The RC functor is very special; it must be applied
|
||||
// before anything else, and it is not accumulative.
|
||||
rc_function rc;
|
||||
// The FL functor is delayed until the end of the sequence.
|
||||
// This allows us to ignore things like ~FL(horiz)~FL(horiz)
|
||||
fl_function fl;
|
||||
// Regular functors
|
||||
std::vector< image::function_base* > functor_queue;
|
||||
modification_queue mods = modification::decode(val_.modifications_);
|
||||
|
||||
const std::vector<std::string> modlist = utils::parenthetical_split(val_.modifications_,'~');
|
||||
for(; !mods.empty(); mods.pop()) {
|
||||
modification* mod = mods.top();
|
||||
|
||||
foreach(const std::string& s, modlist) {
|
||||
const std::vector<std::string> tmpmod = utils::parenthetical_split(s);
|
||||
std::vector<std::string>::const_iterator j = tmpmod.begin();
|
||||
while(j!= tmpmod.end()){
|
||||
const std::string function = *j++;
|
||||
if(j == tmpmod.end()){
|
||||
if(function.size()){
|
||||
ERR_DP << "error parsing image modifications: "
|
||||
<< val_.modifications_<< "\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
const std::string field = *j++;
|
||||
typedef std::pair<Uint32,Uint32> rc_entry_type;
|
||||
|
||||
// Team color (TC), a subset of RC's functionality
|
||||
if("TC" == function) {
|
||||
std::vector<std::string> param = utils::split(field,',');
|
||||
if(param.size() < 2) {
|
||||
ERR_DP << "too few arguments passed to the ~TC() function\n";
|
||||
break;
|
||||
}
|
||||
|
||||
int side_n = lexical_cast_default<int>(param[0], -1);
|
||||
std::string team_color;
|
||||
if (side_n < 1) {
|
||||
ERR_DP << "invalid team (" << side_n << ") passed to the ~TC() function\n";
|
||||
break;
|
||||
}
|
||||
else if (side_n < static_cast<int>(team_colors.size())) {
|
||||
team_color = team_colors[side_n - 1];
|
||||
}
|
||||
else {
|
||||
// This side is not initialized; use default "n"
|
||||
try {
|
||||
team_color = lexical_cast<std::string>(side_n);
|
||||
} catch(bad_lexical_cast const&) {
|
||||
ERR_DP << "bad things happen\n";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Pass parameters for RC functor
|
||||
//
|
||||
if(game_config::tc_info(param[1]).size()){
|
||||
std::map<Uint32, Uint32> tmp_map;
|
||||
try {
|
||||
color_range const& new_color =
|
||||
game_config::color_info(team_color);
|
||||
std::vector<Uint32> const& old_color =
|
||||
game_config::tc_info(param[1]);
|
||||
|
||||
tmp_map = recolor_range(new_color,old_color);
|
||||
}
|
||||
catch(config::error const& e) {
|
||||
ERR_DP
|
||||
<< "caught config::error while processing TC: "
|
||||
<< e.message
|
||||
<< '\n';
|
||||
ERR_DP
|
||||
<< "bailing out from TC\n";
|
||||
tmp_map.clear();
|
||||
}
|
||||
|
||||
foreach(const rc_entry_type& rc_entry, tmp_map) {
|
||||
rc.map()[rc_entry.first] = rc_entry.second;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERR_DP
|
||||
<< "could not load TC info for '" << param[1] << "' palette\n";
|
||||
ERR_DP
|
||||
<< "bailing out from TC\n";
|
||||
}
|
||||
|
||||
}
|
||||
// Palette recolor (RC)
|
||||
else if("RC" == function) {
|
||||
const std::vector<std::string> recolor_params = utils::split(field,'>');
|
||||
if(recolor_params.size()>1){
|
||||
//
|
||||
// recolor source palette to color range
|
||||
//
|
||||
std::map<Uint32, Uint32> tmp_map;
|
||||
try {
|
||||
color_range const& new_color =
|
||||
game_config::color_info(recolor_params[1]);
|
||||
std::vector<Uint32> const& old_color =
|
||||
game_config::tc_info(recolor_params[0]);
|
||||
|
||||
tmp_map = recolor_range(new_color,old_color);
|
||||
}
|
||||
catch (config::error& e) {
|
||||
ERR_DP
|
||||
<< "caught config::error while processing color-range RC: "
|
||||
<< e.message
|
||||
<< '\n';
|
||||
ERR_DP
|
||||
<< "bailing out from RC\n";
|
||||
tmp_map.clear();
|
||||
}
|
||||
|
||||
foreach(const rc_entry_type& rc_entry, tmp_map) {
|
||||
rc.map()[rc_entry.first] = rc_entry.second;
|
||||
}
|
||||
}
|
||||
else {
|
||||
///@Deprecated 1.6 palette switch syntax
|
||||
if(field.find('=') != std::string::npos) {
|
||||
lg::wml_error << "the ~RC() image function cannot be used for palette switch (A=B) in 1.7.x; use ~PAL(A>B) instead\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Palette switch (PAL)
|
||||
else if("PAL" == function) {
|
||||
const std::vector<std::string> remap_params = utils::split(field,'>');
|
||||
if(remap_params.size() > 1) {
|
||||
std::map<Uint32, Uint32> tmp_map;
|
||||
try {
|
||||
std::vector<Uint32> const& old_palette =
|
||||
game_config::tc_info(remap_params[0]);
|
||||
std::vector<Uint32> const& new_palette =
|
||||
game_config::tc_info(remap_params[1]);
|
||||
|
||||
for(size_t i = 0; i < old_palette.size() && i < new_palette.size(); ++i) {
|
||||
tmp_map[old_palette[i]] = new_palette[i];
|
||||
}
|
||||
}
|
||||
catch(config::error& e) {
|
||||
ERR_DP
|
||||
<< "caught config::error while processing PAL function: "
|
||||
<< e.message
|
||||
<< '\n';
|
||||
ERR_DP
|
||||
<< "bailing out from PAL\n";
|
||||
tmp_map.clear();
|
||||
}
|
||||
|
||||
foreach(const rc_entry_type& rc_entry, tmp_map) {
|
||||
rc.map()[rc_entry.first] = rc_entry.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flip-flop (FL)
|
||||
else if("FL" == function) {
|
||||
if(field.empty() || field.find("horiz") != std::string::npos) {
|
||||
fl.toggle_horiz();
|
||||
}
|
||||
if(field.find("vert") != std::string::npos) {
|
||||
fl.toggle_vert();
|
||||
}
|
||||
}
|
||||
// Grayscale (GS)
|
||||
else if("GS" == function) {
|
||||
functor_queue.push_back(new gs_function());
|
||||
}
|
||||
// Color-shift (CS)
|
||||
else if("CS" == function) {
|
||||
std::vector<std::string> const factors = utils::split(field, ',');
|
||||
const size_t s = factors.size();
|
||||
if(s) {
|
||||
int r = 0, g = 0, b = 0;
|
||||
|
||||
r = lexical_cast_default<int>(factors[0]);
|
||||
if( s > 1 ) {
|
||||
g = lexical_cast_default<int>(factors[1]);
|
||||
}
|
||||
if( s > 2 ) {
|
||||
b = lexical_cast_default<int>(factors[2]);
|
||||
}
|
||||
|
||||
functor_queue.push_back(new cs_function(r,g,b));
|
||||
}
|
||||
else {
|
||||
LOG_DP << "no arguments passed to the ~CS() function\n";
|
||||
}
|
||||
}
|
||||
// Crop/slice (CROP)
|
||||
else if("CROP" == function) {
|
||||
std::vector<std::string> const& slice_params = utils::split(field, ',', utils::STRIP_SPACES);
|
||||
const size_t s = slice_params.size();
|
||||
if(s) {
|
||||
SDL_Rect slice_rect = { 0, 0, 0, 0 };
|
||||
|
||||
slice_rect.x = lexical_cast_default<Sint16, const std::string&>(slice_params[0]);
|
||||
if(s > 1) {
|
||||
slice_rect.y = lexical_cast_default<Sint16, const std::string&>(slice_params[1]);
|
||||
}
|
||||
if(s > 2) {
|
||||
slice_rect.w = lexical_cast_default<Uint16, const std::string&>(slice_params[2]);
|
||||
}
|
||||
if(s > 3) {
|
||||
slice_rect.h = lexical_cast_default<Uint16, const std::string&>(slice_params[3]);
|
||||
}
|
||||
|
||||
functor_queue.push_back(new crop_function(slice_rect));
|
||||
}
|
||||
else {
|
||||
ERR_DP << "no arguments passed to the ~CROP() function\n";
|
||||
}
|
||||
}
|
||||
// LOC function
|
||||
else if("LOC" == function) {
|
||||
//FIXME: WIP, don't use it yet
|
||||
std::vector<std::string> const& params = utils::split(field);
|
||||
int x = lexical_cast<int>(params[0]);
|
||||
int y = lexical_cast<int>(params[1]);
|
||||
int cx = lexical_cast<int>(params[2]);
|
||||
int cy = lexical_cast<int>(params[3]);
|
||||
image::locator new_loc(val_.filename_, map_location(x,y), cx, cy, "");//TODO remove only ~LOC
|
||||
surf = get_image(new_loc, TOD_COLORED);
|
||||
}
|
||||
// BLIT function
|
||||
else if("BLIT" == function) {
|
||||
std::vector<std::string> param = utils::parenthetical_split(field, ',');
|
||||
const size_t s = param.size();
|
||||
if(s > 0){
|
||||
int x = 0, y = 0;
|
||||
if(s == 3) {
|
||||
x = lexical_cast_default<int>(param[1]);
|
||||
y = lexical_cast_default<int>(param[2]);
|
||||
}
|
||||
if(x >= 0 && y >= 0) { //required by blit_surface
|
||||
surface surf = get_image(param[0]);
|
||||
functor_queue.push_back(new blit_function(surf, x, y));
|
||||
} else {
|
||||
ERR_DP << "negative position arguments in ~BLIT() function\n";
|
||||
}
|
||||
} else {
|
||||
ERR_DP << "no arguments passed to the ~BLIT() function\n";
|
||||
}
|
||||
}
|
||||
else if("MASK" == function) {
|
||||
std::vector<std::string> param = utils::parenthetical_split(field, ',');
|
||||
const size_t s = param.size();
|
||||
if(s > 0){
|
||||
int x = 0, y = 0;
|
||||
if(s == 3) {
|
||||
x = lexical_cast_default<int>(param[1]);
|
||||
y = lexical_cast_default<int>(param[2]);
|
||||
}
|
||||
if(x >= 0 && y >= 0) { //required by blit_surface
|
||||
surface surf = get_image(param[0]);
|
||||
functor_queue.push_back(new mask_function(surf, x, y));
|
||||
} else {
|
||||
ERR_DP << "negative position arguments in ~MASK() function\n";
|
||||
}
|
||||
} else {
|
||||
ERR_DP << "no arguments passed to the ~MASK() function\n";
|
||||
}
|
||||
}
|
||||
else if("L" == function) {
|
||||
if(!field.empty()){
|
||||
surface surf = get_image(field);
|
||||
functor_queue.push_back(new light_function(surf));
|
||||
} else {
|
||||
ERR_DP << "no arguments passed to the ~L() function\n";
|
||||
}
|
||||
}
|
||||
// Scale (SCALE)
|
||||
else if("SCALE" == function) {
|
||||
std::vector<std::string> const& scale_params = utils::split(field, ',', utils::STRIP_SPACES);
|
||||
const size_t s = scale_params.size();
|
||||
if(s) {
|
||||
int w = 0, h = 0;
|
||||
|
||||
w = lexical_cast_default<int, const std::string&>(scale_params[0]);
|
||||
if(s > 1) {
|
||||
h = lexical_cast_default<int, const std::string&>(scale_params[1]);
|
||||
}
|
||||
|
||||
functor_queue.push_back(new scale_function(w, h));
|
||||
}
|
||||
else {
|
||||
ERR_DP << "no arguments passed to the ~SCALE() function\n";
|
||||
}
|
||||
}
|
||||
// Gaussian-like blur (BL)
|
||||
else if("BL" == function) {
|
||||
const int depth = std::max<int>(0, lexical_cast_default<int>(field));
|
||||
functor_queue.push_back(new bl_function(depth));
|
||||
}
|
||||
// Opacity-shift (O)
|
||||
else if("O" == function) {
|
||||
const std::string::size_type p100_pos = field.find('%');
|
||||
float num = 0.0f;
|
||||
if(p100_pos == std::string::npos)
|
||||
num = lexical_cast_default<float,const std::string&>(field);
|
||||
else {
|
||||
// make multiplier
|
||||
const std::string parsed_field = field.substr(0, p100_pos);
|
||||
num = lexical_cast_default<float,const std::string&>(parsed_field);
|
||||
num /= 100.0f;
|
||||
}
|
||||
functor_queue.push_back(new o_function(num));
|
||||
}
|
||||
//
|
||||
// ~R(), ~G() and ~B() are the children of ~CS(). Merely syntatic sugar.
|
||||
// Hence they are at the end of the evaluation.
|
||||
//
|
||||
// Red component color-shift (R)
|
||||
else if("R" == function) {
|
||||
const int r = lexical_cast_default<int>(field);
|
||||
functor_queue.push_back(new cs_function(r,0,0));
|
||||
}
|
||||
// Green component color-shift (G)
|
||||
else if("G" == function) {
|
||||
const int g = lexical_cast_default<int>(field);
|
||||
functor_queue.push_back(new cs_function(0,g,0));
|
||||
}
|
||||
// Blue component color-shift (B)
|
||||
else if("B" == function) {
|
||||
const int b = lexical_cast_default<int>(field);
|
||||
functor_queue.push_back(new cs_function(0,0,b));
|
||||
}
|
||||
else if("NOP" == function) {
|
||||
}
|
||||
// Fake image function used by GUI2 portraits until
|
||||
// Mordante gets rid of it. *tsk* *tsk*
|
||||
else if("RIGHT" == function) {
|
||||
}
|
||||
// Add a bright overlay.
|
||||
else if (function == "BRIGHTEN") {
|
||||
functor_queue.push_back(new brighten_function());
|
||||
}
|
||||
// Add a dark overlay.
|
||||
else if (function == "DARKEN") {
|
||||
functor_queue.push_back(new darken_function());
|
||||
}
|
||||
// Add a background color.
|
||||
else if (function == "BG")
|
||||
{
|
||||
int c[4] = { 0, 0, 0, 255 };
|
||||
std::vector<std::string> factors = utils::split(field, ',');
|
||||
for (int i = 0; i < std::min<int>(factors.size(), 4); ++i) {
|
||||
c[i] = lexical_cast_default<int>(factors[i]);
|
||||
}
|
||||
functor_queue.push_back(new background_function(create_color(c[0], c[1], c[2], c[3])));
|
||||
}
|
||||
else {
|
||||
ERR_DP << "unknown image function in path: " << function << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!rc.no_op()) {
|
||||
surf = rc(surf);
|
||||
}
|
||||
|
||||
if(!fl.no_op()) {
|
||||
surf = fl(surf);
|
||||
}
|
||||
|
||||
foreach(function_base* f, functor_queue) {
|
||||
surf = (*f)(surf);
|
||||
delete f;
|
||||
}
|
||||
surf = (*mod)(surf);
|
||||
delete mod;
|
||||
}
|
||||
|
||||
return surf;
|
||||
|
@ -943,6 +581,11 @@ void set_team_colors(const std::vector<std::string>* colors)
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string>& get_team_colors()
|
||||
{
|
||||
return team_colors;
|
||||
}
|
||||
|
||||
void set_zoom(int amount)
|
||||
{
|
||||
if(amount != zoom) {
|
||||
|
|
|
@ -168,6 +168,8 @@ namespace image {
|
|||
///using NULL will reset to default TC
|
||||
void set_team_colors(const std::vector<std::string>* colors = NULL);
|
||||
|
||||
const std::vector<std::string>& get_team_colors();
|
||||
|
||||
///sets the pixel format used by the images. Is called every time the
|
||||
///video mode changes. Invalidates all images.
|
||||
void set_pixel_format(SDL_PixelFormat* format);
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2011 by Ignacio R. Morelle <shadowm2006@gmail.com>
|
||||
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 "image_function.hpp"
|
||||
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define ERR_DP LOG_STREAM(err, log_display)
|
||||
|
||||
namespace image {
|
||||
|
||||
surface rc_function::operator()(const surface& src) const
|
||||
{
|
||||
// unchecked
|
||||
return recolor_image(src, rc_map_);
|
||||
}
|
||||
|
||||
surface fl_function::operator()(const surface& src) const
|
||||
{
|
||||
surface ret = src;
|
||||
|
||||
if(horiz_) {
|
||||
ret = flip_surface(ret);
|
||||
}
|
||||
|
||||
if(vert_) {
|
||||
ret = flop_surface(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface gs_function::operator()(const surface& src) const
|
||||
{
|
||||
return greyscale_image(src);
|
||||
}
|
||||
|
||||
surface crop_function::operator()(const surface& src) const
|
||||
{
|
||||
SDL_Rect area = slice_;
|
||||
if(area.w == 0) {
|
||||
area.w = src->w;
|
||||
}
|
||||
if(area.h == 0) {
|
||||
area.h = src->h;
|
||||
}
|
||||
if(area.x < 0) {
|
||||
ERR_DP << "start X coordinate of SECTION function is negative - truncating to zero\n";
|
||||
area.x = 0;
|
||||
}
|
||||
if(area.y < 0) {
|
||||
ERR_DP << "start Y coordinate of SECTION function is negative - truncating to zero\n";
|
||||
area.y = 0;
|
||||
}
|
||||
return cut_surface(src, area);
|
||||
}
|
||||
|
||||
surface blit_function::operator()(const surface& src) const
|
||||
{
|
||||
//blit_surface want neutral surfaces
|
||||
surface nsrc = make_neutral_surface(src);
|
||||
surface nsurf = make_neutral_surface(surf_);
|
||||
SDL_Rect r = create_rect(x_, y_, 0, 0);
|
||||
blit_surface(nsurf, NULL, nsrc, &r);
|
||||
return nsrc;
|
||||
}
|
||||
|
||||
surface mask_function::operator()(const surface& src) const
|
||||
{
|
||||
if(src->w == mask_->w && src->h == mask_->h && x_ == 0 && y_ == 0)
|
||||
return mask_surface(src, mask_);
|
||||
SDL_Rect r = create_rect(x_, y_, 0, 0);
|
||||
surface new_mask = create_neutral_surface(src->w, src->h);
|
||||
blit_surface(mask_, NULL, new_mask, &r);
|
||||
return mask_surface(src, new_mask);
|
||||
}
|
||||
|
||||
surface light_function::operator()(const surface& src) const
|
||||
{
|
||||
return light_surface(src, surf_);;
|
||||
}
|
||||
|
||||
surface scale_function::operator()(const surface& src) const
|
||||
{
|
||||
const int old_w = src->w;
|
||||
const int old_h = src->h;
|
||||
int w = w_;
|
||||
int h = h_;
|
||||
|
||||
if(w <= 0) {
|
||||
if(w < 0) {
|
||||
ERR_DP << "width of SCALE is negative - resetting to original width\n";
|
||||
}
|
||||
w = old_w;
|
||||
}
|
||||
if(h <= 0) {
|
||||
if(h < 0) {
|
||||
ERR_DP << "height of SCALE is negative - resetting to original height\n";
|
||||
}
|
||||
h = old_h;
|
||||
}
|
||||
|
||||
return scale_surface(src, w, h);
|
||||
}
|
||||
|
||||
surface o_function::operator()(const surface& src) const
|
||||
{
|
||||
return adjust_surface_alpha(src, ftofxp(opacity_));
|
||||
}
|
||||
|
||||
surface cs_function::operator()(const surface& src) const
|
||||
{
|
||||
return(
|
||||
(r_ != 0 || g_ != 0 || b_ != 0) ?
|
||||
adjust_surface_color(src, r_, g_, b_) :
|
||||
src
|
||||
);
|
||||
}
|
||||
|
||||
surface bl_function::operator()(const surface& src) const
|
||||
{
|
||||
return blur_alpha_surface(src, depth_);
|
||||
}
|
||||
|
||||
surface brighten_function::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
surface tod_bright(image::get_image(game_config::images:: tod_bright));
|
||||
if (tod_bright)
|
||||
blit_surface(tod_bright, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface darken_function::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
surface tod_dark(image::get_image(game_config::images::tod_dark));
|
||||
if (tod_dark)
|
||||
blit_surface(tod_dark, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface background_function::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
SDL_FillRect(ret, NULL, SDL_MapRGBA(ret->format, color_.r, color_.g, color_.b, color_.unused));
|
||||
SDL_SetAlpha(src, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
|
||||
SDL_BlitSurface(src, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} /* end namespace image */
|
|
@ -1,271 +0,0 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2011 by Ignacio R. Morelle <shadowm2006@gmail.com>
|
||||
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.
|
||||
*/
|
||||
|
||||
/** @file */
|
||||
|
||||
#ifndef IMAGE_FUNCTION_HPP_INCLUDED
|
||||
#define IMAGE_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#include "sdl_utils.hpp"
|
||||
|
||||
namespace image {
|
||||
/**
|
||||
* Base abstract class for an image-path function.
|
||||
* It actually just enforces the operator()() protocol.
|
||||
*/
|
||||
class function_base
|
||||
{
|
||||
public:
|
||||
virtual ~function_base() {}
|
||||
/**
|
||||
* Applies the image-path function on the specified surface.
|
||||
*/
|
||||
virtual surface operator()(const surface& src) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recolor (RC/TC/PAL) function.
|
||||
* It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
|
||||
* but also for team-color-based color range selection and recoloring
|
||||
* ("~TC(3,magenta)") and palette switches ("~PAL(000000,005000 > FFFFFF,FF00FF)").
|
||||
*/
|
||||
class rc_function : public function_base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
rc_function()
|
||||
: rc_map_()
|
||||
{}
|
||||
/**
|
||||
* RC-map based constructor.
|
||||
* @param recolor_map The palette switch map.
|
||||
*/
|
||||
rc_function(const std::map<Uint32, Uint32>& recolor_map)
|
||||
: rc_map_(recolor_map)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
bool no_op() const { return rc_map_.empty(); }
|
||||
|
||||
const std::map<Uint32, Uint32>& map() const { return rc_map_;}
|
||||
std::map<Uint32, Uint32>& map() { return rc_map_;}
|
||||
|
||||
private:
|
||||
std::map<Uint32, Uint32> rc_map_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mirror (FL) function.
|
||||
*/
|
||||
class fl_function : public function_base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param horiz Horizontal mirror flag.
|
||||
* @param vert Vertical mirror flag.
|
||||
*/
|
||||
fl_function(bool horiz = false, bool vert = false)
|
||||
: horiz_(horiz)
|
||||
, vert_(vert)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
void set_horiz(bool val) { horiz_ = val; }
|
||||
void set_vert(bool val) { vert_ = val; }
|
||||
bool get_horiz() const { return horiz_; }
|
||||
bool get_vert() const { return vert_; }
|
||||
/** Toggle horizontal mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_horiz() { return((horiz_ = !horiz_)); }
|
||||
/** Toggle vertical mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_vert() { return((vert_ = !vert_)); }
|
||||
|
||||
bool no_op() const { return ((!horiz_) && (!vert_)); }
|
||||
|
||||
private:
|
||||
bool horiz_;
|
||||
bool vert_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Grayscale (GS) function.
|
||||
*/
|
||||
class gs_function : public function_base
|
||||
{
|
||||
public:
|
||||
gs_function() {}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Crop (CROP) function.
|
||||
*/
|
||||
class crop_function : public function_base
|
||||
{
|
||||
public:
|
||||
crop_function(const SDL_Rect& slice)
|
||||
: slice_(slice)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
SDL_Rect slice_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (BLIT) function.
|
||||
*/
|
||||
|
||||
class blit_function : public function_base
|
||||
{
|
||||
public:
|
||||
blit_function(const surface& surf, int x, int y)
|
||||
: surf_(surf), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mask (MASK) function.
|
||||
*/
|
||||
|
||||
class mask_function : public function_base
|
||||
{
|
||||
public:
|
||||
mask_function(const surface& mask, int x, int y)
|
||||
: mask_(mask), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
surface mask_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* LIGHT (L) function.
|
||||
*/
|
||||
|
||||
class light_function : public function_base
|
||||
{
|
||||
public:
|
||||
light_function(const surface& surf)
|
||||
: surf_(surf)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (SCALE) function.
|
||||
*/
|
||||
class scale_function : public function_base
|
||||
{
|
||||
public:
|
||||
scale_function(int width, int height)
|
||||
: w_(width), h_(height)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
int w_, h_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opacity (O) function
|
||||
*/
|
||||
class o_function : public function_base
|
||||
{
|
||||
public:
|
||||
o_function(float opacity)
|
||||
: opacity_(opacity)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
float opacity_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Color-shift (CS, R, G, B) function.
|
||||
*/
|
||||
class cs_function : public function_base
|
||||
{
|
||||
public:
|
||||
cs_function(int r, int g, int b)
|
||||
: r_(r), g_(g), b_(b)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
int r_, g_, b_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gaussian-like blur (BL) function.
|
||||
*/
|
||||
class bl_function : public function_base
|
||||
{
|
||||
public:
|
||||
bl_function(int depth)
|
||||
: depth_(depth)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
private:
|
||||
int depth_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD brightening (BRIGHTEN).
|
||||
*/
|
||||
struct brighten_function : function_base
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD darkening (DARKEN).
|
||||
*/
|
||||
struct darken_function : function_base
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill background with a color (BG).
|
||||
*/
|
||||
struct background_function : function_base
|
||||
{
|
||||
background_function(SDL_Color const &c): color_(c) {}
|
||||
virtual surface operator()(const surface &src) const;
|
||||
SDL_Color color_;
|
||||
};
|
||||
|
||||
} /* end namespace image */
|
||||
|
||||
#endif /* !defined(IMAGE_FUNCTION_HPP_INCLUDED) */
|
763
src/image_modifications.cpp
Normal file
763
src/image_modifications.cpp
Normal file
|
@ -0,0 +1,763 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2011 by Ignacio R. Morelle <shadowm2006@gmail.com>
|
||||
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 "color_range.hpp"
|
||||
#include "config.hpp"
|
||||
#include "foreach.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "image_modifications.hpp"
|
||||
#include "log.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define ERR_DP LOG_STREAM(err, log_display)
|
||||
#define LOG_DP LOG_STREAM(info, log_display)
|
||||
|
||||
namespace image {
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/// A function used to parse modification arguments
|
||||
typedef modification* (*mod_parser)(const std::string&);
|
||||
|
||||
/** A map of all registered mod parsers
|
||||
*
|
||||
* The mapping is between the modification name and the parser function pointer
|
||||
* An example of an entry would be "TC" -> &parse_TC_mod
|
||||
*/
|
||||
std::map<std::string, mod_parser> mod_parsers;
|
||||
|
||||
/** Decodes a single modification using an appropriate mod_parser
|
||||
*
|
||||
* @param encoded_mod A string representing a single modification
|
||||
*
|
||||
* @return A pointer to the decoded modification object
|
||||
* @retval NULL if the string is invalid or a parser isn't found
|
||||
*/
|
||||
modification* decode_modification(const std::string& encoded_mod)
|
||||
{
|
||||
std::vector<std::string> split = utils::parenthetical_split(encoded_mod);
|
||||
|
||||
if(split.size() != 2) {
|
||||
ERR_DP << "error parsing image modifications: "
|
||||
<< encoded_mod << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::string mod_type = split[0];
|
||||
std::string args = split[1];
|
||||
|
||||
if(mod_parsers.find(mod_type) == mod_parsers.end()) {
|
||||
ERR_DP << "unknown image function in path: "
|
||||
<< mod_type << '\n';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (*mod_parsers[mod_type])(args);
|
||||
}
|
||||
} // end anon namespace
|
||||
|
||||
/** Decodes the modification string
|
||||
*
|
||||
* Important:
|
||||
* It creates new objects which need to be deleted after use
|
||||
*
|
||||
* @param encoded_mods A string representing any number of modifications
|
||||
*
|
||||
* @return A modification_queue filled with decoded modification pointers
|
||||
*/
|
||||
modification_queue modification::decode(const std::string& encoded_mods)
|
||||
{
|
||||
modification_queue mods;
|
||||
|
||||
foreach(const std::string& encoded_mod,
|
||||
utils::parenthetical_split(encoded_mods, '~')) {
|
||||
modification* mod = decode_modification(encoded_mod);
|
||||
|
||||
if(mod) {
|
||||
mods.push(mod);
|
||||
}
|
||||
}
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
/// Compares two modification pointers, providing descending priority order
|
||||
bool mod_ptr_comparator_::operator()(const modification* a,
|
||||
const modification* b) const
|
||||
{
|
||||
return a->priority() < b->priority();
|
||||
}
|
||||
|
||||
surface rc_modification::operator()(const surface& src) const
|
||||
{
|
||||
// unchecked
|
||||
return recolor_image(src, rc_map_);
|
||||
}
|
||||
|
||||
surface fl_modification::operator()(const surface& src) const
|
||||
{
|
||||
surface ret = src;
|
||||
|
||||
if(horiz_) {
|
||||
ret = flip_surface(ret);
|
||||
}
|
||||
|
||||
if(vert_) {
|
||||
ret = flop_surface(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface gs_modification::operator()(const surface& src) const
|
||||
{
|
||||
return greyscale_image(src);
|
||||
}
|
||||
|
||||
surface crop_modification::operator()(const surface& src) const
|
||||
{
|
||||
SDL_Rect area = slice_;
|
||||
if(area.w == 0) {
|
||||
area.w = src->w;
|
||||
}
|
||||
if(area.h == 0) {
|
||||
area.h = src->h;
|
||||
}
|
||||
if(area.x < 0) {
|
||||
ERR_DP << "start X coordinate of SECTION modification is negative - truncating to zero\n";
|
||||
area.x = 0;
|
||||
}
|
||||
if(area.y < 0) {
|
||||
ERR_DP << "start Y coordinate of SECTION modification is negative - truncating to zero\n";
|
||||
area.y = 0;
|
||||
}
|
||||
return cut_surface(src, area);
|
||||
}
|
||||
|
||||
const SDL_Rect& crop_modification::get_slice() const
|
||||
{
|
||||
return slice_;
|
||||
}
|
||||
|
||||
surface blit_modification::operator()(const surface& src) const
|
||||
{
|
||||
//blit_surface want neutral surfaces
|
||||
surface nsrc = make_neutral_surface(src);
|
||||
surface nsurf = make_neutral_surface(surf_);
|
||||
SDL_Rect r = create_rect(x_, y_, 0, 0);
|
||||
blit_surface(nsurf, NULL, nsrc, &r);
|
||||
return nsrc;
|
||||
}
|
||||
|
||||
const surface& blit_modification::get_surface() const
|
||||
{
|
||||
return surf_;
|
||||
}
|
||||
|
||||
int blit_modification::get_x() const
|
||||
{
|
||||
return x_;
|
||||
}
|
||||
|
||||
int blit_modification::get_y() const
|
||||
{
|
||||
return y_;
|
||||
}
|
||||
|
||||
surface mask_modification::operator()(const surface& src) const
|
||||
{
|
||||
if(src->w == mask_->w && src->h == mask_->h && x_ == 0 && y_ == 0)
|
||||
return mask_surface(src, mask_);
|
||||
SDL_Rect r = create_rect(x_, y_, 0, 0);
|
||||
surface new_mask = create_neutral_surface(src->w, src->h);
|
||||
blit_surface(mask_, NULL, new_mask, &r);
|
||||
return mask_surface(src, new_mask);
|
||||
}
|
||||
|
||||
const surface& mask_modification::get_mask() const
|
||||
{
|
||||
return mask_;
|
||||
}
|
||||
|
||||
int mask_modification::get_x() const
|
||||
{
|
||||
return x_;
|
||||
}
|
||||
|
||||
int mask_modification::get_y() const
|
||||
{
|
||||
return y_;
|
||||
}
|
||||
|
||||
surface light_modification::operator()(const surface& src) const
|
||||
{
|
||||
return light_surface(src, surf_);;
|
||||
}
|
||||
|
||||
const surface& light_modification::get_surface() const
|
||||
{
|
||||
return surf_;
|
||||
}
|
||||
|
||||
surface scale_modification::operator()(const surface& src) const
|
||||
{
|
||||
const int old_w = src->w;
|
||||
const int old_h = src->h;
|
||||
int w = w_;
|
||||
int h = h_;
|
||||
|
||||
if(w <= 0) {
|
||||
if(w < 0) {
|
||||
ERR_DP << "width of SCALE is negative - resetting to original width\n";
|
||||
}
|
||||
w = old_w;
|
||||
}
|
||||
if(h <= 0) {
|
||||
if(h < 0) {
|
||||
ERR_DP << "height of SCALE is negative - resetting to original height\n";
|
||||
}
|
||||
h = old_h;
|
||||
}
|
||||
|
||||
return scale_surface(src, w, h);
|
||||
}
|
||||
|
||||
int scale_modification::get_w() const
|
||||
{
|
||||
return w_;
|
||||
}
|
||||
|
||||
int scale_modification::get_h() const
|
||||
{
|
||||
return h_;
|
||||
}
|
||||
|
||||
surface o_modification::operator()(const surface& src) const
|
||||
{
|
||||
return adjust_surface_alpha(src, ftofxp(opacity_));
|
||||
}
|
||||
|
||||
float o_modification::get_opacity() const
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
surface cs_modification::operator()(const surface& src) const
|
||||
{
|
||||
return(
|
||||
(r_ != 0 || g_ != 0 || b_ != 0) ?
|
||||
adjust_surface_color(src, r_, g_, b_) :
|
||||
src
|
||||
);
|
||||
}
|
||||
|
||||
int cs_modification::get_r() const
|
||||
{
|
||||
return r_;
|
||||
}
|
||||
|
||||
int cs_modification::get_g() const
|
||||
{
|
||||
return g_;
|
||||
}
|
||||
|
||||
int cs_modification::get_b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
surface bl_modification::operator()(const surface& src) const
|
||||
{
|
||||
return blur_alpha_surface(src, depth_);
|
||||
}
|
||||
|
||||
int bl_modification::get_depth() const
|
||||
{
|
||||
return depth_;
|
||||
}
|
||||
|
||||
surface brighten_modification::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
surface tod_bright(image::get_image(game_config::images:: tod_bright));
|
||||
if (tod_bright)
|
||||
blit_surface(tod_bright, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface darken_modification::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
surface tod_dark(image::get_image(game_config::images::tod_dark));
|
||||
if (tod_dark)
|
||||
blit_surface(tod_dark, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
surface background_modification::operator()(const surface &src) const
|
||||
{
|
||||
surface ret = make_neutral_surface(src);
|
||||
SDL_FillRect(ret, NULL, SDL_MapRGBA(ret->format, color_.r, color_.g,
|
||||
color_.b, color_.unused));
|
||||
SDL_SetAlpha(src, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
|
||||
SDL_BlitSurface(src, NULL, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const SDL_Color& background_modification::get_color() const
|
||||
{
|
||||
return color_;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/** A macro for automatic modification parser registration
|
||||
*
|
||||
* It automatically registers the created parser in the mod_parsers map
|
||||
* It should be used just like a function header (look at the uses below)
|
||||
* It should only be used within an anonymous namespace
|
||||
*
|
||||
* @param type The modification type to be registered (unquoted)
|
||||
* @args_var The name for the string argument provided
|
||||
*/
|
||||
#define REGISTER_MOD_PARSER(type, args_var) \
|
||||
modification* parse_##type##_mod(const std::string&); \
|
||||
struct parse_##type##_mod_registration \
|
||||
{ \
|
||||
parse_##type##_mod_registration() \
|
||||
{ \
|
||||
mod_parsers[#type] = &parse_##type##_mod; \
|
||||
} \
|
||||
} parse_##type##_mod_registration_aux; \
|
||||
modification* parse_##type##_mod(const std::string& args_var)
|
||||
|
||||
// Color-range-based recoloring
|
||||
REGISTER_MOD_PARSER(TC, args)
|
||||
{
|
||||
std::vector<std::string> params = utils::split(args,',');
|
||||
|
||||
if(params.size() < 2) {
|
||||
ERR_DP << "too few arguments passed to the ~TC() function\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int side_n = lexical_cast_default<int>(params[0], -1);
|
||||
std::string team_color;
|
||||
if (side_n < 1) {
|
||||
ERR_DP << "invalid team (" << side_n
|
||||
<< ") passed to the ~TC() function\n";
|
||||
return NULL;
|
||||
}
|
||||
else if (side_n < static_cast<int>(image::get_team_colors().size())) {
|
||||
team_color = image::get_team_colors()[side_n - 1];
|
||||
}
|
||||
else {
|
||||
// This side is not initialized; use default "n"
|
||||
try {
|
||||
team_color = lexical_cast<std::string>(side_n);
|
||||
} catch(bad_lexical_cast const&) {
|
||||
ERR_DP << "bad things happen\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Pass argseters for RC functor
|
||||
//
|
||||
if(!game_config::tc_info(params[1]).size()){
|
||||
ERR_DP << "could not load TC info for '" << params[1]
|
||||
<< "' palette\n"
|
||||
<< "bailing out from TC\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::map<Uint32, Uint32> rc_map;
|
||||
try {
|
||||
color_range const& new_color =
|
||||
game_config::color_info(team_color);
|
||||
std::vector<Uint32> const& old_color =
|
||||
game_config::tc_info(params[1]);
|
||||
|
||||
rc_map = recolor_range(new_color,old_color);
|
||||
}
|
||||
catch(config::error const& e) {
|
||||
ERR_DP << "caught config::error while processing TC: "
|
||||
<< e.message
|
||||
<< '\n'
|
||||
<< "bailing out from TC\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new rc_modification(rc_map);
|
||||
}
|
||||
|
||||
// Team-color-based color range selection and recoloring
|
||||
REGISTER_MOD_PARSER(RC, args)
|
||||
{
|
||||
const std::vector<std::string> recolor_params = utils::split(args,'>');
|
||||
|
||||
if(recolor_params.size()>1){
|
||||
//
|
||||
// recolor source palette to color range
|
||||
//
|
||||
std::map<Uint32, Uint32> rc_map;
|
||||
try {
|
||||
color_range const& new_color =
|
||||
game_config::color_info(recolor_params[1]);
|
||||
std::vector<Uint32> const& old_color =
|
||||
game_config::tc_info(recolor_params[0]);
|
||||
|
||||
rc_map = recolor_range(new_color,old_color);
|
||||
}
|
||||
catch (config::error& e) {
|
||||
ERR_DP
|
||||
<< "caught config::error while processing color-range RC: "
|
||||
<< e.message
|
||||
<< '\n';
|
||||
ERR_DP
|
||||
<< "bailing out from RC\n";
|
||||
rc_map.clear();
|
||||
}
|
||||
|
||||
return new rc_modification(rc_map);
|
||||
}
|
||||
else {
|
||||
///@Deprecated 1.6 palette switch syntax
|
||||
if(args.find('=') != std::string::npos) {
|
||||
lg::wml_error << "the ~RC() image function cannot be used for palette switch (A=B) in 1.7.x; use ~PAL(A>B) instead\n";
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Palette switch
|
||||
REGISTER_MOD_PARSER(PAL, args)
|
||||
{
|
||||
const std::vector<std::string> remap_params = utils::split(args,'>');
|
||||
|
||||
if(remap_params.size() < 2) {
|
||||
ERR_DP << "not enough arguments passed to the ~PAL() function: "
|
||||
<< args << "\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
std::map<Uint32, Uint32> rc_map;
|
||||
std::vector<Uint32> const& old_palette =
|
||||
game_config::tc_info(remap_params[0]);
|
||||
std::vector<Uint32> const& new_palette =
|
||||
game_config::tc_info(remap_params[1]);
|
||||
|
||||
for(size_t i = 0; i < old_palette.size() && i < new_palette.size(); ++i) {
|
||||
rc_map[old_palette[i]] = new_palette[i];
|
||||
}
|
||||
|
||||
return new rc_modification(rc_map);
|
||||
}
|
||||
catch(config::error& e) {
|
||||
ERR_DP
|
||||
<< "caught config::error while processing PAL function: "
|
||||
<< e.message
|
||||
<< '\n';
|
||||
ERR_DP
|
||||
<< "bailing out from PAL\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Flip/flop
|
||||
REGISTER_MOD_PARSER(FL, args)
|
||||
{
|
||||
bool horiz = (args.empty() || args.find("horiz") != std::string::npos);
|
||||
bool vert = (args.find("vert") != std::string::npos);
|
||||
|
||||
return new fl_modification(horiz, vert);
|
||||
}
|
||||
|
||||
// Grayscale
|
||||
REGISTER_MOD_PARSER(GS, )
|
||||
{
|
||||
return new gs_modification;
|
||||
}
|
||||
|
||||
// Color-shift
|
||||
REGISTER_MOD_PARSER(CS, args)
|
||||
{
|
||||
std::vector<std::string> const factors = utils::split(args, ',');
|
||||
const size_t s = factors.size();
|
||||
|
||||
if(s == 0) {
|
||||
ERR_DP << "no arguments passed to the ~CS() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int r = 0, g = 0, b = 0;
|
||||
|
||||
r = lexical_cast_default<int>(factors[0]);
|
||||
|
||||
if( s > 1 ) {
|
||||
g = lexical_cast_default<int>(factors[1]);
|
||||
}
|
||||
if( s > 2 ) {
|
||||
b = lexical_cast_default<int>(factors[2]);
|
||||
}
|
||||
|
||||
return new cs_modification(r, g, b);
|
||||
}
|
||||
|
||||
// Crop/slice
|
||||
REGISTER_MOD_PARSER(CROP, args)
|
||||
{
|
||||
std::vector<std::string> const& slice_params = utils::split(args, ',', utils::STRIP_SPACES);
|
||||
const size_t s = slice_params.size();
|
||||
|
||||
if(s == 0) {
|
||||
ERR_DP << "no arguments passed to the ~CROP() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_Rect slice_rect = { 0, 0, 0, 0 };
|
||||
|
||||
slice_rect.x = lexical_cast_default<Sint16, const std::string&>(slice_params[0]);
|
||||
|
||||
if(s > 1) {
|
||||
slice_rect.y = lexical_cast_default<Sint16, const std::string&>(slice_params[1]);
|
||||
}
|
||||
if(s > 2) {
|
||||
slice_rect.w = lexical_cast_default<Uint16, const std::string&>(slice_params[2]);
|
||||
}
|
||||
if(s > 3) {
|
||||
slice_rect.h = lexical_cast_default<Uint16, const std::string&>(slice_params[3]);
|
||||
}
|
||||
|
||||
return new crop_modification(slice_rect);
|
||||
}
|
||||
|
||||
// LOC function (unsupported)
|
||||
REGISTER_MOD_PARSER(LOC, )
|
||||
{
|
||||
/*
|
||||
//FIXME: WIP, don't use it yet
|
||||
std::vector<std::string> const& params = utils::split(args);
|
||||
int x = lexical_cast<int>(params[0]);
|
||||
int y = lexical_cast<int>(params[1]);
|
||||
int cx = lexical_cast<int>(params[2]);
|
||||
int cy = lexical_cast<int>(params[3]);
|
||||
image::locator new_loc(val_.filename_, map_location(x,y), cx, cy, "");//TODO remove only ~LOC
|
||||
surf = get_image(new_loc, TOD_COLORED);
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Blit
|
||||
REGISTER_MOD_PARSER(BLIT, args)
|
||||
{
|
||||
std::vector<std::string> param = utils::parenthetical_split(args, ',');
|
||||
const size_t s = param.size();
|
||||
|
||||
if(s == 0){
|
||||
ERR_DP << "no arguments passed to the ~BLIT() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int x = 0, y = 0;
|
||||
|
||||
if(s == 3) {
|
||||
x = lexical_cast_default<int>(param[1]);
|
||||
y = lexical_cast_default<int>(param[2]);
|
||||
}
|
||||
|
||||
if(x < 0 || y < 0) { //required by blit_surface
|
||||
ERR_DP << "negative position arguments in ~BLIT() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface surf = get_image(param[0]);
|
||||
|
||||
return new blit_modification(surf, x, y);
|
||||
}
|
||||
|
||||
// Mask
|
||||
REGISTER_MOD_PARSER(MASK, args)
|
||||
{
|
||||
std::vector<std::string> param = utils::parenthetical_split(args, ',');
|
||||
const size_t s = param.size();
|
||||
|
||||
if(s == 0){
|
||||
ERR_DP << "no arguments passed to the ~MASK() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int x = 0, y = 0;
|
||||
|
||||
if(s == 3) {
|
||||
x = lexical_cast_default<int>(param[1]);
|
||||
y = lexical_cast_default<int>(param[2]);
|
||||
}
|
||||
|
||||
if(x < 0 || y < 0) { //required by blit_surface
|
||||
ERR_DP << "negative position arguments in ~MASK() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface surf = get_image(param[0]);
|
||||
|
||||
return new mask_modification(surf, x, y);
|
||||
}
|
||||
|
||||
// Light
|
||||
REGISTER_MOD_PARSER(L, args)
|
||||
{
|
||||
if(args.empty()){
|
||||
ERR_DP << "no arguments passed to the ~L() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface surf = get_image(args);
|
||||
|
||||
return new light_modification(surf);
|
||||
}
|
||||
|
||||
// Scale
|
||||
REGISTER_MOD_PARSER(SCALE, args)
|
||||
{
|
||||
std::vector<std::string> const& scale_params = utils::split(args, ',', utils::STRIP_SPACES);
|
||||
const size_t s = scale_params.size();
|
||||
|
||||
if(s == 0) {
|
||||
ERR_DP << "no arguments passed to the ~SCALE() function\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int w = 0, h = 0;
|
||||
|
||||
w = lexical_cast_default<int, const std::string&>(scale_params[0]);
|
||||
|
||||
if(s > 1) {
|
||||
h = lexical_cast_default<int, const std::string&>(scale_params[1]);
|
||||
}
|
||||
|
||||
return new scale_modification(w, h);
|
||||
}
|
||||
|
||||
// Gaussian-like blur
|
||||
REGISTER_MOD_PARSER(BL, args)
|
||||
{
|
||||
const int depth = std::max<int>(0, lexical_cast_default<int>(args));
|
||||
|
||||
return new bl_modification(depth);
|
||||
}
|
||||
|
||||
// Opacity-shift
|
||||
REGISTER_MOD_PARSER(O, args)
|
||||
{
|
||||
const std::string::size_type p100_pos = args.find('%');
|
||||
float num = 0.0f;
|
||||
if(p100_pos == std::string::npos)
|
||||
num = lexical_cast_default<float,const std::string&>(args);
|
||||
else {
|
||||
// make multiplier
|
||||
const std::string parsed_field = args.substr(0, p100_pos);
|
||||
num = lexical_cast_default<float,const std::string&>(parsed_field);
|
||||
num /= 100.0f;
|
||||
}
|
||||
|
||||
return new o_modification(num);
|
||||
}
|
||||
|
||||
//
|
||||
// ~R(), ~G() and ~B() are the children of ~CS(). Merely syntatic sugar.
|
||||
// Hence they are at the end of the evaluation.
|
||||
//
|
||||
// Red component color-shift
|
||||
REGISTER_MOD_PARSER(R, args)
|
||||
{
|
||||
const int r = lexical_cast_default<int>(args);
|
||||
|
||||
return new cs_modification(r,0,0);
|
||||
}
|
||||
|
||||
// Green component color-shift
|
||||
REGISTER_MOD_PARSER(G, args)
|
||||
{
|
||||
const int g = lexical_cast_default<int>(args);
|
||||
|
||||
return new cs_modification(0,g,0);
|
||||
}
|
||||
|
||||
// Blue component color-shift
|
||||
REGISTER_MOD_PARSER(B, args)
|
||||
{
|
||||
const int b = lexical_cast_default<int>(args);
|
||||
|
||||
return new cs_modification(0,0,b);
|
||||
}
|
||||
|
||||
REGISTER_MOD_PARSER(NOP, )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fake image function used by GUI2 portraits until
|
||||
// Mordante gets rid of it. *tsk* *tsk*
|
||||
REGISTER_MOD_PARSER(RIGHT, )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Add a bright overlay.
|
||||
REGISTER_MOD_PARSER(BRIGHTEN, )
|
||||
{
|
||||
return new brighten_modification;
|
||||
}
|
||||
|
||||
// Add a dark overlay.
|
||||
REGISTER_MOD_PARSER(DARKEN, )
|
||||
{
|
||||
return new darken_modification;
|
||||
}
|
||||
|
||||
// Add a background color.
|
||||
REGISTER_MOD_PARSER(BG, args)
|
||||
{
|
||||
int c[4] = { 0, 0, 0, 255 };
|
||||
std::vector<std::string> factors = utils::split(args, ',');
|
||||
|
||||
for (int i = 0; i < std::min<int>(factors.size(), 4); ++i) {
|
||||
c[i] = lexical_cast_default<int>(factors[i]);
|
||||
}
|
||||
|
||||
return new background_modification(create_color(c[0], c[1], c[2], c[3]));
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
|
||||
} /* end namespace image */
|
626
src/image_modifications.hpp
Normal file
626
src/image_modifications.hpp
Normal file
|
@ -0,0 +1,626 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2011 by Ignacio R. Morelle <shadowm2006@gmail.com>
|
||||
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.
|
||||
*/
|
||||
|
||||
/** @file */
|
||||
|
||||
#ifndef IMAGE_MODIFICATIONS_HPP_INCLUDED
|
||||
#define IMAGE_MODIFICATIONS_HPP_INCLUDED
|
||||
|
||||
#include "sdl_utils.hpp"
|
||||
#include <queue>
|
||||
|
||||
namespace image {
|
||||
|
||||
class modification;
|
||||
struct mod_ptr_comparator_;
|
||||
/// A priority queue used to enforce using the rc modifications first
|
||||
typedef std::priority_queue<modification*,
|
||||
std::vector<modification*>,
|
||||
mod_ptr_comparator_> modification_queue;
|
||||
|
||||
/// Base abstract class for an image-path modification
|
||||
class modification
|
||||
{
|
||||
public:
|
||||
/// Decodes modifications from a modification string
|
||||
static modification_queue decode(const std::string&);
|
||||
|
||||
virtual ~modification() {}
|
||||
|
||||
///Applies the image-path modification on the specified surface
|
||||
virtual surface operator()(const surface& src) const = 0;
|
||||
|
||||
/// Specifies the priority of the modification
|
||||
virtual int priority() const { return 0; }
|
||||
};
|
||||
|
||||
/// A functor for comparing modification pointers
|
||||
struct mod_ptr_comparator_
|
||||
{
|
||||
/// Provides a descending priority ordering
|
||||
bool operator()(const modification* a, const modification* b) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recolor (RC/TC/PAL) modification.
|
||||
* It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
|
||||
* but also for team-color-based color range selection and recoloring
|
||||
* ("~TC(3,magenta)") and palette switches ("~PAL(000000,005000 > FFFFFF,FF00FF)").
|
||||
*/
|
||||
class rc_modification : public modification
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
rc_modification()
|
||||
: rc_map_()
|
||||
{}
|
||||
/**
|
||||
* RC-map based constructor.
|
||||
* @param recolor_map The palette switch map.
|
||||
*/
|
||||
rc_modification(const std::map<Uint32, Uint32>& recolor_map)
|
||||
: rc_map_(recolor_map)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
// The rc modification has a higher priority
|
||||
virtual int priority() const { return 1; }
|
||||
|
||||
bool no_op() const { return rc_map_.empty(); }
|
||||
|
||||
const std::map<Uint32, Uint32>& map() const { return rc_map_;}
|
||||
std::map<Uint32, Uint32>& map() { return rc_map_;}
|
||||
|
||||
private:
|
||||
std::map<Uint32, Uint32> rc_map_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mirror (FL) modification.
|
||||
*/
|
||||
class fl_modification : public modification
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param horiz Horizontal mirror flag.
|
||||
* @param vert Vertical mirror flag.
|
||||
*/
|
||||
fl_modification(bool horiz = false, bool vert = false)
|
||||
: horiz_(horiz)
|
||||
, vert_(vert)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
void set_horiz(bool val) { horiz_ = val; }
|
||||
void set_vert(bool val) { vert_ = val; }
|
||||
bool get_horiz() const { return horiz_; }
|
||||
bool get_vert() const { return vert_; }
|
||||
/** Toggle horizontal mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_horiz() { return((horiz_ = !horiz_)); }
|
||||
/** Toggle vertical mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_vert() { return((vert_ = !vert_)); }
|
||||
|
||||
bool no_op() const { return ((!horiz_) && (!vert_)); }
|
||||
|
||||
private:
|
||||
bool horiz_;
|
||||
bool vert_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Grayscale (GS) modification.
|
||||
*/
|
||||
class gs_modification : public modification
|
||||
{
|
||||
public:
|
||||
virtual surface operator()(const surface& src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Crop (CROP) modification.
|
||||
*/
|
||||
class crop_modification : public modification
|
||||
{
|
||||
public:
|
||||
crop_modification(const SDL_Rect& slice)
|
||||
: slice_(slice)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const SDL_Rect& get_slice() const;
|
||||
|
||||
private:
|
||||
SDL_Rect slice_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (BLIT) modification.
|
||||
*/
|
||||
|
||||
class blit_modification : public modification
|
||||
{
|
||||
public:
|
||||
blit_modification(const surface& surf, int x, int y)
|
||||
: surf_(surf), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_surface() const;
|
||||
int get_x() const;
|
||||
int get_y() const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mask (MASK) modification.
|
||||
*/
|
||||
|
||||
class mask_modification : public modification
|
||||
{
|
||||
public:
|
||||
mask_modification(const surface& mask, int x, int y)
|
||||
: mask_(mask), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_mask() const;
|
||||
int get_x() const;
|
||||
int get_y() const;
|
||||
|
||||
private:
|
||||
surface mask_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* LIGHT (L) modification.
|
||||
*/
|
||||
|
||||
class light_modification : public modification
|
||||
{
|
||||
public:
|
||||
light_modification(const surface& surf)
|
||||
: surf_(surf)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_surface() const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (SCALE) modification.
|
||||
*/
|
||||
class scale_modification : public modification
|
||||
{
|
||||
public:
|
||||
scale_modification(int width, int height)
|
||||
: w_(width), h_(height)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_w() const;
|
||||
int get_h() const;
|
||||
|
||||
private:
|
||||
int w_, h_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opacity (O) modification
|
||||
*/
|
||||
class o_modification : public modification
|
||||
{
|
||||
public:
|
||||
o_modification(float opacity)
|
||||
: opacity_(opacity)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
float get_opacity() const;
|
||||
|
||||
private:
|
||||
float opacity_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Color-shift (CS, R, G, B) modification.
|
||||
*/
|
||||
class cs_modification : public modification
|
||||
{
|
||||
public:
|
||||
cs_modification(int r, int g, int b)
|
||||
: r_(r), g_(g), b_(b)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_r() const;
|
||||
int get_g() const;
|
||||
int get_b() const;
|
||||
|
||||
private:
|
||||
int r_, g_, b_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gaussian-like blur (BL) modification.
|
||||
*/
|
||||
class bl_modification : public modification
|
||||
{
|
||||
public:
|
||||
bl_modification(int depth)
|
||||
: depth_(depth)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_depth() const;
|
||||
|
||||
private:
|
||||
int depth_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD brightening (BRIGHTEN).
|
||||
*/
|
||||
struct brighten_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD darkening (DARKEN).
|
||||
*/
|
||||
struct darken_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill background with a color (BG).
|
||||
*/
|
||||
struct background_modification : modification
|
||||
{
|
||||
background_modification(SDL_Color const &c): color_(c) {}
|
||||
virtual surface operator()(const surface &src) const;
|
||||
const SDL_Color& get_color() const;
|
||||
|
||||
private:
|
||||
SDL_Color color_;
|
||||
};
|
||||
|
||||
} /* end namespace image */
|
||||
|
||||
#endif /* !defined(IMAGE_MODIFICATIONS_HPP_INCLUDED) */
|
||||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2011 by Ignacio R. Morelle <shadowm2006@gmail.com>
|
||||
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.
|
||||
*/
|
||||
|
||||
/** @file */
|
||||
|
||||
#ifndef IMAGE_MODIFICATIONS_HPP_INCLUDED
|
||||
#define IMAGE_MODIFICATIONS_HPP_INCLUDED
|
||||
|
||||
#include "sdl_utils.hpp"
|
||||
#include <queue>
|
||||
|
||||
namespace image {
|
||||
|
||||
class modification;
|
||||
struct mod_ptr_comparator_;
|
||||
/// A priority queue used to enforce using the rc modifications first
|
||||
typedef std::priority_queue<modification*,
|
||||
std::vector<modification*>,
|
||||
mod_ptr_comparator_> modification_queue;
|
||||
|
||||
/// Base abstract class for an image-path modification
|
||||
class modification
|
||||
{
|
||||
public:
|
||||
/// Decodes modifications from a modification string
|
||||
static modification_queue decode(const std::string&);
|
||||
|
||||
virtual ~modification() {}
|
||||
|
||||
///Applies the image-path modification on the specified surface
|
||||
virtual surface operator()(const surface& src) const = 0;
|
||||
|
||||
/// Specifies the priority of the modification
|
||||
virtual int priority() const { return 0; }
|
||||
};
|
||||
|
||||
/// A functor for comparing modification pointers
|
||||
struct mod_ptr_comparator_
|
||||
{
|
||||
/// Provides a descending priority ordering
|
||||
bool operator()(const modification* a, const modification* b) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recolor (RC/TC/PAL) modification.
|
||||
* It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
|
||||
* but also for team-color-based color range selection and recoloring
|
||||
* ("~TC(3,magenta)") and palette switches ("~PAL(000000,005000 > FFFFFF,FF00FF)").
|
||||
*/
|
||||
class rc_modification : public modification
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
rc_modification()
|
||||
: rc_map_()
|
||||
{}
|
||||
/**
|
||||
* RC-map based constructor.
|
||||
* @param recolor_map The palette switch map.
|
||||
*/
|
||||
rc_modification(const std::map<Uint32, Uint32>& recolor_map)
|
||||
: rc_map_(recolor_map)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
// The rc modification has a higher priority
|
||||
virtual int priority() const { return 1; }
|
||||
|
||||
bool no_op() const { return rc_map_.empty(); }
|
||||
|
||||
const std::map<Uint32, Uint32>& map() const { return rc_map_;}
|
||||
std::map<Uint32, Uint32>& map() { return rc_map_;}
|
||||
|
||||
private:
|
||||
std::map<Uint32, Uint32> rc_map_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mirror (FL) modification.
|
||||
*/
|
||||
class fl_modification : public modification
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param horiz Horizontal mirror flag.
|
||||
* @param vert Vertical mirror flag.
|
||||
*/
|
||||
fl_modification(bool horiz = false, bool vert = false)
|
||||
: horiz_(horiz)
|
||||
, vert_(vert)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
void set_horiz(bool val) { horiz_ = val; }
|
||||
void set_vert(bool val) { vert_ = val; }
|
||||
bool get_horiz() const { return horiz_; }
|
||||
bool get_vert() const { return vert_; }
|
||||
/** Toggle horizontal mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_horiz() { return((horiz_ = !horiz_)); }
|
||||
/** Toggle vertical mirror flag.
|
||||
* @return The new flag state after toggling. */
|
||||
bool toggle_vert() { return((vert_ = !vert_)); }
|
||||
|
||||
bool no_op() const { return ((!horiz_) && (!vert_)); }
|
||||
|
||||
private:
|
||||
bool horiz_;
|
||||
bool vert_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Grayscale (GS) modification.
|
||||
*/
|
||||
class gs_modification : public modification
|
||||
{
|
||||
public:
|
||||
virtual surface operator()(const surface& src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Crop (CROP) modification.
|
||||
*/
|
||||
class crop_modification : public modification
|
||||
{
|
||||
public:
|
||||
crop_modification(const SDL_Rect& slice)
|
||||
: slice_(slice)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const SDL_Rect& get_slice() const;
|
||||
|
||||
private:
|
||||
SDL_Rect slice_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (BLIT) modification.
|
||||
*/
|
||||
|
||||
class blit_modification : public modification
|
||||
{
|
||||
public:
|
||||
blit_modification(const surface& surf, int x, int y)
|
||||
: surf_(surf), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_surface() const;
|
||||
int get_x() const;
|
||||
int get_y() const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mask (MASK) modification.
|
||||
*/
|
||||
|
||||
class mask_modification : public modification
|
||||
{
|
||||
public:
|
||||
mask_modification(const surface& mask, int x, int y)
|
||||
: mask_(mask), x_(x), y_(y)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_mask() const;
|
||||
int get_x() const;
|
||||
int get_y() const;
|
||||
|
||||
private:
|
||||
surface mask_;
|
||||
int x_;
|
||||
int y_;
|
||||
};
|
||||
|
||||
/**
|
||||
* LIGHT (L) modification.
|
||||
*/
|
||||
|
||||
class light_modification : public modification
|
||||
{
|
||||
public:
|
||||
light_modification(const surface& surf)
|
||||
: surf_(surf)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
|
||||
const surface& get_surface() const;
|
||||
|
||||
private:
|
||||
surface surf_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale (SCALE) modification.
|
||||
*/
|
||||
class scale_modification : public modification
|
||||
{
|
||||
public:
|
||||
scale_modification(int width, int height)
|
||||
: w_(width), h_(height)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_w() const;
|
||||
int get_h() const;
|
||||
|
||||
private:
|
||||
int w_, h_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opacity (O) modification
|
||||
*/
|
||||
class o_modification : public modification
|
||||
{
|
||||
public:
|
||||
o_modification(float opacity)
|
||||
: opacity_(opacity)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
float get_opacity() const;
|
||||
|
||||
private:
|
||||
float opacity_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Color-shift (CS, R, G, B) modification.
|
||||
*/
|
||||
class cs_modification : public modification
|
||||
{
|
||||
public:
|
||||
cs_modification(int r, int g, int b)
|
||||
: r_(r), g_(g), b_(b)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_r() const;
|
||||
int get_g() const;
|
||||
int get_b() const;
|
||||
|
||||
private:
|
||||
int r_, g_, b_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gaussian-like blur (BL) modification.
|
||||
*/
|
||||
class bl_modification : public modification
|
||||
{
|
||||
public:
|
||||
bl_modification(int depth)
|
||||
: depth_(depth)
|
||||
{}
|
||||
virtual surface operator()(const surface& src) const;
|
||||
int get_depth() const;
|
||||
|
||||
private:
|
||||
int depth_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD brightening (BRIGHTEN).
|
||||
*/
|
||||
struct brighten_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overlay with ToD darkening (DARKEN).
|
||||
*/
|
||||
struct darken_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill background with a color (BG).
|
||||
*/
|
||||
struct background_modification : modification
|
||||
{
|
||||
background_modification(SDL_Color const &c): color_(c) {}
|
||||
virtual surface operator()(const surface &src) const;
|
||||
const SDL_Color& get_color() const;
|
||||
|
||||
private:
|
||||
SDL_Color color_;
|
||||
};
|
||||
|
||||
} /* end namespace image */
|
||||
|
||||
#endif /* !defined(IMAGE_MODIFICATIONS_HPP_INCLUDED) */
|
Loading…
Add table
Reference in a new issue