static SDL_Window *sdl_window = NULL;
static SDL_Renderer *sdl_renderer = NULL;
static SDL_Texture *sdl_texture = NULL;
+static boolean fullscreen_enabled = FALSE;
#define USE_RENDERER TRUE
#endif
{
static unsigned int update_screen_delay = 0;
unsigned int update_screen_delay_value = 20; /* (milliseconds) */
+ SDL_Surface *screen = backbuffer->surface;
if (limit_screen_updates &&
!DelayReached(&update_screen_delay, update_screen_delay_value))
LimitScreenUpdates(FALSE);
+#if 0
+ {
+ static int LastFrameCounter = 0;
+ boolean changed = (FrameCounter != LastFrameCounter);
+
+ printf("::: FrameCounter == %d [%s]\n", FrameCounter,
+ (changed ? "-" : "SAME FRAME UPDATED"));
+
+ LastFrameCounter = FrameCounter;
+
+ /*
+ if (FrameCounter % 2)
+ return;
+ */
+ }
+#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;
{
SDL_UpdateTexture(sdl_texture, NULL, screen->pixels, screen->pitch);
}
+
+ // clear render target buffer
SDL_RenderClear(sdl_renderer);
+
+ // copy backbuffer to render target buffer
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
+
+#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(DRAW_GLOBAL_ANIM_STAGE_2);
+#endif
+
+ // show render target buffer on screen
SDL_RenderPresent(sdl_renderer);
+
#else
+
if (rect)
SDL_UpdateWindowSurfaceRects(sdl_window, rect, 1);
else
#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
}
#endif
+#if defined(TARGET_SDL2)
+static SDL_Texture *SDLCreateTextureFromSurface(SDL_Surface *surface)
+{
+ SDL_Texture *texture = SDL_CreateTextureFromSurface(sdl_renderer, surface);
+
+ if (texture == NULL)
+ Error(ERR_EXIT, "SDL_CreateTextureFromSurface() failed: %s",
+ SDL_GetError());
+
+ return texture;
+}
+#endif
+
+void SDLCreateBitmapTextures(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 = 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)
/* !!! SDL2 can only set the window icon if the window already exists !!! */
/* set window icon */
- SDLSetWindowIcon(program.sdl_icon_filename);
+ SDLSetWindowIcon(program.icon_filename);
/* set window and icon title */
#if defined(TARGET_SDL2)
SDL_Surface *new_surface = NULL;
#if defined(TARGET_SDL2)
- static boolean fullscreen_enabled = FALSE;
int surface_flags_window = SURFACE_FLAGS | SDL_WINDOW_RESIZABLE;
#if USE_DESKTOP_FULLSCREEN
int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP;
#if defined(TARGET_SDL2)
- // store if initial screen mode on game start is fullscreen mode
- if (sdl_window == NULL)
- video.fullscreen_initial = fullscreen;
+ // 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;
SDLRedrawWindow(); // map window
#endif
+#ifdef DEBUG
+#if defined(PLATFORM_WIN32)
+ // experimental drag and drop code
+
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
-#if defined(PLATFORM_WIN32)
{
SDL_SysWMinfo wminfo;
HWND hwnd;
DragAcceptFiles(hwnd, TRUE);
}
}
+#endif
#endif
return success;
#endif
if (SDL_SetWindowFullscreen(sdl_window, flags) == 0)
- video.fullscreen_enabled = fullscreen;
+ video.fullscreen_enabled = fullscreen_enabled = fullscreen;
- // if game started in fullscreen mode, window will also get fullscreen size
+ // if screen size was changed in fullscreen mode, correct desktop window size
if (!fullscreen && video.fullscreen_initial)
{
SDLSetWindowScaling(setup.window_scaling_percent);
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,
#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)
{
int dst_x = x, dst_y = y;
unsigned int time_last, time_current;
+ // store function for drawing global masked border
+ void (*draw_global_border_function)(int) = gfx.draw_global_border_function;
+
+ // deactivate drawing of global border while fading, if needed
+ 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))
if (draw_border_function != NULL)
draw_border_function();
-#if defined(TARGET_SDL2)
- // SDL_UpdateWindowSurface(sdl_window);
- // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect2, 1);
UpdateScreen(&dst_rect2);
+ }
+ }
+ }
+ else if (fade_mode == FADE_MODE_CURTAIN)
+ {
+ float xx;
+ int xx_final;
+ int xx_size = width / 2;
+
+ SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect);
+#if defined(TARGET_SDL2)
+ SDL_SetSurfaceBlendMode(surface_source, SDL_BLENDMODE_NONE);
#else
- // SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
- UpdateScreen(&dst_rect2);
+ SDL_SetAlpha(surface_source, 0, 0); /* disable alpha blending */
#endif
+
+ for (xx = 0; xx < xx_size;)
+ {
+ time_last = time_current;
+ time_current = SDL_GetTicks();
+ xx += xx_size * ((float)(time_current - time_last) / fade_delay);
+ xx_final = MIN(MAX(0, xx), xx_size);
+
+ 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;
+
+ /* draw new (target) image to screen buffer */
+ SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect);
+
+ if (xx_final < xx_size)
+ {
+ src_rect.w = xx_size - xx_final;
+ src_rect.h = height;
+
+ /* draw old (source) image to screen buffer (left side) */
+
+ src_rect.x = src_x + xx_final;
+ dst_rect.x = dst_x;
+
+ SDL_BlitSurface(surface_source, &src_rect, surface_screen, &dst_rect);
+
+ /* draw old (source) image to screen buffer (right side) */
+
+ src_rect.x = src_x + xx_size;
+ dst_rect.x = dst_x + xx_size + xx_final;
+
+ SDL_BlitSurface(surface_source, &src_rect, surface_screen, &dst_rect);
}
+
+ if (draw_border_function != NULL)
+ draw_border_function();
+
+ /* only update the region of the screen that is affected from fading */
+ UpdateScreen(&dst_rect2);
}
}
- else
+ else /* fading in, fading out or cross-fading */
{
float alpha;
int alpha_final;
}
}
- 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,
void SDLHandleWindowManagerEvent(Event *event)
{
+#ifdef DEBUG
#if defined(PLATFORM_WIN32)
+ // experimental drag and drop code
+
SDL_SysWMEvent *syswmevent = (SDL_SysWMEvent *)event;
SDL_SysWMmsg *syswmmsg = (SDL_SysWMmsg *)(syswmevent->msg);
#endif
}
#endif
+#endif
}