diff --git a/config.def.h b/config.def.h index 3eacf50f23..22a872c014 100644 --- a/config.def.h +++ b/config.def.h @@ -129,6 +129,9 @@ static const unsigned fullscreen_y = 0; // Force 16-bit colors. static const bool force_16bit = false; +// Forcibly disable composition. Only valid on Windows Vista/7 for now. +static const bool disable_composition = false; + // Video VSYNC (recommended) static const bool vsync = true; diff --git a/general.h b/general.h index 9494a8ed92..4754249e91 100644 --- a/general.h +++ b/general.h @@ -89,6 +89,7 @@ struct settings float msg_pos_y; bool force_16bit; + bool disable_composition; char external_driver[256]; } video; diff --git a/gfx/ext.c b/gfx/ext.c index d4e866e528..ce7fcbf42a 100644 --- a/gfx/ext.c +++ b/gfx/ext.c @@ -224,6 +224,15 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive return false; } + const char *cg_shader = NULL; + const char *xml_shader = NULL; + enum ssnes_shader_type type = g_settings.video.shader_type; + if ((type == SSNES_SHADER_CG || type == SSNES_SHADER_AUTO) && *g_settings.video.cg_shader_path) + cg_shader = g_settings.video.cg_shader_path; + else if ((type == SSNES_SHADER_BSNES || type == SSNES_SHADER_AUTO) && *g_settings.video.bsnes_shader_path) + xml_shader = g_settings.video.bsnes_shader_path; + + ssnes_video_info_t info = { .width = video->width, .height = video->height, @@ -234,8 +243,8 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive .smooth = video->smooth, .input_scale = video->input_scale, .color_format = video->rgb32 ? SSNES_COLOR_FORMAT_ARGB8888 : SSNES_COLOR_FORMAT_XRGB1555, - .xml_shader = g_settings.video.bsnes_shader_path, - .cg_shader = g_settings.video.cg_shader_path, + .xml_shader = xml_shader, + .cg_shader = cg_shader, .ttf_font = *g_settings.video.font_path ? g_settings.video.font_path : NULL, .ttf_font_size = g_settings.video.font_size }; diff --git a/gfx/gfx_common.c b/gfx/gfx_common.c index ee49e8b755..89c47243aa 100644 --- a/gfx/gfx_common.c +++ b/gfx/gfx_common.c @@ -60,4 +60,56 @@ bool gfx_window_title(char *buf, size_t size) return ret; } +#ifdef _WIN32 +#include +#include "dynamic.h" +// We only load this library once, so we let it be unloaded at application shutdown, +// since unloading it early seems to cause issues on some systems. + +static dylib_t dwmlib = NULL; + +static void gfx_dwm_shutdown(void) +{ + if (dwmlib) + dylib_close(dwmlib); +} + +void gfx_set_dwm(void) +{ + static bool inited = false; + if (inited) + return; + inited = true; + + dwmlib = dylib_load("dwmapi.dll"); + if (!dwmlib) + { + SSNES_LOG("Did not find dwmapi.dll"); + return; + } + atexit(gfx_dwm_shutdown); + + HRESULT (WINAPI *mmcss)(BOOL) = (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS"); + if (mmcss) + { + SSNES_LOG("Setting multimedia scheduling for DWM.\n"); + mmcss(TRUE); + } + + if (!g_settings.video.disable_composition) + return; + + HRESULT (WINAPI *composition_enable)(UINT) = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition"); + if (!composition_enable) + { + SSNES_ERR("Did not find DwmEnableComposition ...\n"); + return; + } + + HRESULT ret = composition_enable(0); + if (FAILED(ret)) + SSNES_ERR("Failed to set composition state ...\n"); +} + +#endif diff --git a/gfx/gfx_common.h b/gfx/gfx_common.h index 97baee203b..e73f757f02 100644 --- a/gfx/gfx_common.h +++ b/gfx/gfx_common.h @@ -24,4 +24,8 @@ bool gfx_window_title(char *buf, size_t size); void gfx_window_title_reset(void); +#ifdef _WIN32 +void gfx_set_dwm(void); +#endif + #endif diff --git a/gfx/gl.c b/gfx/gl.c index ac6f469b0d..4fd2a91d46 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1036,6 +1036,10 @@ static void gl_set_nonblock_state(void *data, bool state) static void* gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) { +#ifdef _WIN32 + gfx_set_dwm(); +#endif + if (SDL_Init(SDL_INIT_VIDEO) < 0) return NULL; diff --git a/settings.c b/settings.c index 00b12022c9..d56e3f031a 100644 --- a/settings.c +++ b/settings.c @@ -121,6 +121,7 @@ static void set_defaults(void) g_settings.video.fullscreen_x = fullscreen_x; g_settings.video.fullscreen_y = fullscreen_y; g_settings.video.force_16bit = force_16bit; + g_settings.video.disable_composition = disable_composition; g_settings.video.vsync = vsync; g_settings.video.smooth = video_smooth; g_settings.video.force_aspect = force_aspect; @@ -302,6 +303,7 @@ static void parse_config_file(void) } CONFIG_GET_BOOL(video.force_16bit, "video_force_16bit"); + CONFIG_GET_BOOL(video.disable_composition, "video_disable_composition"); CONFIG_GET_BOOL(video.vsync, "video_vsync"); CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect"); diff --git a/ssnes.cfg b/ssnes.cfg index c31cb263cd..595f1d5368 100644 --- a/ssnes.cfg +++ b/ssnes.cfg @@ -25,6 +25,9 @@ # Force 16-bit colors. Apparently some video cards in use today have troubles with 32-bit ... # video_force_16bit = false +# Forcibly disable composition. Only works in Windows Vista/7 for now. +# video_disable_composition = false + # Video vsync. # video_vsync = true