sdl2-compat: fixes after RenderGeometry color changes in SDL3.0

From d5c09b873cbee7a7ee78282ac76852052b998689 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 31 Jan 2024 20:10:10 +0300
Subject: [PATCH] fixes after RenderGeometry color changes in SDL3.0

---
 src/dynapi/SDL_dynapi_procs.h |  2 +-
 src/sdl2_compat.c             | 40 +++++++++++++++++++++++++++++++----
 src/sdl2_compat.h             |  7 ++++++
 src/sdl2_protos.h             |  2 +-
 src/sdl3_syms.h               |  3 +--
 5 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index ec1877e..4b1b217 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -883,7 +883,7 @@ SDL_DYNAPI_PROC(int,SDL_JoystickSendEffect,(SDL_Joystick *a, const void *b, int
 SDL_DYNAPI_PROC(float,SDL_GameControllerGetSensorDataRate,(SDL_GameController *a, SDL_SensorType b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetTextureUserData,(SDL_Texture *a, void *b),(a,b),return)
 SDL_DYNAPI_PROC(void*,SDL_GetTextureUserData,(SDL_Texture *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return)
+SDL_DYNAPI_PROC(int,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL2_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return)
 SDL_DYNAPI_PROC(int,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
 SDL_DYNAPI_PROC(int,SDL_RenderSetVSync,(SDL_Renderer *a, int b),(a,b),return)
 #ifndef SDL_DYNAPI_PROC_NO_VARARGS
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 107f93e..521ed14 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -176,6 +176,14 @@ do { \
     } \
 } while (SDL_NULL_WHILE_LOOP_CONDITION)
 
+#ifndef SDL_DISABLE_ALLOCA
+#define SDL3_stack_alloc(type, count)    (type*)alloca(sizeof(type)*(count))
+#define SDL3_stack_free(data)
+#else
+#define SDL3_stack_alloc(type, count)    (type*)SDL3_malloc(sizeof(type)*(count))
+#define SDL3_stack_free(data)            SDL3_free(data)
+#endif
+
 #include <SDL3/SDL_opengl.h>
 #include <SDL3/SDL_opengl_glext.h>
 
@@ -4237,16 +4245,40 @@ SDL_RenderCopyExF(SDL_Renderer *renderer, SDL_Texture *texture,
 }
 
 DECLSPEC int SDLCALL
-SDL_RenderGeometry(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Vertex *vertices, int num_vertices, const int *indices, int num_indices)
+SDL_RenderGeometry(SDL_Renderer *renderer, SDL_Texture *texture, const SDL2_Vertex *vertices, int num_vertices, const int *indices, int num_indices)
 {
-    const int retval = SDL3_RenderGeometry(renderer, texture, vertices, num_vertices, indices, num_indices);
-    return retval < 0 ? retval : FlushRendererIfNotBatching(renderer);
+    if (vertices) {
+        const float *xy = &vertices->position.x;
+        int xy_stride = sizeof(SDL2_Vertex);
+        const SDL_Color *color = &vertices->color;
+        int color_stride = sizeof(SDL2_Vertex);
+        const float *uv = &vertices->tex_coord.x;
+        int uv_stride = sizeof(SDL2_Vertex);
+        int size_indices = 4;
+        return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, indices, num_indices, size_indices);
+    }
+    return SDL3_InvalidParamError("vertices");
 }
 
 DECLSPEC int SDLCALL
 SDL_RenderGeometryRaw(SDL_Renderer *renderer, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices)
 {
-    const int retval = SDL3_RenderGeometryRaw(renderer, texture, xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, indices, num_indices, size_indices);
+    int i, retval;
+    SDL_FColor *color3 = (SDL_FColor *) SDL3_stack_alloc(SDL_FColor, num_vertices);
+    const char *color2 = (const char *) color;
+
+    for (i = 0; i < num_vertices; ++i) {
+        color3[i].r = color->r / 255.0f;
+        color3[i].g = color->g / 255.0f;
+        color3[i].b = color->b / 255.0f;
+        color3[i].a = color->a / 255.0f;
+        color2 += color_stride;
+        color = (const SDL_Color *) color2;
+    }
+
+    color_stride = sizeof(SDL_FColor);
+    retval = SDL3_RenderGeometryRaw(renderer, texture, xy, xy_stride, color3, color_stride, uv, uv_stride, num_vertices, indices, num_indices, size_indices);
+    SDL3_stack_free(color3);
     return retval < 0 ? retval : FlushRendererIfNotBatching(renderer);
 }
 
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index ffd96c1..239fbc2 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -321,4 +321,11 @@ typedef struct SDL_WindowShapeMode {
     SDL_WindowShapeParams parameters;
 } SDL_WindowShapeMode;
 
+
+typedef struct SDL2_Vertex {
+    SDL_FPoint position;
+    SDL_Color  color;
+    SDL_FPoint tex_coord;
+} SDL2_Vertex;
+
 #endif /* sdl2_compat_h */
diff --git a/src/sdl2_protos.h b/src/sdl2_protos.h
index 01f62d3..6a75a3b 100644
--- a/src/sdl2_protos.h
+++ b/src/sdl2_protos.h
@@ -870,7 +870,7 @@ SDL2_PROTO(int,JoystickSendEffect,(SDL_Joystick *a, const void *b, int c))
 SDL2_PROTO(float,GameControllerGetSensorDataRate,(SDL_GameController *a, SDL_SensorType b))
 SDL2_PROTO(int,SetTextureUserData,(SDL_Texture *a, void *b))
 SDL2_PROTO(void*,GetTextureUserData,(SDL_Texture *a))
-SDL2_PROTO(int,RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f))
+SDL2_PROTO(int,RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL2_Vertex *c, int d, const int *e, int f))
 SDL2_PROTO(int,RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l))
 SDL2_PROTO(int,RenderSetVSync,(SDL_Renderer *a, int b))
 SDL2_PROTO(int,asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...))
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 5fe0f52..f88ec3d 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -705,8 +705,7 @@ SDL3_SYM_PASSTHROUGH(int,FlashWindow,(SDL_Window *a, SDL_FlashOperation b),(a,b)
 SDL3_SYM_RENAMED(int,GameControllerSendEffect,SendGamepadEffect,(SDL_GameController *a, const void *b, int c),(a,b,c),return)
 SDL3_SYM_RENAMED(int,JoystickSendEffect,SendJoystickEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return)
 SDL3_SYM_RENAMED(float,GameControllerGetSensorDataRate,GetGamepadSensorDataRate,(SDL_GameController *a, SDL_SensorType b),(a,b),return)
-SDL3_SYM(int,RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return)
-SDL3_SYM(int,RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
+SDL3_SYM(int,RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_FColor *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
 SDL3_SYM_RENAMED(int,RenderSetVSync,SetRenderVSync,(SDL_Renderer *a, int b),(a,b),return)
 SDL3_SYM_VARARGS(int,asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...))
 SDL3_SYM_PASSTHROUGH(int,vasprintf,(char **a, const char *b, va_list c),(a,b,c),return)