sdl2-compat: Implement SDL_SetError and SDL_GetError.

From a2e713da96d00d2a69a6ea5bc3a2a14ac0bcaad3 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Fri, 25 Nov 2022 17:07:19 -0500
Subject: [PATCH] Implement SDL_SetError and SDL_GetError.

SetError needs to be implemented here because it's varargs, GetError
(possibly unnecessarily) checks for SDL3 failing to load.
---
 src/sdl2_compat.c | 36 ++++++++++++++++++++++++++++++++++++
 src/sdl3_syms.h   |  2 +-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index f5c2255..4bd660d 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -489,6 +489,42 @@ SDL_GetVersion(SDL_version * ver)
     }
 }
 
+DECLSPEC void SDLCALL
+SDL_SetError(const char *fmt, ...)
+{
+    char ch;
+    char *str = NULL;
+    size_t len = 0;
+    va_list ap;
+
+    va_start(ap, fmt);
+    len = SDL3_vsnprintf(&ch, 1, fmt, ap);
+    va_end(ap);
+
+    str = (char *) SDL3_malloc(len + 1);
+    if (!str) {
+        SDL3_OutOfMemory();
+    } else {
+        va_start(ap, fmt);
+        SDL3_vsnprintf(str, len + 1, fmt, ap);
+        va_end(ap);
+        SDL3_SetError("%s", str);
+        SDL3_free(str);
+    }
+}
+
+DECLSPEC const char * SDLCALL
+SDL_GetError(void)
+{
+    /* !!! FIXME: can this actually happen? or did we always terminate the process in this case? */
+    if (SDL3_GetError == NULL) {
+        static const char noload_errstr[] = "SDL3 library isn't loaded.";
+        return noload_errstr;
+    }
+    return SDL3_GetError();
+}
+
+
 DECLSPEC int SDLCALL
 SDL_sscanf(const char *text, const char *fmt, ...)
 {
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index c891aff..48bdd2b 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -142,7 +142,7 @@ SDL3_SYM_PASSTHROUGH(SDL_bool,HasSSE3,(void),(),return)
 SDL3_SYM_PASSTHROUGH(SDL_bool,HasSSE41,(void),(),return)
 SDL3_SYM_PASSTHROUGH(SDL_bool,HasSSE42,(void),(),return)
 SDL3_SYM_PASSTHROUGH(int,GetSystemRAM,(void),(),return)
-SDL3_SYM_PASSTHROUGH(const char*,GetError,(void),(),return)
+SDL3_SYM(const char*,GetError,(void),(),return)
 SDL3_SYM_PASSTHROUGH(void,ClearError,(void),(),)
 SDL3_SYM_PASSTHROUGH(int,Error,(SDL_errorcode a),(a),return)
 SDL3_SYM_PASSTHROUGH(void,PumpEvents,(void),(),)