fixed bug with not setting grid size and buttons after screen changes
[rocksndiamonds.git] / src / libgame / sdl.c
index e561b177579961dea8066def3053a9cd2f284368..a2fe9ab5b3bc3ebf5bfdf3d2a009e09b1ce2d6b4 100644 (file)
@@ -84,8 +84,8 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay)
     static int LastFrameCounter = 0;
     boolean changed = (FrameCounter != LastFrameCounter);
 
-    printf("::: FrameCounter == %d [%s]\n", FrameCounter,
-          (changed ? "-" : "SAME FRAME UPDATED"));
+    Debug("internal:frame", "FrameCounter == %d [%s]", FrameCounter,
+         (changed ? "-" : "SAME FRAME UPDATED"));
 
     LastFrameCounter = FrameCounter;
 
@@ -266,14 +266,14 @@ static void SDLSetWindowIcon(char *basename)
 
   if (filename == NULL)
   {
-    Error(ERR_WARN, "SDLSetWindowIcon(): cannot find file '%s'", basename);
+    Warn("SDLSetWindowIcon(): cannot find file '%s'", basename);
 
     return;
   }
 
   if ((surface = IMG_Load(filename)) == NULL)
   {
-    Error(ERR_WARN, "IMG_Load('%s') failed: %s", basename, SDL_GetError());
+    Warn("IMG_Load('%s') failed: %s", basename, SDL_GetError());
 
     return;
   }
@@ -297,19 +297,35 @@ static boolean equalSDLPixelFormat(SDL_PixelFormat *format1,
          format1->Bmask         == format2->Bmask);
 }
 
-static Pixel SDLGetColorKey(SDL_Surface *surface)
+static void SDLCopyColorKey(SDL_Surface *src_surface, SDL_Surface *dst_surface)
 {
   Pixel color_key;
+  Uint8 r, g, b;
 
-  if (SDL_GetColorKey(surface, &color_key) != 0)
-    return -1;
+  // check if source surface has a color key
+  if (SDL_GetColorKey(src_surface, &color_key) == 0)
+  {
+    // get RGB values of color key of source surface
+    SDL_GetRGB(color_key, src_surface->format, &r, &g, &b);
+
+    // get color key from RGB values in destination surface format
+    color_key = SDL_MapRGB(dst_surface->format, r, g, b);
 
-  return color_key;
+    // set color key in destination surface
+    SDL_SetColorKey(dst_surface, SET_TRANSPARENT_PIXEL, color_key);
+  }
+  else
+  {
+    // unset color key in destination surface
+    SDL_SetColorKey(dst_surface, UNSET_TRANSPARENT_PIXEL, 0);
+  }
 }
 
 static boolean SDLHasColorKey(SDL_Surface *surface)
 {
-  return (SDLGetColorKey(surface) != -1);
+  Pixel color_key;
+
+  return (SDL_GetColorKey(surface, &color_key) == 0);
 }
 
 static boolean SDLHasAlpha(SDL_Surface *surface)
@@ -360,12 +376,11 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
   new_surface = SDL_ConvertSurface(surface, &format, 0);
 
   if (new_surface == NULL)
-    Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError());
+    Fail("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));
+    SDLCopyColorKey(surface, new_surface);
 
   return new_surface;
 }
@@ -401,8 +416,7 @@ 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());
+    Fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError());
 
   return texture;
 }
@@ -443,7 +457,7 @@ void SDLInitVideoDisplay(void)
 
   // initialize SDL video
   if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
-    Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
+    Fail("SDL_InitSubSystem() failed: %s", SDL_GetError());
 
   // set default SDL depth
   video.default_depth = 32;    // (how to determine video depth in SDL2?)
@@ -467,7 +481,7 @@ static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen)
 
   // open SDL video output device (window or fullscreen mode)
   if (!SDLSetVideoMode(fullscreen))
-    Error(ERR_EXIT, "setting video mode failed");
+    Fail("setting video mode failed");
 
   // !!! SDL2 can only set the window icon if the window already exists !!!
   // set window icon
@@ -515,6 +529,14 @@ static boolean SDLCreateScreen(boolean fullscreen)
 
 #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,
@@ -587,6 +609,7 @@ static boolean SDLCreateScreen(boolean fullscreen)
       // 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,
@@ -606,21 +629,21 @@ static boolean SDLCreateScreen(boolean fullscreen)
        new_surface = SDL_CreateRGBSurface(0, width, height, 32, 0,0,0, 0);
 
        if (new_surface == NULL)
-         Error(ERR_WARN, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+         Warn("SDL_CreateRGBSurface() failed: %s", SDL_GetError());
       }
       else
       {
-       Error(ERR_WARN, "SDL_CreateTexture() failed: %s", SDL_GetError());
+       Warn("SDL_CreateTexture() failed: %s", SDL_GetError());
       }
     }
     else
     {
-      Error(ERR_WARN, "SDL_CreateRenderer() failed: %s", SDL_GetError());
+      Warn("SDL_CreateRenderer() failed: %s", SDL_GetError());
     }
   }
   else
   {
-    Error(ERR_WARN, "SDL_CreateWindow() failed: %s", SDL_GetError());
+    Warn("SDL_CreateWindow() failed: %s", SDL_GetError());
   }
 
   SDLSetScreenProperties();
@@ -789,7 +812,7 @@ void SDLSetDisplaySize(void)
     video.display_height = h;
 
 #if 0
-    Error(ERR_DEBUG, "SDL renderer size: %d x %d",
+    Debug("video", "SDL renderer size: %d x %d",
          video.display_width, video.display_height);
 #endif
   }
@@ -803,7 +826,7 @@ void SDLSetDisplaySize(void)
     video.display_height = display_bounds.h;
 
 #if 0
-    Error(ERR_DEBUG, "SDL display size: %d x %d",
+    Debug("video", "SDL display size: %d x %d",
          video.display_width, video.display_height);
 #endif
   }
@@ -834,7 +857,7 @@ void SDLSetScreenSizeAndOffsets(int width, int height)
     video.screen_yoffset = (video.screen_height - height) / 2;
 
 #if 0
-    Error(ERR_DEBUG, "Changing screen from %dx%d to %dx%d (%.2f to %.2f)",
+    Debug("video", "Changing screen from %dx%d to %dx%d (%.2f to %.2f)",
          width, height,
          video.screen_width, video.screen_height,
          ratio_video, ratio_display);
@@ -853,6 +876,8 @@ void SDLSetScreenProperties(void)
   SDLSetDisplaySize();
   SDLSetScreenSizeAndOffsets(video.width, video.height);
   SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height);
+
+  SetOverlayGridSizeAndButtons();
 }
 
 void SDLSetScreenRenderingMode(char *screen_rendering_mode)
@@ -868,15 +893,25 @@ void SDLSetScreenRenderingMode(char *screen_rendering_mode)
 
 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)
@@ -894,7 +929,7 @@ void SDLCreateBitmapContent(Bitmap *bitmap, int width, int height,
     SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth, 0,0,0, 0);
 
   if (surface == NULL)
-    Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+    Fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError());
 
   SDLSetNativeSurface(&surface);
 
@@ -2218,7 +2253,7 @@ static SDL_Surface *SDLGetOpaqueSurface(SDL_Surface *surface)
     return NULL;
 
   if ((new_surface = SDLGetNativeSurface(surface)) == NULL)
-    Error(ERR_EXIT, "SDLGetNativeSurface() failed");
+    Fail("SDLGetNativeSurface() failed");
 
   // remove alpha channel from native non-transparent surface, if defined
   SDLSetAlpha(new_surface, FALSE, 0);
@@ -2249,8 +2284,7 @@ Bitmap *SDLZoomBitmap(Bitmap *src_bitmap, int dst_width, int dst_height)
 
   // set color key for zoomed surface from source surface, if defined
   if (SDLHasColorKey(src_surface))
-    SDL_SetColorKey(dst_surface, SET_TRANSPARENT_PIXEL,
-                   SDLGetColorKey(src_surface));
+    SDLCopyColorKey(src_surface, dst_surface);
 
   // create native non-transparent surface for opaque blitting
   dst_bitmap->surface = SDLGetOpaqueSurface(dst_surface);
@@ -2285,8 +2319,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   // load image to temporary surface
   if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
-    Error(ERR_EXIT, "IMG_Load('%s') failed: %s", getBaseNamePtr(filename),
-         SDL_GetError());
+    Fail("IMG_Load('%s') failed: %s", getBaseNamePtr(filename), SDL_GetError());
 
   print_timestamp_time("IMG_Load");
 
@@ -2294,7 +2327,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   // create native non-transparent surface for current image
   if ((new_bitmap->surface = SDLGetOpaqueSurface(sdl_image_tmp)) == NULL)
-    Error(ERR_EXIT, "SDLGetOpaqueSurface() failed");
+    Fail("SDLGetOpaqueSurface() failed");
 
   print_timestamp_time("SDLGetNativeSurface (opaque)");
 
@@ -2308,7 +2341,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   // create native transparent surface for current image
   if ((new_bitmap->surface_masked = SDLGetNativeSurface(sdl_image_tmp)) == NULL)
-    Error(ERR_EXIT, "SDLGetNativeSurface() failed");
+    Fail("SDLGetNativeSurface() failed");
 
   print_timestamp_time("SDLGetNativeSurface (masked)");
 
@@ -2374,7 +2407,8 @@ void SDLOpenAudio(void)
 
   if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
   {
-    Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError());
+    Warn("SDL_InitSubSystem() failed: %s", SDL_GetError());
+
     return;
   }
 
@@ -2382,7 +2416,8 @@ void SDLOpenAudio(void)
                    AUDIO_NUM_CHANNELS_STEREO,
                    setup.system.audio_fragment_size) < 0)
   {
-    Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
+    Warn("Mix_OpenAudio() failed: %s", SDL_GetError());
+
     return;
   }
 
@@ -2473,7 +2508,7 @@ boolean SDLOpenJoystick(int nr)
   sdl_is_controller[nr] = SDL_IsGameController(nr);
 
 #if DEBUG_JOYSTICKS
-  Error(ERR_DEBUG, "opening joystick %d (%s)",
+  Debug("joystick", "opening joystick %d (%s)",
        nr, (sdl_is_controller[nr] ? "game controller" : "joystick"));
 #endif
 
@@ -2491,7 +2526,7 @@ void SDLCloseJoystick(int nr)
     return;
 
 #if DEBUG_JOYSTICKS
-  Error(ERR_DEBUG, "closing joystick %d", nr);
+  Debug("joystick", "closing joystick %d", nr);
 #endif
 
   if (sdl_is_controller[nr])
@@ -2577,7 +2612,7 @@ void HandleJoystickEvent(Event *event)
   {
     case SDL_CONTROLLERDEVICEADDED:
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEADDED: device %d added",
+      Debug("joystick", "SDL_CONTROLLERDEVICEADDED: device %d added",
            event->cdevice.which);
 #endif
       InitJoysticks();
@@ -2585,7 +2620,7 @@ void HandleJoystickEvent(Event *event)
 
     case SDL_CONTROLLERDEVICEREMOVED:
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEREMOVED: device %d removed",
+      Debug("joystick", "SDL_CONTROLLERDEVICEREMOVED: device %d removed",
            event->cdevice.which);
 #endif
       InitJoysticks();
@@ -2593,7 +2628,7 @@ void HandleJoystickEvent(Event *event)
 
     case SDL_CONTROLLERAXISMOTION:
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_CONTROLLERAXISMOTION: device %d, axis %d: %d",
+      Debug("joystick", "SDL_CONTROLLERAXISMOTION: device %d, axis %d: %d",
            event->caxis.which, event->caxis.axis, event->caxis.value);
 #endif
       setJoystickAxis(event->caxis.which,
@@ -2603,7 +2638,7 @@ void HandleJoystickEvent(Event *event)
 
     case SDL_CONTROLLERBUTTONDOWN:
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONDOWN: device %d, button %d",
+      Debug("joystick", "SDL_CONTROLLERBUTTONDOWN: device %d, button %d",
            event->cbutton.which, event->cbutton.button);
 #endif
       setJoystickButton(event->cbutton.which,
@@ -2613,7 +2648,7 @@ void HandleJoystickEvent(Event *event)
 
     case SDL_CONTROLLERBUTTONUP:
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONUP: device %d, button %d",
+      Debug("joystick", "SDL_CONTROLLERBUTTONUP: device %d, button %d",
            event->cbutton.which, event->cbutton.button);
 #endif
       setJoystickButton(event->cbutton.which,
@@ -2626,7 +2661,7 @@ void HandleJoystickEvent(Event *event)
        break;
 
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_JOYAXISMOTION: device %d, axis %d: %d",
+      Debug("joystick", "SDL_JOYAXISMOTION: device %d, axis %d: %d",
            event->jaxis.which, event->jaxis.axis, event->jaxis.value);
 #endif
       if (event->jaxis.axis < 4)
@@ -2640,7 +2675,7 @@ void HandleJoystickEvent(Event *event)
        break;
 
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_JOYBUTTONDOWN: device %d, button %d",
+      Debug("joystick", "SDL_JOYBUTTONDOWN: device %d, button %d",
            event->jbutton.which, event->jbutton.button);
 #endif
       if (event->jbutton.button < 4)
@@ -2654,7 +2689,7 @@ void HandleJoystickEvent(Event *event)
        break;
 
 #if DEBUG_JOYSTICKS
-      Error(ERR_DEBUG, "SDL_JOYBUTTONUP: device %d, button %d",
+      Debug("joystick", "SDL_JOYBUTTONUP: device %d, button %d",
            event->jbutton.which, event->jbutton.button);
 #endif
       if (event->jbutton.button < 4)
@@ -2686,19 +2721,17 @@ void SDLInitJoysticks(void)
     SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
 
     if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0)
-    {
-      Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
-      return;
-    }
+      Fail("SDL_Init() failed: %s", SDL_GetError());
 
     num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_base);
 
     // the included game controller base mappings should always be found
     if (num_mappings == -1)
-      Error(ERR_WARN, "no game controller base mappings found");
+      Warn("no game controller base mappings found");
 #if DEBUG_JOYSTICKS
     else
-      Error(ERR_INFO, "%d game controller base mapping(s) added", num_mappings);
+      Debug("joystick", "%d game controller base mapping(s) added",
+           num_mappings);
 #endif
 
     num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_user);
@@ -2706,11 +2739,12 @@ void SDLInitJoysticks(void)
 #if DEBUG_JOYSTICKS
     // the personal game controller user mappings may or may not be found
     if (num_mappings == -1)
-      Error(ERR_WARN, "no game controller user mappings found");
+      Warn("no game controller user mappings found");
     else
-      Error(ERR_INFO, "%d game controller user mapping(s) added", num_mappings);
+      Debug("joystick", , "%d game controller user mapping(s) added",
+           num_mappings);
 
-    Error(ERR_INFO, "%d joystick(s) found:", SDL_NumJoysticks());
+    Debug("joystick", "%d joystick(s) found:", SDL_NumJoysticks());
 #endif
 
     checked_free(mappings_file_base);
@@ -2732,7 +2766,7 @@ void SDLInitJoysticks(void)
        type = "joystick";
       }
 
-      Error(ERR_INFO, "- joystick %d (%s): '%s'",
+      Debug("joystick", "- joystick %d (%s): '%s'",
            i, type, (name ? name : "(Unknown)"));
     }
 #endif
@@ -2748,7 +2782,7 @@ void SDLInitJoysticks(void)
     if (joystick_nr >= SDL_NumJoysticks())
     {
       if (setup.input[i].use_joystick && print_warning)
-       Error(ERR_WARN, "cannot find joystick %d", joystick_nr);
+       Warn("cannot find joystick %d", joystick_nr);
 
       joystick_nr = -1;
     }
@@ -2767,7 +2801,7 @@ void SDLInitJoysticks(void)
     if (SDLOpenJoystick(i))
       joystick.status = JOYSTICK_ACTIVATED;
     else if (print_warning)
-      Error(ERR_WARN, "cannot open joystick %d", i);
+      Warn("cannot open joystick %d", i);
   }
 
   SDLClearJoystickState();