Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "exploder_utils.hpp"
00017 #include "game_config.hpp"
00018 #include "serialization/string_utils.hpp"
00019 #include <png.h>
00020 #include <zlib.h>
00021
00022 exploder_point::exploder_point(const std::string &s)
00023 : x(0)
00024 , y(0)
00025 {
00026 std::vector<std::string> items = utils::split(s);
00027 if(items.size() == 2) {
00028 x = atoi(items[0].c_str());
00029 y = atoi(items[1].c_str());
00030 }
00031 }
00032
00033 exploder_rect::exploder_rect(const std::string &s)
00034 : x(0)
00035 , y(0)
00036 , w(0)
00037 , h(0)
00038 {
00039 std::vector<std::string> items = utils::split(s);
00040 if(items.size() == 4) {
00041 x = atoi(items[0].c_str());
00042 y = atoi(items[1].c_str());
00043 w = atoi(items[2].c_str());
00044 h = atoi(items[3].c_str());
00045 }
00046 }
00047
00048 std::string get_mask_dir()
00049 {
00050
00051 return game_config::path + "/images/tools/exploder";
00052 }
00053
00054 std::string get_exploder_dir()
00055 {
00056 return game_config::path + "/data/tools/exploder";
00057 }
00058
00059
00060
00061
00062
00063 void masked_overwrite_surface(surface dest, surface src, surface mask, int x, int y)
00064 {
00065 surface_lock dest_lock(dest);
00066 surface_lock src_lock(src);
00067 surface_lock mask_lock(mask);
00068
00069 Uint32* dest_beg = dest_lock.pixels();
00070 Uint32* src_beg = src_lock.pixels();
00071 Uint32* mask_beg = mask_lock.pixels();
00072
00073 size_t small_shift_before;
00074 size_t small_shift_after;
00075 size_t dest_shift;
00076 size_t src_width = src->w;
00077 size_t src_height = src->h;
00078
00079 if(x < 0) {
00080 small_shift_before = -x;
00081 if (src_width < small_shift_before)
00082 return;
00083 src_width -= small_shift_before;
00084 x = 0;
00085 } else {
00086 small_shift_before = 0;
00087 }
00088
00089 if(x + src_width <= unsigned(dest->w)) {
00090 small_shift_after = 0;
00091 } else {
00092 small_shift_after = src_width - (dest->w - x);
00093 src_width = dest->w - x;
00094 }
00095
00096 if(y >= 0) {
00097 dest_beg += dest->w * y + x;
00098 } else {
00099 src_beg += (-y) * src->w;
00100 mask_beg += (-y) * mask->w;
00101 dest_beg += x;
00102 if (src_height < static_cast<size_t>(-y))
00103 return;
00104 src_height += y;
00105 y = 0;
00106 }
00107
00108 if(y + src_height > unsigned(dest->h)) {
00109 src_height = dest->h - y;
00110 }
00111
00112 dest_shift = dest->w - src_width;
00113
00114 for(size_t j = 0; j < src_height; ++j) {
00115 src_beg += small_shift_before;
00116 mask_beg += small_shift_before;
00117
00118 for(size_t i = 0; i < src_width; ++i) {
00119
00120 if((*mask_beg & 0x00ffffff) != 0x00ffffff) {
00121 *dest_beg = *src_beg;
00122 }
00123 ++dest_beg;
00124 ++src_beg;
00125 ++mask_beg;
00126 }
00127
00128 src_beg += small_shift_after;
00129 mask_beg += small_shift_after;
00130 dest_beg += dest_shift;
00131 }
00132 }
00133
00134
00135
00136
00137 bool image_empty(surface surf)
00138 {
00139
00140
00141
00142
00143 surface_lock lock(surf);
00144
00145 Uint32* beg = lock.pixels();
00146 Uint32* end = beg + surf->w*surf->h;
00147
00148 Uint32 color = *beg;
00149
00150 while(beg != end) {
00151 if((*beg & 0xff000000) != 0 && (*beg != color))
00152 return false;
00153
00154 ++beg;
00155 }
00156 return true;
00157 }
00158
00159
00160 namespace {
00161 struct rgba {
00162 Uint8 r;
00163 Uint8 g;
00164 Uint8 b;
00165 Uint8 a;
00166 };
00167 }
00168
00169
00170 void save_image(surface surf, const std::string &filename)
00171 {
00172
00173 const util::scoped_FILE file(fopen(filename.c_str(),"wb"));
00174
00175
00176
00177
00178 png_struct* png_ptr = png_create_write_struct
00179 (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00180 if(!png_ptr)
00181 throw exploder_failure("Unable to initialize the png write structure");
00182
00183 png_info* info_ptr = png_create_info_struct(png_ptr);
00184 if(!info_ptr) {
00185 png_destroy_write_struct(&png_ptr, NULL);
00186 throw exploder_failure("Unable to initialize the png info structure");
00187 }
00188
00189
00190 png_init_io(png_ptr, file);
00191
00192
00193 png_set_compression_level(png_ptr,
00194 Z_BEST_COMPRESSION);
00195
00196
00197 png_set_IHDR(png_ptr, info_ptr, surf->w, surf->h,
00198 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
00199 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00200
00201
00202 png_byte **row_pointers = new png_byte *[surf->h];
00203 surface_lock lock(surf);
00204
00205
00206
00207
00208 util::scoped_array<rgba> rgba_data(new rgba[surf->w * surf->h]);
00209
00210 Uint32 *surf_data = lock.pixels();
00211 int pos = 0;
00212 for(int y = 0; y < surf->h; ++y) {
00213 row_pointers[y] = reinterpret_cast<png_byte*>(rgba_data + pos);
00214 for(int x = 0; x < surf->w; ++x) {
00215 Uint8 red, green, blue, alpha;
00216 SDL_GetRGBA(*surf_data, surf->format, &red, &green, &blue, &alpha);
00217 rgba_data[pos].r = red;
00218 rgba_data[pos].g = green;
00219 rgba_data[pos].b = blue;
00220 rgba_data[pos].a = alpha;
00221 pos++;
00222 surf_data++;
00223 }
00224 }
00225 png_set_rows(png_ptr, info_ptr, row_pointers);
00226
00227
00228 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00229
00230
00231 png_write_end(png_ptr, info_ptr);
00232 png_destroy_write_struct(&png_ptr, &info_ptr);
00233 delete [] row_pointers;
00234 }
00235