added abstractions for alpha blending and color key handling for SDL/SDL2
[rocksndiamonds.git] / src / libgame / sdl.c
index 9b44b372a0965fb73e3d9c7e422812f21ae7161a..893f765351bf8c45a9a58e0cf3ddde11d61de68e 100644 (file)
@@ -223,34 +223,40 @@ static boolean equalSDLPixelFormat(SDL_PixelFormat *format1,
          format1->BytesPerPixel == format2->BytesPerPixel &&
          format1->Rmask         == format2->Rmask &&
          format1->Gmask         == format2->Gmask &&
-         format1->Bmask         == format2->Bmask &&
-         format1->Amask         == format2->Amask);
+         format1->Bmask         == format2->Bmask);
 }
 
-boolean SDLSetNativeSurface(SDL_Surface **surface)
+static Pixel SDLGetColorKey(SDL_Surface *surface)
 {
-  SDL_Surface *new_surface;
+  Pixel color_key;
 
-  if (surface == NULL ||
-      *surface == NULL ||
-      backbuffer == NULL ||
-      backbuffer->surface == NULL)
-    return FALSE;
+  if (SDL_GetColorKey(surface, &color_key) != 0)
+    return -1;
 
-  // if pixel format already optimized for destination surface, do nothing
-  if (equalSDLPixelFormat((*surface)->format, backbuffer->surface->format))
-    return FALSE;
+  return color_key;
+}
 
-  new_surface = SDL_ConvertSurface(*surface, backbuffer->surface->format, 0);
+static boolean SDLHasColorKey(SDL_Surface *surface)
+{
+  return (SDLGetColorKey(surface) != -1);
+}
 
-  if (new_surface == NULL)
-    Error(ERR_EXIT, "SDL_ConvertSurface() failed: %s", SDL_GetError());
+static boolean SDLHasAlpha(SDL_Surface *surface)
+{
+  SDL_BlendMode blend_mode;
 
-  SDL_FreeSurface(*surface);
+  if (SDL_GetSurfaceBlendMode(surface, &blend_mode) != 0)
+    return FALSE;
 
-  *surface = new_surface;
+  return (blend_mode == SDL_BLENDMODE_BLEND);
+}
 
-  return TRUE;
+static void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+{
+  SDL_BlendMode blend_mode = (set ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
+
+  SDL_SetSurfaceBlendMode(surface, blend_mode);
+  SDL_SetSurfaceAlphaMod(surface, alpha);
 }
 
 SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
@@ -279,21 +285,21 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
   return new_surface;
 }
 
-#else
-
 boolean SDLSetNativeSurface(SDL_Surface **surface)
 {
   SDL_Surface *new_surface;
 
   if (surface == NULL ||
       *surface == NULL ||
-      !video.initialized)
+      backbuffer == NULL ||
+      backbuffer->surface == NULL)
     return FALSE;
 
-  new_surface = SDL_DisplayFormat(*surface);
+  // if pixel format already optimized for destination surface, do nothing
+  if (equalSDLPixelFormat((*surface)->format, backbuffer->surface->format))
+    return FALSE;
 
-  if (new_surface == NULL)
-    Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+  new_surface = SDLGetNativeSurface(*surface);
 
   SDL_FreeSurface(*surface);
 
@@ -302,10 +308,38 @@ boolean SDLSetNativeSurface(SDL_Surface **surface)
   return TRUE;
 }
 
+#else
+
+static Pixel SDLGetColorKey(SDL_Surface *surface)
+{
+  if ((surface->flags & SDL_SRCCOLORKEY) == 0)
+    return -1;
+
+  return surface->format->colorkey;
+}
+
+static boolean SDLHasColorKey(SDL_Surface *surface)
+{
+  return (SDLGetColorKey(surface) != -1);
+}
+
+static boolean SDLHasAlpha(SDL_Surface *surface)
+{
+  return ((surface->flags & SDL_SRCALPHA) != 0);
+}
+
+static void SDLSetAlpha(SDL_Surface *surface, boolean set, int alpha)
+{
+  SDL_SetAlpha(surface, (set ? SDL_SRCALPHA : 0), alpha);
+}
+
 SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
 {
   SDL_Surface *new_surface;
 
+  if (surface == NULL)
+    return NULL;
+
   if (video.initialized)
     new_surface = SDL_DisplayFormat(surface);
   else
@@ -319,6 +353,24 @@ SDL_Surface *SDLGetNativeSurface(SDL_Surface *surface)
   return new_surface;
 }
 
+boolean SDLSetNativeSurface(SDL_Surface **surface)
+{
+  SDL_Surface *new_surface;
+
+  if (surface == NULL ||
+      *surface == NULL ||
+      !video.initialized)
+    return FALSE;
+
+  new_surface = SDLGetNativeSurface(*surface);
+
+  SDL_FreeSurface(*surface);
+
+  *surface = new_surface;
+
+  return TRUE;
+}
+
 #endif
 
 #if defined(TARGET_SDL2)