コード例 #1
0
ファイル: MainWindow.cs プロジェクト: Desmondchaser27/Ryujinx
 private void Window_Close(object sender, DeleteEventArgs args)
 {
     if (!_gameLoaded || GtkDialog.CreateExitDialog())
     {
         End();
     }
     else
     {
         args.RetVal = true;
     }
 }
コード例 #2
0
 private void Window_Close(object sender, DeleteEventArgs args)
 {
     if (!_gameLoaded || !ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
     {
         End();
     }
     else
     {
         args.RetVal = true;
     }
 }
コード例 #3
0
        private void AddUpdate(string path, bool showErrorDialog = true)
        {
            if (File.Exists(path))
            {
                using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());

                    try
                    {
                        (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0);

                        if (controlNca != null && patchNca != null)
                        {
                            ApplicationControlProperty controlData = new ApplicationControlProperty();

                            controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(out IFile nacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
                            nacpFile.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();

                            RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersion.ToString()} - {path}");
                            radioButton.JoinGroup(_noUpdateRadioButton);

                            _availableUpdatesBox.Add(radioButton);
                            _radioButtonToPathDictionary.Add(radioButton, path);

                            radioButton.Show();
                            radioButton.Active = true;
                        }
                        else
                        {
                            GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!");
                        }
                    }
                    catch (InvalidDataException exception)
                    {
                        Logger.Error?.Print(LogClass.Application, $"{exception.Message}. Errored File: {path}");

                        if (showErrorDialog)
                        {
                            GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
                        }
                    }
                    catch (MissingKeyException exception)
                    {
                        Logger.Error?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {path}");

                        if (showErrorDialog)
                        {
                            GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}");
                        }
                    }
                }
            }
        }
コード例 #4
0
        private bool TryFindSaveData(string titleName, ulong titleId, BlitStruct <ApplicationControlProperty> controlHolder, SaveDataFilter filter, out ulong saveDataId)
        {
            saveDataId = default;

            Result result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);

            if (ResultFs.TargetNotFound.Includes(result))
            {
                // Savedata was not found. Ask the user if they want to create it
                using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null)
                      {
                          Title          = "PangoNX Debugger",
                          Icon           = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
                          Text           = $"There is no savedata for {titleName} [{titleId:x16}]",
                          SecondaryText  = "Would you like to create savedata for this game?",
                          WindowPosition = WindowPosition.Center
                      };

                if (messageDialog.Run() != (int)ResponseType.Yes)
                {
                    return(false);
                }

                ref ApplicationControlProperty control = ref controlHolder.Value;

                if (LibHac.Util.IsEmpty(controlHolder.ByteSpan))
                {
                    // If the current application doesn't have a loaded control property, create a dummy one
                    // and set the savedata sizes so a user savedata will be created.
                    control = ref new BlitStruct <ApplicationControlProperty>(1).Value;

                    // The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
                    control.UserAccountSaveDataSize        = 0x4000;
                    control.UserAccountSaveDataJournalSize = 0x4000;

                    Logger.PrintWarning(LogClass.Application,
                                        "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
                }

                Uid user = new Uid(1, 0);

                result = EnsureApplicationSaveData(_virtualFileSystem.FsClient, out _, new TitleId(titleId), ref control, ref user);

                if (result.IsFailure())
                {
                    GtkDialog.CreateErrorDialog($"There was an error creating the specified savedata: {result.ToStringWithName()}");

                    return(false);
                }

                // Try to find the savedata again after creating it
                result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, ref filter);
            }
コード例 #5
0
        public void HandleScreenState(KeyboardState keyboard)
        {
            bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11) ||
                                    ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft) ||
                                      keyboard.IsKeyDown(OpenTK.Input.Key.AltRight)) &&
                                     keyboard.IsKeyDown(OpenTK.Input.Key.Enter)) ||
                                    keyboard.IsKeyDown(OpenTK.Input.Key.Escape);

            bool fullScreenToggled = ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen);

            if (toggleFullscreen != _toggleFullscreen)
            {
                if (toggleFullscreen)
                {
                    if (fullScreenToggled)
                    {
                        ParentWindow.Unfullscreen();
                        (Toplevel as MainWindow)?.ToggleExtraWidgets(true);
                    }
                    else
                    {
                        if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape))
                        {
                            if (GtkDialog.CreateExitDialog())
                            {
                                Exit();
                            }
                        }
                        else
                        {
                            ParentWindow.Fullscreen();
                            (Toplevel as MainWindow)?.ToggleExtraWidgets(false);
                        }
                    }
                }
            }

            _toggleFullscreen = toggleFullscreen;

            bool toggleDockedMode = keyboard.IsKeyDown(OpenTK.Input.Key.F9);

            if (toggleDockedMode != _toggleDockedMode)
            {
                if (toggleDockedMode)
                {
                    ConfigurationState.Instance.System.EnableDockedMode.Value =
                        !ConfigurationState.Instance.System.EnableDockedMode.Value;
                }
            }

            _toggleDockedMode = toggleDockedMode;
        }
コード例 #6
0
        private void Update_Pressed(object sender, EventArgs args)
        {
            string ryuUpdater = System.IO.Path.Combine(new VirtualFileSystem().GetBasePath(), "RyuUpdater.exe");

            try
            {
                Process.Start(new ProcessStartInfo(ryuUpdater, "/U")
                {
                    UseShellExecute = true
                });
            }
            catch (System.ComponentModel.Win32Exception)
            {
                GtkDialog.CreateErrorDialog("Update canceled by user or updater was not found");
            }
        }
コード例 #7
0
ファイル: DlcWindow.cs プロジェクト: ski982/Ryujinx-1
        private Nca TryCreateNca(IStorage ncaStorage, string containerPath)
        {
            try
            {
                return(new Nca(_virtualFileSystem.KeySet, ncaStorage));
            }
            catch (InvalidDataException exception)
            {
                Logger.Error?.Print(LogClass.Application, $"{exception.Message}. Errored File: {containerPath}");

                GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add DLC Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
            }
            catch (MissingKeyException exception)
            {
                Logger.Error?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {containerPath}");

                GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add DLC Failed!", $"Your key set is missing a key with the name: {exception.Name}");
            }

            return(null);
        }
コード例 #8
0
        public void HandleScreenState(KeyboardState keyboard)
        {
            bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11) ||
                                    ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft) ||
                                      keyboard.IsKeyDown(OpenTK.Input.Key.AltRight)) &&
                                     keyboard.IsKeyDown(OpenTK.Input.Key.Enter)) ||
                                    keyboard.IsKeyDown(OpenTK.Input.Key.Escape);

            bool fullScreenToggled = ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen);

            if (toggleFullscreen != _toggleFullscreen)
            {
                if (toggleFullscreen)
                {
                    if (fullScreenToggled)
                    {
                        ParentWindow.Unfullscreen();
                        (Toplevel as MainWindow)?.ToggleExtraWidgets(true);
                    }
                    else
                    {
                        if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape))
                        {
                            if (GtkDialog.CreateChoiceDialog("Ryujinx - Exit", "Are you sure you want to stop emulation?", "All unsaved data will be lost!"))
                            {
                                Exit();
                            }
                        }
                        else
                        {
                            ParentWindow.Fullscreen();
                            (Toplevel as MainWindow)?.ToggleExtraWidgets(false);
                        }
                    }
                }
            }

            _toggleFullscreen = toggleFullscreen;
        }
コード例 #9
0
ファイル: ControllerWindow.cs プロジェクト: valx76/Ryujinx
        private void ProfileRemove_Activated(object sender, EventArgs args)
        {
            ((ToggleButton)sender).SetStateFlags(0, true);

            if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null)
            {
                return;
            }

            MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are your sure you want to continue?");

            if (confirmDialog.Run() == (int)ResponseType.Yes)
            {
                string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);

                if (File.Exists(path))
                {
                    File.Delete(path);
                }

                SetProfiles();
            }
        }
コード例 #10
0
        public static void LoadApplications(List <string> appDirs, VirtualFileSystem virtualFileSystem, Language desiredTitleLanguage)
        {
            int numApplicationsFound  = 0;
            int numApplicationsLoaded = 0;

            _loadingError         = false;
            _virtualFileSystem    = virtualFileSystem;
            _desiredTitleLanguage = desiredTitleLanguage;

            // Builds the applications list with paths to found applications
            List <string> applications = new List <string>();

            foreach (string appDir in appDirs)
            {
                if (!Directory.Exists(appDir))
                {
                    Logger.PrintWarning(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\"");

                    continue;
                }

                foreach (string app in GetFilesInDirectory(appDir))
                {
                    if ((Path.GetExtension(app).ToLower() == ".nsp") ||
                        (Path.GetExtension(app).ToLower() == ".pfs0") ||
                        (Path.GetExtension(app).ToLower() == ".xci") ||
                        (Path.GetExtension(app).ToLower() == ".nca") ||
                        (Path.GetExtension(app).ToLower() == ".nro") ||
                        (Path.GetExtension(app).ToLower() == ".nso"))
                    {
                        applications.Add(app);
                        numApplicationsFound++;
                    }
                }
            }

            // Loops through applications list, creating a struct and then firing an event containing the struct for each application
            foreach (string applicationPath in applications)
            {
                double fileSize        = new FileInfo(applicationPath).Length * 0.000000000931;
                string titleName       = "Unknown";
                string titleId         = "0000000000000000";
                string developer       = "Unknown";
                string version         = "0";
                string saveDataPath    = null;
                byte[] applicationIcon = null;
                BlitStruct <ApplicationControlProperty> controlHolder = new BlitStruct <ApplicationControlProperty>(1);

                try
                {
                    using (FileStream file = new FileStream(applicationPath, FileMode.Open, FileAccess.Read))
                    {
                        if ((Path.GetExtension(applicationPath).ToLower() == ".nsp") ||
                            (Path.GetExtension(applicationPath).ToLower() == ".pfs0") ||
                            (Path.GetExtension(applicationPath).ToLower() == ".xci"))
                        {
                            try
                            {
                                PartitionFileSystem pfs;

                                bool isExeFs = false;

                                if (Path.GetExtension(applicationPath).ToLower() == ".xci")
                                {
                                    Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());

                                    pfs = xci.OpenPartition(XciPartitionType.Secure);
                                }
                                else
                                {
                                    pfs = new PartitionFileSystem(file.AsStorage());

                                    // If the NSP doesn't have a main NCA, decrement the number of applications found and then continue to the next application.
                                    bool hasMainNca = false;

                                    foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*"))
                                    {
                                        if (Path.GetExtension(fileEntry.FullPath).ToLower() == ".nca")
                                        {
                                            pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                            Nca nca       = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
                                            int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);

                                            if (nca.Header.ContentType == NcaContentType.Program && !nca.Header.GetFsHeader(dataIndex).IsPatchSection())
                                            {
                                                hasMainNca = true;

                                                break;
                                            }
                                        }
                                        else if (Path.GetFileNameWithoutExtension(fileEntry.FullPath) == "main")
                                        {
                                            isExeFs = true;
                                        }
                                    }

                                    if (!hasMainNca && !isExeFs)
                                    {
                                        numApplicationsFound--;

                                        continue;
                                    }
                                }

                                if (isExeFs)
                                {
                                    applicationIcon = _nspIcon;

                                    Result result = pfs.OpenFile(out IFile npdmFile, "/main.npdm".ToU8Span(), OpenMode.Read);

                                    if (ResultFs.PathNotFound.Includes(result))
                                    {
                                        Npdm npdm = new Npdm(npdmFile.AsStream());

                                        titleName = npdm.TitleName;
                                        titleId   = npdm.Aci0.TitleId.ToString("x16");
                                    }
                                }
                                else
                                {
                                    // Store the ControlFS in variable called controlFs
                                    GetControlFsAndTitleId(pfs, out IFileSystem controlFs, out titleId);

                                    ReadControlData(controlFs, controlHolder.ByteSpan);

                                    // Creates NACP class from the NACP file
                                    controlFs.OpenFile(out IFile controlNacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                    // Get the title name, title ID, developer name and version number from the NACP
                                    version = IsUpdateApplied(titleId, out string updateVersion) ? updateVersion : controlHolder.Value.DisplayVersion.ToString();

                                    GetNameIdDeveloper(ref controlHolder.Value, out titleName, out _, out developer);

                                    // Read the icon from the ControlFS and store it as a byte array
                                    try
                                    {
                                        controlFs.OpenFile(out IFile icon, $"/icon_{_desiredTitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                        using (MemoryStream stream = new MemoryStream())
                                        {
                                            icon.AsStream().CopyTo(stream);
                                            applicationIcon = stream.ToArray();
                                        }
                                    }
                                    catch (HorizonResultException)
                                    {
                                        foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
                                        {
                                            if (entry.Name == "control.nacp")
                                            {
                                                continue;
                                            }

                                            controlFs.OpenFile(out IFile icon, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                            using (MemoryStream stream = new MemoryStream())
                                            {
                                                icon.AsStream().CopyTo(stream);
                                                applicationIcon = stream.ToArray();
                                            }

                                            if (applicationIcon != null)
                                            {
                                                break;
                                            }
                                        }

                                        if (applicationIcon == null)
                                        {
                                            applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
                                        }
                                    }
                                }
                            }
                            catch (MissingKeyException exception)
                            {
                                applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;

                                Logger.PrintWarning(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
                            }
                            catch (InvalidDataException)
                            {
                                applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;

                                Logger.PrintWarning(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {applicationPath}");
                            }
                            catch (Exception exception)
                            {
                                Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
                                Logger.PrintDebug(LogClass.Application, exception.ToString());

                                numApplicationsFound--;
                                _loadingError = true;

                                continue;
                            }
                        }
                        else if (Path.GetExtension(applicationPath).ToLower() == ".nro")
                        {
                            BinaryReader reader = new BinaryReader(file);

                            byte[] Read(long position, int size)
                            {
                                file.Seek(position, SeekOrigin.Begin);

                                return(reader.ReadBytes(size));
                            }

                            try
                            {
                                file.Seek(24, SeekOrigin.Begin);

                                int assetOffset = reader.ReadInt32();

                                if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
                                {
                                    byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);

                                    long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
                                    long iconSize   = BitConverter.ToInt64(iconSectionInfo, 8);

                                    ulong nacpOffset = reader.ReadUInt64();
                                    ulong nacpSize   = reader.ReadUInt64();

                                    // Reads and stores game icon as byte array
                                    applicationIcon = Read(assetOffset + iconOffset, (int)iconSize);

                                    // Read the NACP data
                                    Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);

                                    // Get the title name, title ID, developer name and version number from the NACP
                                    version = controlHolder.Value.DisplayVersion.ToString();

                                    GetNameIdDeveloper(ref controlHolder.Value, out titleName, out titleId, out developer);
                                }
                                else
                                {
                                    applicationIcon = _nroIcon;
                                    titleName       = Path.GetFileNameWithoutExtension(applicationPath);
                                }
                            }
                            catch
                            {
                                Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");

                                numApplicationsFound--;

                                continue;
                            }
                        }
                        else if (Path.GetExtension(applicationPath).ToLower() == ".nca")
                        {
                            try
                            {
                                Nca nca       = new Nca(_virtualFileSystem.KeySet, new FileStream(applicationPath, FileMode.Open, FileAccess.Read).AsStorage());
                                int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);

                                if (nca.Header.ContentType != NcaContentType.Program || nca.Header.GetFsHeader(dataIndex).IsPatchSection())
                                {
                                    numApplicationsFound--;

                                    continue;
                                }
                            }
                            catch (InvalidDataException)
                            {
                                Logger.PrintWarning(LogClass.Application, $"The NCA header content type check has failed. This is usually because the header key is incorrect or missing. Errored File: {applicationPath}");
                            }
                            catch
                            {
                                Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");

                                numApplicationsFound--;
                                _loadingError = true;

                                continue;
                            }

                            applicationIcon = _ncaIcon;
                            titleName       = Path.GetFileNameWithoutExtension(applicationPath);
                        }
                        // If its an NSO we just set defaults
                        else if (Path.GetExtension(applicationPath).ToLower() == ".nso")
                        {
                            applicationIcon = _nsoIcon;
                            titleName       = Path.GetFileNameWithoutExtension(applicationPath);
                        }
                    }
                }
                catch (IOException exception)
                {
                    Logger.PrintWarning(LogClass.Application, exception.Message);

                    numApplicationsFound--;
                    _loadingError = true;

                    continue;
                }

                ApplicationMetadata appMetadata = LoadAndSaveMetaData(titleId);

                if (ulong.TryParse(titleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNum))
                {
                    SaveDataFilter filter = new SaveDataFilter();
                    filter.SetUserId(new UserId(1, 0));
                    filter.SetProgramId(new TitleId(titleIdNum));

                    Result result = virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);

                    if (result.IsSuccess())
                    {
                        saveDataPath = Path.Combine(virtualFileSystem.GetNandPath(), "user", "save", saveDataInfo.SaveDataId.ToString("x16"));
                    }
                }

                ApplicationData data = new ApplicationData
                {
                    Favorite      = appMetadata.Favorite,
                    Icon          = applicationIcon,
                    TitleName     = titleName,
                    TitleId       = titleId,
                    Developer     = developer,
                    Version       = version,
                    TimePlayed    = ConvertSecondsToReadableString(appMetadata.TimePlayed),
                    LastPlayed    = appMetadata.LastPlayed,
                    FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0, 1),
                    FileSize      = (fileSize < 1) ? (fileSize * 1024).ToString("0.##") + "MB" : fileSize.ToString("0.##") + "GB",
                    Path          = applicationPath,
                    SaveDataPath  = saveDataPath,
                    ControlHolder = controlHolder
                };

                numApplicationsLoaded++;

                OnApplicationAdded(new ApplicationAddedEventArgs()
                {
                    AppData = data
                });

                OnApplicationCountUpdated(new ApplicationCountUpdatedEventArgs()
                {
                    NumAppsFound  = numApplicationsFound,
                    NumAppsLoaded = numApplicationsLoaded
                });
            }

            OnApplicationCountUpdated(new ApplicationCountUpdatedEventArgs()
            {
                NumAppsFound  = numApplicationsFound,
                NumAppsLoaded = numApplicationsLoaded
            });

            if (_loadingError)
            {
                Gtk.Application.Invoke(delegate
                {
                    GtkDialog.CreateErrorDialog("One or more files encountered could not be loaded, check logs for more info.");
                });
            }
        }
コード例 #11
0
ファイル: ControllerWindow.cs プロジェクト: valx76/Ryujinx
        private InputConfig GetValues()
        {
            if (_inputDevice.ActiveId.StartsWith("keyboard"))
            {
                Enum.TryParse(_lStickUp.Label, out Key lStickUp);
                Enum.TryParse(_lStickDown.Label, out Key lStickDown);
                Enum.TryParse(_lStickLeft.Label, out Key lStickLeft);
                Enum.TryParse(_lStickRight.Label, out Key lStickRight);
                Enum.TryParse(_lStickButton.Label, out Key lStickButton);
                Enum.TryParse(_dpadUp.Label, out Key lDPadUp);
                Enum.TryParse(_dpadDown.Label, out Key lDPadDown);
                Enum.TryParse(_dpadLeft.Label, out Key lDPadLeft);
                Enum.TryParse(_dpadRight.Label, out Key lDPadRight);
                Enum.TryParse(_minus.Label, out Key lButtonMinus);
                Enum.TryParse(_l.Label, out Key lButtonL);
                Enum.TryParse(_zL.Label, out Key lButtonZl);
                Enum.TryParse(_lSl.Label, out Key lButtonSl);
                Enum.TryParse(_lSr.Label, out Key lButtonSr);

                Enum.TryParse(_rStickUp.Label, out Key rStickUp);
                Enum.TryParse(_rStickDown.Label, out Key rStickDown);
                Enum.TryParse(_rStickLeft.Label, out Key rStickLeft);
                Enum.TryParse(_rStickRight.Label, out Key rStickRight);
                Enum.TryParse(_rStickButton.Label, out Key rStickButton);
                Enum.TryParse(_a.Label, out Key rButtonA);
                Enum.TryParse(_b.Label, out Key rButtonB);
                Enum.TryParse(_x.Label, out Key rButtonX);
                Enum.TryParse(_y.Label, out Key rButtonY);
                Enum.TryParse(_plus.Label, out Key rButtonPlus);
                Enum.TryParse(_r.Label, out Key rButtonR);
                Enum.TryParse(_zR.Label, out Key rButtonZr);
                Enum.TryParse(_rSl.Label, out Key rButtonSl);
                Enum.TryParse(_rSr.Label, out Key rButtonSr);

                return(new KeyboardConfig
                {
                    Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
                    ControllerType = Enum.Parse <ControllerType>(_controllerType.ActiveId),
                    PlayerIndex = _playerIndex,
                    LeftJoycon = new NpadKeyboardLeft
                    {
                        StickUp = lStickUp,
                        StickDown = lStickDown,
                        StickLeft = lStickLeft,
                        StickRight = lStickRight,
                        StickButton = lStickButton,
                        DPadUp = lDPadUp,
                        DPadDown = lDPadDown,
                        DPadLeft = lDPadLeft,
                        DPadRight = lDPadRight,
                        ButtonMinus = lButtonMinus,
                        ButtonL = lButtonL,
                        ButtonZl = lButtonZl,
                        ButtonSl = lButtonSl,
                        ButtonSr = lButtonSr
                    },
                    RightJoycon = new NpadKeyboardRight
                    {
                        StickUp = rStickUp,
                        StickDown = rStickDown,
                        StickLeft = rStickLeft,
                        StickRight = rStickRight,
                        StickButton = rStickButton,
                        ButtonA = rButtonA,
                        ButtonB = rButtonB,
                        ButtonX = rButtonX,
                        ButtonY = rButtonY,
                        ButtonPlus = rButtonPlus,
                        ButtonR = rButtonR,
                        ButtonZr = rButtonZr,
                        ButtonSl = rButtonSl,
                        ButtonSr = rButtonSr
                    }
                });
            }

            if (_inputDevice.ActiveId.StartsWith("controller"))
            {
                Enum.TryParse(_lStickX.Label, out ControllerInputId lStickX);
                Enum.TryParse(_lStickY.Label, out ControllerInputId lStickY);
                Enum.TryParse(_lStickButton.Label, out ControllerInputId lStickButton);
                Enum.TryParse(_minus.Label, out ControllerInputId lButtonMinus);
                Enum.TryParse(_l.Label, out ControllerInputId lButtonL);
                Enum.TryParse(_zL.Label, out ControllerInputId lButtonZl);
                Enum.TryParse(_lSl.Label, out ControllerInputId lButtonSl);
                Enum.TryParse(_lSr.Label, out ControllerInputId lButtonSr);
                Enum.TryParse(_dpadUp.Label, out ControllerInputId lDPadUp);
                Enum.TryParse(_dpadDown.Label, out ControllerInputId lDPadDown);
                Enum.TryParse(_dpadLeft.Label, out ControllerInputId lDPadLeft);
                Enum.TryParse(_dpadRight.Label, out ControllerInputId lDPadRight);

                Enum.TryParse(_rStickX.Label, out ControllerInputId rStickX);
                Enum.TryParse(_rStickY.Label, out ControllerInputId rStickY);
                Enum.TryParse(_rStickButton.Label, out ControllerInputId rStickButton);
                Enum.TryParse(_a.Label, out ControllerInputId rButtonA);
                Enum.TryParse(_b.Label, out ControllerInputId rButtonB);
                Enum.TryParse(_x.Label, out ControllerInputId rButtonX);
                Enum.TryParse(_y.Label, out ControllerInputId rButtonY);
                Enum.TryParse(_plus.Label, out ControllerInputId rButtonPlus);
                Enum.TryParse(_r.Label, out ControllerInputId rButtonR);
                Enum.TryParse(_zR.Label, out ControllerInputId rButtonZr);
                Enum.TryParse(_rSl.Label, out ControllerInputId rButtonSl);
                Enum.TryParse(_rSr.Label, out ControllerInputId rButtonSr);

                return(new ControllerConfig
                {
                    Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
                    ControllerType = Enum.Parse <ControllerType>(_controllerType.ActiveId),
                    PlayerIndex = _playerIndex,
                    DeadzoneLeft = (float)_controllerDeadzoneLeft.Value,
                    DeadzoneRight = (float)_controllerDeadzoneRight.Value,
                    TriggerThreshold = (float)_controllerTriggerThreshold.Value,
                    LeftJoycon = new NpadControllerLeft
                    {
                        InvertStickX = _invertLStickX.Active,
                        StickX = lStickX,
                        InvertStickY = _invertLStickY.Active,
                        StickY = lStickY,
                        StickButton = lStickButton,
                        ButtonMinus = lButtonMinus,
                        ButtonL = lButtonL,
                        ButtonZl = lButtonZl,
                        ButtonSl = lButtonSl,
                        ButtonSr = lButtonSr,
                        DPadUp = lDPadUp,
                        DPadDown = lDPadDown,
                        DPadLeft = lDPadLeft,
                        DPadRight = lDPadRight
                    },
                    RightJoycon = new NpadControllerRight
                    {
                        InvertStickX = _invertRStickX.Active,
                        StickX = rStickX,
                        InvertStickY = _invertRStickY.Active,
                        StickY = rStickY,
                        StickButton = rStickButton,
                        ButtonA = rButtonA,
                        ButtonB = rButtonB,
                        ButtonX = rButtonX,
                        ButtonY = rButtonY,
                        ButtonPlus = rButtonPlus,
                        ButtonR = rButtonR,
                        ButtonZr = rButtonZr,
                        ButtonSl = rButtonSl,
                        ButtonSr = rButtonSr
                    }
                });
            }

            if (!_inputDevice.ActiveId.StartsWith("disabled"))
            {
                GtkDialog.CreateErrorDialog("Some fields entered where invalid and therefore your config was not saved.");
            }

            return(null);
        }
コード例 #12
0
        public void LoadApplication(string path)
        {
            if (_gameLoaded)
            {
                GtkDialog.CreateInfoDialog("A game has already been loaded", "Please close it first and try again.");
            }
            else
            {
                PerformanceCheck();

                Logger.RestartTime();

                InitializeSwitchInstance();

                UpdateGraphicsConfig();

                SystemVersion firmwareVersion = _contentManager.GetCurrentFirmwareVersion();

                bool isDirectory = Directory.Exists(path);

                if (!SetupValidator.CanStartApplication(_contentManager, path, out UserError userError))
                {
                    if (SetupValidator.CanFixStartApplication(_contentManager, path, userError, out firmwareVersion))
                    {
                        if (userError == UserError.NoFirmware)
                        {
                            string message = $"Would you like to install the firmware embedded in this game? (Firmware {firmwareVersion.VersionString})";

                            ResponseType responseDialog = (ResponseType)GtkDialog.CreateConfirmationDialog("No Firmware Installed", message).Run();

                            if (responseDialog != ResponseType.Yes)
                            {
                                UserErrorDialog.CreateUserErrorDialog(userError);

                                _emulationContext.Dispose();

                                return;
                            }
                        }

                        if (!SetupValidator.TryFixStartApplication(_contentManager, path, userError, out _))
                        {
                            UserErrorDialog.CreateUserErrorDialog(userError);

                            _emulationContext.Dispose();

                            return;
                        }

                        // Tell the user that we installed a firmware for them.
                        if (userError == UserError.NoFirmware)
                        {
                            firmwareVersion = _contentManager.GetCurrentFirmwareVersion();

                            RefreshFirmwareLabel();

                            string message = $"No installed firmware was found but Ryujinx was able to install firmware {firmwareVersion.VersionString} from the provided game.\nThe emulator will now start.";

                            GtkDialog.CreateInfoDialog($"Firmware {firmwareVersion.VersionString} was installed", message);
                        }
                    }
                    else
                    {
                        UserErrorDialog.CreateUserErrorDialog(userError);

                        _emulationContext.Dispose();

                        return;
                    }
                }

                Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {firmwareVersion?.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.");
                        _emulationContext.LoadCart(path, romFsFiles[0]);
                    }
                    else
                    {
                        Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
                        _emulationContext.LoadCart(path);
                    }
                }
                else if (File.Exists(path))
                {
                    switch (System.IO.Path.GetExtension(path).ToLowerInvariant())
                    {
                    case ".xci":
                        Logger.Info?.Print(LogClass.Application, "Loading as XCI.");
                        _emulationContext.LoadXci(path);
                        break;

                    case ".nca":
                        Logger.Info?.Print(LogClass.Application, "Loading as NCA.");
                        _emulationContext.LoadNca(path);
                        break;

                    case ".nsp":
                    case ".pfs0":
                        Logger.Info?.Print(LogClass.Application, "Loading as NSP.");
                        _emulationContext.LoadNsp(path);
                        break;

                    default:
                        Logger.Info?.Print(LogClass.Application, "Loading as homebrew.");
                        try
                        {
                            _emulationContext.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.");

                    _emulationContext.Dispose();

                    return;
                }

                _currentEmulatedGamePath = path;

                _deviceExitStatus.Reset();

                Translator.IsReadyForTranslation.Reset();
#if MACOS_BUILD
                CreateGameWindow();
#else
                Thread windowThread = new Thread(() =>
                {
                    CreateGameWindow();
                })
                {
                    Name = "GUI.WindowThread"
                };

                windowThread.Start();
#endif

                _gameLoaded = true;
                _stopEmulation.Sensitive         = true;
                _simulateWakeUpMessage.Sensitive = true;

                _firmwareInstallFile.Sensitive      = false;
                _firmwareInstallDirectory.Sensitive = false;

                DiscordIntegrationModule.SwitchToPlayingState(_emulationContext.Application.TitleIdText, _emulationContext.Application.TitleName);

                _applicationLibrary.LoadAndSaveMetaData(_emulationContext.Application.TitleIdText, appMetadata =>
                {
                    appMetadata.LastPlayed = DateTime.UtcNow.ToString();
                });
            }
        }
コード例 #13
0
        private void HandleInstallerDialog(FileChooserDialog fileChooser)
        {
            if (fileChooser.Run() == (int)ResponseType.Accept)
            {
                try
                {
                    string filename = fileChooser.Filename;

                    fileChooser.Dispose();

                    SystemVersion firmwareVersion = _contentManager.VerifyFirmwarePackage(filename);

                    string dialogTitle = $"Install Firmware {firmwareVersion.VersionString}";

                    if (firmwareVersion == null)
                    {
                        GtkDialog.CreateErrorDialog($"A valid system firmware was not found in {filename}.");

                        return;
                    }

                    SystemVersion currentVersion = _contentManager.GetCurrentFirmwareVersion();

                    string dialogMessage = $"System version {firmwareVersion.VersionString} will be installed.";

                    if (currentVersion != null)
                    {
                        dialogMessage += $"\n\nThis will replace the current system version {currentVersion.VersionString}. ";
                    }

                    dialogMessage += "\n\nDo you want to continue?";

                    ResponseType responseInstallDialog = (ResponseType)GtkDialog.CreateConfirmationDialog(dialogTitle, dialogMessage).Run();

                    MessageDialog waitingDialog = GtkDialog.CreateWaitingDialog(dialogTitle, "Installing firmware...");

                    if (responseInstallDialog == ResponseType.Yes)
                    {
                        Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");

                        Thread thread = new Thread(() =>
                        {
                            Application.Invoke(delegate
                            {
                                waitingDialog.Run();
                            });

                            try
                            {
                                _contentManager.InstallFirmware(filename);

                                Application.Invoke(delegate
                                {
                                    waitingDialog.Dispose();

                                    string message = $"System version {firmwareVersion.VersionString} successfully installed.";

                                    GtkDialog.CreateInfoDialog(dialogTitle, message);
                                    Logger.Info?.Print(LogClass.Application, message);
                                });
                            }
                            catch (Exception ex)
                            {
                                Application.Invoke(delegate
                                {
                                    waitingDialog.Dispose();

                                    GtkDialog.CreateErrorDialog(ex.Message);
                                });
                            }
                            finally
                            {
                                RefreshFirmwareLabel();
                            }
                        });

                        thread.Name = "GUI.FirmwareInstallerThread";
                        thread.Start();
                    }
                }
                catch (LibHac.MissingKeyException ex)
                {
                    Logger.Error?.Print(LogClass.Application, ex.ToString());
                    UserErrorDialog.CreateUserErrorDialog(UserError.NoKeys);
                }
                catch (Exception ex)
                {
                    GtkDialog.CreateErrorDialog(ex.Message);
                }
            }
            else
            {
                fileChooser.Dispose();
            }
        }
コード例 #14
0
        private void HandleScreenState(KeyboardStateSnapshot keyboard)
        {
            bool toggleFullscreen = keyboard.IsPressed(Key.F11) ||
                                    ((keyboard.IsPressed(Key.AltLeft) ||
                                      keyboard.IsPressed(Key.AltRight)) &&
                                     keyboard.IsPressed(Key.Enter)) ||
                                    keyboard.IsPressed(Key.Escape);

            bool fullScreenToggled = ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen);

            if (toggleFullscreen != _toggleFullscreen)
            {
                if (toggleFullscreen)
                {
                    if (fullScreenToggled)
                    {
                        ParentWindow.Unfullscreen();
                        (Toplevel as MainWindow)?.ToggleExtraWidgets(true);
                    }
                    else
                    {
                        if (keyboard.IsPressed(Key.Escape))
                        {
                            if (!ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
                            {
                                Exit();
                            }
                        }
                        else
                        {
                            ParentWindow.Fullscreen();
                            (Toplevel as MainWindow)?.ToggleExtraWidgets(false);
                        }
                    }
                }
            }

            _toggleFullscreen = toggleFullscreen;

            bool toggleDockedMode = keyboard.IsPressed(Key.F9);

            if (toggleDockedMode != _toggleDockedMode)
            {
                if (toggleDockedMode)
                {
                    ConfigurationState.Instance.System.EnableDockedMode.Value =
                        !ConfigurationState.Instance.System.EnableDockedMode.Value;
                }
            }

            _toggleDockedMode = toggleDockedMode;

            if (_hideCursorOnIdle && !ConfigurationState.Instance.Hid.EnableMouse)
            {
                long cursorMoveDelta = Stopwatch.GetTimestamp() - _lastCursorMoveTime;
                Window.Cursor = (cursorMoveDelta >= CursorHideIdleTime * Stopwatch.Frequency) ? _invisibleCursor : null;
            }

            if (ConfigurationState.Instance.Hid.EnableMouse && _isMouseInClient)
            {
                Window.Cursor = _invisibleCursor;
            }
        }
コード例 #15
0
ファイル: GameTableContextMenu.cs プロジェクト: thubn/Ryujinx
        private void ExtractSection(NcaSectionType ncaSectionType)
        {
            FileChooserDialog fileChooser = new FileChooserDialog("Choose the folder to extract into", null, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Extract", ResponseType.Accept);

            fileChooser.SetPosition(WindowPosition.Center);

            int    response    = fileChooser.Run();
            string destination = fileChooser.Filename;

            fileChooser.Dispose();

            if (response == (int)ResponseType.Accept)
            {
                Thread extractorThread = new Thread(() =>
                {
                    string sourceFile = _gameTableStore.GetValue(_rowIter, 9).ToString();

                    Gtk.Application.Invoke(delegate
                    {
                        _dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Cancel, null)
                        {
                            Title          = "Ryujinx - NCA Section Extractor",
                            Icon           = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
                            SecondaryText  = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(sourceFile)}...",
                            WindowPosition = WindowPosition.Center
                        };

                        int dialogResponse = _dialog.Run();
                        if (dialogResponse == (int)ResponseType.Cancel || dialogResponse == (int)ResponseType.DeleteEvent)
                        {
                            _cancel = true;
                            _dialog.Dispose();
                        }
                    });

                    using (FileStream file = new FileStream(sourceFile, FileMode.Open, FileAccess.Read))
                    {
                        Nca mainNca  = null;
                        Nca patchNca = null;

                        if ((System.IO.Path.GetExtension(sourceFile).ToLower() == ".nsp") ||
                            (System.IO.Path.GetExtension(sourceFile).ToLower() == ".pfs0") ||
                            (System.IO.Path.GetExtension(sourceFile).ToLower() == ".xci"))
                        {
                            PartitionFileSystem pfs;

                            if (System.IO.Path.GetExtension(sourceFile) == ".xci")
                            {
                                Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());

                                pfs = xci.OpenPartition(XciPartitionType.Secure);
                            }
                            else
                            {
                                pfs = new PartitionFileSystem(file.AsStorage());
                            }

                            foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
                            {
                                pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());

                                if (nca.Header.ContentType == NcaContentType.Program)
                                {
                                    int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);

                                    if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
                                    {
                                        patchNca = nca;
                                    }
                                    else
                                    {
                                        mainNca = nca;
                                    }
                                }
                            }
                        }
                        else if (System.IO.Path.GetExtension(sourceFile).ToLower() == ".nca")
                        {
                            mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
                        }

                        if (mainNca == null)
                        {
                            Logger.PrintError(LogClass.Application, "Extraction failed. The main NCA was not present in the selected file.");

                            Gtk.Application.Invoke(delegate
                            {
                                GtkDialog.CreateErrorDialog("Extraction failed. The main NCA was not present in the selected file.");
                            });

                            return;
                        }

                        int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType);

                        IFileSystem ncaFileSystem = patchNca != null ? mainNca.OpenFileSystemWithPatch(patchNca, index, IntegrityCheckLevel.ErrorOnInvalid)
                                                                     : mainNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid);

                        FileSystemClient fsClient = _virtualFileSystem.FsClient;

                        string source = DateTime.Now.ToFileTime().ToString().Substring(10);
                        string output = DateTime.Now.ToFileTime().ToString().Substring(10);

                        fsClient.Register(source.ToU8Span(), ncaFileSystem);
                        fsClient.Register(output.ToU8Span(), new LocalFileSystem(destination));

                        (Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/");

                        if (!canceled)
                        {
                            if (resultCode.Value.IsFailure())
                            {
                                Logger.PrintError(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");

                                Gtk.Application.Invoke(delegate
                                {
                                    _dialog?.Dispose();

                                    GtkDialog.CreateErrorDialog("Extraction failed. Read the log file for further information.");
                                });
                            }
                            else if (resultCode.Value.IsSuccess())
                            {
                                Gtk.Application.Invoke(delegate
                                {
                                    _dialog?.Dispose();

                                    MessageDialog dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null)
                                    {
                                        Title          = "Ryujinx - NCA Section Extractor",
                                        Icon           = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
                                        SecondaryText  = "Extraction has completed successfully.",
                                        WindowPosition = WindowPosition.Center
                                    };

                                    dialog.Run();
                                    dialog.Dispose();
                                });
                            }
                        }

                        fsClient.Unmount(source.ToU8Span());
                        fsClient.Unmount(output.ToU8Span());
                    }
                });

                extractorThread.Name         = "GUI.NcaSectionExtractorThread";
                extractorThread.IsBackground = true;
                extractorThread.Start();
            }
        }
コード例 #16
0
        internal void LoadApplication(string path)
        {
            if (_gameLoaded)
            {
                GtkDialog.CreateErrorDialog("A game has already been loaded. Please close the emulator and try again");
            }
            else
            {
                Logger.RestartTime();

                // TODO: Move this somewhere else + reloadable?
                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();
                }

#if MACOS_BUILD
                CreateGameWindow();
#else
                new Thread(CreateGameWindow).Start();
#endif

                _gameLoaded = true;
                _stopEmulation.Sensitive = true;

                DiscordIntegrationModule.SwitchToPlayingState(_device.System.TitleId, _device.System.TitleName);

                string metadataFolder = System.IO.Path.Combine(new VirtualFileSystem().GetBasePath(), "games", _device.System.TitleId, "gui");
                string metadataFile   = System.IO.Path.Combine(metadataFolder, "metadata.json");

                IJsonFormatterResolver resolver = CompositeResolver.Create(new[] { StandardResolver.AllowPrivateSnakeCase });

                ApplicationMetadata appMetadata;

                if (!File.Exists(metadataFile))
                {
                    Directory.CreateDirectory(metadataFolder);

                    appMetadata = new ApplicationMetadata
                    {
                        Favorite   = false,
                        TimePlayed = 0,
                        LastPlayed = "Never"
                    };

                    byte[] data = JsonSerializer.Serialize(appMetadata, resolver);
                    File.WriteAllText(metadataFile, Encoding.UTF8.GetString(data, 0, data.Length).PrettyPrintJson());
                }

                using (Stream stream = File.OpenRead(metadataFile))
                {
                    appMetadata = JsonSerializer.Deserialize <ApplicationMetadata>(stream, resolver);
                }

                appMetadata.LastPlayed = DateTime.UtcNow.ToString();

                byte[] saveData = JsonSerializer.Serialize(appMetadata, resolver);
                File.WriteAllText(metadataFile, Encoding.UTF8.GetString(saveData, 0, saveData.Length).PrettyPrintJson());
            }
        }
コード例 #17
0
ファイル: MainWindow.cs プロジェクト: Mattscreative/Ryujinx
        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();
                });
            }
        }
コード例 #18
0
ファイル: DlcWindow.cs プロジェクト: ski982/Ryujinx-1
        private void AddButton_Clicked(object sender, EventArgs args)
        {
            FileChooserDialog fileChooser = new FileChooserDialog("Select DLC files", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Add", ResponseType.Accept)
            {
                SelectMultiple = true,
                Filter         = new FileFilter()
            };

            fileChooser.SetPosition(WindowPosition.Center);
            fileChooser.Filter.AddPattern("*.nsp");

            if (fileChooser.Run() == (int)ResponseType.Accept)
            {
                foreach (string containerPath in fileChooser.Filenames)
                {
                    if (!File.Exists(containerPath))
                    {
                        return;
                    }

                    using (FileStream containerFile = File.OpenRead(containerPath))
                    {
                        PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
                        bool containsDlc        = false;

                        _virtualFileSystem.ImportTickets(pfs);

                        TreeIter?parentIter = null;

                        foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
                        {
                            pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();

                            Nca nca = TryCreateNca(ncaFile.AsStorage(), containerPath);

                            if (nca == null)
                            {
                                continue;
                            }

                            if (nca.Header.ContentType == NcaContentType.PublicData)
                            {
                                if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000).ToString("x16") != _titleId)
                                {
                                    break;
                                }

                                parentIter ??= ((TreeStore)_dlcTreeView.Model).AppendValues(true, "", containerPath);

                                ((TreeStore)_dlcTreeView.Model).AppendValues(parentIter.Value, true, nca.Header.TitleId.ToString("X16"), fileEntry.FullPath);
                                containsDlc = true;
                            }
                        }

                        if (!containsDlc)
                        {
                            GtkDialog.CreateErrorDialog("The specified file does not contain a DLC for the selected title!");
                        }
                    }
                }
            }

            fileChooser.Dispose();
        }
コード例 #19
0
ファイル: MainWindow.cs プロジェクト: fifihomeless/Ryujinx
        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();
                });
            }
        }
コード例 #20
0
ファイル: MainWindow.cs プロジェクト: zpoo32/Ryujinx
        internal void LoadApplication(string path)
        {
            if (_gameLoaded)
            {
                GtkDialog.CreateErrorDialog("A game has already been loaded. Please close the emulator and try again");
            }
            else
            {
                Logger.RestartTime();

                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();
                }

#if MACOS_BUILD
                CreateGameWindow();
#else
                new Thread(CreateGameWindow).Start();
#endif

                _gameLoaded = true;
                _stopEmulation.Sensitive = true;

                if (DiscordIntegrationEnabled)
                {
                    if (File.ReadAllLines(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RPsupported.dat")).Contains(_device.System.TitleId))
                    {
                        DiscordPresence.Assets.LargeImageKey = _device.System.TitleId;
                    }

                    string state = _device.System.TitleId;

                    if (state == null)
                    {
                        state = "Ryujinx";
                    }
                    else
                    {
                        state = state.ToUpper();
                    }

                    string details = "Idling";

                    if (_device.System.TitleName != null)
                    {
                        details = $"Playing {_device.System.TitleName}";
                    }

                    DiscordPresence.Details = details;
                    DiscordPresence.State   = state;
                    DiscordPresence.Assets.LargeImageText = _device.System.TitleName;
                    DiscordPresence.Assets.SmallImageKey  = "ryujinx";
                    DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch";
                    DiscordPresence.Timestamps            = new Timestamps(DateTime.UtcNow);

                    DiscordClient.SetPresence(DiscordPresence);
                }

                string metadataFolder = System.IO.Path.Combine(new VirtualFileSystem().GetBasePath(), "games", _device.System.TitleId, "gui");
                string metadataFile   = System.IO.Path.Combine(metadataFolder, "metadata.json");

                IJsonFormatterResolver resolver = CompositeResolver.Create(new[] { StandardResolver.AllowPrivateSnakeCase });

                ApplicationMetadata appMetadata;

                if (!File.Exists(metadataFile))
                {
                    Directory.CreateDirectory(metadataFolder);

                    appMetadata = new ApplicationMetadata
                    {
                        Favorite   = false,
                        TimePlayed = 0,
                        LastPlayed = "Never"
                    };

                    byte[] data = JsonSerializer.Serialize(appMetadata, resolver);
                    File.WriteAllText(metadataFile, Encoding.UTF8.GetString(data, 0, data.Length).PrettyPrintJson());
                }

                using (Stream stream = File.OpenRead(metadataFile))
                {
                    appMetadata = JsonSerializer.Deserialize <ApplicationMetadata>(stream, resolver);
                }

                appMetadata.LastPlayed = DateTime.UtcNow.ToString();

                byte[] saveData = JsonSerializer.Serialize(appMetadata, resolver);
                File.WriteAllText(metadataFile, Encoding.UTF8.GetString(saveData, 0, saveData.Length).PrettyPrintJson());
            }
        }