diff --git a/gfx/context/sdl_ctx.c b/gfx/context/sdl_ctx.c index e6eee2f392..2abd05a0a9 100644 --- a/gfx/context/sdl_ctx.c +++ b/gfx/context/sdl_ctx.c @@ -38,6 +38,11 @@ static SDL_Window *g_window; static SDL_GLContext g_ctx; #endif +#define GL_SYM_WRAP(symbol, proc) if (!symbol) { \ + gfx_ctx_proc_t sym = gfx_ctx_get_proc_address(proc); \ + memcpy(&(symbol), &sym, sizeof(sym)); \ +} + static bool g_fullscreen; static unsigned g_interval; @@ -55,7 +60,7 @@ void gfx_ctx_set_swap_interval(unsigned interval, bool inited) #if defined(_WIN32) static BOOL (APIENTRY *wgl_swap_interval)(int) = NULL; if (!wgl_swap_interval) - SDL_SYM_WRAP(wgl_swap_interval, "wglSwapIntervalEXT"); + GL_SYM_WRAP(wgl_swap_interval, "wglSwapIntervalEXT"); if (wgl_swap_interval) success = wgl_swap_interval(g_interval); #elif defined(__APPLE__) && defined(HAVE_OPENGL) @@ -64,9 +69,9 @@ void gfx_ctx_set_swap_interval(unsigned interval, bool inited) #else static int (*glx_swap_interval)(int) = NULL; if (!glx_swap_interval) - SDL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalSGI"); + GL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalSGI"); if (!glx_swap_interval) - SDL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalMESA"); + GL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalMESA"); if (glx_swap_interval) success = glx_swap_interval(g_interval) == 0; @@ -458,5 +463,18 @@ void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_r gl->mvp = proj; } + +// Enforce void (*)(void) as it's not really legal to cast void* to fn-pointer. +// POSIX allows this, but strict C99 doesn't. +gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol) +{ + rarch_assert(sizeof(void*) == sizeof(void (*)(void))); + gfx_ctx_proc_t ret; + + void *sym__ = SDL_GL_GetProcAddress(symbol); + memcpy(&ret, &sym__, sizeof(void*)); + + return ret; +} #endif diff --git a/gfx/context/sdl_ctx.h b/gfx/context/sdl_ctx.h index 7f3167bc52..5246baa9d7 100644 --- a/gfx/context/sdl_ctx.h +++ b/gfx/context/sdl_ctx.h @@ -25,11 +25,5 @@ #define SDL_MODERN 0 #endif -// Not legal to cast (void*) to fn-pointer. Need workaround to be compliant. -#define SDL_SYM_WRAP(sym, symbol) { \ - rarch_assert(sizeof(void*) == sizeof(void (*)(void))); \ - void *sym__ = SDL_GL_GetProcAddress(symbol); \ - memcpy(&(sym), &sym__, sizeof(void*)); \ -} - #endif + diff --git a/gfx/gfx_context.h b/gfx/gfx_context.h index 84b54f0a9e..5fe4016d6e 100644 --- a/gfx/gfx_context.h +++ b/gfx/gfx_context.h @@ -78,7 +78,9 @@ int gfx_ctx_check_resolution(unsigned resolution_id); #endif #if defined(HAVE_OPENGL) || defined(HAVE_D3D9) || defined(HAVE_D3D8) +typedef void (*gfx_ctx_proc_t)(void); void gfx_ctx_set_projection(VID_HANDLE *gl, const struct gl_ortho *ortho, bool allow_rotate); +gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *sym); #endif #endif diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index db923ee05c..b19a87d4ad 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -890,7 +890,10 @@ static void gl_glsl_reset_attrib(void) gl_attrib_index = 0; } -#define LOAD_GL_SYM(SYM) if (!pgl##SYM) { SDL_SYM_WRAP(pgl##SYM, "gl" #SYM) } +#define LOAD_GL_SYM(SYM) if (!pgl##SYM) { \ + gfx_ctx_proc_t sym = gfx_ctx_get_proc_address("gl" #SYM); \ + memcpy(&(pgl##SYM), &sym, sizeof(sym)); \ +} bool gl_glsl_init(const char *path) {