From 1613354b43021987a21884e56eac02d3311e31a7 Mon Sep 17 00:00:00 2001
From: hzqst <[EMAIL REDACTED]>
Date: Sat, 1 Feb 2025 22:09:28 +0800
Subject: [PATCH] Fixed an issue that SDL_GL_Set/GetAttribute was messing up
with attr > 19 (#281)
Fixed SDL_GL_Set/GetAttribute messing up with SDL3/SDL2 version of
SDL_GL_CONTEXT_PROFILE_MASK which lead to black-screen in GoldSrc
games since HL25th engine update.
---
src/dynapi/SDL_dynapi_procs.h | 4 +-
src/sdl2_compat.c | 216 ++++++++++++++++++++++++++++++++--
src/sdl2_compat.h | 36 ++++++
src/sdl2_protos.h | 4 +-
src/sdl3_syms.h | 4 +-
5 files changed, 246 insertions(+), 18 deletions(-)
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 932be05..d8c7978 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -578,8 +578,8 @@ SDL_DYNAPI_PROC(int,SDL_GL_LoadLibrary,(const char *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_GL_GetProcAddress,(const char *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_GL_UnloadLibrary,(void),(),)
SDL_DYNAPI_PROC(SDL2_bool,SDL_GL_ExtensionSupported,(const char *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_GL_SetAttribute,(SDL_GLAttr a, int b),(a,b),return)
-SDL_DYNAPI_PROC(int,SDL_GL_GetAttribute,(SDL_GLAttr a, int *b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_GL_SetAttribute,(SDL2_GLattr a, int b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_GL_GetAttribute,(SDL2_GLattr a, int *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_GLContext,SDL_GL_CreateContext,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GL_GetCurrentWindow,(void),(),return)
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 5864a85..381ec52 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -5254,6 +5254,198 @@ SDL_AudioQuit(void)
SDL3_QuitSubSystem(SDL_INIT_AUDIO);
}
+SDL_DECLSPEC int SDLCALL
+SDL_GL_GetAttribute(SDL2_GLattr attr, int* value)
+{
+ bool ret = false;
+
+ switch (attr)
+ {
+ case SDL2_GL_RED_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_RED_SIZE, value);
+ break;
+ case SDL2_GL_GREEN_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_GREEN_SIZE, value);
+ break;
+ case SDL2_GL_BLUE_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_BLUE_SIZE, value);
+ break;
+ case SDL2_GL_ALPHA_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ALPHA_SIZE, value);
+ break;
+ case SDL2_GL_BUFFER_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_BUFFER_SIZE, value);
+ break;
+ case SDL2_GL_DOUBLEBUFFER:
+ ret = SDL3_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, value);
+ break;
+ case SDL2_GL_DEPTH_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_DEPTH_SIZE, value);
+ break;
+ case SDL2_GL_STENCIL_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_STENCIL_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_RED_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ACCUM_RED_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_GREEN_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ACCUM_GREEN_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_BLUE_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ACCUM_BLUE_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_ALPHA_SIZE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, value);
+ break;
+ case SDL2_GL_STEREO:
+ ret = SDL3_GL_GetAttribute(SDL_GL_STEREO, value);
+ break;
+ case SDL2_GL_MULTISAMPLEBUFFERS:
+ ret = SDL3_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, value);
+ break;
+ case SDL2_GL_MULTISAMPLESAMPLES:
+ ret = SDL3_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, value);
+ break;
+ case SDL2_GL_ACCELERATED_VISUAL:
+ ret = SDL3_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, value);
+ break;
+ case SDL2_GL_RETAINED_BACKING:
+ ret = SDL3_GL_GetAttribute(SDL_GL_RETAINED_BACKING, value);
+ break;
+ case SDL2_GL_CONTEXT_MAJOR_VERSION:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, value);
+ break;
+ case SDL2_GL_CONTEXT_MINOR_VERSION:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, value);
+ break;
+ case SDL2_GL_CONTEXT_FLAGS:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, value);
+ break;
+ case SDL2_GL_CONTEXT_PROFILE_MASK:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, value);
+ break;
+ case SDL2_GL_SHARE_WITH_CURRENT_CONTEXT:
+ ret = SDL3_GL_GetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, value);
+ break;
+ case SDL2_GL_FRAMEBUFFER_SRGB_CAPABLE:
+ ret = SDL3_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, value);
+ break;
+ case SDL2_GL_CONTEXT_RELEASE_BEHAVIOR:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_RELEASE_BEHAVIOR, value);
+ break;
+ case SDL2_GL_CONTEXT_RESET_NOTIFICATION:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_RESET_NOTIFICATION, value);
+ break;
+ case SDL2_GL_CONTEXT_NO_ERROR:
+ ret = SDL3_GL_GetAttribute(SDL_GL_CONTEXT_NO_ERROR, value);
+ break;
+ case SDL2_GL_FLOATBUFFERS:
+ ret = SDL3_GL_GetAttribute(SDL_GL_FLOATBUFFERS, value);
+ break;
+ case SDL2_GL_CONTEXT_EGL:
+ ret = SDL3_GL_GetAttribute(SDL_GL_EGL_PLATFORM, value);
+ break;
+ }
+
+ return ret ? 0 : -1;
+}
+
+SDL_DECLSPEC int SDLCALL
+SDL_GL_SetAttribute(SDL2_GLattr attr, int value)
+{
+ bool ret = false;
+
+ switch (attr)
+ {
+ case SDL2_GL_RED_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_RED_SIZE, value);
+ break;
+ case SDL2_GL_GREEN_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_GREEN_SIZE, value);
+ break;
+ case SDL2_GL_BLUE_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_BLUE_SIZE, value);
+ break;
+ case SDL2_GL_ALPHA_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ALPHA_SIZE, value);
+ break;
+ case SDL2_GL_BUFFER_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_BUFFER_SIZE, value);
+ break;
+ case SDL2_GL_DOUBLEBUFFER:
+ ret = SDL3_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, value);
+ break;
+ case SDL2_GL_DEPTH_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_DEPTH_SIZE, value);
+ break;
+ case SDL2_GL_STENCIL_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_STENCIL_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_RED_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_GREEN_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_BLUE_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, value);
+ break;
+ case SDL2_GL_ACCUM_ALPHA_SIZE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, value);
+ break;
+ case SDL2_GL_STEREO:
+ ret = SDL3_GL_SetAttribute(SDL_GL_STEREO, value);
+ break;
+ case SDL2_GL_MULTISAMPLEBUFFERS:
+ ret = SDL3_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, value);
+ break;
+ case SDL2_GL_MULTISAMPLESAMPLES:
+ ret = SDL3_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, value);
+ break;
+ case SDL2_GL_ACCELERATED_VISUAL:
+ ret = SDL3_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, value);
+ break;
+ case SDL2_GL_RETAINED_BACKING:
+ ret = SDL3_GL_SetAttribute(SDL_GL_RETAINED_BACKING, value);
+ break;
+ case SDL2_GL_CONTEXT_MAJOR_VERSION:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, value);
+ break;
+ case SDL2_GL_CONTEXT_MINOR_VERSION:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, value);
+ break;
+ case SDL2_GL_CONTEXT_FLAGS:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, value);
+ break;
+ case SDL2_GL_CONTEXT_PROFILE_MASK:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, value);
+ break;
+ case SDL2_GL_SHARE_WITH_CURRENT_CONTEXT:
+ ret = SDL3_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, value);
+ break;
+ case SDL2_GL_FRAMEBUFFER_SRGB_CAPABLE:
+ ret = SDL3_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, value);
+ break;
+ case SDL2_GL_CONTEXT_RELEASE_BEHAVIOR:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_RELEASE_BEHAVIOR, value);
+ break;
+ case SDL2_GL_CONTEXT_RESET_NOTIFICATION:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_RESET_NOTIFICATION, value);
+ break;
+ case SDL2_GL_CONTEXT_NO_ERROR:
+ ret = SDL3_GL_SetAttribute(SDL_GL_CONTEXT_NO_ERROR, value);
+ break;
+ case SDL2_GL_FLOATBUFFERS:
+ ret = SDL3_GL_SetAttribute(SDL_GL_FLOATBUFFERS, value);
+ break;
+ case SDL2_GL_CONTEXT_EGL:
+ ret = SDL3_GL_SetAttribute(SDL_GL_EGL_PLATFORM, value);
+ break;
+ }
+
+ return ret ? 0 : -1;
+}
+
SDL_DECLSPEC int SDLCALL
SDL_VideoInit(const char *driver_name)
{
@@ -5265,10 +5457,10 @@ SDL_VideoInit(const char *driver_name)
ret = SDL3_InitSubSystem(SDL_INIT_VIDEO) ? 0 : -1;
/* default SDL2 GL attributes */
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 2);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
+ SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
+ SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
return ret;
}
@@ -5287,10 +5479,10 @@ SDL_Init(Uint32 flags)
ret = SDL3_InitSubSystem(flags) ? 0 : -1;
if (flags & SDL_INIT_VIDEO) {
/* default SDL2 GL attributes */
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 2);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
+ SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
+ SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
}
return ret;
@@ -5329,10 +5521,10 @@ SDL_InitSubSystem(Uint32 flags)
ret = SDL3_InitSubSystem(flags) ? 0 : -1;
if (flags & SDL_INIT_VIDEO) {
/* default SDL2 GL attributes */
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 3);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 2);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
+ SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
+ SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
+ SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
}
return ret;
}
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index a0d07df..afa4b97 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -1452,6 +1452,42 @@ typedef struct SDL2_Surface
int refcount; /**< Read-mostly */
} SDL2_Surface;
+
+//SDL3 has different SDL_GLattr enum since 19
+// (SDL_GL_CONTEXT_EGL in SDL2 vs SDL_GL_CONTEXT_FLAGS in SDL3), SDL2 apps like GoldSrc will be unhappy with SDL_GL_CONTEXT_PROFILE_MASK or sth.
+
+typedef enum SDL2_GLattr
+{
+ SDL2_GL_RED_SIZE, /**< the minimum number of bits for the red channel of the color buffer; defaults to 3. */
+ SDL2_GL_GREEN_SIZE, /**< the minimum number of bits for the green channel of the color buffer; defaults to 3. */
+ SDL2_GL_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the color buffer; defaults to 2. */
+ SDL2_GL_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the color buffer; defaults to 0. */
+ SDL2_GL_BUFFER_SIZE, /**< the minimum number of bits for frame buffer size; defaults to 0. */
+ SDL2_GL_DOUBLEBUFFER, /**< whether the output is single or double buffered; defaults to double buffering on. */
+ SDL2_GL_DEPTH_SIZE, /**< the minimum number of bits in the depth buffer; defaults to 16. */
+ SDL2_GL_STENCIL_SIZE, /**< the minimum number of bits in the stencil buffer; defaults to 0. */
+ SDL2_GL_ACCUM_RED_SIZE, /**< the minimum number of bits for the red channel of the accumulation buffer; defaults to 0. */
+ SDL2_GL_ACCUM_GREEN_SIZE, /**< the minimum number of bits for the green channel of the accumulation buffer; defaults to 0. */
+ SDL2_GL_ACCUM_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the accumulation buffer; defaults to 0. */
+ SDL2_GL_ACCUM_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the accumulation buffer; defaults to 0. */
+ SDL2_GL_STEREO, /**< whether the output is stereo 3D; defaults to off. */
+ SDL2_GL_MULTISAMPLEBUFFERS, /**< the number of buffers used for multisample anti-aliasing; defaults to 0. */
+ SDL2_GL_MULTISAMPLESAMPLES, /**< the number of samples used around the current pixel used for multisample anti-aliasing. */
+ SDL2_GL_ACCELERATED_VISUAL, /**< set to 1 to require hardware acceleration, set to 0 to force software rendering; defaults to allow either. */
+ SDL2_GL_RETAINED_BACKING, /**< not used (deprecated). */
+ SDL2_GL_CONTEXT_MAJOR_VERSION, /**< OpenGL context major version. */
+ SDL2_GL_CONTEXT_MINOR_VERSION, /**< OpenGL context minor version. */
+ SDL2_GL_CONTEXT_EGL, /**< deprecated: set SDL_GL_CONTEXT_PROFILE_MASK to SDL_GL_CONTEXT_PROFILE_ES to enable instead. */
+ SDL2_GL_CONTEXT_FLAGS, /**< some combination of 0 or more of elements of the SDL_GLcontextFlag enumeration; defaults to 0. */
+ SDL2_GL_CONTEXT_PROFILE_MASK, /**< type of GL context (Core, Compatibility, ES). See SDL_GLprofile; default value depends on platform. */
+ SDL2_GL_SHARE_WITH_CURRENT_CONTEXT, /**< OpenGL context sharing; defaults to 0. */
+ SDL2_GL_FRAMEBUFFER_SRGB_CAPABLE, /**< requests sRGB capable visual; defaults to 0. (>= SDL 2.0.1) */
+ SDL2_GL_CONTEXT_RELEASE_BEHAVIOR, /**< sets context the release behavior; defaults to 1. (>= SDL 2.0.4) */
+ SDL2_GL_CONTEXT_RESET_NOTIFICATION,
+ SDL2_GL_CONTEXT_NO_ERROR,
+ SDL2_GL_FLOATBUFFERS
+} SDL2_GLattr;
+
#define SDL_VIRTUAL_JOYSTICK_DESC_VERSION 1
typedef struct SDL2_VirtualJoystickDesc
diff --git a/src/sdl2_protos.h b/src/sdl2_protos.h
index 8118723..746f44e 100644
--- a/src/sdl2_protos.h
+++ b/src/sdl2_protos.h
@@ -576,8 +576,8 @@ SDL2_PROTO(int,GL_LoadLibrary,(const char *a))
SDL2_PROTO(void*,GL_GetProcAddress,(const char *a))
SDL2_PROTO(void,GL_UnloadLibrary,(void))
SDL2_PROTO(SDL2_bool,GL_ExtensionSupported,(const char *a))
-SDL2_PROTO(int,GL_SetAttribute,(SDL_GLAttr a, int b))
-SDL2_PROTO(int,GL_GetAttribute,(SDL_GLAttr a, int *b))
+SDL2_PROTO(int,GL_SetAttribute,(SDL2_GLattr a, int b))
+SDL2_PROTO(int,GL_GetAttribute,(SDL2_GLattr a, int *b))
SDL2_PROTO(SDL_GLContext,GL_CreateContext,(SDL_Window *a))
SDL2_PROTO(int,GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b))
SDL2_PROTO(SDL_Window*,GL_GetCurrentWindow,(void))
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 085a456..29a8e7a 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -187,7 +187,7 @@ SDL3_SYM_RENAMED(void,FreeCursor,DestroyCursor,(SDL_Cursor *a),(a),)
SDL3_SYM_PASSTHROUGH(SDL_GLContext,GL_CreateContext,(SDL_Window *a),(a),return)
SDL3_SYM(bool,GL_DestroyContext,(SDL_GLContext a),(a),return)
SDL3_SYM_PASSTHROUGH_BOOL(bool,GL_ExtensionSupported,(const char *a),(a),return)
-SDL3_SYM_PASSTHROUGH_RETCODE(bool,GL_GetAttribute,(SDL_GLAttr a, int *b),(a,b),return)
+SDL3_SYM(bool,GL_GetAttribute,(SDL_GLAttr a, int *b),(a,b),return)
SDL3_SYM_PASSTHROUGH(SDL_GLContext,GL_GetCurrentContext,(void),(),return)
SDL3_SYM_PASSTHROUGH(SDL_Window*,GL_GetCurrentWindow,(void),(),return)
SDL3_SYM_PASSTHROUGH(void*,GL_GetProcAddress,(const char *a),(a),return)
@@ -195,7 +195,7 @@ SDL3_SYM(bool,GL_GetSwapInterval,(int *a),(a),return)
SDL3_SYM_PASSTHROUGH_RETCODE(bool,GL_LoadLibrary,(const char *a),(a),return)
SDL3_SYM_PASSTHROUGH_RETCODE(bool,GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return)
SDL3_SYM_PASSTHROUGH(void,GL_ResetAttributes,(void),(),)
-SDL3_SYM_PASSTHROUGH_RETCODE(bool,GL_SetAttribute,(SDL_GLAttr a, int b),(a,b),return)
+SDL3_SYM(bool,GL_SetAttribute,(SDL_GLAttr a, int b),(a,b),return)
SDL3_SYM_PASSTHROUGH_RETCODE(bool,GL_SetSwapInterval,(int a),(a),return)
SDL3_SYM(bool,GL_SwapWindow,(SDL_Window *a),(a),return)
SDL3_SYM_PASSTHROUGH(void,GL_UnloadLibrary,(void),(),)