- increased Tux's safe time to 1250ms
[supertux.git] / src / texture.cpp
index df33c74..f9ed75a 100644 (file)
@@ -251,13 +251,60 @@ Surface::resize(int w_, int h_)
 {
   if (impl)
   {
-  w = w_;
-  h = h_;
+    w = w_;
+    h = h_;
     if (impl->resize(w_,h_) == -2)
       reload();
   }
 }
 
+Surface* Surface::CaptureScreen()
+{
+  Surface *cap_screen;
+
+  if (!(screen->flags & SDL_OPENGL))
+  {
+    cap_screen = new Surface(SDL_GetVideoSurface(),false);
+  }
+
+#ifndef NOOPENGL
+  if (use_gl)
+  {
+    SDL_Surface *temp;
+    unsigned char *pixels;
+    int i;
+    temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+                                0x000000FF, 0x0000FF00, 0x00FF0000, 0
+#else
+                                0x00FF0000, 0x0000FF00, 0x000000FF, 0
+#endif
+                               );
+    if (temp == NULL)
+      st_abort("Error while trying to capture the screen in OpenGL mode","");
+
+    pixels = (unsigned char*) malloc(3 * screen->w * screen->h);
+    if (pixels == NULL)
+    {
+      SDL_FreeSurface(temp);
+      st_abort("Error while trying to capture the screen in OpenGL mode","");
+    }
+
+    glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+    for (i=0; i<screen->h; i++)
+      memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*screen->w * (screen->h-i-1), screen->w*3);
+    free(pixels);
+
+    cap_screen = new Surface(temp,false);
+    SDL_FreeSurface(temp);
+
+  }
+#endif
+  
+return cap_screen;
+}
+
 SDL_Surface*
 sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h,  int use_alpha)
 {
@@ -400,7 +447,7 @@ int SurfaceImpl::resize(int w_, int h_)
   dest.w = w;
   dest.h = h;
   int ret = SDL_SoftStretch(sdl_surface, NULL,
-                  sdl_surface, &dest);
+                            sdl_surface, &dest);
   return ret;
 }
 
@@ -650,15 +697,23 @@ SurfaceSDL::draw(float x, float y, Uint8 alpha, bool update)
   dest.h = h;
 
   if(alpha != 255)
-  {
-    /* Copy the SDL surface, then make it using alpha and use it to blit into the screen */
+    {
+    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
+      to temp sur, blit the temp into the screen */
+    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
+      already have an alpha mask yet... */
+
     SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
                                     sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
-                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask, sdl_surface->format->Bmask,
-                                    sdl_surface->format->Amask);
+                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                    sdl_surface->format->Bmask,
+                                    0);
+    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
+    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
+    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
 
-    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
 
+    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
     SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
 
     int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
@@ -666,9 +721,9 @@ SurfaceSDL::draw(float x, float y, Uint8 alpha, bool update)
     if (update == UPDATE)
       SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
 
-    SDL_FreeSurface (sdl_surface_copy) ;
+    SDL_FreeSurface (sdl_surface_copy);
     return ret;
-  }
+    }
 
   int ret = SDL_BlitSurface(sdl_surface, NULL, screen, &dest);
 
@@ -689,7 +744,33 @@ SurfaceSDL::draw_bg(Uint8 alpha, bool update)
   dest.h = screen->h;
 
   if(alpha != 255)
-    SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
+    {
+    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
+      to temp sur, blit the temp into the screen */
+    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
+      already have an alpha mask yet... */
+
+    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
+                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                    sdl_surface->format->Bmask,
+                                    0);
+    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
+    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
+    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
+
+
+    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
+
+    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
+
+    if (update == UPDATE)
+      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+
+    SDL_FreeSurface (sdl_surface_copy);
+    return ret;
+    }
 
   int ret = SDL_SoftStretch(sdl_surface, NULL, screen, &dest);
 
@@ -715,7 +796,33 @@ SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Ui
   dest.h = (int)h;
 
   if(alpha != 255)
-    SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
+    {
+    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
+      to temp sur, blit the temp into the screen */
+    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
+      already have an alpha mask yet... */
+
+    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
+                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                    sdl_surface->format->Bmask,
+                                    0);
+    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
+    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
+    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
+
+
+    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
+
+    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
+
+    if (update == UPDATE)
+      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+
+    SDL_FreeSurface (sdl_surface_copy);
+    return ret;
+    }
 
   int ret = SDL_BlitSurface(sdl_surface, &src, screen, &dest);
 
@@ -738,7 +845,18 @@ SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool u
   if(alpha != 255)
     SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
 
-  int ret = SDL_SoftStretch(sdl_surface, NULL, screen, &dest);
+
+  SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                  sw, sh, sdl_surface->format->BitsPerPixel,
+                                  sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                  sdl_surface->format->Bmask,
+                                  0);
+
+  SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+  SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest);
+
+  int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest);
+  SDL_FreeSurface(sdl_surface_copy);
 
   if (update == UPDATE)
     update_rect(screen, dest.x, dest.y, dest.w, dest.h);