In the process of adding rectangle drawing
authorSam Lantinga <slouken@libsdl.org>
Fri, 18 Dec 2009 07:03:09 +0000
changeset 3593b931bcfd94a0
parent 3592 25dc4a86132c
child 3594 c8bed77b0386
In the process of adding rectangle drawing
include/SDL_surface.h
src/video/SDL_blendfillrect.c
src/video/SDL_blendrect.c
src/video/SDL_draw.h
src/video/SDL_drawrect.c
     1.1 --- a/include/SDL_surface.h	Thu Dec 17 07:47:03 2009 +0000
     1.2 +++ b/include/SDL_surface.h	Fri Dec 18 07:03:09 2009 +0000
     1.3 @@ -416,7 +416,7 @@
     1.4   *  
     1.5   *  \return 0 on success, or -1 on error.
     1.6   */
     1.7 -extern DECLSPEC int SDLCALL SDL_BlendPoint
     1.8 +extern DECLSPEC int SDLCALL SDL_BlendDrawPoint
     1.9      (SDL_Surface * dst, int x, int y,
    1.10       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.11  extern DECLSPEC int SDLCALL SDL_BlendPoints
    1.12 @@ -449,6 +449,35 @@
    1.13       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.14  
    1.15  /**
    1.16 + *  Draws the given rectangle with \c color.
    1.17 + *  
    1.18 + *  If \c rect is NULL, the whole surface will be outlined with \c color.
    1.19 + *  
    1.20 + *  The color should be a pixel of the format used by the surface, and 
    1.21 + *  can be generated by the SDL_MapRGB() function.
    1.22 + *  
    1.23 + *  \return 0 on success, or -1 on error.
    1.24 + */
    1.25 +extern DECLSPEC int SDLCALL SDL_DrawRect
    1.26 +    (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
    1.27 +extern DECLSPEC int SDLCALL SDL_DrawRects
    1.28 +    (SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);
    1.29 +
    1.30 +/**
    1.31 + *  Blends the given rectangle with \c color.
    1.32 + *  
    1.33 + *  If \c rect is NULL, the whole surface will have a blended outline of \c color.
    1.34 + *  
    1.35 + *  \return 0 on success, or -1 on error.
    1.36 + */
    1.37 +extern DECLSPEC int SDLCALL SDL_BlendRect
    1.38 +    (SDL_Surface * dst, const SDL_Rect * rect,
    1.39 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.40 +extern DECLSPEC int SDLCALL SDL_BlendRects
    1.41 +    (SDL_Surface * dst, const SDL_Rect ** rects, int count,
    1.42 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.43 +
    1.44 +/**
    1.45   *  Performs a fast fill of the given rectangle with \c color.
    1.46   *  
    1.47   *  If \c rect is NULL, the whole surface will be filled with \c color.
    1.48 @@ -466,14 +495,14 @@
    1.49  /**
    1.50   *  Blends an RGBA value into the given rectangle.
    1.51   *  
    1.52 - *  If \c rect is NULL, the whole surface will be filled with \c color.
    1.53 + *  If \c rect is NULL, the whole surface will be blended with \c color.
    1.54   *  
    1.55   *  \return This function returns 0 on success, or -1 on error.
    1.56   */
    1.57 -extern DECLSPEC int SDLCALL SDL_BlendRect
    1.58 +extern DECLSPEC int SDLCALL SDL_BlendFillRect
    1.59      (SDL_Surface * dst, const SDL_Rect * rect,
    1.60       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.61 -extern DECLSPEC int SDLCALL SDL_BlendRects
    1.62 +extern DECLSPEC int SDLCALL SDL_BlendFillRects
    1.63      (SDL_Surface * dst, const SDL_Rect ** rects, int count,
    1.64       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    1.65  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/video/SDL_blendfillrect.c	Fri Dec 18 07:03:09 2009 +0000
     2.3 @@ -0,0 +1,357 @@
     2.4 +/*
     2.5 +    SDL - Simple DirectMedia Layer
     2.6 +    Copyright (C) 1997-2009 Sam Lantinga
     2.7 +
     2.8 +    This library is free software; you can redistribute it and/or
     2.9 +    modify it under the terms of the GNU Lesser General Public
    2.10 +    License as published by the Free Software Foundation; either
    2.11 +    version 2.1 of the License, or (at your option) any later version.
    2.12 +
    2.13 +    This library is distributed in the hope that it will be useful,
    2.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    2.16 +    Lesser General Public License for more details.
    2.17 +
    2.18 +    You should have received a copy of the GNU Lesser General Public
    2.19 +    License along with this library; if not, write to the Free Software
    2.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    2.21 +
    2.22 +    Sam Lantinga
    2.23 +    slouken@libsdl.org
    2.24 +*/
    2.25 +#include "SDL_config.h"
    2.26 +
    2.27 +#include "SDL_video.h"
    2.28 +#include "SDL_draw.h"
    2.29 +
    2.30 +static int
    2.31 +SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
    2.32 +                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    2.33 +{
    2.34 +    unsigned inva = 0xff - a;
    2.35 +
    2.36 +    switch (blendMode) {
    2.37 +    case SDL_BLENDMODE_BLEND:
    2.38 +        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
    2.39 +        break;
    2.40 +    case SDL_BLENDMODE_ADD:
    2.41 +        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
    2.42 +        break;
    2.43 +    case SDL_BLENDMODE_MOD:
    2.44 +        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
    2.45 +        break;
    2.46 +    default:
    2.47 +        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
    2.48 +        break;
    2.49 +    }
    2.50 +    return 0;
    2.51 +}
    2.52 +
    2.53 +static int
    2.54 +SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
    2.55 +                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    2.56 +{
    2.57 +    unsigned inva = 0xff - a;
    2.58 +
    2.59 +    switch (blendMode) {
    2.60 +    case SDL_BLENDMODE_BLEND:
    2.61 +        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
    2.62 +        break;
    2.63 +    case SDL_BLENDMODE_ADD:
    2.64 +        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
    2.65 +        break;
    2.66 +    case SDL_BLENDMODE_MOD:
    2.67 +        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
    2.68 +        break;
    2.69 +    default:
    2.70 +        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
    2.71 +        break;
    2.72 +    }
    2.73 +    return 0;
    2.74 +}
    2.75 +
    2.76 +static int
    2.77 +SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
    2.78 +                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    2.79 +{
    2.80 +    unsigned inva = 0xff - a;
    2.81 +
    2.82 +    switch (blendMode) {
    2.83 +    case SDL_BLENDMODE_BLEND:
    2.84 +        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
    2.85 +        break;
    2.86 +    case SDL_BLENDMODE_ADD:
    2.87 +        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
    2.88 +        break;
    2.89 +    case SDL_BLENDMODE_MOD:
    2.90 +        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
    2.91 +        break;
    2.92 +    default:
    2.93 +        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
    2.94 +        break;
    2.95 +    }
    2.96 +    return 0;
    2.97 +}
    2.98 +
    2.99 +static int
   2.100 +SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
   2.101 +                           int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   2.102 +{
   2.103 +    unsigned inva = 0xff - a;
   2.104 +
   2.105 +    switch (blendMode) {
   2.106 +    case SDL_BLENDMODE_BLEND:
   2.107 +        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
   2.108 +        break;
   2.109 +    case SDL_BLENDMODE_ADD:
   2.110 +        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
   2.111 +        break;
   2.112 +    case SDL_BLENDMODE_MOD:
   2.113 +        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
   2.114 +        break;
   2.115 +    default:
   2.116 +        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
   2.117 +        break;
   2.118 +    }
   2.119 +    return 0;
   2.120 +}
   2.121 +
   2.122 +static int
   2.123 +SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
   2.124 +                      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   2.125 +{
   2.126 +    SDL_PixelFormat *fmt = dst->format;
   2.127 +    unsigned inva = 0xff - a;
   2.128 +
   2.129 +    switch (fmt->BytesPerPixel) {
   2.130 +    case 2:
   2.131 +        switch (blendMode) {
   2.132 +        case SDL_BLENDMODE_BLEND:
   2.133 +            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
   2.134 +            break;
   2.135 +        case SDL_BLENDMODE_ADD:
   2.136 +            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
   2.137 +            break;
   2.138 +        case SDL_BLENDMODE_MOD:
   2.139 +            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
   2.140 +            break;
   2.141 +        default:
   2.142 +            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
   2.143 +            break;
   2.144 +        }
   2.145 +        return 0;
   2.146 +    case 4:
   2.147 +        switch (blendMode) {
   2.148 +        case SDL_BLENDMODE_BLEND:
   2.149 +            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
   2.150 +            break;
   2.151 +        case SDL_BLENDMODE_ADD:
   2.152 +            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
   2.153 +            break;
   2.154 +        case SDL_BLENDMODE_MOD:
   2.155 +            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
   2.156 +            break;
   2.157 +        default:
   2.158 +            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
   2.159 +            break;
   2.160 +        }
   2.161 +        return 0;
   2.162 +    default:
   2.163 +        SDL_Unsupported();
   2.164 +        return -1;
   2.165 +    }
   2.166 +}
   2.167 +
   2.168 +static int
   2.169 +SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
   2.170 +                       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   2.171 +{
   2.172 +    SDL_PixelFormat *fmt = dst->format;
   2.173 +    unsigned inva = 0xff - a;
   2.174 +
   2.175 +    switch (fmt->BytesPerPixel) {
   2.176 +    case 4:
   2.177 +        switch (blendMode) {
   2.178 +        case SDL_BLENDMODE_BLEND:
   2.179 +            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
   2.180 +            break;
   2.181 +        case SDL_BLENDMODE_ADD:
   2.182 +            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
   2.183 +            break;
   2.184 +        case SDL_BLENDMODE_MOD:
   2.185 +            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
   2.186 +            break;
   2.187 +        default:
   2.188 +            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
   2.189 +            break;
   2.190 +        }
   2.191 +        return 0;
   2.192 +    default:
   2.193 +        SDL_Unsupported();
   2.194 +        return -1;
   2.195 +    }
   2.196 +}
   2.197 +
   2.198 +int
   2.199 +SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
   2.200 +                  int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   2.201 +{
   2.202 +    SDL_Rect clipped;
   2.203 +
   2.204 +    if (!dst) {
   2.205 +        SDL_SetError("Passed NULL destination surface");
   2.206 +        return -1;
   2.207 +    }
   2.208 +
   2.209 +    if (blendMode < SDL_BLENDMODE_BLEND) {
   2.210 +        Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a);
   2.211 +        return SDL_FillRect(dst, rect, color);
   2.212 +    }
   2.213 +
   2.214 +    /* This function doesn't work on surfaces < 8 bpp */
   2.215 +    if (dst->format->BitsPerPixel < 8) {
   2.216 +        SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
   2.217 +        return -1;
   2.218 +    }
   2.219 +
   2.220 +    /* If 'rect' == NULL, then fill the whole surface */
   2.221 +    if (rect) {
   2.222 +        /* Perform clipping */
   2.223 +        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   2.224 +            return 0;
   2.225 +        }
   2.226 +        rect = &clipped;
   2.227 +    } else {
   2.228 +        rect = &dst->clip_rect;
   2.229 +    }
   2.230 +
   2.231 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   2.232 +        r = DRAW_MUL(r, a);
   2.233 +        g = DRAW_MUL(g, a);
   2.234 +        b = DRAW_MUL(b, a);
   2.235 +    }
   2.236 +
   2.237 +    switch (dst->format->BitsPerPixel) {
   2.238 +    case 15:
   2.239 +        switch (dst->format->Rmask) {
   2.240 +        case 0x7C00:
   2.241 +            return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
   2.242 +        }
   2.243 +        break;
   2.244 +    case 16:
   2.245 +        switch (dst->format->Rmask) {
   2.246 +        case 0xF800:
   2.247 +            return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
   2.248 +        }
   2.249 +        break;
   2.250 +    case 32:
   2.251 +        switch (dst->format->Rmask) {
   2.252 +        case 0x00FF0000:
   2.253 +            if (!dst->format->Amask) {
   2.254 +                return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a);
   2.255 +            } else {
   2.256 +                return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
   2.257 +            }
   2.258 +            break;
   2.259 +        }
   2.260 +        break;
   2.261 +    default:
   2.262 +        break;
   2.263 +    }
   2.264 +
   2.265 +    if (!dst->format->Amask) {
   2.266 +        return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
   2.267 +    } else {
   2.268 +        return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
   2.269 +    }
   2.270 +}
   2.271 +
   2.272 +int
   2.273 +SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
   2.274 +                   int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   2.275 +{
   2.276 +    SDL_Rect clipped;
   2.277 +    int i;
   2.278 +    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
   2.279 +                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
   2.280 +    int status = 0;
   2.281 +
   2.282 +    if (!dst) {
   2.283 +        SDL_SetError("Passed NULL destination surface");
   2.284 +        return -1;
   2.285 +    }
   2.286 +
   2.287 +    if (blendMode < SDL_BLENDMODE_BLEND) {
   2.288 +        Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a);
   2.289 +        return SDL_FillRects(dst, rects, color);
   2.290 +    }
   2.291 +
   2.292 +    /* This function doesn't work on surfaces < 8 bpp */
   2.293 +    if (dst->format->BitsPerPixel < 8) {
   2.294 +        SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
   2.295 +        return -1;
   2.296 +    }
   2.297 +
   2.298 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   2.299 +        r = DRAW_MUL(r, a);
   2.300 +        g = DRAW_MUL(g, a);
   2.301 +        b = DRAW_MUL(b, a);
   2.302 +    }
   2.303 +
   2.304 +    /* FIXME: Does this function pointer slow things down significantly? */
   2.305 +    switch (dst->format->BitsPerPixel) {
   2.306 +    case 15:
   2.307 +        switch (dst->format->Rmask) {
   2.308 +        case 0x7C00:
   2.309 +            func = SDL_BlendFillRect_RGB555;
   2.310 +        }
   2.311 +        break;
   2.312 +    case 16:
   2.313 +        switch (dst->format->Rmask) {
   2.314 +        case 0xF800:
   2.315 +            func = SDL_BlendFillRect_RGB565;
   2.316 +        }
   2.317 +        break;
   2.318 +    case 32:
   2.319 +        switch (dst->format->Rmask) {
   2.320 +        case 0x00FF0000:
   2.321 +            if (!dst->format->Amask) {
   2.322 +                func = SDL_BlendFillRect_RGB888;
   2.323 +            } else {
   2.324 +                func = SDL_BlendFillRect_ARGB8888;
   2.325 +            }
   2.326 +            break;
   2.327 +        }
   2.328 +        break;
   2.329 +    default:
   2.330 +        break;
   2.331 +    }
   2.332 +
   2.333 +    if (!func) {
   2.334 +        if (!dst->format->Amask) {
   2.335 +            func = SDL_BlendFillRect_RGB;
   2.336 +        } else {
   2.337 +            func = SDL_BlendFillRect_RGBA;
   2.338 +        }
   2.339 +    }
   2.340 +
   2.341 +    for (i = 0; i < count; ++i) {
   2.342 +        const SDL_Rect * rect = rects[i];
   2.343 +
   2.344 +        /* If 'rect' == NULL, then fill the whole surface */
   2.345 +        if (rect) {
   2.346 +            /* Perform clipping */
   2.347 +            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   2.348 +                continue;
   2.349 +            }
   2.350 +            rect = &clipped;
   2.351 +        } else {
   2.352 +            rect = &dst->clip_rect;
   2.353 +        }
   2.354 +
   2.355 +        status = func(dst, rect, blendMode, r, g, b, a);
   2.356 +    }
   2.357 +    return status;
   2.358 +}
   2.359 +
   2.360 +/* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/video/SDL_blendrect.c	Thu Dec 17 07:47:03 2009 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,347 +0,0 @@
     3.4 -/*
     3.5 -    SDL - Simple DirectMedia Layer
     3.6 -    Copyright (C) 1997-2009 Sam Lantinga
     3.7 -
     3.8 -    This library is free software; you can redistribute it and/or
     3.9 -    modify it under the terms of the GNU Lesser General Public
    3.10 -    License as published by the Free Software Foundation; either
    3.11 -    version 2.1 of the License, or (at your option) any later version.
    3.12 -
    3.13 -    This library is distributed in the hope that it will be useful,
    3.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 -    Lesser General Public License for more details.
    3.17 -
    3.18 -    You should have received a copy of the GNU Lesser General Public
    3.19 -    License along with this library; if not, write to the Free Software
    3.20 -    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    3.21 -
    3.22 -    Sam Lantinga
    3.23 -    slouken@libsdl.org
    3.24 -*/
    3.25 -#include "SDL_config.h"
    3.26 -
    3.27 -#include "SDL_video.h"
    3.28 -#include "SDL_draw.h"
    3.29 -
    3.30 -static int
    3.31 -SDL_BlendRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    3.32 -                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    3.33 -{
    3.34 -    unsigned inva = 0xff - a;
    3.35 -
    3.36 -    switch (blendMode) {
    3.37 -    case SDL_BLENDMODE_BLEND:
    3.38 -        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
    3.39 -        break;
    3.40 -    case SDL_BLENDMODE_ADD:
    3.41 -        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
    3.42 -        break;
    3.43 -    case SDL_BLENDMODE_MOD:
    3.44 -        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
    3.45 -        break;
    3.46 -    default:
    3.47 -        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
    3.48 -        break;
    3.49 -    }
    3.50 -    return 0;
    3.51 -}
    3.52 -
    3.53 -static int
    3.54 -SDL_BlendRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    3.55 -                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    3.56 -{
    3.57 -    unsigned inva = 0xff - a;
    3.58 -
    3.59 -    switch (blendMode) {
    3.60 -    case SDL_BLENDMODE_BLEND:
    3.61 -        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
    3.62 -        break;
    3.63 -    case SDL_BLENDMODE_ADD:
    3.64 -        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
    3.65 -        break;
    3.66 -    case SDL_BLENDMODE_MOD:
    3.67 -        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
    3.68 -        break;
    3.69 -    default:
    3.70 -        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
    3.71 -        break;
    3.72 -    }
    3.73 -    return 0;
    3.74 -}
    3.75 -
    3.76 -static int
    3.77 -SDL_BlendRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    3.78 -                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    3.79 -{
    3.80 -    unsigned inva = 0xff - a;
    3.81 -
    3.82 -    switch (blendMode) {
    3.83 -    case SDL_BLENDMODE_BLEND:
    3.84 -        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
    3.85 -        break;
    3.86 -    case SDL_BLENDMODE_ADD:
    3.87 -        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
    3.88 -        break;
    3.89 -    case SDL_BLENDMODE_MOD:
    3.90 -        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
    3.91 -        break;
    3.92 -    default:
    3.93 -        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
    3.94 -        break;
    3.95 -    }
    3.96 -    return 0;
    3.97 -}
    3.98 -
    3.99 -static int
   3.100 -SDL_BlendRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
   3.101 -                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   3.102 -{
   3.103 -    unsigned inva = 0xff - a;
   3.104 -
   3.105 -    switch (blendMode) {
   3.106 -    case SDL_BLENDMODE_BLEND:
   3.107 -        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
   3.108 -        break;
   3.109 -    case SDL_BLENDMODE_ADD:
   3.110 -        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
   3.111 -        break;
   3.112 -    case SDL_BLENDMODE_MOD:
   3.113 -        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
   3.114 -        break;
   3.115 -    default:
   3.116 -        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
   3.117 -        break;
   3.118 -    }
   3.119 -    return 0;
   3.120 -}
   3.121 -
   3.122 -static int
   3.123 -SDL_BlendRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
   3.124 -                  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   3.125 -{
   3.126 -    SDL_PixelFormat *fmt = dst->format;
   3.127 -    unsigned inva = 0xff - a;
   3.128 -
   3.129 -    switch (fmt->BytesPerPixel) {
   3.130 -    case 2:
   3.131 -        switch (blendMode) {
   3.132 -        case SDL_BLENDMODE_BLEND:
   3.133 -            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
   3.134 -            break;
   3.135 -        case SDL_BLENDMODE_ADD:
   3.136 -            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
   3.137 -            break;
   3.138 -        case SDL_BLENDMODE_MOD:
   3.139 -            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
   3.140 -            break;
   3.141 -        default:
   3.142 -            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
   3.143 -            break;
   3.144 -        }
   3.145 -        return 0;
   3.146 -    case 4:
   3.147 -        switch (blendMode) {
   3.148 -        case SDL_BLENDMODE_BLEND:
   3.149 -            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
   3.150 -            break;
   3.151 -        case SDL_BLENDMODE_ADD:
   3.152 -            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
   3.153 -            break;
   3.154 -        case SDL_BLENDMODE_MOD:
   3.155 -            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
   3.156 -            break;
   3.157 -        default:
   3.158 -            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
   3.159 -            break;
   3.160 -        }
   3.161 -        return 0;
   3.162 -    default:
   3.163 -        SDL_Unsupported();
   3.164 -        return -1;
   3.165 -    }
   3.166 -}
   3.167 -
   3.168 -static int
   3.169 -SDL_BlendRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
   3.170 -                   Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   3.171 -{
   3.172 -    SDL_PixelFormat *fmt = dst->format;
   3.173 -    unsigned inva = 0xff - a;
   3.174 -
   3.175 -    switch (fmt->BytesPerPixel) {
   3.176 -    case 4:
   3.177 -        switch (blendMode) {
   3.178 -        case SDL_BLENDMODE_BLEND:
   3.179 -            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
   3.180 -            break;
   3.181 -        case SDL_BLENDMODE_ADD:
   3.182 -            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
   3.183 -            break;
   3.184 -        case SDL_BLENDMODE_MOD:
   3.185 -            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
   3.186 -            break;
   3.187 -        default:
   3.188 -            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
   3.189 -            break;
   3.190 -        }
   3.191 -        return 0;
   3.192 -    default:
   3.193 -        SDL_Unsupported();
   3.194 -        return -1;
   3.195 -    }
   3.196 -}
   3.197 -
   3.198 -int
   3.199 -SDL_BlendRect(SDL_Surface * dst, const SDL_Rect * rect,
   3.200 -              int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   3.201 -{
   3.202 -    SDL_Rect clipped;
   3.203 -
   3.204 -    if (!dst) {
   3.205 -        SDL_SetError("Passed NULL destination surface");
   3.206 -        return -1;
   3.207 -    }
   3.208 -
   3.209 -    /* This function doesn't work on surfaces < 8 bpp */
   3.210 -    if (dst->format->BitsPerPixel < 8) {
   3.211 -        SDL_SetError("SDL_BlendRect(): Unsupported surface format");
   3.212 -        return -1;
   3.213 -    }
   3.214 -
   3.215 -    /* If 'rect' == NULL, then fill the whole surface */
   3.216 -    if (rect) {
   3.217 -        /* Perform clipping */
   3.218 -        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   3.219 -            return 0;
   3.220 -        }
   3.221 -        rect = &clipped;
   3.222 -    } else {
   3.223 -        rect = &dst->clip_rect;
   3.224 -    }
   3.225 -
   3.226 -    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   3.227 -        r = DRAW_MUL(r, a);
   3.228 -        g = DRAW_MUL(g, a);
   3.229 -        b = DRAW_MUL(b, a);
   3.230 -    }
   3.231 -
   3.232 -    switch (dst->format->BitsPerPixel) {
   3.233 -    case 15:
   3.234 -        switch (dst->format->Rmask) {
   3.235 -        case 0x7C00:
   3.236 -            return SDL_BlendRect_RGB555(dst, rect, blendMode, r, g, b, a);
   3.237 -        }
   3.238 -        break;
   3.239 -    case 16:
   3.240 -        switch (dst->format->Rmask) {
   3.241 -        case 0xF800:
   3.242 -            return SDL_BlendRect_RGB565(dst, rect, blendMode, r, g, b, a);
   3.243 -        }
   3.244 -        break;
   3.245 -    case 32:
   3.246 -        switch (dst->format->Rmask) {
   3.247 -        case 0x00FF0000:
   3.248 -            if (!dst->format->Amask) {
   3.249 -                return SDL_BlendRect_RGB888(dst, rect, blendMode, r, g, b, a);
   3.250 -            } else {
   3.251 -                return SDL_BlendRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
   3.252 -            }
   3.253 -            break;
   3.254 -        }
   3.255 -        break;
   3.256 -    default:
   3.257 -        break;
   3.258 -    }
   3.259 -
   3.260 -    if (!dst->format->Amask) {
   3.261 -        return SDL_BlendRect_RGB(dst, rect, blendMode, r, g, b, a);
   3.262 -    } else {
   3.263 -        return SDL_BlendRect_RGBA(dst, rect, blendMode, r, g, b, a);
   3.264 -    }
   3.265 -}
   3.266 -
   3.267 -int
   3.268 -SDL_BlendRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
   3.269 -               int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   3.270 -{
   3.271 -    SDL_Rect clipped;
   3.272 -    int i;
   3.273 -    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
   3.274 -                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
   3.275 -    int status = 0;
   3.276 -
   3.277 -    if (!dst) {
   3.278 -        SDL_SetError("Passed NULL destination surface");
   3.279 -        return -1;
   3.280 -    }
   3.281 -
   3.282 -    /* This function doesn't work on surfaces < 8 bpp */
   3.283 -    if (dst->format->BitsPerPixel < 8) {
   3.284 -        SDL_SetError("SDL_BlendRects(): Unsupported surface format");
   3.285 -        return -1;
   3.286 -    }
   3.287 -
   3.288 -    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   3.289 -        r = DRAW_MUL(r, a);
   3.290 -        g = DRAW_MUL(g, a);
   3.291 -        b = DRAW_MUL(b, a);
   3.292 -    }
   3.293 -
   3.294 -    /* FIXME: Does this function pointer slow things down significantly? */
   3.295 -    switch (dst->format->BitsPerPixel) {
   3.296 -    case 15:
   3.297 -        switch (dst->format->Rmask) {
   3.298 -        case 0x7C00:
   3.299 -            func = SDL_BlendRect_RGB555;
   3.300 -        }
   3.301 -        break;
   3.302 -    case 16:
   3.303 -        switch (dst->format->Rmask) {
   3.304 -        case 0xF800:
   3.305 -            func = SDL_BlendRect_RGB565;
   3.306 -        }
   3.307 -        break;
   3.308 -    case 32:
   3.309 -        switch (dst->format->Rmask) {
   3.310 -        case 0x00FF0000:
   3.311 -            if (!dst->format->Amask) {
   3.312 -                func = SDL_BlendRect_RGB888;
   3.313 -            } else {
   3.314 -                func = SDL_BlendRect_ARGB8888;
   3.315 -            }
   3.316 -            break;
   3.317 -        }
   3.318 -        break;
   3.319 -    default:
   3.320 -        break;
   3.321 -    }
   3.322 -
   3.323 -    if (!func) {
   3.324 -        if (!dst->format->Amask) {
   3.325 -            func = SDL_BlendRect_RGB;
   3.326 -        } else {
   3.327 -            func = SDL_BlendRect_RGBA;
   3.328 -        }
   3.329 -    }
   3.330 -
   3.331 -    for (i = 0; i < count; ++i) {
   3.332 -        const SDL_Rect * rect = rects[i];
   3.333 -
   3.334 -        /* If 'rect' == NULL, then fill the whole surface */
   3.335 -        if (rect) {
   3.336 -            /* Perform clipping */
   3.337 -            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   3.338 -                continue;
   3.339 -            }
   3.340 -            rect = &clipped;
   3.341 -        } else {
   3.342 -            rect = &dst->clip_rect;
   3.343 -        }
   3.344 -
   3.345 -        status = func(dst, rect, blendMode, r, g, b, a);
   3.346 -    }
   3.347 -    return status;
   3.348 -}
   3.349 -
   3.350 -/* vi: set ts=4 sw=4 expandtab: */
     4.1 --- a/src/video/SDL_draw.h	Thu Dec 17 07:47:03 2009 +0000
     4.2 +++ b/src/video/SDL_draw.h	Fri Dec 18 07:03:09 2009 +0000
     4.3 @@ -341,7 +341,44 @@
     4.4  #define DRAWLINE(x0, y0, x1, y1, op)	BRESENHAM(x0, y0, x1, y1, op)
     4.5  
     4.6  /*
     4.7 - * Define blend fill macro
     4.8 + * Define draw rect macro
     4.9 + */
    4.10 +#define DRAWRECT(type, op) \
    4.11 +do { \
    4.12 +    int width = rect->w; \
    4.13 +    int height = rect->h; \
    4.14 +    int pitch = (dst->pitch / dst->format->BytesPerPixel); \
    4.15 +    int skip = pitch - width; \
    4.16 +    type *pixel; \
    4.17 +    pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
    4.18 +    { int n = (width+3)/4; \
    4.19 +        switch (width & 3) { \
    4.20 +        case 0: do {   op; pixel++; \
    4.21 +        case 3:        op; pixel++; \
    4.22 +        case 2:        op; pixel++; \
    4.23 +        case 1:        op; pixel++; \
    4.24 +                } while ( --n > 0 ); \
    4.25 +        } \
    4.26 +    } \
    4.27 +    pixel += skip; \
    4.28 +    width -= 1; \
    4.29 +    height -= 2; \
    4.30 +    while (height--) { \
    4.31 +        op; pixel += width; op; pixel += skip; \
    4.32 +    } \
    4.33 +    { int n = (width+3)/4; \
    4.34 +        switch (width & 3) { \
    4.35 +        case 0: do {   op; pixel++; \
    4.36 +        case 3:        op; pixel++; \
    4.37 +        case 2:        op; pixel++; \
    4.38 +        case 1:        op; pixel++; \
    4.39 +                } while ( --n > 0 ); \
    4.40 +        } \
    4.41 +    } \
    4.42 +} while (0)
    4.43 +
    4.44 +/*
    4.45 + * Define fill rect macro
    4.46   */
    4.47  
    4.48  #define FILLRECT(type, op) \
    4.49 @@ -365,8 +402,4 @@
    4.50      } \
    4.51  } while (0)
    4.52  
    4.53 -/*
    4.54 - * Define blend line macro
    4.55 - */
    4.56 -
    4.57  /* vi: set ts=4 sw=4 expandtab: */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/video/SDL_drawrect.c	Fri Dec 18 07:03:09 2009 +0000
     5.3 @@ -0,0 +1,432 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997-2009 Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Lesser General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2.1 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Lesser General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Lesser General Public
    5.19 +    License along with this library; if not, write to the Free Software
    5.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +#include "SDL_config.h"
    5.26 +
    5.27 +#include "SDL_video.h"
    5.28 +#include "SDL_blit.h"
    5.29 +
    5.30 +
    5.31 +#ifdef __SSE__
    5.32 +/* *INDENT-OFF* */
    5.33 +
    5.34 +#ifdef _MSC_VER
    5.35 +#define SSE_BEGIN \
    5.36 +    __m128 c128; \
    5.37 +    c128.m128_u32[0] = color; \
    5.38 +    c128.m128_u32[1] = color; \
    5.39 +    c128.m128_u32[2] = color; \
    5.40 +    c128.m128_u32[3] = color;
    5.41 +#else
    5.42 +#define SSE_BEGIN \
    5.43 +    DECLARE_ALIGNED(Uint32, cccc[4], 16); \
    5.44 +    cccc[0] = color; \
    5.45 +    cccc[1] = color; \
    5.46 +    cccc[2] = color; \
    5.47 +    cccc[3] = color; \
    5.48 +    __m128 c128 = *(__m128 *)cccc;
    5.49 +#endif
    5.50 +
    5.51 +#define SSE_WORK \
    5.52 +    for (i = n / 64; i--;) { \
    5.53 +        _mm_stream_ps((float *)(p+0), c128); \
    5.54 +        _mm_stream_ps((float *)(p+16), c128); \
    5.55 +        _mm_stream_ps((float *)(p+32), c128); \
    5.56 +        _mm_stream_ps((float *)(p+48), c128); \
    5.57 +        p += 64; \
    5.58 +    }
    5.59 +
    5.60 +#define SSE_END
    5.61 +
    5.62 +#define DEFINE_SSE_FILLRECT(bpp, type) \
    5.63 +static void \
    5.64 +SDL_DrawRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
    5.65 +{ \
    5.66 +    SSE_BEGIN; \
    5.67 + \
    5.68 +    while (h--) { \
    5.69 +        int i, n = w * bpp; \
    5.70 +        Uint8 *p = pixels; \
    5.71 + \
    5.72 +        if (n > 63) { \
    5.73 +            int adjust = 16 - ((uintptr_t)p & 15); \
    5.74 +            if (adjust < 16) { \
    5.75 +                n -= adjust; \
    5.76 +                adjust /= bpp; \
    5.77 +                while (adjust--) { \
    5.78 +                    *((type *)p) = (type)color; \
    5.79 +                    p += bpp; \
    5.80 +                } \
    5.81 +            } \
    5.82 +            SSE_WORK; \
    5.83 +        } \
    5.84 +        if (n & 63) { \
    5.85 +            int remainder = (n & 63); \
    5.86 +            remainder /= bpp; \
    5.87 +            while (remainder--) { \
    5.88 +                *((type *)p) = (type)color; \
    5.89 +                p += bpp; \
    5.90 +            } \
    5.91 +        } \
    5.92 +        pixels += pitch; \
    5.93 +    } \
    5.94 + \
    5.95 +    SSE_END; \
    5.96 +}
    5.97 +
    5.98 +static void
    5.99 +SDL_DrawRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
   5.100 +{
   5.101 +    SSE_BEGIN;
   5.102 +
   5.103 +    while (h--) {
   5.104 +        int i, n = w;
   5.105 +        Uint8 *p = pixels;
   5.106 +
   5.107 +        if (n > 63) {
   5.108 +            int adjust = 16 - ((uintptr_t)p & 15);
   5.109 +            if (adjust) {
   5.110 +                n -= adjust;
   5.111 +                SDL_memset(p, color, adjust);
   5.112 +                p += adjust;
   5.113 +            }
   5.114 +            SSE_WORK;
   5.115 +        }
   5.116 +        if (n & 63) {
   5.117 +            int remainder = (n & 63);
   5.118 +            SDL_memset(p, color, remainder);
   5.119 +            p += remainder;
   5.120 +        }
   5.121 +        pixels += pitch;
   5.122 +    }
   5.123 +
   5.124 +    SSE_END;
   5.125 +}
   5.126 +/*DEFINE_SSE_FILLRECT(1, Uint8)*/
   5.127 +DEFINE_SSE_FILLRECT(2, Uint16)
   5.128 +DEFINE_SSE_FILLRECT(4, Uint32)
   5.129 +
   5.130 +/* *INDENT-ON* */
   5.131 +#endif /* __SSE__ */
   5.132 +
   5.133 +#ifdef __MMX__
   5.134 +/* *INDENT-OFF* */
   5.135 +
   5.136 +#define MMX_BEGIN \
   5.137 +    __m64 c64 = _mm_set_pi32(color, color)
   5.138 +
   5.139 +#define MMX_WORK \
   5.140 +    for (i = n / 64; i--;) { \
   5.141 +        _mm_stream_pi((__m64 *)(p+0), c64); \
   5.142 +        _mm_stream_pi((__m64 *)(p+8), c64); \
   5.143 +        _mm_stream_pi((__m64 *)(p+16), c64); \
   5.144 +        _mm_stream_pi((__m64 *)(p+24), c64); \
   5.145 +        _mm_stream_pi((__m64 *)(p+32), c64); \
   5.146 +        _mm_stream_pi((__m64 *)(p+40), c64); \
   5.147 +        _mm_stream_pi((__m64 *)(p+48), c64); \
   5.148 +        _mm_stream_pi((__m64 *)(p+56), c64); \
   5.149 +        p += 64; \
   5.150 +    }
   5.151 +
   5.152 +#define MMX_END \
   5.153 +    _mm_empty()
   5.154 +
   5.155 +#define DEFINE_MMX_FILLRECT(bpp, type) \
   5.156 +static void \
   5.157 +SDL_DrawRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
   5.158 +{ \
   5.159 +    MMX_BEGIN; \
   5.160 + \
   5.161 +    while (h--) { \
   5.162 +        int i, n = w * bpp; \
   5.163 +        Uint8 *p = pixels; \
   5.164 + \
   5.165 +        if (n > 63) { \
   5.166 +            int adjust = 8 - ((uintptr_t)p & 7); \
   5.167 +            if (adjust < 8) { \
   5.168 +                n -= adjust; \
   5.169 +                adjust /= bpp; \
   5.170 +                while (adjust--) { \
   5.171 +                    *((type *)p) = (type)color; \
   5.172 +                    p += bpp; \
   5.173 +                } \
   5.174 +            } \
   5.175 +            MMX_WORK; \
   5.176 +        } \
   5.177 +        if (n & 63) { \
   5.178 +            int remainder = (n & 63); \
   5.179 +            remainder /= bpp; \
   5.180 +            while (remainder--) { \
   5.181 +                *((type *)p) = (type)color; \
   5.182 +                p += bpp; \
   5.183 +            } \
   5.184 +        } \
   5.185 +        pixels += pitch; \
   5.186 +    } \
   5.187 + \
   5.188 +    MMX_END; \
   5.189 +}
   5.190 +
   5.191 +static void
   5.192 +SDL_DrawRect1MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
   5.193 +{
   5.194 +    MMX_BEGIN;
   5.195 +
   5.196 +    while (h--) {
   5.197 +        int i, n = w;
   5.198 +        Uint8 *p = pixels;
   5.199 +
   5.200 +        if (n > 63) {
   5.201 +            int adjust = 8 - ((uintptr_t)p & 7);
   5.202 +            if (adjust) {
   5.203 +                n -= adjust;
   5.204 +                SDL_memset(p, color, adjust);
   5.205 +                p += adjust;
   5.206 +            }
   5.207 +            MMX_WORK;
   5.208 +        }
   5.209 +        if (n & 63) {
   5.210 +            int remainder = (n & 63);
   5.211 +            SDL_memset(p, color, remainder);
   5.212 +            p += remainder;
   5.213 +        }
   5.214 +        pixels += pitch;
   5.215 +    }
   5.216 +
   5.217 +    MMX_END;
   5.218 +}
   5.219 +/*DEFINE_MMX_FILLRECT(1, Uint8)*/
   5.220 +DEFINE_MMX_FILLRECT(2, Uint16)
   5.221 +DEFINE_MMX_FILLRECT(4, Uint32)
   5.222 +
   5.223 +/* *INDENT-ON* */
   5.224 +#endif /* __MMX__ */
   5.225 +
   5.226 +static void
   5.227 +SDL_DrawRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
   5.228 +{
   5.229 +    while (h--) {
   5.230 +        int n = w;
   5.231 +        Uint8 *p = pixels;
   5.232 +
   5.233 +        if (n > 3) {
   5.234 +            switch ((uintptr_t) p & 3) {
   5.235 +            case 1:
   5.236 +                *p++ = (Uint8) color;
   5.237 +                --n;
   5.238 +            case 2:
   5.239 +                *p++ = (Uint8) color;
   5.240 +                --n;
   5.241 +            case 3:
   5.242 +                *p++ = (Uint8) color;
   5.243 +                --n;
   5.244 +            }
   5.245 +            SDL_memset4(p, color, (n >> 2));
   5.246 +        }
   5.247 +        if (n & 3) {
   5.248 +            p += (n & ~3);
   5.249 +            switch (n & 3) {
   5.250 +            case 3:
   5.251 +                *p++ = (Uint8) color;
   5.252 +            case 2:
   5.253 +                *p++ = (Uint8) color;
   5.254 +            case 1:
   5.255 +                *p++ = (Uint8) color;
   5.256 +            }
   5.257 +        }
   5.258 +        pixels += pitch;
   5.259 +    }
   5.260 +}
   5.261 +
   5.262 +static void
   5.263 +SDL_DrawRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
   5.264 +{
   5.265 +    while (h--) {
   5.266 +        int n = w;
   5.267 +        Uint16 *p = (Uint16 *) pixels;
   5.268 +
   5.269 +        if (n > 1) {
   5.270 +            if ((uintptr_t) p & 2) {
   5.271 +                *p++ = (Uint16) color;
   5.272 +                --n;
   5.273 +            }
   5.274 +            SDL_memset4(p, color, (n >> 1));
   5.275 +        }
   5.276 +        if (n & 1) {
   5.277 +            p[n - 1] = (Uint16) color;
   5.278 +        }
   5.279 +        pixels += pitch;
   5.280 +    }
   5.281 +}
   5.282 +
   5.283 +static void
   5.284 +SDL_DrawRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
   5.285 +{
   5.286 +    Uint8 r = (Uint8) ((color >> 16) & 0xFF);
   5.287 +    Uint8 g = (Uint8) ((color >> 8) & 0xFF);
   5.288 +    Uint8 b = (Uint8) (color & 0xFF);
   5.289 +
   5.290 +    while (h--) {
   5.291 +        int n = w;
   5.292 +        Uint8 *p = pixels;
   5.293 +
   5.294 +        while (n--) {
   5.295 +            *p++ = r;
   5.296 +            *p++ = g;
   5.297 +            *p++ = b;
   5.298 +        }
   5.299 +        pixels += pitch;
   5.300 +    }
   5.301 +}
   5.302 +
   5.303 +static void
   5.304 +SDL_DrawRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
   5.305 +{
   5.306 +    while (h--) {
   5.307 +        SDL_memset4(pixels, color, w);
   5.308 +        pixels += pitch;
   5.309 +    }
   5.310 +}
   5.311 +
   5.312 +/* 
   5.313 + * This function performs a fast fill of the given rectangle with 'color'
   5.314 + */
   5.315 +int
   5.316 +SDL_DrawRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
   5.317 +{
   5.318 +    SDL_Rect clipped;
   5.319 +    Uint8 *pixels;
   5.320 +
   5.321 +    if (!dst) {
   5.322 +        SDL_SetError("Passed NULL destination surface");
   5.323 +        return -1;
   5.324 +    }
   5.325 +
   5.326 +    /* This function doesn't work on surfaces < 8 bpp */
   5.327 +    if (dst->format->BitsPerPixel < 8) {
   5.328 +        SDL_SetError("SDL_DrawRect(): Unsupported surface format");
   5.329 +        return -1;
   5.330 +    }
   5.331 +
   5.332 +    /* If 'rect' == NULL, then fill the whole surface */
   5.333 +    if (rect) {
   5.334 +        /* Perform clipping */
   5.335 +        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   5.336 +            return 0;
   5.337 +        }
   5.338 +        rect = &clipped;
   5.339 +    } else {
   5.340 +        rect = &dst->clip_rect;
   5.341 +    }
   5.342 +
   5.343 +    /* Perform software fill */
   5.344 +    if (!dst->pixels) {
   5.345 +        SDL_SetError("SDL_DrawRect(): You must lock the surface");
   5.346 +        return (-1);
   5.347 +    }
   5.348 +
   5.349 +    pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
   5.350 +                                     rect->x * dst->format->BytesPerPixel;
   5.351 +
   5.352 +    switch (dst->format->BytesPerPixel) {
   5.353 +    case 1:
   5.354 +        {
   5.355 +            color |= (color << 8);
   5.356 +            color |= (color << 16);
   5.357 +#ifdef __SSE__
   5.358 +            if (SDL_HasSSE()) {
   5.359 +                SDL_DrawRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
   5.360 +                break;
   5.361 +            }
   5.362 +#endif
   5.363 +#ifdef __MMX__
   5.364 +            if (SDL_HasMMX()) {
   5.365 +                SDL_DrawRect1MMX(pixels, dst->pitch, color, rect->w, rect->h);
   5.366 +                break;
   5.367 +            }
   5.368 +#endif
   5.369 +            SDL_DrawRect1(pixels, dst->pitch, color, rect->w, rect->h);
   5.370 +            break;
   5.371 +        }
   5.372 +
   5.373 +    case 2:
   5.374 +        {
   5.375 +            color |= (color << 16);
   5.376 +#ifdef __SSE__
   5.377 +            if (SDL_HasSSE()) {
   5.378 +                SDL_DrawRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
   5.379 +                break;
   5.380 +            }
   5.381 +#endif
   5.382 +#ifdef __MMX__
   5.383 +            if (SDL_HasMMX()) {
   5.384 +                SDL_DrawRect2MMX(pixels, dst->pitch, color, rect->w, rect->h);
   5.385 +                break;
   5.386 +            }
   5.387 +#endif
   5.388 +            SDL_DrawRect2(pixels, dst->pitch, color, rect->w, rect->h);
   5.389 +            break;
   5.390 +        }
   5.391 +
   5.392 +    case 3:
   5.393 +        /* 24-bit RGB is a slow path, at least for now. */
   5.394 +        {
   5.395 +            SDL_DrawRect3(pixels, dst->pitch, color, rect->w, rect->h);
   5.396 +            break;
   5.397 +        }
   5.398 +
   5.399 +    case 4:
   5.400 +        {
   5.401 +#ifdef __SSE__
   5.402 +            if (SDL_HasSSE()) {
   5.403 +                SDL_DrawRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
   5.404 +                break;
   5.405 +            }
   5.406 +#endif
   5.407 +#ifdef __MMX__
   5.408 +            if (SDL_HasMMX()) {
   5.409 +                SDL_DrawRect4MMX(pixels, dst->pitch, color, rect->w, rect->h);
   5.410 +                break;
   5.411 +            }
   5.412 +#endif
   5.413 +            SDL_DrawRect4(pixels, dst->pitch, color, rect->w, rect->h);
   5.414 +            break;
   5.415 +        }
   5.416 +    }
   5.417 +
   5.418 +    /* We're done! */
   5.419 +    return 0;
   5.420 +}
   5.421 +
   5.422 +int
   5.423 +SDL_DrawRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
   5.424 +              Uint32 color)
   5.425 +{
   5.426 +    int i;
   5.427 +    int status = 0;
   5.428 +
   5.429 +    for (i = 0; i < count; ++i) {
   5.430 +        status = SDL_DrawRect(dst, rects[i], color);
   5.431 +    }
   5.432 +    return status;
   5.433 +}
   5.434 +
   5.435 +/* vi: set ts=4 sw=4 expandtab: */