From cdf547eb06379d537091390f764b8fa9b34d9853 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 18 Dec 2009 07:41:59 +0000 Subject: [PATCH] Added SDL_DrawRect(), SDL_DrawRects(), SDL_BlendRect() and SDL_BlendRects() Fixed line drawing so when blending a sequence of lines there are no overlapping pixels drawn. --- src/video/SDL_blendfillrect.c | 10 - src/video/SDL_blendline.c | 96 ++++---- src/video/SDL_blendrect.c | 75 +++++++ src/video/SDL_draw.h | 8 +- src/video/SDL_drawline.c | 12 +- src/video/SDL_drawrect.c | 406 ++-------------------------------- 6 files changed, 165 insertions(+), 442 deletions(-) create mode 100644 src/video/SDL_blendrect.c diff --git a/src/video/SDL_blendfillrect.c b/src/video/SDL_blendfillrect.c index a86c55623..27800c4d1 100644 --- a/src/video/SDL_blendfillrect.c +++ b/src/video/SDL_blendfillrect.c @@ -203,11 +203,6 @@ SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, return -1; } - if (blendMode < SDL_BLENDMODE_BLEND) { - Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a); - return SDL_FillRect(dst, rect, color); - } - /* This function doesn't work on surfaces < 8 bpp */ if (dst->format->BitsPerPixel < 8) { SDL_SetError("SDL_BlendFillRect(): Unsupported surface format"); @@ -281,11 +276,6 @@ SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count, return -1; } - if (blendMode < SDL_BLENDMODE_BLEND) { - Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a); - return SDL_FillRects(dst, rects, color); - } - /* This function doesn't work on surfaces < 8 bpp */ if (dst->format->BitsPerPixel < 8) { SDL_SetError("SDL_BlendFillRects(): Unsupported surface format"); diff --git a/src/video/SDL_blendline.c b/src/video/SDL_blendline.c index 89ee45993..8aeda6be0 100644 --- a/src/video/SDL_blendline.c +++ b/src/video/SDL_blendline.c @@ -25,22 +25,23 @@ static int SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { unsigned inva = 0xff - a; switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB555); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB555, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB555); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB555, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB555); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB555, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB555); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB555, draw_end); break; } return 0; @@ -48,22 +49,23 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, static int SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { unsigned inva = 0xff - a; switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB565); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB565, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB565); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB565, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB565); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB565, draw_end); break; } return 0; @@ -71,22 +73,23 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, static int SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { unsigned inva = 0xff - a; switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB888, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB888, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB888, draw_end); break; } return 0; @@ -94,22 +97,23 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, static int SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { unsigned inva = 0xff - a; switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_ARGB8888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_ARGB8888, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_ARGB8888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_ARGB8888, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_ARGB8888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_ARGB8888, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ARGB8888); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ARGB8888, draw_end); break; } return 0; @@ -117,7 +121,8 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, static int SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -126,32 +131,32 @@ SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2, case 2: switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_BLEND_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_BLEND_RGB, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_ADD_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_ADD_RGB, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_MOD_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_MOD_RGB, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_RGB, draw_end); break; } return 0; case 4: switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGB, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGB, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGB, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGB); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGB, draw_end); break; } return 0; @@ -163,7 +168,8 @@ SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2, static int SDL_BlendLine_RGBA(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -172,16 +178,16 @@ SDL_BlendLine_RGBA(SDL_Surface * dst, int x1, int y1, int x2, int y2, case 4: switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGBA); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGBA, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGBA); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGBA, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGBA); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGBA, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGBA); + DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGBA, draw_end); break; } return 0; @@ -218,14 +224,14 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, switch (dst->format->Rmask) { case 0x7C00: return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g, - b, a); + b, a, SDL_TRUE); } break; case 16: switch (dst->format->Rmask) { case 0xF800: return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g, - b, a); + b, a, SDL_TRUE); } break; case 32: @@ -233,10 +239,10 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, case 0x00FF0000: if (!dst->format->Amask) { return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r, - g, b, a); + g, b, a, SDL_TRUE); } else { return SDL_BlendLine_ARGB8888(dst, x1, y1, x2, y2, blendMode, - r, g, b, a); + r, g, b, a, SDL_TRUE); } break; } @@ -246,9 +252,11 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, } if (!dst->format->Amask) { - return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, r, g, b, a); + return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, + r, g, b, a, SDL_TRUE); } else { - return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, r, g, b, a); + return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, + r, g, b, a, SDL_TRUE); } } @@ -260,7 +268,8 @@ SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, int x1, y1; int x2, y2; int (*func)(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL; + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end) = NULL; int status = 0; if (!dst) { @@ -328,7 +337,10 @@ SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, continue; } - status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a); + status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_FALSE); + } + if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { + SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, r, g, b, a); } return status; } diff --git a/src/video/SDL_blendrect.c b/src/video/SDL_blendrect.c new file mode 100644 index 000000000..1b1e9bb44 --- /dev/null +++ b/src/video/SDL_blendrect.c @@ -0,0 +1,75 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" + + +int +SDL_BlendRect(SDL_Surface * dst, const SDL_Rect * rect, + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_Rect full_rect; + SDL_Point points[5]; + + if (!dst) { + SDL_SetError("Passed NULL destination surface"); + return -1; + } + + /* If 'rect' == NULL, then outline the whole surface */ + if (!rect) { + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = dst->w; + full_rect.h = dst->h; + rect = &full_rect; + } + + points[0].x = rect->x; + points[0].y = rect->y; + points[1].x = rect->x+rect->w-1; + points[1].y = rect->y; + points[2].x = rect->x+rect->w-1; + points[2].y = rect->y+rect->h-1; + points[3].x = rect->x; + points[3].y = rect->y+rect->h-1; + points[4].x = rect->x; + points[4].y = rect->y; + return SDL_BlendLines(dst, points, 5, blendMode, r, g, b, a); +} + +int +SDL_BlendRects(SDL_Surface * dst, const SDL_Rect ** rects, int count, + int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + int i; + + for (i = 0; i < count; ++i) { + if (SDL_BlendRect(dst, rects[i], blendMode, r, g, b, a) < 0) { + return -1; + } + } + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_draw.h b/src/video/SDL_draw.h index 3974de0bb..779f3809e 100644 --- a/src/video/SDL_draw.h +++ b/src/video/SDL_draw.h @@ -283,7 +283,7 @@ do { \ #define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) -#define BRESENHAM(x1, y1, x2, y2, op) \ +#define BRESENHAM(x1, y1, x2, y2, op, draw_end) \ { \ int i, deltax, deltay, numpixels; \ int d, dinc1, dinc2; \ @@ -325,6 +325,9 @@ do { \ x = x1; \ y = y1; \ \ + if (!draw_end) { \ + --numpixels; \ + } \ for (i = 0; i < numpixels; ++i) { \ op(x, y); \ if (d < 0) { \ @@ -338,10 +341,11 @@ do { \ } \ } \ } -#define DRAWLINE(x0, y0, x1, y1, op) BRESENHAM(x0, y0, x1, y1, op) +#define DRAWLINE BRESENHAM /* * Define draw rect macro + * (not tested, this level of optimization not needed ... yet?) */ #define DRAWRECT(type, op) \ do { \ diff --git a/src/video/SDL_drawline.c b/src/video/SDL_drawline.c index f606a8a14..3d572ac62 100644 --- a/src/video/SDL_drawline.c +++ b/src/video/SDL_drawline.c @@ -46,16 +46,16 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) switch (dst->format->BytesPerPixel) { case 1: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1, SDL_TRUE); break; case 2: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2, SDL_TRUE); break; case 3: SDL_Unsupported(); return -1; case 4: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4, SDL_TRUE); break; } return 0; @@ -96,16 +96,16 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, switch (dst->format->BytesPerPixel) { case 1: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1, SDL_TRUE); break; case 2: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2, SDL_TRUE); break; case 3: SDL_Unsupported(); return -1; case 4: - DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4); + DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4, SDL_TRUE); break; } } diff --git a/src/video/SDL_drawrect.c b/src/video/SDL_drawrect.c index 6bb012896..e30ec3dd1 100644 --- a/src/video/SDL_drawrect.c +++ b/src/video/SDL_drawrect.c @@ -22,398 +22,39 @@ #include "SDL_config.h" #include "SDL_video.h" -#include "SDL_blit.h" -#ifdef __SSE__ -/* *INDENT-OFF* */ - -#ifdef _MSC_VER -#define SSE_BEGIN \ - __m128 c128; \ - c128.m128_u32[0] = color; \ - c128.m128_u32[1] = color; \ - c128.m128_u32[2] = color; \ - c128.m128_u32[3] = color; -#else -#define SSE_BEGIN \ - DECLARE_ALIGNED(Uint32, cccc[4], 16); \ - cccc[0] = color; \ - cccc[1] = color; \ - cccc[2] = color; \ - cccc[3] = color; \ - __m128 c128 = *(__m128 *)cccc; -#endif - -#define SSE_WORK \ - for (i = n / 64; i--;) { \ - _mm_stream_ps((float *)(p+0), c128); \ - _mm_stream_ps((float *)(p+16), c128); \ - _mm_stream_ps((float *)(p+32), c128); \ - _mm_stream_ps((float *)(p+48), c128); \ - p += 64; \ - } - -#define SSE_END - -#define DEFINE_SSE_FILLRECT(bpp, type) \ -static void \ -SDL_DrawRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ -{ \ - SSE_BEGIN; \ - \ - while (h--) { \ - int i, n = w * bpp; \ - Uint8 *p = pixels; \ - \ - if (n > 63) { \ - int adjust = 16 - ((uintptr_t)p & 15); \ - if (adjust < 16) { \ - n -= adjust; \ - adjust /= bpp; \ - while (adjust--) { \ - *((type *)p) = (type)color; \ - p += bpp; \ - } \ - } \ - SSE_WORK; \ - } \ - if (n & 63) { \ - int remainder = (n & 63); \ - remainder /= bpp; \ - while (remainder--) { \ - *((type *)p) = (type)color; \ - p += bpp; \ - } \ - } \ - pixels += pitch; \ - } \ - \ - SSE_END; \ -} - -static void -SDL_DrawRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) -{ - SSE_BEGIN; - - while (h--) { - int i, n = w; - Uint8 *p = pixels; - - if (n > 63) { - int adjust = 16 - ((uintptr_t)p & 15); - if (adjust) { - n -= adjust; - SDL_memset(p, color, adjust); - p += adjust; - } - SSE_WORK; - } - if (n & 63) { - int remainder = (n & 63); - SDL_memset(p, color, remainder); - p += remainder; - } - pixels += pitch; - } - - SSE_END; -} -/*DEFINE_SSE_FILLRECT(1, Uint8)*/ -DEFINE_SSE_FILLRECT(2, Uint16) -DEFINE_SSE_FILLRECT(4, Uint32) - -/* *INDENT-ON* */ -#endif /* __SSE__ */ - -#ifdef __MMX__ -/* *INDENT-OFF* */ - -#define MMX_BEGIN \ - __m64 c64 = _mm_set_pi32(color, color) - -#define MMX_WORK \ - for (i = n / 64; i--;) { \ - _mm_stream_pi((__m64 *)(p+0), c64); \ - _mm_stream_pi((__m64 *)(p+8), c64); \ - _mm_stream_pi((__m64 *)(p+16), c64); \ - _mm_stream_pi((__m64 *)(p+24), c64); \ - _mm_stream_pi((__m64 *)(p+32), c64); \ - _mm_stream_pi((__m64 *)(p+40), c64); \ - _mm_stream_pi((__m64 *)(p+48), c64); \ - _mm_stream_pi((__m64 *)(p+56), c64); \ - p += 64; \ - } - -#define MMX_END \ - _mm_empty() - -#define DEFINE_MMX_FILLRECT(bpp, type) \ -static void \ -SDL_DrawRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ -{ \ - MMX_BEGIN; \ - \ - while (h--) { \ - int i, n = w * bpp; \ - Uint8 *p = pixels; \ - \ - if (n > 63) { \ - int adjust = 8 - ((uintptr_t)p & 7); \ - if (adjust < 8) { \ - n -= adjust; \ - adjust /= bpp; \ - while (adjust--) { \ - *((type *)p) = (type)color; \ - p += bpp; \ - } \ - } \ - MMX_WORK; \ - } \ - if (n & 63) { \ - int remainder = (n & 63); \ - remainder /= bpp; \ - while (remainder--) { \ - *((type *)p) = (type)color; \ - p += bpp; \ - } \ - } \ - pixels += pitch; \ - } \ - \ - MMX_END; \ -} - -static void -SDL_DrawRect1MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) -{ - MMX_BEGIN; - - while (h--) { - int i, n = w; - Uint8 *p = pixels; - - if (n > 63) { - int adjust = 8 - ((uintptr_t)p & 7); - if (adjust) { - n -= adjust; - SDL_memset(p, color, adjust); - p += adjust; - } - MMX_WORK; - } - if (n & 63) { - int remainder = (n & 63); - SDL_memset(p, color, remainder); - p += remainder; - } - pixels += pitch; - } - - MMX_END; -} -/*DEFINE_MMX_FILLRECT(1, Uint8)*/ -DEFINE_MMX_FILLRECT(2, Uint16) -DEFINE_MMX_FILLRECT(4, Uint32) - -/* *INDENT-ON* */ -#endif /* __MMX__ */ - -static void -SDL_DrawRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) -{ - while (h--) { - int n = w; - Uint8 *p = pixels; - - if (n > 3) { - switch ((uintptr_t) p & 3) { - case 1: - *p++ = (Uint8) color; - --n; - case 2: - *p++ = (Uint8) color; - --n; - case 3: - *p++ = (Uint8) color; - --n; - } - SDL_memset4(p, color, (n >> 2)); - } - if (n & 3) { - p += (n & ~3); - switch (n & 3) { - case 3: - *p++ = (Uint8) color; - case 2: - *p++ = (Uint8) color; - case 1: - *p++ = (Uint8) color; - } - } - pixels += pitch; - } -} - -static void -SDL_DrawRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h) -{ - while (h--) { - int n = w; - Uint16 *p = (Uint16 *) pixels; - - if (n > 1) { - if ((uintptr_t) p & 2) { - *p++ = (Uint16) color; - --n; - } - SDL_memset4(p, color, (n >> 1)); - } - if (n & 1) { - p[n - 1] = (Uint16) color; - } - pixels += pitch; - } -} - -static void -SDL_DrawRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h) -{ - Uint8 r = (Uint8) ((color >> 16) & 0xFF); - Uint8 g = (Uint8) ((color >> 8) & 0xFF); - Uint8 b = (Uint8) (color & 0xFF); - - while (h--) { - int n = w; - Uint8 *p = pixels; - - while (n--) { - *p++ = r; - *p++ = g; - *p++ = b; - } - pixels += pitch; - } -} - -static void -SDL_DrawRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h) -{ - while (h--) { - SDL_memset4(pixels, color, w); - pixels += pitch; - } -} - -/* - * This function performs a fast fill of the given rectangle with 'color' - */ int SDL_DrawRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color) { - SDL_Rect clipped; - Uint8 *pixels; + SDL_Rect full_rect; + SDL_Point points[5]; if (!dst) { SDL_SetError("Passed NULL destination surface"); return -1; } - /* This function doesn't work on surfaces < 8 bpp */ - if (dst->format->BitsPerPixel < 8) { - SDL_SetError("SDL_DrawRect(): Unsupported surface format"); - return -1; - } - - /* If 'rect' == NULL, then fill the whole surface */ - if (rect) { - /* Perform clipping */ - if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) { - return 0; - } - rect = &clipped; - } else { - rect = &dst->clip_rect; - } - - /* Perform software fill */ - if (!dst->pixels) { - SDL_SetError("SDL_DrawRect(): You must lock the surface"); - return (-1); + /* If 'rect' == NULL, then outline the whole surface */ + if (!rect) { + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = dst->w; + full_rect.h = dst->h; + rect = &full_rect; } - pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch + - rect->x * dst->format->BytesPerPixel; - - switch (dst->format->BytesPerPixel) { - case 1: - { - color |= (color << 8); - color |= (color << 16); -#ifdef __SSE__ - if (SDL_HasSSE()) { - SDL_DrawRect1SSE(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif -#ifdef __MMX__ - if (SDL_HasMMX()) { - SDL_DrawRect1MMX(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif - SDL_DrawRect1(pixels, dst->pitch, color, rect->w, rect->h); - break; - } - - case 2: - { - color |= (color << 16); -#ifdef __SSE__ - if (SDL_HasSSE()) { - SDL_DrawRect2SSE(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif -#ifdef __MMX__ - if (SDL_HasMMX()) { - SDL_DrawRect2MMX(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif - SDL_DrawRect2(pixels, dst->pitch, color, rect->w, rect->h); - break; - } - - case 3: - /* 24-bit RGB is a slow path, at least for now. */ - { - SDL_DrawRect3(pixels, dst->pitch, color, rect->w, rect->h); - break; - } - - case 4: - { -#ifdef __SSE__ - if (SDL_HasSSE()) { - SDL_DrawRect4SSE(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif -#ifdef __MMX__ - if (SDL_HasMMX()) { - SDL_DrawRect4MMX(pixels, dst->pitch, color, rect->w, rect->h); - break; - } -#endif - SDL_DrawRect4(pixels, dst->pitch, color, rect->w, rect->h); - break; - } - } - - /* We're done! */ - return 0; + points[0].x = rect->x; + points[0].y = rect->y; + points[1].x = rect->x+rect->w-1; + points[1].y = rect->y; + points[2].x = rect->x+rect->w-1; + points[2].y = rect->y+rect->h-1; + points[3].x = rect->x; + points[3].y = rect->y+rect->h-1; + points[4].x = rect->x; + points[4].y = rect->y; + return SDL_DrawLines(dst, points, 5, color); } int @@ -421,12 +62,13 @@ SDL_DrawRects(SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color) { int i; - int status = 0; for (i = 0; i < count; ++i) { - status = SDL_DrawRect(dst, rects[i], color); + if (SDL_DrawRect(dst, rects[i], color) < 0) { + return -1; + } } - return status; + return 0; } /* vi: set ts=4 sw=4 expandtab: */