src/render/software/SDL_render_sw.c
changeset 6528 e978048ced60
parent 6332 019660f4cc2b
child 6529 9094fcfd378d
     1.1 --- a/src/render/software/SDL_render_sw.c	Mon Oct 01 00:56:58 2012 -0700
     1.2 +++ b/src/render/software/SDL_render_sw.c	Mon Oct 01 20:59:33 2012 -0700
     1.3 @@ -56,16 +56,16 @@
     1.4  static int SW_UpdateViewport(SDL_Renderer * renderer);
     1.5  static int SW_RenderClear(SDL_Renderer * renderer);
     1.6  static int SW_RenderDrawPoints(SDL_Renderer * renderer,
     1.7 -                               const SDL_Point * points, int count);
     1.8 +                               const SDL_FPoint * points, int count);
     1.9  static int SW_RenderDrawLines(SDL_Renderer * renderer,
    1.10 -                              const SDL_Point * points, int count);
    1.11 +                              const SDL_FPoint * points, int count);
    1.12  static int SW_RenderFillRects(SDL_Renderer * renderer,
    1.13 -                              const SDL_Rect * rects, int count);
    1.14 +                              const SDL_FRect * rects, int count);
    1.15  static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    1.16 -                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    1.17 +                         const SDL_Rect * srcrect, const SDL_FRect * dstrect);
    1.18  static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
    1.19 -                          const SDL_Rect * srcrect, const SDL_Rect * dstrect,
    1.20 -                          const double angle, const SDL_Point * center, const SDL_RendererFlip flip);
    1.21 +                          const SDL_Rect * srcrect, const SDL_FRect * dstrect,
    1.22 +                          const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
    1.23  static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.24                                 Uint32 format, void * pixels, int pitch);
    1.25  static void SW_RenderPresent(SDL_Renderer * renderer);
    1.26 @@ -344,28 +344,35 @@
    1.27  }
    1.28  
    1.29  static int
    1.30 -SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
    1.31 +SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
    1.32                      int count)
    1.33  {
    1.34      SDL_Surface *surface = SW_ActivateRenderer(renderer);
    1.35 -    SDL_Point *temp = NULL;
    1.36 -    int status;
    1.37 +    SDL_Point *final_points;
    1.38 +    int i, status;
    1.39  
    1.40      if (!surface) {
    1.41          return -1;
    1.42      }
    1.43  
    1.44 +    final_points = SDL_stack_alloc(SDL_Point, count);
    1.45 +    if (!final_points) {
    1.46 +        SDL_OutOfMemory();
    1.47 +        return -1;
    1.48 +    }
    1.49      if (renderer->viewport.x || renderer->viewport.y) {
    1.50 -        int i;
    1.51 -        int x = renderer->viewport.x;
    1.52 -        int y = renderer->viewport.y;
    1.53 +        float x = renderer->viewport.x * renderer->scale.x;
    1.54 +        float y = renderer->viewport.y * renderer->scale.y;
    1.55  
    1.56 -        temp = SDL_stack_alloc(SDL_Point, count);
    1.57          for (i = 0; i < count; ++i) {
    1.58 -            temp[i].x = x + points[i].x;
    1.59 -            temp[i].y = y + points[i].x;
    1.60 +            final_points[i].x = (int)(x + points[i].x);
    1.61 +            final_points[i].y = (int)(y + points[i].y);
    1.62          }
    1.63 -        points = temp;
    1.64 +    } else {
    1.65 +        for (i = 0; i < count; ++i) {
    1.66 +            final_points[i].x = (int)points[i].x;
    1.67 +            final_points[i].y = (int)points[i].y;
    1.68 +        }
    1.69      }
    1.70  
    1.71      /* Draw the points! */
    1.72 @@ -374,43 +381,48 @@
    1.73                                     renderer->r, renderer->g, renderer->b,
    1.74                                     renderer->a);
    1.75  
    1.76 -        status = SDL_DrawPoints(surface, points, count, color);
    1.77 +        status = SDL_DrawPoints(surface, final_points, count, color);
    1.78      } else {
    1.79 -        status = SDL_BlendPoints(surface, points, count,
    1.80 +        status = SDL_BlendPoints(surface, final_points, count,
    1.81                                  renderer->blendMode,
    1.82                                  renderer->r, renderer->g, renderer->b,
    1.83                                  renderer->a);
    1.84      }
    1.85 +    SDL_stack_free(final_points);
    1.86  
    1.87 -    if (temp) {
    1.88 -        SDL_stack_free(temp);
    1.89 -    }
    1.90      return status;
    1.91  }
    1.92  
    1.93  static int
    1.94 -SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
    1.95 +SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
    1.96                     int count)
    1.97  {
    1.98      SDL_Surface *surface = SW_ActivateRenderer(renderer);
    1.99 -    SDL_Point *temp = NULL;
   1.100 -    int status;
   1.101 +    SDL_Point *final_points;
   1.102 +    int i, status;
   1.103  
   1.104      if (!surface) {
   1.105          return -1;
   1.106      }
   1.107  
   1.108 +    final_points = SDL_stack_alloc(SDL_Point, count);
   1.109 +    if (!final_points) {
   1.110 +        SDL_OutOfMemory();
   1.111 +        return -1;
   1.112 +    }
   1.113      if (renderer->viewport.x || renderer->viewport.y) {
   1.114 -        int i;
   1.115 -        int x = renderer->viewport.x;
   1.116 -        int y = renderer->viewport.y;
   1.117 +        float x = renderer->viewport.x * renderer->scale.x;
   1.118 +        float y = renderer->viewport.y * renderer->scale.y;
   1.119  
   1.120 -        temp = SDL_stack_alloc(SDL_Point, count);
   1.121          for (i = 0; i < count; ++i) {
   1.122 -            temp[i].x = x + points[i].x;
   1.123 -            temp[i].y = y + points[i].y;
   1.124 +            final_points[i].x = (int)(x + points[i].x);
   1.125 +            final_points[i].y = (int)(y + points[i].y);
   1.126          }
   1.127 -        points = temp;
   1.128 +    } else {
   1.129 +        for (i = 0; i < count; ++i) {
   1.130 +            final_points[i].x = (int)points[i].x;
   1.131 +            final_points[i].y = (int)points[i].y;
   1.132 +        }
   1.133      }
   1.134  
   1.135      /* Draw the lines! */
   1.136 @@ -419,80 +431,91 @@
   1.137                                     renderer->r, renderer->g, renderer->b,
   1.138                                     renderer->a);
   1.139  
   1.140 -        status = SDL_DrawLines(surface, points, count, color);
   1.141 +        status = SDL_DrawLines(surface, final_points, count, color);
   1.142      } else {
   1.143 -        status = SDL_BlendLines(surface, points, count,
   1.144 +        status = SDL_BlendLines(surface, final_points, count,
   1.145                                  renderer->blendMode,
   1.146                                  renderer->r, renderer->g, renderer->b,
   1.147                                  renderer->a);
   1.148      }
   1.149 +    SDL_stack_free(final_points);
   1.150  
   1.151 -    if (temp) {
   1.152 -        SDL_stack_free(temp);
   1.153 -    }
   1.154      return status;
   1.155  }
   1.156  
   1.157  static int
   1.158 -SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
   1.159 +SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
   1.160  {
   1.161      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.162 -    SDL_Rect *temp = NULL;
   1.163 -    int status;
   1.164 +    SDL_Rect *final_rects;
   1.165 +    int i, status;
   1.166 +
   1.167 +    if (!surface) {
   1.168 +        return -1;
   1.169 +    }
   1.170 +
   1.171 +    final_rects = SDL_stack_alloc(SDL_Rect, count);
   1.172 +    if (!final_rects) {
   1.173 +        SDL_OutOfMemory();
   1.174 +        return -1;
   1.175 +    }
   1.176 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.177 +        float x = renderer->viewport.x * renderer->scale.x;
   1.178 +        float y = renderer->viewport.y * renderer->scale.y;
   1.179 +
   1.180 +        for (i = 0; i < count; ++i) {
   1.181 +            final_rects[i].x = (int)(x + rects[i].x);
   1.182 +            final_rects[i].y = (int)(y + rects[i].y);
   1.183 +            final_rects[i].w = SDL_max((int)rects[i].w, 1);
   1.184 +            final_rects[i].h = SDL_max((int)rects[i].h, 1);
   1.185 +        }
   1.186 +    } else {
   1.187 +        for (i = 0; i < count; ++i) {
   1.188 +            final_rects[i].x = (int)rects[i].x;
   1.189 +            final_rects[i].y = (int)rects[i].y;
   1.190 +            final_rects[i].w = SDL_max((int)rects[i].w, 1);
   1.191 +            final_rects[i].h = SDL_max((int)rects[i].h, 1);
   1.192 +        }
   1.193 +    }
   1.194 +
   1.195 +    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   1.196 +        Uint32 color = SDL_MapRGBA(surface->format,
   1.197 +                                   renderer->r, renderer->g, renderer->b,
   1.198 +                                   renderer->a);
   1.199 +        status = SDL_FillRects(surface, final_rects, count, color);
   1.200 +    } else {
   1.201 +        status = SDL_BlendFillRects(surface, final_rects, count,
   1.202 +                                    renderer->blendMode,
   1.203 +                                    renderer->r, renderer->g, renderer->b,
   1.204 +                                    renderer->a);
   1.205 +    }
   1.206 +    SDL_stack_free(final_rects);
   1.207 +
   1.208 +    return status;
   1.209 +}
   1.210 +
   1.211 +static int
   1.212 +SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   1.213 +              const SDL_Rect * srcrect, const SDL_FRect * dstrect)
   1.214 +{
   1.215 +    SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.216 +    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
   1.217 +    SDL_Rect final_rect;
   1.218  
   1.219      if (!surface) {
   1.220          return -1;
   1.221      }
   1.222  
   1.223      if (renderer->viewport.x || renderer->viewport.y) {
   1.224 -        int i;
   1.225 -        int x = renderer->viewport.x;
   1.226 -        int y = renderer->viewport.y;
   1.227 +        final_rect.x = (int)((renderer->viewport.x * renderer->scale.x) + dstrect->x);
   1.228 +        final_rect.y = (int)((renderer->viewport.y * renderer->scale.y) + dstrect->y);
   1.229 +    } else {
   1.230 +        final_rect.x = (int)dstrect->x;
   1.231 +        final_rect.y = (int)dstrect->y;
   1.232 +    }
   1.233 +    final_rect.w = (int)dstrect->w;
   1.234 +    final_rect.h = (int)dstrect->h;
   1.235  
   1.236 -        temp = SDL_stack_alloc(SDL_Rect, count);
   1.237 -        for (i = 0; i < count; ++i) {
   1.238 -            temp[i].x = x + rects[i].x;
   1.239 -            temp[i].y = y + rects[i].y;
   1.240 -            temp[i].w = rects[i].w;
   1.241 -            temp[i].h = rects[i].h;
   1.242 -        }
   1.243 -        rects = temp;
   1.244 -    }
   1.245 -
   1.246 -    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   1.247 -        Uint32 color = SDL_MapRGBA(surface->format,
   1.248 -                                   renderer->r, renderer->g, renderer->b,
   1.249 -                                   renderer->a);
   1.250 -        status = SDL_FillRects(surface, rects, count, color);
   1.251 -    } else {
   1.252 -        status = SDL_BlendFillRects(surface, rects, count,
   1.253 -                                    renderer->blendMode,
   1.254 -                                    renderer->r, renderer->g, renderer->b,
   1.255 -                                    renderer->a);
   1.256 -    }
   1.257 -
   1.258 -    if (temp) {
   1.259 -        SDL_stack_free(temp);
   1.260 -    }
   1.261 -    return status;
   1.262 -}
   1.263 -
   1.264 -static int
   1.265 -SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   1.266 -              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
   1.267 -{
   1.268 -    SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.269 -    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
   1.270 -    SDL_Rect final_rect = *dstrect;
   1.271 -
   1.272 -    if (!surface) {
   1.273 -        return -1;
   1.274 -    }
   1.275 -
   1.276 -    if (renderer->viewport.x || renderer->viewport.y) {
   1.277 -        final_rect.x += renderer->viewport.x;
   1.278 -        final_rect.y += renderer->viewport.y;
   1.279 -    }
   1.280      if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) {
   1.281          return SDL_BlitSurface(src, srcrect, surface, &final_rect);
   1.282      } else {
   1.283 @@ -514,12 +537,12 @@
   1.284  
   1.285  static int
   1.286  SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
   1.287 -                const SDL_Rect * srcrect, const SDL_Rect * dstrect,
   1.288 -                const double angle, const SDL_Point * center, const SDL_RendererFlip flip)
   1.289 +                const SDL_Rect * srcrect, const SDL_FRect * dstrect,
   1.290 +                const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
   1.291  {
   1.292      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.293      SDL_Surface *src = (SDL_Surface *) texture->driverdata;
   1.294 -    SDL_Rect final_rect = *dstrect, tmp_rect;
   1.295 +    SDL_Rect final_rect, tmp_rect;
   1.296      SDL_Surface *surface_rotated, *surface_scaled;
   1.297      Uint32 colorkey;
   1.298      int retval, dstwidth, dstheight, abscenterx, abscentery;
   1.299 @@ -530,27 +553,33 @@
   1.300      }
   1.301  
   1.302      if (renderer->viewport.x || renderer->viewport.y) {
   1.303 -        final_rect.x += renderer->viewport.x;
   1.304 -        final_rect.y += renderer->viewport.y;
   1.305 +        final_rect.x = (int)((renderer->viewport.x * renderer->scale.x) + dstrect->x);
   1.306 +        final_rect.y = (int)((renderer->viewport.y * renderer->scale.y) + dstrect->y);
   1.307 +    } else {
   1.308 +        final_rect.x = (int)dstrect->x;
   1.309 +        final_rect.y = (int)dstrect->y;
   1.310      }
   1.311 +    final_rect.w = (int)dstrect->w;
   1.312 +    final_rect.h = (int)dstrect->h;
   1.313  
   1.314      surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel,
   1.315                                            src->format->Rmask, src->format->Gmask,
   1.316                                            src->format->Bmask, src->format->Amask );
   1.317 -    SDL_GetColorKey(src, &colorkey);
   1.318 -    SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey);
   1.319 -    tmp_rect = final_rect;
   1.320 -    tmp_rect.x = 0;
   1.321 -    tmp_rect.y = 0;
   1.322      if (surface_scaled) {
   1.323 +        SDL_GetColorKey(src, &colorkey);
   1.324 +        SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey);
   1.325 +        tmp_rect = final_rect;
   1.326 +        tmp_rect.x = 0;
   1.327 +        tmp_rect.y = 0;
   1.328 +
   1.329          retval = SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect);
   1.330          if (!retval) {
   1.331              _rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle);
   1.332              surface_rotated = _rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
   1.333              if(surface_rotated) {
   1.334                  /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
   1.335 -                abscenterx = final_rect.x + center->x;
   1.336 -                abscentery = final_rect.y + center->y;
   1.337 +                abscenterx = final_rect.x + (int)center->x;
   1.338 +                abscentery = final_rect.y + (int)center->y;
   1.339                  /* Compensate the angle inversion to match the behaviour of the other backends */
   1.340                  sangle = -sangle;
   1.341