diff options
Diffstat (limited to 'source/3rd-party/SDL2/src/render/software')
15 files changed, 4000 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.c b/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.c new file mode 100644 index 0000000..8a3f750 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.c @@ -0,0 +1,336 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_blendfillrect.h" + + +static int +SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB555); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB565); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGB888); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 2: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB); + break; + } + return 0; + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGB); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +static int +SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGBA); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +int +SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_Rect clipped; + + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendFillRect(): Unsupported surface format"); + } + + /* 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; + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a); + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a); + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a); + } else { + return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a); + } + /* break; -Wunreachable-code-break */ + } + break; + default: + break; + } + + if (!dst->format->Amask) { + return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a); + } else { + return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a); + } +} + +int +SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_Rect rect; + int i; + int (*func)(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL; + int status = 0; + + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendFillRects(): Unsupported surface format"); + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + /* FIXME: Does this function pointer slow things down significantly? */ + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + func = SDL_BlendFillRect_RGB555; + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + func = SDL_BlendFillRect_RGB565; + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + func = SDL_BlendFillRect_RGB888; + } else { + func = SDL_BlendFillRect_ARGB8888; + } + break; + } + break; + default: + break; + } + + if (!func) { + if (!dst->format->Amask) { + func = SDL_BlendFillRect_RGB; + } else { + func = SDL_BlendFillRect_RGBA; + } + } + + for (i = 0; i < count; ++i) { + /* Perform clipping */ + if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) { + continue; + } + status = func(dst, &rect, blendMode, r, g, b, a); + } + return status; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.h b/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.h new file mode 100644 index 0000000..3cac834 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_blendfillrect_h_ +#define SDL_blendfillrect_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); + +#endif /* SDL_blendfillrect_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendline.c b/source/3rd-party/SDL2/src/render/software/SDL_blendline.c new file mode 100644 index 0000000..0ed0ccd --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendline.c @@ -0,0 +1,777 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_blendline.h" +#include "SDL_blendpoint.h" + + +static void +SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); + break; + default: + HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); + break; + default: + DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + break; + } + } +} + +typedef void (*BlendLineFunc) (SDL_Surface * dst, + int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, + Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end); + +static BlendLineFunc +SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt) +{ + switch (fmt->BytesPerPixel) { + case 2: + if (fmt->Rmask == 0x7C00) { + return SDL_BlendLine_RGB555; + } else if (fmt->Rmask == 0xF800) { + return SDL_BlendLine_RGB565; + } else { + return SDL_BlendLine_RGB2; + } + /* break; -Wunreachable-code-break */ + case 4: + if (fmt->Rmask == 0x00FF0000) { + if (fmt->Amask) { + return SDL_BlendLine_ARGB8888; + } else { + return SDL_BlendLine_RGB888; + } + } else { + if (fmt->Amask) { + return SDL_BlendLine_RGBA4; + } else { + return SDL_BlendLine_RGB4; + } + } + } + return NULL; +} + +int +SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + BlendLineFunc func; + + if (!dst) { + return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); + } + + func = SDL_CalculateBlendLineFunc(dst->format); + if (!func) { + return SDL_SetError("SDL_BlendLine(): Unsupported surface format"); + } + + /* Perform clipping */ + /* FIXME: We don't actually want to clip, as it may change line slope */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { + return 0; + } + + func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE); + return 0; +} + +int +SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + int i; + int x1, y1; + int x2, y2; + SDL_bool draw_end; + BlendLineFunc func; + + if (!dst) { + return SDL_SetError("SDL_BlendLines(): Passed NULL destination surface"); + } + + func = SDL_CalculateBlendLineFunc(dst->format); + if (!func) { + return SDL_SetError("SDL_BlendLines(): Unsupported surface format"); + } + + for (i = 1; i < count; ++i) { + x1 = points[i-1].x; + y1 = points[i-1].y; + x2 = points[i].x; + y2 = points[i].y; + + /* Perform clipping */ + /* FIXME: We don't actually want to clip, as it may change line slope */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { + continue; + } + + /* Draw the end if it was clipped */ + draw_end = (x2 != points[i].x || y2 != points[i].y); + + func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end); + } + 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, + blendMode, r, g, b, a); + } + return 0; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendline.h b/source/3rd-party/SDL2/src/render/software/SDL_blendline.h new file mode 100644 index 0000000..a48a498 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendline.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_blendline_h_ +#define SDL_blendline_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); + +#endif /* SDL_blendline_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.c b/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.c new file mode 100644 index 0000000..37fb498 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.c @@ -0,0 +1,341 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_blendpoint.h" + + +static int +SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY_BLEND_RGB555(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY_ADD_RGB555(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY_MOD_RGB555(x, y); + break; + default: + DRAW_SETPIXELXY_RGB555(x, y); + break; + } + return 0; +} + +static int +SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY_BLEND_RGB565(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY_ADD_RGB565(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY_MOD_RGB565(x, y); + break; + default: + DRAW_SETPIXELXY_RGB565(x, y); + break; + } + return 0; +} + +static int +SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY_BLEND_RGB888(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY_ADD_RGB888(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY_MOD_RGB888(x, y); + break; + default: + DRAW_SETPIXELXY_RGB888(x, y); + break; + } + return 0; +} + +static int +SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, + Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY_BLEND_ARGB8888(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY_ADD_ARGB8888(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY_MOD_ARGB8888(x, y); + break; + default: + DRAW_SETPIXELXY_ARGB8888(x, y); + break; + } + return 0; +} + +static int +SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 2: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY2_BLEND_RGB(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY2_ADD_RGB(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY2_MOD_RGB(x, y); + break; + default: + DRAW_SETPIXELXY2_RGB(x, y); + break; + } + return 0; + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY4_BLEND_RGB(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY4_ADD_RGB(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY4_MOD_RGB(x, y); + break; + default: + DRAW_SETPIXELXY4_RGB(x, y); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +static int +SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DRAW_SETPIXELXY4_BLEND_RGBA(x, y); + break; + case SDL_BLENDMODE_ADD: + DRAW_SETPIXELXY4_ADD_RGBA(x, y); + break; + case SDL_BLENDMODE_MOD: + DRAW_SETPIXELXY4_MOD_RGBA(x, y); + break; + default: + DRAW_SETPIXELXY4_RGBA(x, y); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +int +SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) +{ + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendPoint(): Unsupported surface format"); + } + + /* Perform clipping */ + if (x < dst->clip_rect.x || y < dst->clip_rect.y || + x >= (dst->clip_rect.x + dst->clip_rect.w) || + y >= (dst->clip_rect.y + dst->clip_rect.h)) { + return 0; + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a); + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a); + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + return SDL_BlendPoint_RGB888(dst, x, y, blendMode, r, g, b, a); + } else { + return SDL_BlendPoint_ARGB8888(dst, x, y, blendMode, r, g, b, a); + } + /* break; -Wunreachable-code-break */ + } + break; + default: + break; + } + + if (!dst->format->Amask) { + return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a); + } else { + return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a); + } +} + +int +SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + int minx, miny; + int maxx, maxy; + int i; + int x, y; + int (*func)(SDL_Surface * dst, int x, int y, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL; + int status = 0; + + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendPoints(): Unsupported surface format"); + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + /* FIXME: Does this function pointer slow things down significantly? */ + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + func = SDL_BlendPoint_RGB555; + break; + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + func = SDL_BlendPoint_RGB565; + break; + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + func = SDL_BlendPoint_RGB888; + } else { + func = SDL_BlendPoint_ARGB8888; + } + break; + } + break; + default: + break; + } + + if (!func) { + if (!dst->format->Amask) { + func = SDL_BlendPoint_RGB; + } else { + func = SDL_BlendPoint_RGBA; + } + } + + minx = dst->clip_rect.x; + maxx = dst->clip_rect.x + dst->clip_rect.w - 1; + miny = dst->clip_rect.y; + maxy = dst->clip_rect.y + dst->clip_rect.h - 1; + + for (i = 0; i < count; ++i) { + x = points[i].x; + y = points[i].y; + + if (x < minx || x > maxx || y < miny || y > maxy) { + continue; + } + status = func(dst, x, y, blendMode, r, g, b, a); + } + return status; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.h b/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.h new file mode 100644 index 0000000..188557c --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_blendpoint.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_blendpoint_h_ +#define SDL_blendpoint_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); + +#endif /* SDL_blendpoint_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_draw.h b/source/3rd-party/SDL2/src/render/software/SDL_draw.h new file mode 100644 index 0000000..945f2bc --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_draw.h @@ -0,0 +1,576 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "../../video/SDL_blit.h" + +/* This code assumes that r, g, b, a are the source color, + * and in the blend and add case, the RGB values are premultiplied by a. + */ + +#define DRAW_MUL(_a, _b) (((unsigned)(_a)*(_b))/255) + +#define DRAW_FASTSETPIXEL(type) \ + *pixel = (type) color + +#define DRAW_FASTSETPIXEL1 DRAW_FASTSETPIXEL(Uint8) +#define DRAW_FASTSETPIXEL2 DRAW_FASTSETPIXEL(Uint16) +#define DRAW_FASTSETPIXEL4 DRAW_FASTSETPIXEL(Uint32) + +#define DRAW_FASTSETPIXELXY(x, y, type, bpp, color) \ + *(type *)((Uint8 *)dst->pixels + (y) * dst->pitch \ + + (x) * bpp) = (type) color + +#define DRAW_FASTSETPIXELXY1(x, y) DRAW_FASTSETPIXELXY(x, y, Uint8, 1, color) +#define DRAW_FASTSETPIXELXY2(x, y) DRAW_FASTSETPIXELXY(x, y, Uint16, 2, color) +#define DRAW_FASTSETPIXELXY4(x, y) DRAW_FASTSETPIXELXY(x, y, Uint32, 4, color) + +#define DRAW_SETPIXEL(setpixel) \ +do { \ + unsigned sr = r, sg = g, sb = b, sa = a; (void) sa; \ + setpixel; \ +} while (0) + +#define DRAW_SETPIXEL_BLEND(getpixel, setpixel) \ +do { \ + unsigned sr, sg, sb, sa = 0xFF; \ + getpixel; \ + sr = DRAW_MUL(inva, sr) + r; \ + sg = DRAW_MUL(inva, sg) + g; \ + sb = DRAW_MUL(inva, sb) + b; \ + sa = DRAW_MUL(inva, sa) + a; \ + setpixel; \ +} while (0) + +#define DRAW_SETPIXEL_ADD(getpixel, setpixel) \ +do { \ + unsigned sr, sg, sb, sa; (void) sa; \ + getpixel; \ + sr += r; if (sr > 0xff) sr = 0xff; \ + sg += g; if (sg > 0xff) sg = 0xff; \ + sb += b; if (sb > 0xff) sb = 0xff; \ + setpixel; \ +} while (0) + +#define DRAW_SETPIXEL_MOD(getpixel, setpixel) \ +do { \ + unsigned sr, sg, sb, sa; (void) sa; \ + getpixel; \ + sr = DRAW_MUL(sr, r); \ + sg = DRAW_MUL(sg, g); \ + sb = DRAW_MUL(sb, b); \ + setpixel; \ +} while (0) + +#define DRAW_SETPIXELXY(x, y, type, bpp, op) \ +do { \ + type *pixel = (type *)((Uint8 *)dst->pixels + (y) * dst->pitch \ + + (x) * bpp); \ + op; \ +} while (0) + +/* + * Define draw operators for RGB555 + */ + +#define DRAW_SETPIXEL_RGB555 \ + DRAW_SETPIXEL(RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB555 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB555 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB555 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555) + +#define DRAW_SETPIXELXY_BLEND_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB555) + +#define DRAW_SETPIXELXY_ADD_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB555) + +#define DRAW_SETPIXELXY_MOD_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555) + +/* + * Define draw operators for RGB565 + */ + +#define DRAW_SETPIXEL_RGB565 \ + DRAW_SETPIXEL(RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB565 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB565 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB565 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565) + +#define DRAW_SETPIXELXY_BLEND_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB565) + +#define DRAW_SETPIXELXY_ADD_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB565) + +#define DRAW_SETPIXELXY_MOD_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565) + +/* + * Define draw operators for RGB888 + */ + +#define DRAW_SETPIXEL_RGB888 \ + DRAW_SETPIXEL(RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB888 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB888 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB888 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB888) + +#define DRAW_SETPIXELXY_BLEND_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB888) + +#define DRAW_SETPIXELXY_ADD_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB888) + +#define DRAW_SETPIXELXY_MOD_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB888) + +/* + * Define draw operators for ARGB8888 + */ + +#define DRAW_SETPIXEL_ARGB8888 \ + DRAW_SETPIXEL(ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_BLEND_ARGB8888 \ + DRAW_SETPIXEL_BLEND(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_ADD_ARGB8888 \ + DRAW_SETPIXEL_ADD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MOD_ARGB8888 \ + DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXELXY_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888) + +#define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_ARGB8888) + +#define DRAW_SETPIXELXY_ADD_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_ARGB8888) + +#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888) + +/* + * Define draw operators for general RGB + */ + +#define DRAW_SETPIXEL_RGB \ + DRAW_SETPIXEL(PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB \ + DRAW_SETPIXEL_BLEND(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB \ + DRAW_SETPIXEL_ADD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB \ + DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXELXY2_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB) + +#define DRAW_SETPIXELXY4_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB) + +#define DRAW_SETPIXELXY2_BLEND_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB) + +#define DRAW_SETPIXELXY4_BLEND_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB) + +#define DRAW_SETPIXELXY2_ADD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB) + +#define DRAW_SETPIXELXY4_ADD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB) + +#define DRAW_SETPIXELXY2_MOD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB) + +#define DRAW_SETPIXELXY4_MOD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB) + + +/* + * Define draw operators for general RGBA + */ + +#define DRAW_SETPIXEL_RGBA \ + DRAW_SETPIXEL(PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_BLEND_RGBA \ + DRAW_SETPIXEL_BLEND(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_ADD_RGBA \ + DRAW_SETPIXEL_ADD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MOD_RGBA \ + DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXELXY4_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA) + +#define DRAW_SETPIXELXY4_BLEND_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGBA) + +#define DRAW_SETPIXELXY4_ADD_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGBA) + +#define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA) + +/* + * Define line drawing macro + */ + +#define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) + +/* Horizontal line */ +#define HLINE(type, op, draw_end) \ +{ \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (x1 <= x2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + length = draw_end ? (x2-x1+1) : (x2-x1); \ + } else { \ + pixel = (type *)dst->pixels + y1 * pitch + x2; \ + if (!draw_end) { \ + ++pixel; \ + } \ + length = draw_end ? (x1-x2+1) : (x1-x2); \ + } \ + while (length--) { \ + op; \ + ++pixel; \ + } \ +} + +/* Vertical line */ +#define VLINE(type, op, draw_end) \ +{ \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (y1 <= y2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + length = draw_end ? (y2-y1+1) : (y2-y1); \ + } else { \ + pixel = (type *)dst->pixels + y2 * pitch + x1; \ + if (!draw_end) { \ + pixel += pitch; \ + } \ + length = draw_end ? (y1-y2+1) : (y1-y2); \ + } \ + while (length--) { \ + op; \ + pixel += pitch; \ + } \ +} + +/* Diagonal line */ +#define DLINE(type, op, draw_end) \ +{ \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (y1 <= y2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + if (x1 <= x2) { \ + ++pitch; \ + } else { \ + --pitch; \ + } \ + length = (y2-y1); \ + } else { \ + pixel = (type *)dst->pixels + y2 * pitch + x2; \ + if (x2 <= x1) { \ + ++pitch; \ + } else { \ + --pitch; \ + } \ + if (!draw_end) { \ + pixel += pitch; \ + } \ + length = (y1-y2); \ + } \ + if (draw_end) { \ + ++length; \ + } \ + while (length--) { \ + op; \ + pixel += pitch; \ + } \ +} + +/* Bresenham's line algorithm */ +#define BLINE(x1, y1, x2, y2, op, draw_end) \ +{ \ + int i, deltax, deltay, numpixels; \ + int d, dinc1, dinc2; \ + int x, xinc1, xinc2; \ + int y, yinc1, yinc2; \ + \ + deltax = ABS(x2 - x1); \ + deltay = ABS(y2 - y1); \ + \ + if (deltax >= deltay) { \ + numpixels = deltax + 1; \ + d = (2 * deltay) - deltax; \ + dinc1 = deltay * 2; \ + dinc2 = (deltay - deltax) * 2; \ + xinc1 = 1; \ + xinc2 = 1; \ + yinc1 = 0; \ + yinc2 = 1; \ + } else { \ + numpixels = deltay + 1; \ + d = (2 * deltax) - deltay; \ + dinc1 = deltax * 2; \ + dinc2 = (deltax - deltay) * 2; \ + xinc1 = 0; \ + xinc2 = 1; \ + yinc1 = 1; \ + yinc2 = 1; \ + } \ + \ + if (x1 > x2) { \ + xinc1 = -xinc1; \ + xinc2 = -xinc2; \ + } \ + if (y1 > y2) { \ + yinc1 = -yinc1; \ + yinc2 = -yinc2; \ + } \ + \ + x = x1; \ + y = y1; \ + \ + if (!draw_end) { \ + --numpixels; \ + } \ + for (i = 0; i < numpixels; ++i) { \ + op(x, y); \ + if (d < 0) { \ + d += dinc1; \ + x += xinc1; \ + y += yinc1; \ + } else { \ + d += dinc2; \ + x += xinc2; \ + y += yinc2; \ + } \ + } \ +} + +/* Xiaolin Wu's line algorithm, based on Michael Abrash's implementation */ +#define WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ +{ \ + Uint16 ErrorAdj, ErrorAcc; \ + Uint16 ErrorAccTemp, Weighting; \ + int DeltaX, DeltaY, Temp, XDir; \ + unsigned r, g, b, a, inva; \ + \ + /* Draw the initial pixel, which is always exactly intersected by \ + the line and so needs no weighting */ \ + opaque_op(x1, y1); \ + \ + /* Draw the final pixel, which is always exactly intersected by the line \ + and so needs no weighting */ \ + if (draw_end) { \ + opaque_op(x2, y2); \ + } \ + \ + /* Make sure the line runs top to bottom */ \ + if (y1 > y2) { \ + Temp = y1; y1 = y2; y2 = Temp; \ + Temp = x1; x1 = x2; x2 = Temp; \ + } \ + DeltaY = y2 - y1; \ + \ + if ((DeltaX = x2 - x1) >= 0) { \ + XDir = 1; \ + } else { \ + XDir = -1; \ + DeltaX = -DeltaX; /* make DeltaX positive */ \ + } \ + \ + /* line is not horizontal, diagonal, or vertical */ \ + ErrorAcc = 0; /* initialize the line error accumulator to 0 */ \ + \ + /* Is this an X-major or Y-major line? */ \ + if (DeltaY > DeltaX) { \ + /* Y-major line; calculate 16-bit fixed-point fractional part of a \ + pixel that X advances each time Y advances 1 pixel, truncating the \ + result so that we won't overrun the endpoint along the X axis */ \ + ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; \ + /* Draw all pixels other than the first and last */ \ + while (--DeltaY) { \ + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \ + if (ErrorAcc <= ErrorAccTemp) { \ + /* The error accumulator turned over, so advance the X coord */ \ + x1 += XDir; \ + } \ + y1++; /* Y-major, so always advance Y */ \ + /* The IntensityBits most significant bits of ErrorAcc give us the \ + intensity weighting for this pixel, and the complement of the \ + weighting for the paired pixel */ \ + Weighting = ErrorAcc >> 8; \ + { \ + a = DRAW_MUL(_a, (Weighting ^ 255)); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1); \ + } \ + { \ + a = DRAW_MUL(_a, Weighting); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1 + XDir, y1); \ + } \ + } \ + } else { \ + /* X-major line; calculate 16-bit fixed-point fractional part of a \ + pixel that Y advances each time X advances 1 pixel, truncating the \ + result to avoid overrunning the endpoint along the X axis */ \ + ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX; \ + /* Draw all pixels other than the first and last */ \ + while (--DeltaX) { \ + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \ + if (ErrorAcc <= ErrorAccTemp) { \ + /* The error accumulator turned over, so advance the Y coord */ \ + y1++; \ + } \ + x1 += XDir; /* X-major, so always advance X */ \ + /* The IntensityBits most significant bits of ErrorAcc give us the \ + intensity weighting for this pixel, and the complement of the \ + weighting for the paired pixel */ \ + Weighting = ErrorAcc >> 8; \ + { \ + a = DRAW_MUL(_a, (Weighting ^ 255)); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1); \ + } \ + { \ + a = DRAW_MUL(_a, Weighting); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1 + 1); \ + } \ + } \ + } \ +} + +#ifdef AA_LINES +#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ + WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) +#else +#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ + BLINE(x1, y1, x2, y2, opaque_op, draw_end) +#endif + +/* + * Define fill rect macro + */ + +#define FILLRECT(type, op) \ +do { \ + int width = rect->w; \ + int height = rect->h; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + int skip = pitch - width; \ + type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \ + while (height--) { \ + { int n = (width+3)/4; \ + switch (width & 3) { \ + case 0: do { op; pixel++; /* fallthrough */ \ + case 3: op; pixel++; /* fallthrough */ \ + case 2: op; pixel++; /* fallthrough */ \ + case 1: op; pixel++; /* fallthrough */ \ + } while ( --n > 0 ); \ + } \ + } \ + pixel += skip; \ + } \ +} while (0) + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_drawline.c b/source/3rd-party/SDL2/src/render/software/SDL_drawline.c new file mode 100644 index 0000000..eeb54ed --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_drawline.c @@ -0,0 +1,209 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_drawline.h" +#include "SDL_drawpoint.h" + + +static void +SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) +{ + if (y1 == y2) { + int length; + int pitch = (dst->pitch / dst->format->BytesPerPixel); + Uint8 *pixel; + if (x1 <= x2) { + pixel = (Uint8 *)dst->pixels + y1 * pitch + x1; + length = draw_end ? (x2-x1+1) : (x2-x1); + } else { + pixel = (Uint8 *)dst->pixels + y1 * pitch + x2; + if (!draw_end) { + ++pixel; + } + length = draw_end ? (x1-x2+1) : (x1-x2); + } + SDL_memset(pixel, color, length); + } else if (x1 == x2) { + VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end); + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end); + } else { + BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end); + } +} + +static void +SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) +{ + if (y1 == y2) { + HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end); + } else if (x1 == x2) { + VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end); + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end); + } else { + Uint8 _r, _g, _b, _a; + const SDL_PixelFormat * fmt = dst->format; + SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a); + if (fmt->Rmask == 0x7C00) { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555, + draw_end); + } else if (fmt->Rmask == 0xF800) { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565, + draw_end); + } else { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB, + draw_end); + } + } +} + +static void +SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) +{ + if (y1 == y2) { + HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); + } else if (x1 == x2) { + VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); + } else { + Uint8 _r, _g, _b, _a; + const SDL_PixelFormat * fmt = dst->format; + SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a); + if (fmt->Rmask == 0x00FF0000) { + if (!fmt->Amask) { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); + } else { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + } + } else { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB, + draw_end); + } + } +} + +typedef void (*DrawLineFunc) (SDL_Surface * dst, + int x1, int y1, int x2, int y2, + Uint32 color, SDL_bool draw_end); + +static DrawLineFunc +SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt) +{ + switch (fmt->BytesPerPixel) { + case 1: + if (fmt->BitsPerPixel < 8) { + break; + } + return SDL_DrawLine1; + case 2: + return SDL_DrawLine2; + case 4: + return SDL_DrawLine4; + } + return NULL; +} + +int +SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) +{ + DrawLineFunc func; + + if (!dst) { + return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface"); + } + + func = SDL_CalculateDrawLineFunc(dst->format); + if (!func) { + return SDL_SetError("SDL_DrawLine(): Unsupported surface format"); + } + + /* Perform clipping */ + /* FIXME: We don't actually want to clip, as it may change line slope */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { + return 0; + } + + func(dst, x1, y1, x2, y2, color, SDL_TRUE); + return 0; +} + +int +SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, + Uint32 color) +{ + int i; + int x1, y1; + int x2, y2; + SDL_bool draw_end; + DrawLineFunc func; + + if (!dst) { + return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface"); + } + + func = SDL_CalculateDrawLineFunc(dst->format); + if (!func) { + return SDL_SetError("SDL_DrawLines(): Unsupported surface format"); + } + + for (i = 1; i < count; ++i) { + x1 = points[i-1].x; + y1 = points[i-1].y; + x2 = points[i].x; + y2 = points[i].y; + + /* Perform clipping */ + /* FIXME: We don't actually want to clip, as it may change line slope */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { + continue; + } + + /* Draw the end if it was clipped */ + draw_end = (x2 != points[i].x || y2 != points[i].y); + + func(dst, x1, y1, x2, y2, color, draw_end); + } + if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { + SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color); + } + return 0; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_drawline.h b/source/3rd-party/SDL2/src/render/software/SDL_drawline.h new file mode 100644 index 0000000..4e8e2bd --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_drawline.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_drawline_h_ +#define SDL_drawline_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color); +extern int SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color); + +#endif /* SDL_drawline_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.c b/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.c new file mode 100644 index 0000000..64a4e52 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.c @@ -0,0 +1,114 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_drawpoint.h" + + +int +SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color) +{ + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_DrawPoint(): Unsupported surface format"); + } + + /* Perform clipping */ + if (x < dst->clip_rect.x || y < dst->clip_rect.y || + x >= (dst->clip_rect.x + dst->clip_rect.w) || + y >= (dst->clip_rect.y + dst->clip_rect.h)) { + return 0; + } + + switch (dst->format->BytesPerPixel) { + case 1: + DRAW_FASTSETPIXELXY1(x, y); + break; + case 2: + DRAW_FASTSETPIXELXY2(x, y); + break; + case 3: + return SDL_Unsupported(); + case 4: + DRAW_FASTSETPIXELXY4(x, y); + break; + } + return 0; +} + +int +SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, + Uint32 color) +{ + int minx, miny; + int maxx, maxy; + int i; + int x, y; + + if (!dst) { + return SDL_SetError("Passed NULL destination surface"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_DrawPoints(): Unsupported surface format"); + } + + minx = dst->clip_rect.x; + maxx = dst->clip_rect.x + dst->clip_rect.w - 1; + miny = dst->clip_rect.y; + maxy = dst->clip_rect.y + dst->clip_rect.h - 1; + + for (i = 0; i < count; ++i) { + x = points[i].x; + y = points[i].y; + + if (x < minx || x > maxx || y < miny || y > maxy) { + continue; + } + + switch (dst->format->BytesPerPixel) { + case 1: + DRAW_FASTSETPIXELXY1(x, y); + break; + case 2: + DRAW_FASTSETPIXELXY2(x, y); + break; + case 3: + return SDL_Unsupported(); + case 4: + DRAW_FASTSETPIXELXY4(x, y); + break; + } + } + return 0; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.h b/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.h new file mode 100644 index 0000000..454774d --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_drawpoint.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_drawpoint_h_ +#define SDL_drawpoint_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color); +extern int SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color); + +#endif /* SDL_drawpoint_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_render_sw.c b/source/3rd-party/SDL2/src/render/software/SDL_render_sw.c new file mode 100644 index 0000000..709dfe8 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_render_sw.c @@ -0,0 +1,887 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if !SDL_RENDER_DISABLED + +#include "../SDL_sysrender.h" +#include "SDL_render_sw_c.h" +#include "SDL_hints.h" + +#include "SDL_draw.h" +#include "SDL_blendfillrect.h" +#include "SDL_blendline.h" +#include "SDL_blendpoint.h" +#include "SDL_drawline.h" +#include "SDL_drawpoint.h" +#include "SDL_rotate.h" + +/* SDL surface based renderer implementation */ + +static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags); +static void SW_WindowEvent(SDL_Renderer * renderer, + const SDL_WindowEvent *event); +static int SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h); +static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int SW_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int SW_SetTextureAlphaMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int SW_SetTextureBlendMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch); +static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); +static int SW_UpdateViewport(SDL_Renderer * renderer); +static int SW_UpdateClipRect(SDL_Renderer * renderer); +static int SW_RenderClear(SDL_Renderer * renderer); +static int SW_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_FPoint * points, int count); +static int SW_RenderDrawLines(SDL_Renderer * renderer, + const SDL_FPoint * points, int count); +static int SW_RenderFillRects(SDL_Renderer * renderer, + const SDL_FRect * rects, int count); +static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect); +static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); +static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch); +static void SW_RenderPresent(SDL_Renderer * renderer); +static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void SW_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver SW_RenderDriver = { + SW_CreateRenderer, + { + "software", + SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE, + 8, + { + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_BGR888, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB555 + }, + 0, + 0} +}; + +typedef struct +{ + SDL_Surface *surface; + SDL_Surface *window; +} SW_RenderData; + + +static SDL_Surface * +SW_ActivateRenderer(SDL_Renderer * renderer) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + + if (!data->surface) { + data->surface = data->window; + } + if (!data->surface) { + SDL_Surface *surface = SDL_GetWindowSurface(renderer->window); + if (surface) { + data->surface = data->window = surface; + + SW_UpdateViewport(renderer); + SW_UpdateClipRect(renderer); + } + } + return data->surface; +} + +SDL_Renderer * +SW_CreateRendererForSurface(SDL_Surface * surface) +{ + SDL_Renderer *renderer; + SW_RenderData *data; + + if (!surface) { + SDL_SetError("Can't create renderer for NULL surface"); + return NULL; + } + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (SW_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SW_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + data->surface = surface; + data->window = surface; + + renderer->WindowEvent = SW_WindowEvent; + renderer->GetOutputSize = SW_GetOutputSize; + renderer->CreateTexture = SW_CreateTexture; + renderer->SetTextureColorMod = SW_SetTextureColorMod; + renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod; + renderer->SetTextureBlendMode = SW_SetTextureBlendMode; + renderer->UpdateTexture = SW_UpdateTexture; + renderer->LockTexture = SW_LockTexture; + renderer->UnlockTexture = SW_UnlockTexture; + renderer->SetRenderTarget = SW_SetRenderTarget; + renderer->UpdateViewport = SW_UpdateViewport; + renderer->UpdateClipRect = SW_UpdateClipRect; + renderer->RenderClear = SW_RenderClear; + renderer->RenderDrawPoints = SW_RenderDrawPoints; + renderer->RenderDrawLines = SW_RenderDrawLines; + renderer->RenderFillRects = SW_RenderFillRects; + renderer->RenderCopy = SW_RenderCopy; + renderer->RenderCopyEx = SW_RenderCopyEx; + renderer->RenderReadPixels = SW_RenderReadPixels; + renderer->RenderPresent = SW_RenderPresent; + renderer->DestroyTexture = SW_DestroyTexture; + renderer->DestroyRenderer = SW_DestroyRenderer; + renderer->info = SW_RenderDriver.info; + renderer->driverdata = data; + + SW_ActivateRenderer(renderer); + + return renderer; +} + +SDL_Renderer * +SW_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_Surface *surface; + + surface = SDL_GetWindowSurface(window); + if (!surface) { + return NULL; + } + return SW_CreateRendererForSurface(surface); +} + +static void +SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { + data->surface = NULL; + data->window = NULL; + } +} + +static int +SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + + if (surface) { + if (w) { + *w = surface->w; + } + if (h) { + *h = surface->h; + } + return 0; + } else { + SDL_SetError("Software renderer doesn't have an output surface"); + return -1; + } +} + +static int +SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if (!SDL_PixelFormatEnumToMasks + (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + return SDL_SetError("Unknown texture format"); + } + + texture->driverdata = + SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, + Bmask, Amask); + SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, + texture->b); + SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); + SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); + + /* Only RLE encode textures without an alpha channel since the RLE coder + * discards the color values of pixels with an alpha value of zero. + */ + if (texture->access == SDL_TEXTUREACCESS_STATIC && !Amask) { + SDL_SetSurfaceRLE(texture->driverdata, 1); + } + + if (!texture->driverdata) { + return -1; + } + return 0; +} + +static int +SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + /* If the color mod is ever enabled (non-white), permanently disable RLE (which doesn't support + * color mod) to avoid potentially frequent RLE encoding/decoding. + */ + if ((texture->r & texture->g & texture->b) != 255) { + SDL_SetSurfaceRLE(surface, 0); + } + return SDL_SetSurfaceColorMod(surface, texture->r, texture->g, + texture->b); +} + +static int +SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + /* If the texture ever has multiple alpha values (surface alpha plus alpha channel), permanently + * disable RLE (which doesn't support this) to avoid potentially frequent RLE encoding/decoding. + */ + if (texture->a != 255 && surface->format->Amask) { + SDL_SetSurfaceRLE(surface, 0); + } + return SDL_SetSurfaceAlphaMod(surface, texture->a); +} + +static int +SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + /* If add or mod blending are ever enabled, permanently disable RLE (which doesn't support + * them) to avoid potentially frequent RLE encoding/decoding. + */ + if ((texture->blendMode == SDL_BLENDMODE_ADD || texture->blendMode == SDL_BLENDMODE_MOD)) { + SDL_SetSurfaceRLE(surface, 0); + } + return SDL_SetSurfaceBlendMode(surface, texture->blendMode); +} + +static int +SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + Uint8 *src, *dst; + int row; + size_t length; + + if(SDL_MUSTLOCK(surface)) + SDL_LockSurface(surface); + src = (Uint8 *) pixels; + dst = (Uint8 *) surface->pixels + + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel; + length = rect->w * surface->format->BytesPerPixel; + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += surface->pitch; + } + if(SDL_MUSTLOCK(surface)) + SDL_UnlockSurface(surface); + return 0; +} + +static int +SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + + *pixels = + (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel); + *pitch = surface->pitch; + return 0; +} + +static void +SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ +} + +static int +SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + + if (texture ) { + data->surface = (SDL_Surface *) texture->driverdata; + } else { + data->surface = data->window; + } + return 0; +} + +static int +SW_UpdateViewport(SDL_Renderer * renderer) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SDL_Surface *surface = data->surface; + + if (!surface) { + /* We'll update the viewport after we recreate the surface */ + return 0; + } + + SDL_SetClipRect(data->surface, &renderer->viewport); + return 0; +} + +static int +SW_UpdateClipRect(SDL_Renderer * renderer) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SDL_Surface *surface = data->surface; + if (surface) { + if (renderer->clipping_enabled) { + SDL_Rect clip_rect; + clip_rect = renderer->clip_rect; + clip_rect.x += renderer->viewport.x; + clip_rect.y += renderer->viewport.y; + SDL_IntersectRect(&renderer->viewport, &clip_rect, &clip_rect); + SDL_SetClipRect(surface, &clip_rect); + } else { + SDL_SetClipRect(surface, &renderer->viewport); + } + } + return 0; +} + +static int +SW_RenderClear(SDL_Renderer * renderer) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + Uint32 color; + SDL_Rect clip_rect; + + if (!surface) { + return -1; + } + + color = SDL_MapRGBA(surface->format, + renderer->r, renderer->g, renderer->b, renderer->a); + + /* By definition the clear ignores the clip rect */ + clip_rect = surface->clip_rect; + SDL_SetClipRect(surface, NULL); + SDL_FillRect(surface, NULL, color); + SDL_SetClipRect(surface, &clip_rect); + return 0; +} + +static int +SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, + int count) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + SDL_Point *final_points; + int i, status; + + if (!surface) { + return -1; + } + + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + return SDL_OutOfMemory(); + } + if (renderer->viewport.x || renderer->viewport.y) { + int x = renderer->viewport.x; + int y = renderer->viewport.y; + + for (i = 0; i < count; ++i) { + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; + } + } + + /* Draw the points! */ + if (renderer->blendMode == SDL_BLENDMODE_NONE) { + Uint32 color = SDL_MapRGBA(surface->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + status = SDL_DrawPoints(surface, final_points, count, color); + } else { + status = SDL_BlendPoints(surface, final_points, count, + renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } + SDL_stack_free(final_points); + + return status; +} + +static int +SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, + int count) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + SDL_Point *final_points; + int i, status; + + if (!surface) { + return -1; + } + + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + return SDL_OutOfMemory(); + } + if (renderer->viewport.x || renderer->viewport.y) { + int x = renderer->viewport.x; + int y = renderer->viewport.y; + + for (i = 0; i < count; ++i) { + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; + } + } + + /* Draw the lines! */ + if (renderer->blendMode == SDL_BLENDMODE_NONE) { + Uint32 color = SDL_MapRGBA(surface->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + status = SDL_DrawLines(surface, final_points, count, color); + } else { + status = SDL_BlendLines(surface, final_points, count, + renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } + SDL_stack_free(final_points); + + return status; +} + +static int +SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + SDL_Rect *final_rects; + int i, status; + + if (!surface) { + return -1; + } + + final_rects = SDL_stack_alloc(SDL_Rect, count); + if (!final_rects) { + return SDL_OutOfMemory(); + } + if (renderer->viewport.x || renderer->viewport.y) { + int x = renderer->viewport.x; + int y = renderer->viewport.y; + + for (i = 0; i < count; ++i) { + final_rects[i].x = (int)(x + rects[i].x); + final_rects[i].y = (int)(y + rects[i].y); + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); + } + } else { + for (i = 0; i < count; ++i) { + final_rects[i].x = (int)rects[i].x; + final_rects[i].y = (int)rects[i].y; + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); + } + } + + if (renderer->blendMode == SDL_BLENDMODE_NONE) { + Uint32 color = SDL_MapRGBA(surface->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + status = SDL_FillRects(surface, final_rects, count, color); + } else { + status = SDL_BlendFillRects(surface, final_rects, count, + renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } + SDL_stack_free(final_rects); + + return status; +} + +static int +SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + SDL_Surface *src = (SDL_Surface *) texture->driverdata; + SDL_Rect final_rect; + + if (!surface) { + return -1; + } + + if (renderer->viewport.x || renderer->viewport.y) { + final_rect.x = (int)(renderer->viewport.x + dstrect->x); + final_rect.y = (int)(renderer->viewport.y + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; + } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; + + if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { + return SDL_BlitSurface(src, srcrect, surface, &final_rect); + } else { + /* If scaling is ever done, permanently disable RLE (which doesn't support scaling) + * to avoid potentially frequent RLE encoding/decoding. + */ + SDL_SetSurfaceRLE(surface, 0); + return SDL_BlitScaled(src, srcrect, surface, &final_rect); + } +} + +static int +SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + SDL_Surface *src = (SDL_Surface *) texture->driverdata; + SDL_Rect final_rect, tmp_rect; + SDL_Surface *src_clone, *src_rotated, *src_scaled; + SDL_Surface *mask = NULL, *mask_rotated = NULL; + int retval = 0, dstwidth, dstheight, abscenterx, abscentery; + double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; + SDL_BlendMode blendmode; + Uint8 alphaMod, rMod, gMod, bMod; + int applyModulation = SDL_FALSE; + int blitRequired = SDL_FALSE; + int isOpaque = SDL_FALSE; + + if (!surface) { + return -1; + } + + if (renderer->viewport.x || renderer->viewport.y) { + final_rect.x = (int)(renderer->viewport.x + dstrect->x); + final_rect.y = (int)(renderer->viewport.y + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; + } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; + + tmp_rect = final_rect; + tmp_rect.x = 0; + tmp_rect.y = 0; + + /* It is possible to encounter an RLE encoded surface here and locking it is + * necessary because this code is going to access the pixel buffer directly. + */ + if (SDL_MUSTLOCK(src)) { + SDL_LockSurface(src); + } + + /* Clone the source surface but use its pixel buffer directly. + * The original source surface must be treated as read-only. + */ + src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch, + src->format->Rmask, src->format->Gmask, + src->format->Bmask, src->format->Amask); + if (src_clone == NULL) { + if (SDL_MUSTLOCK(src)) { + SDL_UnlockSurface(src); + } + return -1; + } + + SDL_GetSurfaceBlendMode(src, &blendmode); + SDL_GetSurfaceAlphaMod(src, &alphaMod); + SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod); + + /* SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted. */ + if (src->format->BitsPerPixel != 32 || SDL_PIXELLAYOUT(src->format->format) != SDL_PACKEDLAYOUT_8888 || !src->format->Amask) { + blitRequired = SDL_TRUE; + } + + /* If scaling and cropping is necessary, it has to be taken care of before the rotation. */ + if (!(srcrect->w == final_rect.w && srcrect->h == final_rect.h && srcrect->x == 0 && srcrect->y == 0)) { + blitRequired = SDL_TRUE; + } + + /* srcrect is not selecting the whole src surface, so cropping is needed */ + if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) { + blitRequired = SDL_TRUE; + } + + /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */ + if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) { + applyModulation = SDL_TRUE; + SDL_SetSurfaceAlphaMod(src_clone, alphaMod); + SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod); + } + + /* Opaque surfaces are much easier to handle with the NONE blend mode. */ + if (blendmode == SDL_BLENDMODE_NONE && !src->format->Amask && alphaMod == 255) { + isOpaque = SDL_TRUE; + } + + /* The NONE blend mode requires a mask for non-opaque surfaces. This mask will be used + * to clear the pixels in the destination surface. The other steps are explained below. + */ + if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) { + mask = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); + if (mask == NULL) { + retval = -1; + } else { + SDL_SetSurfaceBlendMode(mask, SDL_BLENDMODE_MOD); + } + } + + /* Create a new surface should there be a format mismatch or if scaling, cropping, + * or modulation is required. It's possible to use the source surface directly otherwise. + */ + if (!retval && (blitRequired || applyModulation)) { + SDL_Rect scale_rect = tmp_rect; + src_scaled = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); + if (src_scaled == NULL) { + retval = -1; + } else { + SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE); + retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect); + SDL_FreeSurface(src_clone); + src_clone = src_scaled; + src_scaled = NULL; + } + } + + /* SDLgfx_rotateSurface is going to make decisions depending on the blend mode. */ + SDL_SetSurfaceBlendMode(src_clone, blendmode); + + if (!retval) { + SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); + src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); + if (src_rotated == NULL) { + retval = -1; + } + if (!retval && mask != NULL) { + /* The mask needed for the NONE blend mode gets rotated with the same parameters. */ + mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle); + if (mask_rotated == NULL) { + retval = -1; + } + } + if (!retval) { + /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ + abscenterx = final_rect.x + (int)center->x; + abscentery = final_rect.y + (int)center->y; + /* Compensate the angle inversion to match the behaviour of the other backends */ + sangle = -sangle; + + /* Top Left */ + px = final_rect.x - abscenterx; + py = final_rect.y - abscentery; + p1x = px * cangle - py * sangle + abscenterx; + p1y = px * sangle + py * cangle + abscentery; + + /* Top Right */ + px = final_rect.x + final_rect.w - abscenterx; + py = final_rect.y - abscentery; + p2x = px * cangle - py * sangle + abscenterx; + p2y = px * sangle + py * cangle + abscentery; + + /* Bottom Left */ + px = final_rect.x - abscenterx; + py = final_rect.y + final_rect.h - abscentery; + p3x = px * cangle - py * sangle + abscenterx; + p3y = px * sangle + py * cangle + abscentery; + + /* Bottom Right */ + px = final_rect.x + final_rect.w - abscenterx; + py = final_rect.y + final_rect.h - abscentery; + p4x = px * cangle - py * sangle + abscenterx; + p4y = px * sangle + py * cangle + abscentery; + + tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); + tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); + tmp_rect.w = dstwidth; + tmp_rect.h = dstheight; + + /* The NONE blend mode needs some special care with non-opaque surfaces. + * Other blend modes or opaque surfaces can be blitted directly. + */ + if (blendmode != SDL_BLENDMODE_NONE || isOpaque) { + if (applyModulation == SDL_FALSE) { + /* If the modulation wasn't already applied, make it happen now. */ + SDL_SetSurfaceAlphaMod(src_rotated, alphaMod); + SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod); + } + retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect); + } else { + /* The NONE blend mode requires three steps to get the pixels onto the destination surface. + * First, the area where the rotated pixels will be blitted to get set to zero. + * This is accomplished by simply blitting a mask with the NONE blend mode. + * The colorkey set by the rotate function will discard the correct pixels. + */ + SDL_Rect mask_rect = tmp_rect; + SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE); + retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect); + if (!retval) { + /* The next step copies the alpha value. This is done with the BLEND blend mode and + * by modulating the source colors with 0. Since the destination is all zeros, this + * will effectively set the destination alpha to the source alpha. + */ + SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0); + mask_rect = tmp_rect; + retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect); + if (!retval) { + /* The last step gets the color values in place. The ADD blend mode simply adds them to + * the destination (where the color values are all zero). However, because the ADD blend + * mode modulates the colors with the alpha channel, a surface without an alpha mask needs + * to be created. This makes all source pixels opaque and the colors get copied correctly. + */ + SDL_Surface *src_rotated_rgb; + src_rotated_rgb = SDL_CreateRGBSurfaceFrom(src_rotated->pixels, src_rotated->w, src_rotated->h, + src_rotated->format->BitsPerPixel, src_rotated->pitch, + src_rotated->format->Rmask, src_rotated->format->Gmask, + src_rotated->format->Bmask, 0); + if (src_rotated_rgb == NULL) { + retval = -1; + } else { + SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD); + retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect); + SDL_FreeSurface(src_rotated_rgb); + } + } + } + SDL_FreeSurface(mask_rotated); + } + if (src_rotated != NULL) { + SDL_FreeSurface(src_rotated); + } + } + } + + if (SDL_MUSTLOCK(src)) { + SDL_UnlockSurface(src); + } + if (mask != NULL) { + SDL_FreeSurface(mask); + } + if (src_clone != NULL) { + SDL_FreeSurface(src_clone); + } + return retval; +} + +static int +SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + SDL_Surface *surface = SW_ActivateRenderer(renderer); + Uint32 src_format; + void *src_pixels; + + if (!surface) { + return -1; + } + + /* NOTE: The rect is already adjusted according to the viewport by + * SDL_RenderReadPixels. + */ + + if (rect->x < 0 || rect->x+rect->w > surface->w || + rect->y < 0 || rect->y+rect->h > surface->h) { + return SDL_SetError("Tried to read outside of surface bounds"); + } + + src_format = surface->format->format; + src_pixels = (void*)((Uint8 *) surface->pixels + + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel); + + return SDL_ConvertPixels(rect->w, rect->h, + src_format, src_pixels, surface->pitch, + format, pixels, pitch); +} + +static void +SW_RenderPresent(SDL_Renderer * renderer) +{ + SDL_Window *window = renderer->window; + + if (window) { + SDL_UpdateWindowSurface(window); + } +} + +static void +SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + + SDL_FreeSurface(surface); +} + +static void +SW_DestroyRenderer(SDL_Renderer * renderer) +{ + SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + + SDL_free(data); + SDL_free(renderer); +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_render_sw_c.h b/source/3rd-party/SDL2/src/render/software/SDL_render_sw_c.h new file mode 100644 index 0000000..f228517 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_render_sw_c.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_render_sw_c_h_ +#define SDL_render_sw_c_h_ + +extern SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface); + +#endif /* SDL_render_sw_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/source/3rd-party/SDL2/src/render/software/SDL_rotate.c b/source/3rd-party/SDL2/src/render/software/SDL_rotate.c new file mode 100644 index 0000000..09e099c --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_rotate.c @@ -0,0 +1,534 @@ +/* + +SDL_rotate.c: rotates 32bit or 8bit surfaces + +Shamelessly stolen from SDL_gfx by Andreas Schiffler. Original copyright follows: + +Copyright (C) 2001-2011 Andreas Schiffler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +Andreas Schiffler -- aschiffler at ferzkopp dot net + +*/ +#include "../../SDL_internal.h" + +#if defined(__WIN32__) +#include "../../core/windows/SDL_windows.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include "SDL.h" +#include "SDL_rotate.h" + +/* ---- Internally used structures */ + +/* ! +\brief A 32 bit RGBA pixel. +*/ +typedef struct tColorRGBA { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} tColorRGBA; + +/* ! +\brief A 8bit Y/palette pixel. +*/ +typedef struct tColorY { + Uint8 y; +} tColorY; + +/* ! +\brief Returns maximum of two numbers a and b. +*/ +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* ! +\brief Number of guard rows added to destination surfaces. + +This is a simple but effective workaround for observed issues. +These rows allocate extra memory and are then hidden from the surface. +Rows are added to the end of destination surfaces when they are allocated. +This catches any potential overflows which seem to happen with +just the right src image dimensions and scale/rotation and can lead +to a situation where the program can segfault. +*/ +#define GUARD_ROWS (2) + +/* ! +\brief Returns colorkey info for a surface +*/ +static Uint32 +_colorkey(SDL_Surface *src) +{ + Uint32 key = 0; + if (SDL_HasColorKey(src)) { + SDL_GetColorKey(src, &key); + } + return key; +} + + +/* ! +\brief Internal target surface sizing function for rotations with trig result return. + +\param width The source surface width. +\param height The source surface height. +\param angle The angle to rotate in degrees. +\param dstwidth The calculated width of the destination surface. +\param dstheight The calculated height of the destination surface. +\param cangle The sine of the angle +\param sangle The cosine of the angle + +*/ +void +SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, + int *dstwidth, int *dstheight, + double *cangle, double *sangle) +{ + /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ + int angle90 = (int)(angle/90); + if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ + angle90 %= 4; + if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + if(angle90 & 1) { + *dstwidth = height; + *dstheight = width; + *cangle = 0; + *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ + } else { + *dstwidth = width; + *dstheight = height; + *cangle = angle90 == 0 ? 1 : -1; + *sangle = 0; + } + } else { + double x, y, cx, cy, sx, sy; + double radangle; + int dstwidthhalf, dstheighthalf; + /* + * Determine destination width and height by rotating a centered source box + */ + radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */ + *sangle = SDL_sin(radangle); + *cangle = SDL_cos(radangle); + x = (double)(width / 2); + y = (double)(height / 2); + cx = *cangle * x; + cy = *cangle * y; + sx = *sangle * x; + sy = *sangle * y; + + dstwidthhalf = MAX((int) + SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1); + dstheighthalf = MAX((int) + SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1); + *dstwidth = 2 * dstwidthhalf; + *dstheight = 2 * dstheighthalf; + } +} + +/* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */ +static void +computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy, + int *sincx, int *sincy, int *signx, int *signy) +{ + int pitch = flipy ? -src->pitch : src->pitch; + if (flipx) { + bpp = -bpp; + } + switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break; + case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break; + case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break; + case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break; + } + if (flipx) { + *signx = -*signx; + } + if (flipy) { + *signy = -*signy; + } +} + +/* Performs a relatively fast rotation/flip when the angle is a multiple of 90 degrees. */ +#define TRANSFORM_SURFACE_90(pixelType) \ + int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \ + Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \ + \ + computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \ + if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \ + if (signy < 0) sp += (src->h-1)*src->pitch; \ + \ + for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ + if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \ + SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ + sp += dst->w*sizeof(pixelType); \ + dp += dst->w*sizeof(pixelType); \ + } else { \ + for (de = dp + dst->w*sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \ + *(pixelType*)dp = *(pixelType*)sp; \ + } \ + } \ + } + +static void +transformSurfaceRGBA90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +{ + TRANSFORM_SURFACE_90(tColorRGBA); +} + +static void +transformSurfaceY90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +{ + TRANSFORM_SURFACE_90(tColorY); +} + +#undef TRANSFORM_SURFACE_90 + +/* ! +\brief Internal 32 bit rotozoomer with optional anti-aliasing. + +Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control +parameters by scanning the destination surface and applying optionally anti-aliasing +by bilinear interpolation. +Assumes src and dst surfaces are of 32 bit depth. +Assumes dst surface was allocated with the correct dimensions. + +\param src Source surface. +\param dst Destination surface. +\param cx Horizontal center coordinate. +\param cy Vertical center coordinate. +\param isin Integer version of sine of angle. +\param icos Integer version of cosine of angle. +\param flipx Flag indicating horizontal mirroring should be applied. +\param flipy Flag indicating vertical mirroring should be applied. +\param smooth Flag indicating anti-aliasing should be used. +*/ +static void +_transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) +{ + int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + tColorRGBA c00, c01, c10, c11, cswap; + tColorRGBA *pc, *sp; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = (tColorRGBA*) dst->pixels; + gap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (sdx >> 16); + dy = (sdy >> 16); + if (flipx) dx = sw - dx; + if (flipy) dy = sh - dy; + if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx; + c00 = *sp; + sp += 1; + c01 = *sp; + sp += (src->pitch/4); + c11 = *sp; + sp -= 1; + c10 = *sp; + if (flipx) { + cswap = c00; c00=c01; c01=cswap; + cswap = c10; c10=c11; c11=cswap; + } + if (flipy) { + cswap = c00; c00=c10; c10=cswap; + cswap = c01; c01=c11; c11=cswap; + } + /* + * Interpolate colors + */ + ex = (sdx & 0xffff); + ey = (sdy & 0xffff); + t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; + t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; + pc->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; + t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; + pc->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; + t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; + pc->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; + t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; + pc->a = (((t2 - t1) * ey) >> 16) + t1; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } else { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (sdx >> 16); + dy = (sdy >> 16); + if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { + if(flipx) dx = sw - dx; + if(flipy) dy = sh - dy; + *pc = *((tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx); + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } +} + +/* ! + +\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing. + +Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control +parameters by scanning the destination surface. +Assumes src and dst surfaces are of 8 bit depth. +Assumes dst surface was allocated with the correct dimensions. + +\param src Source surface. +\param dst Destination surface. +\param cx Horizontal center coordinate. +\param cy Vertical center coordinate. +\param isin Integer version of sine of angle. +\param icos Integer version of cosine of angle. +\param flipx Flag indicating horizontal mirroring should be applied. +\param flipy Flag indicating vertical mirroring should be applied. +*/ +static void +transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) +{ + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay; + tColorY *pc; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + pc = (tColorY*) dst->pixels; + gap = dst->pitch - dst->w; + /* + * Clear surface to colorkey + */ + SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h); + /* + * Iterate through destination surface + */ + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (sdx >> 16); + dy = (sdy >> 16); + if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { + if (flipx) dx = (src->w-1)-dx; + if (flipy) dy = (src->h-1)-dy; + *pc = *((tColorY *)src->pixels + src->pitch * dy + dx); + } + sdx += icos; + sdy += isin; + pc++; + } + pc += gap; + } +} + + +/* ! +\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. + +Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface. +'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set +then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit +surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes). +The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE +mode will set the BLEND mode on the 'dst' surface. The MOD mode either generates a white 'dst' +surface and sets the colorkey or fills the it with the colorkey before copying the pixels. +When using the NONE and MOD modes, color and alpha modulation must be applied before using this function. + +\param src The surface to rotozoom. +\param angle The angle to rotate in degrees. +\param centerx The horizontal coordinate of the center of rotation +\param zoomy The vertical coordinate of the center of rotation +\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. +\param flipx Set to 1 to flip the image horizontally +\param flipy Set to 1 to flip the image vertically +\param dstwidth The destination surface width +\param dstheight The destination surface height +\param cangle The angle cosine +\param sangle The angle sine +\return The new rotated surface. + +*/ + +SDL_Surface * +SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle) +{ + SDL_Surface *rz_dst; + int is8bit, angle90; + int i; + SDL_BlendMode blendmode; + Uint32 colorkey = 0; + int colorKeyAvailable = SDL_FALSE; + double sangleinv, cangleinv; + + /* Sanity check */ + if (src == NULL) + return NULL; + + if (SDL_HasColorKey(src)) { + if (SDL_GetColorKey(src, &colorkey) == 0) { + colorKeyAvailable = SDL_TRUE; + } + } + + /* This function requires a 32-bit surface or 8-bit surface with a colorkey */ + is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable; + if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask))) + return NULL; + + /* Calculate target factors from sin/cos and zoom */ + sangleinv = sangle*65536.0; + cangleinv = cangle*65536.0; + + /* Alloc space to completely contain the rotated surface */ + rz_dst = NULL; + if (is8bit) { + /* Target surface is 8 bit */ + rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); + if (rz_dst != NULL) { + for (i = 0; i < src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = src->format->palette->ncolors; + } + } else { + /* Target surface is 32 bit with source RGBA ordering */ + rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32, + src->format->Rmask, src->format->Gmask, + src->format->Bmask, src->format->Amask); + } + + /* Check target */ + if (rz_dst == NULL) + return NULL; + + /* Adjust for guard rows */ + rz_dst->h = dstheight; + + SDL_GetSurfaceBlendMode(src, &blendmode); + + if (colorKeyAvailable == SDL_TRUE) { + /* If available, the colorkey will be used to discard the pixels that are outside of the rotated area. */ + SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey); + SDL_FillRect(rz_dst, NULL, colorkey); + } else if (blendmode == SDL_BLENDMODE_NONE) { + blendmode = SDL_BLENDMODE_BLEND; + } else if (blendmode == SDL_BLENDMODE_MOD) { + /* Without a colorkey, the target texture has to be white for the MOD blend mode so + * that the pixels outside the rotated area don't affect the destination surface. + */ + colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0); + SDL_FillRect(rz_dst, NULL, colorkey); + /* Setting a white colorkey for the destination surface makes the final blit discard + * all pixels outside of the rotated area. This doesn't interfere with anything because + * white pixels are already a no-op and the MOD blend mode does not interact with alpha. + */ + SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey); + } + + SDL_SetSurfaceBlendMode(rz_dst, blendmode); + + /* Lock source surface */ + if (SDL_MUSTLOCK(src)) { + SDL_LockSurface(src); + } + + /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce + * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near + * multiples of 90 degrees. + */ + angle90 = (int)(angle/90); + if (angle90 == angle/90) { + angle90 %= 4; + if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + } else { + angle90 = -1; + } + + if (is8bit) { + /* Call the 8-bit transformation routine to do the rotation */ + if(angle90 >= 0) { + transformSurfaceY90(src, rz_dst, angle90, flipx, flipy); + } else { + transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, + flipx, flipy); + } + } else { + /* Call the 32-bit transformation routine to do the rotation */ + if (angle90 >= 0) { + transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy); + } else { + _transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, + flipx, flipy, smooth); + } + } + + /* Unlock source surface */ + if (SDL_MUSTLOCK(src)) { + SDL_UnlockSurface(src); + } + + /* Return rotated surface */ + return rz_dst; +} diff --git a/source/3rd-party/SDL2/src/render/software/SDL_rotate.h b/source/3rd-party/SDL2/src/render/software/SDL_rotate.h new file mode 100644 index 0000000..54c0927 --- /dev/null +++ b/source/3rd-party/SDL2/src/render/software/SDL_rotate.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_rotate_h_ +#define SDL_rotate_h_ + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle); +extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle); + +#endif /* SDL_rotate_h_ */ |