win_opengl: UI for options and add them to config. Reloading changed options at runtime. Improved framerate limitter.

This commit is contained in:
ts-korhonen
2021-04-23 16:09:45 +03:00
parent 579e221a76
commit 2bf6c7aa11
12 changed files with 325 additions and 104 deletions

View File

@@ -130,7 +130,7 @@ int video_fullscreen_first = 0; /* (C) video */
int enable_overscan = 0; /* (C) video */
int force_43 = 0; /* (C) video */
int video_vsync = 0; /* (C) video */
int video_frametime = -1; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
int serial_enabled[SERIAL_MAX] = {0,0}; /* (C) enable serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */

View File

@@ -528,6 +528,12 @@ load_general(void)
#if USE_DISCORD
enable_discord = !!config_get_int(cat, "enable_discord", 0);
#endif
#ifdef DEV_BRANCH /* feature-opengl */
video_framerate = config_get_int(cat, "video_gl_framerate", -1);
video_vsync = config_get_int(cat, "video_gl_vsync", 0);
strcpy_s(video_shader, sizeof(video_shader), config_get_string(cat, "video_gl_shader", ""));
#endif
}
@@ -1968,6 +1974,21 @@ save_general(void)
config_delete_var(cat, "enable_discord");
#endif
#ifdef DEV_BRANCH /* feature-opengl */
if (video_framerate != -1)
config_set_int(cat, "video_gl_framerate", video_framerate);
else
config_delete_var(cat, "video_gl_framerate");
if (video_vsync != 0)
config_set_int(cat, "video_gl_vsync", video_vsync);
else
config_delete_var(cat, "video_gl_vsync");
if (strlen(video_shader) > 0)
config_set_string(cat, "video_gl_shader", video_shader);
else
config_delete_var(cat, "video_gl_shader");
#endif
delete_section_if_empty(cat);
}

View File

@@ -91,7 +91,7 @@ extern int vid_cga_contrast, /* (C) video */
enable_overscan, /* (C) video */
force_43, /* (C) video */
video_vsync, /* (C) video */
video_frametime, /* (C) video */
video_framerate, /* (C) video */
gfxcard; /* (C) graphics/video card */
extern char video_shader[512]; /* (C) video */
extern int serial_enabled[], /* (C) enable serial ports */

View File

@@ -117,6 +117,7 @@
#define IDS_2141 2141 // "%hs Device Configuration"
#define IDS_2142 2142 // "Monitor in sleep mode"
#define IDS_2143 2143 // "OpenGL Shaders (*.GLSL)..."
#define IDS_2144 2144 // "OpenGL options"
#define IDS_4096 4096 // "Hard disk (%s)"
#define IDS_4097 4097 // "%01i:%01i"
@@ -224,7 +225,7 @@
#define IDS_LANG_ENUS IDS_7168
#define STR_NUM_2048 96
#define STR_NUM_2048 97
#define STR_NUM_3072 11
#define STR_NUM_4096 39
#define STR_NUM_4352 6

View File

@@ -101,6 +101,7 @@ extern int plat_dir_check(char *path);
extern int plat_dir_create(char *path);
extern uint64_t plat_timer_read(void);
extern uint32_t plat_get_ticks(void);
extern uint32_t plat_get_micro_ticks(void);
extern void plat_delay_ms(uint32_t count);
extern void plat_pause(int p);
extern void plat_mouse_capture(int on);
@@ -111,7 +112,7 @@ extern void plat_vidsize(int x, int y);
extern void plat_setfullscreen(int on);
extern void plat_resize(int x, int y);
extern void plat_vidapi_enable(int enabled);
extern void plat_vid_reload_options(void);
/* Resource management. */
extern void set_language(int id);

View File

@@ -63,6 +63,10 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define ZIP_SUBMENU_NAME L"ZIPSubmenu"
#define MO_SUBMENU_NAME L"MOSubmenu"
#ifdef DEV_BRANCH /* feature-opengl */
#define VID_GL_SUBMENU L"VidGLSubMenu"
#endif
/* Application-specific window messages.
A dialog sends 0x8895 with WPARAM = 1 followed by 0x8896 with WPARAM = 1 on open,

View File

@@ -23,5 +23,6 @@ extern int opengl_pause(void);
extern void opengl_close(void);
extern void opengl_set_fs(int fs);
extern void opengl_resize(int w, int h);
extern void opengl_reload(void);
#endif /*!WIN_OPENGL_H*/

View File

@@ -73,22 +73,6 @@ BEGIN
MENUITEM "&VNC", IDM_VID_VNC
#endif
END
#ifdef DEV_BRANCH /* feature-opengl */
POPUP "Renderer o&ptions"
BEGIN
POPUP "Target &framerate"
BEGIN
MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER
MENUITEM "&25 fps", IDM_VID_GL_FPS_25
MENUITEM "&30 fps", IDM_VID_GL_FPS_30
MENUITEM "&50 fps", IDM_VID_GL_FPS_50
MENUITEM "&60 fps", IDM_VID_GL_FPS_60
MENUITEM "&75 fps", IDM_VID_GL_FPS_75
END
MENUITEM "&VSync", IDM_VID_GL_VSYNC
MENUITEM "&Select shader...", IDM_VID_GL_SHADER
END
#endif
MENUITEM SEPARATOR
MENUITEM "Specify dimensions", IDM_VID_SPECIFY_DIM
MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43
@@ -253,6 +237,22 @@ BEGIN
END
END
#ifdef DEV_BRANCH /* feature-opengl */
VidGLSubMenu MENU DISCARDABLE
BEGIN
POPUP "Target &framerate"
BEGIN
MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER
MENUITEM "&25 fps", IDM_VID_GL_FPS_25
MENUITEM "&30 fps", IDM_VID_GL_FPS_30
MENUITEM "&50 fps", IDM_VID_GL_FPS_50
MENUITEM "&60 fps", IDM_VID_GL_FPS_60
MENUITEM "&75 fps", IDM_VID_GL_FPS_75
END
MENUITEM "&VSync", IDM_VID_GL_VSYNC
MENUITEM "&Select shader...", IDM_VID_GL_SHADER
END
#endif
/////////////////////////////////////////////////////////////////////////////
//
@@ -1097,6 +1097,7 @@ BEGIN
IDS_2141 "%hs Device Configuration"
IDS_2142 "Monitor in sleep mode"
IDS_2143 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0"
IDS_2144 "OpenGL options"
END
STRINGTABLE DISCARDABLE

View File

@@ -105,7 +105,7 @@ static const struct {
{ "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL },
{ "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL }
#ifdef DEV_BRANCH /* feature-opengl */
,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, NULL}
,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload}
#else
,{ "OpenGL_Core", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL } /* fall back to SDL_OpenGL */
#endif
@@ -858,9 +858,8 @@ plat_timer_read(void)
return(li.QuadPart);
}
uint32_t
plat_get_ticks(void)
static LARGE_INTEGER
plat_get_ticks_common(void)
{
LARGE_INTEGER EndingTime, ElapsedMicroseconds;
@@ -881,9 +880,20 @@ plat_get_ticks(void)
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
return (uint32_t) (ElapsedMicroseconds.QuadPart / 1000);
return ElapsedMicroseconds;
}
uint32_t
plat_get_ticks(void)
{
return (uint32_t)(plat_get_ticks_common().QuadPart / 1000);
}
uint32_t
plat_get_micro_ticks(void)
{
return (uint32_t)plat_get_ticks_common().QuadPart;
}
void
plat_delay_ms(uint32_t count)
@@ -1105,6 +1115,15 @@ plat_setfullscreen(int on)
plat_vidapi_enable(1);
}
void
plat_vid_reload_options(void)
{
if (!vid_api_inited || !vid_apis[vid_api].reload)
return;
vid_apis[vid_api].reload();
}
void
take_screenshot(void)

View File

@@ -114,11 +114,13 @@ static struct
/**
* @brief Renderer options
*/
static volatile struct
static struct
{
int vsync; /* Vertical sync; 0 = off, 1 = on */
int frametime; /* Frametime in ms, or -1 to sync with blitter */
int frametime; /* Frametime in microseconds, or -1 to sync with blitter */
char shaderfile[512]; /* Shader file path. Match the length of openfilestring in win_dialog.c */
int shaderfile_changed; /* Has shader file path changed. To prevent unnecessary shader recompilation. */
mutex_t* mutex;
} options = { 0 };
/**
@@ -228,6 +230,74 @@ static void handle_window_messages(UINT message, WPARAM wParam, LPARAM lParam, i
}
}
/**
* @brief (Re-)apply shaders to OpenGL context.
* @param gl Identifiers from initialize
*/
static void apply_shaders(gl_identifiers* gl)
{
GLuint old_shader_ID = 0;
if (gl->shader_progID != 0)
old_shader_ID = gl->shader_progID;
if (strlen(options.shaderfile) > 0)
gl->shader_progID = load_custom_shaders(options.shaderfile);
else
gl->shader_progID = 0;
if (gl->shader_progID == 0)
gl->shader_progID = load_default_shaders();
glUseProgram(gl->shader_progID);
/* Delete old shader if one exists (changing shader) */
if (old_shader_ID != 0)
glDeleteProgram(old_shader_ID);
GLint vertex_coord = glGetAttribLocation(gl->shader_progID, "VertexCoord");
if (vertex_coord != -1)
{
glEnableVertexAttribArray(vertex_coord);
glVertexAttribPointer(vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
}
GLint tex_coord = glGetAttribLocation(gl->shader_progID, "TexCoord");
if (tex_coord != -1)
{
glEnableVertexAttribArray(tex_coord);
glVertexAttribPointer(tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
}
GLint color = glGetAttribLocation(gl->shader_progID, "Color");
if (color != -1)
{
glEnableVertexAttribArray(color);
glVertexAttribPointer(color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(4 * sizeof(GLfloat)));
}
GLint mvp_matrix = glGetUniformLocation(gl->shader_progID, "MVPMatrix");
if (mvp_matrix != -1)
{
static const GLfloat mvp[] = {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f
};
glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp);
}
GLint frame_direction = glGetUniformLocation(gl->shader_progID, "FrameDirection");
if (frame_direction != -1)
glUniform1i(frame_direction, 1); /* always forward */
gl->input_size = glGetUniformLocation(gl->shader_progID, "InputSize");
gl->output_size = glGetUniformLocation(gl->shader_progID, "OutputSize");
gl->texture_size = glGetUniformLocation(gl->shader_progID, "TextureSize");
gl->frame_count = glGetUniformLocation(gl->shader_progID, "FrameCount");
}
/**
* @brief Initialize OpenGL context
* @return Identifiers
@@ -255,7 +325,7 @@ static gl_identifiers initialize_glcontext()
glGenTextures(1, &gl.textureID);
glBindTexture(GL_TEXTURE_2D, gl.textureID);
GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f };
static const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
@@ -266,61 +336,14 @@ static gl_identifiers initialize_glcontext()
glClearColor(0.f, 0.f, 0.f, 1.f);
gl.shader_progID = load_custom_shaders(options.shaderfile);
if (gl.shader_progID == 0)
gl.shader_progID = load_default_shaders();
glUseProgram(gl.shader_progID);
GLint vertex_coord = glGetAttribLocation(gl.shader_progID, "VertexCoord");
if (vertex_coord != -1)
{
glEnableVertexAttribArray(vertex_coord);
glVertexAttribPointer(vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
}
GLint tex_coord = glGetAttribLocation(gl.shader_progID, "TexCoord");
if (tex_coord != -1)
{
glEnableVertexAttribArray(tex_coord);
glVertexAttribPointer(tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
}
GLint color = glGetAttribLocation(gl.shader_progID, "Color");
if (color != -1)
{
glEnableVertexAttribArray(color);
glVertexAttribPointer(color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(4 * sizeof(GLfloat)));
}
GLint mvp_matrix = glGetUniformLocation(gl.shader_progID, "MVPMatrix");
if (mvp_matrix != -1)
{
static const GLfloat mvp[] = {
1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f
};
glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp);
}
GLint frame_direction = glGetUniformLocation(gl.shader_progID, "FrameDirection");
if (frame_direction != -1)
glUniform1i(frame_direction, 1); /* always forward */
gl.input_size = glGetUniformLocation(gl.shader_progID, "InputSize");
gl.output_size = glGetUniformLocation(gl.shader_progID, "OutputSize");
gl.texture_size = glGetUniformLocation(gl.shader_progID, "TextureSize");
gl.frame_count = glGetUniformLocation(gl.shader_progID, "FrameCount");
apply_shaders(&gl);
return gl;
}
/**
* @brief Clean up OpenGL context
* @param Identifiers from initialize
* @param gl Identifiers from initialize
*/
static void finalize_glcontext(gl_identifiers gl)
{
@@ -359,10 +382,9 @@ static void opengl_main(void* param)
window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
SDL_GL_SetSwapInterval(options.vsync);
/* Keep track of certain parameters, only changed in this thread to avoid race conditions */
int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT;
int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT,
output_width = resize_info.width, output_height = resize_info.height, frametime = options.frametime;
SDL_SysWMinfo wmi = { 0 };
SDL_VERSION(&wmi.version);
@@ -378,31 +400,48 @@ static void opengl_main(void* param)
SDL_GLContext context = SDL_GL_CreateContext(window);
SDL_GL_SetSwapInterval(options.vsync);
gladLoadGLLoader(SDL_GL_GetProcAddress);
gl_identifiers gl = initialize_glcontext();
if (gl.frame_count != -1)
glUniform1i(gl.frame_count, 0);
if (gl.output_size != -1)
glUniform2f(gl.output_size, output_width, output_height);
uint32_t last_swap = -options.frametime;
uint32_t last_swap = plat_get_micro_ticks() - frametime;
/* Render loop */
int closing = 0;
while (!closing)
{
if (options.frametime < 0)
/* Rendering is done right after handling an event. */
if (frametime < 0)
render_and_swap(gl);
DWORD wait_result = WAIT_TIMEOUT;
do
{
if (options.frametime >= 0)
/* Rendering is timed by frame capping. */
if (frametime >= 0)
{
uint32_t ticks = plat_get_ticks();
if (ticks - last_swap >= options.frametime)
uint32_t ticks = plat_get_micro_ticks();
uint32_t elapsed = ticks - last_swap;
if (elapsed + 1000 > frametime)
{
/* Spin the remaining time (< 1ms) to next frame */
while (elapsed < frametime)
{
Sleep(0); /* Yield processor time */
ticks = plat_get_micro_ticks();
elapsed = ticks - last_swap;
}
render_and_swap(gl);
last_swap = ticks;
}
@@ -418,11 +457,6 @@ static void opengl_main(void* param)
DispatchMessage(&msg);
}
/* Keep cursor hidden in full screen and mouse capture */
int show_cursor = !(fullscreen || !!mouse_capture);
if (SDL_ShowCursor(-1) != show_cursor)
SDL_ShowCursor(show_cursor);
/* Wait for synchronized events for 1ms before going back to window events */
wait_result = WaitForMultipleObjects(sizeof(sync_objects) / sizeof(HANDLE), sync_objects.asArray, FALSE, 1);
@@ -515,10 +549,13 @@ static void opengl_main(void* param)
}
}
glViewport(pad_x / 2, pad_y / 2, width - pad_x, height - pad_y);
output_width = width - pad_x;
output_height = height - pad_y;
glViewport(pad_x / 2, pad_y / 2, output_width, output_height);
if (gl.output_size != -1)
glUniform2f(gl.output_size, width - pad_x, height - pad_y);
glUniform2f(gl.output_size, output_width, output_height);
}
else
{
@@ -527,6 +564,9 @@ static void opengl_main(void* param)
/* SWP_NOZORDER is needed for child window and SDL doesn't enable it. */
SetWindowPos(window_hwnd, parent, 0, 0, resize_info.width, resize_info.height, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
output_width = resize_info.width;
output_height = resize_info.height;
glViewport(0, 0, resize_info.width, resize_info.height);
if (gl.output_size != -1)
@@ -535,6 +575,39 @@ static void opengl_main(void* param)
thread_release_mutex(resize_info.mutex);
}
else if (sync_event == sync_objects.reload)
{
thread_wait_mutex(options.mutex);
frametime = options.frametime;
SDL_GL_SetSwapInterval(options.vsync);
if (options.shaderfile_changed)
{
/* Change shader program. */
apply_shaders(&gl);
/* Uniforms need to be updated after proram change. */
if (gl.input_size != -1)
glUniform2f(gl.input_size, video_width, video_height);
if (gl.output_size != -1)
glUniform2f(gl.output_size, output_width, output_height);
if (gl.texture_size != -1)
glUniform2f(gl.texture_size, video_width, video_height);
if (gl.frame_count != -1)
glUniform1i(gl.frame_count, 0);
options.shaderfile_changed = 0;
}
thread_release_mutex(options.mutex);
}
/* Keep cursor hidden in full screen and mouse capture */
int show_cursor = !(fullscreen || !!mouse_capture);
if (SDL_ShowCursor(-1) != show_cursor)
SDL_ShowCursor(show_cursor);
}
finalize_glcontext(gl);
@@ -543,8 +616,6 @@ static void opengl_main(void* param)
set_parent_binding(0);
SDL_SetWindowsMessageHook(NULL, NULL);
SDL_DestroyWindow(window);
window = NULL;
@@ -571,6 +642,14 @@ static void opengl_blit(int x, int y, int y1, int y2, int w, int h)
video_blit_complete();
}
static int framerate_to_frametime(int framerate)
{
if (framerate < 0)
return -1;
return (int)ceilf(1.e6f / (float)framerate);
}
int opengl_init(HWND hwnd)
{
if (thread != NULL)
@@ -594,8 +673,9 @@ int opengl_init(HWND hwnd)
resize_info.mutex = thread_create_mutex();
options.vsync = video_vsync;
options.frametime = -1;
strcpy_s(options.shaderfile, sizeof(options.shaderfile), "shaders/shader.glsl");
options.frametime = framerate_to_frametime(video_framerate);
strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader);
options.mutex = thread_create_mutex();
thread = thread_create(opengl_main, (void*)NULL);
@@ -623,6 +703,7 @@ void opengl_close(void)
memset((void*)&blit_info, 0, sizeof(blit_info));
thread_close_mutex(resize_info.mutex);
thread_close_mutex(options.mutex);
SetEvent(blit_done);
@@ -675,5 +756,18 @@ void opengl_reload(void)
if (thread == NULL)
return;
thread_wait_mutex(options.mutex);
options.vsync = video_vsync;
options.frametime = framerate_to_frametime(video_framerate);
if (strcmp(video_shader, options.shaderfile) != 0)
{
strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader);
options.shaderfile_changed = 1;
}
thread_release_mutex(options.mutex);
SetEvent(sync_objects.reload);
}

View File

@@ -69,13 +69,7 @@ void main() {\n\
*/
static char* read_file_to_string(const char* path)
{
char* full_path = (char*)malloc(sizeof(char) * (strlen(path) + strlen(exe_path) + 1));
plat_append_filename(full_path, exe_path, path);
FILE* file_handle = plat_fopen(full_path, "rb");
free(full_path);
FILE* file_handle = plat_fopen(path, "rb");
if (file_handle != NULL)
{

View File

@@ -177,6 +177,71 @@ video_toggle_option(HMENU h, int *val, int id)
device_force_redraw();
}
/* Recursively finds and deletes target submenu */
int delete_submenu(HMENU parent, HMENU target)
{
for (int i = 0; i < GetMenuItemCount(parent); i++)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (GetMenuItemInfo(parent, i, TRUE, &mii) != 0)
{
if (mii.hSubMenu == target)
{
DeleteMenu(parent, i, MF_BYPOSITION);
return 1;
}
else if (mii.hSubMenu != NULL)
{
if (delete_submenu(mii.hSubMenu, target))
return 1;
}
}
}
return 0;
}
static void
show_render_options_menu()
{
#ifdef DEV_BRANCH /* feature-opengl */
static int menu_vidapi = -1;
static HMENU cur_menu = NULL;
if (vid_api == menu_vidapi)
return;
if (cur_menu != NULL)
{
if (delete_submenu(menuMain, cur_menu))
cur_menu = NULL;
}
if (cur_menu == NULL)
{
switch (IDM_VID_SDL_SW + vid_api)
{
case IDM_VID_OPENGL_CORE:
cur_menu = LoadMenu(hinstance, VID_GL_SUBMENU);
InsertMenu(GetSubMenu(menuMain, 1), 4, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT_PTR)cur_menu, plat_get_string(IDS_2144));
CheckMenuItem(menuMain, IDM_VID_GL_FPS_BLITTER, video_framerate == -1 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_FPS_25, video_framerate == 25 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_FPS_30, video_framerate == 30 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_FPS_50, video_framerate == 50 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_FPS_60, video_framerate == 60 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_FPS_75, video_framerate == 75 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED);
break;
}
}
menu_vidapi = vid_api;
#endif
}
static void
ResetAllMenus(void)
@@ -225,6 +290,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_SDL_OPENGL, MF_UNCHECKED);
#ifdef DEV_BRANCH /* feature-opengl */
CheckMenuItem(menuMain, IDM_VID_OPENGL_CORE, MF_UNCHECKED);
show_render_options_menu();
#endif
#ifdef USE_VNC
CheckMenuItem(menuMain, IDM_VID_VNC, MF_UNCHECKED);
@@ -682,13 +748,31 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
plat_setvid(LOWORD(wParam) - IDM_VID_SDL_SW);
CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_CHECKED);
config_save();
show_render_options_menu();
break;
#ifdef DEV_BRANCH /* feature-opengl */
case IDM_VID_GL_FPS_BLITTER:
case IDM_VID_GL_FPS_25:
case IDM_VID_GL_FPS_30:
case IDM_VID_GL_FPS_50:
case IDM_VID_GL_FPS_60:
case IDM_VID_GL_FPS_75:
{
static const int fps[] = { -1, 25, 30, 50, 60, 75 };
int idx = 0;
for (; fps[idx] != video_framerate; idx++);
CheckMenuItem(hmenu, IDM_VID_GL_FPS_BLITTER + idx, MF_UNCHECKED);
video_framerate = fps[LOWORD(wParam) - IDM_VID_GL_FPS_BLITTER];
CheckMenuItem(hmenu, LOWORD(wParam), MF_CHECKED);
plat_vid_reload_options();
config_save();
break;
}
case IDM_VID_GL_VSYNC:
video_vsync = !video_vsync;
CheckMenuItem(hmenu, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED);
//plat_reload_config
plat_vid_reload_options();
config_save();
break;
case IDM_VID_GL_SHADER:
@@ -696,6 +780,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (file_dlg_st(hwnd, IDS_2143, video_shader, NULL, 0) == 0)
strcpy_s(video_shader, sizeof(video_shader), openfilestring);
win_notify_dlg_closed();
plat_vid_reload_options();
break;
#endif