private static void End() { if (_ending) { return; } _ending = true; if (_gameLoaded) { ApplicationLibrary.LoadAndSaveMetaData(_device.System.TitleIdText, appMetadata => { DateTime lastPlayedDateTime = DateTime.Parse(appMetadata.LastPlayed); double sessionTimePlayed = DateTime.UtcNow.Subtract(lastPlayedDateTime).TotalSeconds; appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero); }); } Profile.FinishProfiling(); _device?.Dispose(); _audioOut?.Dispose(); Logger.Shutdown(); Environment.Exit(0); }
private static void UpdateGameMetadata(string titleId) { if (_gameLoaded) { ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => { DateTime lastPlayedDateTime = DateTime.Parse(appMetadata.LastPlayed); double sessionTimePlayed = DateTime.UtcNow.Subtract(lastPlayedDateTime).TotalSeconds; appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero); }); } }
internal static async Task UpdateGameTable() { if (_updatingGameTable) { return; } _updatingGameTable = true; _tableStore.Clear(); await Task.Run(() => ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, _device.System.KeySet, _device.System.State.DesiredTitleLanguage)); _updatingGameTable = false; }
private void FavToggle_Toggled(object sender, ToggledArgs args) { _tableStore.GetIter(out TreeIter treeIter, new TreePath(args.Path)); string titleId = _tableStore.GetValue(treeIter, 2).ToString().Split("\n")[1].ToLower(); bool newToggleValue = !(bool)_tableStore.GetValue(treeIter, 0); _tableStore.SetValue(treeIter, 0, newToggleValue); ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => { appMetadata.Favorite = newToggleValue; }); }
internal static async Task UpdateGameTable() { if (_updatingGameTable) { return; } _updatingGameTable = true; _tableStore.Clear(); await Task.Run(() => ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, _virtualFileSystem, ConfigurationState.Instance.System.Language)); _updatingGameTable = false; }
internal static void UpdateGameTable() { if (_updatingGameTable) { return; } _updatingGameTable = true; _tableStore.Clear(); Thread applicationLibraryThread = new Thread(() => { ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, _virtualFileSystem, ConfigurationState.Instance.System.Language); _updatingGameTable = false; }); applicationLibraryThread.Name = "GUI.ApplicationLibraryThread"; applicationLibraryThread.IsBackground = true; applicationLibraryThread.Start(); }
private MainWindow(Builder builder) : base(builder.GetObject("_mainWin").Handle) { builder.Autoconnect(this); // Apply custom theme if needed. ThemeHelper.ApplyTheme(); // Sets overridden fields. int monitorWidth = Display.PrimaryMonitor.Geometry.Width * Display.PrimaryMonitor.ScaleFactor; int monitorHeight = Display.PrimaryMonitor.Geometry.Height * Display.PrimaryMonitor.ScaleFactor; DefaultWidth = monitorWidth < 1280 ? monitorWidth : 1280; DefaultHeight = monitorHeight < 760 ? monitorHeight : 760; Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png"); Title = $"Ryujinx {Program.Version}"; // Hide emulation context status bar. _statusBar.Hide(); // Instanciate HLE objects. _virtualFileSystem = VirtualFileSystem.CreateInstance(); _contentManager = new ContentManager(_virtualFileSystem); _userChannelPersistence = new UserChannelPersistence(); // Instanciate GUI objects. _applicationLibrary = new ApplicationLibrary(_virtualFileSystem); _uiHandler = new GtkHostUiHandler(this); _deviceExitStatus = new AutoResetEvent(false); WindowStateEvent += WindowStateEvent_Changed; DeleteEvent += Window_Close; _applicationLibrary.ApplicationAdded += Application_Added; _applicationLibrary.ApplicationCountUpdated += ApplicationCount_Updated; _gameTable.ButtonReleaseEvent += Row_Clicked; _fullScreen.Activated += FullScreen_Toggled; GlRenderer.StatusUpdatedEvent += Update_StatusBar; if (ConfigurationState.Instance.Ui.StartFullscreen) { _startFullScreen.Active = true; } _stopEmulation.Sensitive = false; _simulateWakeUpMessage.Sensitive = false; if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) { _favToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) { _iconToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) { _appToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) { _developerToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) { _versionToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) { _timePlayedToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) { _lastPlayedToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) { _fileExtToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) { _fileSizeToggle.Active = true; } if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) { _pathToggle.Active = true; } _favToggle.Toggled += Fav_Toggled; _iconToggle.Toggled += Icon_Toggled; _appToggle.Toggled += App_Toggled; _developerToggle.Toggled += Developer_Toggled; _versionToggle.Toggled += Version_Toggled; _timePlayedToggle.Toggled += TimePlayed_Toggled; _lastPlayedToggle.Toggled += LastPlayed_Toggled; _fileExtToggle.Toggled += FileExt_Toggled; _fileSizeToggle.Toggled += FileSize_Toggled; _pathToggle.Toggled += Path_Toggled; _gameTable.Model = _tableStore = new ListStore( typeof(bool), typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(BlitStruct <ApplicationControlProperty>)); _tableStore.SetSortFunc(5, SortHelper.TimePlayedSort); _tableStore.SetSortFunc(6, SortHelper.LastPlayedSort); _tableStore.SetSortFunc(8, SortHelper.FileSizeSort); int columnId = ConfigurationState.Instance.Ui.ColumnSort.SortColumnId; bool ascending = ConfigurationState.Instance.Ui.ColumnSort.SortAscending; _tableStore.SetSortColumnId(columnId, ascending ? SortType.Ascending : SortType.Descending); _gameTable.EnableSearch = true; _gameTable.SearchColumn = 2; UpdateColumns(); UpdateGameTable(); ConfigurationState.Instance.Ui.GameDirs.Event += (sender, args) => { if (args.OldValue != args.NewValue) { UpdateGameTable(); } }; Task.Run(RefreshFirmwareLabel); }
internal void LoadApplication(string path) { if (_gameLoaded) { GtkDialog.CreateDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again."); } else { Logger.RestartTime(); HLE.Switch device = InitializeSwitchInstance(); // TODO: Move this somewhere else + reloadable? Graphics.Gpu.GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath; if (Directory.Exists(path)) { string[] romFsFiles = Directory.GetFiles(path, "*.istorage"); if (romFsFiles.Length == 0) { romFsFiles = Directory.GetFiles(path, "*.romfs"); } if (romFsFiles.Length > 0) { Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS."); device.LoadCart(path, romFsFiles[0]); } else { Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS."); device.LoadCart(path); } } else if (File.Exists(path)) { switch (System.IO.Path.GetExtension(path).ToLowerInvariant()) { case ".xci": Logger.PrintInfo(LogClass.Application, "Loading as XCI."); device.LoadXci(path); break; case ".nca": Logger.PrintInfo(LogClass.Application, "Loading as NCA."); device.LoadNca(path); break; case ".nsp": case ".pfs0": Logger.PrintInfo(LogClass.Application, "Loading as NSP."); device.LoadNsp(path); break; default: Logger.PrintInfo(LogClass.Application, "Loading as homebrew."); try { device.LoadProgram(path); } catch (ArgumentOutOfRangeException) { Logger.PrintError(LogClass.Application, "The file which you have specified is unsupported by Ryujinx."); } break; } } else { Logger.PrintWarning(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file."); End(device); } _emulationContext = device; _deviceExitStatus.Reset(); #if MACOS_BUILD CreateGameWindow(device); #else var windowThread = new Thread(() => { CreateGameWindow(device); }) { Name = "GUI.WindowThread" }; windowThread.Start(); #endif _gameLoaded = true; _stopEmulation.Sensitive = true; _firmwareInstallFile.Sensitive = false; _firmwareInstallDirectory.Sensitive = false; DiscordIntegrationModule.SwitchToPlayingState(device.System.TitleIdText, device.System.TitleName); ApplicationLibrary.LoadAndSaveMetaData(device.System.TitleIdText, appMetadata => { appMetadata.LastPlayed = DateTime.UtcNow.ToString(); }); } }
internal void LoadApplication(string path) { if (_gameLoaded) { GtkDialog.CreateInfoDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again."); } else { if (ConfigurationState.Instance.Logger.EnableDebug.Value) { MessageDialog debugWarningDialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null) { Title = "Ryujinx - Warning", Text = "You have debug logging enabled, which is designed to be used by developers only.", SecondaryText = "For optimal performance, it's recommended to disable debug logging. Would you like to disable debug logging now?" }; if (debugWarningDialog.Run() == (int)ResponseType.Yes) { ConfigurationState.Instance.Logger.EnableDebug.Value = false; SaveConfig(); } debugWarningDialog.Dispose(); } if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value)) { MessageDialog shadersDumpWarningDialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null) { Title = "Ryujinx - Warning", Text = "You have shader dumping enabled, which is designed to be used by developers only.", SecondaryText = "For optimal performance, it's recommended to disable shader dumping. Would you like to disable shader dumping now?" }; if (shadersDumpWarningDialog.Run() == (int)ResponseType.Yes) { ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = ""; SaveConfig(); } shadersDumpWarningDialog.Dispose(); } Logger.RestartTime(); HLE.Switch device = InitializeSwitchInstance(); UpdateGraphicsConfig(); Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {_contentManager.GetCurrentFirmwareVersion()?.VersionString}"); if (Directory.Exists(path)) { string[] romFsFiles = Directory.GetFiles(path, "*.istorage"); if (romFsFiles.Length == 0) { romFsFiles = Directory.GetFiles(path, "*.romfs"); } if (romFsFiles.Length > 0) { Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS."); device.LoadCart(path, romFsFiles[0]); } else { Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS."); device.LoadCart(path); } } else if (File.Exists(path)) { switch (System.IO.Path.GetExtension(path).ToLowerInvariant()) { case ".xci": Logger.Info?.Print(LogClass.Application, "Loading as XCI."); device.LoadXci(path); break; case ".nca": Logger.Info?.Print(LogClass.Application, "Loading as NCA."); device.LoadNca(path); break; case ".nsp": case ".pfs0": Logger.Info?.Print(LogClass.Application, "Loading as NSP."); device.LoadNsp(path); break; default: Logger.Info?.Print(LogClass.Application, "Loading as homebrew."); try { device.LoadProgram(path); } catch (ArgumentOutOfRangeException) { Logger.Error?.Print(LogClass.Application, "The file which you have specified is unsupported by Ryujinx."); } break; } } else { Logger.Warning?.Print(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file."); device.Dispose(); return; } _emulationContext = device; _deviceExitStatus.Reset(); #if MACOS_BUILD CreateGameWindow(device); #else Thread windowThread = new Thread(() => { CreateGameWindow(device); }) { Name = "GUI.WindowThread" }; windowThread.Start(); #endif _gameLoaded = true; _stopEmulation.Sensitive = true; _firmwareInstallFile.Sensitive = false; _firmwareInstallDirectory.Sensitive = false; DiscordIntegrationModule.SwitchToPlayingState(device.Application.TitleIdText, device.Application.TitleName); ApplicationLibrary.LoadAndSaveMetaData(device.Application.TitleIdText, appMetadata => { appMetadata.LastPlayed = DateTime.UtcNow.ToString(); }); } }