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