added support for (normal and adaptive) vertical sync (vsync)
[rocksndiamonds.git] / src / libgame / sdl.c
index eee5d59ac56cee2d054f4ecbd79fa788982569c5..b03f01adab1a1bd3026f53ef1e8e8a234cd35905 100644 (file)
@@ -555,7 +555,7 @@ inline static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen)
   SDLSetWindowTitle();
 }
 
-inline static void SDLInitVideoBuffer_DrawBuffer()
+inline static void SDLInitVideoBuffer_DrawBuffer(void)
 {
   /* SDL cannot directly draw to the visible video framebuffer like X11,
      but always uses a backbuffer, which is then blitted to the visible
@@ -677,6 +677,8 @@ static boolean SDLCreateScreen(boolean fullscreen)
       // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
       SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality);
 
+      SDLSetScreenVsyncMode(setup.vsync_mode);
+
       sdl_texture_stream = SDL_CreateTexture(sdl_renderer,
                                             SDL_PIXELFORMAT_ARGB8888,
                                             SDL_TEXTUREACCESS_STREAMING,
@@ -843,7 +845,7 @@ boolean SDLSetVideoMode(boolean fullscreen)
   return success;
 }
 
-void SDLSetWindowTitle()
+void SDLSetWindowTitle(void)
 {
 #if defined(TARGET_SDL2)
   if (sdl_window == NULL)
@@ -936,7 +938,7 @@ void SDLSetWindowFullscreen(boolean fullscreen)
   }
 }
 
-void SDLSetDisplaySize()
+void SDLSetDisplaySize(void)
 {
   SDL_Rect display_bounds;
 
@@ -990,7 +992,7 @@ void SDLSetScreenSizeForRenderer(int width, int height)
   SDL_RenderSetLogicalSize(sdl_renderer, width, height);
 }
 
-void SDLSetScreenProperties()
+void SDLSetScreenProperties(void)
 {
   SDLSetScreenSizeAndOffsets(video.width, video.height);
   SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height);
@@ -1013,7 +1015,22 @@ void SDLSetScreenRenderingMode(char *screen_rendering_mode)
 #endif
 }
 
-void SDLRedrawWindow()
+void SDLSetScreenVsyncMode(char *vsync_mode)
+{
+#if defined(TARGET_SDL2)
+  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);
+  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);
+#endif
+}
+
+void SDLRedrawWindow(void)
 {
   UpdateScreen_WithoutFrameDelay(NULL);
 }
@@ -1522,7 +1539,7 @@ Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y)
 /* http://www.etek.chalmers.se/~e8cal1/sge/index.html                        */
 /* ========================================================================= */
 
-void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   if (x >= 0 && x <= surface->w - 1 && y >= 0 && y <= surface->h - 1)
   {
@@ -1569,23 +1586,24 @@ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   }
 }
 
-void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
-                 Uint8 R, Uint8 G, Uint8 B)
+#if 0
+static void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   _PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
 }
 
-void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
 }
 
-void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
 }
 
-void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   Uint8 *pix;
   int shift;
@@ -1600,12 +1618,12 @@ void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   *(pix+shift/8) = color>>shift;
 }
 
-void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
 }
 
-void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
+static void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
 {
   switch (dest->format->BytesPerPixel)
   {
@@ -1626,8 +1644,9 @@ void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
       break;
   }
 }
+#endif
 
-void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   if (SDL_MUSTLOCK(surface))
   {
@@ -1645,13 +1664,14 @@ void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   }
 }
 
-void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
-                 Uint8 r, Uint8 g, Uint8 b)
+#if 0
+static void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+                           Uint8 r, Uint8 g, Uint8 b)
 {
   sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, r, g, b));
 }
 
-Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
+static Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
 {
   if (y >= 0 && y <= dest->h - 1)
   {
@@ -1678,7 +1698,8 @@ Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
   return -1;
 }
 
-void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
+static void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch,
+                         Uint32 color)
 {
   if (x >= 0 && x <= surface->w - 1 && ypitch >= 0)
   {
@@ -1725,8 +1746,8 @@ void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
   }
 }
 
-void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
-              Uint32 Color)
+static void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                     Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1766,13 +1787,14 @@ void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
   }
 }
 
-void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
-                 Uint8 R, Uint8 G, Uint8 B)
+static void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   sge_HLine(Surface, x1, x2, y, SDL_MapRGB(Surface->format, R, G, B));
 }
 
-void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
+static void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                  Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1799,8 +1821,8 @@ void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
   SDL_FillRect(Surface, &l, Color);
 }
 
-void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
-              Uint32 Color)
+static void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                     Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1840,13 +1862,14 @@ void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
   }
 }
 
-void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
-                 Uint8 R, Uint8 G, Uint8 B)
+static void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   sge_VLine(Surface, x, y1, y2, SDL_MapRGB(Surface->format, R, G, B));
 }
 
-void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
+static void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                  Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1872,11 +1895,12 @@ void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
 
   SDL_FillRect(Surface, &l, Color);
 }
+#endif
 
-void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
-               Sint16 x2, Sint16 y2, Uint32 Color,
-               void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
-                             Uint32 Color))
+static void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
+                      Sint16 x2, Sint16 y2, Uint32 Color,
+                      void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+                                    Uint32 Color))
 {
   Sint16 dx, dy, sdx, sdy, x, y, px, py;
 
@@ -1928,14 +1952,16 @@ void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
   }
 }
 
-void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
-                  Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
-                  void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
-                                Uint32 Color))
+#if 0
+static void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
+                         Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
+                         void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+                                       Uint32 Color))
 {
   sge_DoLine(Surface, X1, Y1, X2, Y2,
             SDL_MapRGB(Surface->format, R, G, B), Callback);
 }
+#endif
 
 void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
              Uint32 Color)
@@ -1956,11 +1982,13 @@ void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
    }
 }
 
-void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
-                Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
+#if 0
+static void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
+                       Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
 {
   sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B));
 }
+#endif
 
 void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel)
 {
@@ -2031,7 +2059,7 @@ typedef struct
   Uint8 a;
 } tColorRGBA;
 
-int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
+static int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
 {
   int x, y;
   tColorRGBA *sp, *csp, *dp;
@@ -2082,7 +2110,7 @@ int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
   return 0;
 }
 
-int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
+static int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
 {
   int x, y, *sax, *say, *csax, *csay;
   float sx, sy;
@@ -2155,7 +2183,7 @@ int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
   -----------------------------------------------------------------------------
 */
 
-int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
+static int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
 {
   Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
   Uint8 *sp, *dp, *csp;
@@ -2255,7 +2283,7 @@ int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
   -----------------------------------------------------------------------------
 */
 
-SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
+static SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
 {
   SDL_Surface *zoom_src = NULL;
   SDL_Surface *zoom_dst = NULL;
@@ -2607,7 +2635,7 @@ static int sdl_js_axis[MAX_PLAYERS][2];
 static int sdl_js_button[MAX_PLAYERS][2];
 static boolean sdl_is_controller[MAX_PLAYERS];
 
-void SDLClearJoystickState()
+void SDLClearJoystickState(void)
 {
   int i, j;
 
@@ -2848,7 +2876,7 @@ void HandleJoystickEvent(Event *event)
   }
 }
 
-void SDLInitJoysticks()
+void SDLInitJoysticks(void)
 {
   static boolean sdl_joystick_subsystem_initialized = FALSE;
   boolean print_warning = !sdl_joystick_subsystem_initialized;
@@ -3151,7 +3179,7 @@ static void DrawTouchInputOverlay_ShowGridButtons(int alpha)
   SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 255);
 }
 
-static void DrawTouchInputOverlay()
+static void DrawTouchInputOverlay(void)
 {
   static SDL_Texture *texture = NULL;
   static boolean initialized = FALSE;