Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2006:
[Freeciv-Dev] (PR#15472) Borders drawn incorrectly in SDL client
Home

[Freeciv-Dev] (PR#15472) Borders drawn incorrectly in SDL client

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Martin.Gerdes@xxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#15472) Borders drawn incorrectly in SDL client
From: "Christian Prochaska" <cp.ml.freeciv.dev@xxxxxxxxxxxxxx>
Date: Thu, 9 Feb 2006 16:49:39 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=15472 >

> [Martin.Gerdes@xxxxxxxxxxxxx - Mi 08. Feb 2006, 12:45:54]:
> 
> -Popups on mouse hover (e.g. in the diplomacy screen) get drawn
>    _below_ the currently active unit.
>

And here's a patch for this problem. You'll need to run autogen.sh after
applying it.
Index: client/gui-sdl/mapview.c
===================================================================
--- client/gui-sdl/mapview.c    (Revision 11553)
+++ client/gui-sdl/mapview.c    (Arbeitskopie)
@@ -54,6 +54,7 @@
 #include "mapview.h"
 
 extern SDL_Event *pFlush_User_Event;
+extern SDL_Rect *pInfo_Area;
 
 int OVERVIEW_START_X;
 int OVERVIEW_START_Y;
@@ -235,7 +236,7 @@
       SDL_BlitSurface(Main.map, &Main.rects[i], Main.screen, &dst);
       dst = Main.rects[i];
       SDL_BlitSurface(Main.gui, &Main.rects[i], Main.screen, &dst);
-      
+
       if (Main.guis) {
         while((j < Main.guis_count) && Main.guis[j]) {
           dst = Main.rects[i];
@@ -243,6 +244,16 @@
         }
       }
       j = 0;
+      
+      /* restore widget info label if it overlaps with this area */
+      if (pInfo_Area && !(((dst.x + dst.w) < pInfo_Area->x)
+                          || (dst.x > (pInfo_Area->x + pInfo_Area->w)) 
+                          || ((dst.y + dst.h) < pInfo_Area->y) 
+                          || (dst.y > (pInfo_Area->y + pInfo_Area->h)))) {
+                            
+        redraw_widget_info_label(&dst);     
+      }
+      
     }
     /* flush main buffer to framebuffer */    
     SDL_UpdateRects(Main.screen, Main.rects_count, Main.rects);
Index: client/gui-sdl/gui_main.c
===================================================================
--- client/gui-sdl/gui_main.c   (Revision 11553)
+++ client/gui-sdl/gui_main.c   (Arbeitskopie)
@@ -603,6 +603,11 @@
     /* ========================================= */
     
     t2 = SDL_GetTicks();
+    
+    if (t2 > real_timer_next_call) {
+      real_timer_next_call = t2 + (real_timer_callback() * 1000);
+    }
+    
     if ((t2 - t1) > UNITS_TIMER_INTERVAL) {
       if (widget_info_counter || autoconnect) {
         if(widget_info_counter > 8) {
@@ -624,10 +629,6 @@
       t1 = SDL_GetTicks();
     }
     
-    if (t2 > real_timer_next_call) {
-      real_timer_next_call = t2 + (real_timer_callback() * 1000);
-    }
-      
     /* ========================================= */
     
     if(loop_action) {
Index: client/gui-sdl/gui_stuff.c
===================================================================
--- client/gui-sdl/gui_stuff.c  (Revision 11553)
+++ client/gui-sdl/gui_stuff.c  (Arbeitskopie)
@@ -40,6 +40,8 @@
 #include "gui_stuff.h"
 
 struct GUI *pSellected_Widget;
+SDL_Rect *pInfo_Area = NULL;
+SDL_Surface *pInfo_Label = NULL;
 
 extern Uint32 widget_info_counter;
 
@@ -72,7 +74,6 @@
   int step;
 };
 
-static SDL_Rect *pInfo_Area = NULL;
 static SDL_Surface *pLocked_buffer = NULL;
 
 static struct GUI *pBeginMainWidgetList;
@@ -376,6 +377,7 @@
   if (pInfo_Area) {
     sdl_dirty_rect(*pInfo_Area);
     FC_FREE(pInfo_Area);
+    FREESURFACE(pInfo_Label);
   }
   
   switch (get_wtype(pWidget)) {
@@ -583,6 +585,7 @@
   if (pInfo_Area) {
     flush_rect(*pInfo_Area);
     FC_FREE(pInfo_Area);
+    FREESURFACE(pInfo_Label);    
   }
 
   pSellected_Widget = NULL;
@@ -652,10 +655,10 @@
 /**************************************************************************
   ...
 **************************************************************************/
-void draw_widget_info_label(void)
+void redraw_widget_info_label(SDL_Rect *rect)
 {
   SDL_Surface *pText, *pBcgd;
-  SDL_Rect dest;
+  SDL_Rect srcrect, dstrect;
   SDL_Color color;
 
   struct GUI *pWidget = pSellected_Widget;
@@ -664,83 +667,92 @@
     return;
   }
 
-  pInfo_Area = fc_calloc(1, sizeof(SDL_Rect));
+  if (!pInfo_Label) {
+  
+    pInfo_Area = fc_calloc(1, sizeof(SDL_Rect));
+  
+    /*pWidget->string16->render = 3;*/
+    
+    color = pWidget->string16->fgcol;
+    pWidget->string16->style |= TTF_STYLE_BOLD;
+    pWidget->string16->fgcol.r = 255;
+    pWidget->string16->fgcol.g = 255;
+    pWidget->string16->fgcol.b = 255;
+    
+    /* create string and bcgd theme */
+    pText = create_text_surf_from_str16(pWidget->string16);
 
-  /*pWidget->string16->render = 3;*/
+    pWidget->string16->fgcol = color;
+    
+    color = *get_game_colorRGB(COLOR_THEME_QUICK_INFO);
+    color.unused = 150;
   
-  color = pWidget->string16->fgcol;
-  pWidget->string16->style |= TTF_STYLE_BOLD;
-  pWidget->string16->fgcol.r = 255;
-  pWidget->string16->fgcol.g = 255;
-  pWidget->string16->fgcol.b = 255;
+    pBcgd = create_filled_surface(pText->w + adj_size(10), pText->h + 
adj_size(6), SDL_SWSURFACE,
+                                  get_game_colorRGB(COLOR_THEME_QUICK_INFO));
+                                  
+    /* calculate start position */
+    if (pWidget->size.y - pBcgd->h - adj_size(6) < 0) {
+      pInfo_Area->y = pWidget->size.y + pWidget->size.h + adj_size(3);
+    } else {
+      pInfo_Area->y = pWidget->size.y - pBcgd->h - adj_size(5);
+    }
   
-  /* create string and bcgd theme */
-  pText = create_text_surf_from_str16(pWidget->string16);
-  /*SDL_SetAlpha(pText, 0x0, 0x0);*/
-  pWidget->string16->fgcol = color;
+    if (pWidget->size.x + pBcgd->w + adj_size(5) > Main.screen->w) {
+      pInfo_Area->x = pWidget->size.x - pBcgd->w - adj_size(5);
+    } else {
+      pInfo_Area->x = pWidget->size.x + adj_size(3);
+    }
   
-  color = *get_game_colorRGB(COLOR_THEME_QUICK_INFO);
-  color.unused = 150;
+    pInfo_Area->w = pBcgd->w + adj_size(2);
+    pInfo_Area->h = pBcgd->h + adj_size(2);
 
+    pInfo_Label = SDL_DisplayFormatAlpha(pBcgd);
+    
+    FREESURFACE(pBcgd);
+    
+    /* draw theme and text */
+    dstrect.x = 6;
+    dstrect.y = 4;
+    
+    alphablit(pText, NULL, pInfo_Label, &dstrect);
+    
+    FREESURFACE(pText);    
+    
+    /* draw frame */
+    putline(pInfo_Label, 1, 0,
+            pInfo_Area->w - adj_size(2), 0, 0x0);
+  
+    putline(pInfo_Label, 0, 1,
+            0, pInfo_Area->h - adj_size(2), 0x0);
+  
+    putline(pInfo_Label, 1, pInfo_Area->h - adj_size(2),
+            pInfo_Area->w - adj_size(2),
+            pInfo_Area->h - adj_size(2), 0x0);
+  
+    putline(pInfo_Label, pInfo_Area->w - 1, 1,
+            pInfo_Area->w - 1,
+            pInfo_Area->h - adj_size(2), 0x0);
+  }
 
-  pBcgd = create_filled_surface(pText->w + adj_size(10), pText->h + 
adj_size(6), SDL_SWSURFACE,
-                               get_game_colorRGB(COLOR_THEME_QUICK_INFO));
+  if (rect) {
+    dstrect.x = MAX(rect->x, pInfo_Area->x);
+    dstrect.y = MAX(rect->y, pInfo_Area->y);
+    
+    srcrect.x = dstrect.x - pInfo_Area->x;
+    srcrect.y = dstrect.y - pInfo_Area->y;
+    srcrect.w = MIN((pInfo_Area->x + pInfo_Area->w), (rect->x + rect->w)) - 
dstrect.x;
+    srcrect.h = MIN((pInfo_Area->y + pInfo_Area->h), (rect->y + rect->h)) - 
dstrect.y;
 
-
-  /* callculate start position */
-  if (pWidget->size.y - pBcgd->h - adj_size(6) < 0) {
-    pInfo_Area->y = pWidget->size.y + pWidget->size.h + adj_size(3);
+    SDL_BlitSurface(pInfo_Label, &srcrect, Main.screen, &dstrect);
   } else {
-    pInfo_Area->y = pWidget->size.y - pBcgd->h - adj_size(5);
+    SDL_BlitSurface(pInfo_Label, NULL, Main.screen, pInfo_Area);
   }
 
-  if (pWidget->size.x + pBcgd->w + adj_size(5) > Main.screen->w) {
-    pInfo_Area->x = pWidget->size.x - pBcgd->w - adj_size(5);
-  } else {
-    pInfo_Area->x = pWidget->size.x + adj_size(3);
-  }
-
-  pInfo_Area->w = pBcgd->w + adj_size(2);
-  pInfo_Area->h = pBcgd->h + adj_size(2);
-  
-  /* draw theme and text */
-  dest = *pInfo_Area;
-  dest.x += 1;
-  dest.y += 1;
-  SDL_BlitSurface(pBcgd, NULL, Main.screen, &dest);
-  /*
-  SDL_FillRect(Main.gui, &dest , 
-     SDL_MapRGBA(Main.gui->format, color.r, color.g, color.b, color.unused));
-  */
-  dest.x += adj_size(5);
-  dest.y += adj_size(3);
-  SDL_BlitSurface(pText, NULL, Main.screen, &dest);
-
-  /* draw frame */
-  putline(Main.screen, pInfo_Area->x + 1, pInfo_Area->y,
-         pInfo_Area->x + pInfo_Area->w - adj_size(2), pInfo_Area->y, 0x0);
-
-  putline(Main.screen, pInfo_Area->x, pInfo_Area->y + 1,
-         pInfo_Area->x, pInfo_Area->y + pInfo_Area->h - adj_size(2), 0x0);
-
-  putline(Main.screen, pInfo_Area->x + 1, pInfo_Area->y + pInfo_Area->h - 
adj_size(2),
-         pInfo_Area->x + pInfo_Area->w - adj_size(2),
-         pInfo_Area->y + pInfo_Area->h - adj_size(2), 0x0);
-
-  putline(Main.screen, pInfo_Area->x + pInfo_Area->w - 1, pInfo_Area->y + 1,
-         pInfo_Area->x + pInfo_Area->w - 1,
-         pInfo_Area->y + pInfo_Area->h - adj_size(2), 0x0);
-
-
-  /*flush_rect(*pInfo_Area);*/
   if (correct_rect_region(pInfo_Area)) {
     SDL_UpdateRect(Main.screen, pInfo_Area->x, pInfo_Area->y,
                                    pInfo_Area->w, pInfo_Area->h);
   }
-
-  FREESURFACE(pText);
-  FREESURFACE(pBcgd);
-
+  
   return;
 }
 
Index: client/gui-sdl/alphablit.c
===================================================================
--- client/gui-sdl/alphablit.c  (Revision 0)
+++ client/gui-sdl/alphablit.c  (Revision 0)
@@ -0,0 +1,449 @@
+/*
+    pygame - Python Game Library
+    Copyright (C) 2000-2001  Pete Shinners
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Pete Shinners
+    pete@xxxxxxxxxxxx
+*/
+
+#include <SDL.h>
+
+int pygame_AlphaBlit (SDL_Surface *src, SDL_Rect *srcrect,
+                   SDL_Surface *dst, SDL_Rect *dstrect);
+
+/* The structure passed to the low level blit functions */
+typedef struct {
+        Uint8 *s_pixels;
+        int s_width;
+        int s_height;
+        int s_skip;
+        Uint8 *d_pixels;
+        int d_width;
+        int d_height;
+        int d_skip;
+        void *aux_data;
+        SDL_PixelFormat *src;
+        Uint8 *table;
+        SDL_PixelFormat *dst;
+} SDL_BlitInfo;
+static void alphablit_alpha(SDL_BlitInfo *info);
+static void alphablit_colorkey(SDL_BlitInfo *info);
+static void alphablit_solid(SDL_BlitInfo *info);
+static int SoftBlitAlpha(SDL_Surface *src, SDL_Rect *srcrect,
+                        SDL_Surface *dst, SDL_Rect *dstrect);
+extern int SDL_RLESurface(SDL_Surface *surface);
+extern void SDL_UnRLESurface(SDL_Surface *surface, int recode);
+
+
+
+/*we assume the "dst" has pixel alpha*/
+
+int pygame_AlphaBlit (SDL_Surface *src, SDL_Rect *srcrect,
+                   SDL_Surface *dst, SDL_Rect *dstrect)
+{
+        SDL_Rect fulldst;
+        int srcx, srcy, w, h;
+
+        /* Make sure the surfaces aren't locked */
+        if ( ! src || ! dst ) {
+                SDL_SetError("SDL_UpperBlit: passed a NULL surface");
+                return(-1);
+        }
+        if ( src->locked || dst->locked ) {
+                SDL_SetError("Surfaces must not be locked during blit");
+                return(-1);
+        }
+
+        /* If the destination rectangle is NULL, use the entire dest surface */
+        if ( dstrect == NULL ) {
+                fulldst.x = fulldst.y = 0;
+                dstrect = &fulldst;
+        }
+
+        /* clip the source rectangle to the source surface */
+        if(srcrect) {
+                int maxw, maxh;
+
+                srcx = srcrect->x;
+                w = srcrect->w;
+                if(srcx < 0) {
+                        w += srcx;
+                        dstrect->x -= srcx;
+                        srcx = 0;
+                }
+                maxw = src->w - srcx;
+                if(maxw < w)
+                        w = maxw;
+
+                srcy = srcrect->y;
+                h = srcrect->h;
+                if(srcy < 0) {
+                        h += srcy;
+                        dstrect->y -= srcy;
+                        srcy = 0;
+                }
+                maxh = src->h - srcy;
+                if(maxh < h)
+                        h = maxh;
+
+        } else {
+                srcx = srcy = 0;
+                w = src->w;
+                h = src->h;
+        }
+
+        /* clip the destination rectangle against the clip rectangle */
+        {
+                SDL_Rect *clip = &dst->clip_rect;
+                int dx, dy;
+
+                dx = clip->x - dstrect->x;
+                if(dx > 0) {
+                        w -= dx;
+                        dstrect->x += dx;
+                        srcx += dx;
+                }
+                dx = dstrect->x + w - clip->x - clip->w;
+                if(dx > 0)
+                        w -= dx;
+
+                dy = clip->y - dstrect->y;
+                if(dy > 0) {
+                        h -= dy;
+                        dstrect->y += dy;
+                        srcy += dy;
+                }
+                dy = dstrect->y + h - clip->y - clip->h;
+                if(dy > 0)
+                        h -= dy;
+        }
+
+        if(w > 0 && h > 0) {
+                SDL_Rect sr;
+                sr.x = srcx;
+                sr.y = srcy;
+                sr.w = dstrect->w = w;
+                sr.h = dstrect->h = h;
+                return SoftBlitAlpha(src, &sr, dst, dstrect);
+        }
+        dstrect->w = dstrect->h = 0;
+        return 0;
+}
+
+static int SoftBlitAlpha(SDL_Surface *src, SDL_Rect *srcrect,
+                        SDL_Surface *dst, SDL_Rect *dstrect)
+{
+        int okay;
+        int src_locked;
+        int dst_locked;
+
+    /* Everything is okay at the beginning...  */
+        okay = 1;
+
+        /* Lock the destination if it's in hardware */
+        dst_locked = 0;
+        if ( SDL_MUSTLOCK(dst) ) {
+                if ( SDL_LockSurface(dst) < 0 )
+                        okay = 0;
+                else
+                        dst_locked = 1;
+        }
+        /* Lock the source if it's in hardware */
+        src_locked = 0;
+        if ( SDL_MUSTLOCK(src) ) {
+                if ( SDL_LockSurface(src) < 0 )
+                        okay = 0;
+                else
+                        src_locked = 1;
+        }
+
+        /* Set up source and destination buffer pointers, and BLIT! */
+        if ( okay  && srcrect->w && srcrect->h ) {
+                SDL_BlitInfo info;
+
+                /* Set up the blit information */
+                info.s_pixels = (Uint8 *)src->pixels + src->offset +
+                                (Uint16)srcrect->y*src->pitch +
+                                (Uint16)srcrect->x*src->format->BytesPerPixel;
+                info.s_width = srcrect->w;
+                info.s_height = srcrect->h;
+                info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel;
+                info.d_pixels = (Uint8 *)dst->pixels + dst->offset +
+                                (Uint16)dstrect->y*dst->pitch +
+                                (Uint16)dstrect->x*dst->format->BytesPerPixel;
+                info.d_width = dstrect->w;
+                info.d_height = dstrect->h;
+                info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel;
+                info.src = src->format;
+                info.dst = dst->format;
+
+                if(src->flags&SDL_SRCALPHA && src->format->Amask)
+                    alphablit_alpha(&info);
+                else if(src->flags & SDL_SRCCOLORKEY)
+                    alphablit_colorkey(&info);
+                else
+                    alphablit_solid(&info);
+        }
+
+        /* We need to unlock the surfaces if they're locked */
+        if ( dst_locked )
+                SDL_UnlockSurface(dst);
+        if ( src_locked )
+                SDL_UnlockSurface(src);
+        /* Blit is done! */
+        return(okay ? 0 : -1);
+}
+
+
+#define GET_PIXEL(buf, bpp, fmt, pixel)                    \
+do {                                                                       \
+        switch (bpp) {                                                         
  \
+                case 1:                                                        
   \
+                        pixel = *((Uint8 *)(buf));                           \
+                break;                                                       \
+                case 2:                                                        
   \
+                        pixel = *((Uint16 *)(buf));                           \
+                break;                                                         
  \
+                case 4:                                                        
   \
+                        pixel = *((Uint32 *)(buf));                           \
+                break;                                                         
  \
+                default:        {/* case 3: FIXME: broken code (no alpha) */   
                \
+                        Uint8 *b = (Uint8 *)buf;                           \
+                        if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {                  
 \
+                                pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
+                        } else {                                           \
+                                pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
+                        }                                                   \
+                }                                                           \
+                break;                                                         
  \
+        }                                                                   \
+} while(0)
+
+
+#define DISEMBLE_RGBA(buf, bpp, fmt, pixel, R, G, B, A)                    \
+do {                                                                       \
+        if(bpp==1){\
+            pixel = *((Uint8 *)(buf));                           \
+            R = fmt->palette->colors[pixel].r; \
+            G = fmt->palette->colors[pixel].g; \
+            B = fmt->palette->colors[pixel].b; \
+            A = 255; \
+        } else { \
+        switch (bpp) {                                                         
  \
+                case 2:                                                        
   \
+                        pixel = *((Uint16 *)(buf));                           \
+                break;                                                         
  \
+                case 4:                                                        
   \
+                        pixel = *((Uint32 *)(buf));                           \
+                break;                                                         
  \
+                default:        {/* case 3: FIXME: broken code (no alpha) */   
                \
+                        Uint8 *b = (Uint8 *)buf;                           \
+                        if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {                  
 \
+                                pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
+                        } else {                                           \
+                                pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
+                        }                                                   \
+                }                                                           \
+                break;                                                         
  \
+            }                                                                  
 \
+            R = ((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss;                 
\
+            G = ((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss;                 
\
+            B = ((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss;                 
\
+            A = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;                 
\
+        }\
+} while(0)
+
+#define PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a)                         \
+{                                                                       \
+        pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|                                
\
+                ((g>>fmt->Gloss)<<fmt->Gshift)|                                
\
+                ((b>>fmt->Bloss)<<fmt->Bshift)|                                
\
+                ((a<<fmt->Aloss)<<fmt->Ashift);                                
\
+}
+#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)                        \
+{                                                                       \
+        switch (bpp) {                                                        \
+                case 2: {                                                \
+                        Uint16 pixel;                                        \
+                        PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);        \
+                        *((Uint16 *)(buf)) = pixel;                        \
+                }                                                        \
+                break;                                                        \
+                case 4: {                                                \
+                        Uint32 pixel;                                        \
+                        PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);        \
+                        *((Uint32 *)(buf)) = pixel;                        \
+                }                                                        \
+                break;                                                        \
+        }                                                                \
+}
+
+#if 0
+#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA)  \
+do {                                            \
+        dR = (((sR-dR)*(sA))>>8)+dR;                \
+        dG = (((sG-dG)*(sA))>>8)+dG;                \
+        dB = (((sB-dB)*(sA))>>8)+dB;                \
+        dA = sA+dA - ((sA*dA)/255);                \
+} while(0)
+#else
+#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA)  \
+do {   if(dA){\
+        dR = ( ((255-sA)*dR ) + ((sR*sA)) ) >> 8;                \
+        dG = ( ((255-sA)*dG ) + ((sG*sA)) ) >> 8;                \
+        dB = ( ((255-sA)*dB ) + ((sB*sA)) ) >> 8;                \
+        dA = sA+dA - ((sA*dA)/255);                \
+    }else{\
+        dR = sR;                \
+        dG = sG;                \
+        dB = sB;                \
+        dA = sA;               \
+    }\
+} while(0)
+#endif
+
+#if 0
+/* a sad tale of many other blending techniques that didn't fly */
+    if(0&&dA){\
+        dR = (((255-sA)*(dR<<8)/dA)) + (sR>>8) ) >> 8;                \
+        dG = (((255-sA)*(dG<<8)/dA)) + (sG>>8) ) >> 8;                \
+        dB = (((255-sA)*(dB<<8)/dA)) + (sB>>8) ) >> 8;                \
+        dA = sA+dA - ((sA*dA)>>8);               \
+    }else{\
+        dR = 255;                \
+        dG = 0;                \
+        dB = 255;                \
+        dA = 255;               \
+    }\
+
+
+        int temp; \
+        temp = (((sR-dR)*(sA))>>8)+dR; dR = (((sR-temp)*(255-dA))>>8)+temp; \
+        temp = (((sG-dG)*(sA))>>8)+dG; dG = (((sG-temp)*(255-dA))>>8)+temp; \
+        temp = (((sB-dB)*(sA))>>8)+dB; dB = (((sB-temp)*(255-dA))>>8)+temp; \
+
+        temp = (((sR-dR)*(sA))>>8)+dR; dR = (((temp-sR)*dA)>>8)+sR; \
+        temp = (((sG-dG)*(sA))>>8)+dG; dG = (((temp-sG)*dA)>>8)+sG; \
+        temp = (((sB-dB)*(sA))>>8)+dB; dB = (((temp-sB)*dA)>>8)+sB; \
+
+        dR = (((dR - sR) * (255-sA) * dA) >> 16) + (sR*sA)>>8);
+        dG = (((dG - sG) * (255-sA) * dA) >> 16) + (sG*sA)>>8);
+        dB = (((dB - sB) * (255-sA) * dA) >> 16) + (sB*sA)>>8);
+#endif
+
+
+
+static void alphablit_alpha(SDL_BlitInfo *info)
+{
+        int n;
+        int width = info->d_width;
+        int height = info->d_height;
+        Uint8 *src = info->s_pixels;
+        int srcskip = info->s_skip;
+        Uint8 *dst = info->d_pixels;
+        int dstskip = info->d_skip;
+        SDL_PixelFormat *srcfmt = info->src;
+        SDL_PixelFormat *dstfmt = info->dst;
+        int srcbpp = srcfmt->BytesPerPixel;
+        int dstbpp = dstfmt->BytesPerPixel;
+        int dR, dG, dB, dA, sR, sG, sB, sA;
+
+        while ( height-- )
+        {
+            for(n=width; n>0; --n)
+            {
+                Uint32 pixel;
+                DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
+                DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+                ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA);
+                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+                src += srcbpp;
+                dst += dstbpp;
+            }
+            src += srcskip;
+            dst += dstskip;
+        }
+}
+
+static void alphablit_colorkey(SDL_BlitInfo *info)
+{
+        int n;
+        int width = info->d_width;
+        int height = info->d_height;
+        Uint8 *src = info->s_pixels;
+        int srcskip = info->s_skip;
+        Uint8 *dst = info->d_pixels;
+        int dstskip = info->d_skip;
+        SDL_PixelFormat *srcfmt = info->src;
+        SDL_PixelFormat *dstfmt = info->dst;
+        int srcbpp = srcfmt->BytesPerPixel;
+        int dstbpp = dstfmt->BytesPerPixel;
+        int dR, dG, dB, dA, sR, sG, sB, sA;
+        int alpha = srcfmt->alpha;
+        Uint32 colorkey = srcfmt->colorkey;
+
+        while ( height-- )
+        {
+            for(n=width; n>0; --n)
+            {
+                Uint32 pixel;
+                DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+                DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
+                sA = (pixel == colorkey) ? 0 : alpha;
+                ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA);
+                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+                src += srcbpp;
+                dst += dstbpp;
+            }
+            src += srcskip;
+            dst += dstskip;
+        }
+}
+
+
+static void alphablit_solid(SDL_BlitInfo *info)
+{
+        int n;
+        int width = info->d_width;
+        int height = info->d_height;
+        Uint8 *src = info->s_pixels;
+        int srcskip = info->s_skip;
+        Uint8 *dst = info->d_pixels;
+        int dstskip = info->d_skip;
+        SDL_PixelFormat *srcfmt = info->src;
+        SDL_PixelFormat *dstfmt = info->dst;
+        int srcbpp = srcfmt->BytesPerPixel;
+        int dstbpp = dstfmt->BytesPerPixel;
+        int dR, dG, dB, dA, sR, sG, sB, sA;
+        int alpha = srcfmt->alpha;
+
+        while ( height-- )
+        {
+            for(n=width; n>0; --n)
+            {
+                int pixel;
+                DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+                DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
+                ALPHA_BLEND(sR, sG, sB, alpha, dR, dG, dB, dA);
+                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+                src += srcbpp;
+                dst += dstbpp;
+            }
+            src += srcskip;
+            dst += dstskip;
+        }
+}
Index: client/gui-sdl/gui_stuff.h
===================================================================
--- client/gui-sdl/gui_stuff.h  (Revision 11553)
+++ client/gui-sdl/gui_stuff.h  (Arbeitskopie)
@@ -233,8 +233,10 @@
 Uint16 widget_pressed_action(struct GUI *pWidget);
 
 void unsellect_widget_action(void);
-void draw_widget_info_label(void);
 
+#define draw_widget_info_label() redraw_widget_info_label(NULL);
+void redraw_widget_info_label(SDL_Rect *area);
+
 /* Group */
 Uint16 redraw_group(const struct GUI *pBeginGroupWidgetList,
                    const struct GUI *pEndGroupWidgetList,
Index: client/gui-sdl/graphics.c
===================================================================
--- client/gui-sdl/graphics.c   (Revision 11553)
+++ client/gui-sdl/graphics.c   (Arbeitskopie)
@@ -64,6 +64,23 @@
 
 /* ============ FreeCiv sdl graphics function =========== */
 
+#ifdef USE_ALPHABLIT
+int alphablit(SDL_Surface *src, SDL_Rect *srcrect, 
+              SDL_Surface *dst, SDL_Rect *dstrect) {
+
+  if (!(src && dst)) {
+    return 0;
+  }
+
+  /* use for RGBA->RGBA blits only */  
+  if (src->format->Amask && dst->format->Amask) {
+    return pygame_AlphaBlit(src, srcrect, dst, dstrect);
+  } else {
+    return SDL_BlitSurface(src, srcrect, dst, dstrect);
+  }   
+}
+#endif
+
 /**************************************************************************
   Create new surface (pRect->w x pRect->h size) and copy pRect area of
   pSource.
Index: client/gui-sdl/graphics.h
===================================================================
--- client/gui-sdl/graphics.h   (Revision 11553)
+++ client/gui-sdl/graphics.h   (Arbeitskopie)
@@ -29,6 +29,8 @@
 #include "canvas.h"
 #include "gui_main.h"
 
+#define USE_ALPHABLIT
+
 #define        RECT_LIMIT      80
 /* #define     HAVE_MMX1 */
 
@@ -192,6 +194,15 @@
   SDL_Event event;             /* main event struct */
 };
 
+#ifdef USE_ALPHABLIT
+int pygame_AlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, 
+                     SDL_Surface *dst, SDL_Rect *dstrect);
+int alphablit(SDL_Surface *src, SDL_Rect *srcrect, 
+              SDL_Surface *dst, SDL_Rect *dstrect);
+#else
+#define alphablit SDL_BlitSurface
+#endif
+
 SDL_Surface *load_surf(const char *pFname);
 SDL_Surface *load_surf_with_flags(const char *pFname, int iFlags);
 
Index: client/gui-sdl/Makefile.am
===================================================================
--- client/gui-sdl/Makefile.am  (Revision 11553)
+++ client/gui-sdl/Makefile.am  (Arbeitskopie)
@@ -24,6 +24,7 @@
        Freeciv.h       \
        SDL_ttf.c       \
        SDL_ttf.h       \
+       alphablit.c     \
        canvas.c        \
        canvas.h        \
        chatline.c      \

[Prev in Thread] Current Thread [Next in Thread]