src/video/sdl/sdl_texture.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include <config.h>
00018 
00019 #include "supertux/gameconfig.hpp"
00020 #include "supertux/globals.hpp"
00021 #include "video/color.hpp"
00022 #include "video/sdl/sdl_texture.hpp"
00023 #include "util/log.hpp"
00024 #include "math/random_generator.hpp"
00025 
00026 #include <assert.h>
00027 
00028 #include <SDL.h>
00029 
00030 namespace {
00031 #define BILINEAR
00032 
00033 static Uint32 get_pixel_mapping (SDL_Surface *src, void *pixel)
00034 {
00035   Uint32 mapped = 0;
00036 
00037   switch (src->format->BytesPerPixel)
00038   {
00039     case 1:
00040       mapped = *((Uint8 *) pixel);
00041       break;
00042     case 2:
00043       mapped = *((Uint16 *) pixel);
00044       break;
00045     case 3:
00046     {
00047       Uint8 *tmp = (Uint8 *) pixel;
00048 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00049       mapped |= tmp[0] << 16;
00050       mapped |= tmp[1] << 8;
00051       mapped |= tmp[2] << 0;
00052 #else
00053       mapped |= tmp[0] << 0;
00054       mapped |= tmp[1] << 8;
00055       mapped |= tmp[2] << 16;
00056 #endif
00057       break;
00058     }
00059     case 4:
00060       mapped = *((Uint32 *) pixel);
00061       break;
00062 
00063     default:
00064       log_warning << "Unknown BytesPerPixel value: "
00065         << src->format->BytesPerPixel << std::endl;
00066       mapped = 0;
00067   } /* switch (bpp) */
00068 
00069   return (mapped);
00070 } /* Uint32 get_pixel_mapping */
00071 
00072 static Uint32 get_random_color (SDL_Surface *src)
00073 {
00074   Uint32 r;
00075 
00076   r = (Uint32) graphicsRandom.rand ();
00077   /* rand() returns 31bit random numbers. So call it twice to get full 32 bit. */
00078   r <<= 1;
00079   r |= (Uint32) graphicsRandom.rand ();
00080 
00081   switch (src->format->BytesPerPixel)
00082   {
00083     case 1:
00084       r &= 0x000000ff;
00085       break;
00086 
00087     case 2:
00088       r &= 0x0000ffff;
00089       break;
00090 
00091     case 3:
00092       r &= 0x0000ffff;
00093       break;
00094   }
00095 
00096   return (r);
00097 } /* Uint32 get_random_color */
00098 
00099 static bool color_is_used (SDL_Surface *src, Uint32 color)
00100 {
00101   if(SDL_MUSTLOCK(src))
00102     SDL_LockSurface(src);
00103 
00104   for(int y = 0; y < src->h; y++) {
00105     for(int x = 0; x < src->w; x++) {
00106       Uint8 *pixel = (Uint8 *) src->pixels
00107         + (y * src->pitch) + (x * src->format->BytesPerPixel);
00108       Uint32 mapped = get_pixel_mapping (src, pixel);
00109 
00110       if (color == mapped)
00111         return (true);
00112     }
00113   }
00114 
00115   return (false);
00116 } /* bool color_is_used */
00117 
00118 static Uint32 get_unused_color (SDL_Surface *src)
00119 {
00120   Uint32 random_color;
00121 
00122   do
00123   {
00124     random_color = get_random_color (src);
00125   } while (color_is_used (src, random_color));
00126 
00127   return (random_color);
00128 } /* Uint32 get_unused_color */
00129 
00130 #ifdef NAIVE
00131 SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
00132 {
00133   if(numerator == denominator)
00134   {
00135     src->refcount++;
00136     return src;
00137   }
00138   else
00139   {
00140     SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask,  src->format->Gmask, src->format->Bmask, src->format->Amask);
00141     int bpp = dst->format->BytesPerPixel;
00142     if(SDL_MUSTLOCK(src))
00143     {
00144       SDL_LockSurface(src);
00145     }
00146     if(SDL_MUSTLOCK(dst))
00147     {
00148       SDL_LockSurface(dst);
00149     }
00150     for(int y = 0;y < dst->h;y++) {
00151       for(int x = 0;x < dst->w;x++) {
00152         Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp;
00153         Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00154         switch(bpp) {
00155           case 4:
00156             dstpixel[3] = srcpixel[3];
00157           case 3:
00158             dstpixel[2] = srcpixel[2];
00159           case 2:
00160             dstpixel[1] = srcpixel[1];
00161           case 1:
00162             dstpixel[0] = srcpixel[0];
00163         }
00164       }
00165     }
00166     if(SDL_MUSTLOCK(dst))
00167     {
00168       SDL_UnlockSurface(dst);
00169     }
00170     if(SDL_MUSTLOCK(src))
00171     {
00172       SDL_UnlockSurface(src);
00173     }
00174     if(!src->format->Amask)
00175     {
00176       if(src->flags & SDL_SRCALPHA)
00177       {
00178         SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
00179       }
00180       if(src->flags & SDL_SRCCOLORKEY)
00181       {
00182         SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
00183       }
00184     }
00185     return dst;
00186   }
00187 } // namespace
00188 #endif
00189 
00190 #ifdef BILINEAR
00191 void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4])
00192 {
00193   int bpp = src->format->BytesPerPixel;
00194   if(srcx == src->w)
00195   {
00196     srcx--;
00197   }
00198   if(srcy == src->h)
00199   {
00200     srcy--;
00201   }
00202   Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
00203   Uint32 mapped = get_pixel_mapping (src, srcpixel);
00204   SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]);
00205 }
00206 
00207 void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total)
00208 {
00209   color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
00210   color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
00211   color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
00212   color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total;
00213 }
00214 
00215 SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
00216 {
00217   if(numerator == denominator)
00218   {
00219     src->refcount++;
00220     return src;
00221   }
00222   else
00223   {
00224     SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask,  src->format->Gmask, src->format->Bmask, src->format->Amask);
00225     int bpp = dst->format->BytesPerPixel;
00226     if(SDL_MUSTLOCK(src))
00227     {
00228       SDL_LockSurface(src);
00229     }
00230     if(SDL_MUSTLOCK(dst))
00231     {
00232       SDL_LockSurface(dst);
00233     }
00234     for(int y = 0;y < dst->h;y++) {
00235       for(int x = 0;x < dst->w;x++) {
00236         int srcx = x * denominator / numerator;
00237         int srcy = y * denominator / numerator;
00238         Uint8 color00[4], color01[4], color10[4], color11[4];
00239         getpixel(src, srcx, srcy, color00);
00240         getpixel(src, srcx + 1, srcy, color01);
00241         getpixel(src, srcx, srcy + 1, color10);
00242         getpixel(src, srcx + 1, srcy + 1, color11);
00243         Uint8 color0[4], color1[4], color[4];
00244         int remx = x * denominator % numerator;
00245         merge(color0, color00, color01, remx, numerator);
00246         merge(color1, color10, color11, remx, numerator);
00247         int remy = y * denominator % numerator;
00248         merge(color, color0, color1, remy, numerator);
00249         Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00250         Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]);
00251         switch(bpp) {
00252           case 1:
00253             *dstpixel = mapped;
00254             break;
00255           case 2:
00256             *(Uint16 *)dstpixel = mapped;
00257             break;
00258           case 3:
00259 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00260             dstpixel[0] = (mapped >> 16) & 0xff;
00261             dstpixel[1] = (mapped >> 8) & 0xff;
00262             dstpixel[2] = (mapped >> 0) & 0xff;
00263 #else
00264             dstpixel[0] = (mapped >> 0) & 0xff;
00265             dstpixel[1] = (mapped >> 8) & 0xff;
00266             dstpixel[2] = (mapped >> 16) & 0xff;
00267 #endif
00268             break;
00269           case 4:
00270             *(Uint32 *)dstpixel = mapped;
00271             break;
00272         }
00273       }
00274     }
00275     if(SDL_MUSTLOCK(dst))
00276     {
00277       SDL_UnlockSurface(dst);
00278     }
00279     if(SDL_MUSTLOCK(src))
00280     {
00281       SDL_UnlockSurface(src);
00282     }
00283     if(!src->format->Amask)
00284     {
00285       if(src->flags & SDL_SRCALPHA)
00286       {
00287         SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
00288       }
00289       if(src->flags & SDL_SRCCOLORKEY)
00290       {
00291         SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
00292       }
00293     }
00294     return dst;
00295   }
00296 }
00297 #endif
00298 
00299 SDL_Surface *horz_flip(SDL_Surface *src)
00300 {
00301   SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask,  src->format->Gmask, src->format->Bmask, src->format->Amask);
00302   int bpp = dst->format->BytesPerPixel;
00303   if(SDL_MUSTLOCK(src))
00304   {
00305     SDL_LockSurface(src);
00306   }
00307   if(SDL_MUSTLOCK(dst))
00308   {
00309     SDL_LockSurface(dst);
00310   }
00311   for(int y = 0;y < dst->h;y++) {
00312     for(int x = 0;x < dst->w;x++) {
00313       Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
00314       Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp;
00315       switch(bpp) {
00316         case 4:
00317           dstpixel[3] = srcpixel[3];
00318         case 3:
00319           dstpixel[2] = srcpixel[2];
00320         case 2:
00321           dstpixel[1] = srcpixel[1];
00322         case 1:
00323           dstpixel[0] = srcpixel[0];
00324       }
00325     }
00326   }
00327   if(SDL_MUSTLOCK(dst))
00328   {
00329     SDL_UnlockSurface(dst);
00330   }
00331   if(SDL_MUSTLOCK(src))
00332   {
00333     SDL_UnlockSurface(src);
00334   }
00335   if(!src->format->Amask)
00336   {
00337     if(src->flags & SDL_SRCALPHA)
00338     {
00339       SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
00340     }
00341     if(src->flags & SDL_SRCCOLORKEY)
00342     {
00343       SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
00344     }
00345   }
00346   return dst;
00347 }
00348 
00349 SDL_Surface *vert_flip(SDL_Surface *src)
00350 {
00351   SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask,  src->format->Gmask, src->format->Bmask, src->format->Amask);
00352   int bpp = dst->format->BytesPerPixel;
00353   if(SDL_MUSTLOCK(src))
00354   {
00355     SDL_LockSurface(src);
00356   }
00357   if(SDL_MUSTLOCK(dst))
00358   {
00359     SDL_LockSurface(dst);
00360   }
00361   for(int y = 0;y < dst->h;y++) {
00362     for(int x = 0;x < dst->w;x++) {
00363       Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
00364       Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp;
00365       switch(bpp) {
00366         case 4:
00367           dstpixel[3] = srcpixel[3];
00368         case 3:
00369           dstpixel[2] = srcpixel[2];
00370         case 2:
00371           dstpixel[1] = srcpixel[1];
00372         case 1:
00373           dstpixel[0] = srcpixel[0];
00374       }
00375     }
00376   }
00377   if(SDL_MUSTLOCK(dst))
00378   {
00379     SDL_UnlockSurface(dst);
00380   }
00381   if(SDL_MUSTLOCK(src))
00382   {
00383     SDL_UnlockSurface(src);
00384   }
00385   if(!src->format->Amask)
00386   {
00387     if(src->flags & SDL_SRCALPHA)
00388     {
00389       SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
00390     }
00391     if(src->flags & SDL_SRCCOLORKEY)
00392     {
00393       SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
00394     }
00395   }
00396   return dst;
00397 }
00398 
00399 SDL_Surface *colorize(SDL_Surface *src, const Color &color)
00400 {
00401   // FIXME: This is really slow
00402   assert(color.red != 1.0 || color.green != 1.0 || color.blue != 1.0);
00403   int red = (int) (color.red * 256);
00404   int green = (int) (color.green * 256);
00405   int blue = (int) (color.blue * 256);
00406   SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask,  src->format->Gmask, src->format->Bmask, src->format->Amask);
00407   int bpp = dst->format->BytesPerPixel;
00408   if(SDL_MUSTLOCK(src))
00409   {
00410     SDL_LockSurface(src);
00411   }
00412   if(SDL_MUSTLOCK(dst))
00413   {
00414     SDL_LockSurface(dst);
00415   }
00416   for(int y = 0;y < dst->h;y++) {
00417     for(int x = 0;x < dst->w;x++) {
00418       Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
00419       Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00420       Uint32 mapped = 0;
00421       switch(bpp) {
00422         case 1:
00423           mapped = *srcpixel;
00424           break;
00425         case 2:
00426           mapped = *(Uint16 *)srcpixel;
00427           break;
00428         case 3:
00429 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00430           mapped |= srcpixel[0] << 16;
00431           mapped |= srcpixel[1] << 8;
00432           mapped |= srcpixel[2] << 0;
00433 #else
00434           mapped |= srcpixel[0] << 0;
00435           mapped |= srcpixel[1] << 8;
00436           mapped |= srcpixel[2] << 16;
00437 #endif
00438           break;
00439         case 4:
00440           mapped = *(Uint32 *)srcpixel;
00441           break;
00442       }
00443       if(src->format->Amask || !(src->flags & SDL_SRCCOLORKEY) || mapped != src->format->colorkey)
00444       {
00445         Uint8 r, g, b, a;
00446         SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
00447         mapped = SDL_MapRGBA(dst->format, (r * red) >> 8, (g * green) >> 8, (b * blue) >> 8, a);
00448       }
00449       switch(bpp) {
00450         case 1:
00451           *dstpixel = mapped;
00452           break;
00453         case 2:
00454           *(Uint16 *)dstpixel = mapped;
00455           break;
00456         case 3:
00457 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00458           dstpixel[0] = (mapped >> 16) & 0xff;
00459           dstpixel[1] = (mapped >> 8) & 0xff;
00460           dstpixel[2] = (mapped >> 0) & 0xff;
00461 #else
00462           dstpixel[0] = (mapped >> 0) & 0xff;
00463           dstpixel[1] = (mapped >> 8) & 0xff;
00464           dstpixel[2] = (mapped >> 16) & 0xff;
00465 #endif
00466           break;
00467         case 4:
00468           *(Uint32 *)dstpixel = mapped;
00469           break;
00470       }
00471     }
00472   }
00473   if(SDL_MUSTLOCK(dst))
00474   {
00475     SDL_UnlockSurface(dst);
00476   }
00477   if(SDL_MUSTLOCK(src))
00478   {
00479     SDL_UnlockSurface(src);
00480   }
00481   if(!src->format->Amask)
00482   {
00483     if(src->flags & SDL_SRCALPHA)
00484     {
00485       SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
00486     }
00487     if(src->flags & SDL_SRCCOLORKEY)
00488     {
00489       SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
00490     }
00491   }
00492   return dst;
00493 }
00494 
00502 SDL_Surface *optimize(SDL_Surface *src)
00503 {
00504   bool have_transparent = false;
00505   bool have_semi_trans = false;
00506   bool have_opaque = false;
00507 
00508   if(!src->format->Amask)
00509     return SDL_DisplayFormat(src);
00510 
00511   if(SDL_MUSTLOCK(src))
00512     SDL_LockSurface(src);
00513 
00514   /* Iterate over all the pixels and record which ones we found. */
00515   for(int y = 0; y < src->h; y++) {
00516     for(int x = 0; x < src->w; x++) {
00517       Uint8 *pixel = (Uint8 *) src->pixels
00518         + (y * src->pitch) + (x * src->format->BytesPerPixel);
00519       Uint32 mapped = get_pixel_mapping (src, pixel);
00520       Uint8 red, green, blue, alpha;
00521       SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
00522 
00523       if (alpha < 16)
00524         have_transparent = true;
00525       else if (alpha > 240)
00526         have_opaque = true;
00527       else
00528         have_semi_trans = true;
00529     } /* for (x) */
00530   } /* for (y) */
00531 
00532   if(SDL_MUSTLOCK(src))
00533     SDL_UnlockSurface(src);
00534 
00535   if (have_semi_trans)
00536     return SDL_DisplayFormatAlpha(src);
00537 
00538   if (!have_transparent /* && !have_semi_trans */)
00539     return SDL_DisplayFormat(src);
00540 
00541   /* The surface is totally transparent. We shouldn't return a surface at all,
00542    * but since the calling code can't cope with that, use the alpha channel in
00543    * this case. */
00544   if (!have_opaque /* && !have_semi_trans */)
00545     return SDL_DisplayFormatAlpha(src);
00546 
00547   /* If we get here, the surface has fully transparent pixels and fully opaque
00548    * pixels, but no semi-transparent pixels. We can therefore use a one bit
00549    * transparency, which is pretty fast to draw. This code path is a bit bulky
00550    * and rarely used (~25 surfaces when starting the game and entering a
00551    * level), so it could be removed for readabilities sake. -octo */
00552 
00553   /* Create a new surface without alpha channel */
00554   SDL_Surface *dst = SDL_CreateRGBSurface(src->flags & ~(SDL_SRCALPHA),
00555       src->w, src->h, src->format->BitsPerPixel,
00556       src->format->Rmask,  src->format->Gmask, src->format->Bmask, /* Amask = */ 0);
00557   /* Get a color that's not in the source surface. It is used to mark
00558    * transparent pixels. There's a possible race condition: Maybe we should
00559    * lock the surface before calling this function and add a "bool have_lock"
00560    * argument to "get_unused_color"? -octo */
00561   Uint32 color_key = get_unused_color (src);
00562 
00563   if(SDL_MUSTLOCK(src))
00564     SDL_LockSurface(src);
00565   if(SDL_MUSTLOCK(dst))
00566     SDL_LockSurface(dst);
00567 
00568   /* Copy all the pixels to the new surface */
00569   for(int y = 0; y < src->h; y++) {
00570     for(int x = 0; x < src->w; x++) {
00571       Uint8 *src_pixel = (Uint8 *) src->pixels
00572         + (y * src->pitch) + (x * src->format->BytesPerPixel);
00573       Uint8 *dst_pixel = (Uint8 *) dst->pixels
00574         + (y * dst->pitch) + (x * dst->format->BytesPerPixel);
00575       Uint32 mapped = get_pixel_mapping (src, src_pixel);
00576       Uint8 red, green, blue, alpha;
00577       SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
00578 
00579       /* "alpha" should either be smaller than 16 or greater than 240. We
00580        * unlocked the surface in between though, so use 128 to play it save,
00581        * i.e. don't leave any unspecified code paths. */
00582       if (alpha < 128)
00583         mapped = color_key;
00584 
00585       switch (dst->format->BytesPerPixel)
00586       {
00587         case 1:
00588           *dst_pixel = (Uint8) mapped;
00589           break;
00590 
00591         case 2:
00592           *((Uint16 *) dst_pixel) = (Uint16) mapped;
00593           break;
00594 
00595         case 3:
00596 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00597             dst_pixel[0] = (mapped >> 16) & 0xff;
00598             dst_pixel[1] = (mapped >> 8) & 0xff;
00599             dst_pixel[2] = (mapped >> 0) & 0xff;
00600 #else
00601             dst_pixel[0] = (mapped >> 0) & 0xff;
00602             dst_pixel[1] = (mapped >> 8) & 0xff;
00603             dst_pixel[2] = (mapped >> 16) & 0xff;
00604 #endif
00605             break;
00606 
00607         case 4:
00608             *((Uint32 *) dst_pixel) = mapped;
00609       } /* switch (dst->format->BytesPerPixel) */
00610     } /* for (x) */
00611   } /* for (y) */
00612 
00613   if(SDL_MUSTLOCK(src))
00614     SDL_UnlockSurface(src);
00615   if(SDL_MUSTLOCK(dst))
00616     SDL_UnlockSurface(dst);
00617 
00618   /* Tell SDL that the "color_key" color is supposed to be transparent. */
00619   SDL_SetColorKey (dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, color_key);
00620   SDL_Surface *convert = SDL_DisplayFormat(dst);
00621   SDL_FreeSurface(dst);
00622   return convert;
00623 } /* SDL_Surface *optimize */
00624 
00625 } /* namespace */
00626 
00627 SDLTexture::SDLTexture(SDL_Surface* image) :
00628   texture()
00629 {
00630   texture = optimize(image);
00631   //width = texture->w;
00632   //height = texture->h;
00633   int numerator   = 1;
00634   int denominator = 1;
00635   //FIXME: float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
00636   //FIXME: float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
00637   /* FIXME: 
00638      if(xfactor < yfactor)
00639      {
00640      numerator = config->screenwidth;
00641      denominator = SCREEN_WIDTH;
00642      }
00643      else
00644      {
00645      numerator = config->screenheight;
00646      denominator = SCREEN_HEIGHT;
00647      }
00648   */
00649   cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
00650 }
00651 
00652 SDLTexture::~SDLTexture()
00653 {
00654   SDL_FreeSurface(texture);
00655 }
00656 
00657 SDL_Surface*
00658 SDLTexture::get_transform(const Color &color, DrawingEffect effect)
00659 {
00660   if(cache[NO_EFFECT][color] == 0) {
00661     assert(cache[NO_EFFECT][Color::WHITE]);
00662     cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color);
00663   }
00664   if(cache[effect][color] == 0) {
00665     assert(cache[NO_EFFECT][color]);
00666     switch(effect) {
00667       case NO_EFFECT:
00668         break;
00669       case HORIZONTAL_FLIP:
00670         cache[HORIZONTAL_FLIP][color] = horz_flip(cache[NO_EFFECT][color]);
00671         break;
00672       case VERTICAL_FLIP:
00673         cache[VERTICAL_FLIP][color] = vert_flip(cache[NO_EFFECT][color]);
00674         break;
00675       default:
00676         return 0;
00677     }
00678   }
00679   return cache[effect][color];
00680 }
00681 
00682 /* vim: set sw=2 sts=2 et : */
00683 /* EOF */

Generated on Mon Jun 9 03:38:24 2014 for SuperTux by  doxygen 1.5.1