/* SDL internal variables */
#if defined(TARGET_SDL2)
+#define USE_TARGET_TEXTURE TRUE
+#define USE_TARGET_TEXTURE_ONLY FALSE
+
static SDL_Window *sdl_window = NULL;
static SDL_Renderer *sdl_renderer = NULL;
+#if USE_TARGET_TEXTURE
+static SDL_Texture *sdl_texture_stream = NULL;
+static SDL_Texture *sdl_texture_target = NULL;
+#else
static SDL_Texture *sdl_texture = NULL;
+#endif
static boolean fullscreen_enabled = FALSE;
-
-#define USE_RENDERER TRUE
#endif
/* stuff needed to work around SDL/Windows fullscreen drawing bug */
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 &&
// copy global masked border to render target buffer, if defined
if (gfx.draw_global_border_function != NULL)
- gfx.draw_global_border_function(REDRAW_ALL);
+ gfx.draw_global_border_function(DRAW_BORDER_TO_SCREEN);
// copy global animations to render target buffer, if defined (above border)
if (gfx.draw_global_anim_function != NULL)
}
#endif
+#if USE_TARGET_TEXTURE
+#if USE_TARGET_TEXTURE_ONLY
+ SDL_Texture *sdl_texture = sdl_texture_target;
+#else
+ SDL_Texture *sdl_texture = sdl_texture_stream;
+#endif
+#endif
+
#if defined(TARGET_SDL2)
-#if USE_RENDERER
if (rect)
{
int bytes_x = screen->pitch / video.width;
// clear render target buffer
SDL_RenderClear(sdl_renderer);
+#if USE_TARGET_TEXTURE
+ SDL_SetRenderTarget(sdl_renderer, sdl_texture_target);
+
+ // copy backbuffer to render target buffer
+ if (sdl_texture != sdl_texture_target)
+ SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
+#else
// copy backbuffer to render target buffer
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
+#endif
#if !USE_FINAL_SCREEN_BITMAP
// copy global animations to render target buffer, if defined (below border)
// copy global masked border to render target buffer, if defined
if (gfx.draw_global_border_function != NULL)
- gfx.draw_global_border_function(REDRAW_ALL);
+ gfx.draw_global_border_function(DRAW_BORDER_TO_SCREEN);
// 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);
#endif
+#if USE_TARGET_TEXTURE
+ SDL_SetRenderTarget(sdl_renderer, NULL);
+ SDL_RenderCopy(sdl_renderer, sdl_texture_target, NULL, NULL);
+#endif
+
// show render target buffer on screen
SDL_RenderPresent(sdl_renderer);
-#else
-
- if (rect)
- SDL_UpdateWindowSurfaceRects(sdl_window, rect, 1);
- else
- SDL_UpdateWindowSurface(sdl_window);
-#endif
-
#else // TARGET_SDL
if (rect)
SDL_UpdateRects(screen, 1, rect);
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());
// store if initial screen mode is fullscreen mode when changing screen size
video.fullscreen_initial = fullscreen;
-#if USE_RENDERER
float window_scaling_factor = (float)setup.window_scaling_percent / 100;
#if !USE_DESKTOP_FULLSCREEN
float screen_scaling_factor = (fullscreen ? 1 : window_scaling_factor);
(*backbuffer)->surface = NULL;
}
+#if USE_TARGET_TEXTURE
+ if (sdl_texture_stream)
+ {
+ SDL_DestroyTexture(sdl_texture_stream);
+ sdl_texture_stream = NULL;
+ }
+
+ if (sdl_texture_target)
+ {
+ SDL_DestroyTexture(sdl_texture_target);
+ sdl_texture_target = NULL;
+ }
+#else
if (sdl_texture)
{
SDL_DestroyTexture(sdl_texture);
sdl_texture = NULL;
}
+#endif
if (!(fullscreen && fullscreen_enabled))
{
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality);
+#if USE_TARGET_TEXTURE
+ sdl_texture_stream = SDL_CreateTexture(sdl_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_STREAMING,
+ width, height);
+
+ sdl_texture_target = SDL_CreateTexture(sdl_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET,
+ width, height);
+#else
sdl_texture = SDL_CreateTexture(sdl_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
width, height);
+#endif
+#if USE_TARGET_TEXTURE
+ if (sdl_texture_stream != NULL &&
+ sdl_texture_target != NULL)
+#else
if (sdl_texture != NULL)
+#endif
{
// use SDL default values for RGB masks and no alpha channel
new_surface = SDL_CreateRGBSurface(0, width, height, 32, 0,0,0, 0);
Error(ERR_WARN, "SDL_CreateWindow() failed: %s", SDL_GetError());
}
-#else
-
- if (sdl_window)
- SDL_DestroyWindow(sdl_window);
-
- sdl_window = SDL_CreateWindow(program.window_title,
- SDL_WINDOWPOS_CENTERED,
- SDL_WINDOWPOS_CENTERED,
- width, height,
- surface_flags);
-
- if (sdl_window != NULL)
- new_surface = SDL_GetWindowSurface(sdl_window);
-#endif
-
#else
new_surface = SDL_SetVideoMode(width, height, video.depth, surface_flags);
#endif
void SDLSetWindowScalingQuality(char *window_scaling_quality)
{
+#if USE_TARGET_TEXTURE
+ SDL_Texture *new_texture;
+
+ if (sdl_texture_stream == NULL ||
+ sdl_texture_target == NULL)
+ return;
+
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, window_scaling_quality);
+
+ new_texture = SDL_CreateTexture(sdl_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_STREAMING,
+ video.width, video.height);
+
+ if (new_texture != NULL)
+ {
+ SDL_DestroyTexture(sdl_texture_stream);
+
+ sdl_texture_stream = new_texture;
+ }
+
+ new_texture = SDL_CreateTexture(sdl_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET,
+ video.width, video.height);
+
+ if (new_texture != NULL)
+ {
+ SDL_DestroyTexture(sdl_texture_target);
+
+ sdl_texture_target = new_texture;
+ }
+
+ SDLRedrawWindow();
+
+#else
if (sdl_texture == NULL)
return;
SDLRedrawWindow();
}
+#endif
video.window_scaling_quality = window_scaling_quality;
}
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;
SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect);
#endif
-#endif
}
void SDLFillRectangle(Bitmap *dst_bitmap, 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_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;
if (draw_border_function == NULL)
gfx.draw_global_border_function = NULL;
- /* 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;
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);
+
+ draw_global_border_function(DRAW_BORDER_TO_FADE_SOURCE);
+ draw_global_border_function(DRAW_BORDER_TO_FADE_TARGET);
}
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);
+
+ draw_global_border_function(DRAW_BORDER_TO_FADE_TARGET);
}
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);
+
+ draw_global_border_function(DRAW_BORDER_TO_FADE_SOURCE);
}
time_current = SDL_GetTicks();
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)
{