diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs index 25c92d829..01f46c846 100644 --- a/src/ARMeilleure/Translation/PTC/Ptc.cs +++ b/src/ARMeilleure/Translation/PTC/Ptc.cs @@ -3,6 +3,7 @@ using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.Common; using ARMeilleure.Memory; +using ARMeilleure.State; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; @@ -28,8 +29,8 @@ namespace ARMeilleure.Translation.PTC { private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - - private const uint InternalVersion = 6997; //! To be incremented manually for each change to the ARMeilleure project. + + private const uint InternalVersion = 6998; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1"; @@ -182,6 +183,36 @@ namespace ARMeilleure.Translation.PTC InitializeCarriers(); } + private bool ContainsBlacklistedFunctions() + { + List blacklist = Profiler.GetBlacklistedFunctions(); + bool containsBlacklistedFunctions = false; + _infosStream.Seek(0L, SeekOrigin.Begin); + bool foundBadFunction = false; + + for (int index = 0; index < GetEntriesCount(); index++) + { + InfoEntry infoEntry = DeserializeStructure(_infosStream); + foreach (ulong address in blacklist) + { + if (infoEntry.Address == address) + { + containsBlacklistedFunctions = true; + Logger.Warning?.Print(LogClass.Ptc, "PPTC cache invalidated: Found blacklisted functions in PPTC cache"); + foundBadFunction = true; + break; + } + } + + if (foundBadFunction) + { + break; + } + } + + return containsBlacklistedFunctions; + } + private void PreLoad() { string fileNameActual = $"{CachePathActual}.cache"; @@ -530,7 +561,7 @@ namespace ARMeilleure.Translation.PTC public void LoadTranslations(Translator translator) { - if (AreCarriersEmpty()) + if (AreCarriersEmpty() || ContainsBlacklistedFunctions()) { return; } @@ -833,10 +864,18 @@ namespace ARMeilleure.Translation.PTC while (profiledFuncsToTranslate.TryDequeue(out var item)) { ulong address = item.address; + ExecutionMode executionMode = item.funcProfile.Mode; + bool highCq = item.funcProfile.HighCq; Debug.Assert(Profiler.IsAddressInStaticCodeRange(address)); - TranslatedFunction func = translator.Translate(address, item.funcProfile.Mode, item.funcProfile.HighCq); + TranslatedFunction func = translator.Translate(address, executionMode, highCq); + + if (func == null) + { + Profiler.UpdateEntry(address, executionMode, true, true); + continue; + } bool isAddressUnique = translator.Functions.TryAdd(address, func.GuestSize, func); @@ -885,7 +924,14 @@ namespace ARMeilleure.Translation.PTC PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount); - Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s"); + if (_translateCount == _translateTotalCount) + { + Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s"); + } + else + { + Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | {_translateTotalCount - _translateCount} function{(_translateTotalCount - _translateCount != 1 ? "s" : "")} blacklisted | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s"); + } Thread preSaveThread = new(PreSave) { diff --git a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs index 80f72c011..4962f2d1f 100644 --- a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs +++ b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs @@ -23,11 +23,13 @@ namespace ARMeilleure.Translation.PTC { private const string OuterHeaderMagicString = "Pohd\0\0\0\0"; - private const uint InternalVersion = 5518; //! Not to be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 6698; //! Not to be incremented manually for each change to the ARMeilleure project. - private static readonly uint[] _migrateInternalVersions = { + private static readonly uint[] _migrateInternalVersions = + [ 1866, - }; + 5518, + ]; private const int SaveInterval = 30; // Seconds. @@ -72,20 +74,30 @@ namespace ARMeilleure.Translation.PTC Enabled = false; } - public void AddEntry(ulong address, ExecutionMode mode, bool highCq) + public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false) { if (IsAddressInStaticCodeRange(address)) { Debug.Assert(!highCq); - lock (_lock) + if (blacklist) { - ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false)); + lock (_lock) + { + ProfiledFuncs[address] = new FuncProfile(mode, highCq: false, true); + } + } + else + { + lock (_lock) + { + ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false, false)); + } } } } - public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq) + public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq, bool? blacklist = null) { if (IsAddressInStaticCodeRange(address)) { @@ -95,7 +107,7 @@ namespace ARMeilleure.Translation.PTC { Debug.Assert(ProfiledFuncs.ContainsKey(address)); - ProfiledFuncs[address] = new FuncProfile(mode, highCq: true); + ProfiledFuncs[address] = new FuncProfile(mode, highCq: true, blacklist ?? ProfiledFuncs[address].Blacklist); } } } @@ -111,7 +123,7 @@ namespace ARMeilleure.Translation.PTC foreach (var profiledFunc in ProfiledFuncs) { - if (!funcs.ContainsKey(profiledFunc.Key)) + if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist) { profiledFuncsToTranslate.Enqueue((profiledFunc.Key, profiledFunc.Value)); } @@ -126,6 +138,24 @@ namespace ARMeilleure.Translation.PTC ProfiledFuncs.TrimExcess(); } + public List GetBlacklistedFunctions() + { + List funcs = new List(); + + foreach (var profiledFunc in ProfiledFuncs) + { + if (profiledFunc.Value.Blacklist) + { + if (!funcs.Contains(profiledFunc.Key)) + { + funcs.Add(profiledFunc.Key); + } + } + } + + return funcs; + } + public void PreLoad() { _lastHash = default; @@ -216,13 +246,18 @@ namespace ARMeilleure.Translation.PTC return false; } + Func migrateEntryFunc = null; + switch (outerHeader.InfoFileVersion) { case InternalVersion: ProfiledFuncs = Deserialize(stream); break; case 1866: - ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile)); + migrateEntryFunc = (address, profile) => (address + 0x500000UL, profile); + goto case 5518; + case 5518: + ProfiledFuncs = DeserializeAddBlacklist(stream, migrateEntryFunc); break; default: Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache."); @@ -252,6 +287,16 @@ namespace ARMeilleure.Translation.PTC return DeserializeDictionary(stream, DeserializeStructure); } + private static Dictionary DeserializeAddBlacklist(Stream stream, Func migrateEntryFunc = null) + { + if (migrateEntryFunc != null) + { + return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure(stream)); }, migrateEntryFunc); + } + + return DeserializeDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure(stream)); }); + } + private static ReadOnlySpan GetReadOnlySpan(MemoryStream memoryStream) { return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position); @@ -383,13 +428,35 @@ namespace ARMeilleure.Translation.PTC } } - [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)] + [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 6*/)] public struct FuncProfile { public ExecutionMode Mode; public bool HighCq; + public bool Blacklist; - public FuncProfile(ExecutionMode mode, bool highCq) + public FuncProfile(ExecutionMode mode, bool highCq, bool blacklist) + { + Mode = mode; + HighCq = highCq; + Blacklist = blacklist; + } + + public FuncProfile(FuncProfilePreBlacklist fp) + { + Mode = fp.Mode; + HighCq = fp.HighCq; + Blacklist = false; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)] + public struct FuncProfilePreBlacklist + { + public ExecutionMode Mode; + public bool HighCq; + + public FuncProfilePreBlacklist(ExecutionMode mode, bool highCq) { Mode = mode; HighCq = highCq; diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index 00852de65..367aa69c7 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -248,6 +248,11 @@ namespace ARMeilleure.Translation ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter counter); + if (cfg == null) + { + return null; + } + ulong funcSize = funcRange.End - funcRange.Start; Logger.EndPass(PassName.Translation, cfg); @@ -406,6 +411,11 @@ namespace ARMeilleure.Translation if (opCode.Instruction.Emitter != null) { opCode.Instruction.Emitter(context); + if (opCode.Instruction.Name == InstName.Und && blkIndex == 0) + { + range = new Range(rangeStart, rangeEnd); + return null; + } } else { diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs index 14775fb1d..080971dee 100644 --- a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs +++ b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs @@ -20,6 +20,7 @@ namespace Ryujinx.HLE.HOS private readonly string _titleIdText; private readonly string _displayVersion; private readonly bool _diskCacheEnabled; + private readonly string _diskCacheSelector; private readonly ulong _codeAddress; private readonly ulong _codeSize; @@ -31,6 +32,7 @@ namespace Ryujinx.HLE.HOS string titleIdText, string displayVersion, bool diskCacheEnabled, + string diskCacheSelector, ulong codeAddress, ulong codeSize) { @@ -39,6 +41,7 @@ namespace Ryujinx.HLE.HOS _titleIdText = titleIdText; _displayVersion = displayVersion; _diskCacheEnabled = diskCacheEnabled; + _diskCacheSelector = diskCacheSelector; _codeAddress = codeAddress; _codeSize = codeSize; } @@ -114,7 +117,7 @@ namespace Ryujinx.HLE.HOS } } - DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, "default"); //Ready for exefs profiles + DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, _diskCacheSelector ?? "default"); return processContext; } diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs index bdccbc95a..5d9842088 100644 --- a/src/Ryujinx.HLE/HOS/ModLoader.cs +++ b/src/Ryujinx.HLE/HOS/ModLoader.cs @@ -5,6 +5,7 @@ using LibHac.FsSystem; using LibHac.Loader; using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.RomFs; +using LibHac.Util; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; @@ -18,6 +19,7 @@ using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Linq; +using System.Security.Cryptography; using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile; using Path = System.IO.Path; @@ -598,6 +600,7 @@ namespace Ryujinx.HLE.HOS public BitVector32 Stubs; public BitVector32 Replaces; public MetaLoader Npdm; + public string Hash; public bool Modified => (Stubs.Data | Replaces.Data) != 0; } @@ -608,8 +611,11 @@ namespace Ryujinx.HLE.HOS { Stubs = new BitVector32(), Replaces = new BitVector32(), + Hash = null, }; + string tempHash = string.Empty; + if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.ExefsDirs.Count == 0) { return modLoadResult; @@ -645,8 +651,16 @@ namespace Ryujinx.HLE.HOS modLoadResult.Replaces[1 << i] = true; - nsos[i] = new NsoExecutable(nsoFile.OpenRead().AsStorage(), nsoName); - Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced"); + using (FileStream stream = nsoFile.OpenRead()) + { + nsos[i] = new NsoExecutable(stream.AsStorage(), nsoName); + Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced"); + using (MD5 md5 = MD5.Create()) + { + stream.Seek(0, SeekOrigin.Begin); + tempHash += BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant(); + } + } } modLoadResult.Stubs[1 << i] |= File.Exists(Path.Combine(mod.Path.FullName, nsoName + StubExtension)); @@ -678,6 +692,14 @@ namespace Ryujinx.HLE.HOS } } + if (!string.IsNullOrEmpty(tempHash)) + { + using (MD5 md5 = MD5.Create()) + { + modLoadResult.Hash += BitConverter.ToString(md5.ComputeHash(tempHash.ToBytes())).Replace("-", "").ToLowerInvariant(); + } + } + return modLoadResult; } diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs index 3904d660e..06e0e89f8 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs @@ -82,13 +82,6 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions // Apply Nsos patches. device.Configuration.VirtualFileSystem.ModLoader.ApplyNsoPatches(programId, nsoExecutables); - // Don't use PTC if ExeFS files have been replaced. - bool enablePtc = device.System.EnablePtc && !modLoadResult.Modified; - if (!enablePtc) - { - Logger.Warning?.Print(LogClass.Ptc, "Detected unsupported ExeFs modifications. PTC disabled."); - } - string programName = ""; if (!isHomebrew && programId > 0x010000000000FFFF) @@ -115,7 +108,8 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions device.System.KernelContext, metaLoader, nacpData, - enablePtc, + device.System.EnablePtc, + modLoadResult.Hash, true, programName, metaLoader.GetProgramId(), diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs index 12d9c8bd9..798f574ab 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs @@ -212,6 +212,7 @@ namespace Ryujinx.HLE.Loaders.Processes dummyExeFs.GetNpdm(), nacpData, diskCacheEnabled: false, + diskCacheSelector: null, allowCodeMemoryForJit: true, programName, programId, diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs index 136e2eb48..5874c420d 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs @@ -185,6 +185,7 @@ namespace Ryujinx.HLE.Loaders.Processes string.Empty, string.Empty, false, + null, codeAddress, codeSize); @@ -225,6 +226,7 @@ namespace Ryujinx.HLE.Loaders.Processes MetaLoader metaLoader, BlitStruct applicationControlProperties, bool diskCacheEnabled, + string diskCacheSelector, bool allowCodeMemoryForJit, string name, ulong programId, @@ -378,6 +380,7 @@ namespace Ryujinx.HLE.Loaders.Processes $"{programId:x16}", displayVersion, diskCacheEnabled, + diskCacheSelector, codeStart, codeSize); diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json index 031dff9ce..b58f96d00 100644 --- a/src/Ryujinx/Assets/Locales/ar_SA.json +++ b/src/Ryujinx/Assets/Locales/ar_SA.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "‫‫يفتح المجلد الذي يحتوي على ذاكرة التخزين المؤقت للترجمة المستمرة (PPTC) للتطبيق", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "فتح مجلد الذاكرة المؤقتة لمرشحات الفيديو ", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "يفتح المجلد الذي يحتوي على ذاكرة المظللات المؤقتة للتطبيق", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "استخراج البيانات", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "‫‫ استخراج قسم نظام الملفات القابل للتنفيذ (ExeFS) من الإعدادات الحالية للتطبيقات (يتضمن التحديثات)", @@ -487,6 +489,7 @@ "DialogWarning": "تحذير", "DialogPPTCDeletionMessage": "أنت على وشك الإنتظار لإعادة بناء ذاكرة التخزين المؤقت للترجمة المستمرة (PPTC) عند الإقلاع التالي لـ:\n\n{0}\n\nأمتأكد من رغبتك في المتابعة؟", "DialogPPTCDeletionErrorMessage": "خطأ خلال تنظيف ذاكرة التخزين المؤقت للترجمة المستمرة (PPTC) في {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "أنت على وشك حذف ذاكرة المظللات المؤقتة ل:\n\n{0}\n\nهل انت متأكد انك تريد المتابعة؟", "DialogShaderDeletionErrorMessage": "حدث خطأ أثناء تنظيف ذاكرة المظللات المؤقتة في {0}: {1}", "DialogRyujinxErrorMessage": "واجه ريوجينكس خطأ", diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json index 2e9070ef0..c49563159 100644 --- a/src/Ryujinx/Assets/Locales/de_DE.json +++ b/src/Ryujinx/Assets/Locales/de_DE.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Öffnet das Verzeichnis, das den PPTC-Cache der Anwendung beinhaltet", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader-Cache-Verzeichnis öffnen", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Öffnet das Verzeichnis, das den Shader Cache der Anwendung beinhaltet", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Daten extrahieren", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Extrahiert das ExeFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates)", @@ -487,6 +489,7 @@ "DialogWarning": "Warnung", "DialogPPTCDeletionMessage": "Du bist dabei den PPTC für das folgende Spiel als ungültig zu markieren:\n\n{0}\n\nWirklich fortfahren?", "DialogPPTCDeletionErrorMessage": "Fehler bei der Löschung des PPTC Caches bei {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Du bist dabei, den Shader Cache zu löschen für :\n\n{0}\n\nWirklich fortfahren?", "DialogShaderDeletionErrorMessage": "Es ist ein Fehler bei der Löschung des Shader Caches bei {0}: {1} aufgetreten", "DialogRyujinxErrorMessage": "Ein Fehler ist aufgetreten", diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json index e1bbbb0e0..0694bff4a 100644 --- a/src/Ryujinx/Assets/Locales/el_GR.json +++ b/src/Ryujinx/Assets/Locales/el_GR.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει τη προσωρινή μνήμη PPTC της εφαρμογής", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Άνοιγμα τοποθεσίας προσωρινής μνήμης Shader", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την προσωρινή μνήμη Shader της εφαρμογής", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Εξαγωγή Δεδομένων", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Εξαγωγή της ενότητας ExeFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)", @@ -487,6 +489,7 @@ "DialogWarning": "Προειδοποίηση", "DialogPPTCDeletionMessage": "Πρόκειται να διαγράψετε την προσωρινή μνήμη PPTC για :\n\n{0}\n\nΕίστε βέβαιοι ότι θέλετε να συνεχίσετε;", "DialogPPTCDeletionErrorMessage": "Σφάλμα κατά την εκκαθάριση προσωρινής μνήμης PPTC στο {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Πρόκειται να διαγράψετε την προσωρινή μνήμη Shader για :\n\n{0}\n\nΕίστε βέβαιοι ότι θέλετε να συνεχίσετε;", "DialogShaderDeletionErrorMessage": "Σφάλμα κατά την εκκαθάριση προσωρινής μνήμης Shader στο {0}: {1}", "DialogRyujinxErrorMessage": "Το Ryujinx αντιμετώπισε σφάλμα", diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index 7ec896100..388c22506 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -77,6 +77,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Opens the directory which contains Application's PPTC cache", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Open Shader Cache Directory", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Opens the directory which contains Application's shader cache", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Extract Data", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Extract the ExeFS section from Application's current config (including updates)", @@ -511,6 +513,7 @@ "DialogWarning": "Warning", "DialogPPTCDeletionMessage": "You are about to queue a PPTC rebuild on the next boot of:\n\n{0}\n\nAre you sure you want to proceed?", "DialogPPTCDeletionErrorMessage": "Error purging PPTC cache at {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "You are about to delete the Shader cache for :\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionErrorMessage": "Error purging Shader cache at {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx has encountered an error", diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json index 6f3eba166..ec26fc936 100644 --- a/src/Ryujinx/Assets/Locales/es_ES.json +++ b/src/Ryujinx/Assets/Locales/es_ES.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Abrir la carpeta que contiene la caché de PPTC de esta aplicación", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Abrir carpeta de caché de sombreadores", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Abrir la carpeta que contiene la caché de sombreadores de esta aplicación", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Extraer datos", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Extraer la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones)", @@ -487,6 +489,7 @@ "DialogWarning": "Advertencia", "DialogPPTCDeletionMessage": "Vas a borrar la caché de PPTC para:\n\n{0}\n\n¿Estás seguro de querer continuar?", "DialogPPTCDeletionErrorMessage": "Error purgando la caché de PPTC en {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Vas a borrar la caché de sombreadores para:\n\n{0}\n\n¿Estás seguro de querer continuar?", "DialogShaderDeletionErrorMessage": "Error purgando la caché de sombreadores en {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx ha encontrado un error", diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json index 3b1badbaa..2b0c64d46 100644 --- a/src/Ryujinx/Assets/Locales/fr_FR.json +++ b/src/Ryujinx/Assets/Locales/fr_FR.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Ouvre le dossier contenant le PPTC du jeu", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Ouvrir le dossier du cache des shaders", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Ouvre le dossier contenant le cache des shaders du jeu", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Extraire les données", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Extrait la section ExeFS du jeu (mise à jour incluse)", @@ -489,6 +491,7 @@ "DialogWarning": "Avertissement", "DialogPPTCDeletionMessage": "Vous êtes sur le point de mettre en file d'attente une reconstruction PPTC au prochain démarrage de :\n\n{0}\n\nÊtes-vous sûr de vouloir continuer ?", "DialogPPTCDeletionErrorMessage": "Erreur lors de la purge du cache PPTC à {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Vous êtes sur le point de supprimer le cache du Shader pour :\n\n{0}\n\nÊtes-vous sûr de vouloir continuer ?", "DialogShaderDeletionErrorMessage": "Erreur lors de la purge du cache du Shader à {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx a rencontré une erreur", diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json index 92abf5213..16a16b1d8 100644 --- a/src/Ryujinx/Assets/Locales/he_IL.json +++ b/src/Ryujinx/Assets/Locales/he_IL.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "פותח את התקייה של מטמון ה-PPTC של האפליקציה", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "פתח את תקיית המטמון של ההצללות", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "פותח את תקיית מטמון ההצללות של היישום", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "חילוץ נתונים", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים)", @@ -487,6 +489,7 @@ "DialogWarning": "אזהרה", "DialogPPTCDeletionMessage": "אם תמשיכו אתם עומדים לגרום לבנייה מחדש של מטמון ה-PPTC עבור:\n\n{0}", "DialogPPTCDeletionErrorMessage": "שגיאה בטיהור מטמון PPTC ב-{0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "אם תמשיכו אתם עומדים למחוק את מטמון ההצללות עבור:\n\n{0}", "DialogShaderDeletionErrorMessage": "שגיאה בניקוי מטמון ההצללות ב-{0}: {1}", "DialogRyujinxErrorMessage": "ריוג'ינקס נתקלה בשגיאה", diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json index 9023bc18f..60f56d65d 100644 --- a/src/Ryujinx/Assets/Locales/it_IT.json +++ b/src/Ryujinx/Assets/Locales/it_IT.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Apre la cartella che contiene la cache PPTC dell'applicazione", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Apri la cartella della cache degli shader", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Apre la cartella che contiene la cache degli shader dell'applicazione", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Estrai dati", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", @@ -487,6 +489,7 @@ "DialogWarning": "Avviso", "DialogPPTCDeletionMessage": "Stai per accodare la rigenerazione della cache PPTC al prossimo avvio per:\n\n{0}\n\nSei sicuro di voler proseguire?", "DialogPPTCDeletionErrorMessage": "Errore nell'eliminazione della cache PPTC a {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Stai per eliminare la cache degli shader per:\n\n{0}\n\nSei sicuro di voler proseguire?", "DialogShaderDeletionErrorMessage": "Errore nell'eliminazione della cache degli shader a {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx ha incontrato un errore", diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json index f63eb0c97..9340f2fb4 100644 --- a/src/Ryujinx/Assets/Locales/ja_JP.json +++ b/src/Ryujinx/Assets/Locales/ja_JP.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "アプリケーションの PPTC キャッシュを格納するディレクトリを開きます", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "シェーダーキャッシュディレクトリを開く", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "アプリケーションのシェーダーキャッシュを格納するディレクトリを開きます", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "データを展開", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します", @@ -487,6 +489,7 @@ "DialogWarning": "警告", "DialogPPTCDeletionMessage": "次回起動時に PPTC を再構築します:\n\n{0}\n\n実行してよろしいですか?", "DialogPPTCDeletionErrorMessage": "PPTC キャッシュ破棄エラー {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "シェーダーキャッシュを破棄しようとしています:\n\n{0}\n\n実行してよろしいですか?", "DialogShaderDeletionErrorMessage": "シェーダーキャッシュ破棄エラー {0}: {1}", "DialogRyujinxErrorMessage": "エラーが発生しました", diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json index 6ab75f482..fc5447cd4 100644 --- a/src/Ryujinx/Assets/Locales/ko_KR.json +++ b/src/Ryujinx/Assets/Locales/ko_KR.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "응용프로그램 PPTC 캐시가 포함된 디렉터리 열기", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "셰이더 캐시 디렉터리 열기", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "응용프로그램 셰이더 캐시가 포함된 디렉터리 열기", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "데이터 추출", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "응용프로그램의 현재 구성에서 ExeFS 추출 (업데이트 포함)", @@ -487,6 +489,7 @@ "DialogWarning": "경고", "DialogPPTCDeletionMessage": "다음 부팅 시, PPTC 재구축을 대기열에 추가 :\n\n{0}\n\n계속하겠습니까?", "DialogPPTCDeletionErrorMessage": "{0}에서 PPTC 캐시 삭제 오류 : {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "다음에 대한 셰이더 캐시 삭제 :\n\n{0}\n\n계속하겠습니까?", "DialogShaderDeletionErrorMessage": "{0}에서 셰이더 캐시 제거 오류 : {1}", "DialogRyujinxErrorMessage": "Ryujinx에 오류 발생", diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json index b46f996f0..be1856d2b 100644 --- a/src/Ryujinx/Assets/Locales/pl_PL.json +++ b/src/Ryujinx/Assets/Locales/pl_PL.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Otwiera katalog, który zawiera pamięć podręczną PPTC aplikacji", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Otwórz katalog pamięci podręcznej cieni", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Otwiera katalog, który zawiera pamięć podręczną cieni aplikacji", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Wypakuj dane", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)", @@ -487,6 +489,7 @@ "DialogWarning": "Uwaga", "DialogPPTCDeletionMessage": "Masz zamiar umieścić w kolejce rekompilację PPTC przy następnym uruchomieniu:\n\n{0}\n\nCzy na pewno chcesz kontynuować?", "DialogPPTCDeletionErrorMessage": "Błąd czyszczenia cache PPTC w {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Zamierzasz usunąć cache Shaderów dla :\n\n{0}\n\nNa pewno chcesz kontynuować?", "DialogShaderDeletionErrorMessage": "Błąd czyszczenia cache Shaderów w {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx napotkał błąd", diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json index 5325681da..edcfc0ba6 100644 --- a/src/Ryujinx/Assets/Locales/pt_BR.json +++ b/src/Ryujinx/Assets/Locales/pt_BR.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Abre o diretório contendo os arquivos do cache PPTC", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Abrir diretório do cache de Shader", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Abre o diretório contendo os arquivos do cache de Shader", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Extrair dados", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Extrai a seção ExeFS do jogo (incluindo atualizações)", @@ -487,6 +489,7 @@ "DialogWarning": "Alerta", "DialogPPTCDeletionMessage": "Você está prestes a apagar o cache PPTC para :\n\n{0}\n\nTem certeza que deseja continuar?", "DialogPPTCDeletionErrorMessage": "Erro apagando cache PPTC em {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Você está prestes a apagar o cache de Shader para :\n\n{0}\n\nTem certeza que deseja continuar?", "DialogShaderDeletionErrorMessage": "Erro apagando o cache de Shader em {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx encontrou um erro", diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json index 1290dbf9f..d031ca1e0 100644 --- a/src/Ryujinx/Assets/Locales/ru_RU.json +++ b/src/Ryujinx/Assets/Locales/ru_RU.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Открывает папку, содержащую PPTC кэш приложений и игр", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Открыть папку с кэшем шейдеров", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Открывает папку, содержащую кэш шейдеров приложений и игр", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Извлечь данные", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Извлечение раздела ExeFS из текущих настроек приложения (включая обновления)", @@ -487,6 +489,7 @@ "DialogWarning": "Внимание", "DialogPPTCDeletionMessage": "Вы собираетесь перестроить кэш PPTC при следующем запуске для:\n\n{0}\n\nВы уверены, что хотите продолжить?", "DialogPPTCDeletionErrorMessage": "Ошибка очистки кэша PPTC в {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Вы собираетесь удалить кэш шейдеров для:\n\n{0}\n\nВы уверены, что хотите продолжить?", "DialogShaderDeletionErrorMessage": "Ошибка очистки кэша шейдеров в {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx обнаружил ошибку", diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json index ba965cbfb..d1fe4641a 100644 --- a/src/Ryujinx/Assets/Locales/th_TH.json +++ b/src/Ryujinx/Assets/Locales/th_TH.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "เปิดไดเร็กทอรี่ PPTC แคช ของแอปพลิเคชัน", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "เปิดไดเรกทอรี่ แคช พื้นผิวและแสงเงา", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "เปิดไดเรกทอรี่ แคช พื้นผิวและแสงเงา ของแอปพลิเคชัน", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "แยกส่วนข้อมูล", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "แยกส่วน ExeFS ออกจากการกำหนดค่าปัจจุบันของแอปพลิเคชัน (รวมถึงการอัปเดต)", @@ -487,6 +489,7 @@ "DialogWarning": "คำเตือน", "DialogPPTCDeletionMessage": "คุณกำลังจะจัดคิวการสร้าง PPTC ใหม่ในการบูตครั้งถัดไป:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "DialogPPTCDeletionErrorMessage": "มีข้อผิดพลาดในการล้างแคช PPTC {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "คุณกำลังจะลบ เชเดอร์แคช:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "DialogShaderDeletionErrorMessage": "เกิดข้อผิดพลาดในการล้าง เชเดอร์แคช {0}: {1}", "DialogRyujinxErrorMessage": "รียูจินซ์ พบข้อผิดพลาด", diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json index c008a1c9a..ea5616aff 100644 --- a/src/Ryujinx/Assets/Locales/tr_TR.json +++ b/src/Ryujinx/Assets/Locales/tr_TR.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Uygulamanın PPTC Önbelleğinin bulunduğu dizini açar", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader Önbelleği Dizinini Aç", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Uygulamanın shader önbelleğinin bulunduğu dizini açar", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Veriyi Ayıkla", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)", @@ -487,6 +489,7 @@ "DialogWarning": "Uyarı", "DialogPPTCDeletionMessage": "Belirtilen PPTC cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "DialogPPTCDeletionErrorMessage": "Belirtilen PPTC cache temizlenirken hata {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Belirtilen Shader cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "DialogShaderDeletionErrorMessage": "Belirtilen Shader cache temizlenirken hata {0}: {1}", "DialogRyujinxErrorMessage": "Ryujinx bir hata ile karşılaştı", diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json index e485f8fad..d4ad5a6b1 100644 --- a/src/Ryujinx/Assets/Locales/uk_UA.json +++ b/src/Ryujinx/Assets/Locales/uk_UA.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Відкриває каталог, який містить кеш PPTC програми", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Відкрити каталог кешу шейдерів", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Відкриває каталог, який містить кеш шейдерів програми", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "Видобути дані", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "Видобуває розділ ExeFS із поточної конфігурації програми (включаючи оновлення)", @@ -487,6 +489,7 @@ "DialogWarning": "Увага", "DialogPPTCDeletionMessage": "Ви збираєтеся видалити кеш PPTC для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", "DialogPPTCDeletionErrorMessage": "Помилка очищення кешу PPTC на {0}: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "Ви збираєтеся видалити кеш шейдерів для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", "DialogShaderDeletionErrorMessage": "Помилка очищення кешу шейдерів на {0}: {1}", "DialogRyujinxErrorMessage": "У Ryujinx сталася помилка", diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json index 880867902..0c89e20ea 100644 --- a/src/Ryujinx/Assets/Locales/zh_CN.json +++ b/src/Ryujinx/Assets/Locales/zh_CN.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "打开储存游戏 PPTC 缓存文件的目录", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "打开着色器缓存目录", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "打开储存游戏着色器缓存文件的目录", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "提取数据", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "从游戏的当前状态中提取 ExeFS 分区 (包括更新)", @@ -487,6 +489,7 @@ "DialogWarning": "警告", "DialogPPTCDeletionMessage": "您即将删除:\n\n{0} 的 PPTC 缓存文件\n\n确定吗?", "DialogPPTCDeletionErrorMessage": "清除 {0} 的 PPTC 缓存文件时出错:{1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "您即将删除:\n\n{0} 的着色器缓存文件\n\n确定吗?", "DialogShaderDeletionErrorMessage": "清除 {0} 的着色器缓存文件时出错:{1}", "DialogRyujinxErrorMessage": "Ryujinx 模拟器发生错误", diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json index d6221ea4c..aec9f5efb 100644 --- a/src/Ryujinx/Assets/Locales/zh_TW.json +++ b/src/Ryujinx/Assets/Locales/zh_TW.json @@ -75,6 +75,8 @@ "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "開啟此應用程式的 PPTC 快取資料夾", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "開啟著色器快取資料夾", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "開啟此應用程式的著色器快取資料夾", + "GameListContextMenuCacheManagementNukePptc": "Purge PPTC cache", + "GameListContextMenuCacheManagementNukePptcToolTip": "Deletes all PPTC cache files for the Application", "GameListContextMenuExtractData": "提取資料", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "從應用程式的目前配置中提取 ExeFS 分區 (包含更新)", @@ -487,6 +489,7 @@ "DialogWarning": "警告", "DialogPPTCDeletionMessage": "您將在下一次啟動時佇列重建以下遊戲的 PPTC:\n\n{0}\n\n您確定要繼續嗎?", "DialogPPTCDeletionErrorMessage": "在 {0} 清除 PPTC 快取時出錯: {1}", + "DialogPPTCNukeMessage": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", "DialogShaderDeletionMessage": "您將刪除以下遊戲的著色器快取:\n\n{0}\n\n您確定要繼續嗎?", "DialogShaderDeletionErrorMessage": "在 {0} 清除著色器快取時出錯: {1}", "DialogRyujinxErrorMessage": "Ryujinx 遇到錯誤", diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml index 4b007bd24..23718ed25 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml @@ -71,6 +71,10 @@ Click="PurgePtcCache_Click" Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}" ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" /> + cacheFiles = new(); + + if (mainDir.Exists) + { + cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache")); + cacheFiles.AddRange(mainDir.EnumerateFiles("*.info")); + } + + if (backupDir.Exists) + { + cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache")); + cacheFiles.AddRange(mainDir.EnumerateFiles("*.info")); + } + + if (cacheFiles.Count > 0) + { + foreach (FileInfo file in cacheFiles) + { + try + { + file.Delete(); + } + catch (Exception ex) + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex)); + } + } + } + } + } + public async void PurgeShaderCache_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;