Android fixes and features

* Jit cache eviction (fixes out of memory errors in some games)

* Low power PPTC

* Fix 'unknown' games displayed when using game folder with subfolders

* Turn off NCE and PPTC by default
This commit is contained in:
KeatonTheBot 2025-05-31 03:00:29 -05:00
parent 3af88ad2e6
commit fda90239bc
58 changed files with 914 additions and 190 deletions

View file

@ -8,6 +8,9 @@ namespace ARMeilleure
// low-core count PPTC // low-core count PPTC
public static bool EcoFriendly { get; set; } = false; public static bool EcoFriendly { get; set; } = false;
// Jit cache eviction
public static bool CacheEviction { get; set; } = false;
public static bool FastFP { get; set; } = true; public static bool FastFP { get; set; } = true;
public static bool AllowLcqInFunctionTable { get; set; } = true; public static bool AllowLcqInFunctionTable { get; set; } = true;

View file

@ -2,10 +2,12 @@ using ARMeilleure.CodeGen;
using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using ARMeilleure.Native; using ARMeilleure.Native;
using Ryujinx.Common.Logging;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading; using System.Threading;
@ -17,8 +19,15 @@ namespace ARMeilleure.Translation.Cache
private static readonly int _pageSize = (int)MemoryBlock.GetPageSize(); private static readonly int _pageSize = (int)MemoryBlock.GetPageSize();
private static readonly int _pageMask = _pageSize - 1; private static readonly int _pageMask = _pageSize - 1;
private const int CodeAlignment = 4; // Bytes. private const int CodeAlignment = 4;
private const int CacheSize = 2047 * 1024 * 1024; private const int FullCacheSize = 2047 * 1024 * 1024;
private const int ReducedCacheSize = FullCacheSize / 8;
private const float EvictionTargetPercentage = 0.20f;
private const int MaxEntriesToEvictAtOnce = 100;
// Simple logging configuration
private const int LogInterval = 5000; // Log every 5000 allocations
private static ReservedRegion _jitRegion; private static ReservedRegion _jitRegion;
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
@ -26,9 +35,33 @@ namespace ARMeilleure.Translation.Cache
private static CacheMemoryAllocator _cacheAllocator; private static CacheMemoryAllocator _cacheAllocator;
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
private static readonly Dictionary<int, EntryUsageStats> _entryUsageStats = [];
private static readonly Lock _lock = new(); private static readonly Lock _lock = new();
private static bool _initialized; private static bool _initialized;
private static int _cacheSize;
// Basic statistics
private static int _totalAllocations = 0;
private static int _totalEvictions = 0;
private class EntryUsageStats
{
public long LastAccessTime { get; private set; }
public int UsageCount { get; private set; }
public EntryUsageStats()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount = 1;
}
public void UpdateUsage()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount++;
}
}
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
[LibraryImport("kernel32.dll", SetLastError = true)] [LibraryImport("kernel32.dll", SetLastError = true)]
@ -48,20 +81,22 @@ namespace ARMeilleure.Translation.Cache
return; return;
} }
_jitRegion = new ReservedRegion(allocator, CacheSize); _cacheSize = Optimizations.CacheEviction ? ReducedCacheSize : FullCacheSize;
_jitRegion = new ReservedRegion(allocator, (ulong)_cacheSize);
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{ {
_jitCacheInvalidator = new JitCacheInvalidation(allocator); _jitCacheInvalidator = new JitCacheInvalidation(allocator);
} }
_cacheAllocator = new CacheMemoryAllocator(CacheSize); _cacheAllocator = new CacheMemoryAllocator(_cacheSize);
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {
JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(_pageSize)); JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, (uint)_cacheSize, _jitRegion.Pointer + Allocate(_pageSize));
} }
Logger.Info?.Print(LogClass.Cpu, $"JIT Cache initialized: Size={_cacheSize / (1024 * 1024)} MB, Eviction={Optimizations.CacheEviction}");
_initialized = true; _initialized = true;
} }
} }
@ -73,8 +108,32 @@ namespace ARMeilleure.Translation.Cache
lock (_lock) lock (_lock)
{ {
Debug.Assert(_initialized); Debug.Assert(_initialized);
_totalAllocations++;
int funcOffset = Allocate(code.Length); int funcOffset;
if (Optimizations.CacheEviction)
{
int codeSize = AlignCodeSize(code.Length);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
EvictEntries(codeSize);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
throw new OutOfMemoryException("JIT Cache exhausted even after eviction.");
}
}
_jitRegion.ExpandIfNeeded((ulong)funcOffset + (ulong)codeSize);
}
else
{
funcOffset = Allocate(code.Length);
}
IntPtr funcPtr = _jitRegion.Pointer + funcOffset; IntPtr funcPtr = _jitRegion.Pointer + funcOffset;
@ -106,6 +165,12 @@ namespace ARMeilleure.Translation.Cache
Add(funcOffset, code.Length, func.UnwindInfo); Add(funcOffset, code.Length, func.UnwindInfo);
// Simple periodic logging
if (_totalAllocations % LogInterval == 0)
{
LogCacheStatus();
}
return funcPtr; return funcPtr;
} }
} }
@ -122,6 +187,11 @@ namespace ARMeilleure.Translation.Cache
{ {
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
_cacheEntries.RemoveAt(entryIndex); _cacheEntries.RemoveAt(entryIndex);
if (Optimizations.CacheEviction)
{
_entryUsageStats.Remove(funcOffset);
}
} }
} }
} }
@ -179,6 +249,11 @@ namespace ARMeilleure.Translation.Cache
} }
_cacheEntries.Insert(index, entry); _cacheEntries.Insert(index, entry);
if (Optimizations.CacheEviction)
{
_entryUsageStats[offset] = new EntryUsageStats();
}
} }
public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex) public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
@ -195,6 +270,12 @@ namespace ARMeilleure.Translation.Cache
if (index >= 0) if (index >= 0)
{ {
entry = _cacheEntries[index]; entry = _cacheEntries[index];
if (Optimizations.CacheEviction && _entryUsageStats.TryGetValue(offset, out var stats))
{
stats.UpdateUsage();
}
entryIndex = index; entryIndex = index;
return true; return true;
} }
@ -204,5 +285,83 @@ namespace ARMeilleure.Translation.Cache
entryIndex = 0; entryIndex = 0;
return false; return false;
} }
private static void EvictEntries(int requiredSize)
{
if (!Optimizations.CacheEviction)
{
return;
}
lock (_lock)
{
int targetSpace = Math.Max(requiredSize, (int)(_cacheSize * EvictionTargetPercentage));
int freedSpace = 0;
int evictedCount = 0;
var entriesWithStats = _cacheEntries
.Where(e => _entryUsageStats.ContainsKey(e.Offset))
.Select(e => new {
Entry = e,
Stats = _entryUsageStats[e.Offset],
Score = CalculateEvictionScore(_entryUsageStats[e.Offset])
})
.OrderBy(x => x.Score)
.Take(MaxEntriesToEvictAtOnce)
.ToList();
foreach (var item in entriesWithStats)
{
int entrySize = AlignCodeSize(item.Entry.Size);
int entryIndex = _cacheEntries.BinarySearch(item.Entry);
if (entryIndex >= 0)
{
_cacheAllocator.Free(item.Entry.Offset, entrySize);
_cacheEntries.RemoveAt(entryIndex);
_entryUsageStats.Remove(item.Entry.Offset);
freedSpace += entrySize;
evictedCount++;
if (freedSpace >= targetSpace)
{
break;
}
}
}
_totalEvictions += evictedCount;
Logger.Info?.Print(LogClass.Cpu, $"JIT Cache: Evicted {evictedCount} entries, freed {freedSpace / (1024 * 1024.0):F2} MB");
}
}
private static double CalculateEvictionScore(EntryUsageStats stats)
{
long currentTime = DateTime.UtcNow.Ticks;
long ageInTicks = currentTime - stats.LastAccessTime;
double ageInSeconds = ageInTicks / 10_000_000.0;
const double usageWeight = 1.0;
const double ageWeight = 2.0;
double usageScore = Math.Log10(stats.UsageCount + 1) * usageWeight;
double ageScore = (10.0 / (ageInSeconds + 1.0)) * ageWeight;
return usageScore + ageScore;
}
private static void LogCacheStatus()
{
int estimatedUsedSize = _cacheEntries.Sum(e => AlignCodeSize(e.Size));
double usagePercentage = 100.0 * estimatedUsedSize / _cacheSize;
Logger.Info?.Print(LogClass.Cpu,
$"JIT Cache status: entries={_cacheEntries.Count}, " +
$"est. used={estimatedUsedSize / (1024 * 1024.0):F2} MB ({usagePercentage:F1}%), " +
$"evictions={_totalEvictions}, allocations={_totalAllocations}");
}
} }
} }

View file

@ -1,5 +1,4 @@
using ARMeilleure.Instructions; using ARMeilleure.Instructions;
using ARMeilleure.State;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;

View file

@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 6998; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 7008; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";
@ -563,6 +563,7 @@ namespace ARMeilleure.Translation.PTC
{ {
if (AreCarriersEmpty() || ContainsBlacklistedFunctions()) if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
{ {
ResetCarriersIfNeeded();
return; return;
} }
@ -869,7 +870,7 @@ namespace ARMeilleure.Translation.PTC
Debug.Assert(Profiler.IsAddressInStaticCodeRange(address)); Debug.Assert(Profiler.IsAddressInStaticCodeRange(address));
TranslatedFunction func = translator.Translate(address, executionMode, highCq); TranslatedFunction func = translator.Translate(address, executionMode, highCq, pptcTranslation: true);
if (func == null) if (func == null)
{ {

View file

@ -219,7 +219,7 @@ namespace ARMeilleure.Translation
} }
} }
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false) internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false, bool pptcTranslation = false)
{ {
var context = new ArmEmitterContext( var context = new ArmEmitterContext(
Memory, Memory,
@ -246,7 +246,12 @@ namespace ARMeilleure.Translation
context.Branch(context.GetLabel(address)); context.Branch(context.GetLabel(address));
} }
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter); ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter, pptcTranslation);
if (cfg == null)
{
return null;
}
ulong funcSize = funcRange.End - funcRange.Start; ulong funcSize = funcRange.End - funcRange.Start;
@ -321,7 +326,8 @@ namespace ARMeilleure.Translation
ArmEmitterContext context, ArmEmitterContext context,
Block[] blocks, Block[] blocks,
out Range range, out Range range,
out Counter<uint> counter) out Counter<uint> counter,
bool pptcTranslation)
{ {
counter = null; counter = null;
@ -406,6 +412,14 @@ namespace ARMeilleure.Translation
if (opCode.Instruction.Emitter != null) if (opCode.Instruction.Emitter != null)
{ {
opCode.Instruction.Emitter(context); opCode.Instruction.Emitter(context);
// if we're pre-compiling PPTC functions, and we hit an Undefined instruction as the first
// instruction in the block, mark the function as blacklisted
// this way, we don't pre-compile Exlaunch hooks, which allows ExeFS mods to run with PPTC
if (pptcTranslation && opCode.Instruction.Name == InstName.Und && blkIndex == 0)
{
range = new Range(rangeStart, rangeEnd);
return null;
}
} }
else else
{ {

View file

@ -1,20 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64</RuntimeIdentifiers>
<AssemblyName>Kenjinx.Headless</AssemblyName>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>2.0.3</Version> <Version>2.0.3</Version>
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants> <DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
<SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate> <SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate>
<ApplicationIcon>Kenjinx.ico</ApplicationIcon>
<IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion> <IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' == '' AND '$(BuildingInsideVisualStudio)' == 'true'">
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('OSX'))">osx-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'win-arm64'">
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="OpenTK.Core" /> <PackageReference Include="OpenTK.Core" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-arm64'" />
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.Linux" Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'" /> <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.Linux" Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'" />
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.macOS" Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'" /> <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.macOS" Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'" />
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.Windows" Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-arm64'" /> <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.Windows" Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-arm64'" />
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'" />
<PackageReference Include="Silk.NET.Vulkan" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<PackageReference Include="SPB" />
<PackageReference Include="SharpZipLib" />
</ItemGroup> </ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))"> <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
@ -39,6 +65,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-arm64'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>alsoft.ini</TargetPath>
</Content>
<Content Include="..\..\distribution\legal\THIRDPARTY.md"> <Content Include="..\..\distribution\legal\THIRDPARTY.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>THIRDPARTY.md</TargetPath> <TargetPath>THIRDPARTY.md</TargetPath>
@ -47,6 +77,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>LICENSE.txt</TargetPath> <TargetPath>LICENSE.txt</TargetPath>
</Content> </Content>
<Content Include="Kenjinx.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'" > <ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'" >

View file

@ -470,6 +470,7 @@ namespace Ryujinx.Ava
public void Start() public void Start()
{ {
ARMeilleure.Optimizations.EcoFriendly = ConfigurationState.Instance.System.EnableLowPowerPtc; ARMeilleure.Optimizations.EcoFriendly = ConfigurationState.Instance.System.EnableLowPowerPtc;
ARMeilleure.Optimizations.CacheEviction = ConfigurationState.Instance.System.EnableJitCacheEviction;
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (ذاكرة التخزين المؤقت للترجمة المستمرة)", "SettingsTabSystemEnablePptc": "PPTC (ذاكرة التخزين المؤقت للترجمة المستمرة)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "التحقق من سلامة نظام الملفات", "SettingsTabSystemEnableFsIntegrityChecks": "التحقق من سلامة نظام الملفات",
"SettingsTabSystemAudioBackend": "خلفية الصوت:", "SettingsTabSystemAudioBackend": "خلفية الصوت:",
"SettingsTabSystemAudioBackendDummy": "زائف", "SettingsTabSystemAudioBackendDummy": "زائف",
@ -589,7 +590,8 @@
"TimeTooltip": "تغيير وقت النظام", "TimeTooltip": "تغيير وقت النظام",
"VSyncToggleTooltip": "محاكاة المزامنة العمودية للجهاز. في الأساس محدد الإطار لغالبية الألعاب؛ قد يؤدي تعطيله إلى تشغيل الألعاب بسرعة أعلى أو جعل شاشات التحميل تستغرق وقتا أطول أو تتعطل.\n\nيمكن تبديله داخل اللعبة باستخدام مفتاح التشغيل السريع الذي تفضله (F1 افتراضيا). نوصي بالقيام بذلك إذا كنت تخطط لتعطيله.\n\nاتركه ممكنا إذا لم تكن متأكدا.", "VSyncToggleTooltip": "محاكاة المزامنة العمودية للجهاز. في الأساس محدد الإطار لغالبية الألعاب؛ قد يؤدي تعطيله إلى تشغيل الألعاب بسرعة أعلى أو جعل شاشات التحميل تستغرق وقتا أطول أو تتعطل.\n\nيمكن تبديله داخل اللعبة باستخدام مفتاح التشغيل السريع الذي تفضله (F1 افتراضيا). نوصي بالقيام بذلك إذا كنت تخطط لتعطيله.\n\nاتركه ممكنا إذا لم تكن متأكدا.",
"PptcToggleTooltip": "يحفظ وظائف JIT المترجمة بحيث لا تحتاج إلى ترجمتها في كل مرة يتم فيها تحميل اللعبة.\n\nيقلل من التقطيع ويسرع بشكل ملحوظ أوقات التشغيل بعد التشغيل الأول للعبة.\n\nاتركه ممكنا إذا لم تكن متأكدا.", "PptcToggleTooltip": "يحفظ وظائف JIT المترجمة بحيث لا تحتاج إلى ترجمتها في كل مرة يتم فيها تحميل اللعبة.\n\nيقلل من التقطيع ويسرع بشكل ملحوظ أوقات التشغيل بعد التشغيل الأول للعبة.\n\nاتركه ممكنا إذا لم تكن متأكدا.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "قم بتحميل PPTC باستخدام ثلث كمية النوى",
"JitCacheEvictionToggleTooltip": "م بتمكين إخلاء JIT Cache لإدارة الذاكرة بكفاءة",
"FsIntegrityToggleTooltip": "يتحقق من وجود ملفات تالفة عند تشغيل لعبة ما، وإذا تم اكتشاف ملفات تالفة، فسيتم عرض خطأ تجزئة في السجل.\n\nليس له أي تأثير على الأداء ويهدف إلى المساعدة في استكشاف الأخطاء وإصلاحها.\n\nاتركه مفعلا إذا كنت غير متأكد.", "FsIntegrityToggleTooltip": "يتحقق من وجود ملفات تالفة عند تشغيل لعبة ما، وإذا تم اكتشاف ملفات تالفة، فسيتم عرض خطأ تجزئة في السجل.\n\nليس له أي تأثير على الأداء ويهدف إلى المساعدة في استكشاف الأخطاء وإصلاحها.\n\nاتركه مفعلا إذا كنت غير متأكد.",
"AudioBackendTooltip": "يغير الواجهة الخلفية المستخدمة لتقديم الصوت.\n\nSDL2 هو الخيار المفضل، بينما يتم استخدام OpenAL وSoundIO كبديلين. زائف لن يكون لها صوت.\n\nاضبط على SDL2 إذا لم تكن متأكدا.", "AudioBackendTooltip": "يغير الواجهة الخلفية المستخدمة لتقديم الصوت.\n\nSDL2 هو الخيار المفضل، بينما يتم استخدام OpenAL وSoundIO كبديلين. زائف لن يكون لها صوت.\n\nاضبط على SDL2 إذا لم تكن متأكدا.",
"MemoryManagerTooltip": "تغيير كيفية تعيين ذاكرة الضيف والوصول إليها. يؤثر بشكل كبير على أداء وحدة المعالجة المركزية التي تمت محاكاتها.\n\nاضبط على المضيف غير محدد إذا لم تكن متأكدا.", "MemoryManagerTooltip": "تغيير كيفية تعيين ذاكرة الضيف والوصول إليها. يؤثر بشكل كبير على أداء وحدة المعالجة المركزية التي تمت محاكاتها.\n\nاضبط على المضيف غير محدد إذا لم تكن متأكدا.",

View file

@ -148,6 +148,7 @@
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Kleinleistungs-PPTC", "SettingsTabSystemEnableLowPowerPptc": "Kleinleistungs-PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit-Cache-Räumung",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integritätsprüfung", "SettingsTabSystemEnableFsIntegrityChecks": "FS Integritätsprüfung",
"SettingsTabSystemAudioBackend": "Audio-Backend:", "SettingsTabSystemAudioBackend": "Audio-Backend:",
"SettingsTabSystemAudioBackendDummy": "Ohne Funktion", "SettingsTabSystemAudioBackendDummy": "Ohne Funktion",
@ -591,6 +592,7 @@
"VSyncToggleTooltip": "Vertikale Synchronisierung der emulierten Konsole. Diese Option ist quasi ein Frame-Limiter für die meisten Spiele; die Deaktivierung kann dazu führen, dass Spiele mit höherer Geschwindigkeit laufen oder Ladebildschirme länger benötigen/hängen bleiben.\n\nKann beim Spielen mit einem frei wählbaren Hotkey ein- und ausgeschaltet werden (standardmäßig F1). \n\nIm Zweifelsfall AN lassen.", "VSyncToggleTooltip": "Vertikale Synchronisierung der emulierten Konsole. Diese Option ist quasi ein Frame-Limiter für die meisten Spiele; die Deaktivierung kann dazu führen, dass Spiele mit höherer Geschwindigkeit laufen oder Ladebildschirme länger benötigen/hängen bleiben.\n\nKann beim Spielen mit einem frei wählbaren Hotkey ein- und ausgeschaltet werden (standardmäßig F1). \n\nIm Zweifelsfall AN lassen.",
"PptcToggleTooltip": "Speichert übersetzte JIT-Funktionen, sodass jene nicht jedes Mal übersetzt werden müssen, wenn das Spiel geladen wird.\n\nVerringert Stottern und die Zeit beim zweiten und den darauffolgenden Startvorgängen eines Spiels erheblich.\n\nIm Zweifelsfall AN lassen.", "PptcToggleTooltip": "Speichert übersetzte JIT-Funktionen, sodass jene nicht jedes Mal übersetzt werden müssen, wenn das Spiel geladen wird.\n\nVerringert Stottern und die Zeit beim zweiten und den darauffolgenden Startvorgängen eines Spiels erheblich.\n\nIm Zweifelsfall AN lassen.",
"LowPowerPptcToggleTooltip": "Lädt den PPTC mit einem Drittel der verfügbaren Prozessorkernen", "LowPowerPptcToggleTooltip": "Lädt den PPTC mit einem Drittel der verfügbaren Prozessorkernen",
"JitCacheEvictionToggleTooltip": "Aktivieren Sie die JIT-Cache-Eviction, um den Speicher effizient zu verwalten",
"FsIntegrityToggleTooltip": "Prüft beim Startvorgang auf beschädigte Dateien und zeigt bei beschädigten Dateien einen Hash-Fehler (Hash Error) im Log an.\n\nDiese Einstellung hat keinen Einfluss auf die Leistung und hilft bei der Fehlersuche.\n\nIm Zweifelsfall AN lassen.", "FsIntegrityToggleTooltip": "Prüft beim Startvorgang auf beschädigte Dateien und zeigt bei beschädigten Dateien einen Hash-Fehler (Hash Error) im Log an.\n\nDiese Einstellung hat keinen Einfluss auf die Leistung und hilft bei der Fehlersuche.\n\nIm Zweifelsfall AN lassen.",
"AudioBackendTooltip": "Ändert das Backend, das zum Rendern von Audio verwendet wird.\n\nSDL2 ist das bevorzugte Audio-Backend, OpenAL und SoundIO sind als Alternativen vorhanden. Dummy wird keinen Audio-Output haben.\n\nIm Zweifelsfall SDL2 auswählen.", "AudioBackendTooltip": "Ändert das Backend, das zum Rendern von Audio verwendet wird.\n\nSDL2 ist das bevorzugte Audio-Backend, OpenAL und SoundIO sind als Alternativen vorhanden. Dummy wird keinen Audio-Output haben.\n\nIm Zweifelsfall SDL2 auswählen.",
"MemoryManagerTooltip": "Ändert wie der Gastspeicher abgebildet wird und wie auf ihn zugegriffen wird. Beinflusst die Leistung der emulierten CPU erheblich.\n\nIm Zweifelsfall Host ungeprüft auswählen.", "MemoryManagerTooltip": "Ändert wie der Gastspeicher abgebildet wird und wie auf ihn zugegriffen wird. Beinflusst die Leistung der emulierten CPU erheblich.\n\nIm Zweifelsfall Host ungeprüft auswählen.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "Ενεργοποίηση Κατακόρυφου Συγχρονισμού", "SettingsTabSystemEnableVsync": "Ενεργοποίηση Κατακόρυφου Συγχρονισμού",
"SettingsTabSystemEnablePptc": "Ενεργοποίηση PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "Ενεργοποίηση PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Ενεργοποίηση Ελέγχων Ακεραιότητας FS", "SettingsTabSystemEnableFsIntegrityChecks": "Ενεργοποίηση Ελέγχων Ακεραιότητας FS",
"SettingsTabSystemAudioBackend": "Backend Ήχου:", "SettingsTabSystemAudioBackend": "Backend Ήχου:",
"SettingsTabSystemAudioBackendDummy": "Απενεργοποιημένο", "SettingsTabSystemAudioBackendDummy": "Απενεργοποιημένο",
@ -589,7 +590,8 @@
"TimeTooltip": "Αλλαγή Ώρας Συστήματος", "TimeTooltip": "Αλλαγή Ώρας Συστήματος",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "Ενεργοποιεί ή απενεργοποιεί το PPTC", "PptcToggleTooltip": "Ενεργοποιεί ή απενεργοποιεί το PPTC",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Φορτώστε το PPTC χρησιμοποιώντας το ένα τρίτο της ποσότητας πυρήνων",
"JitCacheEvictionToggleTooltip": "Ενεργοποιήστε την εξαγωγή JIT Cache για αποτελεσματική διαχείριση της μνήμης",
"FsIntegrityToggleTooltip": "Ενεργοποιεί τους ελέγχους ακεραιότητας σε αρχεία περιεχομένου παιχνιδιού", "FsIntegrityToggleTooltip": "Ενεργοποιεί τους ελέγχους ακεραιότητας σε αρχεία περιεχομένου παιχνιδιού",
"AudioBackendTooltip": "Αλλαγή ήχου υποστήριξης", "AudioBackendTooltip": "Αλλαγή ήχου υποστήριξης",
"MemoryManagerTooltip": "Αλλάξτε τον τρόπο αντιστοίχισης και πρόσβασης στη μνήμη επισκέπτη. Επηρεάζει σε μεγάλο βαθμό την απόδοση της προσομοίωσης της CPU.", "MemoryManagerTooltip": "Αλλάξτε τον τρόπο αντιστοίχισης και πρόσβασης στη μνήμη επισκέπτη. Επηρεάζει σε μεγάλο βαθμό την απόδοση της προσομοίωσης της CPU.",

View file

@ -168,6 +168,7 @@
"SettingsTabSystemCustomVSyncIntervalValue": "Custom Refresh Rate Value:", "SettingsTabSystemCustomVSyncIntervalValue": "Custom Refresh Rate Value:",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC cache", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC cache",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks", "SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks",
"SettingsTabSystemAudioBackend": "Audio Backend:", "SettingsTabSystemAudioBackend": "Audio Backend:",
"SettingsTabSystemAudioBackendDummy": "Dummy", "SettingsTabSystemAudioBackendDummy": "Dummy",
@ -621,7 +622,8 @@
"MatchTimeTooltip": "Sync System Time to match your PC's current date & time.", "MatchTimeTooltip": "Sync System Time to match your PC's current date & time.",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "Saves translated JIT functions so that they do not need to be translated every time the game loads.\n\nReduces stuttering and significantly speeds up boot times after the first boot of a game.\n\nLeave ON if unsure.", "PptcToggleTooltip": "Saves translated JIT functions so that they do not need to be translated every time the game loads.\n\nReduces stuttering and significantly speeds up boot times after the first boot of a game.\n\nLeave ON if unsure.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores",
"JitCacheEvictionToggleTooltip": "Enable JIT Cache eviction to manage memory efficiently",
"FsIntegrityToggleTooltip": "Checks for corrupt files when booting a game, and if corrupt files are detected, displays a hash error in the log.\n\nHas no impact on performance and is meant to help troubleshooting.\n\nLeave ON if unsure.", "FsIntegrityToggleTooltip": "Checks for corrupt files when booting a game, and if corrupt files are detected, displays a hash error in the log.\n\nHas no impact on performance and is meant to help troubleshooting.\n\nLeave ON if unsure.",
"AudioBackendTooltip": "Changes the backend used to render audio.\n\nSDL2 is the preferred one, while OpenAL and SoundIO are used as fallbacks. Dummy will have no sound.\n\nSet to SDL2 if unsure.", "AudioBackendTooltip": "Changes the backend used to render audio.\n\nSDL2 is the preferred one, while OpenAL and SoundIO are used as fallbacks. Dummy will have no sound.\n\nSet to SDL2 if unsure.",
"MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.\n\nSet to HOST UNCHECKED if unsure.", "MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.\n\nSet to HOST UNCHECKED if unsure.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "Sincronización vertical", "SettingsTabSystemEnableVsync": "Sincronización vertical",
"SettingsTabSystemEnablePptc": "PPTC (Cache de Traducción de Perfil Persistente)", "SettingsTabSystemEnablePptc": "PPTC (Cache de Traducción de Perfil Persistente)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Comprobar integridad de los archivos", "SettingsTabSystemEnableFsIntegrityChecks": "Comprobar integridad de los archivos",
"SettingsTabSystemAudioBackend": "Motor de audio:", "SettingsTabSystemAudioBackend": "Motor de audio:",
"SettingsTabSystemAudioBackendDummy": "Vacio", "SettingsTabSystemAudioBackendDummy": "Vacio",
@ -589,7 +590,8 @@
"TimeTooltip": "Cambia la hora del sistema", "TimeTooltip": "Cambia la hora del sistema",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "Guarda funciones de JIT traducidas para que no sea necesario traducirlas cada vez que el juego carga.\n\nReduce los tirones y acelera significativamente el tiempo de inicio de los juegos después de haberlos ejecutado al menos una vez.\n\nActívalo si no sabes qué hacer.", "PptcToggleTooltip": "Guarda funciones de JIT traducidas para que no sea necesario traducirlas cada vez que el juego carga.\n\nReduce los tirones y acelera significativamente el tiempo de inicio de los juegos después de haberlos ejecutado al menos una vez.\n\nActívalo si no sabes qué hacer.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Cargue el PPTC usando un tercio de la cantidad de núcleos",
"JitCacheEvictionToggleTooltip": "Habilite el desalojo de JIT Cache para administrar la memoria de manera eficiente",
"FsIntegrityToggleTooltip": "Comprueba si hay archivos corruptos en los juegos que ejecutes al abrirlos, y si detecta archivos corruptos, muestra un error de Hash en los registros.\n\nEsto no tiene impacto alguno en el rendimiento y está pensado para ayudar a resolver problemas.\n\nActívalo si no sabes qué hacer.", "FsIntegrityToggleTooltip": "Comprueba si hay archivos corruptos en los juegos que ejecutes al abrirlos, y si detecta archivos corruptos, muestra un error de Hash en los registros.\n\nEsto no tiene impacto alguno en el rendimiento y está pensado para ayudar a resolver problemas.\n\nActívalo si no sabes qué hacer.",
"AudioBackendTooltip": "Cambia el motor usado para renderizar audio.\n\nSDL2 es el preferido, mientras que OpenAL y SoundIO se usan si hay problemas con este. Dummy no produce audio.\n\nSelecciona SDL2 si no sabes qué hacer.", "AudioBackendTooltip": "Cambia el motor usado para renderizar audio.\n\nSDL2 es el preferido, mientras que OpenAL y SoundIO se usan si hay problemas con este. Dummy no produce audio.\n\nSelecciona SDL2 si no sabes qué hacer.",
"MemoryManagerTooltip": "Cambia la forma de mapear y acceder a la memoria del guest. Afecta en gran medida al rendimiento de la CPU emulada.\n\nSelecciona \"Host sin verificación\" si no sabes qué hacer.", "MemoryManagerTooltip": "Cambia la forma de mapear y acceder a la memoria del guest. Afecta en gran medida al rendimiento de la CPU emulada.\n\nSelecciona \"Host sin verificación\" si no sabes qué hacer.",

View file

@ -149,6 +149,7 @@
"SettingsTabSystemEnableVsync": "Synchronisation verticale (VSync)", "SettingsTabSystemEnableVsync": "Synchronisation verticale (VSync)",
"SettingsTabSystemEnablePptc": "Activer le PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "Activer le PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Activer la vérification de l'intégrité du système de fichiers", "SettingsTabSystemEnableFsIntegrityChecks": "Activer la vérification de l'intégrité du système de fichiers",
"SettingsTabSystemAudioBackend": "Bibliothèque Audio :", "SettingsTabSystemAudioBackend": "Bibliothèque Audio :",
"SettingsTabSystemAudioBackendDummy": "Factice", "SettingsTabSystemAudioBackendDummy": "Factice",
@ -592,7 +593,8 @@
"MatchTimeTooltip": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.", "MatchTimeTooltip": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.",
"VSyncToggleTooltip": "La synchronisation verticale de la console émulée. Essentiellement un limiteur de trame pour la majorité des jeux ; le désactiver peut entraîner un fonctionnement plus rapide des jeux ou prolonger ou bloquer les écrans de chargement.\n\nPeut être activé ou désactivé en jeu avec un raccourci clavier de votre choix (F1 par défaut). Nous recommandons de le faire si vous envisagez de le désactiver.\n\nLaissez activé si vous n'êtes pas sûr.", "VSyncToggleTooltip": "La synchronisation verticale de la console émulée. Essentiellement un limiteur de trame pour la majorité des jeux ; le désactiver peut entraîner un fonctionnement plus rapide des jeux ou prolonger ou bloquer les écrans de chargement.\n\nPeut être activé ou désactivé en jeu avec un raccourci clavier de votre choix (F1 par défaut). Nous recommandons de le faire si vous envisagez de le désactiver.\n\nLaissez activé si vous n'êtes pas sûr.",
"PptcToggleTooltip": "Sauvegarde les fonctions JIT afin qu'elles n'aient pas besoin d'être à chaque fois recompiler lorsque le jeu se charge.\n\nRéduit les lags et accélère considérablement le temps de chargement après le premier lancement d'un jeu.\n\nLaissez par défaut si vous n'êtes pas sûr.", "PptcToggleTooltip": "Sauvegarde les fonctions JIT afin qu'elles n'aient pas besoin d'être à chaque fois recompiler lorsque le jeu se charge.\n\nRéduit les lags et accélère considérablement le temps de chargement après le premier lancement d'un jeu.\n\nLaissez par défaut si vous n'êtes pas sûr.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Chargez le PPTC en utilisant un tiers de la quantité de cœurs",
"JitCacheEvictionToggleTooltip": "Activer l'expulsion du cache JIT pour gérer efficacement la mémoire",
"FsIntegrityToggleTooltip": "Vérifie si des fichiers sont corrompus lors du lancement d'un jeu, et si des fichiers corrompus sont détectés, affiche une erreur de hachage dans la console.\n\nN'a aucun impact sur les performances et est destiné à aider le dépannage.\n\nLaissez activer en cas d'incertitude.", "FsIntegrityToggleTooltip": "Vérifie si des fichiers sont corrompus lors du lancement d'un jeu, et si des fichiers corrompus sont détectés, affiche une erreur de hachage dans la console.\n\nN'a aucun impact sur les performances et est destiné à aider le dépannage.\n\nLaissez activer en cas d'incertitude.",
"AudioBackendTooltip": "Modifie le backend utilisé pour donnée un rendu audio.\n\nSDL2 est préféré, tandis que OpenAL et SoundIO sont utilisés comme backend secondaire. Le backend Dummy (Factice) ne rends aucun son.\n\nLaissez sur SDL2 si vous n'êtes pas sûr.", "AudioBackendTooltip": "Modifie le backend utilisé pour donnée un rendu audio.\n\nSDL2 est préféré, tandis que OpenAL et SoundIO sont utilisés comme backend secondaire. Le backend Dummy (Factice) ne rends aucun son.\n\nLaissez sur SDL2 si vous n'êtes pas sûr.",
"MemoryManagerTooltip": "Change la façon dont la mémoire émulée est mappée et utiliser. Cela affecte grandement les performances du processeur.\n\nRéglez sur Host Uncheked en cas d'incertitude.", "MemoryManagerTooltip": "Change la façon dont la mémoire émulée est mappée et utiliser. Cela affecte grandement les performances du processeur.\n\nRéglez sur Host Uncheked en cas d'incertitude.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "FS בדיקות תקינות", "SettingsTabSystemEnableFsIntegrityChecks": "FS בדיקות תקינות",
"SettingsTabSystemAudioBackend": "אחראי שמע:", "SettingsTabSystemAudioBackend": "אחראי שמע:",
"SettingsTabSystemAudioBackendDummy": "גולם", "SettingsTabSystemAudioBackendDummy": "גולם",
@ -589,7 +590,8 @@
"TimeTooltip": "שנה זמן מערכת", "TimeTooltip": "שנה זמן מערכת",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "שומר את פונקציות ה-JIT המתורגמות כך שלא יצטרכו לעבור תרגום שוב כאשר משחק עולה.\n\nמפחית תקיעות ומשפר מהירות עלייה של המערכת אחרי הפתיחה הראשונה של המשחק.\n\nמוטב להשאיר דלוק אם לא בטוחים.", "PptcToggleTooltip": "שומר את פונקציות ה-JIT המתורגמות כך שלא יצטרכו לעבור תרגום שוב כאשר משחק עולה.\n\nמפחית תקיעות ומשפר מהירות עלייה של המערכת אחרי הפתיחה הראשונה של המשחק.\n\nמוטב להשאיר דלוק אם לא בטוחים.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "טען את ה-PPTC באמצעות שליש מכמות הליבות",
"JitCacheEvictionToggleTooltip": "אפשר פינוי JIT Cache לניהול זיכרון ביעילות",
"FsIntegrityToggleTooltip": "בודק לקבצים שגויים כאשר משחק עולה, ואם מתגלים כאלו, מציג את מזהה השגיאה שלהם לקובץ הלוג.\n\nאין לכך השפעה על הביצועים ונועד לעזור לבדיקה וניפוי שגיאות של האמולטור.\n\nמוטב להשאיר דלוק אם לא בטוחים.", "FsIntegrityToggleTooltip": "בודק לקבצים שגויים כאשר משחק עולה, ואם מתגלים כאלו, מציג את מזהה השגיאה שלהם לקובץ הלוג.\n\nאין לכך השפעה על הביצועים ונועד לעזור לבדיקה וניפוי שגיאות של האמולטור.\n\nמוטב להשאיר דלוק אם לא בטוחים.",
"AudioBackendTooltip": "משנה את אחראי השמע.\n\nSDL2 הוא הנבחר, למראת שOpenAL וגם SoundIO משומשים כאפשרויות חלופיות. אפשרות הDummy לא תשמיע קול כלל.\n\nמוטב להשאיר על SDL2 אם לא בטוחים.", "AudioBackendTooltip": "משנה את אחראי השמע.\n\nSDL2 הוא הנבחר, למראת שOpenAL וגם SoundIO משומשים כאפשרויות חלופיות. אפשרות הDummy לא תשמיע קול כלל.\n\nמוטב להשאיר על SDL2 אם לא בטוחים.",
"MemoryManagerTooltip": "שנה איך שזיכרון מארח מיוחד ומונגד. משפיע מאוד על ביצועי המעבד המדומה.\n\nמוטב להשאיר על מארח לא מבוקר אם לא בטוחים.", "MemoryManagerTooltip": "שנה איך שזיכרון מארח מיוחד ומונגד. משפיע מאוד על ביצועי המעבד המדומה.\n\nמוטב להשאיר על מארח לא מבוקר אם לא בטוחים.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "Attiva VSync", "SettingsTabSystemEnableVsync": "Attiva VSync",
"SettingsTabSystemEnablePptc": "Attiva PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "Attiva PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Attiva controlli d'integrità FS", "SettingsTabSystemEnableFsIntegrityChecks": "Attiva controlli d'integrità FS",
"SettingsTabSystemAudioBackend": "Backend audio:", "SettingsTabSystemAudioBackend": "Backend audio:",
"SettingsTabSystemAudioBackendDummy": "Dummy", "SettingsTabSystemAudioBackendDummy": "Dummy",
@ -590,7 +591,8 @@
"MatchTimeTooltip": "Sincronizza data e ora del sistema con quelle del PC.", "MatchTimeTooltip": "Sincronizza data e ora del sistema con quelle del PC.",
"VSyncToggleTooltip": "Sincronizzazione verticale della console Emulata. Essenzialmente un limitatore di frame per la maggior parte dei giochi; disabilitarlo può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata in gioco con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarlo.\n\nLascia ON se non sei sicuro.", "VSyncToggleTooltip": "Sincronizzazione verticale della console Emulata. Essenzialmente un limitatore di frame per la maggior parte dei giochi; disabilitarlo può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata in gioco con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarlo.\n\nLascia ON se non sei sicuro.",
"PptcToggleTooltip": "Salva le funzioni JIT tradotte in modo che non debbano essere tradotte tutte le volte che si avvia un determinato gioco.\n\nRiduce i fenomeni di stuttering e velocizza sensibilmente gli avvii successivi del gioco.\n\nNel dubbio, lascia l'opzione attiva.", "PptcToggleTooltip": "Salva le funzioni JIT tradotte in modo che non debbano essere tradotte tutte le volte che si avvia un determinato gioco.\n\nRiduce i fenomeni di stuttering e velocizza sensibilmente gli avvii successivi del gioco.\n\nNel dubbio, lascia l'opzione attiva.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Carica il PPTC utilizzando un terzo della quantità di core",
"JitCacheEvictionToggleTooltip": "Abilita l'eliminazione della cache JIT per gestire la memoria in modo efficiente",
"FsIntegrityToggleTooltip": "Controlla la presenza di file corrotti quando si avvia un gioco. Se vengono rilevati dei file corrotti, verrà mostrato un errore di hash nel log.\n\nQuesta opzione non influisce sulle prestazioni ed è pensata per facilitare la risoluzione dei problemi.\n\nNel dubbio, lascia l'opzione attiva.", "FsIntegrityToggleTooltip": "Controlla la presenza di file corrotti quando si avvia un gioco. Se vengono rilevati dei file corrotti, verrà mostrato un errore di hash nel log.\n\nQuesta opzione non influisce sulle prestazioni ed è pensata per facilitare la risoluzione dei problemi.\n\nNel dubbio, lascia l'opzione attiva.",
"AudioBackendTooltip": "Cambia il backend usato per riprodurre l'audio.\n\nSDL2 è quello preferito, mentre OpenAL e SoundIO sono usati come ripiego. Dummy non riprodurrà alcun suono.\n\nNel dubbio, imposta l'opzione su SDL2.", "AudioBackendTooltip": "Cambia il backend usato per riprodurre l'audio.\n\nSDL2 è quello preferito, mentre OpenAL e SoundIO sono usati come ripiego. Dummy non riprodurrà alcun suono.\n\nNel dubbio, imposta l'opzione su SDL2.",
"MemoryManagerTooltip": "Cambia il modo in cui la memoria guest è mappata e vi si accede. Influisce notevolmente sulle prestazioni della CPU emulata.\n\nNel dubbio, imposta l'opzione su Host Unchecked.", "MemoryManagerTooltip": "Cambia il modo in cui la memoria guest è mappata e vi si accede. Influisce notevolmente sulle prestazioni della CPU emulata.\n\nNel dubbio, imposta l'opzione su Host Unchecked.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "ファイルシステム整合性チェック", "SettingsTabSystemEnableFsIntegrityChecks": "ファイルシステム整合性チェック",
"SettingsTabSystemAudioBackend": "音声バックエンド:", "SettingsTabSystemAudioBackend": "音声バックエンド:",
"SettingsTabSystemAudioBackendDummy": "ダミー", "SettingsTabSystemAudioBackendDummy": "ダミー",
@ -589,7 +590,8 @@
"TimeTooltip": "システムの時刻を変更します", "TimeTooltip": "システムの時刻を変更します",
"VSyncToggleTooltip": "エミュレートされたゲーム機の垂直同期です. 多くのゲームにおいて, フレームリミッタとして機能します. 無効にすると, ゲームが高速で実行されたり, ロード中に時間がかかったり, 止まったりすることがあります.\n\n設定したホットキー(デフォルトではF1)で, ゲーム内で切り替え可能です. 無効にする場合は, この操作を行うことをおすすめします.\n\nよくわからない場合はオンのままにしてください.", "VSyncToggleTooltip": "エミュレートされたゲーム機の垂直同期です. 多くのゲームにおいて, フレームリミッタとして機能します. 無効にすると, ゲームが高速で実行されたり, ロード中に時間がかかったり, 止まったりすることがあります.\n\n設定したホットキー(デフォルトではF1)で, ゲーム内で切り替え可能です. 無効にする場合は, この操作を行うことをおすすめします.\n\nよくわからない場合はオンのままにしてください.",
"PptcToggleTooltip": "翻訳されたJIT関数をセーブすることで, ゲームをロードするたびに毎回翻訳する処理を不要とします.\n\n一度ゲームを起動すれば,二度目以降の起動時遅延を大きく軽減できます.\n\nよくわからない場合はオンのままにしてください.", "PptcToggleTooltip": "翻訳されたJIT関数をセーブすることで, ゲームをロードするたびに毎回翻訳する処理を不要とします.\n\n一度ゲームを起動すれば,二度目以降の起動時遅延を大きく軽減できます.\n\nよくわからない場合はオンのままにしてください.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "コア数の 3 分の 1 を使用して PPTC をロードします。",
"JitCacheEvictionToggleTooltip": "JIT キャッシュのエビクションを有効にしてメモリを効率的に管理する",
"FsIntegrityToggleTooltip": "ゲーム起動時にファイル破損をチェックし,破損が検出されたらログにハッシュエラーを表示します..\n\nパフォーマンスには影響なく, トラブルシューティングに役立ちます.\n\nよくわからない場合はオンのままにしてください.", "FsIntegrityToggleTooltip": "ゲーム起動時にファイル破損をチェックし,破損が検出されたらログにハッシュエラーを表示します..\n\nパフォーマンスには影響なく, トラブルシューティングに役立ちます.\n\nよくわからない場合はオンのままにしてください.",
"AudioBackendTooltip": "音声レンダリングに使用するバックエンドを変更します.\n\nSDL2 が優先され, OpenAL と SoundIO はフォールバックとして使用されます. ダミーは音声出力しません.\n\nよくわからない場合は SDL2 を設定してください.", "AudioBackendTooltip": "音声レンダリングに使用するバックエンドを変更します.\n\nSDL2 が優先され, OpenAL と SoundIO はフォールバックとして使用されます. ダミーは音声出力しません.\n\nよくわからない場合は SDL2 を設定してください.",
"MemoryManagerTooltip": "ゲストメモリのマップ/アクセス方式を変更します. エミュレートされるCPUのパフォーマンスに大きな影響を与えます.\n\nよくわからない場合は「ホスト,チェックなし」を設定してください.", "MemoryManagerTooltip": "ゲストメモリのマップ/アクセス方式を変更します. エミュレートされるCPUのパフォーマンスに大きな影響を与えます.\n\nよくわからない場合は「ホスト,チェックなし」を設定してください.",

View file

@ -150,6 +150,7 @@
"SettingsTabSystemEnableVsync": "수직 동기화", "SettingsTabSystemEnableVsync": "수직 동기화",
"SettingsTabSystemEnablePptc": "PPTC(프로파일된 영구 번역 캐시)", "SettingsTabSystemEnablePptc": "PPTC(프로파일된 영구 번역 캐시)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "파일 시스템 무결성 검사", "SettingsTabSystemEnableFsIntegrityChecks": "파일 시스템 무결성 검사",
"SettingsTabSystemAudioBackend": "음향 후단부 :", "SettingsTabSystemAudioBackend": "음향 후단부 :",
"SettingsTabSystemAudioBackendDummy": "더미", "SettingsTabSystemAudioBackendDummy": "더미",
@ -593,7 +594,8 @@
"MatchTimeTooltip": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.", "MatchTimeTooltip": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.",
"VSyncToggleTooltip": "에뮬레이트된 콘솔의 수직 동기화. 기본적으로 대부분의 게임에 대한 프레임 제한 장치로, 비활성화시 게임이 더 빠른 속도로 실행되거나 로딩 화면이 더 오래 걸리거나 멈출 수 있습니다.\n\n게임 내에서 선호하는 핫키로 전환할 수 있습니다(기본값 F1). 핫키를 비활성화할 계획이라면 이 작업을 수행하는 것이 좋습니다.\n\n이 옵션에 대해 잘 모른다면 켜기를 권장드립니다.", "VSyncToggleTooltip": "에뮬레이트된 콘솔의 수직 동기화. 기본적으로 대부분의 게임에 대한 프레임 제한 장치로, 비활성화시 게임이 더 빠른 속도로 실행되거나 로딩 화면이 더 오래 걸리거나 멈출 수 있습니다.\n\n게임 내에서 선호하는 핫키로 전환할 수 있습니다(기본값 F1). 핫키를 비활성화할 계획이라면 이 작업을 수행하는 것이 좋습니다.\n\n이 옵션에 대해 잘 모른다면 켜기를 권장드립니다.",
"PptcToggleTooltip": "게임이 불러올 때마다 번역할 필요가 없도록 번역된 JIT 기능을 저장합니다.\n\n게임을 처음 부팅한 후 끊김 현상을 줄이고 부팅 시간을 크게 단축합니다.\n\n확실하지 않으면 켜 두세요.", "PptcToggleTooltip": "게임이 불러올 때마다 번역할 필요가 없도록 번역된 JIT 기능을 저장합니다.\n\n게임을 처음 부팅한 후 끊김 현상을 줄이고 부팅 시간을 크게 단축합니다.\n\n확실하지 않으면 켜 두세요.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "코어 양의 1/3을 사용하여 PPTC를 로드합니다.",
"JitCacheEvictionToggleTooltip": "메모리를 효율적으로 관리하기 위해 JIT 캐시 제거를 활성화합니다.",
"FsIntegrityToggleTooltip": "게임을 부팅할 때 손상된 파일을 확인하고 손상된 파일이 감지되면 로그에 해시 오류를 표시합니다.\n\n성능에 영향을 미치지 않으며 문제 해결에 도움이 됩니다.\n\n확실하지 않으면 켜 두세요.", "FsIntegrityToggleTooltip": "게임을 부팅할 때 손상된 파일을 확인하고 손상된 파일이 감지되면 로그에 해시 오류를 표시합니다.\n\n성능에 영향을 미치지 않으며 문제 해결에 도움이 됩니다.\n\n확실하지 않으면 켜 두세요.",
"AudioBackendTooltip": "오디오를 렌더링하는 데 사용되는 백엔드를 변경합니다.\n\nSDL2가 선호되는 반면 OpenAL 및 사운드IO는 폴백으로 사용됩니다. 더미는 소리가 나지 않습니다.\n\n확실하지 않으면 SDL2로 설정하세요.", "AudioBackendTooltip": "오디오를 렌더링하는 데 사용되는 백엔드를 변경합니다.\n\nSDL2가 선호되는 반면 OpenAL 및 사운드IO는 폴백으로 사용됩니다. 더미는 소리가 나지 않습니다.\n\n확실하지 않으면 SDL2로 설정하세요.",
"MemoryManagerTooltip": "게스트 메모리가 매핑되고 접속되는 방식을 변경합니다. 에뮬레이트된 CPU 성능에 크게 영향을 미칩니다.\n\n확실하지 않은 경우 호스트 확인 안함으로 설정하세요.", "MemoryManagerTooltip": "게스트 메모리가 매핑되고 접속되는 방식을 변경합니다. 에뮬레이트된 CPU 성능에 크게 영향을 미칩니다.\n\n확실하지 않은 경우 호스트 확인 안함으로 설정하세요.",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "Synchronizacja pionowa", "SettingsTabSystemEnableVsync": "Synchronizacja pionowa",
"SettingsTabSystemEnablePptc": "PPTC (Profilowana pamięć podręczna trwałych łłumaczeń)", "SettingsTabSystemEnablePptc": "PPTC (Profilowana pamięć podręczna trwałych łłumaczeń)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Sprawdzanie integralności systemu plików", "SettingsTabSystemEnableFsIntegrityChecks": "Sprawdzanie integralności systemu plików",
"SettingsTabSystemAudioBackend": "Backend Dżwięku:", "SettingsTabSystemAudioBackend": "Backend Dżwięku:",
"SettingsTabSystemAudioBackendDummy": "Atrapa", "SettingsTabSystemAudioBackendDummy": "Atrapa",
@ -589,7 +590,8 @@
"TimeTooltip": "Zmień czas systemowy", "TimeTooltip": "Zmień czas systemowy",
"VSyncToggleTooltip": "Synchronizacja pionowa emulowanej konsoli. Zasadniczo ogranicznik klatek dla większości gier; wyłączenie jej może spowodować, że gry będą działać z większą szybkością, ekrany wczytywania wydłużą się lub nawet utkną.\n\nMoże być przełączana w grze za pomocą preferowanego skrótu klawiszowego. Zalecamy to zrobić, jeśli planujesz ją wyłączyć.\n\nW razie wątpliwości pozostaw WŁĄCZONĄ.", "VSyncToggleTooltip": "Synchronizacja pionowa emulowanej konsoli. Zasadniczo ogranicznik klatek dla większości gier; wyłączenie jej może spowodować, że gry będą działać z większą szybkością, ekrany wczytywania wydłużą się lub nawet utkną.\n\nMoże być przełączana w grze za pomocą preferowanego skrótu klawiszowego. Zalecamy to zrobić, jeśli planujesz ją wyłączyć.\n\nW razie wątpliwości pozostaw WŁĄCZONĄ.",
"PptcToggleTooltip": "Zapisuje przetłumaczone funkcje JIT, dzięki czemu nie muszą być tłumaczone za każdym razem, gdy gra się ładuje.\n\nZmniejsza zacinanie się i znacznie przyspiesza uruchamianie po pierwszym uruchomieniu gry.\n\nJeśli nie masz pewności, pozostaw WŁĄCZONE", "PptcToggleTooltip": "Zapisuje przetłumaczone funkcje JIT, dzięki czemu nie muszą być tłumaczone za każdym razem, gdy gra się ładuje.\n\nZmniejsza zacinanie się i znacznie przyspiesza uruchamianie po pierwszym uruchomieniu gry.\n\nJeśli nie masz pewności, pozostaw WŁĄCZONE",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Załaduj PPTC, używając jednej trzeciej liczby rdzeni",
"JitCacheEvictionToggleTooltip": "Włącz eksmisję pamięci podręcznej JIT, aby efektywnie zarządzać pamięcią",
"FsIntegrityToggleTooltip": "Sprawdza pliki podczas uruchamiania gry i jeśli zostaną wykryte uszkodzone pliki, wyświetla w dzienniku błąd hash.\n\nNie ma wpływu na wydajność i ma pomóc w rozwiązywaniu problemów.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.", "FsIntegrityToggleTooltip": "Sprawdza pliki podczas uruchamiania gry i jeśli zostaną wykryte uszkodzone pliki, wyświetla w dzienniku błąd hash.\n\nNie ma wpływu na wydajność i ma pomóc w rozwiązywaniu problemów.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.",
"AudioBackendTooltip": "Zmienia backend używany do renderowania dźwięku.\n\nSDL2 jest preferowany, podczas gdy OpenAL i SoundIO są używane jako rezerwy. Dummy nie będzie odtwarzać dźwięku.\n\nW razie wątpliwości ustaw SDL2.", "AudioBackendTooltip": "Zmienia backend używany do renderowania dźwięku.\n\nSDL2 jest preferowany, podczas gdy OpenAL i SoundIO są używane jako rezerwy. Dummy nie będzie odtwarzać dźwięku.\n\nW razie wątpliwości ustaw SDL2.",
"MemoryManagerTooltip": "Zmień sposób mapowania i uzyskiwania dostępu do pamięci gości. Znacznie wpływa na wydajność emulowanego procesora.\n\nUstaw na HOST UNCHECKED, jeśli nie masz pewności.", "MemoryManagerTooltip": "Zmień sposób mapowania i uzyskiwania dostępu do pamięci gości. Znacznie wpływa na wydajność emulowanego procesora.\n\nUstaw na HOST UNCHECKED, jeśli nie masz pewności.",

View file

@ -150,6 +150,7 @@
"SettingsTabSystemEnableVsync": "Habilitar sincronia vertical", "SettingsTabSystemEnableVsync": "Habilitar sincronia vertical",
"SettingsTabSystemEnablePptc": "Habilitar PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "Habilitar PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Habilitar verificação de integridade do sistema de arquivos", "SettingsTabSystemEnableFsIntegrityChecks": "Habilitar verificação de integridade do sistema de arquivos",
"SettingsTabSystemAudioBackend": "Biblioteca de saída de áudio:", "SettingsTabSystemAudioBackend": "Biblioteca de saída de áudio:",
"SettingsTabSystemAudioBackendDummy": "Nenhuma", "SettingsTabSystemAudioBackendDummy": "Nenhuma",
@ -592,7 +593,8 @@
"TimeTooltip": "Mudar a hora do sistema", "TimeTooltip": "Mudar a hora do sistema",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "Habilita ou desabilita PPTC", "PptcToggleTooltip": "Habilita ou desabilita PPTC",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Carregue o PPTC usando um terço da quantidade de núcleos",
"JitCacheEvictionToggleTooltip": "Habilite a remoção do JIT Cache para gerenciar a memória com eficiência",
"FsIntegrityToggleTooltip": "Habilita ou desabilita verificação de integridade dos arquivos do jogo", "FsIntegrityToggleTooltip": "Habilita ou desabilita verificação de integridade dos arquivos do jogo",
"AudioBackendTooltip": "Mudar biblioteca de áudio", "AudioBackendTooltip": "Mudar biblioteca de áudio",
"MemoryManagerTooltip": "Muda como a memória do sistema convidado é acessada. Tem um grande impacto na performance da CPU emulada.", "MemoryManagerTooltip": "Muda como a memória do sistema convidado é acessada. Tem um grande impacto na performance da CPU emulada.",

View file

@ -168,6 +168,7 @@
"SettingsTabSystemCustomVSyncIntervalValue": "Значение пользовательской частоты обновления:", "SettingsTabSystemCustomVSyncIntervalValue": "Значение пользовательской частоты обновления:",
"SettingsTabSystemEnablePptc": "Использовать PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "Использовать PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Проверка целостности файловой системы", "SettingsTabSystemEnableFsIntegrityChecks": "Проверка целостности файловой системы",
"SettingsTabSystemAudioBackend": "Аудио бэкенд:", "SettingsTabSystemAudioBackend": "Аудио бэкенд:",
"SettingsTabSystemAudioBackendDummy": "Без звука", "SettingsTabSystemAudioBackendDummy": "Без звука",
@ -621,6 +622,7 @@
"VSyncToggleTooltip": "Эмуляция вертикальной синхронизации консоли, которая ограничивает количество кадров в секунду в большинстве игр; отключение может привести к тому, что игры будут запущены с более высокой частотой кадров, но загрузка игры может занять больше времени, либо игра не запустится вообще.\n\nМожно включать и выключать эту настройку непосредственно в игре с помощью горячих клавиш (F1 по умолчанию). Если планируете отключить вертикальную синхронизацию, рекомендуем настроить горячие клавиши.\n\nРекомендуется оставить включенным.", "VSyncToggleTooltip": "Эмуляция вертикальной синхронизации консоли, которая ограничивает количество кадров в секунду в большинстве игр; отключение может привести к тому, что игры будут запущены с более высокой частотой кадров, но загрузка игры может занять больше времени, либо игра не запустится вообще.\n\nМожно включать и выключать эту настройку непосредственно в игре с помощью горячих клавиш (F1 по умолчанию). Если планируете отключить вертикальную синхронизацию, рекомендуем настроить горячие клавиши.\n\nРекомендуется оставить включенным.",
"PptcToggleTooltip": "Сохраняет скомпилированные JIT-функции для того, чтобы не преобразовывать их по новой каждый раз при запуске игры.\n\nУменьшает статтеры и значительно ускоряет последующую загрузку игр.\n\nРекомендуется оставить включенным.", "PptcToggleTooltip": "Сохраняет скомпилированные JIT-функции для того, чтобы не преобразовывать их по новой каждый раз при запуске игры.\n\nУменьшает статтеры и значительно ускоряет последующую загрузку игр.\n\nРекомендуется оставить включенным.",
"LowPowerPptcToggleTooltip": "Загружает PPTC, используя треть от количества ядер.", "LowPowerPptcToggleTooltip": "Загружает PPTC, используя треть от количества ядер.",
"JitCacheEvictionToggleTooltip": "Включите вытеснение JIT-кэша для эффективного управления памятью.",
"FsIntegrityToggleTooltip": "Проверяет файлы при загрузке игры и если обнаружены поврежденные файлы, выводит сообщение о поврежденном хэше в журнале.\n\nНе влияет на производительность и необходим для помощи в устранении неполадок.\n\nРекомендуется оставить включенным.", "FsIntegrityToggleTooltip": "Проверяет файлы при загрузке игры и если обнаружены поврежденные файлы, выводит сообщение о поврежденном хэше в журнале.\n\nНе влияет на производительность и необходим для помощи в устранении неполадок.\n\nРекомендуется оставить включенным.",
"AudioBackendTooltip": "Изменяет используемый аудио бэкенд для рендера звука.\n\nSDL2 является предпочтительным вариантом, в то время как OpenAL и SoundIO используются в качестве резервных.\n\nРекомендуется использование SDL2.", "AudioBackendTooltip": "Изменяет используемый аудио бэкенд для рендера звука.\n\nSDL2 является предпочтительным вариантом, в то время как OpenAL и SoundIO используются в качестве резервных.\n\nРекомендуется использование SDL2.",
"MemoryManagerTooltip": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить \"Хост не установлен\"", "MemoryManagerTooltip": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить \"Хост не установлен\"",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (แคชโปรไฟล์การแปลแบบถาวร)", "SettingsTabSystemEnablePptc": "PPTC (แคชโปรไฟล์การแปลแบบถาวร)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "ตรวจสอบความถูกต้องของ FS", "SettingsTabSystemEnableFsIntegrityChecks": "ตรวจสอบความถูกต้องของ FS",
"SettingsTabSystemAudioBackend": "ระบบเสียงเบื้องหลัง:", "SettingsTabSystemAudioBackend": "ระบบเสียงเบื้องหลัง:",
"SettingsTabSystemAudioBackendDummy": "Dummy", "SettingsTabSystemAudioBackendDummy": "Dummy",
@ -589,7 +590,8 @@
"TimeTooltip": "เปลี่ยนเวลาของระบบ", "TimeTooltip": "เปลี่ยนเวลาของระบบ",
"VSyncToggleTooltip": "Vertical Sync ของคอนโซลจำลอง โดยพื้นฐานแล้วเป็นตัวจำกัดเฟรมสำหรับเกมส่วนใหญ่ การปิดใช้งานอาจทำให้เกมทำงานด้วยความเร็วสูงขึ้น หรือทำให้หน้าจอการโหลดใช้เวลานานขึ้นหรือค้าง\n\nสามารถสลับได้ในเกมด้วยปุ่มลัดตามที่คุณต้องการ (F1 เป็นค่าเริ่มต้น) เราขอแนะนำให้ทำเช่นนี้หากคุณวางแผนที่จะปิดการใช้งาน\n\nหากคุณไม่แน่ใจให้ปล่อยไว้อย่างนั้น", "VSyncToggleTooltip": "Vertical Sync ของคอนโซลจำลอง โดยพื้นฐานแล้วเป็นตัวจำกัดเฟรมสำหรับเกมส่วนใหญ่ การปิดใช้งานอาจทำให้เกมทำงานด้วยความเร็วสูงขึ้น หรือทำให้หน้าจอการโหลดใช้เวลานานขึ้นหรือค้าง\n\nสามารถสลับได้ในเกมด้วยปุ่มลัดตามที่คุณต้องการ (F1 เป็นค่าเริ่มต้น) เราขอแนะนำให้ทำเช่นนี้หากคุณวางแผนที่จะปิดการใช้งาน\n\nหากคุณไม่แน่ใจให้ปล่อยไว้อย่างนั้น",
"PptcToggleTooltip": "บันทึกฟังก์ชั่น JIT ที่แปลแล้ว ดังนั้นจึงไม่จำเป็นต้องแปลทุกครั้งที่โหลดเกม\n\nลดอาการกระตุกและเร่งความเร็วการบูตได้อย่างมากหลังจากการบูตครั้งแรกของเกม\n\nปล่อยไว้หากคุณไม่แน่ใจ", "PptcToggleTooltip": "บันทึกฟังก์ชั่น JIT ที่แปลแล้ว ดังนั้นจึงไม่จำเป็นต้องแปลทุกครั้งที่โหลดเกม\n\nลดอาการกระตุกและเร่งความเร็วการบูตได้อย่างมากหลังจากการบูตครั้งแรกของเกม\n\nปล่อยไว้หากคุณไม่แน่ใจ",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์",
"JitCacheEvictionToggleTooltip": "เปิดใช้งานการขับไล่ JIT Cache เพื่อจัดการหน่วยความจำอย่างมีประสิทธิภาพ",
"FsIntegrityToggleTooltip": "ตรวจสอบไฟล์ที่เสียหายเมื่อบูตเกม และหากตรวจพบไฟล์ที่เสียหาย จะแสดงข้อผิดพลาดของแฮชในบันทึก\n\nไม่มีผลกระทบต่อประสิทธิภาพการทำงานและมีไว้เพื่อช่วยในการแก้ไขปัญหา\n\nปล่อยไว้หากคุณไม่แน่ใจ", "FsIntegrityToggleTooltip": "ตรวจสอบไฟล์ที่เสียหายเมื่อบูตเกม และหากตรวจพบไฟล์ที่เสียหาย จะแสดงข้อผิดพลาดของแฮชในบันทึก\n\nไม่มีผลกระทบต่อประสิทธิภาพการทำงานและมีไว้เพื่อช่วยในการแก้ไขปัญหา\n\nปล่อยไว้หากคุณไม่แน่ใจ",
"AudioBackendTooltip": "เปลี่ยนแบ็กเอนด์ที่ใช้ในการเรนเดอร์เสียง\n\nSDL2 เป็นที่ต้องการ ในขณะที่ OpenAL และ SoundIO ถูกใช้เป็นทางเลือกสำรอง ดัมมี่จะไม่มีเสียง\n\nปล่อยไว้หากคุณไม่แน่ใจ", "AudioBackendTooltip": "เปลี่ยนแบ็กเอนด์ที่ใช้ในการเรนเดอร์เสียง\n\nSDL2 เป็นที่ต้องการ ในขณะที่ OpenAL และ SoundIO ถูกใช้เป็นทางเลือกสำรอง ดัมมี่จะไม่มีเสียง\n\nปล่อยไว้หากคุณไม่แน่ใจ",
"MemoryManagerTooltip": "เปลี่ยนวิธีการแมปและเข้าถึงหน่วยความจำของผู้เยี่ยมชม ส่งผลอย่างมากต่อประสิทธิภาพการทำงานของ CPU ที่จำลอง\n\nตั้งค่าเป็น ไม่ทำการตรวจสอบ โฮสต์ หากคุณไม่แน่ใจ", "MemoryManagerTooltip": "เปลี่ยนวิธีการแมปและเข้าถึงหน่วยความจำของผู้เยี่ยมชม ส่งผลอย่างมากต่อประสิทธิภาพการทำงานของ CPU ที่จำลอง\n\nตั้งค่าเป็น ไม่ทำการตรวจสอบ โฮสต์ หากคุณไม่แน่ใจ",

View file

@ -147,6 +147,7 @@
"SettingsTabSystemEnableVsync": "Dikey Eşitleme", "SettingsTabSystemEnableVsync": "Dikey Eşitleme",
"SettingsTabSystemEnablePptc": "PPTC (Profilli Sürekli Çeviri Önbelleği)", "SettingsTabSystemEnablePptc": "PPTC (Profilli Sürekli Çeviri Önbelleği)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Bütünlük Kontrolleri", "SettingsTabSystemEnableFsIntegrityChecks": "FS Bütünlük Kontrolleri",
"SettingsTabSystemAudioBackend": "Ses Motoru:", "SettingsTabSystemAudioBackend": "Ses Motoru:",
"SettingsTabSystemAudioBackendDummy": "Yapay", "SettingsTabSystemAudioBackendDummy": "Yapay",
@ -589,7 +590,8 @@
"TimeTooltip": "Sistem Saatini Değiştir", "TimeTooltip": "Sistem Saatini Değiştir",
"VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
"PptcToggleTooltip": "Çevrilen JIT fonksiyonlarını oyun her açıldığında çevrilmek zorunda kalmaması için kaydeder.\n\nTeklemeyi azaltır ve ilk açılıştan sonra oyunların ilk açılış süresini ciddi biçimde hızlandırır.\n\nEmin değilseniz aktif halde bırakın.", "PptcToggleTooltip": "Çevrilen JIT fonksiyonlarını oyun her açıldığında çevrilmek zorunda kalmaması için kaydeder.\n\nTeklemeyi azaltır ve ilk açılıştan sonra oyunların ilk açılış süresini ciddi biçimde hızlandırır.\n\nEmin değilseniz aktif halde bırakın.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Çekirdek miktarının üçte birini kullanarak PPTC'yi yükleyin",
"JitCacheEvictionToggleTooltip": "Belleği verimli bir şekilde yönetmek için JIT Önbellek tahliyesini etkinleştirin",
"FsIntegrityToggleTooltip": "Oyun açarken hatalı dosyaların olup olmadığını kontrol eder, ve hatalı dosya bulursa log dosyasında hash hatası görüntüler.\n\nPerformansa herhangi bir etkisi yoktur ve sorun gidermeye yardımcı olur.\n\nEmin değilseniz aktif halde bırakın.", "FsIntegrityToggleTooltip": "Oyun açarken hatalı dosyaların olup olmadığını kontrol eder, ve hatalı dosya bulursa log dosyasında hash hatası görüntüler.\n\nPerformansa herhangi bir etkisi yoktur ve sorun gidermeye yardımcı olur.\n\nEmin değilseniz aktif halde bırakın.",
"AudioBackendTooltip": "Ses çıkış motorunu değiştirir.\n\nSDL2 tercih edilen seçenektir, OpenAL ve SoundIO ise alternatif olarak kullanılabilir. Dummy seçeneğinde ses çıkışı olmayacaktır.\n\nEmin değilseniz SDL2 seçeneğine ayarlayın.", "AudioBackendTooltip": "Ses çıkış motorunu değiştirir.\n\nSDL2 tercih edilen seçenektir, OpenAL ve SoundIO ise alternatif olarak kullanılabilir. Dummy seçeneğinde ses çıkışı olmayacaktır.\n\nEmin değilseniz SDL2 seçeneğine ayarlayın.",
"MemoryManagerTooltip": "Guest hafızasının nasıl tahsis edilip erişildiğini değiştirir. Emüle edilen CPU performansını ciddi biçimde etkiler.\n\nEmin değilseniz HOST UNCHECKED seçeneğine ayarlayın.", "MemoryManagerTooltip": "Guest hafızasının nasıl tahsis edilip erişildiğini değiştirir. Emüle edilen CPU performansını ciddi biçimde etkiler.\n\nEmin değilseniz HOST UNCHECKED seçeneğine ayarlayın.",

View file

@ -150,6 +150,7 @@
"SettingsTabSystemEnableVsync": "Вертикальна синхронізація", "SettingsTabSystemEnableVsync": "Вертикальна синхронізація",
"SettingsTabSystemEnablePptc": "PPTC (профільований постійний кеш перекладу)", "SettingsTabSystemEnablePptc": "PPTC (профільований постійний кеш перекладу)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "Перевірка цілісності FS", "SettingsTabSystemEnableFsIntegrityChecks": "Перевірка цілісності FS",
"SettingsTabSystemAudioBackend": "Аудіосистема:", "SettingsTabSystemAudioBackend": "Аудіосистема:",
"SettingsTabSystemAudioBackendDummy": "Dummy", "SettingsTabSystemAudioBackendDummy": "Dummy",
@ -593,7 +594,8 @@
"MatchTimeTooltip": "Синхронізувати системний час, щоб він відповідав поточній даті та часу вашого ПК.", "MatchTimeTooltip": "Синхронізувати системний час, щоб він відповідав поточній даті та часу вашого ПК.",
"VSyncToggleTooltip": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.", "VSyncToggleTooltip": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.",
"PptcToggleTooltip": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.", "PptcToggleTooltip": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "Завантажте PPTC, використовуючи третину кількості ядер",
"JitCacheEvictionToggleTooltip": "Увімкніть видалення кешу JIT для ефективного керування пам’яттю",
"FsIntegrityToggleTooltip": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.", "FsIntegrityToggleTooltip": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.",
"AudioBackendTooltip": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.", "AudioBackendTooltip": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.",
"MemoryManagerTooltip": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.", "MemoryManagerTooltip": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.",

View file

@ -150,6 +150,7 @@
"SettingsTabSystemEnableVsync": "启用垂直同步", "SettingsTabSystemEnableVsync": "启用垂直同步",
"SettingsTabSystemEnablePptc": "开启 PPTC 缓存", "SettingsTabSystemEnablePptc": "开启 PPTC 缓存",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "启用文件系统完整性检查", "SettingsTabSystemEnableFsIntegrityChecks": "启用文件系统完整性检查",
"SettingsTabSystemAudioBackend": "音频处理引擎:", "SettingsTabSystemAudioBackend": "音频处理引擎:",
"SettingsTabSystemAudioBackendDummy": "无", "SettingsTabSystemAudioBackendDummy": "无",
@ -593,7 +594,8 @@
"MatchTimeTooltip": "重新同步系统时间以匹配您电脑的当前日期和时间。", "MatchTimeTooltip": "重新同步系统时间以匹配您电脑的当前日期和时间。",
"VSyncToggleTooltip": "模拟控制台的垂直同步,开启后会降低大部分游戏的帧率。关闭后,可以获得更高的帧率,但也可能导致游戏画面加载耗时更长或卡住。\n\n在游戏中可以使用热键进行切换默认为 F1 键)。\n\n如果不确定请保持开启状态。", "VSyncToggleTooltip": "模拟控制台的垂直同步,开启后会降低大部分游戏的帧率。关闭后,可以获得更高的帧率,但也可能导致游戏画面加载耗时更长或卡住。\n\n在游戏中可以使用热键进行切换默认为 F1 键)。\n\n如果不确定请保持开启状态。",
"PptcToggleTooltip": "缓存已编译的游戏指令,这样每次游戏加载时就无需重新编译。\n\n可以减少卡顿和启动时间提高游戏响应速度。\n\n如果不确定请保持开启状态。", "PptcToggleTooltip": "缓存已编译的游戏指令,这样每次游戏加载时就无需重新编译。\n\n可以减少卡顿和启动时间提高游戏响应速度。\n\n如果不确定请保持开启状态。",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "使用三分之一的核心数量加载 PPTC",
"JitCacheEvictionToggleTooltip": "启用 JIT 缓存驱逐以有效管理内存",
"FsIntegrityToggleTooltip": "启动游戏时检查游戏文件的完整性,并在日志中记录损坏的文件。\n\n对性能没有影响用于排查故障。\n\n如果不确定请保持开启状态。", "FsIntegrityToggleTooltip": "启动游戏时检查游戏文件的完整性,并在日志中记录损坏的文件。\n\n对性能没有影响用于排查故障。\n\n如果不确定请保持开启状态。",
"AudioBackendTooltip": "更改音频处理引擎。\n\n推荐选择“SDL2”另外“OpenAL”和“SoundIO”可以作为备选选择“无”将没有声音。\n\n如果不确定请设置为“SDL2”。", "AudioBackendTooltip": "更改音频处理引擎。\n\n推荐选择“SDL2”另外“OpenAL”和“SoundIO”可以作为备选选择“无”将没有声音。\n\n如果不确定请设置为“SDL2”。",
"MemoryManagerTooltip": "更改模拟器内存映射和访问的方式,对模拟器 CPU 的性能影响很大。\n\n如果不确定请设置为“跳过检查的本机映射”。", "MemoryManagerTooltip": "更改模拟器内存映射和访问的方式,对模拟器 CPU 的性能影响很大。\n\n如果不确定请设置为“跳过检查的本机映射”。",

View file

@ -150,6 +150,7 @@
"SettingsTabSystemEnableVsync": "垂直同步", "SettingsTabSystemEnableVsync": "垂直同步",
"SettingsTabSystemEnablePptc": "PPTC (剖析式持久轉譯快取, Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (剖析式持久轉譯快取, Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC", "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
"SettingsTabSystemEnableJitCacheEviction": "Jit Cache Eviction",
"SettingsTabSystemEnableFsIntegrityChecks": "檔案系統完整性檢查", "SettingsTabSystemEnableFsIntegrityChecks": "檔案系統完整性檢查",
"SettingsTabSystemAudioBackend": "音效後端:", "SettingsTabSystemAudioBackend": "音效後端:",
"SettingsTabSystemAudioBackendDummy": "虛設 (Dummy)", "SettingsTabSystemAudioBackendDummy": "虛設 (Dummy)",
@ -593,7 +594,8 @@
"MatchTimeTooltip": "重新同步系統韌體時間至 PC 目前的日期和時間。", "MatchTimeTooltip": "重新同步系統韌體時間至 PC 目前的日期和時間。",
"VSyncToggleTooltip": "模擬遊戲機的垂直同步。對大多數遊戲來說,它本質上是一個幀率限制器;停用它可能會導致遊戲以更高的速度執行,或使載入畫面耗時更長或卡住。\n\n可以在遊戲中使用快速鍵進行切換 (預設為 F1)。如果您打算停用,我們建議您這樣做。\n\n如果不確定請保持開啟狀態。", "VSyncToggleTooltip": "模擬遊戲機的垂直同步。對大多數遊戲來說,它本質上是一個幀率限制器;停用它可能會導致遊戲以更高的速度執行,或使載入畫面耗時更長或卡住。\n\n可以在遊戲中使用快速鍵進行切換 (預設為 F1)。如果您打算停用,我們建議您這樣做。\n\n如果不確定請保持開啟狀態。",
"PptcToggleTooltip": "儲存已轉譯的 JIT 函數,這樣每次載入遊戲時就無需再轉譯這些函數。\n\n減少遊戲首次啟動後的卡頓現象並大大加快啟動時間。\n\n如果不確定請保持開啟狀態。", "PptcToggleTooltip": "儲存已轉譯的 JIT 函數,這樣每次載入遊戲時就無需再轉譯這些函數。\n\n減少遊戲首次啟動後的卡頓現象並大大加快啟動時間。\n\n如果不確定請保持開啟狀態。",
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.", "LowPowerPptcToggleTooltip": "使用三分之一的核心數量加載 PPTC",
"JitCacheEvictionToggleTooltip": "啟用 JIT 快取驅逐以有效管理內存",
"FsIntegrityToggleTooltip": "在啟動遊戲時檢查損壞的檔案,如果檢測到損壞的檔案,則在日誌中顯示雜湊值錯誤。\n\n對效能沒有影響旨在幫助排除故障。\n\n如果不確定請保持開啟狀態。", "FsIntegrityToggleTooltip": "在啟動遊戲時檢查損壞的檔案,如果檢測到損壞的檔案,則在日誌中顯示雜湊值錯誤。\n\n對效能沒有影響旨在幫助排除故障。\n\n如果不確定請保持開啟狀態。",
"AudioBackendTooltip": "變更用於繪製音訊的後端。\n\nSDL2 是首選,而 OpenAL 和 SoundIO 則作為備用。虛設 (Dummy) 將沒有聲音。\n\n如果不確定請設定為 SDL2。", "AudioBackendTooltip": "變更用於繪製音訊的後端。\n\nSDL2 是首選,而 OpenAL 和 SoundIO 則作為備用。虛設 (Dummy) 將沒有聲音。\n\n如果不確定請設定為 SDL2。",
"MemoryManagerTooltip": "變更客體記憶體的映射和存取方式。這會極大地影響模擬 CPU 效能。\n\n如果不確定請設定為主體略過檢查模式。", "MemoryManagerTooltip": "變更客體記憶體的映射和存取方式。這會極大地影響模擬 CPU 效能。\n\n如果不確定請設定為主體略過檢查模式。",

View file

@ -14,12 +14,19 @@
<IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion> <IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' == '' AND '$(BuildingInsideVisualStudio)' == 'true'">
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('OSX'))">osx-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x64</RuntimeIdentifier>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))"> <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
<Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f --deep -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" /> <Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f --deep -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
</Target> </Target>
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''"> <PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<TrimmerSingleWarn>false</TrimmerSingleWarn> <TrimmerSingleWarn>false</TrimmerSingleWarn>
<PublishTrimmed>true</PublishTrimmed> <PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode> <TrimMode>partial</TrimMode>

View file

@ -1223,15 +1223,15 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
try try
{ {
// Creazione di una copia completa di Applications
List<ApplicationData> appsCopy; List<ApplicationData> appsCopy;
lock (_applicationsLock) lock (_applicationsLock)
{ {
appsCopy = new List<ApplicationData>(Applications); appsCopy = new List<ApplicationData>(Applications);
} }
// Filtraggio e ordinamento in una lista temporanea
var tempApplications = new List<ApplicationData>(); var tempApplications = new List<ApplicationData>();
foreach (var app in appsCopy) foreach (var app in appsCopy)
{ {
if (Filter(app)) if (Filter(app))
@ -1240,10 +1240,8 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
// Ordinamento alfabetico
tempApplications.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); tempApplications.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
// Creazione delle directory di salvataggio
foreach (var application in tempApplications) foreach (var application in tempApplications)
{ {
try try
@ -1252,19 +1250,16 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
catch (Exception ex) catch (Exception ex)
{ {
// Log dell'errore se necessario
Logger.Error?.Print(LogClass.Application, $"Failed to create save directory for {application.Name}: {ex.Message}"); Logger.Error?.Print(LogClass.Application, $"Failed to create save directory for {application.Name}: {ex.Message}");
} }
} }
// Ricreazione dell'observable collection in modo thread-safe
Dispatcher.UIThread.InvokeAsync(() => Dispatcher.UIThread.InvokeAsync(() =>
{ {
try try
{ {
lock (_applicationsLock) lock (_applicationsLock)
{ {
// Ricrea la collezione osservabile in modo più sicuro
var source = Applications.ToObservableChangeSet(); var source = Applications.ToObservableChangeSet();
var filtered = source.Filter(Filter); var filtered = source.Filter(Filter);
var sorted = filtered.Sort(GetComparer()); var sorted = filtered.Sort(GetComparer());

View file

@ -227,6 +227,8 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
public bool EnablePptc { get; set; } public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; } public bool EnableLowPowerPptc { get; set; }
public bool EnableJitCacheEviction { get; set; }
public bool EnableInternetAccess { get; set; } public bool EnableInternetAccess { get; set; }
public bool EnableFsIntegrityChecks { get; set; } public bool EnableFsIntegrityChecks { get; set; }
public bool IgnoreMissingServices { get; set; } public bool IgnoreMissingServices { get; set; }
@ -571,6 +573,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// CPU // CPU
EnablePptc = config.System.EnablePtc; EnablePptc = config.System.EnablePtc;
EnableLowPowerPptc = config.System.EnableLowPowerPtc; EnableLowPowerPptc = config.System.EnableLowPowerPtc;
EnableJitCacheEviction = config.System.EnableJitCacheEviction;
MemoryMode = (int)config.System.MemoryManagerMode.Value; MemoryMode = (int)config.System.MemoryManagerMode.Value;
UseHypervisor = config.System.UseHypervisor; UseHypervisor = config.System.UseHypervisor;
@ -679,6 +682,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// CPU // CPU
config.System.EnablePtc.Value = EnablePptc; config.System.EnablePtc.Value = EnablePptc;
config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc; config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc;
config.System.EnableJitCacheEviction.Value = EnableJitCacheEviction;
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode; config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
config.System.UseHypervisor.Value = UseHypervisor; config.System.UseHypervisor.Value = UseHypervisor;

View file

@ -36,6 +36,10 @@
<TextBlock Text="{locale:Locale SettingsTabSystemEnableLowPowerPptc}" <TextBlock Text="{locale:Locale SettingsTabSystemEnableLowPowerPptc}"
ToolTip.Tip="{locale:Locale LowPowerPptcToggleTooltip}" /> ToolTip.Tip="{locale:Locale LowPowerPptcToggleTooltip}" />
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding EnableJitCacheEviction}">
<TextBlock Text="{locale:Locale SettingsTabSystemEnableJitCacheEviction}"
ToolTip.Tip="{locale:Locale JitCacheEvictionToggleTooltip}" />
</CheckBox>
</StackPanel> </StackPanel>
<Separator Height="1" /> <Separator Height="1" />
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabCpuMemory}" /> <TextBlock Classes="h1" Text="{locale:Locale SettingsTabCpuMemory}" />

View file

@ -16,6 +16,8 @@ interface KenjinxNativeJna : Library {
vSyncMode: Int, vSyncMode: Int,
enableDockedMode: Boolean, enableDockedMode: Boolean,
enablePptc: Boolean, enablePptc: Boolean,
enableLowPowerPptc: Boolean,
enableJitCacheEviction: Boolean,
enableInternetAccess: Boolean, enableInternetAccess: Boolean,
enableFsIntegrityChecks: Boolean, enableFsIntegrityChecks: Boolean,
fsGlobalAccessLogMode: Int, fsGlobalAccessLogMode: Int,

View file

@ -248,4 +248,24 @@ class MainActivity : BaseActivity() {
} }
} }
} }
fun shutdownAndRestart() {
// Create an intent to restart the app
val packageManager = packageManager
val intent = packageManager.getLaunchIntentForPackage(packageName)
val componentName = intent?.component
val restartIntent = Intent.makeRestartActivityTask(componentName)
// Clean up resources if needed
mainViewModel?.let {
// Perform any critical cleanup
it.performanceManager?.setTurboMode(false)
}
// Start the new activity directly
startActivity(restartIntent)
// Force immediate process termination
Runtime.getRuntime().exit(0)
}
} }

View file

@ -50,6 +50,10 @@ class GameModel(var file: DocumentFile, val context: Context) {
} }
} }
fun isUnknown() : Boolean {
return (titleName == "Unknown")
}
fun open(): Int { fun open(): Int {
descriptor = context.contentResolver.openFileDescriptor(file.uri, "rw") descriptor = context.contentResolver.openFileDescriptor(file.uri, "rw")

View file

@ -107,6 +107,11 @@ class HomeViewModel(
for(game in loadedCache) for(game in loadedCache)
{ {
game.getGameInfo() game.getGameInfo()
if(game.isUnknown())
{
loadedCache.remove(game);
}
} }
} finally { } finally {
isLoading.value = false isLoading.value = false

View file

@ -179,6 +179,8 @@ class MainViewModel(val activity: MainActivity) {
settings.vSyncMode.ordinal, settings.vSyncMode.ordinal,
settings.enableDocked, settings.enableDocked,
settings.enablePptc, settings.enablePptc,
settings.enableLowPowerPptc,
settings.enableJitCacheEviction,
false, false,
settings.enableFsIntegrityChecks, settings.enableFsIntegrityChecks,
settings.fsGlobalAccessLogMode, settings.fsGlobalAccessLogMode,
@ -285,6 +287,8 @@ class MainViewModel(val activity: MainActivity) {
settings.vSyncMode.ordinal, settings.vSyncMode.ordinal,
settings.enableDocked, settings.enableDocked,
settings.enablePptc, settings.enablePptc,
settings.enableLowPowerPptc,
settings.enableJitCacheEviction,
false, false,
settings.enableFsIntegrityChecks, settings.enableFsIntegrityChecks,
settings.fsGlobalAccessLogMode, settings.fsGlobalAccessLogMode,

View file

@ -7,6 +7,8 @@ import androidx.preference.PreferenceManager
class QuickSettings(val activity: Activity) { class QuickSettings(val activity: Activity) {
var ignoreMissingServices: Boolean var ignoreMissingServices: Boolean
var enablePptc: Boolean var enablePptc: Boolean
var enableLowPowerPptc: Boolean
var enableJitCacheEviction: Boolean
var enableFsIntegrityChecks: Boolean var enableFsIntegrityChecks: Boolean
var fsGlobalAccessLogMode: Int var fsGlobalAccessLogMode: Int
var enableDocked: Boolean var enableDocked: Boolean
@ -39,11 +41,13 @@ class QuickSettings(val activity: Activity) {
init { init {
memoryManagerMode = MemoryManagerMode.values()[sharedPref.getInt("memoryManagerMode", MemoryManagerMode.HostMappedUnsafe.ordinal)] memoryManagerMode = MemoryManagerMode.values()[sharedPref.getInt("memoryManagerMode", MemoryManagerMode.HostMappedUnsafe.ordinal)]
useNce = sharedPref.getBoolean("useNce", true) useNce = sharedPref.getBoolean("useNce", false)
memoryConfiguration = MemoryConfiguration.values()[sharedPref.getInt("memoryConfiguration", MemoryConfiguration.MemoryConfiguration4GiB.ordinal)] memoryConfiguration = MemoryConfiguration.values()[sharedPref.getInt("memoryConfiguration", MemoryConfiguration.MemoryConfiguration4GiB.ordinal)]
vSyncMode = VSyncMode.values()[sharedPref.getInt("vSyncMode", VSyncMode.Switch.ordinal)] vSyncMode = VSyncMode.values()[sharedPref.getInt("vSyncMode", VSyncMode.Switch.ordinal)]
enableDocked = sharedPref.getBoolean("enableDocked", true) enableDocked = sharedPref.getBoolean("enableDocked", true)
enablePptc = sharedPref.getBoolean("enablePptc", true) enablePptc = sharedPref.getBoolean("enablePptc", true)
enableLowPowerPptc = sharedPref.getBoolean("enableLowPowerPptc", false)
enableJitCacheEviction = sharedPref.getBoolean("enableJitCacheEviction", true)
enableFsIntegrityChecks = sharedPref.getBoolean("enableFsIntegrityChecks", false) enableFsIntegrityChecks = sharedPref.getBoolean("enableFsIntegrityChecks", false)
fsGlobalAccessLogMode = sharedPref.getInt("fsGlobalAccessLogMode", 0) fsGlobalAccessLogMode = sharedPref.getInt("fsGlobalAccessLogMode", 0)
ignoreMissingServices = sharedPref.getBoolean("ignoreMissingServices", false) ignoreMissingServices = sharedPref.getBoolean("ignoreMissingServices", false)
@ -78,6 +82,8 @@ class QuickSettings(val activity: Activity) {
editor.putInt("vSyncMode", vSyncMode.ordinal) editor.putInt("vSyncMode", vSyncMode.ordinal)
editor.putBoolean("enableDocked", enableDocked) editor.putBoolean("enableDocked", enableDocked)
editor.putBoolean("enablePptc", enablePptc) editor.putBoolean("enablePptc", enablePptc)
editor.putBoolean("enableLowPowerPptc", enableLowPowerPptc)
editor.putBoolean("enableJitCacheEviction", enableJitCacheEviction)
editor.putBoolean("enableFsIntegrityChecks", enableFsIntegrityChecks) editor.putBoolean("enableFsIntegrityChecks", enableFsIntegrityChecks)
editor.putInt("fsGlobalAccessLogMode", fsGlobalAccessLogMode) editor.putInt("fsGlobalAccessLogMode", fsGlobalAccessLogMode)
editor.putBoolean("ignoreMissingServices", ignoreMissingServices) editor.putBoolean("ignoreMissingServices", ignoreMissingServices)

View file

@ -31,14 +31,6 @@ class SettingsViewModel(val activity: MainActivity) {
sharedPref = getPreferences() sharedPref = getPreferences()
previousFolderCallback = activity.storageHelper!!.onFolderSelected previousFolderCallback = activity.storageHelper!!.onFolderSelected
previousFileCallback = activity.storageHelper!!.onFileSelected previousFileCallback = activity.storageHelper!!.onFileSelected
activity.storageHelper!!.onFolderSelected = { _, folder ->
run {
val p = folder.getAbsolutePath(activity)
val editor = sharedPref.edit()
editor?.putString("gameFolder", p)
editor?.apply()
}
}
} }
private fun getPreferences(): SharedPreferences { private fun getPreferences(): SharedPreferences {
@ -52,6 +44,8 @@ class SettingsViewModel(val activity: MainActivity) {
vSyncMode: MutableState<VSyncMode>, vSyncMode: MutableState<VSyncMode>,
enableDocked: MutableState<Boolean>, enableDocked: MutableState<Boolean>,
enablePptc: MutableState<Boolean>, enablePptc: MutableState<Boolean>,
enableLowPowerPptc: MutableState<Boolean>,
enableJitCacheEviction: MutableState<Boolean>,
enableFsIntegrityChecks: MutableState<Boolean>, enableFsIntegrityChecks: MutableState<Boolean>,
fsGlobalAccessLogMode: MutableState<Int>, fsGlobalAccessLogMode: MutableState<Int>,
ignoreMissingServices: MutableState<Boolean>, ignoreMissingServices: MutableState<Boolean>,
@ -77,11 +71,13 @@ class SettingsViewModel(val activity: MainActivity) {
enableGraphicsLogs: MutableState<Boolean> enableGraphicsLogs: MutableState<Boolean>
) { ) {
memoryManagerMode.value = MemoryManagerMode.values()[sharedPref.getInt("memoryManagerMode", MemoryManagerMode.HostMappedUnsafe.ordinal)] memoryManagerMode.value = MemoryManagerMode.values()[sharedPref.getInt("memoryManagerMode", MemoryManagerMode.HostMappedUnsafe.ordinal)]
useNce.value = sharedPref.getBoolean("useNce", true) useNce.value = sharedPref.getBoolean("useNce", false)
memoryConfiguration.value = MemoryConfiguration.values()[sharedPref.getInt("memoryConfiguration", MemoryConfiguration.MemoryConfiguration4GiB.ordinal)] memoryConfiguration.value = MemoryConfiguration.values()[sharedPref.getInt("memoryConfiguration", MemoryConfiguration.MemoryConfiguration4GiB.ordinal)]
vSyncMode.value = VSyncMode.values()[sharedPref.getInt("vSyncMode", VSyncMode.Switch.ordinal)] vSyncMode.value = VSyncMode.values()[sharedPref.getInt("vSyncMode", VSyncMode.Switch.ordinal)]
enableDocked.value = sharedPref.getBoolean("enableDocked", true) enableDocked.value = sharedPref.getBoolean("enableDocked", true)
enablePptc.value = sharedPref.getBoolean("enablePptc", true) enablePptc.value = sharedPref.getBoolean("enablePptc", true)
enableLowPowerPptc.value = sharedPref.getBoolean("enableLowPowerPptc", false)
enableJitCacheEviction.value = sharedPref.getBoolean("enableJitCacheEviction", false)
enableFsIntegrityChecks.value = sharedPref.getBoolean("enableFsIntegrityChecks", false) enableFsIntegrityChecks.value = sharedPref.getBoolean("enableFsIntegrityChecks", false)
fsGlobalAccessLogMode.value = sharedPref.getInt("fsGlobalAccessLogMode", 0) fsGlobalAccessLogMode.value = sharedPref.getInt("fsGlobalAccessLogMode", 0)
ignoreMissingServices.value = sharedPref.getBoolean("ignoreMissingServices", false) ignoreMissingServices.value = sharedPref.getBoolean("ignoreMissingServices", false)
@ -102,7 +98,7 @@ class SettingsViewModel(val activity: MainActivity) {
enableErrorLogs.value = sharedPref.getBoolean("enableErrorLogs", true) enableErrorLogs.value = sharedPref.getBoolean("enableErrorLogs", true)
enableGuestLogs.value = sharedPref.getBoolean("enableGuestLogs", true) enableGuestLogs.value = sharedPref.getBoolean("enableGuestLogs", true)
enableFsAccessLogs.value = sharedPref.getBoolean("enableFsAccessLogs", false) enableFsAccessLogs.value = sharedPref.getBoolean("enableFsAccessLogs", false)
enableTraceLogs.value = sharedPref.getBoolean("enableStubLogs", false) enableTraceLogs.value = sharedPref.getBoolean("enableTraceLogs", false)
enableDebugLogs.value = sharedPref.getBoolean("enableDebugLogs", false) enableDebugLogs.value = sharedPref.getBoolean("enableDebugLogs", false)
enableGraphicsLogs.value = sharedPref.getBoolean("enableGraphicsLogs", false) enableGraphicsLogs.value = sharedPref.getBoolean("enableGraphicsLogs", false)
} }
@ -114,6 +110,8 @@ class SettingsViewModel(val activity: MainActivity) {
vSyncMode: MutableState<VSyncMode>, vSyncMode: MutableState<VSyncMode>,
enableDocked: MutableState<Boolean>, enableDocked: MutableState<Boolean>,
enablePptc: MutableState<Boolean>, enablePptc: MutableState<Boolean>,
enableLowPowerPptc: MutableState<Boolean>,
enableJitCacheEviction: MutableState<Boolean>,
enableFsIntegrityChecks: MutableState<Boolean>, enableFsIntegrityChecks: MutableState<Boolean>,
fsGlobalAccessLogMode: MutableState<Int>, fsGlobalAccessLogMode: MutableState<Int>,
ignoreMissingServices: MutableState<Boolean>, ignoreMissingServices: MutableState<Boolean>,
@ -146,6 +144,8 @@ class SettingsViewModel(val activity: MainActivity) {
editor.putInt("vSyncMode", vSyncMode.value.ordinal) editor.putInt("vSyncMode", vSyncMode.value.ordinal)
editor.putBoolean("enableDocked", enableDocked.value) editor.putBoolean("enableDocked", enableDocked.value)
editor.putBoolean("enablePptc", enablePptc.value) editor.putBoolean("enablePptc", enablePptc.value)
editor.putBoolean("enableLowPowerPptc", enableLowPowerPptc.value)
editor.putBoolean("enableJitCacheEviction", enableJitCacheEviction.value)
editor.putBoolean("enableFsIntegrityChecks", enableFsIntegrityChecks.value) editor.putBoolean("enableFsIntegrityChecks", enableFsIntegrityChecks.value)
editor.putInt("fsGlobalAccessLogMode", fsGlobalAccessLogMode.value) editor.putInt("fsGlobalAccessLogMode", fsGlobalAccessLogMode.value)
editor.putBoolean("ignoreMissingServices", ignoreMissingServices.value) editor.putBoolean("ignoreMissingServices", ignoreMissingServices.value)
@ -171,7 +171,6 @@ class SettingsViewModel(val activity: MainActivity) {
editor.putBoolean("enableGraphicsLogs", enableGraphicsLogs.value) editor.putBoolean("enableGraphicsLogs", enableGraphicsLogs.value)
editor.apply() editor.apply()
activity.storageHelper!!.onFolderSelected = previousFolderCallback
KenjinxNative.loggingSetEnabled(LogLevel.Info, enableInfoLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Info, enableInfoLogs.value)
KenjinxNative.loggingSetEnabled(LogLevel.Stub, enableStubLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Stub, enableStubLogs.value)
@ -187,6 +186,15 @@ class SettingsViewModel(val activity: MainActivity) {
fun openGameFolder() { fun openGameFolder() {
val path = sharedPref.getString("gameFolder", "") ?: "" val path = sharedPref.getString("gameFolder", "") ?: ""
activity.storageHelper!!.onFolderSelected = { _, folder ->
val p = folder.getAbsolutePath(activity)
val editor = sharedPref.edit()
editor.putString("gameFolder", p)
editor.apply()
activity.storageHelper!!.onFolderSelected = previousFolderCallback
activity.shutdownAndRestart()
}
if (path.isEmpty()) if (path.isEmpty())
activity.storageHelper?.storage?.openFolderPicker() activity.storageHelper?.storage?.openFolderPicker()
else else
@ -197,22 +205,20 @@ class SettingsViewModel(val activity: MainActivity) {
} }
fun selectKey(installState: MutableState<KeyInstallState>) { fun selectKey(installState: MutableState<KeyInstallState>) {
if (installState.value != KeyInstallState.None) if (installState.value != KeyInstallState.File)
return return
activity.storageHelper!!.onFileSelected = { _, files -> activity.storageHelper!!.onFileSelected = { _, files ->
run {
activity.storageHelper!!.onFileSelected = previousFileCallback
val file = files.firstOrNull() val file = files.firstOrNull()
file?.apply { file?.apply {
if (name == "prod.keys") { if (name == "prod.keys") {
selectedKeyFile = file selectedKeyFile = file
installState.value = KeyInstallState.Query installState.value = KeyInstallState.Query
} } else {
else {
installState.value = KeyInstallState.Cancelled installState.value = KeyInstallState.Cancelled
} }
} }
} activity.storageHelper!!.onFileSelected = previousFileCallback
} }
activity.storageHelper?.storage?.openFilePicker() activity.storageHelper?.storage?.openFilePicker()
} }
@ -221,7 +227,7 @@ class SettingsViewModel(val activity: MainActivity) {
if (installState.value != KeyInstallState.Query) if (installState.value != KeyInstallState.Query)
return return
if (selectedKeyFile == null) { if (selectedKeyFile == null) {
installState.value = KeyInstallState.None installState.value = KeyInstallState.File
return return
} }
selectedKeyFile?.apply { selectedKeyFile?.apply {
@ -247,21 +253,19 @@ class SettingsViewModel(val activity: MainActivity) {
fun clearKeySelection(installState: MutableState<KeyInstallState>) { fun clearKeySelection(installState: MutableState<KeyInstallState>) {
selectedKeyFile = null selectedKeyFile = null
installState.value = KeyInstallState.None installState.value = KeyInstallState.File
} }
fun selectFirmware(installState: MutableState<FirmwareInstallState>) { fun selectFirmware(installState: MutableState<FirmwareInstallState>) {
if (installState.value != FirmwareInstallState.None) if (installState.value != FirmwareInstallState.File)
return return
activity.storageHelper!!.onFileSelected = { _, files -> activity.storageHelper!!.onFileSelected = { _, files ->
run {
activity.storageHelper!!.onFileSelected = previousFileCallback
val file = files.firstOrNull() val file = files.firstOrNull()
file?.apply { file?.apply {
if (extension == "xci" || extension == "zip") { if (extension == "xci" || extension == "zip") {
installState.value = FirmwareInstallState.Verifying installState.value = FirmwareInstallState.Verifying
thread { thread {
Thread.sleep(1000)
val descriptor = activity.contentResolver.openFileDescriptor(file.uri, "rw") val descriptor = activity.contentResolver.openFileDescriptor(file.uri, "rw")
descriptor?.use { d -> descriptor?.use { d ->
selectedFirmwareVersion = KenjinxNative.deviceVerifyFirmware(d.fd, extension == "xci") selectedFirmwareVersion = KenjinxNative.deviceVerifyFirmware(d.fd, extension == "xci")
@ -277,7 +281,7 @@ class SettingsViewModel(val activity: MainActivity) {
installState.value = FirmwareInstallState.Cancelled installState.value = FirmwareInstallState.Cancelled
} }
} }
} activity.storageHelper!!.onFileSelected = previousFileCallback
} }
activity.storageHelper?.storage?.openFilePicker() activity.storageHelper?.storage?.openFilePicker()
} }
@ -286,7 +290,7 @@ class SettingsViewModel(val activity: MainActivity) {
if (installState.value != FirmwareInstallState.Query) if (installState.value != FirmwareInstallState.Query)
return return
if (selectedFirmwareFile == null) { if (selectedFirmwareFile == null) {
installState.value = FirmwareInstallState.None installState.value = FirmwareInstallState.File
return return
} }
selectedFirmwareFile?.apply { selectedFirmwareFile?.apply {
@ -312,7 +316,34 @@ class SettingsViewModel(val activity: MainActivity) {
fun clearFirmwareSelection(installState: MutableState<FirmwareInstallState>) { fun clearFirmwareSelection(installState: MutableState<FirmwareInstallState>) {
selectedFirmwareFile = null selectedFirmwareFile = null
selectedFirmwareVersion = "" selectedFirmwareVersion = ""
installState.value = FirmwareInstallState.None installState.value = FirmwareInstallState.File
}
fun resetAppData(
dataResetState: MutableState<DataResetState>
) {
dataResetState.value = DataResetState.Reset
thread {
Thread.sleep(1000)
try {
MainActivity.StorageHelper?.apply {
val folders = listOf("bis", "games", "profiles", "system")
for (f in folders) {
val dir = File(MainActivity.AppPath + "${File.separator}${f}")
if (dir.exists()) {
dir.deleteRecursively()
}
dir.mkdirs()
}
}
} finally {
dataResetState.value = DataResetState.Done
KenjinxNative.deviceReloadFilesystem()
MainActivity.mainViewModel?.refreshFirmwareVersion()
}
}
} }
fun importAppData( fun importAppData(
@ -320,6 +351,9 @@ class SettingsViewModel(val activity: MainActivity) {
dataImportState: MutableState<DataImportState> dataImportState: MutableState<DataImportState>
) { ) {
dataImportState.value = DataImportState.Import dataImportState.value = DataImportState.Import
thread {
Thread.sleep(1000)
try { try {
MainActivity.StorageHelper?.apply { MainActivity.StorageHelper?.apply {
val stream = file.openInputStream(storage.context) val stream = file.openInputStream(storage.context)
@ -366,9 +400,10 @@ class SettingsViewModel(val activity: MainActivity) {
} }
} }
} }
}
enum class KeyInstallState { enum class KeyInstallState {
None, File,
Cancelled, Cancelled,
Query, Query,
Install, Install,
@ -376,7 +411,7 @@ enum class KeyInstallState {
} }
enum class FirmwareInstallState { enum class FirmwareInstallState {
None, File,
Cancelled, Cancelled,
Verifying, Verifying,
Query, Query,
@ -384,8 +419,14 @@ enum class FirmwareInstallState {
Done Done
} }
enum class DataResetState {
Query,
Reset,
Done
}
enum class DataImportState { enum class DataImportState {
None, File,
Query, Query,
Import, Import,
Done Done

View file

@ -22,6 +22,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.Build
import androidx.compose.material.icons.filled.Create
import androidx.compose.material.icons.filled.FileDownload import androidx.compose.material.icons.filled.FileDownload
import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.MailOutline import androidx.compose.material.icons.filled.MailOutline
@ -62,6 +63,7 @@ import kotlin.concurrent.thread
import org.kenjinx.android.MainActivity import org.kenjinx.android.MainActivity
import org.kenjinx.android.providers.DocumentProvider import org.kenjinx.android.providers.DocumentProvider
import org.kenjinx.android.viewmodels.DataImportState import org.kenjinx.android.viewmodels.DataImportState
import org.kenjinx.android.viewmodels.DataResetState
import org.kenjinx.android.viewmodels.FirmwareInstallState import org.kenjinx.android.viewmodels.FirmwareInstallState
import org.kenjinx.android.viewmodels.KeyInstallState import org.kenjinx.android.viewmodels.KeyInstallState
import org.kenjinx.android.viewmodels.MainViewModel import org.kenjinx.android.viewmodels.MainViewModel
@ -90,6 +92,8 @@ class SettingViews {
val vSyncMode = remember { mutableStateOf(VSyncMode.Switch) } val vSyncMode = remember { mutableStateOf(VSyncMode.Switch) }
val enableDocked = remember { mutableStateOf(false) } val enableDocked = remember { mutableStateOf(false) }
val enablePptc = remember { mutableStateOf(false) } val enablePptc = remember { mutableStateOf(false) }
val enableLowPowerPptc = remember { mutableStateOf(false) }
val enableJitCacheEviction = remember { mutableStateOf(false) }
var enableFsIntegrityChecks = remember { mutableStateOf(false) } var enableFsIntegrityChecks = remember { mutableStateOf(false) }
var fsGlobalAccessLogMode = remember { mutableStateOf(0) } var fsGlobalAccessLogMode = remember { mutableStateOf(0) }
val ignoreMissingServices = remember { mutableStateOf(false) } val ignoreMissingServices = remember { mutableStateOf(false) }
@ -100,12 +104,14 @@ class SettingViews {
val maxAnisotropy = remember { mutableStateOf(0f) } val maxAnisotropy = remember { mutableStateOf(0f) }
val useVirtualController = remember { mutableStateOf(true) } val useVirtualController = remember { mutableStateOf(true) }
val showKeyDialog = remember { mutableStateOf(false) } val showKeyDialog = remember { mutableStateOf(false) }
val keyInstallState = remember { mutableStateOf(KeyInstallState.None) } val keyInstallState = remember { mutableStateOf(KeyInstallState.File) }
val showFirwmareDialog = remember { mutableStateOf(false) } val showFirwmareDialog = remember { mutableStateOf(false) }
val firmwareInstallState = remember { mutableStateOf(FirmwareInstallState.None) } val firmwareInstallState = remember { mutableStateOf(FirmwareInstallState.File) }
val firmwareVersion = remember { mutableStateOf(mainViewModel.firmwareVersion) } val firmwareVersion = remember { mutableStateOf(mainViewModel.firmwareVersion) }
val showDataResetDialog = remember { mutableStateOf(false) }
val showDataImportDialog = remember { mutableStateOf(false) } val showDataImportDialog = remember { mutableStateOf(false) }
val dataImportState = remember { mutableStateOf(DataImportState.None) } val dataResetState = remember { mutableStateOf(DataResetState.Query) }
val dataImportState = remember { mutableStateOf(DataImportState.File) }
var dataFile = remember { mutableStateOf<DocumentFile?>(null) } var dataFile = remember { mutableStateOf<DocumentFile?>(null) }
val isGrid = remember { mutableStateOf(true) } val isGrid = remember { mutableStateOf(true) }
val useSwitchLayout = remember { mutableStateOf(true) } val useSwitchLayout = remember { mutableStateOf(true) }
@ -131,6 +137,8 @@ class SettingViews {
vSyncMode, vSyncMode,
enableDocked, enableDocked,
enablePptc, enablePptc,
enableLowPowerPptc,
enableJitCacheEviction,
enableFsIntegrityChecks, enableFsIntegrityChecks,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,
ignoreMissingServices, ignoreMissingServices,
@ -172,6 +180,8 @@ class SettingViews {
vSyncMode, vSyncMode,
enableDocked, enableDocked,
enablePptc, enablePptc,
enableLowPowerPptc,
enableJitCacheEviction,
enableFsIntegrityChecks, enableFsIntegrityChecks,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,
ignoreMissingServices, ignoreMissingServices,
@ -236,23 +246,6 @@ class SettingViews {
modifier = Modifier.align(Alignment.CenterVertically) modifier = Modifier.align(Alignment.CenterVertically)
) )
} }
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 8.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween,
){
ActionButton(
onClick = {
settingsViewModel.openGameFolder()
},
text = "Add Game Folder",
icon = Icons.Default.Add,
modifier = Modifier.weight(1f),
isFullWidth = false,
)
}
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -287,7 +280,40 @@ class SettingViews {
isFullWidth = false, isFullWidth = false,
) )
} }
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 8.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween,
){
ActionButton(
onClick = {
settingsViewModel.openGameFolder()
},
text = "Add Game Folder",
icon = Icons.Default.Add,
modifier = Modifier.weight(1f),
isFullWidth = false,
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 8.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween,
) {
ActionButton(
onClick = {
showDataResetDialog.value = true
},
text = "Reinit App Data",
icon = Icons.Default.Create,
modifier = Modifier.weight(1f),
isFullWidth = false,
)
}
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -359,6 +385,7 @@ class SettingViews {
if (keyInstallState.value != KeyInstallState.Install) { if (keyInstallState.value != KeyInstallState.Install) {
showKeyDialog.value = false showKeyDialog.value = false
settingsViewModel.clearKeySelection(keyInstallState) settingsViewModel.clearKeySelection(keyInstallState)
keyInstallState.value = KeyInstallState.File
} }
} }
) { ) {
@ -378,7 +405,7 @@ class SettingViews {
) )
when (keyInstallState.value) { when (keyInstallState.value) {
KeyInstallState.None -> { KeyInstallState.File -> {
Text( Text(
text = "Select a key file to install key from.", text = "Select a key file to install key from.",
modifier = Modifier modifier = Modifier
@ -437,7 +464,7 @@ class SettingViews {
keyInstallState keyInstallState
) )
if (keyInstallState.value == KeyInstallState.None) { if (keyInstallState.value == KeyInstallState.File) {
showKeyDialog.value = false showKeyDialog.value = false
settingsViewModel.clearKeySelection(keyInstallState) settingsViewModel.clearKeySelection(keyInstallState)
} }
@ -561,6 +588,7 @@ class SettingViews {
if (firmwareInstallState.value != FirmwareInstallState.Install) { if (firmwareInstallState.value != FirmwareInstallState.Install) {
showFirwmareDialog.value = false showFirwmareDialog.value = false
settingsViewModel.clearFirmwareSelection(firmwareInstallState) settingsViewModel.clearFirmwareSelection(firmwareInstallState)
firmwareInstallState.value = FirmwareInstallState.File
} }
} }
) { ) {
@ -580,7 +608,7 @@ class SettingViews {
) )
when (firmwareInstallState.value) { when (firmwareInstallState.value) {
FirmwareInstallState.None -> { FirmwareInstallState.File -> {
Text( Text(
text = "Select a zip or xci file to install firmware from.", text = "Select a zip or xci file to install firmware from.",
modifier = Modifier modifier = Modifier
@ -635,7 +663,7 @@ class SettingViews {
onClick = { onClick = {
settingsViewModel.installFirmware(firmwareInstallState) settingsViewModel.installFirmware(firmwareInstallState)
if (firmwareInstallState.value == FirmwareInstallState.None) { if (firmwareInstallState.value == FirmwareInstallState.File) {
showFirwmareDialog.value = false showFirwmareDialog.value = false
settingsViewModel.clearFirmwareSelection(firmwareInstallState) settingsViewModel.clearFirmwareSelection(firmwareInstallState)
} }
@ -779,13 +807,125 @@ class SettingViews {
} }
} }
} }
SimpleAlertDialog.Custom(
showDialog = showDataResetDialog,
onDismissRequest = {
if (dataResetState.value != DataResetState.Reset) {
showDataResetDialog.value = false
dataResetState.value = DataResetState.Query
}
}
) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "App Data Reinit",
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp),
textAlign = TextAlign.Center
)
when (dataResetState.value) {
DataResetState.Query -> {
Text(
text = "Current bis, games, profiles and system folders will be reset. Do you want to continue?",
modifier = Modifier
.fillMaxWidth()
.padding(start = 8.dp, bottom = 8.dp),
textAlign = TextAlign.Start
)
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
) {
Button(
onClick = {
thread {
settingsViewModel.resetAppData(dataResetState)
}
},
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Text(text = "Yes")
}
Button(
onClick = {
showDataResetDialog.value = false
},
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Text(text = "No")
}
}
}
DataResetState.Reset -> {
Text(
text = "Resetting app data...",
modifier = Modifier
.fillMaxWidth()
.padding(start = 8.dp, bottom = 8.dp),
textAlign = TextAlign.Start
)
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
)
}
DataResetState.Done -> {
Text(
text = "Data reset completed successfully.",
modifier = Modifier
.fillMaxWidth()
.padding(start = 8.dp, bottom = 8.dp),
textAlign = TextAlign.Start
)
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
) {
Button(
onClick = {
showDataResetDialog.value = false
firmwareVersion.value = mainViewModel.firmwareVersion
dataResetState.value = DataResetState.Query
mainViewModel.userViewModel.refreshUsers()
mainViewModel.homeViewModel.requestReload()
mainViewModel.activity.shutdownAndRestart()
},
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Text(text = "Close")
}
}
}
}
}
}
SimpleAlertDialog.Custom( SimpleAlertDialog.Custom(
showDialog = showDataImportDialog, showDialog = showDataImportDialog,
onDismissRequest = { onDismissRequest = {
if (dataImportState.value != DataImportState.Import) { if (dataImportState.value != DataImportState.Import) {
showDataImportDialog.value = false showDataImportDialog.value = false
dataFile.value = null dataFile.value = null
dataImportState.value = DataImportState.None dataImportState.value = DataImportState.File
} }
} }
) { ) {
@ -805,9 +945,9 @@ class SettingViews {
) )
when (dataImportState.value) { when (dataImportState.value) {
DataImportState.None -> { DataImportState.File -> {
Text( Text(
text = "Select a zip file to import app data from.", text = "Select a zip file to import bis, games, profiles and system folders from another Android installation.",
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(start = 8.dp, bottom = 8.dp), .padding(start = 8.dp, bottom = 8.dp),
@ -854,7 +994,7 @@ class SettingViews {
onClick = { onClick = {
showDataImportDialog.value = false showDataImportDialog.value = false
dataFile.value = null dataFile.value = null
dataImportState.value = DataImportState.None dataImportState.value = DataImportState.File
}, },
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
@ -942,9 +1082,10 @@ class SettingViews {
showDataImportDialog.value = false showDataImportDialog.value = false
dataFile.value = null dataFile.value = null
firmwareVersion.value = mainViewModel.firmwareVersion firmwareVersion.value = mainViewModel.firmwareVersion
dataImportState.value = DataImportState.None dataImportState.value = DataImportState.File
mainViewModel.userViewModel.refreshUsers() mainViewModel.userViewModel.refreshUsers()
mainViewModel.homeViewModel.requestReload() mainViewModel.homeViewModel.requestReload()
mainViewModel.activity.shutdownAndRestart()
}, },
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
@ -1032,6 +1173,8 @@ class SettingViews {
Column(modifier = Modifier.fillMaxWidth()) { Column(modifier = Modifier.fillMaxWidth()) {
useNce.SwitchSelector(label = "Enable NCE (Native Code Execution)") useNce.SwitchSelector(label = "Enable NCE (Native Code Execution)")
enablePptc.SwitchSelector(label = "Enable PPTC (Profiled Persistent Translation Cache)") enablePptc.SwitchSelector(label = "Enable PPTC (Profiled Persistent Translation Cache)")
enableLowPowerPptc.SwitchSelector(label = "Enable Low-Power PPTC")
enableJitCacheEviction.SwitchSelector(label = "Enable Jit Cache Eviction")
MemoryModeDropdown( MemoryModeDropdown(
selectedMemoryManagerMode = memoryManagerMode.value, selectedMemoryManagerMode = memoryManagerMode.value,
onModeSelected = { mode -> onModeSelected = { mode ->

View file

@ -79,6 +79,8 @@ namespace LibKenjinx
int vSyncMode, int vSyncMode,
bool enableDockedMode, bool enableDockedMode,
bool enablePtc, bool enablePtc,
bool enableLowPowerPtc,
bool enableJitCacheEviction,
bool enableInternetAccess, bool enableInternetAccess,
bool enableFsIntegrityChecks, bool enableFsIntegrityChecks,
int fsGlobalAccessLogMode, int fsGlobalAccessLogMode,
@ -98,6 +100,8 @@ namespace LibKenjinx
(VSyncMode)vSyncMode, (VSyncMode)vSyncMode,
enableDockedMode, enableDockedMode,
enablePtc, enablePtc,
enableLowPowerPtc,
enableJitCacheEviction,
enableInternetAccess, enableInternetAccess,
enableFsIntegrityChecks, enableFsIntegrityChecks,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,

View file

@ -26,6 +26,8 @@ namespace LibKenjinx
VSyncMode vSyncMode, VSyncMode vSyncMode,
bool enableDockedMode, bool enableDockedMode,
bool enablePtc, bool enablePtc,
bool enableLowPowerPtc,
bool enableJitCacheEviction,
bool enableInternetAccess, bool enableInternetAccess,
bool enableFsIntegrityChecks, bool enableFsIntegrityChecks,
int fsGlobalAccessLogMode, int fsGlobalAccessLogMode,
@ -45,6 +47,8 @@ namespace LibKenjinx
vSyncMode, vSyncMode,
enableDockedMode, enableDockedMode,
enablePtc, enablePtc,
enableLowPowerPtc,
enableJitCacheEviction,
enableInternetAccess, enableInternetAccess,
enableFsIntegrityChecks, enableFsIntegrityChecks,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,

View file

@ -10,6 +10,7 @@ using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.UI.Common.Configuration;
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -94,6 +95,9 @@ namespace LibKenjinx
{ {
return; return;
} }
ARMeilleure.Optimizations.EcoFriendly = SwitchDevice!.EnableLowPowerPtc;
ARMeilleure.Optimizations.CacheEviction = SwitchDevice!.EnableJitCacheEviction;
var device = SwitchDevice!.EmulationContext!; var device = SwitchDevice!.EmulationContext!;
_gpuDoneEvent = new ManualResetEvent(true); _gpuDoneEvent = new ManualResetEvent(true);

View file

@ -41,6 +41,8 @@ namespace LibKenjinx
VSyncMode vSyncMode, VSyncMode vSyncMode,
bool enableDockedMode, bool enableDockedMode,
bool enablePtc, bool enablePtc,
bool enableLowPowerPtc,
bool enableJitCacheEviction,
bool enableInternetAccess, bool enableInternetAccess,
bool enableFsIntegrityChecks, bool enableFsIntegrityChecks,
int fsGlobalAccessLogMode, int fsGlobalAccessLogMode,
@ -55,6 +57,8 @@ namespace LibKenjinx
vSyncMode, vSyncMode,
enableDockedMode, enableDockedMode,
enablePtc, enablePtc,
enableLowPowerPtc,
enableJitCacheEviction,
enableInternetAccess, enableInternetAccess,
enableFsIntegrityChecks, enableFsIntegrityChecks,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,

View file

@ -419,7 +419,7 @@ namespace LibKenjinx
} }
// Return the ControlFS // Return the ControlFS
controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None); controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, SwitchDevice.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None);
titleId = controlNca?.Header.TitleId.ToString("x16"); titleId = controlNca?.Header.TitleId.ToString("x16");
} }
@ -486,7 +486,7 @@ namespace LibKenjinx
if (patchNca != null && controlNca != null) if (patchNca != null && controlNca != null)
{ {
updatedControlFs = controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None); updatedControlFs = controlNca.OpenFileSystem(NcaSectionType.Data, SwitchDevice.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None);
return true; return true;
} }
@ -708,6 +708,10 @@ namespace LibKenjinx
public InputManager? InputManager { get; set; } public InputManager? InputManager { get; set; }
public Switch? EmulationContext { get; set; } public Switch? EmulationContext { get; set; }
public IHostUIHandler? HostUiHandler { get; set; } public IHostUIHandler? HostUiHandler { get; set; }
public bool EnableLowPowerPtc { get; set; }
public bool EnableJitCacheEviction { get; set; }
public bool EnableFsIntegrityChecks { get; set; }
internal void DisposeContext() internal void DisposeContext()
{ {
@ -803,6 +807,8 @@ namespace LibKenjinx
VSyncMode vSyncMode, VSyncMode vSyncMode,
bool enableDockedMode, bool enableDockedMode,
bool enablePtc, bool enablePtc,
bool enableLowPowerPtc,
bool enableJitCacheEviction,
bool enableInternetAccess, bool enableInternetAccess,
bool enableFsIntegrityChecks, bool enableFsIntegrityChecks,
int fsGlobalAccessLogMode, int fsGlobalAccessLogMode,
@ -824,6 +830,10 @@ namespace LibKenjinx
renderer = new ThreadedRenderer(renderer); renderer = new ThreadedRenderer(renderer);
} }
EnableLowPowerPtc = enableLowPowerPtc;
EnableJitCacheEviction = enableJitCacheEviction;
EnableFsIntegrityChecks = enableFsIntegrityChecks;
HLEConfiguration configuration = new HLEConfiguration(VirtualFileSystem, HLEConfiguration configuration = new HLEConfiguration(VirtualFileSystem,
LibHacHorizonManager, LibHacHorizonManager,
ContentManager, ContentManager,
@ -839,7 +849,7 @@ namespace LibKenjinx
enableDockedMode, enableDockedMode,
enablePtc, enablePtc,
enableInternetAccess, enableInternetAccess,
enableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
fsGlobalAccessLogMode, fsGlobalAccessLogMode,
0, 0,
timeZone, timeZone,

View file

@ -27,6 +27,6 @@ namespace Ryujinx.Common
public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannelOwner); public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannelOwner);
public static string Version => (IsValid || !RuntimeFeature.IsDynamicCodeCompiled) ? (PlatformInfo.IsBionic ? "Android_2.0.3" : BuildVersion) : Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion; public static string Version => (IsValid || !RuntimeFeature.IsDynamicCodeCompiled) ? (PlatformInfo.IsBionic ? "Bionic_2.0.3" : BuildVersion) : Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
} }
} }

View file

@ -1,8 +1,11 @@
using ARMeilleure;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using Ryujinx.Common.Logging;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading; using System.Threading;
@ -14,8 +17,15 @@ namespace Ryujinx.Cpu.LightningJit.Cache
private static readonly int _pageSize = (int)MemoryBlock.GetPageSize(); private static readonly int _pageSize = (int)MemoryBlock.GetPageSize();
private static readonly int _pageMask = _pageSize - 1; private static readonly int _pageMask = _pageSize - 1;
private const int CodeAlignment = 4; // Bytes. private const int CodeAlignment = 4;
private const int CacheSize = 2047 * 1024 * 1024; private const int FullCacheSize = 2047 * 1024 * 1024;
private const int ReducedCacheSize = FullCacheSize / 8;
private const float EvictionTargetPercentage = 0.20f;
private const int MaxEntriesToEvictAtOnce = 100;
// Simple logging configuration
private const int LogInterval = 5000; // Log every 5000 allocations
private static ReservedRegion _jitRegion; private static ReservedRegion _jitRegion;
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
@ -23,9 +33,33 @@ namespace Ryujinx.Cpu.LightningJit.Cache
private static CacheMemoryAllocator _cacheAllocator; private static CacheMemoryAllocator _cacheAllocator;
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
private static readonly Dictionary<int, EntryUsageStats> _entryUsageStats = [];
private static readonly Lock _lock = new(); private static readonly Lock _lock = new();
private static bool _initialized; private static bool _initialized;
private static int _cacheSize;
// Basic statistics
private static int _totalAllocations = 0;
private static int _totalEvictions = 0;
private class EntryUsageStats
{
public long LastAccessTime { get; private set; }
public int UsageCount { get; private set; }
public EntryUsageStats()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount = 1;
}
public void UpdateUsage()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount++;
}
}
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
[LibraryImport("kernel32.dll", SetLastError = true)] [LibraryImport("kernel32.dll", SetLastError = true)]
@ -45,15 +79,17 @@ namespace Ryujinx.Cpu.LightningJit.Cache
return; return;
} }
_jitRegion = new ReservedRegion(allocator, CacheSize); _cacheSize = Optimizations.CacheEviction ? ReducedCacheSize : FullCacheSize;
_jitRegion = new ReservedRegion(allocator, (ulong)_cacheSize);
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{ {
_jitCacheInvalidator = new JitCacheInvalidation(allocator); _jitCacheInvalidator = new JitCacheInvalidation(allocator);
} }
_cacheAllocator = new CacheMemoryAllocator(CacheSize); _cacheAllocator = new CacheMemoryAllocator(_cacheSize);
Logger.Info?.Print(LogClass.Cpu, $"Lightning JIT Cache initialized: Size={_cacheSize / (1024 * 1024)} MB, Eviction={Optimizations.CacheEviction}");
_initialized = true; _initialized = true;
} }
} }
@ -63,8 +99,32 @@ namespace Ryujinx.Cpu.LightningJit.Cache
lock (_lock) lock (_lock)
{ {
Debug.Assert(_initialized); Debug.Assert(_initialized);
_totalAllocations++;
int funcOffset = Allocate(code.Length); int funcOffset;
if (Optimizations.CacheEviction)
{
int codeSize = AlignCodeSize(code.Length);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
EvictEntries(codeSize);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
throw new OutOfMemoryException("JIT Cache exhausted even after eviction.");
}
}
_jitRegion.ExpandIfNeeded((ulong)funcOffset + (ulong)codeSize);
}
else
{
funcOffset = Allocate(code.Length);
}
IntPtr funcPtr = _jitRegion.Pointer + funcOffset; IntPtr funcPtr = _jitRegion.Pointer + funcOffset;
@ -96,6 +156,12 @@ namespace Ryujinx.Cpu.LightningJit.Cache
Add(funcOffset, code.Length); Add(funcOffset, code.Length);
// Simple periodic logging
if (_totalAllocations % LogInterval == 0)
{
LogCacheStatus();
}
return funcPtr; return funcPtr;
} }
} }
@ -112,6 +178,11 @@ namespace Ryujinx.Cpu.LightningJit.Cache
{ {
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
_cacheEntries.RemoveAt(entryIndex); _cacheEntries.RemoveAt(entryIndex);
if (Optimizations.CacheEviction)
{
_entryUsageStats.Remove(funcOffset);
}
} }
} }
} }
@ -169,6 +240,11 @@ namespace Ryujinx.Cpu.LightningJit.Cache
} }
_cacheEntries.Insert(index, entry); _cacheEntries.Insert(index, entry);
if (Optimizations.CacheEviction)
{
_entryUsageStats[offset] = new EntryUsageStats();
}
} }
public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex) public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
@ -185,6 +261,12 @@ namespace Ryujinx.Cpu.LightningJit.Cache
if (index >= 0) if (index >= 0)
{ {
entry = _cacheEntries[index]; entry = _cacheEntries[index];
if (Optimizations.CacheEviction && _entryUsageStats.TryGetValue(offset, out var stats))
{
stats.UpdateUsage();
}
entryIndex = index; entryIndex = index;
return true; return true;
} }
@ -194,5 +276,83 @@ namespace Ryujinx.Cpu.LightningJit.Cache
entryIndex = 0; entryIndex = 0;
return false; return false;
} }
private static void EvictEntries(int requiredSize)
{
if (!Optimizations.CacheEviction)
{
return;
}
lock (_lock)
{
int targetSpace = Math.Max(requiredSize, (int)(_cacheSize * EvictionTargetPercentage));
int freedSpace = 0;
int evictedCount = 0;
var entriesWithStats = _cacheEntries
.Where(e => _entryUsageStats.ContainsKey(e.Offset))
.Select(e => new {
Entry = e,
Stats = _entryUsageStats[e.Offset],
Score = CalculateEvictionScore(_entryUsageStats[e.Offset])
})
.OrderBy(x => x.Score)
.Take(MaxEntriesToEvictAtOnce)
.ToList();
foreach (var item in entriesWithStats)
{
int entrySize = AlignCodeSize(item.Entry.Size);
int entryIndex = _cacheEntries.BinarySearch(item.Entry);
if (entryIndex >= 0)
{
_cacheAllocator.Free(item.Entry.Offset, entrySize);
_cacheEntries.RemoveAt(entryIndex);
_entryUsageStats.Remove(item.Entry.Offset);
freedSpace += entrySize;
evictedCount++;
if (freedSpace >= targetSpace)
{
break;
}
}
}
_totalEvictions += evictedCount;
Logger.Info?.Print(LogClass.Cpu, $"Lightning JIT Cache: Evicted {evictedCount} entries, freed {freedSpace / (1024 * 1024.0):F2} MB");
}
}
private static double CalculateEvictionScore(EntryUsageStats stats)
{
long currentTime = DateTime.UtcNow.Ticks;
long ageInTicks = currentTime - stats.LastAccessTime;
double ageInSeconds = ageInTicks / 10_000_000.0;
const double usageWeight = 1.0;
const double ageWeight = 2.0;
double usageScore = Math.Log10(stats.UsageCount + 1) * usageWeight;
double ageScore = (10.0 / (ageInSeconds + 1.0)) * ageWeight;
return usageScore + ageScore;
}
private static void LogCacheStatus()
{
int estimatedUsedSize = _cacheEntries.Sum(e => AlignCodeSize(e.Size));
double usagePercentage = 100.0 * estimatedUsedSize / _cacheSize;
Logger.Info?.Print(LogClass.Cpu,
$"Lightning JIT Cache status: entries={_cacheEntries.Count}, " +
$"est. used={estimatedUsedSize / (1024 * 1024.0):F2} MB ({usagePercentage:F1}%), " +
$"evictions={_totalEvictions}, allocations={_totalAllocations}");
}
} }
} }

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
{ {
private const int CodeAlignment = 4; // Bytes. private const int CodeAlignment = 4; // Bytes.
private const int SharedCacheSize = 2047 * 1024 * 1024; private const int SharedCacheSize = 2047 * 1024 * 1024;
private const int LocalCacheSize = 128 * 1024 * 1024; private const int LocalCacheSize = 256 * 1024 * 1024;
// How many calls to the same function we allow until we pad the shared cache to force the function to become available there // How many calls to the same function we allow until we pad the shared cache to force the function to become available there
// and allow the guest to take the fast path. // and allow the guest to take the fast path.

View file

@ -512,14 +512,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend) if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend)
{ {
IoDefinition firstOutput = outputs.ElementAtOrDefault(0); IoDefinition firstOutput = outputs.ElementAtOrDefault(0);
IoDefinition secondOutput = outputs.ElementAtOrDefault(1);
if (firstOutput.Location + 1 == secondOutput.Location)
{
DeclareOutputDualSourceBlendAttribute(context, firstOutput.Location); DeclareOutputDualSourceBlendAttribute(context, firstOutput.Location);
outputs = outputs.Skip(2); outputs = outputs.Skip(2);
} }
}
foreach (var ioDefinition in outputs) foreach (var ioDefinition in outputs)
{ {

View file

@ -9,6 +9,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{ {
public static void RunPass(TransformContext context) public static void RunPass(TransformContext context)
{ {
for (int blkIndex = 0; blkIndex < context.Blocks.Length; blkIndex++)
{
XmadOptimizer.RunPass(context.Blocks[blkIndex]);
}
RunOptimizationPasses(context.Blocks, context.ResourceManager); RunOptimizationPasses(context.Blocks, context.ResourceManager);
// TODO: Some of those are not optimizations and shouldn't be here. // TODO: Some of those are not optimizations and shouldn't be here.

View file

@ -181,13 +181,29 @@ namespace Ryujinx.Graphics.Shader.Translation
private static void EmitOutputsInitialization(EmitterContext context, AttributeUsage attributeUsage, IGpuAccessor gpuAccessor, ShaderStage stage) private static void EmitOutputsInitialization(EmitterContext context, AttributeUsage attributeUsage, IGpuAccessor gpuAccessor, ShaderStage stage)
{ {
// Compute has no output attributes, and fragment is the last stage, so we // Compute has no output attributes, so we
// don't need to initialize outputs on those stages. // don't need to initialize outputs on that stage.
if (stage == ShaderStage.Compute || stage == ShaderStage.Fragment) if (stage == ShaderStage.Compute)
{ {
return; return;
} }
if (stage == ShaderStage.Fragment)
{
// Fragment is the last stage, so we don't need to
// initialize outputs unless we're using DSB, in which
// we need to make sure the ouput has a valid value.
if (gpuAccessor.QueryGraphicsState().DualSourceBlendEnable)
{
for (int i = 0; i < 4; i++)
{
context.Store(StorageKind.Output, IoVariable.FragmentOutputColor, null, Const(1), Const(i), ConstF(0));
}
}
return;
}
if (stage == ShaderStage.Vertex) if (stage == ShaderStage.Vertex)
{ {
InitializeVertexOutputs(context); InitializeVertexOutputs(context);

View file

@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Vulkan
// If binding 3 is immediately used, use an alternate set of reserved bindings. // If binding 3 is immediately used, use an alternate set of reserved bindings.
ReadOnlyCollection<ResourceUsage> uniformUsage = layout.SetUsages[0].Usages; ReadOnlyCollection<ResourceUsage> uniformUsage = layout.SetUsages[0].Usages;
bool hasBinding3 = uniformUsage.Any(x => x.Binding == 3); bool hasBinding3 = uniformUsage.Any(x => x.Binding == 3);
int[] reserved = isCompute ? Array.Empty<int>() : gd.GetPushDescriptorReservedBindings(hasBinding3); int[] reserved = isCompute ? [] : gd.GetPushDescriptorReservedBindings(hasBinding3);
// Can't use any of the reserved usages. // Can't use any of the reserved usages.
for (int i = 0; i < uniformUsage.Count; i++) for (int i = 0; i < uniformUsage.Count; i++)
@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Vulkan
for (int setIndex = 0; setIndex < sets.Count; setIndex++) for (int setIndex = 0; setIndex < sets.Count; setIndex++)
{ {
List<ResourceBindingSegment> currentSegments = new(); List<ResourceBindingSegment> currentSegments = [];
ResourceDescriptor currentDescriptor = default; ResourceDescriptor currentDescriptor = default;
int currentCount = 0; int currentCount = 0;
@ -298,7 +298,7 @@ namespace Ryujinx.Graphics.Vulkan
for (int setIndex = 0; setIndex < setUsages.Count; setIndex++) for (int setIndex = 0; setIndex < setUsages.Count; setIndex++)
{ {
List<ResourceBindingSegment> currentSegments = new(); List<ResourceBindingSegment> currentSegments = [];
ResourceUsage currentUsage = default; ResourceUsage currentUsage = default;
int currentCount = 0; int currentCount = 0;

View file

@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples); var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true); var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities);
var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit; var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
@ -307,7 +307,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage) public static ImageUsageFlags GetImageUsage(Format format, Target target, in HardwareCapabilities capabilities)
{ {
var usage = DefaultUsageFlags; var usage = DefaultUsageFlags;
@ -320,11 +320,19 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit; usage |= ImageUsageFlags.ColorAttachmentBit;
} }
if ((format.IsImageCompatible() && isMsImageStorageSupported) || extendedUsage) bool isMsImageStorageSupported = capabilities.SupportsShaderStorageImageMultisample;
if (format.IsImageCompatible() && (isMsImageStorageSupported || !target.IsMultisample()))
{ {
usage |= ImageUsageFlags.StorageBit; usage |= ImageUsageFlags.StorageBit;
} }
if (capabilities.SupportsAttachmentFeedbackLoop &&
(usage & (ImageUsageFlags.DepthStencilAttachmentBit | ImageUsageFlags.ColorAttachmentBit)) != 0)
{
usage |= ImageUsageFlags.AttachmentFeedbackLoopBitExt;
}
return usage; return usage;
} }

View file

@ -64,8 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample(); bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported); var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
var usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false); var usage = TextureStorage.GetImageUsage(info.Format, info.Target, gd.Capabilities);
var levels = (uint)info.Levels; var levels = (uint)info.Levels;
var layers = (uint)info.GetLayers(); var layers = (uint)info.GetLayers();

View file

@ -468,9 +468,9 @@ namespace Ryujinx.Graphics.Vulkan
_gd.CommandBufferPool.Return( _gd.CommandBufferPool.Return(
cbs, cbs,
stackalloc[] { _imageAvailableSemaphores[semaphoreIndex] }, [_imageAvailableSemaphores[semaphoreIndex]],
stackalloc[] { PipelineStageFlags.ColorAttachmentOutputBit }, [PipelineStageFlags.ColorAttachmentOutputBit],
stackalloc[] { _renderFinishedSemaphores[semaphoreIndex] }); [_renderFinishedSemaphores[semaphoreIndex]]);
// TODO: Present queue. // TODO: Present queue.
var semaphore = _renderFinishedSemaphores[semaphoreIndex]; var semaphore = _renderFinishedSemaphores[semaphoreIndex];

View file

@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
// TODO: Remove once we no longer need to initialize it externally. // TODO: Remove once we no longer need to initialize it externally.
HandleTable = new KHandleTable(); HandleTable = new KHandleTable();
_threads = new LinkedList<KThread>(); _threads = [];
Debugger = new HleProcessDebugger(this); Debugger = new HleProcessDebugger(this);
} }

View file

@ -121,7 +121,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
device.System.KernelContext, device.System.KernelContext,
metaLoader, metaLoader,
nacpData, nacpData,
device.System.EnablePtc, enablePtc,
modLoadResult.Hash, modLoadResult.Hash,
true, true,
programName, programName,

View file

@ -305,6 +305,13 @@ namespace Ryujinx.HLE.Loaders.Processes
if (string.IsNullOrWhiteSpace(programName)) if (string.IsNullOrWhiteSpace(programName))
{ {
foreach (ApplicationControlProperty.ApplicationTitle nacpTitles in nacpData.Value.Title)
{
if (nacpTitles.Name[0] != 0)
continue;
programName = nacpTitles.NameString.ToString();
}
programName = Array.Find(nacpData.Value.Title.AsReadOnlySpan().ToArray(), x => x.Name[0] != 0).NameString.ToString(); programName = Array.Find(nacpData.Value.Title.AsReadOnlySpan().ToArray(), x => x.Name[0] != 0).NameString.ToString();
} }

View file

@ -235,7 +235,7 @@ namespace Ryujinx.HLE.Loaders.Processes
ulong programId, ulong programId,
byte programIndex, byte programIndex,
byte[] arguments = null, byte[] arguments = null,
params IExecutable[] executables) params ReadOnlySpan<IExecutable> executables)
{ {
context.Device.System.ServiceTable.WaitServicesReady(); context.Device.System.ServiceTable.WaitServicesReady();
@ -255,12 +255,17 @@ namespace Ryujinx.HLE.Loaders.Processes
ulong codeStart = ((meta.Flags & 1) != 0 ? 0x8000000UL : 0x200000UL) + CodeStartOffset; ulong codeStart = ((meta.Flags & 1) != 0 ? 0x8000000UL : 0x200000UL) + CodeStartOffset;
ulong codeSize = 0; ulong codeSize = 0;
IEnumerable<string> buildIds = executables.Select(e => (e switch string[] buildIds = new string[executables.Length];
for (int i = 0; i < executables.Length; i++)
{
buildIds[i] = (executables[i] switch
{ {
NsoExecutable nso => Convert.ToHexString(nso.BuildId), NsoExecutable nso => Convert.ToHexString(nso.BuildId),
NroExecutable nro => Convert.ToHexString(nro.Header.BuildId), NroExecutable nro => Convert.ToHexString(nro.Header.BuildId),
_ => string.Empty, _ => string.Empty
}).ToUpper()); }).ToUpper();
}
NceCpuCodePatch[] nsoPatch = new NceCpuCodePatch[executables.Length]; NceCpuCodePatch[] nsoPatch = new NceCpuCodePatch[executables.Length];
ulong[] nsoBase = new ulong[executables.Length]; ulong[] nsoBase = new ulong[executables.Length];

View file

@ -16,7 +16,7 @@ namespace Ryujinx.UI.Common.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 58; public const int CurrentVersion = 59;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@ -240,6 +240,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public bool EnableLowPowerPtc { get; set; } public bool EnableLowPowerPtc { get; set; }
/// <summary>
/// Enables or disables JIT cache eviction to avoid out of memory errors in some games
/// </summary>
public bool EnableJitCacheEviction { get; set; }
/// <summary> /// <summary>
/// Enables or disables guest Internet access /// Enables or disables guest Internet access
/// </summary> /// </summary>

View file

@ -345,6 +345,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public ReactiveObject<bool> EnableLowPowerPtc { get; private set; } public ReactiveObject<bool> EnableLowPowerPtc { get; private set; }
/// <summary>
/// Enables or disables JIT cache eviction to avoid out of memory errors in some games
/// </summary>
public ReactiveObject<bool> EnableJitCacheEviction { get; private set; }
/// <summary> /// <summary>
/// Enables or disables guest Internet access /// Enables or disables guest Internet access
/// </summary> /// </summary>
@ -405,6 +410,8 @@ namespace Ryujinx.UI.Common.Configuration
EnablePtc.Event += static (sender, e) => LogValueChange(e, nameof(EnablePtc)); EnablePtc.Event += static (sender, e) => LogValueChange(e, nameof(EnablePtc));
EnableLowPowerPtc = new ReactiveObject<bool>(); EnableLowPowerPtc = new ReactiveObject<bool>();
EnableLowPowerPtc.Event += static (sender, e) => LogValueChange(e, nameof(EnableLowPowerPtc)); EnableLowPowerPtc.Event += static (sender, e) => LogValueChange(e, nameof(EnableLowPowerPtc));
EnableJitCacheEviction = new ReactiveObject<bool>();
EnableJitCacheEviction.Event += static (sender, e) => LogValueChange(e, nameof(EnableJitCacheEviction));
EnableInternetAccess = new ReactiveObject<bool>(); EnableInternetAccess = new ReactiveObject<bool>();
EnableInternetAccess.Event += static (sender, e) => LogValueChange(e, nameof(EnableInternetAccess)); EnableInternetAccess.Event += static (sender, e) => LogValueChange(e, nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject<bool>(); EnableFsIntegrityChecks = new ReactiveObject<bool>();
@ -775,6 +782,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough, EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
EnablePtc = System.EnablePtc, EnablePtc = System.EnablePtc,
EnableLowPowerPtc = System.EnableLowPowerPtc, EnableLowPowerPtc = System.EnableLowPowerPtc,
EnableJitCacheEviction = System.EnableJitCacheEviction,
EnableInternetAccess = System.EnableInternetAccess, EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks, EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode, FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
@ -1648,6 +1656,15 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true; configurationFileUpdated = true;
} }
if (configurationFileFormat.Version < 59)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 59.");
configurationFileFormat.EnableJitCacheEviction = false;
configurationFileUpdated = true;
}
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale; Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom; Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@ -1692,6 +1709,7 @@ namespace Ryujinx.UI.Common.Configuration
Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough; Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
System.EnablePtc.Value = configurationFileFormat.EnablePtc; System.EnablePtc.Value = configurationFileFormat.EnablePtc;
System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc; System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc;
System.EnableJitCacheEviction.Value = configurationFileFormat.EnableJitCacheEviction;
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess; System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks; System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode; System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;