added support for setting alpha value for global animations
authorHolger Schemel <info@artsoft.org>
Sun, 19 Nov 2023 11:27:57 +0000 (12:27 +0100)
committerHolger Schemel <info@artsoft.org>
Sun, 19 Nov 2023 13:20:22 +0000 (14:20 +0100)
To set alpha value for global animation graphics, just use the new
attribute ".alpha" for the global animation's graphics definition,
where the value "0" means transparent and "255" means "opaque".

src/anim.c
src/conf_gfx.c
src/init.c
src/libgame/sdl.c
src/libgame/sdl.h
src/libgame/system.c
src/libgame/system.h
src/main.h

index 222369e1abb3b0c364e6198dfae4f23bae4256b8..5967bb735525e288e93621c3379ff248c2af75d1 100644 (file)
@@ -781,6 +781,8 @@ static void BlitGlobalAnimation(struct GlobalAnimPartControlInfo *part,
       dst_x += part->viewport_x;
       dst_y += part->viewport_y;
 
+      SetBitmapAlphaNextBlit(src_bitmap, g->alpha);
+
       if (drawing_target == DRAW_TO_SCREEN)
        blit_screen(src_bitmap, src_x, src_y, width, height,
                    dst_x, dst_y);
index 73eb60dbcd3f70232e43956a874275bf086e9139..31b17a70836e48ddd1f190bd6a21ba986e02a5fb 100644 (file)
@@ -82,6 +82,7 @@ struct ConfigTypeInfo image_config_suffix[] =
   { ".sort_priority",                  ARG_UNDEFINED,  TYPE_INTEGER    },
   { ".class",                          ARG_UNDEFINED,  TYPE_STRING     },
   { ".style",                          ARG_UNDEFINED,  TYPE_STRING     },
+  { ".alpha",                          ARG_UNDEFINED,  TYPE_INTEGER    },
   { ".active_xoffset",                 "0",            TYPE_INTEGER    },
   { ".active_yoffset",                 "0",            TYPE_INTEGER    },
   { ".pressed_xoffset",                        "0",            TYPE_INTEGER    },
index e96344eb51caf8da240895cc395e18bc1b096e16..33c47f98e9c423f7c056b7d74a53ded8173e8826 100644 (file)
@@ -1412,6 +1412,7 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->sort_priority = 0;                        // default for title screens
   g->class = 0;
   g->style = STYLE_DEFAULT;
+  g->alpha = -1;
 
   g->bitmaps = src_bitmaps;
   g->bitmap = src_bitmap;
@@ -1686,6 +1687,8 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
     g->class = parameter[GFX_ARG_CLASS];
   if (parameter[GFX_ARG_STYLE] != ARG_UNDEFINED_VALUE)
     g->style = parameter[GFX_ARG_STYLE];
+  if (parameter[GFX_ARG_ALPHA] != ARG_UNDEFINED_VALUE)
+    g->alpha = parameter[GFX_ARG_ALPHA];
 
   // this is only used for drawing menu buttons and text
   g->active_xoffset = parameter[GFX_ARG_ACTIVE_XOFFSET];
index 59fe7c3df988d35d5a7269041c2c83e2c0745e30..64d28bdbb6fb5c17243947b6d81899324a2c32d2 100644 (file)
@@ -351,7 +351,7 @@ static boolean SDLHasAlpha(SDL_Surface *surface)
   return (blend_mode == SDL_BLENDMODE_BLEND);
 }
 
-void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+static void SDLSetSurfaceAlpha(SDL_Surface *surface, boolean set, int alpha)
 {
   SDL_BlendMode blend_mode = (set ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
 
@@ -359,6 +359,49 @@ void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
   SDL_SetSurfaceAlphaMod(surface, alpha);
 }
 
+static void SDLSetTextureAlpha(SDL_Texture *texture, boolean set, int alpha)
+{
+  SDL_BlendMode blend_mode = (set ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
+
+  SDL_SetTextureBlendMode(texture, blend_mode);
+  SDL_SetTextureAlphaMod(texture, alpha);
+}
+
+static void SDLSetBitmapAlpha(Bitmap *bitmap, boolean is_texture,
+                             boolean is_masked)
+{
+  int alpha_next_blit = bitmap->alpha_next_blit;
+
+  // alpha value must be requested every time before blitting, if needed
+  bitmap->alpha_next_blit = -1;
+
+  // nothing to do if requested alpha value is already set
+  if (bitmap->alpha[is_texture][is_masked] == alpha_next_blit)
+    return;
+
+  // store requested alpha value for masked/unmasked surface/texture
+  bitmap->alpha[is_texture][is_masked] = alpha_next_blit;
+
+  // set blend mode if bitmap is masked or if alpha value is defined
+  boolean set_blend_mode = (is_masked || alpha_next_blit != -1);
+
+  // if alpha value is undefined, use default (opaque) alpha value
+  if (alpha_next_blit == -1)
+    alpha_next_blit = SDL_ALPHA_OPAQUE;
+
+  if (is_texture)
+    SDLSetTextureAlpha(is_masked ? bitmap->texture_masked : bitmap->texture,
+                      set_blend_mode, alpha_next_blit);
+  else
+    SDLSetSurfaceAlpha(is_masked ? bitmap->surface_masked : bitmap->surface,
+                      set_blend_mode, alpha_next_blit);
+}
+
+void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+{
+  SDLSetSurfaceAlpha(surface, set, alpha);
+}
+
 const char *SDLGetRendererName(void)
 {
   static SDL_RendererInfo renderer_info;
@@ -986,6 +1029,8 @@ void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
   dst_rect.w = width;
   dst_rect.h = height;
 
+  SDLSetBitmapAlpha(src_bitmap, FALSE, mask_mode == BLIT_MASKED);
+
   // if (src_bitmap != backbuffer || dst_bitmap != window)
   if (!(src_bitmap == backbuffer && dst_bitmap == window))
     SDL_BlitSurface((mask_mode == BLIT_MASKED ?
@@ -1020,6 +1065,8 @@ void SDLBlitTexture(Bitmap *bitmap,
   dst_rect.w = width;
   dst_rect.h = height;
 
+  SDLSetBitmapAlpha(bitmap, TRUE, mask_mode == BLIT_MASKED);
+
   SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect);
 }
 
index f279ebc4121309254fe5149827b1434671c141f6..31de93da084907c5cb7871d98d74433822ee35bf 100644 (file)
@@ -75,6 +75,10 @@ struct SDLSurfaceInfo
   char *source_filename;
 
   int width, height;
+
+  int alpha[2][2];             // [surface|texture][opaque|masked]
+  int alpha_next_blit;
+
   SDL_Surface *surface;
   SDL_Surface *surface_masked;
   SDL_Texture *texture;
index a3eae88217bc14c3ee295acea1f721530c7ecec2..2f21541d8e0419b5c938853082051c8075f550fe 100644 (file)
@@ -601,7 +601,15 @@ void FreeBitmap(Bitmap *bitmap)
 
 Bitmap *CreateBitmapStruct(void)
 {
-  return checked_calloc(sizeof(Bitmap));
+  Bitmap *new_bitmap = checked_calloc(sizeof(Bitmap));
+
+  new_bitmap->alpha[0][0] = -1;
+  new_bitmap->alpha[0][1] = -1;
+  new_bitmap->alpha[1][0] = -1;
+  new_bitmap->alpha[1][1] = -1;
+  new_bitmap->alpha_next_blit = -1;
+
+  return new_bitmap;
 }
 
 Bitmap *CreateBitmap(int width, int height, int depth)
@@ -772,6 +780,12 @@ static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y,
   return TRUE;
 }
 
+void SetBitmapAlphaNextBlit(Bitmap *bitmap, int alpha)
+{
+  // set alpha value for next blitting of bitmap
+  bitmap->alpha_next_blit = alpha;
+}
+
 void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
                int src_x, int src_y, int width, int height,
                int dst_x, int dst_y)
index b2f95e358d73182a3ff53224b821cdc3f2163d2f..e5938dee7772abfe95220ff60f10e3f37781b76e 100644 (file)
@@ -2013,6 +2013,7 @@ Bitmap *CreateBitmapStruct(void);
 Bitmap *CreateBitmap(int, int, int);
 void ReCreateBitmap(Bitmap **, int, int);
 void FreeBitmap(Bitmap *);
+void SetBitmapAlphaNextBlit(Bitmap *, int);
 void BlitBitmap(Bitmap *, Bitmap *, int, int, int, int, int, int);
 void BlitBitmapTiled(Bitmap *, Bitmap *, int, int, int, int, int, int, int, int);
 void FadeRectangle(int, int, int, int, int, int, int,
index 8cc19c8f2d9b12921c02617f0b57988ab775cb0e..228ca5a63b0d6b92f462b95ba6259921e22ae57f 100644 (file)
@@ -2497,6 +2497,7 @@ enum
   GFX_ARG_SORT_PRIORITY,
   GFX_ARG_CLASS,
   GFX_ARG_STYLE,
+  GFX_ARG_ALPHA,
   GFX_ARG_ACTIVE_XOFFSET,
   GFX_ARG_ACTIVE_YOFFSET,
   GFX_ARG_PRESSED_XOFFSET,
@@ -3743,6 +3744,7 @@ struct GraphicInfo
 
   int class;
   int style;
+  int alpha;
 
   int active_xoffset;
   int active_yoffset;