rnd-20140117-1-src
[rocksndiamonds.git] / src / libgame / sdl.c
index fbac750141434b8f2dbaebbc54056fd53f7de85f..123916520339578ec0cea14ece88db5e1ce0c17f 100644 (file)
@@ -40,13 +40,31 @@ static int fullscreen_xoffset;
 static int fullscreen_yoffset;
 static int video_xoffset;
 static int video_yoffset;
+static boolean limit_screen_updates = FALSE;
+
 
 /* functions from SGE library */
 void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
 
-#if defined(TARGET_SDL2)
+void SDLLimitScreenUpdates(boolean enable)
+{
+  limit_screen_updates = enable;
+}
+
 static void UpdateScreen(SDL_Rect *rect)
 {
+  static unsigned int update_screen_delay = 0;
+  unsigned int update_screen_delay_value = 100;                /* (milliseconds) */
+
+#if 1
+  if (limit_screen_updates &&
+      !DelayReached(&update_screen_delay, update_screen_delay_value))
+    return;
+
+  LimitScreenUpdates(FALSE);
+#endif
+
+#if defined(TARGET_SDL2)
 #if USE_RENDERER
   SDL_Surface *screen = backbuffer->surface;
 
@@ -79,8 +97,14 @@ static void UpdateScreen(SDL_Rect *rect)
   else
     SDL_UpdateWindowSurface(sdl_window);
 #endif
-}
+
+#else  // TARGET_SDL
+  if (rect)
+    SDL_UpdateRects(backbuffer->surface, 1, rect);
+  else
+    SDL_UpdateRect(backbuffer->surface, 0, 0, 0, 0);
 #endif
+}
 
 static void setFullscreenParameters(char *fullscreen_mode_string)
 {
@@ -391,11 +415,10 @@ static SDL_Surface *SDLCreateScreen(DrawBuffer **backbuffer,
                                    boolean fullscreen)
 {
   SDL_Surface *new_surface = NULL;
-  static boolean fullscreen_enabled = FALSE;
 
-  int surface_flags_window = SURFACE_FLAGS;
 #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;
 #else
@@ -403,6 +426,7 @@ static SDL_Surface *SDLCreateScreen(DrawBuffer **backbuffer,
 #endif
 
 #else
+  int surface_flags_window = SURFACE_FLAGS;
   int surface_flags_fullscreen = SURFACE_FLAGS | SDL_FULLSCREEN;
 #endif
 
@@ -411,13 +435,32 @@ static SDL_Surface *SDLCreateScreen(DrawBuffer **backbuffer,
   int surface_flags = (fullscreen ? surface_flags_fullscreen :
                       surface_flags_window);
 
+  // default window size is unscaled
+  video.window_width  = video.width;
+  video.window_height = video.height;
+
 #if defined(TARGET_SDL2)
 
+  // store if initial screen mode on game start is fullscreen mode
+  if (sdl_window == NULL)
+  {
+#if 0
+    printf("::: GAME STARTS WITH FULLSCREEN %d\n", fullscreen);
+#endif
+
+    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);
+#endif
 
-#if 1
+  video.window_width  = window_scaling_factor * width;
+  video.window_height = window_scaling_factor * height;
+
+#if 0
   printf("::: use window scaling factor %f\n", screen_scaling_factor);
 #endif
 
@@ -448,18 +491,25 @@ static SDL_Surface *SDLCreateScreen(DrawBuffer **backbuffer,
     }
   }
 
+#if 0
   Error(ERR_INFO, "::: checking 'sdl_window' ...");
 
   if (sdl_window == NULL)
     Error(ERR_INFO, "::: calling SDL_CreateWindow() [%d, %d, %d] ...",
          setup.fullscreen, fullscreen, fullscreen_enabled);
+#endif
 
   if (sdl_window == NULL)
     sdl_window = SDL_CreateWindow(program.window_title,
                                  SDL_WINDOWPOS_CENTERED,
                                  SDL_WINDOWPOS_CENTERED,
+#if USE_DESKTOP_FULLSCREEN
+                                 video.window_width,
+                                 video.window_height,
+#else
                                  (int)(screen_scaling_factor * width),
                                  (int)(screen_scaling_factor * height),
+#endif
                                  surface_flags);
 
   if (sdl_window != NULL)
@@ -533,9 +583,11 @@ static SDL_Surface *SDLCreateScreen(DrawBuffer **backbuffer,
   new_surface = SDL_SetVideoMode(width, height, video.depth, surface_flags);
 #endif
 
+#if defined(TARGET_SDL2)
   // store fullscreen state ("video.fullscreen_enabled" may not reflect this!)
   if (new_surface != NULL)
     fullscreen_enabled = fullscreen;
+#endif
 
   return new_surface;
 }
@@ -748,7 +800,8 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen)
   }
 
 #if defined(TARGET_SDL2)
-  UpdateScreen(NULL);          // map window
+  SDLRedrawWindow();                   // map window
+  // UpdateScreen(NULL);               // map window
 #endif
 
 #if 1
@@ -772,6 +825,69 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen)
   return success;
 }
 
+#if defined(TARGET_SDL2)
+void SDLSetWindowScaling(int window_scaling_percent)
+{
+  if (sdl_window == NULL)
+    return;
+
+  float window_scaling_factor = (float)window_scaling_percent / 100;
+  int new_window_width  = (int)(window_scaling_factor * video.width);
+  int new_window_height = (int)(window_scaling_factor * video.height);
+
+#if 0
+  Error(ERR_DEBUG, "::: SDLSetWindowScaling(%d) ...", window_scaling_percent);
+#endif
+
+  SDL_SetWindowSize(sdl_window, new_window_width, new_window_height);
+
+  video.window_scaling_percent = window_scaling_percent;
+  video.window_width  = new_window_width;
+  video.window_height = new_window_height;
+}
+
+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 0
+  Error(ERR_DEBUG, "::: SDL_SetWindowFullscreen(%d) ...", fullscreen);
+#endif
+
+  if (SDL_SetWindowFullscreen(sdl_window, flags) == 0)
+    video.fullscreen_enabled = fullscreen;
+
+#if 0
+  printf("::: SDLSetWindowFullscreen: %d, %d\n",
+        fullscreen, video.fullscreen_initial);
+#endif
+
+#if 1
+  // if game started in fullscreen mode, window will also get fullscreen 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;
+  }
+#endif
+}
+
+void SDLRedrawWindow()
+{
+  UpdateScreen(NULL);
+}
+#endif
+
 void SDLCreateBitmapContent(Bitmap *new_bitmap, int width, int height,
                            int depth)
 {
@@ -844,7 +960,10 @@ void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
   }
 #else
   if (dst_bitmap == window)
-    SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+  {
+    // SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+    UpdateScreen(&dst_rect);
+  }
 #endif
 }
 
@@ -876,7 +995,10 @@ void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height,
   }
 #else
   if (dst_bitmap == window)
-    SDL_UpdateRect(backbuffer->surface, x, y, width, height);
+  {
+    // SDL_UpdateRect(backbuffer->surface, x, y, width, height);
+    UpdateScreen(&rect);
+  }
 #endif
 }
 
@@ -891,9 +1013,7 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
   SDL_Surface *surface_screen = backbuffer->surface;
   SDL_Surface *surface_cross = (bitmap_cross ? bitmap_cross->surface : NULL);
   SDL_Rect src_rect, dst_rect;
-#if defined(TARGET_SDL2)
   SDL_Rect dst_rect2;
-#endif
   int src_x = x, src_y = y;
   int dst_x = x, dst_y = y;
   unsigned int time_last, time_current;
@@ -922,9 +1042,7 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
   dst_rect.w = width;          /* (ignored) */
   dst_rect.h = height;         /* (ignored) */
 
-#if defined(TARGET_SDL2)
   dst_rect2 = dst_rect;
-#endif
 
   if (initialization_needed)
   {
@@ -1125,7 +1243,8 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
        // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect2, 1);
        UpdateScreen(&dst_rect2);
 #else
-       SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+       // SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+       UpdateScreen(&dst_rect2);
 #endif
       }
     }
@@ -1164,7 +1283,8 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
       // SDL_UpdateWindowSurfaceRects(sdl_window, &dst_rect, 1);
       UpdateScreen(&dst_rect);
 #else
-      SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+      // SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height);
+      UpdateScreen(&dst_rect);
 #endif
 #else
       SDL_Flip(surface_screen);