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);