SDL: Add dummy driver

From 2660449c6cb33f405d5f3cf4329511a424198550 Mon Sep 17 00:00:00 2001
From: Daniel Santos <[EMAIL REDACTED]>
Date: Thu, 30 Jun 2022 11:44:35 -0300
Subject: [PATCH] Add dummy driver

---
 CMakeLists.txt                     |    4 +-
 src/render/SDL_render.c            |    3 +
 src/render/SDL_sysrender.h         |    1 +
 src/render/ps2/SDL_blendfillrect.c |  357 ++++++++
 src/render/ps2/SDL_blendfillrect.h |   33 +
 src/render/ps2/SDL_blendline.c     |  875 ++++++++++++++++++++
 src/render/ps2/SDL_blendline.h     |   33 +
 src/render/ps2/SDL_blendpoint.c    |  362 ++++++++
 src/render/ps2/SDL_blendpoint.h    |   33 +
 src/render/ps2/SDL_draw.h          |  632 ++++++++++++++
 src/render/ps2/SDL_drawline.c      |  213 +++++
 src/render/ps2/SDL_drawline.h      |   33 +
 src/render/ps2/SDL_drawpoint.c     |  114 +++
 src/render/ps2/SDL_drawpoint.h     |   33 +
 src/render/ps2/SDL_render_sw.c     | 1229 ++++++++++++++++++++++++++++
 src/render/ps2/SDL_render_sw_c.h   |   37 +
 src/render/ps2/SDL_rotate.c        |  577 +++++++++++++
 src/render/ps2/SDL_rotate.h        |   30 +
 src/render/ps2/SDL_triangle.c      |  888 ++++++++++++++++++++
 src/render/ps2/SDL_triangle.h      |   42 +
 src/video/ps2/SDL_ps2video.c       |   77 +-
 21 files changed, 5534 insertions(+), 72 deletions(-)
 create mode 100644 src/render/ps2/SDL_blendfillrect.c
 create mode 100644 src/render/ps2/SDL_blendfillrect.h
 create mode 100644 src/render/ps2/SDL_blendline.c
 create mode 100644 src/render/ps2/SDL_blendline.h
 create mode 100644 src/render/ps2/SDL_blendpoint.c
 create mode 100644 src/render/ps2/SDL_blendpoint.h
 create mode 100644 src/render/ps2/SDL_draw.h
 create mode 100644 src/render/ps2/SDL_drawline.c
 create mode 100644 src/render/ps2/SDL_drawline.h
 create mode 100644 src/render/ps2/SDL_drawpoint.c
 create mode 100644 src/render/ps2/SDL_drawpoint.h
 create mode 100644 src/render/ps2/SDL_render_sw.c
 create mode 100644 src/render/ps2/SDL_render_sw_c.h
 create mode 100644 src/render/ps2/SDL_rotate.c
 create mode 100644 src/render/ps2/SDL_rotate.h
 create mode 100644 src/render/ps2/SDL_triangle.c
 create mode 100644 src/render/ps2/SDL_triangle.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f430a7cbef..2fe57578e98 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2572,7 +2572,9 @@ elseif(PS2)
   if(SDL_VIDEO)
     set(SDL_VIDEO_DRIVER_PS2 1)
     set(SDL_VIDEO_RENDER_PS2 1)
-    file(GLOB PS2_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/ps2/*.c)
+    file(GLOB PS2_VIDEO_SOURCES 
+    ${SDL2_SOURCE_DIR}/src/video/ps2/*.c
+    ${SDL2_SOURCE_DIR}/src/render/ps2/*.c)
     set(SOURCE_FILES ${SOURCE_FILES} ${PS2_VIDEO_SOURCES})
     set(SDL_VIDEO_OPENGL 0)
     set(HAVE_SDL_VIDEO TRUE)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index cd33242d964..702cde7efdc 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -114,6 +114,9 @@ static const SDL_RenderDriver *render_drivers[] = {
 #if SDL_VIDEO_RENDER_DIRECTFB
     &DirectFB_RenderDriver,
 #endif
+#if SDL_VIDEO_RENDER_PS2
+    &PS2_RenderDriver,
+#endif
 #if SDL_VIDEO_RENDER_PSP
     &PSP_RenderDriver,
 #endif
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index f559a2629be..4dcb98ac225 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -293,6 +293,7 @@ extern SDL_RenderDriver GLES2_RenderDriver;
 extern SDL_RenderDriver GLES_RenderDriver;
 extern SDL_RenderDriver DirectFB_RenderDriver;
 extern SDL_RenderDriver METAL_RenderDriver;
+extern SDL_RenderDriver PS2_RenderDriver;
 extern SDL_RenderDriver PSP_RenderDriver;
 extern SDL_RenderDriver SW_RenderDriver;
 extern SDL_RenderDriver VITA_GXM_RenderDriver;
diff --git a/src/render/ps2/SDL_blendfillrect.c b/src/render/ps2/SDL_blendfillrect.c
new file mode 100644
index 00000000000..d0e2f836d7d
--- /dev/null
+++ b/src/render/ps2/SDL_blendfillrect.c
@@ -0,0 +1,357 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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_VIDEO_RENDER_PS2 && !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;
+    case SDL_BLENDMODE_MUL:
+        FILLRECT(Uint16, DRAW_SETPIXEL_MUL_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;
+    case SDL_BLENDMODE_MUL:
+        FILLRECT(Uint16, DRAW_SETPIXEL_MUL_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;
+    case SDL_BLENDMODE_MUL:
+        FILLRECT(Uint32, DRAW_SETPIXEL_MUL_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;
+    case SDL_BLENDMODE_MUL:
+        FILLRECT(Uint32, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            FILLRECT(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            FILLRECT(Uint32, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            FILLRECT(Uint32, DRAW_SETPIXEL_MUL_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_InvalidParamError("SDL_BlendFillRect(): dst");
+    }
+
+    /* 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_InvalidParamError("SDL_BlendFillRects(): dst");
+    }
+
+    /* 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_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/render/ps2/SDL_blendfillrect.h b/src/render/ps2/SDL_blendfillrect.h
new file mode 100644
index 00000000000..8ee62b198d5
--- /dev/null
+++ b/src/render/ps2/SDL_blendfillrect.h
@@ -0,0 +1,33 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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/src/render/ps2/SDL_blendline.c b/src/render/ps2/SDL_blendline.c
new file mode 100644
index 00000000000..363b7a887ab
--- /dev/null
+++ b/src/render/ps2/SDL_blendline.c
@@ -0,0 +1,875 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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_VIDEO_RENDER_PS2 && !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;
+        case SDL_BLENDMODE_MUL:
+            HLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            VLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            DLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            AALINE(x1, y1, x2, y2,
+                   DRAW_SETPIXELXY2_MUL_RGB, DRAW_SETPIXELXY2_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            HLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            VLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            DLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            AALINE(x1, y1, x2, y2,
+                   DRAW_SETPIXELXY_MUL_RGB555, DRAW_SETPIXELXY_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            HLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            VLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            DLINE(Uint16, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            AALINE(x1, y1, x2, y2,
+                   DRAW_SETPIXELXY_MUL_RGB565, DRAW_SETPIXELXY_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            HLINE(Uint32, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            VLINE(Uint32, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            DLINE(Uint32, DRAW_SETPIXEL_MUL_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;
+        case SDL_BLENDMODE_MUL:
+            AALINE(x1, y1, x2, y2,
+                   DRAW_SETPIXELXY4_MUL_RGB, DRAW_SETPIXELXY4_MUL_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_PixelForma

(Patch may be truncated, please check the link at the top of this post.)