00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SDL_UTILS_INCLUDED
00018 #define SDL_UTILS_INCLUDED
00019
00020 #include "scoped_resource.hpp"
00021 #include "util.hpp"
00022
00023 #include "SDL.h"
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027 #include <string>
00028 #include <vector>
00029
00030
00031
00032
00033 #ifndef SDL_BUTTON_WHEELUP
00034 #define SDL_BUTTON_WHEELUP 4
00035 #endif
00036
00037 #ifndef SDL_BUTTON_WHEELDOWN
00038 #define SDL_BUTTON_WHEELDOWN 5
00039 #endif
00040
00041 #ifndef SDL_BUTTON_WHEELLEFT
00042 #define SDL_BUTTON_WHEELLEFT 6
00043 #endif
00044
00045 #ifndef SDL_BUTTON_WHEELRIGHT
00046 #define SDL_BUTTON_WHEELRIGHT 7
00047 #endif
00048
00049 namespace {
00050 const SDL_Rect empty_rect = { 0, 0, 0, 0 };
00051 }
00052
00053 SDLKey sdl_keysym_from_name(std::string const &keyname);
00054
00055 bool point_in_rect(int x, int y, const SDL_Rect& rect);
00056 bool rects_overlap(const SDL_Rect& rect1, const SDL_Rect& rect2);
00057 SDL_Rect intersect_rects(SDL_Rect const &rect1, SDL_Rect const &rect2);
00058
00059 SDL_Rect create_rect(const int x, const int y, const int w, const int h);
00060
00061 struct surface
00062 {
00063 private:
00064 static void sdl_add_ref(SDL_Surface *surf)
00065 {
00066 if (surf != NULL)
00067 ++surf->refcount;
00068 }
00069
00070 struct free_sdl_surface {
00071 void operator()(SDL_Surface *surf) const
00072 {
00073 if (surf != NULL)
00074 SDL_FreeSurface(surf);
00075 }
00076 };
00077
00078 typedef util::scoped_resource<SDL_Surface*,free_sdl_surface> scoped_sdl_surface;
00079 public:
00080 surface() : surface_(NULL)
00081 {}
00082
00083 surface(SDL_Surface *surf) : surface_(surf)
00084 {}
00085
00086 surface(const surface& o) : surface_(o.surface_.get())
00087 {
00088 sdl_add_ref(surface_.get());
00089 }
00090
00091 void assign(const surface& o)
00092 {
00093 SDL_Surface *surf = o.surface_.get();
00094 sdl_add_ref(surf);
00095 surface_.assign(surf);
00096 }
00097
00098 surface& operator=(const surface& o)
00099 {
00100 assign(o);
00101 return *this;
00102 }
00103
00104 operator SDL_Surface*() const { return surface_.get(); }
00105
00106 SDL_Surface* get() const { return surface_.get(); }
00107
00108 SDL_Surface* operator->() const { return surface_.get(); }
00109
00110 void assign(SDL_Surface* surf) { surface_.assign(surf); }
00111
00112 bool null() const { return surface_.get() == NULL; }
00113
00114 private:
00115 scoped_sdl_surface surface_;
00116 };
00117
00118 bool operator<(const surface& a, const surface& b);
00119
00120 surface make_neutral_surface(surface const &surf);
00121 surface create_optimized_surface(surface const &surf);
00122
00123
00124 surface stretch_surface_horizontal(
00125 const surface& surf, const unsigned w, const bool optimize = true);
00126
00127
00128 surface stretch_surface_vertical(
00129 const surface& surf, const unsigned h, const bool optimize = true);
00130
00131 surface scale_surface(surface const &surf, int w, int h, bool optimize=true);
00132 surface scale_surface_blended(surface const &surf, int w, int h, bool optimize=true);
00133 surface adjust_surface_colour(surface const &surf, int r, int g, int b, bool optimize=true);
00134 surface greyscale_image(surface const &surf, bool optimize=true);
00135 surface darken_image(surface const &surf, bool optimize=true);
00136 surface recolor_image(surface surf, const std::map<Uint32, Uint32>& map_rgb, bool optimize=true);
00137
00138 surface brighten_image(surface const &surf, fixed_t amount, bool optimize=true);
00139
00140 surface get_surface_portion(surface const &surf, SDL_Rect &rect);
00141 surface adjust_surface_alpha(surface const &surf, fixed_t amount, bool optimize=true);
00142 surface adjust_surface_alpha_add(surface const &surf, int amount, bool optimize=true);
00143 surface mask_surface(surface const &surf, surface const &mask);
00144 surface blur_surface(surface const &surf, int depth = 1, bool optimize=true);
00145 surface blur_alpha_surface(surface const &surf, int depth = 1, bool optimize=true);
00146 surface cut_surface(surface const &surf, SDL_Rect const &r);
00147 surface blend_surface(surface const &surf, double amount, Uint32 colour, bool optimize=true);
00148 surface flip_surface(surface const &surf, bool optimize=true);
00149 surface flop_surface(surface const &surf, bool optimize=true);
00150 surface create_compatible_surface(surface const &surf, int width = -1, int height = -1);
00151
00152 void blit_surface(const surface& src,
00153 const SDL_Rect* srcrect, surface& dst, const SDL_Rect* dstrect);
00154
00155 void fill_rect_alpha(SDL_Rect &rect, Uint32 colour, Uint8 alpha, surface const &target);
00156
00157 SDL_Rect get_non_transparent_portion(surface const &surf);
00158
00159 bool operator==(const SDL_Rect& a, const SDL_Rect& b);
00160 bool operator!=(const SDL_Rect& a, const SDL_Rect& b);
00161 bool operator==(const SDL_Color& a, const SDL_Color& b);
00162 bool operator!=(const SDL_Color& a, const SDL_Color& b);
00163 SDL_Color inverse(const SDL_Color& colour);
00164 SDL_Color int_to_color(const Uint32 rgb);
00165 Uint32 color_to_int(const SDL_Color& rgb);
00166
00167 class config;
00168
00169 struct pixel_data
00170 {
00171 pixel_data() : r(0), g(0), b(0)
00172 {}
00173
00174 pixel_data(int red, int green, int blue) : r(red), g(green), b(blue)
00175 {}
00176
00177 pixel_data(int pixel, SDL_PixelFormat* fmt) : r(0), g(0), b(0) {
00178 unformat(pixel, fmt);
00179 }
00180
00181 pixel_data(config& cfg) : r(0), g(0), b(0) {
00182 read(cfg);
00183 }
00184
00185 int format(SDL_PixelFormat* fmt) const {
00186 return SDL_MapRGB(fmt,r,g,b);
00187 }
00188
00189 void unformat(int pixel, SDL_PixelFormat* fmt) {
00190 r = ((pixel&fmt->Rmask) >> fmt->Rshift);
00191 g = ((pixel&fmt->Gmask) >> fmt->Gshift);
00192 b = ((pixel&fmt->Bmask) >> fmt->Bshift);
00193 }
00194
00195 void read(const config& cfg);
00196
00197 int r, g, b;
00198 };
00199
00200 struct surface_lock
00201 {
00202 surface_lock(surface const &surf) : surface_(surf), locked_(false)
00203 {
00204 if(SDL_MUSTLOCK(surface_)) {
00205 const int res = SDL_LockSurface(surface_);
00206 if(res == 0) {
00207 locked_ = true;
00208 }
00209 }
00210 }
00211
00212 ~surface_lock()
00213 {
00214 if(locked_) {
00215 SDL_UnlockSurface(surface_);
00216 }
00217 }
00218
00219 Uint32* pixels() { return reinterpret_cast<Uint32*>(surface_->pixels); }
00220 private:
00221 surface const surface_;
00222 bool locked_;
00223 };
00224
00225 struct surface_restorer
00226 {
00227 surface_restorer();
00228 surface_restorer(class CVideo* target, const SDL_Rect& rect);
00229 ~surface_restorer();
00230
00231 void restore() const;
00232 void restore(SDL_Rect const &dst) const;
00233 void update();
00234 void cancel();
00235
00236 const SDL_Rect& area() const { return rect_; }
00237
00238 private:
00239 class CVideo* target_;
00240 SDL_Rect rect_;
00241 surface surface_;
00242 };
00243
00244 struct clip_rect_setter
00245 {
00246 clip_rect_setter(surface const &surf, const SDL_Rect& r) : surface_(surf), rect()
00247 {
00248 SDL_GetClipRect(surface_,&rect);
00249 SDL_SetClipRect(surface_,&r);
00250 }
00251
00252 ~clip_rect_setter() { SDL_SetClipRect(surface_,&rect); }
00253
00254 private:
00255 surface surface_;
00256 SDL_Rect rect;
00257 };
00258
00259
00260 void draw_rectangle(int x, int y, int w, int h, Uint32 colour, surface tg);
00261
00262 void draw_solid_tinted_rectangle(int x, int y, int w, int h,
00263 int r, int g, int b,
00264 double alpha, surface target);
00265
00266
00267
00268 void draw_centered_on_background(surface surf, const SDL_Rect& rect,
00269 const SDL_Color& color, surface target);
00270
00271 #endif