diff --git a/Makefile b/Makefile index 2da091af2c..35787962d6 100644 --- a/Makefile +++ b/Makefile @@ -77,10 +77,6 @@ else endif endif -ifeq ($(HAVE_FBO), 1) - DEFINES += -DHAVE_FBO -endif - ifeq ($(HAVE_XVIDEO), 1) OBJ += gfx/xvideo.o input/x11_input.o LIBS += -lXv -lX11 @@ -133,7 +129,7 @@ ifneq ($(V),1) Q := @ endif -CFLAGS += -Wall -O3 -g -I. +CFLAGS += -Wall -O3 -g -I. -pedantic ifneq ($(findstring icc,$(CC)),) CFLAGS += -std=c99 else diff --git a/audio/ext.c b/audio/ext.c index 931778643b..b556c8ddf4 100644 --- a/audio/ext.c +++ b/audio/ext.c @@ -64,7 +64,7 @@ static void* audio_ext_init(const char *device, unsigned rate, unsigned latency) goto error; } - const ssnes_audio_driver_t* (*plugin_load)(void) = dylib_proc(ext->lib, "ssnes_audio_driver_init"); + const ssnes_audio_driver_t* (*plugin_load)(void) = (const ssnes_audio_driver_t* (*)(void))dylib_proc(ext->lib, "ssnes_audio_driver_init"); if (!plugin_load) { diff --git a/driver.c b/driver.c index e5ddae8d6e..db0c9e96cb 100644 --- a/driver.c +++ b/driver.c @@ -161,7 +161,8 @@ static void init_dsp_plugin(void) return; } - const ssnes_dsp_plugin_t* (*SSNES_API_CALLTYPE plugin_init)(void) = dylib_proc(g_extern.audio_data.dsp_lib, "ssnes_dsp_plugin_init"); + const ssnes_dsp_plugin_t* (*SSNES_API_CALLTYPE plugin_init)(void) = + (const ssnes_dsp_plugin_t *(*)(void))dylib_proc(g_extern.audio_data.dsp_lib, "ssnes_dsp_plugin_init"); if (!plugin_init) { SSNES_ERR("Failed to find symbol \"ssnes_dsp_plugin_init\" in DSP plugin.\n"); @@ -310,8 +311,12 @@ static void init_filter(void) return; } - g_extern.filter.psize = dylib_proc(g_extern.filter.lib, "filter_size"); - g_extern.filter.prender = dylib_proc(g_extern.filter.lib, "filter_render"); + g_extern.filter.psize = + (void (*)(unsigned*, unsigned*))dylib_proc(g_extern.filter.lib, "filter_size"); + g_extern.filter.prender = + (void (*)(uint32_t*, uint32_t*, + unsigned, const uint16_t*, + unsigned, unsigned, unsigned))dylib_proc(g_extern.filter.lib, "filter_render"); if (!g_extern.filter.psize || !g_extern.filter.prender) { SSNES_ERR("Failed to find functions in filter...\n"); diff --git a/dynamic.c b/dynamic.c index e1ed48cd74..8a377cabbc 100644 --- a/dynamic.c +++ b/dynamic.c @@ -18,6 +18,7 @@ #include "dynamic.h" #include "general.h" #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -34,13 +35,13 @@ #ifdef HAVE_DYNAMIC #define DLSYM(lib, x) dylib_proc(lib, #x) -#define SYM(x) do { \ - p##x = DLSYM(lib_handle, x); \ +#define SYM(type, x) do { \ + p##x = (type)DLSYM(lib_handle, x); \ if (p##x == NULL) { SSNES_ERR("Failed to load symbol: \"%s\"\n", #x); exit(1); } \ } while(0) -#define OPT_SYM(x) do { \ - p##x = DLSYM(lib_handle, x); \ +#define OPT_SYM(type, x) do { \ + p##x = (type)DLSYM(lib_handle, x); \ } while(0) static dylib_t lib_handle = NULL; @@ -106,33 +107,38 @@ static void load_dynamic(void) exit(1); } - SYM(snes_init); - SYM(snes_set_video_refresh); - SYM(snes_set_audio_sample); - SYM(snes_set_input_poll); - SYM(snes_set_input_state); - OPT_SYM(snes_library_id); - SYM(snes_library_revision_minor); - SYM(snes_library_revision_major); - SYM(snes_cheat_reset); - SYM(snes_cheat_set); - SYM(snes_reset); - SYM(snes_run); - SYM(snes_get_region); - SYM(snes_load_cartridge_normal); - SYM(snes_load_cartridge_super_game_boy); - SYM(snes_load_cartridge_bsx); - SYM(snes_load_cartridge_bsx_slotted); - SYM(snes_load_cartridge_sufami_turbo); - SYM(snes_set_controller_port_device); - SYM(snes_serialize_size); - SYM(snes_serialize); - SYM(snes_unserialize); - SYM(snes_set_cartridge_basename); - SYM(snes_get_memory_data); - SYM(snes_get_memory_size); - SYM(snes_unload_cartridge); - SYM(snes_term); + SYM(void (*)(void), snes_init); + SYM(void (*)(snes_video_refresh_t), snes_set_video_refresh); + SYM(void (*)(snes_audio_sample_t), snes_set_audio_sample); + SYM(void (*)(snes_input_poll_t), snes_set_input_poll); + SYM(void (*)(snes_input_state_t), snes_set_input_state); + OPT_SYM(const char *(*)(void), snes_library_id); + SYM(unsigned (*)(void), snes_library_revision_minor); + SYM(unsigned (*)(void), snes_library_revision_major); + SYM(void (*)(void), snes_cheat_reset); + SYM(void (*)(unsigned, bool, const char*), snes_cheat_set); + SYM(void (*)(void), snes_reset); + SYM(void (*)(void), snes_run); + SYM(bool (*)(void), snes_get_region); + SYM(bool (*)(const char*, const uint8_t*, unsigned), snes_load_cartridge_normal); + SYM(bool (*)(const char*, const uint8_t*, unsigned, + const char*, const uint8_t*, unsigned), snes_load_cartridge_super_game_boy); + SYM(bool (*)(const char*, const uint8_t*, unsigned, + const char*, const uint8_t*, unsigned), snes_load_cartridge_bsx); + SYM(bool (*)(const char*, const uint8_t*, unsigned, + const char*, const uint8_t*, unsigned), snes_load_cartridge_bsx_slotted); + SYM(bool (*)(const char*, const uint8_t*, unsigned, + const char*, const uint8_t*, unsigned, + const char*, const uint8_t*, unsigned), snes_load_cartridge_sufami_turbo); + SYM(void (*)(bool, unsigned), snes_set_controller_port_device); + SYM(unsigned (*)(void), snes_serialize_size); + SYM(bool (*)(uint8_t*, unsigned), snes_serialize); + SYM(bool (*)(const uint8_t*, unsigned), snes_unserialize); + SYM(void (*)(const char*), snes_set_cartridge_basename); + SYM(uint8_t *(*)(unsigned), snes_get_memory_data); + SYM(unsigned (*)(unsigned), snes_get_memory_size); + SYM(void (*)(void), snes_unload_cartridge); + SYM(void (*)(void), snes_term); } #endif @@ -174,6 +180,9 @@ static void set_statics(void) void init_dlsym(void) { + // Guarantee that we can do "dirty" casting. Every OS that this program supports should pass this ... + assert(sizeof(void*) == sizeof(void (*)(void))); + #ifdef HAVE_DYNAMIC if (strlen(g_settings.libsnes) > 0) load_dynamic(); @@ -205,12 +214,15 @@ dylib_t dylib_load(const char *path) #endif } -void* dylib_proc(dylib_t lib, const char *proc) +function_t dylib_proc(dylib_t lib, const char *proc) { #ifdef _WIN32 - void *sym = (void*)GetProcAddress(lib, proc); + function_t sym = (function_t)GetProcAddress(lib, proc); #else - void *sym = dlsym(lib, proc); + // Dirty hack to workaround the non-legality of void* -> fn-pointer casts. + void *ptr_sym = dlsym(lib, proc); + function_t sym; + memcpy(&sym, &ptr_sym, sizeof(void*)); #endif if (!sym) diff --git a/dynamic.h b/dynamic.h index 6572c48cee..4ed107bdb3 100644 --- a/dynamic.h +++ b/dynamic.h @@ -25,10 +25,11 @@ void init_dlsym(void); void uninit_dlsym(void); typedef void *dylib_t; +typedef void (*function_t)(void); dylib_t dylib_load(const char *path); void dylib_close(dylib_t lib); -void* dylib_proc(dylib_t lib, const char *proc); +function_t dylib_proc(dylib_t lib, const char *proc); extern void (*psnes_init)(void); diff --git a/general.h b/general.h index 3dcf53c2df..a25e931618 100644 --- a/general.h +++ b/general.h @@ -274,19 +274,19 @@ void parse_config(void); extern struct settings g_settings; extern struct global g_extern; -#define SSNES_LOG(msg, args...) do { \ +#define SSNES_LOG(...) do { \ if (g_extern.verbose) \ - fprintf(stderr, "SSNES: " msg, ##args); \ + fprintf(stderr, "SSNES: " __VA_ARGS__); \ fflush(stderr); \ } while(0) -#define SSNES_ERR(msg, args...) do { \ - fprintf(stderr, "SSNES [ERROR] :: " msg, ##args); \ +#define SSNES_ERR(...) do { \ + fprintf(stderr, "SSNES [ERROR] :: " __VA_ARGS__); \ fflush(stderr); \ } while(0) -#define SSNES_WARN(msg, args...) do { \ - fprintf(stderr, "SSNES [WARN] :: " msg, ##args); \ +#define SSNES_WARN(...) do { \ + fprintf(stderr, "SSNES [WARN] :: " __VA_ARGS__); \ fflush(stderr); \ } while(0) diff --git a/gfx/ext.c b/gfx/ext.c index 41f4ad67d2..d4e866e528 100644 --- a/gfx/ext.c +++ b/gfx/ext.c @@ -273,7 +273,8 @@ static void* video_ext_init(const video_info_t *video, const input_driver_t **in goto error; } - const ssnes_video_driver_t* (*video_init)(void) = dylib_proc(g_lib, "ssnes_video_init"); + const ssnes_video_driver_t* (*video_init)(void) = + (const ssnes_video_driver_t *(*)(void))dylib_proc(g_lib, "ssnes_video_init"); if (!video_init) { SSNES_ERR("Couldn't find function ssnes_video_init in library ...\n"); diff --git a/gfx/gl.c b/gfx/gl.c index 41ca093f70..e71a3ebc75 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -81,7 +81,7 @@ static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D = NULL; static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus = NULL; static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers = NULL; -#define LOAD_SYM(sym) if (!p##sym) p##sym = ((void*)SDL_GL_GetProcAddress(#sym)) +#define LOAD_SYM(sym) if (!p##sym) { SDL_SYM_WRAP(p##sym, #sym) } static bool load_fbo_proc(void) { LOAD_SYM(glGenFramebuffers); @@ -942,12 +942,21 @@ static void gl_set_nonblock_state(void *data, bool state) SSNES_LOG("GL VSync => %s\n", state ? "off" : "on"); #ifdef _WIN32 static BOOL (APIENTRY *wgl_swap_interval)(int) = NULL; - if (!wgl_swap_interval) wgl_swap_interval = (BOOL (APIENTRY*)(int)) SDL_GL_GetProcAddress("wglSwapIntervalEXT"); + if (!wgl_swap_interval) + { + SDL_SYM_WRAP(wgl_swap_interval, "wglSwapIntervalEXT"); + } if (wgl_swap_interval) wgl_swap_interval(state ? 0 : 1); #else static int (*glx_swap_interval)(int) = NULL; - if (!glx_swap_interval) glx_swap_interval = (int (*)(int))SDL_GL_GetProcAddress("glXSwapIntervalSGI"); - if (!glx_swap_interval) glx_swap_interval = (int (*)(int))SDL_GL_GetProcAddress("glXSwapIntervalMESA"); + if (!glx_swap_interval) + { + SDL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalSGI"); + } + if (!glx_swap_interval) + { + SDL_SYM_WRAP(glx_swap_interval, "glxSwapIntervalMESA"); + } if (glx_swap_interval) glx_swap_interval(state ? 0 : 1); #endif } diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 9ff0225ac7..2c6d14750b 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -106,6 +106,13 @@ struct gl_tex_info float coord[8]; }; +// Not legal to cast void* to fn-pointer. Need dirty hack to be compilant. +// sizeof(void*) == sizeof(void (*)(void)) is asserted earlier. +#define SDL_SYM_WRAP(sym, symbol) { \ + void *sym__ = SDL_GL_GetProcAddress(symbol); \ + memcpy(&(sym), &sym__, sizeof(void*)); \ +} + // Windows ... <_< #if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) extern PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture; diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index b71ebc5543..13229701d2 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -321,7 +321,7 @@ static bool load_plain(const char *path) return true; } -#define print_buf(buf, args...) snprintf(buf, sizeof(buf), ##args) +#define print_buf(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) #ifdef HAVE_CONFIGFILE static bool load_textures(const char *dir_path, config_file_t *conf) diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 933db488d0..c1f5b33441 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -706,7 +706,7 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size return true; } -#define LOAD_GL_SYM(SYM) if (!(pgl##SYM)) pgl##SYM = SDL_GL_GetProcAddress("gl" #SYM) +#define LOAD_GL_SYM(SYM) if (!pgl##SYM) { SDL_SYM_WRAP(pgl##SYM, "gl" #SYM) } bool gl_glsl_init(const char *path) {