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. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%404344
This commit is contained in:
parent
e4c73114dc
commit
2b04928c0e
6 changed files with 165 additions and 442 deletions
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
75
src/video/SDL_blendrect.c
Normal file
75
src/video/SDL_blendrect.c
Normal file
|
@ -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: */
|
|
@ -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 { \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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: */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue