src/render/software/SDL_render_sw.c
changeset 6320 6077a1310907
parent 6283 03a7ceb3487b
child 6332 019660f4cc2b
     1.1 --- a/src/render/software/SDL_render_sw.c	Fri Jun 01 19:42:15 2012 -0300
     1.2 +++ b/src/render/software/SDL_render_sw.c	Fri Jun 01 19:51:08 2012 -0300
     1.3 @@ -24,6 +24,7 @@
     1.4  
     1.5  #include "../SDL_sysrender.h"
     1.6  #include "SDL_render_sw_c.h"
     1.7 +#include "SDL_hints.h"
     1.8  
     1.9  #include "SDL_draw.h"
    1.10  #include "SDL_blendfillrect.h"
    1.11 @@ -31,7 +32,7 @@
    1.12  #include "SDL_blendpoint.h"
    1.13  #include "SDL_drawline.h"
    1.14  #include "SDL_drawpoint.h"
    1.15 -
    1.16 +#include "SDL_rotate.h"
    1.17  
    1.18  /* SDL surface based renderer implementation */
    1.19  
    1.20 @@ -62,6 +63,9 @@
    1.21                                const SDL_Rect * rects, int count);
    1.22  static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    1.23                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    1.24 +static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
    1.25 +                          const SDL_Rect * srcrect, const SDL_Rect * dstrect,
    1.26 +                          const double angle, const SDL_Point * center, const SDL_RendererFlip flip);
    1.27  static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.28                                 Uint32 format, void * pixels, int pitch);
    1.29  static void SW_RenderPresent(SDL_Renderer * renderer);
    1.30 @@ -152,6 +156,7 @@
    1.31      renderer->RenderDrawLines = SW_RenderDrawLines;
    1.32      renderer->RenderFillRects = SW_RenderFillRects;
    1.33      renderer->RenderCopy = SW_RenderCopy;
    1.34 +    renderer->RenderCopyEx = SW_RenderCopyEx;
    1.35      renderer->RenderReadPixels = SW_RenderReadPixels;
    1.36      renderer->RenderPresent = SW_RenderPresent;
    1.37      renderer->DestroyTexture = SW_DestroyTexture;
    1.38 @@ -496,6 +501,102 @@
    1.39  }
    1.40  
    1.41  static int
    1.42 +GetScaleQuality(void)
    1.43 +{
    1.44 +    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
    1.45 +
    1.46 +    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
    1.47 +        return 0;
    1.48 +    } else {
    1.49 +        return 1;
    1.50 +    }
    1.51 +}
    1.52 +
    1.53 +static int
    1.54 +SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
    1.55 +                const SDL_Rect * srcrect, const SDL_Rect * dstrect,
    1.56 +                const double angle, const SDL_Point * center, const SDL_RendererFlip flip)
    1.57 +{
    1.58 +    SDL_Surface *surface = SW_ActivateRenderer(renderer);
    1.59 +    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
    1.60 +    SDL_Rect final_rect = *dstrect, tmp_rect;
    1.61 +    SDL_Surface *surface_rotated, *surface_scaled;
    1.62 +    SDL_Point final_rect_center;
    1.63 +    Uint32 colorkey;
    1.64 +    int retval, dstwidth, dstheight, abscenterx, abscentery;
    1.65 +    double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
    1.66 +
    1.67 +    if (!surface) {
    1.68 +        return -1;
    1.69 +    }
    1.70 +
    1.71 +    if (renderer->viewport.x || renderer->viewport.y) {
    1.72 +        final_rect.x += renderer->viewport.x;
    1.73 +        final_rect.y += renderer->viewport.y;
    1.74 +    }
    1.75 +
    1.76 +    surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel,
    1.77 +                                          src->format->Rmask, src->format->Gmask,
    1.78 +                                          src->format->Bmask, src->format->Amask );
    1.79 +    SDL_GetColorKey(src, &colorkey);
    1.80 +    SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey);
    1.81 +    tmp_rect = final_rect;
    1.82 +    tmp_rect.x = 0;
    1.83 +    tmp_rect.y = 0;
    1.84 +    if (surface_scaled) {
    1.85 +        retval = SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect);
    1.86 +        if (!retval) {
    1.87 +            _rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle);
    1.88 +            surface_rotated = _rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
    1.89 +            if(surface_rotated) {
    1.90 +                /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
    1.91 +                abscenterx = final_rect.x + center->x;
    1.92 +                abscentery = final_rect.y + center->y;
    1.93 +                /* Compensate the angle inversion to match the behaviour of the other backends */
    1.94 +                sangle = -sangle;
    1.95 +
    1.96 +                /* Top Left */
    1.97 +                px = final_rect.x - abscenterx;
    1.98 +                py = final_rect.y - abscentery;
    1.99 +                p1x = px * cangle - py * sangle + abscenterx;
   1.100 +                p1y = px * sangle + py * cangle + abscentery;
   1.101 +
   1.102 +                /* Top Right */
   1.103 +                px = final_rect.x + final_rect.w - abscenterx;
   1.104 +                py = final_rect.y - abscentery;
   1.105 +                p2x = px * cangle - py * sangle + abscenterx;
   1.106 +                p2y = px * sangle + py * cangle + abscentery;
   1.107 +
   1.108 +                /* Bottom Left */
   1.109 +                px = final_rect.x - abscenterx;
   1.110 +                py = final_rect.y + final_rect.h - abscentery;
   1.111 +                p3x = px * cangle - py * sangle + abscenterx;
   1.112 +                p3y = px * sangle + py * cangle + abscentery;
   1.113 +
   1.114 +                /* Bottom Right */
   1.115 +                px = final_rect.x + final_rect.w - abscenterx;
   1.116 +                py = final_rect.y + final_rect.h - abscentery;
   1.117 +                p4x = px * cangle - py * sangle + abscenterx;
   1.118 +                p4y = px * sangle + py * cangle + abscentery;
   1.119 +
   1.120 +                tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x));
   1.121 +                tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y));
   1.122 +                tmp_rect.w = dstwidth;
   1.123 +                tmp_rect.h = dstheight;
   1.124 +
   1.125 +                retval = SDL_BlitSurface(surface_rotated, NULL, surface, &tmp_rect);
   1.126 +                SDL_FreeSurface(surface_scaled);
   1.127 +                SDL_FreeSurface(surface_rotated);
   1.128 +                return retval;
   1.129 +            }
   1.130 +        }
   1.131 +        return retval;
   1.132 +    }
   1.133 +
   1.134 +    return -1;
   1.135 +}
   1.136 +
   1.137 +static int
   1.138  SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   1.139                      Uint32 format, void * pixels, int pitch)
   1.140  {