static gpointer video_thread_entry(gpointer data) { fs_log("video thread started\n"); if (!wglMakeCurrent(g_hdc, g_hrc)) { fs_log("could not set current wgl context for video thread\n"); } // this function must be called from the video thread fse_init_video_opengl(); if (fs_ml_video_vsync()) { wglSwapIntervalEXT(1); } else { wglSwapIntervalEXT(0); } while (1) { //g_mutex_lock(g_video_mutex); // ... //fs_log("c\n"); if (!fs_ml_video_vsync()) { // when vsync is off, we wait until a new frame is ready and // then we display it immediately g_mutex_lock(g_video_mutex); g_cond_wait(g_video_cond, g_video_mutex); g_mutex_unlock(g_video_mutex); } fs_emu_render(); //fs_log("d\n"); //g_mutex_unlock(g_video_mutex); //fs_emu_msleep(5); //fs_ml_swap_buffers(); /* if (WaitForVerticalBlank) { fs_log("wait\n"); int result = WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); if (result != DD_OK) { fs_log("wait error %d\n", result); } } */ if (fs_ml_video_vsync()) { fs_gl_finish(); SwapBuffers(g_hdc); fs_gl_finish(); g_cond_signal(g_video_cond); } else { SwapBuffers(g_hdc); fs_gl_finish(); } fs_emu_swap_buffers(); } return NULL; }
int fs_ml_video_create_window(const char *title) { fs_log("fs_ml_video_create_window\n"); g_window_title = g_strdup(title); g_fs_ml_keyboard_input_grab = fs_config_get_boolean( "keyboard_input_grab"); if (g_fs_ml_automatic_input_grab == FS_CONFIG_NONE) { g_fs_ml_keyboard_input_grab = 1; } fs_log("keyboard input grab: %d\n", g_fs_ml_keyboard_input_grab); static int initialized = 0; SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, g_fs_ml_keyboard_input_grab ? "1" : "0"); SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); #ifdef WINDOWS SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); #endif SDL_Init(SDL_INIT_VIDEO); SDL_version cversion, lversion; SDL_VERSION(&cversion); SDL_GetVersion(&lversion); fs_log("[SDL] Version %d.%d.%d (Compiled against %d.%d.%d)\n", lversion.major, lversion.minor, lversion.patch, cversion.major, cversion.minor, cversion.patch); if (!initialized) { int display_index = 0; SDL_DisplayMode mode; int error = SDL_GetCurrentDisplayMode(display_index, &mode); if (error) { fs_log("SDL_GetCurrentDisplayMode failed\n"); SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Display Error", "SDL_GetCurrentDisplayMode failed.", NULL); exit(1); } fs_emu_monitor_init(); const char *mon = fs_config_get_const_string("monitor"); int mon_flag = -1; if (mon == NULL) { mon = "middle-left"; } if (strcmp(mon, "left") == 0) { mon_flag = FS_EMU_MONITOR_FLAG_LEFT; } else if (strcmp(mon, "middle-left") == 0) { mon_flag = FS_EMU_MONITOR_FLAG_MIDDLE_LEFT; } else if (strcmp(mon, "middle-right") == 0) { mon_flag = FS_EMU_MONITOR_FLAG_MIDDLE_RIGHT; } else if (strcmp(mon, "right") == 0) { mon_flag = FS_EMU_MONITOR_FLAG_RIGHT; } else { mon_flag = FS_EMU_MONITOR_FLAG_MIDDLE_LEFT; } FSEmuMonitor monitor; fs_emu_monitor_get_by_flag(mon_flag, &monitor); fs_log("Monitor \"%s\" (flag %d) => index %d\n", mon, mon_flag, monitor.index); g_display = monitor.index; g_fullscreen_width = fs_config_get_int("fullscreen_width"); if (g_fullscreen_width == FS_CONFIG_NONE) { g_fullscreen_width = mode.w; } g_fullscreen_height = fs_config_get_int("fullscreen_height"); if (g_fullscreen_height == FS_CONFIG_NONE) { g_fullscreen_height = mode.h; } if (g_fs_emu_video_fullscreen_mode_string == NULL) { g_fs_emu_video_fullscreen_mode = -1; } else if (g_ascii_strcasecmp(g_fs_emu_video_fullscreen_mode_string, "window") == 0) { g_fs_emu_video_fullscreen_mode = FULLSCREEN_WINDOW; } else if (g_ascii_strcasecmp(g_fs_emu_video_fullscreen_mode_string, "fullscreen") == 0) { g_fs_emu_video_fullscreen_mode = FULLSCREEN_FULLSCREEN; } else if (g_ascii_strcasecmp(g_fs_emu_video_fullscreen_mode_string, "desktop") == 0) { g_fs_emu_video_fullscreen_mode = FULLSCREEN_DESKTOP; } if (g_fs_emu_video_fullscreen_mode == -1) { #ifdef MACOSX g_fs_emu_video_fullscreen_mode = FULLSCREEN_FULLSCREEN; #else g_fs_emu_video_fullscreen_mode = FULLSCREEN_FULLSCREEN; #endif fs_log("[SDL] Defaulting to fullscreen_mode = desktop for SDL 2\n"); g_fs_emu_video_fullscreen_mode = FULLSCREEN_DESKTOP; } initialized = 1; } if (g_fs_ml_video_sync) { g_fs_ml_vblank_sync = 1; } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (g_fsaa) { fs_log("setting FSAA samples to %d\n", g_fsaa); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, g_fsaa); } g_window_width = fs_config_get_int("window_width"); if (g_window_width == FS_CONFIG_NONE) { g_window_width = 1920 / 2; } g_window_height = fs_config_get_int("window_height"); if (g_window_height == FS_CONFIG_NONE) { g_window_height = 1080/ 2; } g_window_x = fs_config_get_int("window_x"); if (g_window_x == FS_CONFIG_NONE) { g_window_x = SDL_WINDOWPOS_CENTERED; } g_window_y = fs_config_get_int("window_y"); if (g_window_y == FS_CONFIG_NONE) { g_window_y = SDL_WINDOWPOS_CENTERED; } g_window_resizable = fs_config_get_boolean("window_resizable"); if (g_window_resizable == FS_CONFIG_NONE) { g_window_resizable = 1; } g_fs_ml_automatic_input_grab = fs_config_get_boolean( "automatic_input_grab"); if (g_fs_ml_automatic_input_grab == FS_CONFIG_NONE) { if (fs_ml_mouse_integration()) { g_fs_ml_automatic_input_grab = 0; } else { g_fs_ml_automatic_input_grab = 1; } } fs_log("automatic input grab: %d\n", g_fs_ml_automatic_input_grab); g_initial_input_grab = g_fs_ml_automatic_input_grab; if (fs_config_get_boolean("initial_input_grab") == 1) { g_initial_input_grab = 1; } else if (fs_config_get_boolean("initial_input_grab") == 0 || // deprecated names: fs_config_get_boolean("input_grab") == 0 || fs_config_get_boolean("grab_input") == 0) { g_initial_input_grab = 0; } set_video_mode(); if (g_fs_ml_vblank_sync) { fs_emu_log("*** Setting swap interval to 1 ***\n"); if (SDL_GL_SetSwapInterval(1) != 0) { fs_emu_warning("SDL_GL_SetSwapInterval(1) failed"); } } else { fs_emu_log("*** Setting swap interval to 0 ***\n"); SDL_GL_SetSwapInterval(0); } fs_log("initial input grab: %d\n", g_initial_input_grab); if (g_initial_input_grab && !g_has_input_grab) { fs_ml_set_input_grab(true); } fs_ml_show_cursor(0, 1); /* This looks a bit peculiar, but it helps to show the window in * fullscreen mode as soon as possible to reduce flickering, at least under GNOME 3. */ glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(g_fs_ml_window); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(g_fs_ml_window); int64_t start_time = fs_emu_monotonic_time(); SDL_Event event; while (fs_emu_monotonic_time() - start_time < 100 * 1000) { SDL_WaitEventTimeout(&event, 10); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(g_fs_ml_window); } // this function must be called from the video thread fs_log("init_opengl\n"); fse_init_video_opengl(); SDL_StartTextInput(); #ifdef WINDOWS if (!fs_config_false(OPTION_RAW_INPUT)) { fs_ml_init_raw_input(); } #endif fs_log("create windows is done\n"); return 1; }