def on_setting(self, key, _): if key in [ "config_search", "game_list_uuid", "database_show_games", "database_show_adult", "database_show_unpublished", ]: # if key == "game_list_uuid": self.update_search() if len(self.items) > 0: self.select_item(None) self.select_item(0) else: # self.select_item(None) if LauncherSettings.get(PARENT_UUID): LauncherSettings.set(PARENT_UUID, "") LauncherConfig.load_default_config() elif key == "__config_refresh": self.update_search() self.select_item(None) old_parent_uuid = LauncherSettings.get(PARENT_UUID) if old_parent_uuid: LauncherSettings.set(PARENT_UUID, "") LauncherSettings.set(PARENT_UUID, old_parent_uuid) elif key == PARENT_UUID or key == "config_path": if not (LauncherSettings.get(PARENT_UUID) or LauncherSettings.get("config_path")): self.select_item(None)
def update_search(self): search = LauncherSettings.get("config_search").strip().lower() print("search for", search) words = [] special = [] for word in search.split(" "): word = word.strip() if not word: continue if ":" in word[1:-1]: special.append(word) else: words.append(word) terms = GameNameUtil.extract_search_terms(" ".join(words)) terms.update(special) database = Database.get_instance() try: have = int(LauncherSettings.get("database_show_games")) except ValueError: # default is show all downloadable and locally available games have = 1 items = database.find_games_new( " ".join(terms), have=have, list_uuid=LauncherSettings.get("game_list_uuid"), ) self.set_items(items)
def on_resize(self): width, height = self.get_size() # print("on_resize, size =", width, height) if self.is_maximized(): if LauncherSettings.get("maximized") != "1": LauncherSettings.set("maximized", "1") else: if LauncherSettings.get("maximized") != "0": LauncherSettings.set("maximized", "0") if self.screenshots_panel is not None: available = width - 2 * 10 - self.game_info_panel.get_min_width() num_screenshots = int( (available - 22 + 22) / (Constants.SCREEN_SIZE[0] + 22)) # print("Screenshots count:", num_screenshots) screenshots_panel_width = ( (Constants.SCREEN_SIZE[0] + 22) * num_screenshots - 22 + 22) self.screenshots_panel.set_min_width(screenshots_panel_width) if width > CONFIGURATIONS_PANEL_WIDTH_THRESHOLD_2: configurations_width = (SCREENSHOT_WIDTH * 3 + SCREENSHOT_SPACING * 2 + MARGIN) self.configurations_panel.set_min_width( CONFIGURATIONS_PANEL_WIDTH_2) else: self.configurations_panel.set_min_width( CONFIGURATIONS_PANEL_WIDTH_1) super().on_resize()
def update_environment_with_centering_info(self, env): # FIXME: does not really belong here (dependency loop) from launcher.launcher_config import LauncherConfig from launcher.launcher_settings import LauncherSettings width = (LauncherConfig.get("window_width") or LauncherSettings.get("window_width")) height = (LauncherConfig.get("window_height") or LauncherSettings.get("window_height")) try: width = int(width) except: width = 960 try: height = int(height) except: height = 540 from launcher.ui.launcherwindow import LauncherWindow if LauncherWindow.current() is None: return main_w, main_h = LauncherWindow.current().get_size() main_x, main_y = LauncherWindow.current().get_position() x = main_x + (main_w - width) // 2 y = main_y + (main_h - height) // 2 # FIXME: REMOVE env["FSGS_WINDOW_X"] = str(x) env["FSGS_WINDOW_Y"] = str(y) # FIXME: REMOVE env["SDL_VIDEO_WINDOW_POS"] = str("{0},{1}".format(x, y)) env["FSGS_WINDOW_CENTER"] = "{0},{1}".format(main_x + main_w // 2, main_y + main_h // 2)
def update_info(self, value=None): if LauncherSettings.get("fullscreen") != "1": self.set_text("") return if value is None: value = LauncherSettings.get("monitor") x, y, w, h = GameDriver.screen_rect_for_monitor(value) # index = GameRunner.screen_index_for_monitor(value) refresh_rate = GameDriver.screen_refresh_rate_for_monitor(value) assume_refresh_rate = LauncherSettings.get("assume_refresh_rate") if assume_refresh_rate: refresh_rate_override = " (OVERRIDING {})".format(refresh_rate) try: refresh_rate = float(assume_refresh_rate) except ValueError: refresh_rate = 0.0 else: refresh_rate_override = "" if x or y: pos_str = " ({}, {})".format(x, y) else: pos_str = "" self.set_text( "{}x{}{} @ {}Hz{}".format( w, h, pos_str, refresh_rate, refresh_rate_override ) )
def __init__(self, database): self.database = database database_cursor = self.database.cursor() database_cursor.execute( "SELECT uuid, update_stamp, have, id FROM game " "WHERE uuid IS NOT NULL") self.existing_games = {} for row in database_cursor: self.existing_games[row[0]] = row[1], row[2], row[3] database_cursor.execute( "SELECT uuid, update_stamp, have, id FROM game_variant") self.existing_variants = {} for row in database_cursor: self.existing_variants[row[0]] = row[1], row[2], row[3] self.file_stamps = FileDatabase.get_instance().get_last_event_stamps() cached_file_stamps = self.database.get_last_file_event_stamps() self.added_files = (self.file_stamps["last_file_insert"] != cached_file_stamps["last_file_insert"]) self.deleted_files = (self.file_stamps["last_file_delete"] != cached_file_stamps["last_file_delete"]) # print(LauncherSettings.get(Option.DATABASE_LOCKER), # cached_file_stamps["database_locker"]) # assert 0 if (LauncherSettings.get(Option.DATABASE_LOCKER) != cached_file_stamps["database_locker"]): # Assume that files could be deleted or removed... if LauncherSettings.get(Option.DATABASE_LOCKER) == "0": self.deleted_files = True else: self.added_files = True
def center_window(cls, args, env): # FIXME: does not really belong here (dependency loop) from launcher.launcher_config import LauncherConfig from launcher.launcher_settings import LauncherSettings width = (LauncherConfig.get("window_width") or LauncherSettings.get("window_width")) height = (LauncherConfig.get("window_height") or LauncherSettings.get("window_height")) try: width = int(width) except: width = 960 try: height = int(height) except: height = 540 from launcher.ui.launcher_window import LauncherWindow if LauncherWindow.current() is None: return main_w, main_h = LauncherWindow.current().get_size() main_x, main_y = LauncherWindow.current().get_position() x = main_x + (main_w - width) // 2 y = main_y + (main_h - height) // 2 # FIXME: re-implement without wx # if windows: # import wx # y += wx.SystemSettings_GetMetric(wx.SYS_CAPTION_Y) env[str("SDL_VIDEO_WINDOW_POS")] = str("{0},{1}".format(x, y)) args.append("--window-x={0}".format(x)) args.append("--window-y={0}".format(y))
def center_window(cls, args, env): # FIXME: does not really belong here (dependency loop) from launcher.launcher_config import LauncherConfig from launcher.launcher_settings import LauncherSettings width = (LauncherConfig.get("window_width") or LauncherSettings.get("window_width")) height = (LauncherConfig.get("window_height") or LauncherSettings.get("window_height")) try: width = int(width) except: width = 960 try: height = int(height) except: height = 540 from launcher.ui.launcher_window import LauncherWindow if LauncherWindow.current() is None: return main_w, main_h = LauncherWindow.current().get_size() main_x, main_y = LauncherWindow.current().get_position() x = main_x + (main_w - width) // 2 y = main_y + (main_h - height) // 2 # FIXME: re-implement without wx # if windows: # import wx # y += wx.SystemSettings_GetMetric(wx.SYS_CAPTION_Y) env[str("SDL_VIDEO_WINDOW_POS")] = str("{0},{1}".format(x, y)) args.append("--window-x={0}".format(x)) args.append("--window-y={0}".format(y))
def load_settings(cls): if cls.settings_loaded: return cls.settings_loaded = True settings = Settings.instance() settings.load() path = settings.path # path = app.get_settings_path() print("loading last config from " + repr(path)) if not os.path.exists(path): print("settings file does not exist") # noinspection PyArgumentList cp = ConfigParser(interpolation=None) try: cp.read([path]) except Exception as e: print(repr(e)) return for key in LauncherSettings.old_keys: if app.settings.get(key): print("[SETTINGS] Removing old key", key) app.settings.set(key, "") if fsgs.config.add_from_argv(): print("[CONFIG] Configuration specified via command line") # Prevent the launcher from loading the last used game LauncherSettings.set("parent_uuid", "") elif LauncherSettings.get("config_path"): if LauncherConfig.load_file(LauncherSettings.get("config_path")): print("[CONFIG] Loaded last configuration file") else: print("[CONFIG] Failed to load last configuration file") LauncherConfig.load_default_config() else: pass # config = {} # try: # keys = cp.options("config") # except NoSectionError: # keys = [] # for key in keys: # config[key] = fs.from_utf8_str(cp.get("config", key)) # for key, value in config.items(): # print("loaded", key, value) # fsgs.config.values[key] = value # Argument --new-config[=<platform>] new_config = "--new-config" in sys.argv new_config_platform = None for platform_id in PLATFORM_IDS: if "--new-config=" + platform_id in sys.argv: new_config = True new_config_platform = platform_id if new_config: LauncherConfig.load_default_config(platform=new_config_platform) # Prevent the launcher from loading the last used game LauncherSettings.set("parent_uuid", "")
def load_settings(cls): if cls.settings_loaded: return cls.settings_loaded = True settings = Settings.instance() settings.load() path = settings.path # path = app.get_settings_path() print("loading last config from " + repr(path)) if not os.path.exists(path): print("settings file does not exist") # noinspection PyArgumentList cp = ConfigParser(interpolation=None) try: cp.read([path]) except Exception as e: print(repr(e)) return for key in LauncherSettings.old_keys: if app.settings.get(key): print("[SETTINGS] Removing old key", key) app.settings.set(key, "") if fsgs.config.add_from_argv(): print("[CONFIG] Configuration specified via command line") # Prevent the launcher from loading the last used game LauncherSettings.set("parent_uuid", "") elif LauncherSettings.get("config_path"): if LauncherConfig.load_file(LauncherSettings.get("config_path")): print("[CONFIG] Loaded last configuration file") else: print("[CONFIG] Failed to load last configuration file") LauncherConfig.load_default_config() else: pass # config = {} # try: # keys = cp.options("config") # except NoSectionError: # keys = [] # for key in keys: # config[key] = fs.from_utf8_str(cp.get("config", key)) # for key, value in config.items(): # print("loaded", key, value) # fsgs.config.values[key] = value # Argument --new-config[=<platform>] new_config = "--new-config" in sys.argv new_config_platform = None for platform_id in PLATFORM_IDS: if "--new-config=" + platform_id in sys.argv: new_config = True new_config_platform = platform_id if new_config: LauncherConfig.load_default_config(platform=new_config_platform) # Prevent the launcher from loading the last used game LauncherSettings.set("parent_uuid", "")
def get_preferred_joysticks(cls): prefs = [] if LauncherSettings.get("primary_joystick"): prefs.append( Device.create_cmp_id(LauncherSettings.get("primary_joystick"))) if LauncherSettings.get("secondary_joystick"): prefs.append( Device.create_cmp_id( LauncherSettings.get("secondary_joystick"))) return prefs
def _check_platform(self, platform_option): if LauncherSettings.get(platform_option) == "1": return True if platform_option in [Option.AMIGA_DATABASE, Option.CD32_DATABASE, Option.CDTV_DATABASE]: if LauncherSettings.get(platform_option) != "0": return True return False if openretro and platform_option in OPENRETRO_DEFAULT_DATABASES: if LauncherSettings.get(platform_option) == "0": return False return True return False
def get_preferred_joysticks(cls): prefs = [] if LauncherSettings.get("primary_joystick"): prefs.append( Device.create_cmp_id(LauncherSettings.get("primary_joystick")) ) if LauncherSettings.get("secondary_joystick"): prefs.append( Device.create_cmp_id( LauncherSettings.get("secondary_joystick") ) ) return prefs
def create_menu(self): menu = fsui.PopupMenu() if LauncherSettings.get(Option.DATABASE_AUTH): menu.add_item(gettext("Update Game Database"), self.on_update_game_database) menu.add_item(gettext("Update File Database"), self.on_update_file_database) menu.add_separator() menu.add_item(gettext("ADF Creator"), self.on_adf_creator) menu.add_item(gettext("HDF Creator"), self.on_hdf_creator) if LauncherSettings.get(Option.NETPLAY_FEATURE) != "0": menu.add_item(gettext("Net Play"), self.on_net_play) menu.add_separator() menu.add_item( gettext("Import Kickstarts") + "...", self.on_import_kickstarts) menu.add_item( gettext("Amiga Forever Import") + "...", self.on_import_kickstarts) menu.add_separator() self.add_user_menu_content(menu) menu.add_separator() # menu.add_item( # gettext("Kickstarts & ROMs"), self.on_import_kickstarts) if LauncherSettings.get(Option.LAUNCHER_SETUP_WIZARD_FEATURE): menu.add_item( gettext("Setup Wizard") + "...", self.on_setup_wizard) menu.add_preferences_item(gettext("Settings"), self.on_settings_button) menu.add_separator() menu.add_item( gettext("About {name}").format(name="OpenRetro.org"), self.on_what_is_this, ) if fsgs_module.product == "OpenRetro": app_name = "OpenRetro Launcher" else: app_name = "FS-UAE Launcher" menu.add_about_item( gettext("About {name}").format(name=app_name), self.on_about) menu.add_separator() menu.add_about_item(gettext("Quit"), self.on_quit) return menu
def update_title(self): if Skin.fws(): # Just want to keep "FS-UAE Launcher" in the title return auth = LauncherSettings.get(Option.DATABASE_AUTH) if auth: username = LauncherSettings.get(Option.DATABASE_USERNAME) login_info = username else: login_info = gettext("Not logged in") app_name = "{} Launcher".format(Product.base_name) title = "{} {} ({})".format(app_name, Application.instance().version, login_info) self.set_title(title)
def __init__(self, parent): StatusElement.__init__(self, parent) self.error_icon = Image("launcher:res/16/error.png") self.warning_icon = Image("launcher:res/16/warning_3.png") self.notice_icon = Image("launcher:res/16/information.png") self.icons = [ self.error_icon, self.warning_icon, self.notice_icon, ] self.coordinates = [] self.warnings = [] self.game_notice = "" self.variant_notice = "" self.variant_warning = "" self.variant_error = "" self.joy_emu_conflict = "" self.using_joy_emu = False self.kickstart_file = "" self.x_kickstart_file_sha1 = "" self.update_available = "" self.__error = "" self.x_missing_files = "" self.download_page = "" self.download_file = "" self.amiga_model = "" self.amiga_model_calculated = "" self.chip_memory = "" self.chip_memory_calculated = 0 self.outdated_plugins = [] self.custom_config = set() self.custom_uae_config = set() self.settings_config_keys = set() plugin_manager = PluginManager.instance() for plugin in plugin_manager.plugins(): if plugin.outdated: self.outdated_plugins.append(plugin.name) ConfigBehavior(self, [ "x_game_notice", "x_variant_notice", "x_variant_warning", "x_variant_error", "x_joy_emu_conflict", "amiga_model", "x_kickstart_file_sha1", "kickstart_file", "download_page", "download_file", "x_missing_files", "__error", "chip_memory", "jit_compiler"]) SettingsBehavior(self, ["__update_available"]) LauncherConfig.add_listener(self) for key in JOYSTICK_KEYS: self.on_config(key, LauncherConfig.get(key)) for key in LauncherConfig.keys(): if LauncherConfig.is_custom_uae_option(key): self.on_config(key, LauncherConfig.get(key)) elif LauncherConfig.is_custom_option(key): self.on_config(key, LauncherConfig.get(key)) LauncherSettings.add_listener(self) for key in LauncherSettings.keys(): if LauncherConfig.is_config_only_option(key): self.on_setting(key, LauncherSettings.get(key))
def __init__(self, parent): # fsui.VerticalItemView.__init__(self, parent) fsui.ItemChoice.__init__(self, parent) self.parent_uuid = "" self.items = [] # type: list [dict] # self.last_variants = LastVariants() self.icon = fsui.Image("launcher:/data/fsuae_config_16.png") self.adf_icon = fsui.Image("launcher:/data/adf_game_16.png") self.ipf_icon = fsui.Image("launcher:/data/ipf_game_16.png") self.cd_icon = fsui.Image("launcher:/data/cd_game_16.png") self.hd_icon = fsui.Image("launcher:/data/hd_game_16.png") # self.missing_icon = fsui.Image( # "launcher:/data/missing_game_16.png") self.missing_icon = fsui.Image("launcher:/data/16x16/delete_grey.png") self.missing_color = fsui.Color(0xA8, 0xA8, 0xA8) self.blank_icon = fsui.Image("launcher:/data/16x16/blank.png") self.bullet_icon = fsui.Image("launcher:/data/16x16/bullet.png") self.manual_download_icon = fsui.Image( "launcher:/data/16x16/arrow_down_yellow.png") self.auto_download_icon = fsui.Image( "launcher:/data/16x16/arrow_down_green.png") self.up_icon = fsui.Image("launcher:/data/16x16/thumb_up_mod.png") self.down_icon = fsui.Image("launcher:/data/16x16/thumb_down_mod.png") self.fav_icon = fsui.Image("launcher:/data/rating_fav_16.png") LauncherSettings.add_listener(self) self.on_setting("parent_uuid", LauncherSettings.get("parent_uuid"))
def _check_platform(self, platform_option): if LauncherSettings.get(platform_option) == "1": return True if platform_option in [ Option.AMIGA_DATABASE, Option.CD32_DATABASE, Option.CDTV_DATABASE, ]: if LauncherSettings.get(platform_option) != "0": return True return False if openretro and platform_option in OPENRETRO_DEFAULT_DATABASES: if LauncherSettings.get(platform_option) == "0": return False return True return False
def finish(self): database_cursor = self.database.cursor() # variants left in this list must now be deleted for row in self.existing_variants.values(): variant_id = row[2] database_cursor.execute("DELETE FROM game_variant WHERE id = ?", (variant_id, )) # games left in this list must now be deleted for row in self.existing_games.values(): game_id = row[2] database_cursor.execute("DELETE FROM game WHERE id = ?", (game_id, )) database_cursor.execute( "SELECT count(*) FROM game WHERE uuid IS NOT NULL " "AND (have IS NULL OR have != (SELECT coalesce(max(have), 0) " "FROM game_variant WHERE game_uuid = game.uuid))") update_rows = database_cursor.fetchone()[0] print(update_rows, "game entries need update for have field") if update_rows > 0: database_cursor.execute( "UPDATE game SET have = (SELECT coalesce(max(have), 0) FROM " "game_variant WHERE game_uuid = game.uuid) WHERE uuid IS NOT " "NULL AND (have IS NULL OR have != (SELECT coalesce(max(" "have), 0) FROM game_variant WHERE game_uuid = game.uuid))") # FIXME: Remove this line? FileDatabase.get_instance().get_last_event_stamps() self.file_stamps["database_locker"] = LauncherSettings.get( Option.DATABASE_LOCKER) self.database.update_last_file_event_stamps(self.file_stamps)
def config_startup_scan(cls): if cls._config_scanned: return cls._config_scanned = True configs_dir = FSGSDirectories.get_configurations_dir() print("config_startup_scan", configs_dir) print(LauncherSettings.settings) settings_mtime = LauncherSettings.get("configurations_dir_mtime") dir_mtime = cls.get_dir_mtime_str(configs_dir) if settings_mtime == dir_mtime + "+" + str(Database.VERSION): print("... mtime not changed", settings_mtime, dir_mtime) return database = Database.get_instance() file_database = FileDatabase.get_instance() print("... database.find_local_configurations") local_configs = Database.get_instance().find_local_configurations() print("... walk configs_dir") for dir_path, dir_names, file_names in os.walk(configs_dir): for file_name in file_names: if not file_name.endswith(".fs-uae"): continue path = Paths.join(dir_path, file_name) if path in local_configs: local_configs[path] = None # already exists in database continue name, ext = os.path.splitext(file_name) # search = ConfigurationScanner.create_configuration_search( # name) scanner = ConfigurationScanner() print("[startup] adding config", path) file_database.delete_file(path=path) with open(path, "rb") as f: sha1 = hashlib.sha1(f.read()).hexdigest() file_database.add_file(path=path, sha1=sha1) game_id = database.add_configuration( path=path, name=scanner.create_configuration_name(name) ) database.update_game_search_terms( game_id, scanner.create_search_terms(name) ) for path, config_id in local_configs.items(): if config_id is not None: print("[startup] removing configuration", path) database.delete_game(id=config_id) file_database.delete_file(path=path) print("... commit") database.commit() LauncherSettings.set( "configurations_dir_mtime", cls.get_dir_mtime_str(configs_dir) + "+" + str(Database.VERSION), )
def _check_platform(self, platform_option): if LauncherSettings.get(platform_option) == "1": return True if Product.includes_amiga() and platform_option in [ Option.AMIGA_DATABASE, Option.CD32_DATABASE, Option.CDTV_DATABASE, ]: if LauncherSettings.get(platform_option) != "0": return True return False if (Product.is_openretro() and platform_option in OPENRETRO_DEFAULT_DATABASES): if LauncherSettings.get(platform_option) == "0": return False return True return False
def _update_game_database(self, database_name, game_database): game_database_client = GameDatabaseClient(game_database) synchronizer = GameDatabaseSynchronizer( self.context, game_database_client, on_status=self.on_status, stop_check=self.stop_check, platform_id=database_name) synchronizer.username = "******" synchronizer.password = LauncherSettings.get("database_auth") synchronizer.synchronize()
def config_startup_scan(cls): if cls._config_scanned: return cls._config_scanned = True configs_dir = FSGSDirectories.get_configurations_dir() print("config_startup_scan", configs_dir) print(LauncherSettings.settings) settings_mtime = LauncherSettings.get("configurations_dir_mtime") dir_mtime = cls.get_dir_mtime_str(configs_dir) if settings_mtime == dir_mtime + "+" + str(Database.VERSION): print("... mtime not changed", settings_mtime, dir_mtime) return database = Database.get_instance() file_database = FileDatabase.get_instance() print("... database.find_local_configurations") local_configs = Database.get_instance().find_local_configurations() print("... walk configs_dir") for dir_path, dir_names, file_names in os.walk(configs_dir): for file_name in file_names: if not file_name.endswith(".fs-uae"): continue path = Paths.join(dir_path, file_name) if path in local_configs: local_configs[path] = None # already exists in database continue name, ext = os.path.splitext(file_name) # search = ConfigurationScanner.create_configuration_search( # name) scanner = ConfigurationScanner() print("[startup] adding config", path) file_database.delete_file(path=path) with open(path, "rb") as f: sha1 = hashlib.sha1(f.read()).hexdigest() file_database.add_file(path=path, sha1=sha1) game_id = database.add_configuration( path=path, name=scanner.create_configuration_name(name)) database.update_game_search_terms( game_id, scanner.create_search_terms(name)) for path, config_id in local_configs.items(): if config_id is not None: print("[startup] removing configuration", path) database.delete_game(id=config_id) file_database.delete_file(path=path) print("... commit") database.commit() LauncherSettings.set( "configurations_dir_mtime", cls.get_dir_mtime_str(configs_dir) + "+" + str(Database.VERSION), )
def _scan_thread(cls, database): if cls.scan_for_files: scanner = FileScanner( cls.paths, cls.purge_other_dirs, on_status=cls.on_status, stop_check=cls.stop_check, ) scanner.scan() if cls.stop_check(): return # if cls.scan_for_configs or # if cls.update_game_database: scanner = ConfigurationScanner(cls.paths, on_status=cls.on_status, stop_check=cls.stop_check) scanner.scan(database) if cls.update_game_database: context = SynchronizerContext() synchronizer = MetaSynchronizer(context, on_status=cls.on_status, stop_check=cls.stop_check) synchronizer.synchronize() synchronizer = GameRatingSynchronizer( context, database, on_status=cls.on_status, stop_check=cls.stop_check, ) synchronizer.username = "******" synchronizer.password = LauncherSettings.get("database_auth") synchronizer.synchronize() synchronizer = ListsSynchronizer(context, on_status=cls.on_status, stop_check=cls.stop_check) synchronizer.synchronize() scanner = GameScanner( context, cls.paths, on_status=cls.on_status, stop_check=cls.stop_check, ) scanner.update_game_database() scanner = GameScanner(None, cls.paths, on_status=cls.on_status, stop_check=cls.stop_check) scanner.scan(database)
def _scan_thread(cls, database): if cls.scan_for_files: scanner = FileScanner( cls.paths, cls.purge_other_dirs, on_status=cls.on_status, stop_check=cls.stop_check, ) scanner.scan() if cls.stop_check(): return # if cls.scan_for_configs or # if cls.update_game_database: scanner = ConfigurationScanner( cls.paths, on_status=cls.on_status, stop_check=cls.stop_check ) scanner.scan(database) if cls.update_game_database: context = SynchronizerContext() synchronizer = MetaSynchronizer( context, on_status=cls.on_status, stop_check=cls.stop_check ) synchronizer.synchronize() synchronizer = GameRatingSynchronizer( context, database, on_status=cls.on_status, stop_check=cls.stop_check, ) synchronizer.username = "******" synchronizer.password = LauncherSettings.get("database_auth") synchronizer.synchronize() synchronizer = ListsSynchronizer( context, on_status=cls.on_status, stop_check=cls.stop_check ) synchronizer.synchronize() scanner = GameScanner( context, cls.paths, on_status=cls.on_status, stop_check=cls.stop_check, ) scanner.update_game_database() scanner = GameScanner( None, cls.paths, on_status=cls.on_status, stop_check=cls.stop_check ) scanner.scan(database)
def update_environment_with_centering_info(self, env): # FIXME: does not really belong here (dependency loop) from launcher.launcher_config import LauncherConfig from launcher.launcher_settings import LauncherSettings width = LauncherConfig.get("window_width") or LauncherSettings.get( "window_width" ) height = LauncherConfig.get("window_height") or LauncherSettings.get( "window_height" ) try: width = int(width) except: width = 960 try: height = int(height) except: height = 540 from launcher.ui.launcherwindow import LauncherWindow if LauncherWindow.current() is None: return main_w, main_h = LauncherWindow.current().get_size() main_x, main_y = LauncherWindow.current().get_position() x = main_x + (main_w - width) // 2 y = main_y + (main_h - height) // 2 # FIXME: REMOVE env["FSGS_WINDOW_X"] = str(x) env["FSGS_WINDOW_Y"] = str(y) # FIXME: REMOVE env["SDL_VIDEO_WINDOW_POS"] = str("{0},{1}".format(x, y)) env["FSGS_WINDOW_POS"] = str("{0},{1}".format(x, y)) env["FSGS_WINDOW_CENTER"] = "{0},{1}".format( main_x + main_w // 2, main_y + main_h // 2 )
def _update_game_database(self, database_name, game_database): game_database_client = GameDatabaseClient(game_database) synchronizer = GameDatabaseSynchronizer( self.context, game_database_client, on_status=self.on_status, stop_check=self.stop_check, platform_id=database_name, ) synchronizer.username = "******" synchronizer.password = LauncherSettings.get("database_auth") synchronizer.synchronize()
def __init__(self, database): self.database = database database_cursor = self.database.cursor() database_cursor.execute( "SELECT uuid, update_stamp, have, id FROM game " "WHERE uuid IS NOT NULL" ) self.existing_games = {} for row in database_cursor: self.existing_games[row[0]] = row[1], row[2], row[3] database_cursor.execute( "SELECT uuid, update_stamp, have, id FROM game_variant" ) self.existing_variants = {} for row in database_cursor: self.existing_variants[row[0]] = row[1], row[2], row[3] self.file_stamps = FileDatabase.get_instance().get_last_event_stamps() cached_file_stamps = self.database.get_last_file_event_stamps() self.added_files = ( self.file_stamps["last_file_insert"] != cached_file_stamps["last_file_insert"] ) self.deleted_files = ( self.file_stamps["last_file_delete"] != cached_file_stamps["last_file_delete"] ) # print(LauncherSettings.get(Option.DATABASE_LOCKER), # cached_file_stamps["database_locker"]) # assert 0 if ( LauncherSettings.get(Option.DATABASE_LOCKER) != cached_file_stamps["database_locker"] ): # Assume that files could be deleted or removed... if LauncherSettings.get(Option.DATABASE_LOCKER) == "0": self.deleted_files = True else: self.added_files = True
def __init__(self, parent, names): parent.__settings_enable_behavior = self self._parent = weakref.ref(parent) self._names = set(names) LauncherSettings.add_listener(self) try: parent.destroyed.connect(self.on_parent_destroyed) except AttributeError: print("WARNING: SettingsBehavior without remove_listener " "implementation") for name in names: # Broadcast initial value self.on_setting(name, LauncherSettings.get(name))
def __init__(self, parent, names): parent.__settings_enable_behavior = self self._parent = weakref.ref(parent) self._names = set(names) LauncherSettings.add_listener(self) try: parent.destroyed.connect(self.on_parent_destroyed) except AttributeError: print("WARNING: SettingsBehavior without remove_listener " "implementation") for name in names: # Broadcast initial value self.on_setting(name, LauncherSettings.get(name))
def add_user_menu_content(self, menu): if LauncherSettings.get(Option.DATABASE_AUTH): # menu.add_item(_("Log In / Register"), self.on_log_in) # menu.add_item(gettext("Update Game Database"), # self.on_game_database_refresh) if is_locker_enabled(): menu.add_item( gettext("Upload Files to OpenRetro Locker"), self.on_upload_locker_files, ) # menu.add_separator() menu.add_item(gettext("Log Out"), self.on_log_out) else: menu.add_item(gettext("Log In / Register"), self.on_log_in)
def update_widgets(self): value = LauncherSettings.get("video_sync") vblank = value in ["1", "auto", "full", "vblank"] full = value in ["1", "auto", "full"] # self.full_sync_checkbox.enable(vblank) self.sync_method_group.label.enable(vblank) self.sync_method_group.widget.enable(vblank) self.sync_method_group.help_button.enable(vblank) self.sync_method_label.enable(vblank) # self.smooth_label.enable(vblank) self.low_latency_group.label.enable(full) self.low_latency_group.widget.enable(full) self.low_latency_group.help_button.enable(full)
def update_widgets(self): value = LauncherSettings.get("video_sync") vblank = value in ["1", "auto", "full", "vblank"] full = value in ["1", "auto", "full"] # self.full_sync_checkbox.enable(vblank) self.sync_method_group.label.enable(vblank) self.sync_method_group.widget.enable(vblank) self.sync_method_group.help_button.enable(vblank) self.sync_method_label.enable(vblank) # self.smooth_label.enable(vblank) self.low_latency_group.label.enable(full) self.low_latency_group.widget.enable(full) self.low_latency_group.help_button.enable(full)
def load_settings(cls): if cls.settings_loaded: return cls.settings_loaded = True settings = Settings.instance() settings.load() path = settings.path # path = app.get_settings_path() print("loading last config from " + repr(path)) if not os.path.exists(path): print("settings file does not exist") # noinspection PyArgumentList cp = ConfigParser(interpolation=None) try: cp.read([path]) except Exception as e: print(repr(e)) return for key in LauncherSettings.old_keys: if app.settings.get(key): print("[SETTINGS] Removing old key", key) app.settings.set(key, "") if fsgs.config.add_from_argv(): print("[CONFIG] Configuration specified via command line") # Prevent the launcher from loading the last used game LauncherSettings.set("parent_uuid", "") elif LauncherSettings.get("config_path"): if LauncherConfig.load_file(LauncherSettings.get("config_path")): print("[CONFIG] Loaded last configuration file") else: print("[CONFIG] Failed to load last configuration file") LauncherConfig.load_default_config() pass
def update_info(self, value=None): if LauncherSettings.get("fullscreen") != "1": self.set_text("") return if value is None: value = LauncherSettings.get("monitor") x, y, w, h = GameRunner.screen_rect_for_monitor(value) # index = GameRunner.screen_index_for_monitor(value) refresh_rate = GameRunner.screen_refresh_rate_for_monitor(value) assume_refresh_rate = LauncherSettings.get("assume_refresh_rate") if assume_refresh_rate: refresh_rate_override = " (OVERRIDING {})".format(refresh_rate) try: refresh_rate = float(assume_refresh_rate) except ValueError: refresh_rate = 0.0 else: refresh_rate_override = "" if x or y: pos_str = " ({}, {})".format(x, y) else: pos_str = "" self.set_text("{}x{}{} @ {}Hz{}".format( w, h, pos_str, refresh_rate, refresh_rate_override))
def __init__(self, parent): fsui.Choice.__init__(self, parent) # FIXME: include in () what language is currently the automatic one selected_language = LauncherSettings.get("language") k = 0 selected_index = 0 for label, language_key, icon_name in LANGUAGE_ITEMS: self.add_item(label, fsui.Image( "workspace:res/16/flag-{0}.png".format(icon_name))) if language_key == selected_language: selected_index = k k += 1 if selected_index > 0: self.set_index(selected_index)
def kickstart_startup_scan(cls): if cls._kickstart_scanned: return cls._kickstart_scanned = True print("kickstart_startup_scan") kickstarts_dir = FSGSDirectories.get_kickstarts_dir() if LauncherSettings.get( "kickstarts_dir_mtime" ) == cls.get_dir_mtime_str(kickstarts_dir): print("... mtime not changed") else: file_database = FileDatabase.get_instance() print("... database.find_local_roms") local_roms = file_database.find_local_roms() print("... walk kickstarts_dir") for dir_path, dir_names, file_names in os.walk(kickstarts_dir): for file_name in file_names: if not file_name.lower().endswith( ".rom" ) and not file_name.lower().endswith(".bin"): continue path = Paths.join(dir_path, file_name) if path in local_roms: local_roms[path] = None # already exists in database continue print("[startup] adding kickstart", path) ROMManager.add_rom_to_database(path, file_database) print(local_roms) for path, file_id in local_roms.items(): if file_id is not None: print("[startup] removing kickstart", path) file_database.delete_file(id=file_id) print("... commit") file_database.commit() LauncherSettings.set( "kickstarts_dir_mtime", cls.get_dir_mtime_str(kickstarts_dir) ) amiga = Amiga.get_model_config("A500") for sha1 in amiga["kickstarts"]: if fsgs.file.find_by_sha1(sha1=sha1): break else: file_database = FileDatabase.get_instance() cls.amiga_forever_kickstart_scan() file_database.commit()
def __init__(self, parent): fsui.Choice.__init__(self, parent) # FIXME: include in () what language is currently the automatic one selected_language = LauncherSettings.get("language") k = 0 selected_index = 0 for label, language_key, icon_name in LANGUAGE_ITEMS: self.add_item( label, fsui.Image("workspace:res/16/flag-{0}.png".format(icon_name))) if language_key == selected_language: selected_index = k k += 1 if selected_index > 0: self.set_index(selected_index)
def kickstart_startup_scan(cls): if cls._kickstart_scanned: return cls._kickstart_scanned = True print("kickstart_startup_scan") kickstarts_dir = FSGSDirectories.get_kickstarts_dir() if LauncherSettings.get("kickstarts_dir_mtime") == \ cls.get_dir_mtime_str(kickstarts_dir): print("... mtime not changed") else: file_database = FileDatabase.get_instance() print("... database.find_local_roms") local_roms = file_database.find_local_roms() print("... walk kickstarts_dir") for dir_path, dir_names, file_names in os.walk(kickstarts_dir): for file_name in file_names: if not file_name.lower().endswith(".rom") and not \ file_name.lower().endswith(".bin"): continue path = Paths.join(dir_path, file_name) if path in local_roms: local_roms[path] = None # already exists in database continue print("[startup] adding kickstart", path) ROMManager.add_rom_to_database(path, file_database) print(local_roms) for path, file_id in local_roms.items(): if file_id is not None: print("[startup] removing kickstart", path) file_database.delete_file(id=file_id) print("... commit") file_database.commit() LauncherSettings.set( "kickstarts_dir_mtime", cls.get_dir_mtime_str(kickstarts_dir)) amiga = Amiga.get_model_config("A500") for sha1 in amiga["kickstarts"]: if fsgs.file.find_by_sha1(sha1=sha1): break else: file_database = FileDatabase.get_instance() cls.amiga_forever_kickstart_scan() file_database.commit()
def on_remove_button(self): path = self.list_view.get_item(self.list_view.get_index()) search_path = LauncherSettings.get("search_path") search_path = [x.strip() for x in search_path.split(";") if x.strip()] for i in range(len(search_path)): if search_path[i].startswith("-"): if path == search_path[i][1:]: # Already removed. break else: if search_path[i] == path: search_path.remove(search_path[i]) break default_paths = FSGSDirectories.get_default_search_path() if path in default_paths: search_path.append("-" + path) LauncherSettings.set("search_path", ";".join(search_path))
def observe(observer, scheduler): print(" -- new listener") # def listener(key, value): # if key == # observer.on_next(value) # Broadcast initial value observer.on_next(LauncherSettings.get(key)) listener = SettingListener(key, observer) # HACK, BECAUSE LauncherSettings do not keep ref SettingObservable.listeners.append(listener) LauncherSettings.add_listener(listener) def dispose(): SettingObservable.listeners.remove(listener) LauncherSettings.remove_listener(listener) return Disposable(dispose)
def on_add_button(self): search_path = LauncherSettings.get("search_path") search_path = [x.strip() for x in search_path.split(";") if x.strip()] path = fsui.pick_directory(parent=self.get_window()) if path: for i in range(len(search_path)): if search_path[i].startswith("-"): if path == search_path[i][1:]: search_path.remove(search_path[i]) break else: if search_path[i] == path: # Already added. break else: default_paths = FSGSDirectories.get_default_search_path() if path not in default_paths: search_path.append(path) LauncherSettings.set("search_path", ";".join(search_path))
def expand_path(cls, path, default_dir=None): if path and path[0] == "$": cmp_path = path.upper().replace("\\", "/") if cmp_path.startswith("$BASE/"): return cls.join(cls.get_base_dir(), path[6:]) if cmp_path.startswith("$CONFIG/"): # FIXME: dependency loop, have FS-UAE Launcher register # this prefix with this class instead from launcher.launcher_settings import LauncherSettings config_path = LauncherSettings.get("config_path") if config_path: return cls.join(os.path.dirname(config_path), path[8:]) if cmp_path.startswith("$HOME/"): return cls.join(cls.get_home_dir(), path[6:]) # FIXME: $base_dir is deprecated if cmp_path.startswith("$BASE_DIR/"): return cls.join(cls.get_base_dir(), path[10:]) elif not os.path.isabs(path) and default_dir is not None: return os.path.join(default_dir, path) return path
def expand_path(cls, path, default_dir=None): if path and path[0] == "$": cmp_path = path.upper().replace("\\", "/") if cmp_path.startswith("$BASE/"): return cls.join(cls.get_base_dir(), path[6:]) if cmp_path.startswith("$CONFIG/"): # FIXME: dependency loop, have FS-UAE Launcher register # this prefix with this class instead from launcher.launcher_settings import LauncherSettings config_path = LauncherSettings.get("config_path") if config_path: return cls.join(os.path.dirname(config_path), path[8:]) if cmp_path.startswith("$HOME/"): return cls.join(cls.get_home_dir(), path[6:]) # FIXME: $base_dir is deprecated if cmp_path.startswith("$BASE_DIR/"): return cls.join(cls.get_base_dir(), path[10:]) elif not os.path.isabs(path) and default_dir is not None: return os.path.join(default_dir, path) return path
def finish(self): database_cursor = self.database.cursor() # variants left in this list must now be deleted for row in self.existing_variants.values(): variant_id = row[2] database_cursor.execute( "DELETE FROM game_variant WHERE id = ?", (variant_id,) ) # games left in this list must now be deleted for row in self.existing_games.values(): game_id = row[2] database_cursor.execute( "DELETE FROM game WHERE id = ?", (game_id,) ) database_cursor.execute( "SELECT count(*) FROM game WHERE uuid IS NOT NULL " "AND (have IS NULL OR have != (SELECT coalesce(max(have), 0) " "FROM game_variant WHERE game_uuid = game.uuid))" ) update_rows = database_cursor.fetchone()[0] print(update_rows, "game entries need update for have field") if update_rows > 0: database_cursor.execute( "UPDATE game SET have = (SELECT coalesce(max(have), 0) FROM " "game_variant WHERE game_uuid = game.uuid) WHERE uuid IS NOT " "NULL AND (have IS NULL OR have != (SELECT coalesce(max(" "have), 0) FROM game_variant WHERE game_uuid = game.uuid))" ) # FIXME: Remove this line? FileDatabase.get_instance().get_last_event_stamps() self.file_stamps["database_locker"] = LauncherSettings.get( Option.DATABASE_LOCKER ) self.database.update_last_file_event_stamps(self.file_stamps)
def get_search_path(cls): paths = FSGSDirectories.get_default_search_path() search_path = LauncherSettings.get("search_path") for p in search_path.split(";"): p = p.strip() if not p: continue elif p[0] == "-": p = p[1:] if p in paths: paths.remove(p) else: if p not in paths: paths.append(p) # The Configurations dir is always scanned on startup (whenever # modification time has changed). If we don't include it here too # always, the result will be that the configs sometimes appear (on # startup) and disappear (on scan). if not FSGSDirectories.get_configurations_dir() in paths: paths.append(FSGSDirectories.get_configurations_dir()) # Likewise, we force the Kickstarts directory to always be scanned. if not FSGSDirectories.get_kickstarts_dir() in paths: paths.append(FSGSDirectories.get_kickstarts_dir()) return paths
def start_local_game_amiga(cls): # make sure x_kickstart_file is initialized LauncherConfig.set_kickstart_from_model() # if not Config.get("x_kickstart_file"): # or not \ # # os.path.exists(Config.get("kickstart_file")): # fsui.show_error( # gettext("No kickstart found for this model. Use the 'Import " # "Kickstarts' function from the menu.")) # return cs = Amiga.get_model_config( LauncherConfig.get("amiga_model"))["ext_roms"] if len(cs) > 0: # extended kickstart ROM is needed if not LauncherConfig.get("x_kickstart_ext_file"): fsui.show_error( gettext("No extended kickstart found for this model. " "Try 'scan' function.")) return config = LauncherConfig.copy() prepared_config = cls.prepare_config(config) model = LauncherConfig.get("amiga_model") if model.startswith("CD32"): platform = "CD32" elif model == "CDTV": platform = "CDTV" else: platform = "Amiga" name = LauncherSettings.get("config_name") uuid = LauncherConfig.get("x_game_uuid") from fsgs.SaveStateHandler import SaveStateHandler save_state_handler = SaveStateHandler(fsgs, name, platform, uuid) from fsgs.amiga.LaunchHandler import LaunchHandler launch_handler = LaunchHandler(fsgs, name, prepared_config, save_state_handler) from .ui.launcher_window import LauncherWindow task = AmigaLaunchTask(launch_handler) # dialog = LaunchDialog(MainWindow.instance, launch_handler) dialog = LaunchDialog( LauncherWindow.current(), gettext("Launching FS-UAE"), task) dialog.show() def on_show_license_information(license_text): unused(license_text) # FIXME: don't depend on wx here # noinspection PyUnresolvedReferences # import wx # license_dialog = wx.MessageDialog( # dialog, license_text, _("Terms of Use"), # wx.OK | wx.CANCEL | wx.CENTRE) # license_dialog.CenterOnParent() # result = license_dialog.ShowModal() # return result == wx.ID_OK # FIXME return True fsgs.file.on_show_license_information = on_show_license_information LauncherConfig.set("__running", "1") task.start()
def __init__(self, parent): super().__init__(parent) icon = fsui.Icon("video-settings", "pkg:workspace") gettext("Video Synchronization Settings") title = gettext("Synchronization") subtitle = gettext("Synchronize FS-UAE with your display for " "smooth video") self.add_header(icon, title, subtitle) label = fsui.MultiLineLabel( self, gettext( "Enabling the following option will synchronize the emulation " "to the display when the emulation refresh rate matches the" "screen refresh rate."), 640) self.layout.add(label, fill=True, margin_top=0) self.video_sync_group = self.add_option("video_sync") self.low_latency_group = self.add_option("low_latency_vsync") # label = fsui.MultiLineLabel(self, gettext( # "Enabling the following option will prevent tearing from " # "occurring, but will also use more CPU. Input latency " # "may become slightly higher."), 640) # self.layout.add(label, fill=True, margin_top=0) # self.vblank_checkbox = fsui.HeadingCheckBox(self, gettext( # "Synchronize buffer swaps with display (prevents tearing)")) # self.layout.add(self.vblank_checkbox, margin_top=20) self.sync_method_label = fsui.MultiLineLabel( self, gettext("Depending on your OS and OpenGL drivers, synchronizing " "can use needlessly much CPU (esp. applies to " "Linux). You can experiment with different sync methods " "to improve performance."), 640) self.layout.add(self.sync_method_label, fill=True, margin_top=20) self.sync_method_group = self.add_option("video_sync_method") # self.smooth_label = fsui.MultiLineLabel(self, gettext( # "In order to get really smooth Amiga graphics, you need to " # "enable the following option, and also make sure your display " # "is running at 50Hz (for PAL) or 60Hz (for NTSC)."), 640) # self.layout.add(self.smooth_label, fill=True, margin_top=20) # self.full_sync_checkbox = fsui.HeadingCheckBox(self, gettext( # "Also synchronize emulation with display when possible " # "(smooth scrolling)")) # self.layout.add(self.full_sync_checkbox, margin_top=20) self.layout.add_spacer(0, expand=True) hori_layout = fsui.HorizontalLayout() self.layout.add(hori_layout, fill=True, margin_top=10) hori_layout.add( fsui.ImageView(self, fsui.Image("launcher:res/16x16/world_link.png"))) label = fsui.URLLabel( self, gettext("How to achieve perfectly smooth scrolling"), "https://fs-uae.net/perfectly-smooth-scrolling") hori_layout.add(label, margin_left=6) text = gettext( "Synchronizing with the display can in some cases cause " "increased stuttering and low frame rates (esp. in some Linux " "desktop environments with compositing enabled).") link = (" <a href='https://fs-uae.net/video-synchronization-issues'>" "{0}</a>.".format(gettext("Read more"))) label = fsui.MultiLineLabel(self, text + link, min_width=640) self.layout.add(label, fill=True, margin_top=20) LauncherSettings.add_listener(self) for key in ["video_sync"]: self.on_setting(key, LauncherSettings.get(key))
def has_close_buttons(self): return LauncherSettings.get(Option.LAUNCHER_CLOSE_BUTTONS) == "1"
def __init__(self, parent, index=0): PagedDialog.__init__( self, parent, "{} - {} Launcher".format(gettext("Settings"), fsgs.product), ) # FIXME: remove this once the dialog uses Window as base class # self.setAttribute(Qt.WA_DeleteOnClose, True) # self.add_page( # # gettext("Appearance"), LanguageSettingsPage, # gettext("Language"), LanguageSettingsPage, # fsui.Icon("language-settings", "pkg:workspace")) self.add_page( gettext("Common"), LanguageSettingsPage, fsui.Icon("language-settings", "pkg:workspace"), bold=True, ) self.add_page( gettext("Controllers"), JoystickSettingsPage, fsui.Icon("gamepad", "pkg:workspace"), ) self.add_page( gettext("Plugins"), PluginsSettingsPage, fsui.Icon("settings", "pkg:workspace"), ) self.add_page( gettext("Directories"), DirectoriesSettingsPage, fsui.Icon("folder", "pkg:launcher"), ) self.add_page( gettext("Advanced"), AdvancedSettingsPage, fsui.Icon("settings", "pkg:workspace"), ) self.add_page( "FS-UAE", FSUAESettingsPage, fsui.Icon("fs-uae", "pkg:launcher"), bold=True, ) self.add_page( gettext("Keyboard"), KeyboardSettingsPage, fsui.Icon("keyboard-settings", "pkg:workspace"), ) self.add_page( gettext("Mouse"), MouseSettingsPage, fsui.Icon("mouse-settings", "pkg:workspace"), ) self.add_page( gettext("Audio"), AudioSettingsPage, fsui.Icon("audio-settings", "pkg:workspace"), ) self.add_page( gettext("Video"), VideoSettingsPage, fsui.Icon("video-settings", "pkg:workspace"), ) self.add_page( gettext("Advanced Video"), AdvancedVideoSettingsPage, fsui.Icon("video-settings", "pkg:workspace"), ) # self.add_page( # gettext("Synchronization"), VideoSyncSettingsPage, # fsui.Icon("video-settings", "pkg:workspace")) # self.add_page( # gettext("Filters & Scaling"), FilterSettingsPage, # fsui.Icon("video-settings", "pkg:workspace")) # self.add_page(gettext("OpenGL Settings"), OpenGLSettingsPage) # if Settings.get("database_feature") == "1": # self.add_page( # gettext("Logging"), LoggingSettingsPage, # fsui.Icon("settings", "pkg:workspace")) self.add_page( "{} Launcher".format(fsgs.product), LauncherSettingsPage, fsui.Icon("fs-uae-launcher", "pkg:launcher"), bold=True, ) self.add_page( gettext("File Database"), ScanSettingsPage, fsui.Icon("indexing-settings", "pkg:workspace"), ) self.add_page( gettext("Game Database"), GameDatabaseSettingsPage, fsui.Icon("database-settings", "pkg:workspace"), ) if fsgs.openretro or settings.get(Option.PLATFORMS_FEATURE) == "1": self.add_page( gettext("Game Platforms"), GamePlatformsSettingsPage, fsui.Icon("database-settings", "pkg:workspace"), ) # self.add_page(gettext("Custom Settings"), CustomSettingsPage) if LauncherSettings.get(Option.NETPLAY_FEATURE) != "0": self.add_page( gettext("Net Play"), NetplaySettingsPage, fsui.Icon("netplay-settings", "pkg:workspace"), ) self.add_page( "WHDLoad", WHDLoadSettingsPage, fsui.Icon("hd", "pkg:launcher") ) # self.add_page( # gettext("Experimental Features"), ExperimentalFeaturesPage, # fsui.Icon("settings", "pkg:workspace")) # self.add_page( # gettext("Maintenance"), MaintenanceSettingsPage, # fsui.Icon("maintenance", "pkg:workspace")) self.add_page( "{} Arcade".format(fsgs.product), ArcadeSettingsPage, fsui.Icon("fs-uae-arcade", "pkg:launcher"), bold=True, ) # Old texts # gettext("Video Synchronization") # gettext("Synchronization") gettext("Advanced") last_index = self.get_page_index_by_title( LauncherSettings.get("last_settings_page") ) index = last_index or index self.list_view.set_index(index) defaults_button = fsui.Button(self, gettext("Reset to Defaults")) defaults_button.activated.connect(self.__defaults_activated) self.button_layout.insert(0, defaults_button, fill=True) defaults_label = fsui.Label( self, gettext("Choices marked with (*) is the default setting") ) self.button_layout.insert(1, defaults_label, margin_left=20) self.set_size((940, 560)) # self.center_on_parent() self.closed.connect(self.__closed) self.page_changed.connect(self.__page_changed)
def __init__(self, parent): fsui.Panel.__init__(self, parent) Skin.set_background_color(self) self.layout = fsui.HorizontalLayout() vert_layout = fsui.VerticalLayout() self.layout.add(vert_layout, fill=True, expand=True) hor_layout = fsui.HorizontalLayout() vert_layout.add(hor_layout, fill=True) label_stand_in = fsui.Panel(self) tw, th = label_stand_in.measure_text("Games") label_stand_in.set_min_height(th) hor_layout.add(label_stand_in, margin_top=10, margin_bottom=10) hor_layout.add(NewButton(self), margin_left=10, margin_right=10) game_list_selector = GameListSelector(self) game_list_selector.set_min_width(250) game_list_selector.setMaximumWidth(250) game_list_selector.changed.connect(self.on_game_list_changed) hor_layout.add(game_list_selector, expand=False, margin_left=10) self.text_field = fsui.TextField( self, LauncherSettings.get("config_search")) self.text_field.on_changed = self.on_search_changed if VariantsBrowser.use_horizontal_layout(): # window is big enough to use fixed size # self.text_field.set_min_width(210) self.text_field.set_min_width(229) hor_layout.add( self.text_field, expand=False, margin=10, margin_top=0, margin_bottom=0) else: hor_layout.add( self.text_field, expand=True, margin=10, margin_top=0, margin_bottom=0) # self.refresh_button = IconButton(self, "refresh_button.png") # self.refresh_button.set_tooltip( # gettext("Refresh Game Configurations from Online Database")) # self.refresh_button.activated.connect(self.on_refresh_button) # hor_layout.add( # self.refresh_button, margin=10, margin_top=0, margin_bottom=0) self.configurations_browser = ConfigurationsBrowser(self) vert_layout.add( self.configurations_browser, fill=True, expand=3, margin=10) self.variants_panel = fsui.Panel(self) vert_layout.add(self.variants_panel, fill=True, expand=False, margin=10, margin_top=20) self.variants_panel.layout = fsui.HorizontalLayout() self.variants_browser = VariantsBrowser(self.variants_panel) # Do not use fill=True with the default OS X theme at least, # if you do the item will be rendered with the old Aqua look self.variants_panel.layout.add( self.variants_browser, fill=False, expand=True) # for rating in [1, 4, 5]: # button = RatingButton(self.variants_panel, rating) # self.variants_panel.layout.add(button, margin_left=5, fill=True) self.variants_panel.layout.add( RatingChoice(self.variants_panel), margin_left=5, fill=True) self.config_panel = fsui.Panel(self) vert_layout.add(self.config_panel, fill=True, expand=False, margin_bottom=10, margin_top=20) self.config_panel.layout = fsui.VerticalLayout() self.config_group = ConfigGroup(self.config_panel, new_button=False) self.config_panel.layout.add(self.config_group, fill=True, expand=True) LauncherSettings.add_listener(self) self.on_setting("parent_uuid", LauncherSettings.get("parent_uuid"))
def save_config(): print("SaveButton.save_config") database = Database.get_instance() name = LauncherSettings.get("config_name").strip() if not name: print("no config_name") # FIXME: notify user return file_name = name + ".fs-uae" path = os.path.join(FSGSDirectories.get_configurations_dir(), file_name) with io.open(path, "w", encoding="UTF-8") as f: f.write("# FS-UAE configuration saved by FS-UAE Launcher\n") f.write("# Last saved: {0}\n".format( datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S"))) f.write("\n[fs-uae]\n") keys = sorted(fsgs.config.values.keys()) for key in keys: value = LauncherConfig.get(key) if key.startswith("__"): continue if key in LauncherConfig.no_save_keys_set: continue # elif key == "joystick_port_2_mode" and value == "nothing": # continue # elif key == "joystick_port_3_mode" and value == "nothing": # continue if value == LauncherConfig.default_config.get(key, ""): continue if value: f.write("{0} = {1}\n".format(key, value)) # scanner = ConfigurationScanner() # search = ConfigurationScanner.create_configuration_search(name) # name = scanner.create_configuration_name(name) # print("adding", path) # # deleting the path from the database first in case it already exists # database.delete_configuration(path=path) # database.delete_file(path=path) # database.add_file(path=path) # database.add_configuration( # path=path, uuid="", name=name, scan=0, search=search) file_database = FileDatabase.get_instance() scanner = ConfigurationScanner() print("[save config] adding config", path) file_database.delete_file(path=path) with open(path, "rb") as f: sha1 = hashlib.sha1(f.read()).hexdigest() file_database.add_file(path=path, sha1=sha1) game_id = database.add_configuration( path=path, name=scanner.create_configuration_name(name)) database.update_game_search_terms(game_id, scanner.create_search_terms(name)) database.commit() file_database.commit() LauncherSettings.set("__config_refresh", str(time.time())) # Settings.set("config_changed", "0") LauncherConfig.set("__changed", "0")
def get(key): return LauncherSettings.get(key)
def save_config(): print("SaveButton.save_config") database = Database.get_instance() name = LauncherSettings.get("config_name").strip() if not name: print("no config_name") # FIXME: notify user return file_name = name + ".fs-uae" path = os.path.join( FSGSDirectories.get_configurations_dir(), file_name) with io.open(path, "w", encoding="UTF-8") as f: f.write("# FS-UAE configuration saved by FS-UAE Launcher\n") f.write("# Last saved: {0}\n".format( datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S"))) f.write("\n[fs-uae]\n") keys = sorted(fsgs.config.values.keys()) for key in keys: value = LauncherConfig.get(key) if key.startswith("__"): continue if key in LauncherConfig.no_save_keys_set: continue # elif key == "joystick_port_2_mode" and value == "nothing": # continue # elif key == "joystick_port_3_mode" and value == "nothing": # continue if value == LauncherConfig.default_config.get(key, ""): continue if value: f.write("{0} = {1}\n".format(key, value)) # scanner = ConfigurationScanner() # search = ConfigurationScanner.create_configuration_search(name) # name = scanner.create_configuration_name(name) # print("adding", path) # # deleting the path from the database first in case it already exists # database.delete_configuration(path=path) # database.delete_file(path=path) # database.add_file(path=path) # database.add_configuration( # path=path, uuid="", name=name, scan=0, search=search) file_database = FileDatabase.get_instance() scanner = ConfigurationScanner() print("[save config] adding config", path) file_database.delete_file(path=path) with open(path, "rb") as f: sha1 = hashlib.sha1(f.read()).hexdigest() file_database.add_file(path=path, sha1=sha1) game_id = database.add_game( path=path, name=scanner.create_configuration_name(name)) database.update_game_search_terms( game_id, scanner.create_search_terms(name)) database.commit() file_database.commit() LauncherSettings.set("__config_refresh", str(time.time())) # Settings.set("config_changed", "0") LauncherConfig.set("__changed", "0")
def __init__(self, parent): super().__init__(parent) icon = fsui.Icon("video-settings", "pkg:workspace") gettext("Video Synchronization Settings") title = gettext("Synchronization") subtitle = gettext("Synchronize FS-UAE with your display for " "smooth video") self.add_header(icon, title, subtitle) label = fsui.MultiLineLabel(self, gettext( "Enabling the following option will synchronize the emulation " "to the display when the emulation refresh rate matches the" "screen refresh rate."), 640) self.layout.add(label, fill=True, margin_top=0) self.video_sync_group = self.add_option("video_sync") self.low_latency_group = self.add_option("low_latency_vsync") # label = fsui.MultiLineLabel(self, gettext( # "Enabling the following option will prevent tearing from " # "occurring, but will also use more CPU. Input latency " # "may become slightly higher."), 640) # self.layout.add(label, fill=True, margin_top=0) # self.vblank_checkbox = fsui.HeadingCheckBox(self, gettext( # "Synchronize buffer swaps with display (prevents tearing)")) # self.layout.add(self.vblank_checkbox, margin_top=20) self.sync_method_label = fsui.MultiLineLabel(self, gettext( "Depending on your OS and OpenGL drivers, synchronizing " "can use needlessly much CPU (esp. applies to " "Linux). You can experiment with different sync methods " "to improve performance."), 640) self.layout.add(self.sync_method_label, fill=True, margin_top=20) self.sync_method_group = self.add_option("video_sync_method") # self.smooth_label = fsui.MultiLineLabel(self, gettext( # "In order to get really smooth Amiga graphics, you need to " # "enable the following option, and also make sure your display " # "is running at 50Hz (for PAL) or 60Hz (for NTSC)."), 640) # self.layout.add(self.smooth_label, fill=True, margin_top=20) # self.full_sync_checkbox = fsui.HeadingCheckBox(self, gettext( # "Also synchronize emulation with display when possible " # "(smooth scrolling)")) # self.layout.add(self.full_sync_checkbox, margin_top=20) self.layout.add_spacer(0, expand=True) hori_layout = fsui.HorizontalLayout() self.layout.add(hori_layout, fill=True, margin_top=10) hori_layout.add(fsui.ImageView(self, fsui.Image( "launcher:res/16/world_link.png"))) label = fsui.URLLabel(self, gettext( "How to achieve perfectly smooth scrolling"), "http://fs-uae.net/perfectly-smooth-scrolling") hori_layout.add(label, margin_left=6) text = gettext( "Synchronizing with the display can in some cases cause " "increased stuttering and low frame rates (esp. in some Linux " "desktop environments with compositing enabled).") link = (" <a href='https://fs-uae.net/video-synchronization-issues'>" "{0}</a>.".format(gettext("Read more"))) label = fsui.MultiLineLabel(self, text + link, min_width=640) self.layout.add(label, fill=True, margin_top=20) LauncherSettings.add_listener(self) for key in ["video_sync"]: self.on_setting(key, LauncherSettings.get(key))
def create_group( cls, parent, name, description=None, help_button=True, thin=False ): group = fsui.Group(parent) group.layout = fsui.HorizontalLayout() if thin: thin_layout = fsui.VerticalLayout() thin_layout.add(group.layout, fill=True) option = Option.get(name) if description == "": description = gettext(option["description"]) if description: group.label = fsui.Label(group, description + ":") group.layout.add(group.label, margin_right=10) group.layout.add(OverrideWarning(group, name), margin_right=10) if thin: group.layout = fsui.HorizontalLayout() if description: thin_layout.add(group.layout, fill=True, margin_top=6) else: thin_layout.add(group.layout, fill=True, margin_top=0) choice_values = [] if description: default_tmpl = "{0} (*)" # default_tmpl = "Default - {0}" else: default_tmpl = "{0} (*)" # default_tmpl = "Default - {0}" if option["type"].lower() == "boolean": if option["default"] == "1": default_desc = gettext(default_tmpl).format(gettext("On")) elif option["default"] == "0": default_desc = gettext(default_tmpl).format(gettext("Off")) else: default_desc = gettext("Default") choice_values.append(("", default_desc)) choice_values.append(("1", gettext("On"))) choice_values.append(("0", gettext("Off"))) elif option["type"].lower() == "choice": for i, value in enumerate(option["values"]): if option["default"] == value[0]: default_desc = gettext(default_tmpl).format( gettext(value[1]) ) break else: default_desc = gettext("Default") choice_values.append(("", default_desc)) for option in option["values"]: choice_values.append((option[0], gettext(option[1]))) elif option["type"].lower() == "string": def on_changed(): val = text_field.get_text() LauncherSettings.set(name, val.strip()) text_field = fsui.TextField(group) # text_field.set_min_width(400) text_field.set_text(LauncherSettings.get(name)) text_field.on_changed = on_changed group.layout.add(text_field, expand=True) elif ( option["type"].lower() == "integer" and "min" in option and "max" in option ): current = LauncherSettings.get(name) if name == Option.LAUNCHER_FONT_SIZE: font = app.qapplication.font() Option.get(Option.LAUNCHER_FONT_SIZE)[ "default" ] = font.pointSize() current_int = int(option["default"]) if current: try: current_int = int(current) except ValueError: pass current_int = max(option["min"], min(option["max"], current_int)) check_box = fsui.CheckBox(group, gettext("Default")) spin_ctrl = fsui.SpinCtrl( group, option["min"], option["max"], current_int ) if current == "": check_box.check() spin_ctrl.disable() def on_checkbox(): if check_box.is_checked(): spin_ctrl.set_value(int(option["default"])) spin_ctrl.disable() LauncherSettings.set(name, "") else: spin_ctrl.enable() check_box.on_changed = on_checkbox def on_spin(): val = spin_ctrl.get_value() val = max(option["min"], min(option["max"], val)) LauncherSettings.set(name, str(val)) spin_ctrl.on_changed = on_spin group.layout.add_spacer(0, expand=True) group.layout.add(check_box) group.layout.add(spin_ctrl, margin_left=10) if choice_values: def on_changed(): index = choice.get_index() LauncherSettings.set(name, choice_values[index][0]) choice_labels = [x[1] for x in choice_values] choice = fsui.Choice(group, choice_labels) current = LauncherSettings.get(name) for i, value in enumerate(choice_values): if current == value[0]: choice.set_index(i) break choice.on_changed = on_changed if thin: group.layout.add(choice, expand=True) else: group.layout.add_spacer(0, expand=True) group.layout.add(choice) group.widget = choice if help_button: option_url = "https://fs-uae.net/docs/options/" + name.replace( "_", "-" ) group.help_button = HelpButton(parent, option_url) group.layout.add(group.help_button, margin_left=10) if thin: group.layout = thin_layout return group