From a9e8a4cac51cb2856f339d84bab5e07e8be75037 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 19 Nov 2023 12:27:57 +0100 Subject: [PATCH] added support for setting alpha value for global animations 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 | 2 ++ src/conf_gfx.c | 1 + src/init.c | 3 +++ src/libgame/sdl.c | 49 +++++++++++++++++++++++++++++++++++++++++++- src/libgame/sdl.h | 4 ++++ src/libgame/system.c | 16 ++++++++++++++- src/libgame/system.h | 1 + src/main.h | 2 ++ 8 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/anim.c b/src/anim.c index 222369e1..5967bb73 100644 --- a/src/anim.c +++ b/src/anim.c @@ -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); diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 73eb60db..31b17a70 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -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 }, diff --git a/src/init.c b/src/init.c index e96344eb..33c47f98 100644 --- a/src/init.c +++ b/src/init.c @@ -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]; diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 59fe7c3d..64d28bdb 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -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); } diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index f279ebc4..31de93da 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -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; diff --git a/src/libgame/system.c b/src/libgame/system.c index a3eae882..2f21541d 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -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) diff --git a/src/libgame/system.h b/src/libgame/system.h index b2f95e35..e5938dee 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -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, diff --git a/src/main.h b/src/main.h index 8cc19c8f..228ca5a6 100644 --- a/src/main.h +++ b/src/main.h @@ -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; -- 2.34.1