static void configure_memory(amiga_config *c) { int chip_memory = fs_config_get_int("chip_memory"); if (chip_memory != FS_CONFIG_NONE) { if (chip_memory % 512 == 0) { amiga_set_int_option("chipmem_size", chip_memory / 512); } else { fs_emu_warning("chip_memory must be a multiple of 512"); chip_memory = 0; } } else { chip_memory = 0; } int slow_memory = fs_config_get_int("slow_memory"); if (slow_memory != FS_CONFIG_NONE) { if (slow_memory % 256 == 0) { amiga_set_int_option("bogomem_size", slow_memory / 256); } else { fs_emu_warning("slow_memory must be a multiple of 256"); slow_memory = 0; } } else { slow_memory = 0; } int fast_memory = fs_config_get_int("fast_memory"); if (fast_memory != FS_CONFIG_NONE) { if (fast_memory % 1024 == 0) { amiga_set_int_option("fastmem_size", fast_memory / 1024); } else { fs_emu_warning("fast_memory must be a multiple of 1024"); fast_memory = 0; } } else { fast_memory = 0; } int z3_memory = fs_config_get_int("zorro_iii_memory"); if (z3_memory != FS_CONFIG_NONE) { if (z3_memory && !c->allow_z3_memory) { fs_emu_warning("Zorro III fast memory needs a processor " "with 32-bit addressing"); z3_memory = 0; } else if (z3_memory % 1024 == 0) { amiga_set_int_option("z3mem_size", z3_memory / 1024); } else { fs_emu_warning("zorro_iii_memory must be a multiple of 1024"); z3_memory = 0; } } else { z3_memory = 0; } }
static void configure_accuracy(amiga_config *c) { #ifdef NEW_ACCURACY_SYSTEM int cpu_accuracy = fs_config_get_int("cpu_accuracy"); if (cpu_accuracy == FS_CONFIG_NONE) { cpu_accuracy = fs_config_get_int("accuracy"); } if (cpu_accuracy != FS_CONFIG_NONE) { if (cpu_accuracy <= 0) { amiga_set_option("cpu_cycle_exact", "false"); if (g_fs_uae_amiga_model == MODEL_A1200 || g_fs_uae_amiga_model == MODEL_CD32) { // FIXME: test this setting some more //amiga_set_option("cpu_speed", "2"); amiga_set_option("cpu_speed", "0"); } } if (cpu_accuracy <= -1) { amiga_set_option("cpu_compatible", "false"); } } int blitter_accuracy = fs_config_get_int("blitter_accuracy"); if (blitter_accuracy == FS_CONFIG_NONE) { blitter_accuracy = fs_config_get_int("accuracy"); } if (blitter_accuracy != FS_CONFIG_NONE) { if (blitter_accuracy <= 0) { amiga_set_option("blitter_cycle_exact", "false"); } if (blitter_accuracy <= -1) { amiga_set_option("immediate_blits", "true"); } } int audio_accuracy = fs_config_get_int("audio_accuracy"); if (audio_accuracy == FS_CONFIG_NONE) { // we don't want to use interrupts unless we specifically requested // audio_accuracy of -1 audio_accuracy = fs_config_get_int_clamped("accuracy", 0, 1); } if (audio_accuracy != FS_CONFIG_NONE) { if (audio_accuracy == 0) { amiga_set_option("sound_output", "normal"); } else if (audio_accuracy <= -1) { amiga_set_option("sound_output", "interrupts"); } } #endif }
static void configure_logging(const char *logstr) { if (fs_config_get_int(OPTION_LOG_BSDSOCKET) == 1) { log_bsd = 1; } if (!logstr) { fs_log("configure logging: none\n"); return; } fs_log("configure logging: %s\n", logstr); int all = strstr(logstr, "all") != 0; int uae_all = all || strstr(logstr, "uae") != 0; if (uae_all || strstr(logstr, "uae_disk")) { disk_debug_logging = 2; } if (uae_all || strstr(logstr, "uae_rand")) { g_random_debug_logging = 2; } if (uae_all || strstr(logstr, "uae_input")) { inputdevice_logging = 0xffff; } if (uae_all || strstr(logstr, "uae_fs")) { g_fsdb_debug = 1; } if (uae_all || strstr(logstr, "uae_frame")) { g_frame_debug_logging = 1; } }
int fs_config_get_int_clamped(const char *key, int min, int max) { int value = fs_config_get_int(key); if (value == FS_CONFIG_NONE) { return value; } if (value < min) { fs_log("clamping value %d for key %s to %d\n", value, key, min); return min; } if (value > max) { fs_log("clamping value %d for key %s to %d\n", value, key, max); return max; } return value; }
void fs_ml_configure_window() { SDL_SysWMinfo info; SDL_VERSION(&info.version); // this is important! #ifdef USE_SDL2 if (!SDL_GetWindowWMInfo(g_fs_ml_window, &info)) { fs_log("error getting window information\n"); return; } g_display = info.info.x11.display; g_window = info.info.x11.window; #else if (!SDL_GetWMInfo(&info)) { fs_log("error getting window information\n"); return; } g_display = info.info.x11.display; g_window = info.info.x11.wmwindow; #endif // Set the PID related to the window for the given hostname, if possible // if (data->pid > 0) { // _NET_WM_PID = XInternAtom(display, "_NET_WM_PID", False); // XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, // (unsigned char *)&data->pid, 1); Atom UTF8_STRING = XInternAtom(g_display, "UTF8_STRING", False); fs_log("requesting dark window manager theme\n"); Atom _GTK_THEME_VARIANT = XInternAtom(g_display, "_GTK_THEME_VARIANT", False); XChangeProperty(g_display, g_window, _GTK_THEME_VARIANT, UTF8_STRING, 8, PropModeReplace, (const unsigned char *) "dark", 4); set_window_icon(); if (fs_config_get_int("always_on_top") == 1) { set_above_state(); } /* set_window_icon(32); set_window_icon(48); set_window_icon(64); set_window_icon(128); */ }
static void on_init() { fs_log("\n"); fs_log(LOG_LINE); fs_log("uae configuration\n"); fs_log(LOG_LINE); fs_log("\n"); amiga_set_gui_message_function(on_gui_message); //fs_uae_configure_amiga_model(); fs_uae_configure_amiga_hardware(); fs_uae_configure_floppies(); fs_uae_configure_hard_drives(); fs_uae_configure_cdrom(); fs_uae_configure_input(); fs_uae_configure_directories(); if (fs_config_get_int("save_state_compression") == 0) { amiga_set_save_state_compression(0); } else { amiga_set_save_state_compression(1); } if (fs_config_get_int("min_first_line_pal") != FS_CONFIG_NONE) { amiga_set_min_first_line(fs_config_get_int("min_first_line_pal"), 0); } if (fs_config_get_int("min_first_line_ntsc") != FS_CONFIG_NONE) { amiga_set_min_first_line(fs_config_get_int("min_first_line_ntsc"), 1); } /* if (fs_emu_get_video_sync()) { fs_log("fs_emu_get_video_sync returned true\n"); amiga_set_option("gfx_vsync", "true"); } else { fs_log("fs_emu_get_video_sync returned false\n"); } if (fs_emu_netplay_enabled()) { fs_log("netplay is enabled\n"); // make sure UAE does not sleep between frames, we must be able // to control sleep times for net play amiga_set_option("gfx_vsync", "true"); } */ /* With sound_auto set to true, UAE stops audio output if the amiga does * not produce sound. */ // amiga_set_option("sound_auto", "false"); amiga_set_audio_frequency(fs_emu_audio_output_frequency()); //amiga_set_audio_frequency(22050); // set the input frequency to the output frequency, since we configured // libamiga to output at the same frequency // FIXME: check the actual frequency libuae/libamiga outputs, seems // to output at 44100 Hz even though currprefs.freq says 48000. // fs_emu_set_audio_buffer_frequency(0, fs_emu_get_audio_frequency()); //amiga_set_option("gfx_gamma", "40"); fs_uae_set_uae_paths(); fs_uae_read_custom_uae_options(fs_uae_argc, fs_uae_argv); char *uae_file; uae_file = g_build_filename(fs_uae_logs_dir(), "LastConfig.uae", NULL); if (fs_path_exists(uae_file)) { g_unlink(uae_file); } g_free(uae_file); uae_file = g_build_filename(fs_uae_logs_dir(), "DebugConfig.uae", NULL); if (fs_path_exists(uae_file)) { g_unlink(uae_file); } g_free(uae_file); uae_file = g_build_filename(fs_uae_logs_dir(), "Debug.uae", NULL); if (fs_path_exists(uae_file)) { g_unlink(uae_file); } g_free(uae_file); uae_file = g_build_filename(fs_uae_logs_dir(), "debug.uae", NULL); amiga_write_uae_config(uae_file); g_free(uae_file); fs_log("\n"); fs_log(LOG_LINE); fs_log("end of uae configuration\n"); fs_log(LOG_LINE); fs_log("\n"); }
void fs_uae_process_input_event(int line, int action, int state, int playback) { static int first_time = 1; if (first_time == 1) { first_time = 0; int load_state_number = fs_config_get_int("load_state"); if (load_state_number >= 1 && load_state_number <= 9) { // FIXME: improvement, check if state file exists and show // GUI warning if not... fs_log("trying to load state number: %d\n", load_state_number); amiga_send_input_event( INPUTEVENT_SPC_STATERESTORE1 - 1 + load_state_number, 1); } } #if 0 g_fs_uae_last_input_event = input_event; g_fs_uae_last_input_event_state = state; fs_emu_lua_run_handler("on_fs_uae_input_event"); // handler can modify input event amiga_send_input_event(g_fs_uae_last_input_event, g_fs_uae_last_input_event_state); #endif #if 0 if (action == INPUTEVENT_KEY_RETURN) { printf("FIXME: ignoring RETURN event for now\n"); return; } #endif if (action >= INPUTEVENT_AMIGA_JOYPORT_MODE_0_NONE && action < INPUTEVENT_AMIGA_JOYPORT_MODE_3_LAST) { change_port_device_mode( action - INPUTEVENT_AMIGA_JOYPORT_MODE_0_NONE); return; } if (action >= INPUTEVENT_AMIGA_JOYPORT_0_DEVICE_0 && action < INPUTEVENT_AMIGA_JOYPORT_0_DEVICE_LAST) { select_port_0_device(action - INPUTEVENT_AMIGA_JOYPORT_0_DEVICE_0); return; } if (state && action >= INPUTEVENT_AMIGA_JOYPORT_0_AUTOFIRE && action <= INPUTEVENT_AMIGA_JOYPORT_3_AUTOFIRE) { int port = action - INPUTEVENT_AMIGA_JOYPORT_0_AUTOFIRE; if (g_fs_uae_input_ports[port].autofire_mode) { g_fs_uae_input_ports[port].autofire_mode = 0; amiga_set_joystick_port_autofire(port, 0); fs_emu_warning(_("Auto-fire disabled for port %d"), port); } else { g_fs_uae_input_ports[port].autofire_mode = 1; amiga_set_joystick_port_autofire(port, 1); fs_emu_warning(_("Auto-fire enabled for port %d"), port); } fs_emu_menu_update_current(); // this event must be passed on to the Amiga core } int record_event = 1; if (playback) { record_event = 0; } int load_state = 0; int save_state = 0; if (action >= INPUTEVENT_SPC_STATESAVE1 && action <= INPUTEVENT_SPC_STATESAVE9) { save_state = action - INPUTEVENT_SPC_STATESAVE1 + 1; g_fs_uae_state_number = save_state; } if (action >= INPUTEVENT_SPC_STATERESTORE1 && action <= INPUTEVENT_SPC_STATERESTORE9) { load_state = action - INPUTEVENT_SPC_STATERESTORE1 + 1; g_fs_uae_state_number = load_state; } if (load_state) { #ifdef WITH_LUA fs_log("run handler on_fs_uae_load_state\n"); fs_emu_lua_run_handler("on_fs_uae_load_state"); #endif record_event = 0; } else if (save_state) { #ifdef WITH_LUA fs_log("run handler on_fs_uae_save_state\n"); fs_emu_lua_run_handler("on_fs_uae_save_state"); #endif record_event = 0; } if (record_event) { fs_uae_record_input_event(line, action, state); } amiga_send_input_event(action, state); if (load_state) { #ifdef WITH_LUA fs_log("run handler on_fs_uae_load_state_done\n"); fs_emu_lua_run_handler("on_fs_uae_load_state_done"); #endif } else if (save_state) { #ifdef WITH_LUA fs_log("run handler on_fs_uae_save_state_done\n"); fs_emu_lua_run_handler("on_fs_uae_save_state_done"); #endif } }
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; #ifdef USE_SDL2 SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, g_fs_ml_keyboard_input_grab ? "1" : "0"); #endif SDL_Init(SDL_INIT_VIDEO); SDL_version version; SDL_VERSION(&version); fs_log("FS-UAE was compiled for SDL %d.%d.%d\n", version.major, version.minor, version.patch); if (!initialized) { #ifdef USE_SDL2 int display_index = 0; SDL_DisplayMode mode; int should_be_zero = SDL_GetCurrentDisplayMode(display_index, &mode); if(should_be_zero != 0) { fs_log("SDL_GetCurrentDisplayMode failed\n"); SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Display Error", "SDL_GetCurrentDisplayMode failed.", NULL); exit(1); } #else const SDL_VideoInfo* info = SDL_GetVideoInfo(); #endif g_fullscreen_width = fs_config_get_int("fullscreen_width"); if (g_fullscreen_width == FS_CONFIG_NONE) { #ifdef USE_SDL2 g_fullscreen_width = mode.w; #else g_fullscreen_width = info->current_w; #endif } g_fullscreen_height = fs_config_get_int("fullscreen_height"); if (g_fullscreen_height == FS_CONFIG_NONE) { #ifdef USE_SDL2 g_fullscreen_height = mode.h; #else g_fullscreen_height = info->current_h; #endif } 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; } #ifdef USE_SDL2 else if (g_ascii_strcasecmp(g_fs_emu_video_fullscreen_mode_string, "desktop") == 0) { g_fs_emu_video_fullscreen_mode = FULLSCREEN_DESKTOP; } #endif 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 #ifdef USE_SDL2 fs_log("defaulting to fullscreen_mode = desktop for SDL2\n"); g_fs_emu_video_fullscreen_mode = FULLSCREEN_DESKTOP; #endif } initialized = 1; } if (g_fs_ml_video_sync) { g_fs_ml_vblank_sync = 1; } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #ifdef USE_SDL2 // setting swap interval after creating OpenGL context #else if (g_fs_ml_vblank_sync) { fs_emu_log("*** Setting swap interval to 1 ***\n"); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); } else { fs_emu_log("*** Setting swap interval to 0 ***\n"); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); } #endif 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; } #ifdef USE_SDL2 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; } #endif 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(); #ifdef USE_SDL2 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); } #endif // we display a black frame as soon as possible (to reduce flickering on // startup) glClear(GL_COLOR_BUFFER_BIT); #ifdef USE_SDL2 SDL_GL_SwapWindow(g_fs_ml_window); #else SDL_GL_SwapBuffers(); #endif fs_gl_finish(); #ifdef USE_SDL2 // set in SDL_CreateWindow instead #else SDL_WM_SetCaption(g_window_title, fs_get_application_name()); #endif fs_log("initial input grab: %d\n", g_initial_input_grab); if (g_initial_input_grab && !g_has_input_grab) { fs_ml_grab_input(1, 1); } fs_ml_show_cursor(0, 1); // this function must be called from the video thread fs_log("init_opengl\n"); fs_emu_video_init_opengl(); #ifdef WINDOWS #ifdef USE_SDL2 // we use only SDL functions with SDL2 #else fs_ml_init_raw_input(); #endif #else #ifdef USE_SDL2 SDL_StartTextInput(); #else // enable keysym to unicode char translation SDL_EnableUNICODE(1); #endif #endif fs_log("create windows is done\n"); return 1; }
int fs_config_get_boolean(const char *key) { return fs_config_get_int(key); }
void fs_emu_video_init_options(void) { //int auto_sync_mode = 1; //int sync_to_vblank = 1; //int sync_with_emu = 0; char *sync_mode_str = NULL; int fsaa = fs_config_get_int_clamped("fsaa", 0, 4); if (fsaa != FS_CONFIG_NONE) { fs_log("setting full-scene anti-aliasing (FSAA) to %dx%d\n", fsaa, fsaa); fs_ml_set_video_fsaa(fsaa); } else { fs_log("full-scene anti-aliasing is not requested\n"); } fs_ml_video_mode mode; memset(&mode, 0, sizeof(fs_ml_video_mode)); if (fs_ml_video_mode_get_current(&mode) == 0) { fs_log("current display mode is %dx%d @ %d Hz\n", mode.width, mode.height, mode.fps); int assume_refresh_rate = fs_config_get_int("assume_refresh_rate"); if (assume_refresh_rate != FS_CONFIG_NONE) { fs_log("assuming host refresh rate: %d Hz (from config)\n", assume_refresh_rate); g_fs_emu_video_frame_rate_host = assume_refresh_rate; } else { g_fs_emu_video_frame_rate_host = mode.fps; } } else { fs_log("could not get display mode\n"); } fs_log("checking video sync mode\n"); sync_mode_str = fs_config_get_string("video_sync"); if (!sync_mode_str) { // compatibility key, FIXME: remove when FS-UAE translates compat // option names when loading config. sync_mode_str = fs_config_get_string("sync"); } if (sync_mode_str) { if (g_ascii_strcasecmp(sync_mode_str, "auto") == 0) { g_fs_emu_video_sync_to_vblank = 1; g_fs_emu_video_allow_full_sync = 1; } else if (g_ascii_strcasecmp(sync_mode_str, "1") == 0) { // shortcut option, nice from command line (e.g. --video-sync) g_fs_emu_video_sync_to_vblank = 1; g_fs_emu_video_allow_full_sync = 1; } else if (g_ascii_strcasecmp(sync_mode_str, "full") == 0) { // old compatibility option g_fs_emu_video_sync_to_vblank = 1; g_fs_emu_video_allow_full_sync = 1; } else if (g_ascii_strcasecmp(sync_mode_str, "0") == 0) { // shortcut option, nice from command line (e.g. --no-video-sync) g_fs_emu_video_sync_to_vblank = 0; g_fs_emu_video_allow_full_sync = 0; } else if (g_ascii_strcasecmp(sync_mode_str, "off") == 0) { //g_fs_emu_video_sync_to_vblank = 0; //g_fs_emu_video_allow_full_sync = 0; } else if (g_ascii_strcasecmp(sync_mode_str, "vblank") == 0) { g_fs_emu_video_sync_to_vblank = 1; } else { fs_log("WARNING: invalid value for video-sync: %s\n", sync_mode_str); } free(sync_mode_str); } else { //fs_log("not specified: using automatic video sync mode\n"); fs_log("not specified: no video sync\n"); //g_fs_emu_video_sync_to_vblank = 0; //g_fs_emu_video_allow_full_sync = 0; } /* if (auto_sync_mode) { fs_log("auto sync mode is enabled\n"); if (frame_rate && frame_rate == mode.fps) { fs_log("frame rate (%d) equals screen refresh (%d)\n", frame_rate, mode.fps); sync_to_vblank = 1; sync_with_emu = 1; } else { fs_log("frame rate (%d) does not equal screen refresh (%d)\n", frame_rate, mode.fps); sync_to_vblank = 1; } } */ if (fs_emu_netplay_enabled()) { fs_log("netplay is enabled, disabling full video/emulator sync\n"); g_fs_emu_video_allow_full_sync = 0; //sync_with_emu = 0; //sync_to_vblank = 0; } if (fs_config_get_boolean("benchmark") != FS_CONFIG_NONE) { fs_log("benchmarking enable, disabling video sync\n"); g_fs_emu_video_sync_to_vblank = 0; //sync_with_emu = 0; g_fs_emu_benchmarking = 1; g_fs_ml_benchmarking = 1; g_fs_emu_video_allow_full_sync = 0; } //if (sync_with_emu && !g_fs_emu_full_sync_allowed) { // FIXME: check where g_fs_emu_full_sync_allowed is used if (!g_fs_emu_full_sync_allowed) { fs_log("full video/emu sync is not allowed in this mode\n"); //sync_with_emu = 0; g_fs_emu_video_allow_full_sync = 0; } /* if (sync_with_emu) { fs_log("will sync emulation and video with vblank\n"); fs_ml_video_sync_enable(); if (frame_rate && mode.fps) { double pitch = (1.0 * mode.fps) / frame_rate; fs_log("changing audio pitch to %0.2f based on frame rates\n", pitch); fs_emu_audio_set_default_pitch(pitch); } } else if (sync_to_vblank) { fs_log("will sync video output only to vblank (no tearing)\n"); fs_ml_vblank_sync_enable(); } else { fs_log("no video sync\n"); } */ if (g_fs_emu_video_sync_to_vblank) { fs_log("will sync video updates to vblank\n"); fs_ml_vblank_sync_enable(); } else { fs_log("no video sync (using timers only)\n"); } if (fs_config_get_boolean("disable_aspect_correction") == 1) { g_fs_emu_disable_aspect_correction = 1; } else if (fs_config_get_boolean("keep_aspect") == 1) { fs_emu_video_set_aspect_correction(1); } // the default texture format is RGB, set here because some video // formats implicitly changes the default texture format g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB; const char *s = fs_config_get_const_string("video_format"); if (s) { if (g_ascii_strcasecmp(s, "bgra") == 0) { fs_log("using video format BGRA\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_BGRA; g_fs_emu_video_bpp = 4; } else if (g_ascii_strcasecmp(s, "rgba") == 0) { fs_log("using video format RGBA\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_RGBA; g_fs_emu_video_bpp = 4; } else if (g_ascii_strcasecmp(s, "rgb") == 0) { fs_log("using video format RGB\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_RGB; g_fs_emu_video_bpp = 3; } else if (g_ascii_strcasecmp(s, "rgb565") == 0) { fs_log("using video format RGB565\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_R5G6B5; g_fs_emu_video_bpp = 2; g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB5; } else if (g_ascii_strcasecmp(s, "rgba5551") == 0) { fs_log("using video format RGBA5551\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_R5G5B5A1; g_fs_emu_video_bpp = 2; g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB5_A1; } else { fs_emu_warning("Unknown video format"); } } if (!g_fs_emu_video_format) { fs_log("using default video format BGRA\n"); g_fs_emu_video_format = FS_EMU_VIDEO_FORMAT_BGRA; g_fs_emu_video_bpp = 4; } s = fs_config_get_const_string("texture_format"); if (s) { if (g_ascii_strcasecmp(s, "rgb") == 0) { fs_log("using texture format RGB\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB; } else if (g_ascii_strcasecmp(s, "rgb8") == 0) { fs_log("using texture format RGB8\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB8; } else if (g_ascii_strcasecmp(s, "rgba") == 0) { fs_log("using texture format RGBA\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGBA; } else if (g_ascii_strcasecmp(s, "rgba8") == 0) { fs_log("using texture format RGBA8\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGBA8; } else if (g_ascii_strcasecmp(s, "rgb5") == 0) { fs_log("using texture format RGB5\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB5; } else if (g_ascii_strcasecmp(s, "rgb5_a1") == 0) { fs_log("using texture format RGB5_A1\n"); g_fs_emu_texture_format = FS_EMU_TEXTURE_FORMAT_RGB5_A1; } else { fs_emu_warning("Unknown texture format (using default)"); } } else { fs_log("using default texture format\n"); } double dval; if (fs_config_get_boolean("scanlines") == 1) { g_fs_emu_scanlines = 1; } dval = fs_config_get_double_clamped("scanlines_light", 0, 100); if (dval != FS_CONFIG_NONE) { g_fs_emu_scanlines_light = 255.0 * dval / 100.0; } dval = fs_config_get_double_clamped("scanlines_dark", 0, 100); if (dval != FS_CONFIG_NONE) { g_fs_emu_scanlines_dark = 255.0 * dval / 100.0; } }
static void configure_cpu(void) { bool uae_cpu_24bit_addressing = !cfg->cpu_32bit_addressing; const char *uae_cpu_model = cfg->default_cpu; const char *uae_fpu_model = cfg->default_fpu; const char *uae_mmu_model = cfg->default_mmu; //bool allow_6888x_fpu = false; //bool allow_68040_fpu = false; //bool allow_68060_fpu = false; const char *cpu = fs_config_get_const_string(OPTION_CPU); if (cpu == NULL) { cpu = cfg->accelerator_cpu; } if (cpu == NULL || fs_uae_values_matches(cpu, "auto")) { /* Go with the already configured value */ } else if (fs_uae_values_matches(cpu, "68000")) { uae_cpu_24bit_addressing = true; uae_cpu_model = "68000"; uae_fpu_model = "0"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68010")) { uae_cpu_24bit_addressing = true; uae_cpu_model = "68010"; uae_fpu_model = "0"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68EC020")) { uae_cpu_24bit_addressing = true; uae_cpu_model = "68020"; uae_fpu_model = cfg->default_fpu_noninternal; uae_mmu_model = "0"; //allow_6888x_fpu = true; } else if (fs_uae_values_matches(cpu, "68020")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68020"; uae_fpu_model = cfg->default_fpu_noninternal; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68EC030")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68030"; uae_fpu_model = "0"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68030")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68030"; uae_fpu_model = cfg->default_fpu_noninternal; uae_mmu_model = "68030"; } else if (fs_uae_values_matches(cpu, "68EC040")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68040"; uae_fpu_model = "0"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68LC040")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68040"; uae_fpu_model = "0"; uae_mmu_model = "68040"; } else if (fs_uae_values_matches(cpu, "68040")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68040"; uae_fpu_model = "68040"; uae_mmu_model = "68040"; } else if (fs_uae_values_matches(cpu, "68040-NOMMU")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68040"; uae_fpu_model = "68040"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68EC060")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68060"; uae_fpu_model = "0"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68LC060")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68060"; uae_fpu_model = "0"; uae_mmu_model = "68060"; } else if (fs_uae_values_matches(cpu, "68060-NOMMU")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68060"; uae_fpu_model = "68060"; uae_mmu_model = "0"; } else if (fs_uae_values_matches(cpu, "68060")) { uae_cpu_24bit_addressing = false; uae_cpu_model = "68060"; uae_fpu_model = "68060"; uae_mmu_model = "68060"; } else { fs_emu_warning("Unknown CPU specified"); } const char *fpu = fs_config_get_const_string(OPTION_FPU); if (fpu == NULL || fs_uae_values_matches(fpu, "auto")) { /* Go with the already configured value */ } else if (fs_uae_values_matches(fpu, "0")) { uae_fpu_model = "0"; } else if (fs_uae_values_matches(fpu, "68881")) { if (fs_uae_values_matches(uae_cpu_model, "68020") || fs_uae_values_matches(uae_cpu_model, "68030")) { uae_fpu_model = "68881"; } else { fs_emu_warning("68881 FPU must be paired with 68020/68030 CPU\n"); } } else if (fs_uae_values_matches(fpu, "68882")) { if (strcmp(uae_cpu_model, "68020") == 0 || strcmp(uae_cpu_model, "68030") == 0) { uae_fpu_model = "68882"; } else { fs_emu_warning("68882 FPU must be paired with 68020/68030 CPU\n"); } } else if (fs_uae_values_matches(fpu, "68040")) { if (strcmp(uae_cpu_model, "68040") == 0) { uae_fpu_model = "68040"; } else { fs_emu_warning("68040 FPU must be paired with 68040 CPU"); } } else if (fs_uae_values_matches(fpu, "68060")) { if (strcmp(uae_cpu_model, "68060") == 0) { uae_fpu_model = "68060"; } else { fs_emu_warning("68060 FPU must be paired with 68060 CPU"); } } else { fs_emu_warning("Unknown FPU specified"); } const char *mmu = fs_config_get_const_string(OPTION_MMU); if (mmu == NULL || fs_uae_values_matches(mmu, "auto")) { /* Go with the already configured value */ } else if (fs_uae_values_matches(mmu, "0")) { uae_mmu_model = "0"; } else if (fs_uae_values_matches(mmu, "68030")) { if (strcmp(uae_cpu_model, "68030") == 0) { uae_mmu_model = "68030"; } else { fs_emu_warning("68030 MMU must be paired with 68030 CPU"); } } else if (fs_uae_values_matches(mmu, "68040")) { if (strcmp(uae_cpu_model, "68040") == 0) { uae_mmu_model = "68040"; } else { fs_emu_warning("68040 MMU must be paired with 68040 CPU"); } } else if (fs_uae_values_matches(mmu, "68060")) { if (strcmp(uae_cpu_model, "68060") == 0) { uae_mmu_model = "68060"; } else { fs_emu_warning("68060 MMU must be paired with 68060 CPU"); } } else { fs_emu_warning("Unknown MMU specified"); } if (uae_cpu_model[0]) { amiga_set_option("cpu_model", uae_cpu_model); } if (uae_fpu_model[0]) { amiga_set_option("fpu_model", uae_fpu_model); } if (uae_mmu_model[0]) { amiga_set_option("mmu_model", uae_mmu_model); } if (uae_cpu_24bit_addressing) { amiga_set_option("cpu_24bit_addressing", "true"); } else { amiga_set_option("cpu_24bit_addressing", "false"); } cfg->cpu_32bit_addressing = !uae_cpu_24bit_addressing; cfg->allow_z3_memory = !uae_cpu_24bit_addressing; int accuracy = fs_config_get_int("accuracy"); if (accuracy == FS_CONFIG_NONE) { accuracy = 1; } int blitter_mode = BLITTER_MODE_NORMAL; int cpu_mode = CPU_MODE_CYCLE_EXACT; int cpu_speed = CPU_SPEED_REAL; if (strcmp(uae_cpu_model, "68030") == 0 || strcmp(uae_cpu_model, "68040") == 0 || strcmp(uae_cpu_model, "68060") == 0) { cpu_speed = CPU_SPEED_MAX; cpu_mode = CPU_MODE_NONCOMPATIBLE; } else { cpu_speed = CPU_SPEED_REAL; if (accuracy > 0) { cpu_mode = CPU_MODE_CYCLE_EXACT; } else if (accuracy == 0) { cpu_mode = CPU_MODE_COMPATIBLE; } else if (accuracy < 0) { cpu_mode = CPU_MODE_NONCOMPATIBLE; } } if (cpu_mode == CPU_MODE_CYCLE_EXACT && strcmp(uae_cpu_model, "68000") == 0) { blitter_mode = BLITTER_MODE_NORMAL; } else if (accuracy < 0) { blitter_mode = BLITTER_MODE_IMMEDIATE; } else { blitter_mode = BLITTER_MODE_WAITING; } if (cpu_speed == CPU_SPEED_MAX) { amiga_set_option("cpu_speed", "max"); } else { amiga_set_option("cpu_speed", "real"); } if (cpu_mode == CPU_MODE_CYCLE_EXACT) { amiga_set_option("blitter_cycle_exact", "true"); amiga_set_option("cpu_compatible", "true"); amiga_set_option("cpu_cycle_exact", "true"); } else if (cpu_mode == CPU_MODE_COMPATIBLE) { amiga_set_option("blitter_cycle_exact", "false"); amiga_set_option("cpu_compatible", "true"); amiga_set_option("cpu_cycle_exact", "false"); } else if (cpu_mode == CPU_MODE_NONCOMPATIBLE) { amiga_set_option("blitter_cycle_exact", "false"); amiga_set_option("cpu_compatible", "false"); amiga_set_option("cpu_cycle_exact", "false"); } if (blitter_mode == BLITTER_MODE_NORMAL) { amiga_set_option("waiting_blits", "false"); amiga_set_option("immediate_blits", "false"); } else if (blitter_mode == BLITTER_MODE_WAITING) { amiga_set_option("waiting_blits", "true"); amiga_set_option("immediate_blits", "false"); } else if (blitter_mode == BLITTER_MODE_IMMEDIATE) { amiga_set_option("waiting_blits", "false"); amiga_set_option("immediate_blits", "true"); } int cpu_idle = fs_config_get_int_clamped(OPTION_CPU_IDLE, 0, 10); if (cpu_idle == FS_CONFIG_NONE) { cpu_idle = cfg->cpu_idle; } if (cpu_idle != FS_CONFIG_NONE) { fs_log("Setting cpu_idle to %d\n", cpu_idle); amiga_set_cpu_idle(cpu_idle); } }
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; }
static void set_video_mode() { int flags = SDL_WINDOW_OPENGL; if (g_fs_emu_video_fullscreen_mode != FULLSCREEN_WINDOW && g_window_resizable) { flags |= SDL_WINDOW_RESIZABLE; } int x = g_window_x, y = g_window_y; int w = -1, h = -1; // if (g_initial_input_grab) { // flags |= SDL_WINDOW_INPUT_GRABBED; // g_has_input_grab = 1; // } if (g_fs_emu_video_fullscreen == 1) { w = g_fullscreen_width; h = g_fullscreen_height; //w = g_window_width; //h = g_window_height; if (g_fs_emu_video_fullscreen_mode == FULLSCREEN_WINDOW) { fs_log("using fullscreen window mode\n"); //x = 0; //y = 0; //w = g_fullscreen_width; //h = g_fullscreen_height; flags |= SDL_WINDOW_BORDERLESS; FSEmuMonitor monitor; fs_emu_monitor_get_by_index(g_display, &monitor); x = monitor.rect.x; y = monitor.rect.y; w = monitor.rect.w; h = monitor.rect.h; } else if (g_fs_emu_video_fullscreen_mode == FULLSCREEN_DESKTOP) { fs_log("using fullscreen desktop mode\n"); // the width and height will not be used for the fullscreen // desktop mode, only for the window when toggling fullscreen // state #if 0 w = g_window_width; h = g_window_height; #else FSEmuMonitor monitor; fs_emu_monitor_get_by_index(g_display, &monitor); x = monitor.rect.x; y = monitor.rect.y; w = monitor.rect.w; h = monitor.rect.h; #endif flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { fs_log("using SDL_FULLSCREEN mode\n"); flags |= SDL_WINDOW_FULLSCREEN; } fs_log("setting (fullscreen) video mode %d %d\n", w, h); } else { w = g_window_width; h = g_window_height; fs_log("using windowed mode\n"); //SDL_putenv("SDL_VIDEO_WINDOW_POS="); fs_log("setting (windowed) video mode %d %d\n", w, h); } if (fs_config_get_boolean("window_border") == 0) { fs_log("borderless window requested\n"); flags |= SDL_WINDOW_BORDERLESS; } #if 0 Uint8 data[] = "\0"; SDL_Cursor *cursor = SDL_CreateCursor(data, data, 8, 1, 0, 0); SDL_SetCursor(cursor); #endif g_fs_ml_video_width = w; g_fs_ml_video_height = h; fs_log("[SDL] CreateWindow(x=%d, y=%d, w=%d, h=%d, flags=%d)\n", x, y, w, h, flags); g_fs_ml_window = SDL_CreateWindow(g_window_title, x, y, w, h, flags); int assume_refresh_rate = fs_config_get_int("assume_refresh_rate"); if (assume_refresh_rate != FS_CONFIG_NONE) { fs_log("[DISPLAY] Assuming host refresh rate: %d Hz (from config)\n", assume_refresh_rate); g_fs_emu_video_frame_rate_host = assume_refresh_rate; } else { SDL_DisplayMode mode; if (SDL_GetWindowDisplayMode(g_fs_ml_window, &mode) == 0) { g_fs_emu_video_frame_rate_host = mode.refresh_rate; } else { g_fs_emu_video_frame_rate_host = 0; } fs_log("[DISPLAY] Host refresh rate: %d Hz\n", g_fs_emu_video_frame_rate_host); } if (g_fs_emu_video_frame_rate_host) { g_fs_ml_target_frame_time = 1000000 / g_fs_emu_video_frame_rate_host; } g_fs_ml_context = SDL_GL_CreateContext(g_fs_ml_window); #ifdef WITH_GLEW static int glew_initialized = 0; if (!glew_initialized) { GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "[GLEW] Error: %s\n", glewGetErrorString(err)); fs_emu_fatal("[GLEW] Error initializing glew"); } fs_log("[GLEW] Version %s\n", glewGetString(GLEW_VERSION)); glew_initialized = 1; } #elif defined(WITH_GLAD) static int glad_initialized = 0; if (!glad_initialized) { if (!gladLoadGLLoader((GLADloadproc) SDL_GL_GetProcAddress)) { fs_emu_fatal("[GLAD] Failed to initialize OpenGL context"); } glad_initialized = 1; } #endif fs_ml_configure_window(); // FIXME: this can be removed g_fs_ml_opengl_context_stamp++; log_opengl_information(); }
static void load_theme() { fs_log("loading theme \"%s\"\n", g_fs_emu_theme.path); char *p = fs_path_join(g_fs_emu_theme.path, "theme.conf", NULL); if (fs_path_exists(p)) { fs_config_read_file(p, 1); } free(p); char *cv; int iv; iv = fs_config_get_int("theme_width"); if (iv != FS_CONFIG_NONE && iv > 0) { g_fs_emu_theme.width = iv; } iv = fs_config_get_int("theme_height"); if (iv != FS_CONFIG_NONE && iv > 0) { g_fs_emu_theme.height = iv; } set_color_from_string(g_fs_emu_theme.floor_color_1, fs_config_get_const_string("theme_floor_color_1")); set_color_from_string(g_fs_emu_theme.floor_color_2, fs_config_get_const_string("theme_floor_color_2")); set_color_from_string(g_fs_emu_theme.wall_color_1, fs_config_get_const_string("theme_wall_color_1")); set_color_from_string(g_fs_emu_theme.wall_color_2, fs_config_get_const_string("theme_wall_color_2")); iv = fs_config_get_int("theme_floor_height"); if (iv != FS_CONFIG_NONE) { g_fs_emu_theme.floor_height = iv; } cv = fs_config_get_string("theme_overlay_image"); if (cv) { free(g_fs_emu_theme.overlay_image); g_fs_emu_theme.overlay_image = cv; } set_color_from_string(g_fs_emu_theme.fade_color, fs_config_get_const_string("theme_fade_color")); set_color_from_string(g_fs_emu_theme.heading_color, fs_config_get_const_string("theme_heading_color")); set_color_from_string(g_fs_emu_theme.item_color, fs_config_get_const_string("theme_item_color")); for (int i = 0; i < FS_EMU_MAX_OVERLAYS; i++) { char *name; int val; // the first options read here are old compatibility options name = fs_strdup_printf("theme_custom_%d_x", i - FS_EMU_FIRST_CUSTOM_OVERLAY); val = fs_config_get_int(name); free(name); if (val != FS_CONFIG_NONE) { //printf("x is %d\n", val); g_fs_emu_theme.overlays[i].x = (double) val / g_fs_emu_theme.width; } name = fs_strdup_printf("theme_custom_%d_y", i - FS_EMU_FIRST_CUSTOM_OVERLAY); val = fs_config_get_int(name); free(name); if (val != FS_CONFIG_NONE) { g_fs_emu_theme.overlays[i].y = (double) val / g_fs_emu_theme.height; } if (!g_fs_emu_theme.overlays[i].name) { continue; } // these are new theme / overlay options name = fs_strdup_printf("theme_%s_pos", g_fs_emu_theme.overlays[i].name); const char *csval = fs_config_get_const_string(name); free(name); if (csval) { int x, y; if (sscanf(csval, "%d,%d", &x, &y) == 2) { g_fs_emu_theme.overlays[i].x = (double) x / g_fs_emu_theme.width; g_fs_emu_theme.overlays[i].y = (double) y / g_fs_emu_theme.height; } } } #ifdef WITH_LUA fs_emu_theme_init_lua(); #endif }
int fs_ml_video_create_window(const char *title) { fs_log("fs_ml_video_create_window\n"); g_window_title = g_strdup(title); static int initialized = 0; SDL_Init(SDL_INIT_VIDEO); #ifdef HAVE_GLES if (!EGL_Open()) exit(1); #endif if (!initialized) { const SDL_VideoInfo* info = SDL_GetVideoInfo(); g_fullscreen_width = fs_config_get_int("fullscreen_width"); if (g_fullscreen_width == FS_CONFIG_NONE) { g_fullscreen_width = info->current_w; } g_fullscreen_height = fs_config_get_int("fullscreen_height"); if (g_fullscreen_height == FS_CONFIG_NONE) { g_fullscreen_height = info->current_h; } if (g_fs_emu_video_fullscreen_mode == NULL) { g_fs_emu_video_fullscreen_window = -1; } else if (g_strcasecmp(g_fs_emu_video_fullscreen_mode, "window") == 0) { g_fs_emu_video_fullscreen_window = 1; } else if (g_strcasecmp(g_fs_emu_video_fullscreen_mode, "fullscreen") == 0) { g_fs_emu_video_fullscreen_window = 0; } if (g_fs_emu_video_fullscreen_window == -1) { #ifdef MACOSX g_fs_emu_video_fullscreen_window = 0; #else g_fs_emu_video_fullscreen_window = 0; #endif } initialized = 1; } if (g_fs_ml_video_sync) { g_fs_ml_vblank_sync = 1; } #ifndef HAVE_GLES SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (g_fs_ml_vblank_sync) { fs_emu_log("*** SDL_GL_SWAP_CONTROL is enabled ***\n"); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); } else { fs_emu_log("*** SDL_GL_SWAP_CONTROL is disabled ***\n"); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); } 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); } #endif 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_resizable = fs_config_get_boolean("window_resizable"); if (g_window_resizable == FS_CONFIG_NONE) { g_window_resizable = 1; } set_video_mode(); #ifdef HAVE_GLES EGL_Init(); #endif // we display a black frame as soon as possible (to reduce flickering on // startup) glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapBuffers(); fs_gl_finish(); SDL_WM_SetCaption(g_window_title, g_get_application_name()); if (fs_config_get_boolean("grab_input") != 0) { fs_ml_grab_input(1, 1); } fs_ml_show_cursor(0, 1); // this function must be called from the video thread fs_log("init_opengl\n"); fs_emu_video_init_opengl(); #ifdef WINDOWS fs_ml_init_raw_input(); #else // enable keysym to unicode char translation SDL_EnableUNICODE(1); #endif fs_log("create windows is done\n"); return 1; }
void fs_emu_audio_openal_init(void) { fs_log("fs_emu_audio_openal_init\n"); register_functions(); // select the "preferred device" g_device = alcOpenDevice(NULL); if (g_device) { fs_log("[OPENAL] Opened device: %s\n", alcGetString(g_device, ALC_DEVICE_SPECIFIER)); } else { fs_log("[OPENAL] NULL from alcOpenDevice\n"); ALenum error_code = alGetError(); fs_log("[OPENAL] Error code %d\n", error_code); if (alGetString(error_code)) { fs_log("[OPENAL] %s\n", alGetString(error_code)); } fs_emu_warning("OPENAL: Could not open audio device"); } if (!g_device) { return; } log_openal_info(); log_openal_devices(); int frequencies[] = { 48000, 44100, 0 }; if (fs_config_get_int("audio_frequency") != FS_CONFIG_NONE) { frequencies[0] = fs_config_get_int("audio_frequency"); } for (int i = 0; frequencies[i]; i++) { int frequency = frequencies[i]; fs_log("OPENAL: trying frequency %d\n", frequency); ALCint attributes[] = { ALC_MONO_SOURCES, 0, ALC_STEREO_SOURCES, 2, ALC_FREQUENCY, frequency, 0 }; g_context = alcCreateContext(g_device, attributes); if (g_context) { g_audio_out_frequency = frequency; break; } } if (g_context) { fs_log("OPENAL: created context\n"); alcMakeContextCurrent(g_context); check_al_error("alcMakeContextCurrent"); fs_log("OPENAL: made context current\n"); } else { fs_emu_warning("OpenAL: no context created\n"); //check_al_error("alcCreateContext"); } int stereo_sources; alcGetIntegerv(g_device, ALC_STEREO_SOURCES, 1, &stereo_sources); fs_log("openal: number of stereo sources is %d\n", stereo_sources); // FIXME: configure elsewhere int abt = fs_config_get_int_clamped("audio_buffer_target_size", 1, 100); if (abt == FS_CONFIG_NONE) { if (fs_config_get_int("audio_buffer_target_bytes") != FS_CONFIG_NONE) { fs_emu_warning("Use audio_buffer_target_size instead\n"); } abt = 40; #if 0 if (abt == FS_CONFIG_NONE) { abt = 40; } else { abt = (int) (abt / 1000.0 * (options->frequency * 2 * 2)); } #endif } fs_log("AUDIO: Buffer target size (ms) = %d\n", abt); //abt = (int) (abt / 1000.0 * (options->frequency * 2 * 2)); // fs_log("AUDIO: Buffer target size (bytes) = %d\n", abt); /* Specifying fill target in microseconds */ g_default_fill_target = abt * 1000; }
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"); SDL_Init(SDL_INIT_VIDEO); SDL_version version; SDL_VERSION(&version); fs_log("FS-UAE was compiled for SDL %d.%d.%d\n", version.major, version.minor, version.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("defaulting to fullscreen_mode = desktop for SDL2\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); } // we display a black frame as soon as possible (to reduce flickering on // startup) glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(g_fs_ml_window); fs_gl_finish(); 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 function must be called from the video thread fs_log("init_opengl\n"); fs_emu_video_init_opengl(); SDL_StartTextInput(); fs_log("create windows is done\n"); return 1; }