// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// sdl.c
// ============================================================================
#include "joystick.h"
#include "misc.h"
#include "setup.h"
+#include "gadgets.h"
#define ENABLE_UNUSED_CODE 0 // currently unused functions
#if defined(USE_TOUCH_INPUT_OVERLAY)
// functions to draw overlay graphics for touch device input
-static void DrawTouchInputOverlay();
+static void DrawTouchInputOverlay(void);
+static void DrawTouchGadgetsOverlay(void);
#endif
void SDLLimitScreenUpdates(boolean enable)
#if defined(USE_TOUCH_INPUT_OVERLAY)
// draw overlay graphics for touch device input, if needed
DrawTouchInputOverlay();
+
+ // draw overlay gadgets for touch device input, if needed
+ DrawTouchGadgetsOverlay();
#endif
// global synchronization point of the game to align video frame delay
if (with_frame_delay)
WaitUntilDelayReached(&video.frame_delay, video.frame_delay_value);
+ video.frame_counter++;
+
// show render target buffer on screen
SDL_RenderPresent(sdl_renderer);
}
static void UpdateScreen_WithFrameDelay(SDL_Rect *rect)
{
+ PumpEvents(); // execute event filter actions while waiting
+
UpdateScreenExt(rect, TRUE);
}
if ((surface = IMG_Load(filename)) == NULL)
{
- Error(ERR_WARN, "IMG_Load() failed: %s", SDL_GetError());
+ Error(ERR_WARN, "IMG_Load('%s') failed: %s", basename, SDL_GetError());
return;
}
SDL_SetSurfaceAlphaMod(surface, alpha);
}
+const char *SDLGetRendererName(void)
+{
+ static SDL_RendererInfo renderer_info;
+
+ SDL_GetRendererInfo(sdl_renderer, &renderer_info);
+
+ return renderer_info.name;
+}
+
SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
{
SDL_PixelFormat format;
if (new_surface == NULL)
Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError());
+ // workaround for a bug in SDL 2.0.12 (which does not convert the color key)
+ if (SDLHasColorKey(surface) && !SDLHasColorKey(new_surface))
+ SDL_SetColorKey(new_surface, SET_TRANSPARENT_PIXEL,
+ SDLGetColorKey(surface));
+
return new_surface;
}
void SDLInitVideoDisplay(void)
{
+ // set hint to select render driver as specified in setup config file
+ if (!strEqual(setup.system.sdl_renderdriver, ARG_DEFAULT))
+ SDL_SetHint(SDL_HINT_RENDER_DRIVER, setup.system.sdl_renderdriver);
+
// initialize SDL video
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
{
SDL_Surface *new_surface = NULL;
- int surface_flags_window = SURFACE_FLAGS | SDL_WINDOW_RESIZABLE;
+ int surface_flags_window = SURFACE_FLAGS;
int surface_flags_fullscreen = SURFACE_FLAGS | SDL_WINDOW_FULLSCREEN_DESKTOP;
#if 1
int renderer_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
+
+ video.vsync_mode = VSYNC_MODE_OFF;
+
+ if (!strEqual(setup.vsync_mode, STR_VSYNC_MODE_OFF))
+ {
+ renderer_flags |= SDL_RENDERER_PRESENTVSYNC;
+ video.vsync_mode = VSYNC_MODE_NORMAL;
+ }
#else
/* If SDL_CreateRenderer() is called from within a VirtualBox Windows VM
_without_ enabling 2D/3D acceleration and/or guest additions installed,
int renderer_flags = SDL_RENDERER_SOFTWARE;
#endif
- SDLSetScreenSizeAndOffsets(video.width, video.height);
-
int width = video.width;
int height = video.height;
int screen_width = video.screen_width;
if (sdl_renderer != NULL)
{
- SDL_RenderSetLogicalSize(sdl_renderer, screen_width, screen_height);
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality);
+ // required for setting adaptive vsync when using OpenGL renderer
SDLSetScreenVsyncMode(setup.vsync_mode);
sdl_texture_stream = SDL_CreateTexture(sdl_renderer,
Error(ERR_WARN, "SDL_CreateWindow() failed: %s", SDL_GetError());
}
+ SDLSetScreenProperties();
+
// store fullscreen state ("video.fullscreen_enabled" may not reflect this!)
if (new_surface != NULL)
fullscreen_enabled = fullscreen;
SDLRedrawWindow(); // map window
-#ifdef DEBUG
-#if defined(PLATFORM_WIN32)
- // experimental drag and drop code
-
- SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
-
- {
- SDL_SysWMinfo wminfo;
- HWND hwnd;
- boolean wminfo_success = FALSE;
-
- SDL_VERSION(&wminfo.version);
-
- if (sdl_window)
- wminfo_success = SDL_GetWindowWMInfo(sdl_window, &wminfo);
-
- if (wminfo_success)
- {
- hwnd = wminfo.info.win.window;
-
- DragAcceptFiles(hwnd, TRUE);
- }
- }
-#endif
-#endif
-
return success;
}
void SDLSetDisplaySize(void)
{
- SDL_Rect display_bounds;
+ if (sdl_renderer != NULL)
+ {
+ int w, h;
- SDL_GetDisplayBounds(0, &display_bounds);
+ SDL_GetRendererOutputSize(sdl_renderer, &w, &h);
- video.display_width = display_bounds.w;
- video.display_height = display_bounds.h;
+ video.display_width = w;
+ video.display_height = h;
#if 0
- Error(ERR_DEBUG, "SDL real screen size: %d x %d",
- video.display_width, video.display_height);
+ Error(ERR_DEBUG, "SDL renderer size: %d x %d",
+ video.display_width, video.display_height);
#endif
+ }
+ else
+ {
+ SDL_Rect display_bounds;
+
+ SDL_GetDisplayBounds(0, &display_bounds);
+
+ video.display_width = display_bounds.w;
+ video.display_height = display_bounds.h;
+
+#if 0
+ Error(ERR_DEBUG, "SDL display size: %d x %d",
+ video.display_width, video.display_height);
+#endif
+ }
}
void SDLSetScreenSizeAndOffsets(int width, int height)
void SDLSetScreenProperties(void)
{
+ SDLSetDisplaySize();
SDLSetScreenSizeAndOffsets(video.width, video.height);
SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height);
}
void SDLSetScreenVsyncMode(char *vsync_mode)
{
- int interval =
- (strEqual(vsync_mode, STR_VSYNC_MODE_NORMAL) ? VSYNC_MODE_NORMAL :
- strEqual(vsync_mode, STR_VSYNC_MODE_ADAPTIVE) ? VSYNC_MODE_ADAPTIVE :
- VSYNC_MODE_OFF);
+ // changing vsync mode without re-creating renderer only supported by OpenGL
+ if (!strPrefixLower((char *)SDLGetRendererName(), "opengl"))
+ return;
+
+ int interval = VSYNC_MODE_STR_TO_INT(vsync_mode);
int result = SDL_GL_SetSwapInterval(interval);
// if adaptive vsync requested, but not supported, retry with normal vsync
if (result == -1 && interval == VSYNC_MODE_ADAPTIVE)
- SDL_GL_SetSwapInterval(VSYNC_MODE_NORMAL);
+ {
+ interval = VSYNC_MODE_NORMAL;
+
+ result = SDL_GL_SetSwapInterval(interval);
+ }
+
+ if (result == -1)
+ interval = VSYNC_MODE_OFF;
+
+ video.vsync_mode = interval;
}
void SDLRedrawWindow(void)
time_current = SDL_GetTicks();
+ if (fade_delay <= 0)
+ {
+ // immediately draw final target frame without delay
+ fade_mode &= (FADE_MODE_FADE | FADE_MODE_TRANSFORM);
+ fade_delay = 1;
+ time_current -= 1;
+
+ // when fading without delay, also skip post delay
+ post_delay = 0;
+ }
+
if (fade_mode == FADE_MODE_MELT)
{
boolean done = FALSE;
// load image to temporary surface
if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
- Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError());
+ Error(ERR_EXIT, "IMG_Load('%s') failed: %s", getBaseNamePtr(filename),
+ SDL_GetError());
print_timestamp_time("IMG_Load");
SDL_WaitEvent(event);
}
-void SDLHandleWindowManagerEvent(Event *event)
+void SDLCorrectRawMousePosition(int *x, int *y)
{
-#ifdef DEBUG
-#if defined(PLATFORM_WIN32)
- // experimental drag and drop code
-
- SDL_SysWMEvent *syswmevent = (SDL_SysWMEvent *)event;
- SDL_SysWMmsg *syswmmsg = (SDL_SysWMmsg *)(syswmevent->msg);
-
- if (syswmmsg->msg.win.msg == WM_DROPFILES)
- {
- HDROP hdrop = (HDROP)syswmmsg->msg.win.wParam;
- int i, num_files;
-
- printf("::: SDL_SYSWMEVENT:\n");
+ if (sdl_renderer == NULL)
+ return;
- num_files = DragQueryFile(hdrop, 0xffffffff, NULL, 0);
+ // this corrects the raw mouse position for logical screen size within event
+ // filters (correction done later by SDL library when handling mouse events)
- for (i = 0; i < num_files; i++)
- {
- int buffer_len = DragQueryFile(hdrop, i, NULL, 0);
- char buffer[buffer_len + 1];
+ SDL_Rect viewport;
+ float scale_x, scale_y;
- DragQueryFile(hdrop, i, buffer, buffer_len + 1);
+ SDL_RenderGetViewport(sdl_renderer, &viewport);
+ SDL_RenderGetScale(sdl_renderer, &scale_x, &scale_y);
- printf("::: - '%s'\n", buffer);
- }
+ *x = (int)(*x / scale_x);
+ *y = (int)(*y / scale_y);
- DragFinish((HDROP)syswmmsg->msg.win.wParam);
- }
-#endif
-#endif
+ *x -= viewport.x;
+ *y -= viewport.y;
}
void HandleJoystickEvent(Event *event)
{
- switch(event->type)
+ // when using joystick, disable overlay touch buttons
+ runtime.uses_touch_device = FALSE;
+
+ switch (event->type)
{
case SDL_CONTROLLERDEVICEADDED:
#if DEBUG_JOYSTICKS
continue;
if (grid_button == overlay.grid_button_highlight)
- alpha_draw = alpha_highlight;
+ {
+ draw_outlined = FALSE;
+ alpha_draw = MIN((float)alpha_highlight * 1.5, SDL_ALPHA_OPAQUE);
+ }
if (draw_pressed && overlay.grid_button_action & grid_button_action)
{
static void DrawTouchInputOverlay(void)
{
- static SDL_Texture *texture = NULL;
- static boolean initialized = FALSE;
static boolean deactivated = TRUE;
static boolean show_grid = FALSE;
- static int width = 0, height = 0;
- static int alpha_last = -1;
static int alpha = 0;
int alpha_max = ALPHA_FROM_TRANSPARENCY(setup.touch.transparency);
int alpha_step = ALPHA_FADING_STEPSIZE(alpha_max);
DrawTouchInputOverlay_ShowGrid(alpha);
DrawTouchInputOverlay_ShowGridButtons(alpha);
+}
- return;
-
-
- // !!! VIRTUAL BUTTONS FROM IMAGE FILE NOT USED ANYMORE !!!
-
- if (!initialized)
- {
- char *basename = "overlay/VirtualButtons.png";
- char *filename = getCustomImageFilename(basename);
-
- if (filename == NULL)
- Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
-
- SDL_Surface *surface;
-
- if ((surface = IMG_Load(filename)) == NULL)
- Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError());
-
- width = surface->w;
- height = surface->h;
-
- // set black pixel to transparent if no alpha channel / transparent color
- if (!SDLHasAlpha(surface) &&
- !SDLHasColorKey(surface))
- SDL_SetColorKey(surface, SET_TRANSPARENT_PIXEL,
- SDL_MapRGB(surface->format, 0x00, 0x00, 0x00));
-
- if ((texture = SDLCreateTextureFromSurface(surface)) == NULL)
- Error(ERR_EXIT, "SDLCreateTextureFromSurface() failed");
-
- SDL_FreeSurface(surface);
-
- SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
-
- initialized = TRUE;
- }
-
- if (alpha != alpha_last)
- SDL_SetTextureAlphaMod(texture, alpha);
-
- alpha_last = alpha;
-
- float ratio_overlay = (float) width / height;
- float ratio_screen = (float) video.screen_width / video.screen_height;
- int width_scaled, height_scaled;
- int xpos, ypos;
-
- if (ratio_overlay > ratio_screen)
- {
- width_scaled = video.screen_width;
- height_scaled = video.screen_height * ratio_screen / ratio_overlay;
- xpos = 0;
- ypos = video.screen_height - height_scaled;
- }
- else
- {
- width_scaled = video.screen_width * ratio_overlay / ratio_screen;
- height_scaled = video.screen_height;
- xpos = (video.screen_width - width_scaled) / 2;
- ypos = 0;
- }
-
- SDL_Rect src_rect = { 0, 0, width, height };
- SDL_Rect dst_rect = { xpos, ypos, width_scaled, height_scaled };
-
- SDL_RenderCopy(sdl_renderer, texture, &src_rect, &dst_rect);
+static void DrawTouchGadgetsOverlay(void)
+{
+ DrawGadgets_OverlayTouchButtons();
}
#endif