예제 #1
0
        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);
        }
예제 #2
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);
                });
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
            });
        }
예제 #5
0
        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;
        }
예제 #6
0
        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();
        }
예제 #7
0
        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);
        }
예제 #8
0
        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();
                });
            }
        }
예제 #9
0
        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();
                });
            }
        }