+void SDLSetWindowFullscreen(boolean fullscreen)
+{
+ if (sdl_window == NULL)
+ return;
+
+#if USE_DESKTOP_FULLSCREEN
+ int flags = (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+#else
+ int flags = (fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
+#endif
+
+ if (SDL_SetWindowFullscreen(sdl_window, flags) == 0)
+ video.fullscreen_enabled = fullscreen_enabled = fullscreen;
+
+ // if screen size was changed in fullscreen mode, correct desktop window size
+ if (!fullscreen && video.fullscreen_initial)
+ {
+ SDLSetWindowScaling(setup.window_scaling_percent);
+ SDL_SetWindowPosition(sdl_window,
+ SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+
+ video.fullscreen_initial = FALSE;
+ }
+}
+
+void SDLRedrawWindow()
+{
+ UpdateScreen(NULL);
+}
+#endif
+
+void SDLCreateBitmapContent(Bitmap *bitmap, int width, int height,
+ int depth)
+{
+ SDL_Surface *surface =
+ SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth, 0,0,0, 0);
+
+ if (surface == NULL)
+ Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+
+ SDLSetNativeSurface(&surface);
+
+ bitmap->surface = surface;
+}
+
+void SDLFreeBitmapPointers(Bitmap *bitmap)
+{
+ if (bitmap->surface)
+ SDL_FreeSurface(bitmap->surface);
+ if (bitmap->surface_masked)
+ SDL_FreeSurface(bitmap->surface_masked);
+
+ bitmap->surface = NULL;
+ bitmap->surface_masked = NULL;
+
+#if defined(TARGET_SDL2)
+ 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 SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y, int mask_mode)
+{
+ Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
+ SDL_Rect src_rect, dst_rect;
+
+ if (src_bitmap == backbuffer)
+ {
+ src_x += video_xoffset;
+ src_y += video_yoffset;
+ }
+
+ src_rect.x = src_x;
+ src_rect.y = src_y;
+ src_rect.w = width;
+ src_rect.h = height;
+
+ if (dst_bitmap == backbuffer || dst_bitmap == window)
+ {
+ dst_x += video_xoffset;
+ dst_y += video_yoffset;
+ }
+
+ dst_rect.x = dst_x;
+ dst_rect.y = dst_y;
+ dst_rect.w = width;
+ dst_rect.h = height;
+
+ // if (src_bitmap != backbuffer || dst_bitmap != window)
+ if (!(src_bitmap == backbuffer && dst_bitmap == window))
+ SDL_BlitSurface((mask_mode == BLIT_MASKED ?
+ src_bitmap->surface_masked : src_bitmap->surface),
+ &src_rect, real_dst_bitmap->surface, &dst_rect);
+
+#if defined(TARGET_SDL2)
+ if (dst_bitmap == window)
+ {
+ // SDL_UpdateWindowSurface(sdl_window);
+ // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect, 1);
+ UpdateScreen(&dst_rect);
+ }
+#else
+ if (dst_bitmap == window)
+ {
+ // SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+ UpdateScreen(&dst_rect);
+ }
+#endif
+}
+
+void SDLBlitTexture(Bitmap *bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y, int mask_mode)
+{
+#if defined(TARGET_SDL2)
+#if USE_RENDERER
+ SDL_Texture *texture;
+ SDL_Rect src_rect;
+ SDL_Rect dst_rect;
+
+ texture =
+ (mask_mode == BLIT_MASKED ? bitmap->texture_masked : bitmap->texture);
+
+ if (texture == NULL)
+ return;
+
+ src_rect.x = src_x;
+ src_rect.y = src_y;
+ src_rect.w = width;
+ src_rect.h = height;
+
+ dst_rect.x = dst_x;
+ dst_rect.y = dst_y;
+ dst_rect.w = width;
+ dst_rect.h = height;
+
+ SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect);
+#endif
+#endif
+}
+
+void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height,
+ Uint32 color)
+{
+ Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
+ SDL_Rect rect;
+
+ if (dst_bitmap == backbuffer || dst_bitmap == window)
+ {
+ x += video_xoffset;
+ y += video_yoffset;
+ }
+
+ rect.x = x;
+ rect.y = y;
+ rect.w = width;
+ rect.h = height;
+
+ SDL_FillRect(real_dst_bitmap->surface, &rect, color);
+
+#if defined(TARGET_SDL2)
+ if (dst_bitmap == window)
+ {
+ // SDL_UpdateWindowSurface(sdl_window);
+ // SDL_UpdateWindowSurfaceRects(sdl_window, &rect, 1);
+ UpdateScreen(&rect);
+ }
+#else
+ if (dst_bitmap == window)
+ {
+ // SDL_UpdateRect(backbuffer->surface, x, y, width, height);
+ UpdateScreen(&rect);
+ }
+#endif
+}
+
+void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
+ 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_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;
+ 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);
+
+ initialization_needed = TRUE;
+ }
+
+ src_rect.x = src_x;
+ src_rect.y = src_y;
+ src_rect.w = width;
+ src_rect.h = height;
+
+ dst_x += video_xoffset;
+ dst_y += video_yoffset;
+
+ dst_rect.x = dst_x;
+ dst_rect.y = dst_y;
+ dst_rect.w = width; /* (ignored) */
+ dst_rect.h = height; /* (ignored) */
+
+ 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)
+ {
+ SDL_BlitSurface(surface_cross, &src_rect, surface_source, &src_rect);
+ SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect);
+ }
+ else if (fade_mode & FADE_TYPE_FADE_IN)
+ {
+ SDL_BlitSurface(surface_black, &src_rect, surface_source, &src_rect);
+ SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect);
+ }
+ else /* FADE_TYPE_FADE_OUT */
+ {
+ SDL_BlitSurface(surface_screen, &dst_rect, surface_source, &src_rect);
+ SDL_BlitSurface(surface_black, &src_rect, surface_target, &src_rect);
+ }