static void UpdateScreen(SDL_Rect *rect)
{
static unsigned int update_screen_delay = 0;
- unsigned int update_screen_delay_value = 20; /* (milliseconds) */
+ unsigned int update_screen_delay_value = 50; /* (milliseconds) */
+ SDL_Surface *screen = backbuffer->surface;
if (limit_screen_updates &&
!DelayReached(&update_screen_delay, update_screen_delay_value))
}
#endif
+#if USE_FINAL_SCREEN_BITMAP
+ if (gfx.final_screen_bitmap != NULL) // may not be initialized yet
+ {
+ // !!! TEST !!!
+ // draw global animations using bitmaps instead of using textures
+ // to prevent texture scaling artefacts (this is potentially slower)
+
+ BlitBitmap(backbuffer, gfx.final_screen_bitmap, 0, 0,
+ gfx.win_xsize, gfx.win_ysize, 0, 0);
+
+ // copy global animations to render target buffer, if defined (below border)
+ if (gfx.draw_global_anim_function != NULL)
+ gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_1);
+
+ // copy global masked border to render target buffer, if defined
+ if (gfx.draw_global_border_function != NULL)
+ gfx.draw_global_border_function(REDRAW_ALL);
+
+ // copy global animations to render target buffer, if defined (above border)
+ if (gfx.draw_global_anim_function != NULL)
+ gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_2);
+
+ screen = gfx.final_screen_bitmap->surface;
+
+ // force full window redraw
+ rect = NULL;
+ }
+#endif
+
#if defined(TARGET_SDL2)
#if USE_RENDERER
- SDL_Surface *screen = backbuffer->surface;
-
if (rect)
{
int bytes_x = screen->pitch / video.width;
// copy backbuffer to render target buffer
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
- // copy global animations to render target buffer, if defined
+#if !USE_FINAL_SCREEN_BITMAP
+ // copy global animations to render target buffer, if defined (below border)
+ if (gfx.draw_global_anim_function != NULL)
+ gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_1);
+
+ // copy global masked border to render target buffer, if defined
+ if (gfx.draw_global_border_function != NULL)
+ gfx.draw_global_border_function(REDRAW_ALL);
+
+ // copy global animations to render target buffer, if defined (above border)
if (gfx.draw_global_anim_function != NULL)
- gfx.draw_global_anim_function();
+ gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_2);
+#endif
// show render target buffer on screen
SDL_RenderPresent(sdl_renderer);
#else // TARGET_SDL
if (rect)
- SDL_UpdateRects(backbuffer->surface, 1, rect);
+ SDL_UpdateRects(screen, 1, rect);
else
- SDL_UpdateRect(backbuffer->surface, 0, 0, 0, 0);
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
#endif
}
SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
{
+ SDL_PixelFormat format;
SDL_Surface *new_surface;
if (surface == NULL)
return NULL;
if (backbuffer && backbuffer->surface)
- new_surface = SDL_ConvertSurface(surface, backbuffer->surface->format, 0);
+ {
+ format = *backbuffer->surface->format;
+ format.Amask = surface->format->Amask; // keep alpha channel
+ }
else
- new_surface = SDL_ConvertSurface(surface, surface->format, 0);
+ {
+ format = *surface->format;
+ }
+
+ new_surface = SDL_ConvertSurface(surface, &format, 0);
if (new_surface == NULL)
Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError());
if (bitmap == NULL)
return;
+ if (bitmap->texture)
+ SDL_DestroyTexture(bitmap->texture);
+ if (bitmap->texture_masked)
+ SDL_DestroyTexture(bitmap->texture_masked);
+
bitmap->texture = SDLCreateTextureFromSurface(bitmap->surface);
bitmap->texture_masked = SDLCreateTextureFromSurface(bitmap->surface_masked);
#endif
}
+void SDLFreeBitmapTextures(Bitmap *bitmap)
+{
+#if defined(TARGET_SDL2)
+ if (bitmap == NULL)
+ return;
+
+ if (bitmap->texture)
+ SDL_DestroyTexture(bitmap->texture);
+ if (bitmap->texture_masked)
+ SDL_DestroyTexture(bitmap->texture_masked);
+
+ bitmap->texture = NULL;
+ bitmap->texture_masked = NULL;
+#endif
+}
+
void SDLInitVideoDisplay(void)
{
#if !defined(TARGET_SDL2)
int fade_mode, int fade_delay, int post_delay,
void (*draw_border_function)(void))
{
- static boolean initialization_needed = TRUE;
- static SDL_Surface *surface_source = NULL;
- static SDL_Surface *surface_target = NULL;
- static SDL_Surface *surface_black = NULL;
+ SDL_Surface *surface_source = gfx.fade_bitmap_source->surface;
+ SDL_Surface *surface_target = gfx.fade_bitmap_target->surface;
+ SDL_Surface *surface_black = gfx.fade_bitmap_black->surface;
SDL_Surface *surface_screen = backbuffer->surface;
SDL_Surface *surface_cross = (bitmap_cross ? bitmap_cross->surface : NULL);
SDL_Rect src_rect, dst_rect;
int dst_x = x, dst_y = y;
unsigned int time_last, time_current;
- /* check if screen size has changed */
- if (surface_source != NULL && (video.width != surface_source->w ||
- video.height != surface_source->h))
- {
- SDL_FreeSurface(surface_source);
- SDL_FreeSurface(surface_target);
- SDL_FreeSurface(surface_black);
+ // store function for drawing global masked border
+ void (*draw_global_border_function)(int) = gfx.draw_global_border_function;
- initialization_needed = TRUE;
- }
+ // deactivate drawing of global border while fading, if needed
+ if (draw_border_function == NULL)
+ gfx.draw_global_border_function = NULL;
src_rect.x = src_x;
src_rect.y = src_y;
dst_rect2 = dst_rect;
- if (initialization_needed)
- {
-#if defined(TARGET_SDL2)
- unsigned int flags = 0;
-#else
- unsigned int flags = SDL_SRCALPHA;
-
- /* use same surface type as screen surface */
- if ((surface_screen->flags & SDL_HWSURFACE))
- flags |= SDL_HWSURFACE;
- else
- flags |= SDL_SWSURFACE;
-#endif
-
- /* create surface for temporary copy of screen buffer (source) */
- if ((surface_source =
- SDL_CreateRGBSurface(flags,
- video.width,
- video.height,
- surface_screen->format->BitsPerPixel,
- surface_screen->format->Rmask,
- surface_screen->format->Gmask,
- surface_screen->format->Bmask,
- surface_screen->format->Amask)) == NULL)
- Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
-
- /* create surface for cross-fading screen buffer (target) */
- if ((surface_target =
- SDL_CreateRGBSurface(flags,
- video.width,
- video.height,
- surface_screen->format->BitsPerPixel,
- surface_screen->format->Rmask,
- surface_screen->format->Gmask,
- surface_screen->format->Bmask,
- surface_screen->format->Amask)) == NULL)
- Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
-
- /* create black surface for fading from/to black */
- if ((surface_black =
- SDL_CreateRGBSurface(flags,
- video.width,
- video.height,
- surface_screen->format->BitsPerPixel,
- surface_screen->format->Rmask,
- surface_screen->format->Gmask,
- surface_screen->format->Bmask,
- surface_screen->format->Amask)) == NULL)
- Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
-
- /* completely fill the surface with black color pixels */
- SDL_FillRect(surface_black, NULL,
- SDL_MapRGB(surface_screen->format, 0, 0, 0));
-
- initialization_needed = FALSE;
- }
-
/* copy source and target surfaces to temporary surfaces for fading */
if (fade_mode & FADE_TYPE_TRANSFORM)
{
}
}
- Delay(post_delay);
+ if (post_delay > 0)
+ {
+ unsigned int time_post_delay;
+
+ time_current = SDL_GetTicks();
+ time_post_delay = time_current + post_delay;
+
+ while (time_current < time_post_delay)
+ {
+ // do not wait longer than 10 ms at a time to be able to ...
+ Delay(MIN(10, time_post_delay - time_current));
+
+ // ... continue drawing global animations during post delay
+ UpdateScreen(NULL);
+
+ time_current = SDL_GetTicks();
+ }
+ }
+
+ // restore function for drawing global masked border
+ gfx.draw_global_border_function = draw_global_border_function;
}
void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y,
UPDATE_BUSY_STATE();
/* create native transparent surface for current image */
- SDL_SetColorKey(sdl_image_tmp, SET_TRANSPARENT_PIXEL,
- SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
+ if (sdl_image_tmp->format->Amask == 0)
+ SDL_SetColorKey(sdl_image_tmp, SET_TRANSPARENT_PIXEL,
+ SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
if ((new_bitmap->surface_masked = SDLGetNativeSurface(sdl_image_tmp)) == NULL)
{