sdl2-compat: Added initial shot at sdl2-compat framework.

From 85bbefdcfb48e5a719402d91c6585a8a1973d548 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Thu, 24 Nov 2022 01:04:42 -0500
Subject: [PATCH] Added initial shot at sdl2-compat framework.

Just loads stuff and knows what symbols to passthrough. As ABI breaks for
SDL3 we will add more to this.

Untested!
---
 src/sdl2_compat.c          |  515 +++++
 src/sdl3_include_wrapper.h | 4419 ++++++++++++++++++++++++++++++++++++
 src/sdl3_syms.h            |  980 ++++++++
 3 files changed, 5914 insertions(+)
 create mode 100644 src/sdl2_compat.c
 create mode 100644 src/sdl3_include_wrapper.h
 create mode 100644 src/sdl3_syms.h

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
new file mode 100644
index 0000000..439989c
--- /dev/null
+++ b/src/sdl2_compat.c
@@ -0,0 +1,515 @@
+/*
+  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.
+*/
+
+/* This file contains functions for backwards compatibility with SDL2 */
+
+#include "sdl3_include_wrapper.h"
+
+/*
+ * We report the library version as
+ * 2.$(SDL2_COMPAT_VERSION_MINOR).$(SDL2_COMPAT_VERSION_PATCH). This number
+ * should be way ahead of what SDL2 Classic would report, so apps can
+ * decide if they're running under the compat layer, if they really care.
+ * The patch level changes in release cycles. The minor version starts at 90
+ * to be high by default, and usually doesn't change (and maybe never changes).
+ * The number might increment past 90 if there are a ton of releases.
+ */
+#define SDL2_COMPAT_VERSION_MINOR 90
+#define SDL2_COMPAT_VERSION_PATCH 0
+
+#include <stdarg.h>
+#include <limits.h>
+#include <stddef.h>
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+/* intptr_t already handled by stddef.h. */
+#else
+#include <stdint.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+#else
+#include <stdio.h> /* fprintf(), etc. */
+#include <stdlib.h>    /* for abort() */
+#include <string.h>
+#endif
+
+/* mingw headers may define these ... */
+#undef strtod
+#undef strcasecmp
+#undef strncasecmp
+#undef snprintf
+#undef vsnprintf
+
+#define SDL_BlitSurface SDL_UpperBlit
+
+#ifdef __linux__
+#include <unistd.h> /* for readlink() */
+#endif
+
+#if defined(__unix__) || defined(__APPLE__)
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+#define SDL12_MAXPATH PATH_MAX
+#elif defined _WIN32
+#define SDL12_MAXPATH MAX_PATH
+#elif defined __OS2__
+#define SDL12_MAXPATH CCHMAXPATH
+#else
+#define SDL12_MAXPATH 1024
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL3_SYM(rc,fn,params,args,ret) \
+    typedef rc (SDLCALL *SDL3_##fn##_t) params; \
+    static SDL3_##fn##_t SDL3_##fn = NULL;
+#include "sdl3_syms.h"
+
+/* Things that _should_ be binary compatible pass right through... */
+#define SDL3_SYM_PASSTHROUGH(rc,fn,params,args,ret) \
+    DECLSPEC rc SDLCALL SDL_##fn params { ret SDL3_##fn args; }
+#include "sdl3_syms.h"
+
+
+/* these are macros (etc) in the SDL headers, so make our own. */
+#define SDL3_OutOfMemory() SDL3_Error(SDL_ENOMEM)
+#define SDL3_Unsupported() SDL3_Error(SDL_UNSUPPORTED)
+#define SDL3_InvalidParamError(param) SDL3_SetError("Parameter '%s' is invalid", (param))
+#define SDL3_zero(x) SDL3_memset(&(x), 0, sizeof((x)))
+#define SDL3_zerop(x) SDL3_memset((x), 0, sizeof(*(x)))
+#define SDL_ReportAssertion SDL3_ReportAssertion
+
+/* Obviously we can't use SDL_LoadObject() to load SDL2.  :)  */
+static char loaderror[256];
+#if defined(_WIN32)
+    #define DIRSEP "\\"
+    #define SDL3_LIBNAME "SDL3.dll"
+    static HMODULE Loaded_SDL3 = NULL;
+    #define LoadSDL3Library() ((Loaded_SDL3 = LoadLibraryA(SDL3_LIBNAME)) != NULL)
+    #define LookupSDL3Sym(sym) (void *)GetProcAddress(Loaded_SDL3, sym)
+    #define CloseSDL3Library() { if (Loaded_SDL3) { FreeLibrary(Loaded_SDL3); Loaded_SDL3 = NULL; } }
+    #define strcpy_fn  lstrcpyA
+    #define sprintf_fn wsprintfA
+#elif defined(__APPLE__)
+    #include <dlfcn.h>
+    #include <pwd.h>
+    #include <unistd.h>
+    #define SDL3_LIBNAME "libSDL3-3.0.0.dylib"
+    /* SDL2 cmake'ry is (was?) messy: */
+    #define SDL3_LIBNAME2 "libSDL3-3.0.dylib"
+    #define SDL3_FRAMEWORK "SDL3.framework/Versions/A/SDL3"
+    #define strcpy_fn  strcpy
+    #define sprintf_fn sprintf
+    static void *Loaded_SDL3 = NULL;
+    #define LookupSDL3Sym(sym) dlsym(Loaded_SDL3, sym)
+    #define CloseSDL3Library() { if (Loaded_SDL3) { dlclose(Loaded_SDL3); Loaded_SDL3 = NULL; } }
+    static SDL_bool LoadSDL3Library(void) {
+        /* I don't know if this is the _right_ order to try, but this seems reasonable */
+        static const char * const dylib_locations[] = {
+            "@loader_path/" SDL3_LIBNAME, /* MyApp.app/Contents/MacOS/libSDL2-2.0.0.dylib */
+            "@loader_path/" SDL3_LIBNAME2, /* MyApp.app/Contents/MacOS/libSDL2-2.0.dylib */
+            "@loader_path/../Frameworks/" SDL3_FRAMEWORK, /* MyApp.app/Contents/Frameworks/SDL2.framework */
+            "@executable_path/" SDL3_LIBNAME, /* MyApp.app/Contents/MacOS/libSDL2-2.0.0.dylib */
+            "@executable_path/" SDL3_LIBNAME2, /* MyApp.app/Contents/MacOS/libSDL2-2.0.dylib */
+            "@executable_path/../Frameworks/" SDL3_FRAMEWORK, /* MyApp.app/Contents/Frameworks/SDL2.framework */
+            NULL,  /* /Users/username/Library/Frameworks/SDL2.framework */
+            "/Library/Frameworks" SDL3_FRAMEWORK, /* /Library/Frameworks/SDL2.framework */
+            SDL3_LIBNAME, /* oh well, anywhere the system can see the .dylib (/usr/local/lib or whatever) */
+            SDL3_LIBNAME2
+        };
+
+        int i;
+        for (i = 0; i < (int) SDL_arraysize(dylib_locations); i++) {
+            const char *location = dylib_locations[i];
+            if (location) {
+                Loaded_SDL3 = dlopen(location, RTLD_LOCAL|RTLD_NOW);
+            } else { /* hack to mean "try homedir" */
+                const char *homedir = NULL;
+                struct passwd *pwent = getpwuid(getuid());
+                if (pwent) {
+                    homedir = pwent->pw_dir;
+                }
+                if (!homedir) {
+                    homedir = getenv("HOME");
+                }
+                if (homedir) {
+                    char framework[512];
+                    const int rc = snprintf(framework, sizeof (framework), "%s/Library/Frameworks/" SDL3_FRAMEWORK, homedir);
+                    if ((rc > 0) && (rc < (int) sizeof(framework))) {
+                        Loaded_SDL3 = dlopen(framework, RTLD_LOCAL|RTLD_NOW);
+                    }
+                }
+            }
+
+            if (Loaded_SDL3) {
+                return SDL_TRUE;
+            }
+        }
+
+        return SDL_FALSE; /* didn't find it anywhere reasonable. :( */
+    }
+#elif defined(__unix__)
+    #include <dlfcn.h>
+    #define SDL3_LIBNAME "libSDL2-2.0.so.0"
+    static void *Loaded_SDL3 = NULL;
+    #define LoadSDL3Library() ((Loaded_SDL3 = dlopen(SDL3_LIBNAME, RTLD_LOCAL|RTLD_NOW)) != NULL)
+    #define LookupSDL3Sym(sym) dlsym(Loaded_SDL3, sym)
+    #define CloseSDL3Library() { if (Loaded_SDL3) { dlclose(Loaded_SDL3); Loaded_SDL3 = NULL; } }
+    #define strcpy_fn  strcpy
+    #define sprintf_fn sprintf
+#else
+    #error Please define your platform.
+#endif
+
+#ifndef SDL3_REQUIRED_VER
+#define SDL3_REQUIRED_VER SDL_VERSIONNUM(3,0,0)
+#endif
+
+#ifndef DIRSEP
+#define DIRSEP "/"
+#endif
+
+static void *
+LoadSDL3Symbol(const char *fn, int *okay)
+{
+    void *retval = NULL;
+    if (*okay) { /* only bother trying if we haven't previously failed. */
+        retval = LookupSDL3Sym(fn);
+        if (retval == NULL) {
+            sprintf_fn(loaderror, "%s missing in SDL2 library.", fn);
+            *okay = 0;
+        }
+    }
+    return retval;
+}
+
+static void
+UnloadSDL3(void)
+{
+    #define SDL3_SYM(rc,fn,params,args,ret) SDL3_##fn = NULL;
+    #include "sdl3_syms.h"
+    CloseSDL3Library();
+}
+
+typedef struct QuirkEntryType
+{
+    const char *exe_name;
+    const char *hint_name;
+    const char *hint_value;
+} QuirkEntryType;
+
+static QuirkEntryType quirks[] = {
+    /* TODO: Add any quirks needed for various systems. */
+    {"", "", "0"} /* A dummy entry to keep compilers happy. */
+};
+
+#ifdef __linux__
+static void OS_GetExeName(char *buf, const unsigned maxpath) {
+    buf[0] = '\0';
+    readlink("/proc/self/exe", buf, maxpath);
+}
+#elif defined(_WIN32)
+static void OS_GetExeName(char *buf, const unsigned maxpath) {
+    buf[0] = '\0';
+    GetModuleFileNameA(NULL, buf, maxpath);
+}
+#elif defined(__APPLE__) || defined(__FREEBSD__)
+static void OS_GetExeName(char *buf, const unsigned maxpath) {
+    const char *progname = getprogname();
+    if (progname != NULL) {
+        strlcpy(buf, progname, maxpath);
+    } else {
+        buf[0] = '\0';
+    }
+}
+#else
+#warning Please implement this for your platform.
+static void OS_GetExeName(char *buf, const unsigned maxpath) {
+    buf[0] = '\0';
+    (void)maxpath;
+}
+#endif
+
+static const char *
+SDL2Compat_GetExeName(void)
+{
+    static const char *exename = NULL;
+    if (exename == NULL) {
+        static char path_buf[SDL12_MAXPATH];
+        static char *base_path;
+        OS_GetExeName(path_buf, SDL12_MAXPATH);
+        base_path = SDL3_strrchr(path_buf, *DIRSEP);
+        if (base_path) {
+            /* We have a '\\' component. */
+            exename = base_path + 1;
+        } else {
+            /* No slashes, return the whole module filanem. */
+            exename = path_buf;
+        }
+    }
+    return exename;
+}
+
+static const char *
+SDL2Compat_GetHint(const char *name)
+{
+    return SDL3_getenv(name);
+}
+
+static SDL_bool
+SDL2Compat_GetHintBoolean(const char *name, SDL_bool default_value)
+{
+    const char *val = SDL2Compat_GetHint(name);
+
+    if (!val) {
+        return default_value;
+    }
+
+    return (SDL3_atoi(val) != 0) ? SDL_TRUE : SDL_FALSE;
+}
+
+static float
+SDL2Compat_GetHintFloat(const char *name, float default_value)
+{
+    const char *val = SDL2Compat_GetHint(name);
+
+    if (!val) {
+        return default_value;
+    }
+
+    return (float) SDL3_atof(val);
+}
+
+static void
+SDL2Compat_ApplyQuirks(SDL_bool force_x11)
+{
+    const char *exe_name = SDL2Compat_GetExeName();
+    int i;
+
+    if (WantDebugLogging) {
+        SDL3_Log("This app appears to be named '%s'", exe_name);
+    }
+
+    #ifdef __linux__
+    if (force_x11) {
+        const char *videodriver_env = SDL3_getenv("SDL_VIDEODRIVER");
+        if (videodriver_env && (SDL3_strcmp(videodriver_env, "x11") != 0)) {
+            if (WantDebugLogging) {
+                SDL3_Log("This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is set to \"%s\". If you have issues, try setting SDL_VIDEODRIVER=x11", videodriver_env);
+            }
+        } else {
+            if (WantDebugLogging) {
+                SDL3_Log("sdl12-compat: We are forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc.");
+            }
+            SDL3_setenv("SDL_VIDEODRIVER", "x11", 1);
+        }
+    }
+    #endif
+
+    if (*exe_name == '\0') {
+        return;
+    }
+    for (i = 0; i < (int) SDL_arraysize(quirks); i++) {
+        if (!SDL3_strcmp(exe_name, quirks[i].exe_name)) {
+            if (!SDL3_getenv(quirks[i].hint_name)) {
+                if (WantDebugLogging) {
+                    SDL3_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name);
+                }
+                SDL3_setenv(quirks[i].hint_name, quirks[i].hint_value, 1);
+            } else {
+                if (WantDebugLogging) {
+                    SDL3_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n",
+                            quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL3_getenv(quirks[i].hint_name));
+                }
+            }
+        }
+    }
+}
+
+static int
+LoadSDL3(void)
+{
+    int okay = 1;
+    if (!Loaded_SDL3) {
+        SDL_bool force_x11 = SDL_FALSE;
+
+        #ifdef __linux__
+        void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW);
+
+        /* Use linked libraries to detect what quirks we are likely to need */
+        if (global_symbols != NULL) {
+            if (dlsym(global_symbols, "glxewInit") != NULL) {  /* GLEW (e.g. Frogatto, SLUDGE) */
+                force_x11 = SDL_TRUE;
+            } else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) {  /* NVIDIA Cg (e.g. Awesomenauts, Braid) */
+                force_x11 = SDL_TRUE;
+            } else if (dlsym(global_symbols, "_Z7ssgInitv") != NULL) {  /* ::ssgInit(void) in plib (e.g. crrcsim) */
+                force_x11 = SDL_TRUE;
+            }
+            dlclose(global_symbols);
+        }
+        #endif
+
+        okay = LoadSDL3Library();
+        if (!okay) {
+            strcpy_fn(loaderror, "Failed loading SDL3 library.");
+        } else {
+            #define SDL3_SYM(rc,fn,params,args,ret) SDL3_##fn = (SDL3_##fn##_t) LoadSDL3Symbol("SDL_" #fn, &okay);
+            #include "sdl3_syms.h"
+            if (okay) {
+                SDL_version v;
+                SDL3_GetVersion(&v);
+                LinkedSDL2VersionInt = SDL_VERSIONNUM(v.major, v.minor, v.patch);
+                okay = (LinkedSDL2VersionInt >= SDL3_REQUIRED_VER);
+                if (!okay) {
+                    sprintf_fn(loaderror, "SDL3 %d.%d.%d library is too old.", v.major, v.minor, v.patch);
+                } else {
+                    WantDebugLogging = SDL2Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE);
+                    if (WantDebugLogging) {
+                        #if defined(__DATE__) && defined(__TIME__)
+                        SDL3_Log("sdl2-compat 2.%d.%d, built on " __DATE__ " at " __TIME__ ", talking to SDL3 %d.%d.%d", SDL2_COMPAT_VERSION_MINOR, SDL2_COMPAT_VERSION_PATCH, v.major, v.minor, v.patch);
+                        #else
+                        SDL3_Log("sdl2-compat 2.%d.%d, talking to SDL3 %d.%d.%d", SDL2_COMPAT_VERSION_MINOR, SDL2_COMPAT_VERSION_PATCH, v.major, v.minor, v.patch);
+                        #endif
+                    }
+                    SDL2Compat_ApplyQuirks(force_x11);  /* Apply and maybe print a list of any enabled quirks. */
+                }
+            }
+            if (!okay) {
+                UnloadSDL3();
+            }
+        }
+    }
+    return okay;
+}
+
+#if defined(_WIN32)
+static void error_dialog(const char *errorMsg)
+{
+    MessageBoxA(NULL, errorMsg, "Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
+}
+#elif defined(__APPLE__)
+extern void error_dialog(const char *errorMsg);
+#else
+static void error_dialog(const char *errorMsg)
+{
+    fprintf(stderr, "%s\n", errorMsg);
+}
+#endif
+
+#if defined(__GNUC__) && !defined(_WIN32)
+static void dllinit(void) __attribute__((constructor));
+static void dllinit(void)
+{
+    if (!LoadSDL3()) {
+        error_dialog(loaderror);
+        abort();
+    }
+}
+static void dllquit(void) __attribute__((destructor));
+static void dllquit(void)
+{
+    UnloadSDL3();
+}
+
+#elif defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__))
+#if defined(_MSC_VER) && !defined(__FLTUSED__)
+#define __FLTUSED__
+__declspec(selectany) int _fltused = 1;
+#endif
+#if defined(__MINGW32__)
+#define _DllMainCRTStartup DllMainCRTStartup
+#endif
+#if defined(__WATCOMC__)
+#define _DllMainCRTStartup LibMain
+#endif
+BOOL WINAPI _DllMainCRTStartup(HANDLE dllhandle, DWORD reason, LPVOID reserved)
+{
+    (void) dllhandle;
+    (void) reserved;
+    switch (reason) {
+    case DLL_PROCESS_DETACH:
+        UnloadSDL3();
+        break;
+
+    case DLL_PROCESS_ATTACH: /* init once for each new process */
+        if (!LoadSDL3()) {
+            error_dialog(loaderror);
+            #if 0
+            TerminateProcess(GetCurrentProcess(), 42);
+            ExitProcess(42);
+            #endif
+            return FALSE;
+        }
+        break;
+
+    case DLL_THREAD_ATTACH: /* thread-specific init. */
+    case DLL_THREAD_DETACH: /* thread-specific cleanup */
+        break;
+    }
+    return TRUE;
+}
+
+#else
+    #error Please define an init procedure for your platform.
+#endif
+
+
+DECLSPEC const SDL_version * SDLCALL
+SDL_Linked_Version(void)
+{
+    static const SDL_version version = { 2, SDL2_COMPAT_VERSION_MINOR, SDL2_COMPAT_VERSION_PATCH };
+    return &version;
+}
+
+DECLSPEC int SDLCALL
+SDL_sscanf(const char *text, const char *fmt, ...)
+{
+    int retval;
+    va_list ap;
+    va_start(ap, fmt);
+    retval = (int) SDL3_vsscanf(text, fmt, ap);
+    va_end(ap);
+    return retval;
+}
+
+DECLSPEC int SDLCALL
+SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
+{
+    int retval;
+    va_list ap;
+    va_start(ap, fmt);
+    retval = (int) SDL3_vsnprintf(text, maxlen, fmt, ap);
+    va_end(ap);
+    return retval;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/sdl3_include_wrapper.h b/src/sdl3_include_wrapper.h
new file mode 100644
index 0000000..a75633f
--- /dev/null
+++ b/src/sdl3_include_wrapper.h
@@ -0,0 +1,4419 @@
+/*
+  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.
+*/
+
+/*
+ * This file #includes the proper SDL3 headers, but #defines a whole
+ *  bunch of stuff so we don't conflict with symbols we plan to offer with
+ *  the SDL2 signatures. Ugly business.
+ */
+
+#ifndef _INCL_SDL3_INCLUDE_WRAPPER_H_
+#define _INCL_SDL3_INCLUDE_WRAPPER_H_
+
+#define SDL_GetVersion IGNORE_THIS_VERSION_OF_SDL_GetVersion
+#define SDL_GetRevision IGNORE_THIS_VERSION_OF_SDL_GetRevision
+#define SDL_GetRevisionNumber IGNORE_THIS_VERSION_OF_SDL_GetRevisionNumber
+#define SDL_RecordGesture IGNORE_THIS_VERSION_OF_SDL_RecordGesture
+#define SDL_SaveAllDollarTemplates IGNORE_THIS_VERSION_OF_SDL_SaveAllDollarTemplates
+#define SDL_SaveDollarTemplate IGNORE_THIS_VERSION_OF_SDL_SaveDollarTemplate
+#define SDL_LoadDollarTemplates IGNORE_THIS_VERSION_OF_SDL_LoadDollarTemplates
+#define SDL_CreateRGBSurface IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurface
+#define SDL_CreateRGBSurfaceWithFormat IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceWithFormat
+#define SDL_CreateRGBSurfaceFrom IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceFrom
+#define SDL_CreateRGBSurfaceWithFormatFrom IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceWithFormatFrom
+#define SDL_FreeSurface IGNORE_THIS_VERSION_OF_SDL_FreeSurface
+#define SDL_SetSurfacePalette IGNORE_THIS_VERSION_OF_SDL_SetSurfacePalette
+#define SDL_LockSurface IGNORE_THIS_VERSION_OF_SDL_LockSurface
+#define SDL_UnlockSurface IGNORE_THIS_VERSION_OF_SDL_UnlockSurface
+#define SDL_LoadBMP_RW IGNORE_THIS_VERSION_OF_SDL_LoadBMP_RW
+#define SDL_SaveBMP_RW IGNORE_THIS_VERSION_OF_SDL_SaveBMP_RW
+#define SDL_SetSurfaceRLE IGNORE_THIS_VERSION_OF_SDL_SetSurfaceRLE
+#define SDL_HasSurfaceRLE IGNORE_THIS_VERSION_OF_SDL_HasSurfaceRLE
+#define SDL_SetColorKey IGNORE_THIS_VERSION_OF_SDL_SetColorKey
+#define SDL_HasColorKey IGNORE_THIS_VERSION_OF_SDL_HasColorKey
+#define SDL_GetColorKey IGNORE_THIS_VERSION_OF_SDL_GetColorKey
+#define SDL_SetSurfaceColorMod IGNORE_THIS_VERSION_OF_SDL_SetSurfaceColorMod
+#define SDL_GetSurfaceColorMod IGNORE_THIS_VERSION_OF_SDL_GetSurfaceColorMod
+#define SDL_SetSurfaceAlphaMod IGNORE_THIS_VERSION_OF_SDL_SetSurfaceAlphaMod
+#define SDL_GetSurfaceAlphaMod IGNORE_THIS_VERSION_OF_SDL_GetSurfaceAlphaMod
+#define SDL_SetSurfaceBlendMode IGNORE_THIS_VERSION_OF_SDL_SetSurfaceBlendMode
+#define SDL_GetSurfaceBlendMode IGNORE_THIS_VERSION_OF_SDL_GetSurfaceBlendMode
+#define SDL_SetClipRect IGNORE_THIS_VERSION_OF_SDL_SetClipRect
+#define SDL_GetClipRect IGNORE_THIS_VERSION_OF_SDL_GetClipRect
+#define SDL_DuplicateSurface IGNORE_THIS_VERSION_OF_SDL_DuplicateSurface
+#define SDL_ConvertSurface IGNORE_THIS_VERSION_OF_SDL_ConvertSurface
+#define SDL_ConvertSurfaceFormat IGNORE_THIS_VERSION_OF_SDL_ConvertSurfaceFormat
+#define SDL_ConvertPixels IGNORE_THIS_VERSION_OF_SDL_ConvertPixels
+#define SDL_PremultiplyAlpha IGNORE_THIS_VERSION_OF_SDL_PremultiplyAlpha
+#define SDL_FillRect IGNORE_THIS_VERSION_OF_SDL_FillRect
+#define SDL_FillRects IGNORE_THIS_VERSION_OF_SDL_FillRects
+#define SDL_UpperBlit IGNORE_THIS_VERSION_OF_SDL_UpperBlit
+#define SDL_LowerBlit IGNORE_THIS_VERSION_OF_SDL_LowerBlit
+#define SDL_SoftStretch IGNORE_THIS_VERSION_OF_SDL_SoftStretch
+#define SDL_SoftStretchLinear IGNORE_THIS_VERSION_OF_SDL_SoftStretchLinear
+#define SDL_UpperBlitScaled IGNORE_THIS_VERSION_OF_SDL_UpperBlitScaled
+#define SDL_LowerBlitScaled IGNORE_THIS_VERSION_OF_SDL_LowerBlitScaled
+#define SDL_SetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_SetYUVConversionMode
+#define SDL_GetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionMode
+#define SDL_GetYUVConversionModeForResolution IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionModeForResolution
+#define SDL_GetPixelFormatName IGNORE_THIS_VERSION_OF_SDL_GetPixelFormatName
+#define SDL_PixelFormatEnumToMasks IGNORE_THIS_VERSION_OF_SDL_PixelFormatEnumToMasks
+#define SDL_MasksToPixelFormatEnum IGNORE_THIS_VERSION_OF_SDL_MasksToPixelFormatEnum
+#define SDL_AllocFormat IGNORE_THIS_VERSION_OF_SDL_AllocFormat
+#define SDL_FreeFormat IGNORE_THIS_VERSION_OF_SDL_FreeFormat
+#define SDL_AllocPalette IGNORE_THIS_VERSION_OF_SDL_AllocPalette
+#define SDL_SetPixelFormatPalette IGNORE_THIS_VERSION_OF_SDL_SetPixelFormatPalette
+#define SDL_SetPaletteColors IGNORE_THIS_VERSION_OF_SDL_SetPaletteColors
+#define SDL_FreePalette IGNORE_THIS_VERSION_OF_SDL_FreePalette
+#define SDL_MapRGB IGNORE_THIS_VERSION_OF_SDL_MapRGB
+#define SDL_MapRGBA IGNORE_THIS_VERSION_OF_SDL_MapRGBA
+#define SDL_GetRGB IGNORE_THIS_VERSION_OF_SDL_GetRGB
+#define SDL_GetRGBA IGNORE_THIS_VERSION_OF_SDL_GetRGBA
+#define SDL_CalculateGammaRamp IGNORE_THIS_VERSION_OF_SDL_CalculateGammaRamp
+#define SDL_GetNumAudioDrivers IGNORE_THIS_VERSION_OF_SDL_GetNumAudioDrivers
+#define SDL_GetAudioDriver IGNORE_THIS_VERSION_OF_SDL_GetAudioDriver
+#define SDL_AudioInit IGNORE_THIS_VERSION_OF_SDL_AudioInit
+#define SDL_AudioQuit IGNORE_THIS_VERSION_OF_SDL_AudioQuit
+#define SDL_GetCurrentAudioDriver IGNORE_THIS_VERSION_OF_SDL_GetCurrentAudioDriver
+#define SDL_OpenAudio IGNORE_THIS_VERSION_OF_SDL_OpenAudio
+#define SDL_GetNumAudioDevices IGNORE_THIS_VERSION_OF_SDL_GetNumAudioDevices
+#define SDL_GetAudioDeviceName IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceName
+#define SDL_GetAudioDeviceSpec IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceSpec
+#define SDL_GetDefaultAudioInfo IGNORE_THIS_VERSION_OF_SDL_GetDefaultAudioInfo
+#define SDL_OpenAudioDevice IGNORE_THIS_VERSION_OF_SDL_OpenAudioDevice
+#define SDL_GetAudioStatus IGNORE_THIS_VERSION_OF_SDL_GetAudioStatus
+#define SDL_GetAudioDeviceStatus IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceStatus
+#define SDL_PauseAudio IGNORE_THIS_VERSION_OF_SDL_PauseAudio
+#define SDL_PauseAudioDevice IGNORE_THIS_VERSION_OF_SDL_PauseAudioDevice
+#define SDL_LoadWAV_RW IGNORE_THIS_VERSION_OF_SDL_LoadWAV_RW
+#define SDL_FreeWAV IGNORE_THIS_VERSION_OF_SDL_FreeWAV
+#define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT
+#define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio
+#define SDL_NewAudioStream IGNORE_THIS_VERSION_OF_SDL_NewAudioStream
+#define SDL_AudioStreamPut IGNORE_THIS_VERSION_OF_SDL_AudioStreamPut
+#define SDL_AudioStreamGet IGNORE_THIS_VERSION_OF_SDL_AudioStreamGet
+#define SDL_AudioStreamAvailable IGNORE_THIS_VERSION_OF_SDL_AudioStreamAvailable
+#define SDL_AudioStreamFlush IGNORE_THIS_VERSION_OF_SDL_AudioStreamFlush
+#define SDL_AudioStreamClear IGNORE_THIS_VERSION_OF_SDL_AudioStreamClear
+#define SDL_FreeAudioStream IGNORE_THIS_VERSION_OF_SDL_FreeAudioStream
+#define SDL_MixAudio IGNORE_THIS_VERSION_OF_SDL_MixAudio
+#define SDL_MixAudioFormat IGNORE_THIS_VERSION_OF_SDL_MixAudioFormat
+#define SDL_QueueAudio IGNORE_THIS_VERSION_OF_SDL_QueueAudio
+#define SDL_DequeueAudio IGNORE_THIS_VERSION_OF_SDL_DequeueAudio
+#define SDL_GetQueuedAudioSize IGNORE_THIS_VERSION_OF_SDL_GetQueuedAudioSize
+#define SDL_ClearQueuedAudio IGNORE_THIS_VERSION_OF_SDL_ClearQueuedAudio
+#define SDL_LockAudio IGNORE_THIS_VERSION_OF_SDL_LockAudio
+#define SDL_LockAudioDevice IGNORE_THIS_VERSION_OF_SDL_LockAudioDevice
+#define SDL_UnlockAudio IGNORE_THIS_VERSION_OF_SDL_UnlockAudio
+#define SDL_UnlockAudioDevice IGNORE_THIS_VERSION_OF_SDL_UnlockAudioDevice
+#define SDL_CloseAudio IGNORE_THIS_VERSION_OF_SDL_CloseAudio
+#define SDL_CloseAudioDevice IGNORE_THIS_VERSION_OF_SDL_CloseAudioDevice
+#define SDL_GUIDToString IGNORE_THIS_VERSION_OF_SDL_GUIDToString
+#define SDL_GUIDFromString IGNORE_THIS_VERSION_OF_SDL_GUIDFromString
+#define SDL_GetNumRenderDrivers IGNORE_THIS_VERSION_OF_SDL_GetNumRenderDrivers
+#define SDL_GetRenderDriverInfo IGNORE_THIS_VERSION_OF_SDL_GetRenderDriverInfo
+#define SDL_CreateWindowAndRenderer IGNORE_THIS_VERSION_OF_SDL_CreateWindowAndRenderer
+#define SDL_CreateRenderer IGNORE_THIS_VERSION_OF_SDL_CreateRenderer
+#define SDL_CreateSoftwareRenderer IGNORE_THIS_VERSION_OF_SDL_CreateSoftwareRenderer
+#define SDL_GetRenderer IGNORE_THIS_VERSION_OF_SDL_GetRenderer
+#define SDL_RenderGetWindow IGNORE_THIS_VERSION_OF_SDL_RenderGetWindow
+#define SDL_GetRendererInfo IGNORE_THIS_VERSION_OF_SDL_GetRendererInfo
+#define SDL_GetRendererOutputSize IGNORE_THIS_VERSION_OF_SDL_GetRendererOutputSize
+#define SDL_CreateTexture IGNORE_THIS_VERSION_OF_SDL_CreateTexture
+#define SDL_CreateTextureFromSurface IGNORE_THIS_VERSION_OF_SDL_CreateTextureFromSurface
+#define SDL_QueryTexture IGNORE_THIS_VERSION_OF_SDL_QueryTexture
+#define SDL_SetTextureColorMod IGNORE_THIS_VERSION_OF_SDL_SetTextureColorMod
+#define SDL_GetTextureColorMod IGNORE_THIS_VERSION_OF_SDL_GetTextureColorMod
+#define SDL_SetTextureAlphaMod IGNORE_THIS_VERSION_OF_SDL_SetTextureAlphaMod
+#define SDL_GetTextureAlphaMod IGNORE_THIS_VERSION_OF_SDL_GetTextureAlphaMod
+#define SDL_SetTextureBlendMode IGNORE_THIS_VERSION_OF_SDL_SetTextureBlendMode
+#define SDL_GetTextureBlendMode IGNORE_THIS_VERSION_OF_SDL_GetTextureBlendMode
+#define SDL_SetTextureScaleMode IGNORE_THIS_VERSION_OF_SDL_SetTextureScaleMode
+#define SDL_GetTextureScaleMode IGNORE_THIS_VERSION_OF_SDL_GetTextureScaleMode
+#define SDL_SetTextureUserData IGNORE_THIS_VERSION_OF_SDL_SetTextureUserData
+#define SDL_GetTextureUserData IGNORE_THIS_VERSION_OF_SDL_GetTextureUserData
+#define SDL_UpdateTexture IGNORE_THIS_VERSION_OF_SDL_UpdateTexture
+#define SDL_UpdateYUVTexture IGNORE_THIS_VERSION_OF_SDL_UpdateYUVTexture
+#define SDL_UpdateNVTexture IGNORE_THIS_VERSION_OF_SDL_UpdateNVTexture
+#define SDL_LockTexture IGNORE_THIS_VERSION_OF_SDL_LockTexture
+#define SDL_LockTextureToSurface IGNORE_THIS_VERSION_OF_SDL_LockTextureToSurface
+#define SDL_UnlockTexture IGNORE_THIS_VERSION_OF_SDL_UnlockTexture
+#define SDL_RenderTargetSupported IGNORE_THIS_VERSION_OF_SDL_RenderTargetSupported
+#define SDL_SetRenderTarget IGNORE_THIS_VERSION_OF_SDL_SetRenderTarget
+#define SDL_GetRenderTarget IGNORE_THIS_VERSION_OF_SDL_GetRenderTarget
+#define SDL_RenderSetLogicalSize IGNORE_THIS_VERSION_OF_SDL_RenderSetLogicalSize
+#define SDL_RenderGetLogicalSize IGNORE_THIS_VERSION_OF_SDL_RenderGetLogicalSize
+#define SDL_RenderSetIntegerScale IGNORE_THIS_VERSION_OF_SDL_RenderSetIntegerScale
+#define SDL_RenderGetIntegerScale IGNORE_THIS_VERSION_OF_SDL_RenderGetIntegerScale
+#define SDL_RenderSetViewport IGNORE_THIS_VERSION_OF_SDL_RenderSetViewport
+#define SDL_RenderGetViewport IGNORE_THIS_VERSION_OF_SDL_RenderGetViewport
+#define SDL_RenderSetClipRect IGNORE_THIS_VERSION_OF_SDL_RenderSetClipRect
+#define SDL_RenderGetClipRect IGNORE_THIS_VERSION_OF_SDL_RenderGetClipRect
+#define SDL_RenderIsClipEnabled IGNORE_THIS_VERSION_OF_SDL_RenderIsClipEnabled
+#define SDL_RenderSetScale IGNORE_THIS_VERSION_OF_SDL_RenderSetScale
+#define SDL_RenderGetScale IGNORE_THIS_VERSION_OF_SDL_RenderGetScale
+#define SDL_RenderWindowToLogical IGNORE_THIS_VERSION_OF_SDL_RenderWindowToLogical
+#define SDL_RenderLogicalToWindow IGNORE_THIS_VERSION_OF_SDL_RenderLogicalToWindow
+#define SDL_SetRenderDrawColor IGNORE_THIS_VERSION_OF_SDL_SetRenderDrawColor
+#define SDL_GetRenderDrawColor IGNORE_THIS_VERSION_OF_SDL_GetRenderDrawColor
+#define SDL_SetRenderDrawBlendMode IGNORE_THIS_VERSION_OF_SDL_SetRenderDrawBlendMode
+#define SDL_GetRenderDrawBlendMode IGNORE_THIS_VERSION_OF_SDL_GetRenderDrawBlendMode
+#define SDL_RenderClear IGNORE_THIS_VERSION_OF_SDL_RenderClear
+#define SDL_RenderDrawPoint IGNORE_THIS_VERSION_OF_SDL_RenderDrawPoint
+#define SDL_RenderDrawPoints IGNORE_THIS_VERSION_OF_SDL_RenderDrawPoints
+#define SDL_RenderDrawLine IGNORE_THIS_VERSION_OF_SDL_RenderDrawLine
+#define SDL_RenderDrawLines IGNORE_THIS_VERSION_OF_SDL_RenderDrawLines
+#define SDL_RenderDrawRect IGNORE_THIS_VERSION_OF_SDL_RenderDrawRect
+#define SDL_RenderDrawRects IGNORE_THIS_VERSION_OF_SDL_RenderDrawRects
+#define SDL_RenderFillRect IGNORE_THIS_VERSION_OF_SDL_RenderFillRect
+#define SDL_RenderFillRects IGNORE_THIS_VERSION_OF_SDL_RenderFillRects
+#define SDL_RenderCopy IGNORE_THIS_VERSION_OF_SDL_RenderCopy
+#define SDL_RenderCopyEx IGNORE_THIS_VERSION_OF_SDL_RenderCopyEx
+#define SDL_RenderDrawPointF IGNORE_THIS_VERSION_OF_SDL_RenderDrawPointF
+#define SDL_RenderDrawPointsF IGNORE_THIS_VERSION_OF_SDL_RenderDrawPointsF
+#define SDL_RenderDrawLineF IGNORE_THIS_VERSION_OF_SDL_RenderDrawLineF
+#define SDL_RenderDrawLinesF IGNORE_THIS_VERSION_OF_SDL_RenderDrawLinesF
+#define SDL_RenderDrawRectF IGNORE_THIS_VERSION_OF_SDL_RenderDrawRectF
+#define SDL_RenderDrawRectsF IGNORE_THIS_VERSION_OF_SDL_RenderDrawRectsF
+#define SDL_RenderFillRectF IGNORE_THIS_VERSION_OF_SDL_RenderFillRectF
+#define SDL_RenderFillRectsF IGNORE_THIS_VERSION_OF_SDL_RenderFillRectsF
+#define SDL_RenderCopyF IGNORE_THIS_VERSION_OF_SDL_RenderCopyF
+#define SDL_RenderCopyExF IGNORE_THIS_VERSION_OF_SDL_

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