[cppcheck] Part 2: Some further style fixes etc.
[supertux.git] / src / video / sdl / sdl_painter.cpp
index b47c7f1..5a68c5a 100644 (file)
 
 #include "SDL.h"
 
+#include "util/log.hpp"
 #include "video/drawing_request.hpp"
 #include "video/sdl/sdl_texture.hpp"
 
+namespace {
+
+SDL_BlendMode blend2sdl(const Blend& blend)
+{
+  if (blend.sfactor == GL_ONE &&
+      blend.dfactor == GL_ZERO)
+  {
+    return SDL_BLENDMODE_NONE;
+  }
+  else if (blend.sfactor == GL_SRC_ALPHA &&
+           blend.dfactor == GL_ONE_MINUS_SRC_ALPHA)
+  {
+    return SDL_BLENDMODE_BLEND;
+  }
+  else if (blend.sfactor == GL_SRC_ALPHA &&
+           blend.dfactor == GL_ONE)
+  {
+    return SDL_BLENDMODE_ADD;
+  }
+  else if (blend.sfactor == GL_DST_COLOR &&
+           blend.dfactor == GL_ZERO)
+  {
+    return SDL_BLENDMODE_MOD;
+  }
+  else
+  {
+    log_warning << "unknown blend mode combinations: sfactor=" << blend.sfactor << " dfactor=" << blend.dfactor << std::endl;
+    return SDL_BLENDMODE_BLEND;
+  }
+}
+
+} // namespace
+
 void
 SDLPainter::draw_surface(SDL_Renderer* renderer, const DrawingRequest& request)
 {
-  //FIXME: support parameters request.angle, request.blend
-  const Surface* surface = (const Surface*) request.request_data;
-  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
+  const Surface* surface = static_cast<const SurfaceRequest*>(request.request_data)->surface;
+  std::shared_ptr<SDLTexture> sdltexture = std::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
 
   SDL_Rect dst_rect;
   dst_rect.x = request.pos.x;
@@ -40,51 +73,42 @@ SDLPainter::draw_surface(SDL_Renderer* renderer, const DrawingRequest& request)
   Uint8 a = static_cast<Uint8>(request.color.alpha * request.alpha * 255);
   SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b);
   SDL_SetTextureAlphaMod(sdltexture->get_texture(), a);
+  SDL_SetTextureBlendMode(sdltexture->get_texture(), blend2sdl(request.blend));
 
-  if (surface->get_flipx())
+  SDL_RendererFlip flip = SDL_FLIP_NONE;
+  if (surface->get_flipx() || request.drawing_effect & HORIZONTAL_FLIP)
   {
-    SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
+    flip = static_cast<SDL_RendererFlip>(flip | SDL_FLIP_HORIZONTAL);
   }
-  else
+
+  if (request.drawing_effect & VERTICAL_FLIP)
   {
-    switch(request.drawing_effect)
-    {
-      case VERTICAL_FLIP:
-        SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL);
-        break;
-
-      case HORIZONTAL_FLIP:
-        SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
-        break;
-
-      default:
-      case NO_EFFECT:
-        SDL_RenderCopy(renderer, sdltexture->get_texture(), NULL, &dst_rect);
-        break;
-    }
+    flip = static_cast<SDL_RendererFlip>(flip | SDL_FLIP_VERTICAL);
   }
+
+  SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, request.angle, NULL, flip);
 }
 
 void
 SDLPainter::draw_surface_part(SDL_Renderer* renderer, const DrawingRequest& request)
 {
-  //FIXME: support parameters request.angle, request.blend
-  const SurfacePartRequest* surface = (const SurfacePartRequest*) request.request_data;
-  const SurfacePartRequest* surfacepartrequest = (SurfacePartRequest*) request.request_data;
+  //FIXME: support parameters request.blend
+  const SurfacePartRequest* surface = static_cast<const SurfacePartRequest*>(request.request_data);
+  const SurfacePartRequest* surfacepartrequest = static_cast<SurfacePartRequest*>(request.request_data);
 
-  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->surface->get_texture());
+  std::shared_ptr<SDLTexture> sdltexture = std::dynamic_pointer_cast<SDLTexture>(surface->surface->get_texture());
 
   SDL_Rect src_rect;
-  src_rect.x = surfacepartrequest->source.x;
-  src_rect.y = surfacepartrequest->source.y;
-  src_rect.w = surfacepartrequest->size.x;
-  src_rect.h = surfacepartrequest->size.y;
+  src_rect.x = surfacepartrequest->srcrect.p1.x;
+  src_rect.y = surfacepartrequest->srcrect.p1.y;
+  src_rect.w = surfacepartrequest->srcrect.get_width();
+  src_rect.h = surfacepartrequest->srcrect.get_height();
 
   SDL_Rect dst_rect;
   dst_rect.x = request.pos.x;
   dst_rect.y = request.pos.y;
-  dst_rect.w = surfacepartrequest->size.x;
-  dst_rect.h = surfacepartrequest->size.y;
+  dst_rect.w = surfacepartrequest->dstsize.width;
+  dst_rect.h = surfacepartrequest->dstsize.height;
 
   Uint8 r = static_cast<Uint8>(request.color.red * 255);
   Uint8 g = static_cast<Uint8>(request.color.green * 255);
@@ -92,54 +116,43 @@ SDLPainter::draw_surface_part(SDL_Renderer* renderer, const DrawingRequest& requ
   Uint8 a = static_cast<Uint8>(request.color.alpha * request.alpha * 255);
   SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b);
   SDL_SetTextureAlphaMod(sdltexture->get_texture(), a);
+  SDL_SetTextureBlendMode(sdltexture->get_texture(), blend2sdl(request.blend));
 
-  if (surface->surface->get_flipx())
+  SDL_RendererFlip flip = SDL_FLIP_NONE;
+  if (surface->surface->get_flipx() || request.drawing_effect & HORIZONTAL_FLIP)
   {
-    SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
+    flip = static_cast<SDL_RendererFlip>(flip | SDL_FLIP_HORIZONTAL);
   }
-  else
+
+  if (request.drawing_effect & VERTICAL_FLIP)
   {
-    switch(request.drawing_effect)
-    {
-      case VERTICAL_FLIP:
-        SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL);
-        break;
-
-      case HORIZONTAL_FLIP:
-        SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
-        break;
-
-      default:
-      case NO_EFFECT:
-        SDL_RenderCopy(renderer, sdltexture->get_texture(), &src_rect, &dst_rect);
-        break;
-    }
+    flip = static_cast<SDL_RendererFlip>(flip | SDL_FLIP_VERTICAL);
   }
+
+  SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, request.angle, NULL, flip);
 }
 
 void
 SDLPainter::draw_gradient(SDL_Renderer* renderer, const DrawingRequest& request)
 {
-  const GradientRequest* gradientrequest 
-    = (GradientRequest*) request.request_data;
+  const GradientRequest* gradientrequest
+    = static_cast<GradientRequest*>(request.request_data);
   const Color& top = gradientrequest->top;
   const Color& bottom = gradientrequest->bottom;
 
-  SDL_Rect viewport;
-  SDL_RenderGetViewport(renderer, &viewport);
-
   // calculate the maximum number of steps needed for the gradient
   int n = static_cast<int>(std::max(std::max(fabsf(top.red - bottom.red),
                                              fabsf(top.green - bottom.green)),
                                     std::max(fabsf(top.blue - bottom.blue),
                                              fabsf(top.alpha - bottom.alpha))) * 255);
+  n = std::max(n, 1);
   for(int i = 0; i < n; ++i)
   {
     SDL_Rect rect;
     rect.x = 0;
-    rect.y = viewport.h * i / n;
-    rect.w = viewport.w;
-    rect.h = (viewport.h * (i+1) / n) - rect.y;
+    rect.y = SCREEN_HEIGHT * i / n;
+    rect.w = SCREEN_WIDTH;
+    rect.h = (SCREEN_HEIGHT * (i+1) / n) - rect.y;
 
     float p = static_cast<float>(i+1) / static_cast<float>(n);
     Uint8 r = static_cast<Uint8>(((1.0f - p) * top.red + p * bottom.red)  * 255);
@@ -157,7 +170,7 @@ void
 SDLPainter::draw_filled_rect(SDL_Renderer* renderer, const DrawingRequest& request)
 {
   const FillRectRequest* fillrectrequest
-    = (FillRectRequest*) request.request_data;
+    = static_cast<FillRectRequest*>(request.request_data);
 
   SDL_Rect rect;
   rect.x = request.pos.x;
@@ -233,10 +246,7 @@ SDLPainter::draw_filled_rect(SDL_Renderer* renderer, const DrawingRequest& reque
 void
 SDLPainter::draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& request)
 {
-  const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data;
-  
-  SDL_Rect viewport;
-  SDL_RenderGetViewport(renderer, &viewport);
+  const InverseEllipseRequest* ellipse = static_cast<InverseEllipseRequest*>(request.request_data);
 
   float x = request.pos.x;
   float w = ellipse->size.x;
@@ -249,7 +259,7 @@ SDLPainter::draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& r
   int slices = std::min(static_cast<int>(ellipse->size.y), max_slices);
   for(int i = 0; i < slices; ++i)
   {
-    float p = ((static_cast<float>(i) + 0.5f) / static_cast<float>(slices)) * 2.0f - 1.0f; 
+    float p = ((static_cast<float>(i) + 0.5f) / static_cast<float>(slices)) * 2.0f - 1.0f;
     int xoff = static_cast<int>(sqrtf(1.0f - p*p) * w / 2);
 
     SDL_Rect& left  = rects[2*i+0];
@@ -262,7 +272,7 @@ SDLPainter::draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& r
 
     right.x = x + xoff;
     right.y = left.y;
-    right.w = viewport.w - right.x;
+    right.w = SCREEN_WIDTH - right.x;
     right.h = left.h;
   }
 
@@ -271,13 +281,13 @@ SDLPainter::draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& r
 
   top_rect.x = 0;
   top_rect.y = 0;
-  top_rect.w = viewport.w;
+  top_rect.w = SCREEN_WIDTH;
   top_rect.h = top;
 
   bottom_rect.x = 0;
   bottom_rect.y = top + h;
-  bottom_rect.w = viewport.w;
-  bottom_rect.h = viewport.h - bottom_rect.y;
+  bottom_rect.w = SCREEN_WIDTH;
+  bottom_rect.h = SCREEN_HEIGHT - bottom_rect.y;
 
   Uint8 r = static_cast<Uint8>(ellipse->color.red * 255);
   Uint8 g = static_cast<Uint8>(ellipse->color.green * 255);