Hello,

I was a bit surprised to see that in order to flip a surface, RotoZoomXY
was used. Granted, it works, it probably doesn't zoom and rotate that
much, and it is only used on sprite loading.

Still, I quickly wrote a function for this. Please find attached a diff
for its addition.

Best regards,
Kurosu
Index: src/graphic/sprite.cpp
===================================================================
--- src/graphic/sprite.cpp	(révision 406)
+++ src/graphic/sprite.cpp	(copie de travail)
@@ -207,16 +207,20 @@
 
   for ( unsigned int f = 0 ; f < frames.size() ; f++)
   {
-	  Wormux::Surface flippedSurface = frames[f].surface.RotoZoomXY( 0.0, -1.0, 1.0, SMOOTHING_OFF);	  
-	  frames[f].flipped_surface = flippedSurface;
+#if 0
+    Wormux::Surface flippedSurface = frames[f].surface.RotoZoomXY( 0.0, -1.0, 1.0, SMOOTHING_OFF);
+#else
+    Wormux::Surface flippedSurface = frames[f].surface.HorizontalFlip();
+#endif
+    frames[f].flipped_surface = flippedSurface;
     if(have_rotation_cache)
     {
       frames[f].rotated_flipped_surface=new Wormux::Surface[rotation_cache_size];
Index: src/graphic/surface.cpp
===================================================================
--- src/graphic/surface.cpp	(révision 406)
+++ src/graphic/surface.cpp	(copie de travail)
@@ -208,6 +208,80 @@
 	return surface != NULL;
 }
 
+Surface Surface::HorizontalFlip(void)
+{
+  Surface            newSurf;
+  const SDL_Surface *src = surface;
+  SDL_Surface       *dst;
+  int                x, y;
+  
+  /* MMX horizontal flip
+   * Stream get 4 bytes, unpack, pshuf, repack, stream write
+   * (src->w&3) bytes, left, do conventional
+   */
+  if (src->format->BitsPerPixel == 32)
+  {
+    dst = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+                               src->format->Rmask, src->format->Gmask,
+                               src->format->Bmask, src->format->Amask);
+
+    /* Copying RGBA => 4 bytes at a time - MMX accelaration quite possible */
+    const Uint32 *src_ptr = (Uint32*)src->pixels;
+    const Sint32  src_gap = (Sint32)(src->pitch>>2) - src->w;
+    Uint32       *dst_ptr = ((Uint32*)dst->pixels)+(Sint32)dst->w-1;
+    const Sint32  dst_gap = (Sint32)(dst->pitch>>2) + dst->w;
+    
+    for (y=0; y<src->h; y++)
+    {
+      for (x=0; x<src->w; x++)
+        *(dst_ptr--) = *(src_ptr++);
+
+      /* Add gap between end of line and start of next one */
+      src_ptr += src_gap;
+      dst_ptr += dst_gap;
+    }
+    SDL_SetAlpha(dst, SDL_SRCALPHA, 255);
+  }
+  else if (src->format->BitsPerPixel == 8)
+  {
+    dst = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->w, 8,
+                               src->format->Rmask, src->format->Gmask,
+                               src->format->Bmask, src->format->Amask);
+
+    /* Copying Y => 1 byte at a time - MMX accelaration quite possible */
+    const Uint8  *src_ptr = (Uint8*)src->pixels;
+    const Sint32  src_gap = (Sint32)src->pitch - src->w;
+    Uint8        *dst_ptr = ((Uint8*)dst->pixels)+(Sint32)dst->w-1;
+    const Sint32  dst_gap = dst->pitch + dst->w;
+    
+    for (y=0; y<src->h; y++)
+    {
+      for (x=0; x<src->w; x++)
+        *(dst_ptr--) = *(src_ptr++);
+
+      /* Add gap between end of line and start of next one */
+      src_ptr += src_gap;
+      dst_ptr += dst_gap;
+    }
+
+    SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+  }
+  else
+  {
+    /* Fallback */
+    return RotoZoomXY( 0.0, -1.0, 1.0, SMOOTHING_OFF);
+  }
+  
+  /* Store */
+  newSurf.SetSurface( dst );
+
+  if( newSurf.IsNull() )
+    Error( "Unable to horizontally flip the surface !" );
+
+  return newSurf;	
+}
+
 Surface Surface::RotoZoomXY(double angle, double zoomx, double zoomy, int smooth){
 	Surface newSurf;
 
Index: src/graphic/surface.h
===================================================================
--- src/graphic/surface.h	(révision 406)
+++ src/graphic/surface.h	(copie de travail)
@@ -62,6 +62,7 @@
 			void Unlock();
 			int Blit(SDL_Surface *src, SDL_Rect *srcRect, SDL_Rect *dstRect);
 			int Blit(Surface src, SDL_Rect *srcRect, SDL_Rect *dstRect);
+            Surface HorizontalFlip(void);
 			int SetColorKey(Uint32 flag, Uint32 key);
 			int SetColorKey(Uint32 flag, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 			Uint32 MapRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a);

Répondre à