summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/render/software
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/render/software')
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.c336
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendfillrect.h33
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendline.c777
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendline.h33
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendpoint.c341
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_blendpoint.h33
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_draw.h576
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_drawline.c209
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_drawline.h33
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_drawpoint.c114
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_drawpoint.h33
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_render_sw.c887
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_render_sw_c.h29
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_rotate.c534
-rw-r--r--source/3rd-party/SDL2/src/render/software/SDL_rotate.h32
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_ */