X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=4b44daa1c53d6ce82c6c59f62cc134800b671d61;hp=ebfd6a5c48b279fc7ff84abd233f241b2ade0d9a;hb=b4a4b3e959ada7bae876a4a9d78f534e320a7b41;hpb=ae3b4e39699426588abeb16a6114819652aa2cdb diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index ebfd6a5c..4b44daa1 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -42,19 +42,19 @@ void SDLLimitScreenUpdates(boolean enable) limit_screen_updates = enable; } -static void FinalizeScreen() +static void FinalizeScreen(int draw_target) { // 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); + gfx.draw_global_anim_function(draw_target, 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(DRAW_BORDER_TO_SCREEN); + gfx.draw_global_border_function(draw_target); // 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); + gfx.draw_global_anim_function(draw_target, DRAW_GLOBAL_ANIM_STAGE_2); } static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) @@ -95,7 +95,7 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) BlitBitmap(backbuffer, gfx.final_screen_bitmap, 0, 0, gfx.win_xsize, gfx.win_ysize, 0, 0); - FinalizeScreen(); + FinalizeScreen(DRAW_TO_SCREEN); screen = gfx.final_screen_bitmap->surface; @@ -142,7 +142,7 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) SDL_RenderCopy(sdl_renderer, sdl_texture_stream, NULL, NULL); if (video.screen_rendering_mode != SPECIAL_RENDERING_BITMAP) - FinalizeScreen(); + FinalizeScreen(DRAW_TO_SCREEN); // when using target texture, copy it to screen buffer if (video.screen_rendering_mode == SPECIAL_RENDERING_TARGET || @@ -223,34 +223,7 @@ static boolean equalSDLPixelFormat(SDL_PixelFormat *format1, format1->BytesPerPixel == format2->BytesPerPixel && format1->Rmask == format2->Rmask && format1->Gmask == format2->Gmask && - format1->Bmask == format2->Bmask && - format1->Amask == format2->Amask); -} - -boolean SDLSetNativeSurface(SDL_Surface **surface) -{ - SDL_Surface *new_surface; - - if (surface == NULL || - *surface == NULL || - backbuffer == NULL || - backbuffer->surface == NULL) - return FALSE; - - // if pixel format already optimized for destination surface, do nothing - if (equalSDLPixelFormat((*surface)->format, backbuffer->surface->format)) - return FALSE; - - new_surface = SDL_ConvertSurface(*surface, backbuffer->surface->format, 0); - - if (new_surface == NULL) - Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError()); - - SDL_FreeSurface(*surface); - - *surface = new_surface; - - return TRUE; + format1->Bmask == format2->Bmask); } SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) @@ -279,21 +252,21 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) return new_surface; } -#else - boolean SDLSetNativeSurface(SDL_Surface **surface) { SDL_Surface *new_surface; if (surface == NULL || *surface == NULL || - !video.initialized) + backbuffer == NULL || + backbuffer->surface == NULL) return FALSE; - new_surface = SDL_DisplayFormat(*surface); + // if pixel format already optimized for destination surface, do nothing + if (equalSDLPixelFormat((*surface)->format, backbuffer->surface->format)) + return FALSE; - if (new_surface == NULL) - Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError()); + new_surface = SDLGetNativeSurface(*surface); SDL_FreeSurface(*surface); @@ -302,10 +275,15 @@ boolean SDLSetNativeSurface(SDL_Surface **surface) return TRUE; } +#else + SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) { SDL_Surface *new_surface; + if (surface == NULL) + return NULL; + if (video.initialized) new_surface = SDL_DisplayFormat(surface); else @@ -319,6 +297,24 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface) return new_surface; } +boolean SDLSetNativeSurface(SDL_Surface **surface) +{ + SDL_Surface *new_surface; + + if (surface == NULL || + *surface == NULL || + !video.initialized) + return FALSE; + + new_surface = SDLGetNativeSurface(*surface); + + SDL_FreeSurface(*surface); + + *surface = new_surface; + + return TRUE; +} + #endif #if defined(TARGET_SDL2) @@ -431,7 +427,7 @@ void SDLInitVideoBuffer(boolean fullscreen) should never be drawn to directly, it would do no harm nevertheless. */ /* create additional (symbolic) buffer for double-buffering */ - ReCreateBitmap(&window, video.width, video.height, video.depth); + ReCreateBitmap(&window, video.width, video.height); } static boolean SDLCreateScreen(boolean fullscreen) @@ -908,15 +904,31 @@ void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height, UpdateScreen_WithFrameDelay(&rect); } -void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, +void PrepareFadeBitmap(int draw_target) +{ + Bitmap *fade_bitmap = + (draw_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source : + draw_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL); + + if (fade_bitmap == NULL) + return; + + // copy backbuffer to fading buffer + BlitBitmap(backbuffer, fade_bitmap, 0, 0, gfx.win_xsize, gfx.win_ysize, 0, 0); + + // add border and animations to fading buffer + FinalizeScreen(draw_target); +} + +void SDLFadeRectangle(int x, int y, int width, int height, int fade_mode, int fade_delay, int post_delay, void (*draw_border_function)(void)) { + SDL_Surface *surface_backup = gfx.fade_bitmap_backup->surface; 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; SDL_Rect dst_rect2; int src_x = x, src_y = y; @@ -942,28 +954,24 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, dst_rect2 = dst_rect; + // before fading in, store backbuffer (without animation graphics) + if (fade_mode & (FADE_TYPE_FADE_IN | FADE_TYPE_TRANSFORM)) + SDL_BlitSurface(surface_screen, &dst_rect, surface_backup, &src_rect); + /* copy source and target surfaces to temporary surfaces for fading */ if (fade_mode & FADE_TYPE_TRANSFORM) { - SDL_BlitSurface(surface_cross, &src_rect, surface_source, &src_rect); - SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_BORDER_TO_FADE_SOURCE); - draw_global_border_function(DRAW_BORDER_TO_FADE_TARGET); + // (source and target fading buffer already prepared) } else if (fade_mode & FADE_TYPE_FADE_IN) { + // (target fading buffer already prepared) SDL_BlitSurface(surface_black, &src_rect, surface_source, &src_rect); - SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_BORDER_TO_FADE_TARGET); } else /* FADE_TYPE_FADE_OUT */ { - SDL_BlitSurface(surface_screen, &dst_rect, surface_source, &src_rect); + // (source fading buffer already prepared) SDL_BlitSurface(surface_black, &src_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_BORDER_TO_FADE_SOURCE); } time_current = SDL_GetTicks(); @@ -1198,6 +1206,10 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, // restore function for drawing global masked border gfx.draw_global_border_function = draw_global_border_function; + + // after fading in, restore backbuffer (without animation graphics) + if (fade_mode & (FADE_TYPE_FADE_IN | FADE_TYPE_TRANSFORM)) + SDL_BlitSurface(surface_backup, &dst_rect, surface_screen, &src_rect); } void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y,