Compare commits
13 Commits
Canary-1.2
...
2a914aa7b4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a914aa7b4 | ||
|
|
819f7ca072 | ||
|
|
4d6eeb6052 | ||
|
|
d652072cca | ||
|
|
50ecc2f764 | ||
|
|
f048bd8cb0 | ||
|
|
24406e639d | ||
|
|
2c34117957 | ||
|
|
ebeac1f4aa | ||
|
|
92b6756d24 | ||
|
|
a93adad50b | ||
|
|
8ff24506fb | ||
|
|
f05b3cdd53 |
@@ -3,8 +3,6 @@ using ARMeilleure.CodeGen.Linking;
|
||||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Common;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using Humanizer;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
@@ -32,8 +30,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 7007; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const uint InternalVersion = 6998; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
@@ -186,36 +184,6 @@ namespace ARMeilleure.Translation.PTC
|
||||
InitializeCarriers();
|
||||
}
|
||||
|
||||
private bool ContainsBlacklistedFunctions()
|
||||
{
|
||||
List<ulong> blacklist = Profiler.GetBlacklistedFunctions();
|
||||
bool containsBlacklistedFunctions = false;
|
||||
_infosStream.Seek(0L, SeekOrigin.Begin);
|
||||
bool foundBadFunction = false;
|
||||
|
||||
for (int index = 0; index < GetEntriesCount(); index++)
|
||||
{
|
||||
InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream);
|
||||
foreach (ulong address in blacklist)
|
||||
{
|
||||
if (infoEntry.Address == address)
|
||||
{
|
||||
containsBlacklistedFunctions = true;
|
||||
Logger.Warning?.Print(LogClass.Ptc, "PPTC cache invalidated: Found blacklisted functions in PPTC cache");
|
||||
foundBadFunction = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundBadFunction)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return containsBlacklistedFunctions;
|
||||
}
|
||||
|
||||
private void PreLoad()
|
||||
{
|
||||
string fileNameActual = $"{CachePathActual}.cache";
|
||||
@@ -564,7 +532,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
public void LoadTranslations(Translator translator)
|
||||
{
|
||||
if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
|
||||
if (AreCarriersEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -867,18 +835,10 @@ namespace ARMeilleure.Translation.PTC
|
||||
while (profiledFuncsToTranslate.TryDequeue(out (ulong address, PtcProfiler.FuncProfile funcProfile) item))
|
||||
{
|
||||
ulong address = item.address;
|
||||
ExecutionMode executionMode = item.funcProfile.Mode;
|
||||
bool highCq = item.funcProfile.HighCq;
|
||||
|
||||
Debug.Assert(Profiler.IsAddressInStaticCodeRange(address));
|
||||
|
||||
TranslatedFunction func = translator.Translate(address, executionMode, highCq);
|
||||
|
||||
if (func == null)
|
||||
{
|
||||
Profiler.UpdateEntry(address, executionMode, true, true);
|
||||
continue;
|
||||
}
|
||||
TranslatedFunction func = translator.Translate(address, item.funcProfile.Mode, item.funcProfile.HighCq);
|
||||
|
||||
bool isAddressUnique = translator.Functions.TryAdd(address, func.GuestSize, func);
|
||||
|
||||
@@ -924,11 +884,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
sw.Stop();
|
||||
|
||||
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
|
||||
|
||||
Logger.Info?.Print(LogClass.Ptc,
|
||||
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
|
||||
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
|
||||
$"| Thread count: {degreeOfParallelism}");
|
||||
|
||||
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
|
||||
|
||||
Thread preSaveThread = new(PreSave)
|
||||
{
|
||||
|
||||
@@ -24,12 +24,11 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
|
||||
|
||||
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 5518; //! Not to be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private static readonly uint[] _migrateInternalVersions =
|
||||
private static readonly uint[] _migrateInternalVersions =
|
||||
[
|
||||
1866,
|
||||
5518,
|
||||
1866
|
||||
];
|
||||
|
||||
private const int SaveInterval = 30; // Seconds.
|
||||
@@ -78,30 +77,20 @@ namespace ARMeilleure.Translation.PTC
|
||||
private void TimerElapsed(object _, ElapsedEventArgs __)
|
||||
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
|
||||
|
||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
|
||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||
{
|
||||
if (IsAddressInStaticCodeRange(address))
|
||||
{
|
||||
Debug.Assert(!highCq);
|
||||
|
||||
if (blacklist)
|
||||
lock (_lock)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: false, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false, false));
|
||||
}
|
||||
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq, bool? blacklist = null)
|
||||
public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||
{
|
||||
if (IsAddressInStaticCodeRange(address))
|
||||
{
|
||||
@@ -111,7 +100,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
Debug.Assert(ProfiledFuncs.ContainsKey(address));
|
||||
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: true, blacklist ?? ProfiledFuncs[address].Blacklist);
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +116,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
foreach (KeyValuePair<ulong, FuncProfile> profiledFunc in ProfiledFuncs)
|
||||
{
|
||||
if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist)
|
||||
if (!funcs.ContainsKey(profiledFunc.Key))
|
||||
{
|
||||
profiledFuncsToTranslate.Enqueue((profiledFunc.Key, profiledFunc.Value));
|
||||
}
|
||||
@@ -142,24 +131,6 @@ namespace ARMeilleure.Translation.PTC
|
||||
ProfiledFuncs.TrimExcess();
|
||||
}
|
||||
|
||||
public List<ulong> GetBlacklistedFunctions()
|
||||
{
|
||||
List<ulong> funcs = new List<ulong>();
|
||||
|
||||
foreach (var profiledFunc in ProfiledFuncs)
|
||||
{
|
||||
if (profiledFunc.Value.Blacklist)
|
||||
{
|
||||
if (!funcs.Contains(profiledFunc.Key))
|
||||
{
|
||||
funcs.Add(profiledFunc.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return funcs;
|
||||
}
|
||||
|
||||
public void PreLoad()
|
||||
{
|
||||
_lastHash = default;
|
||||
@@ -250,18 +221,13 @@ namespace ARMeilleure.Translation.PTC
|
||||
return false;
|
||||
}
|
||||
|
||||
Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null;
|
||||
|
||||
switch (outerHeader.InfoFileVersion)
|
||||
{
|
||||
case InternalVersion:
|
||||
ProfiledFuncs = Deserialize(stream);
|
||||
break;
|
||||
case 1866:
|
||||
migrateEntryFunc = (address, profile) => (address + 0x500000UL, profile);
|
||||
goto case 5518;
|
||||
case 5518:
|
||||
ProfiledFuncs = DeserializeAddBlacklist(stream, migrateEntryFunc);
|
||||
ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile));
|
||||
break;
|
||||
default:
|
||||
Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache.");
|
||||
@@ -291,16 +257,6 @@ namespace ARMeilleure.Translation.PTC
|
||||
return DeserializeDictionary<ulong, FuncProfile>(stream, DeserializeStructure<FuncProfile>);
|
||||
}
|
||||
|
||||
private static Dictionary<ulong, FuncProfile> DeserializeAddBlacklist(Stream stream, Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null)
|
||||
{
|
||||
if (migrateEntryFunc != null)
|
||||
{
|
||||
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
|
||||
}
|
||||
|
||||
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
|
||||
{
|
||||
return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position);
|
||||
@@ -432,35 +388,13 @@ namespace ARMeilleure.Translation.PTC
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 6*/)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
|
||||
public struct FuncProfile
|
||||
{
|
||||
public ExecutionMode Mode;
|
||||
public bool HighCq;
|
||||
public bool Blacklist;
|
||||
|
||||
public FuncProfile(ExecutionMode mode, bool highCq, bool blacklist)
|
||||
{
|
||||
Mode = mode;
|
||||
HighCq = highCq;
|
||||
Blacklist = blacklist;
|
||||
}
|
||||
|
||||
public FuncProfile(FuncProfilePreBlacklist fp)
|
||||
{
|
||||
Mode = fp.Mode;
|
||||
HighCq = fp.HighCq;
|
||||
Blacklist = false;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
|
||||
public struct FuncProfilePreBlacklist
|
||||
{
|
||||
public ExecutionMode Mode;
|
||||
public bool HighCq;
|
||||
|
||||
public FuncProfilePreBlacklist(ExecutionMode mode, bool highCq)
|
||||
public FuncProfile(ExecutionMode mode, bool highCq)
|
||||
{
|
||||
Mode = mode;
|
||||
HighCq = highCq;
|
||||
|
||||
@@ -249,11 +249,6 @@ namespace ARMeilleure.Translation
|
||||
|
||||
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter);
|
||||
|
||||
if (cfg == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ulong funcSize = funcRange.End - funcRange.Start;
|
||||
|
||||
Logger.EndPass(PassName.Translation, cfg);
|
||||
@@ -412,11 +407,6 @@ namespace ARMeilleure.Translation
|
||||
if (opCode.Instruction.Emitter != null)
|
||||
{
|
||||
opCode.Instruction.Emitter(context);
|
||||
if (opCode.Instruction.Name == InstName.Und && blkIndex == 0)
|
||||
{
|
||||
range = new Range(rangeStart, rangeEnd);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.Metal
|
||||
return model;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
|
||||
foreach (MemoryDefinition memory in memories)
|
||||
{
|
||||
string arraySize = string.Empty;
|
||||
string arraySize = "";
|
||||
if ((memory.Type & AggregateType.Array) != 0)
|
||||
{
|
||||
arraySize = $"[{memory.ArrayLength}]";
|
||||
@@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
BufferDefinition buffer = buffers[i];
|
||||
|
||||
bool needsPadding = buffer.Layout == BufferLayout.Std140;
|
||||
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : string.Empty;
|
||||
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : "";
|
||||
|
||||
bufferDec[i] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name}{fsiSuffix};";
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
type &= ~AggregateType.Array;
|
||||
|
||||
string typeName = GetVarTypeName(type);
|
||||
string arraySuffix = string.Empty;
|
||||
string arraySuffix = "";
|
||||
|
||||
if (field.Type.HasFlag(AggregateType.Array))
|
||||
{
|
||||
@@ -353,7 +353,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
imageTypeName = $"array<{imageTypeName}, {image.ArrayLength}>";
|
||||
}
|
||||
|
||||
string fsiSuffix = fsi ? " [[raster_order_group(0)]]" : string.Empty;
|
||||
string fsiSuffix = fsi ? " [[raster_order_group(0)]]" : "";
|
||||
|
||||
imageDec[i] = $"{imageTypeName} {image.Name}{fsiSuffix};";
|
||||
}
|
||||
@@ -454,7 +454,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
IoVariable.VertexIndex => "[[vertex_id]]",
|
||||
// IoVariable.PointCoord => "[[point_coord]]",
|
||||
IoVariable.UserDefined => context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{ioDefinition.Location})]]" : $"[[attribute({ioDefinition.Location})]]",
|
||||
_ => string.Empty
|
||||
_ => ""
|
||||
};
|
||||
|
||||
context.AppendLine($"{type} {name} {iq}{suffix};");
|
||||
@@ -545,7 +545,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
IoVariable.FragmentOutputColor => $"[[color({ioDefinition.Location})]]",
|
||||
IoVariable.FragmentOutputDepth => "[[depth(any)]]",
|
||||
IoVariable.ClipDistance => $"[[clip_distance]][{Defaults.TotalClipDistances}]",
|
||||
_ => string.Empty
|
||||
_ => ""
|
||||
};
|
||||
|
||||
context.AppendLine($"{type} {name} {suffix};");
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
inputsCount--;
|
||||
}
|
||||
|
||||
string fieldName = string.Empty;
|
||||
string fieldName = "";
|
||||
switch (storageKind)
|
||||
{
|
||||
case StorageKind.ConstantBuffer:
|
||||
@@ -140,7 +140,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
}
|
||||
}
|
||||
varName += fieldName;
|
||||
varName += fieldHasPadding ? ".x" : string.Empty;
|
||||
varName += fieldHasPadding ? ".x" : "";
|
||||
|
||||
if (isStore)
|
||||
{
|
||||
@@ -434,7 +434,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
|
||||
string prefix = intCoords ? "uint" : "float";
|
||||
|
||||
return prefix + (count > 1 ? count : string.Empty) + "(" + coords + ")";
|
||||
return prefix + (count > 1 ? count : "") + "(" + coords + ")";
|
||||
}
|
||||
|
||||
Append(AssemblePVector(pCount));
|
||||
@@ -504,7 +504,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
}
|
||||
|
||||
texCallBuilder.Append(')');
|
||||
texCallBuilder.Append(colorIsVector ? GetMaskMultiDest(texOp.Index) : string.Empty);
|
||||
texCallBuilder.Append(colorIsVector ? GetMaskMultiDest(texOp.Index) : "");
|
||||
|
||||
return texCallBuilder.ToString();
|
||||
}
|
||||
@@ -558,7 +558,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
||||
{
|
||||
if (mask == 0x0)
|
||||
{
|
||||
return string.Empty;
|
||||
return "";
|
||||
}
|
||||
|
||||
string swizzle = ".";
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||
if (parameters.Definitions.Stage is not (ShaderStage.Vertex or ShaderStage.Fragment or ShaderStage.Compute))
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, $"Attempted to generate unsupported shader type {parameters.Definitions.Stage}!");
|
||||
return string.Empty;
|
||||
return "";
|
||||
}
|
||||
|
||||
CodeGenContext context = new(info, parameters);
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace Ryujinx.Graphics.Shader
|
||||
_ => "float"
|
||||
};
|
||||
|
||||
return $"{typeName}<{format}{(image ? ", access::read_write" : string.Empty)}>";
|
||||
return $"{typeName}<{format}{(image ? ", access::read_write" : "")}>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,6 @@ namespace Ryujinx.HLE
|
||||
/// <summary>
|
||||
/// The desired hacky workarounds.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
public EnabledDirtyHack[] Hacks { internal get; set; }
|
||||
|
||||
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace Ryujinx.HLE.HOS
|
||||
private readonly string _titleIdText;
|
||||
private readonly string _displayVersion;
|
||||
private readonly bool _diskCacheEnabled;
|
||||
private readonly string _diskCacheSelector;
|
||||
private readonly ulong _codeAddress;
|
||||
private readonly ulong _codeSize;
|
||||
|
||||
@@ -32,7 +31,6 @@ namespace Ryujinx.HLE.HOS
|
||||
string titleIdText,
|
||||
string displayVersion,
|
||||
bool diskCacheEnabled,
|
||||
string diskCacheSelector,
|
||||
ulong codeAddress,
|
||||
ulong codeSize)
|
||||
{
|
||||
@@ -41,7 +39,6 @@ namespace Ryujinx.HLE.HOS
|
||||
_titleIdText = titleIdText;
|
||||
_displayVersion = displayVersion;
|
||||
_diskCacheEnabled = diskCacheEnabled;
|
||||
_diskCacheSelector = diskCacheSelector;
|
||||
_codeAddress = codeAddress;
|
||||
_codeSize = codeSize;
|
||||
}
|
||||
@@ -117,7 +114,7 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
}
|
||||
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, _diskCacheSelector ?? "default");
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, "default"); //Ready for exefs profiles
|
||||
|
||||
return processContext;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ using LibHac.Loader;
|
||||
using LibHac.Tools.Fs;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.RomFs;
|
||||
using LibHac.Util;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Utilities;
|
||||
@@ -20,7 +19,6 @@ using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
@@ -583,7 +581,6 @@ namespace Ryujinx.HLE.HOS
|
||||
public BitVector32 Stubs;
|
||||
public BitVector32 Replaces;
|
||||
public MetaLoader Npdm;
|
||||
public string Hash;
|
||||
|
||||
public bool Modified => (Stubs.Data | Replaces.Data) != 0;
|
||||
}
|
||||
@@ -594,11 +591,8 @@ namespace Ryujinx.HLE.HOS
|
||||
{
|
||||
Stubs = new BitVector32(),
|
||||
Replaces = new BitVector32(),
|
||||
Hash = null,
|
||||
};
|
||||
|
||||
string tempHash = string.Empty;
|
||||
|
||||
if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.ExefsDirs.Count == 0)
|
||||
{
|
||||
return modLoadResult;
|
||||
@@ -634,16 +628,8 @@ namespace Ryujinx.HLE.HOS
|
||||
|
||||
modLoadResult.Replaces[1 << i] = true;
|
||||
|
||||
using (FileStream stream = nsoFile.OpenRead())
|
||||
{
|
||||
nsos[i] = new NsoExecutable(stream.AsStorage(), nsoName);
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced");
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
tempHash += BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
nsos[i] = new NsoExecutable(nsoFile.OpenRead().AsStorage(), nsoName);
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced");
|
||||
}
|
||||
|
||||
modLoadResult.Stubs[1 << i] |= File.Exists(Path.Combine(mod.Path.FullName, nsoName + StubExtension));
|
||||
@@ -675,14 +661,6 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(tempHash))
|
||||
{
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
modLoadResult.Hash += BitConverter.ToString(md5.ComputeHash(tempHash.ToBytes())).Replace("-", string.Empty).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
return modLoadResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu
|
||||
|
||||
private void UpdatePassphraseIfNeeded()
|
||||
{
|
||||
string passphrase = _config.MultiplayerLdnPassphrase ?? string.Empty;
|
||||
string passphrase = _config.MultiplayerLdnPassphrase ?? "";
|
||||
if (passphrase != _passphrase)
|
||||
{
|
||||
_passphrase = passphrase;
|
||||
|
||||
@@ -84,6 +84,13 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
||||
// Apply Nsos patches.
|
||||
device.Configuration.VirtualFileSystem.ModLoader.ApplyNsoPatches(programId, nsoExecutables);
|
||||
|
||||
// Don't use PTC if ExeFS files have been replaced.
|
||||
bool enablePtc = device.System.EnablePtc && !modLoadResult.Modified;
|
||||
if (!enablePtc)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Ptc, "Detected unsupported ExeFs modifications. PTC disabled.");
|
||||
}
|
||||
|
||||
string programName = string.Empty;
|
||||
|
||||
if (!isHomebrew && programId > 0x010000000000FFFF)
|
||||
@@ -110,8 +117,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
||||
device.System.KernelContext,
|
||||
metaLoader,
|
||||
nacpData,
|
||||
device.System.EnablePtc,
|
||||
modLoadResult.Hash,
|
||||
enablePtc,
|
||||
true,
|
||||
programName,
|
||||
metaLoader.GetProgramId(),
|
||||
|
||||
@@ -235,7 +235,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
dummyExeFs.GetNpdm(),
|
||||
nacpData,
|
||||
diskCacheEnabled: false,
|
||||
diskCacheSelector: null,
|
||||
allowCodeMemoryForJit: true,
|
||||
programName,
|
||||
programId,
|
||||
|
||||
@@ -186,7 +186,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
false,
|
||||
null,
|
||||
codeAddress,
|
||||
codeSize);
|
||||
|
||||
@@ -227,7 +226,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
MetaLoader metaLoader,
|
||||
BlitStruct<ApplicationControlProperty> applicationControlProperties,
|
||||
bool diskCacheEnabled,
|
||||
string diskCacheSelector,
|
||||
bool allowCodeMemoryForJit,
|
||||
string name,
|
||||
ulong programId,
|
||||
@@ -381,7 +379,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
$"{programId:x16}",
|
||||
displayVersion,
|
||||
diskCacheEnabled,
|
||||
diskCacheSelector,
|
||||
codeStart,
|
||||
codeSize);
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
bool isFirmwareApplication = ProgramId <= 0x0100000000007FFF;
|
||||
|
||||
string name = !isFirmware
|
||||
? (isFirmwareApplication ? "Firmware Application " : string.Empty) + (!string.IsNullOrWhiteSpace(Name) ? Name : "<Unknown Name>")
|
||||
? (isFirmwareApplication ? "Firmware Application " : "") + (!string.IsNullOrWhiteSpace(Name) ? Name : "<Unknown Name>")
|
||||
: "Firmware";
|
||||
|
||||
// TODO: LibHac npdm currently doesn't support version field.
|
||||
|
||||
@@ -589,7 +589,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Starta spel med dolt användargränssnitt",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -2022,56 +2022,6 @@
|
||||
"zh_TW": "下一次啟動遊戲時,觸發 PPTC 進行重建"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuCacheManagementNukePptc",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Purge PPTC cache",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuCacheManagementNukePptcToolTip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Deletes all PPTC cache files for the Application",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "GameListContextMenuCacheManagementPurgeShaderCache",
|
||||
"Translations": {
|
||||
@@ -2389,7 +2339,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Extrahera RomFS från en vald DLC-fil",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -4046,7 +3996,7 @@
|
||||
"zh_CN": "繁体中文(推荐)",
|
||||
"zh_TW": "正體中文 (建議)"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemSystemLanguageSwedish",
|
||||
"Translations": {
|
||||
@@ -4071,7 +4021,7 @@
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemSystemLanguageNorwegian",
|
||||
"Translations": {
|
||||
@@ -5814,7 +5764,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Ok",
|
||||
"th_TH": "ตกลง",
|
||||
"tr_TR": "Tamam",
|
||||
"uk_UA": "",
|
||||
@@ -7714,7 +7664,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Inaktivera",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -7739,7 +7689,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Regnbåge",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -7764,11 +7714,11 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Färg",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "颜色",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
@@ -12997,31 +12947,6 @@
|
||||
"zh_TW": "在 {0} 清除 PPTC 快取時出錯: {1}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "DialogPPTCNukeMessage",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "DialogShaderDeletionMessage",
|
||||
"Translations": {
|
||||
@@ -14564,7 +14489,7 @@
|
||||
"pl_PL": "Seria Amiibo",
|
||||
"pt_BR": "Franquia Amiibo",
|
||||
"ru_RU": "Серия Amiibo",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Amiibo-serie",
|
||||
"th_TH": "",
|
||||
"tr_TR": "Amiibo Serisi",
|
||||
"uk_UA": "Серія Amiibo",
|
||||
@@ -17939,7 +17864,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ryujinx - Informação",
|
||||
"ru_RU": "Ryujinx - Информация",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Ryujinx - Information",
|
||||
"th_TH": "Ryujinx – ข้อมูล",
|
||||
"tr_TR": "Ryujinx - Bilgi",
|
||||
"uk_UA": "Ryujin x - Інформація",
|
||||
@@ -19014,11 +18939,11 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "LED-inställningar",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "LED 设置",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
@@ -21214,7 +21139,7 @@
|
||||
"pl_PL": "Głoś",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "Громкость",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Volym",
|
||||
"th_TH": "ระดับเสียง",
|
||||
"tr_TR": "Ses",
|
||||
"uk_UA": "Гуч.",
|
||||
@@ -23164,7 +23089,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Välj en DLC att extrahera",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -23173,4 +23098,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Configuration.Hid;
|
||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
using Ryujinx.Common.GraphicsDriver;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Logging.Targets;
|
||||
@@ -27,7 +26,6 @@ using Ryujinx.SDL2.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Headless
|
||||
@@ -288,9 +286,6 @@ namespace Ryujinx.Headless
|
||||
GraphicsConfig.EnableMacroHLE = !option.DisableMacroHLE;
|
||||
|
||||
DriverUtilities.InitDriverConfig(option.BackendThreading == BackendThreading.Off);
|
||||
|
||||
if (_inputConfiguration.OfType<StandardControllerInputConfig>().Any(ic => ic.Led.UseRainbow))
|
||||
Rainbow.Enable();
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
mc:Ignorable="d"
|
||||
Focusable="True"
|
||||
x:DataType="viewModels:UserSelectorDialogViewModel">
|
||||
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Design.DataContext>
|
||||
<viewModels:UserSelectorDialogViewModel />
|
||||
</Design.DataContext>
|
||||
@@ -75,7 +80,7 @@
|
||||
Height="96"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
MaxWidth="90"
|
||||
@@ -105,5 +110,12 @@
|
||||
</ListBox>
|
||||
</Border>
|
||||
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Margin="0 24 0 0"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Horizontal"
|
||||
Spacing="10">
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -81,11 +81,6 @@
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgePptc}"
|
||||
Icon="{ext:Icon mdi-refresh}"
|
||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
|
||||
<MenuItem
|
||||
Click="NukePtcCache_Click"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementNukePptc}"
|
||||
Icon="{ext:Icon mdi-delete-alert}"
|
||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementNukePptcToolTip}" />
|
||||
<MenuItem
|
||||
Click="PurgeShaderCache_Click"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
|
||||
|
||||
@@ -175,52 +175,6 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
}
|
||||
}
|
||||
|
||||
public async void NukePtcCache_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
return;
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogWarning],
|
||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCNukeMessage, viewModel.SelectedApplication.Name)
|
||||
);
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
|
||||
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
|
||||
|
||||
List<FileInfo> cacheFiles = new();
|
||||
|
||||
if (mainDir.Exists)
|
||||
{
|
||||
cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
|
||||
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
|
||||
}
|
||||
|
||||
if (backupDir.Exists)
|
||||
{
|
||||
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
|
||||
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
|
||||
}
|
||||
|
||||
if (cacheFiles.Count > 0)
|
||||
{
|
||||
foreach (FileInfo file in cacheFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
file.Delete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async void PurgeShaderCache_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
mc:Ignorable="d"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
@@ -65,7 +68,7 @@
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
||||
<Panel
|
||||
Grid.Row="1"
|
||||
Height="50"
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
mc:Ignorable="d"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
@@ -59,7 +62,7 @@
|
||||
Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
|
||||
Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
|
||||
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
|
||||
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
Margin="0,0,5,0"
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
internal class BitmapArrayValueConverter : IValueConverter
|
||||
{
|
||||
public static readonly BitmapArrayValueConverter Instance = new();
|
||||
public static BitmapArrayValueConverter Instance = new();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
internal class DownloadableContentLabelConverter : IMultiValueConverter
|
||||
{
|
||||
public static readonly DownloadableContentLabelConverter Instance = new();
|
||||
public static DownloadableContentLabelConverter Instance = new();
|
||||
|
||||
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
internal class KeyValueConverter : IValueConverter
|
||||
{
|
||||
public static readonly KeyValueConverter Instance = new();
|
||||
public static KeyValueConverter Instance = new();
|
||||
|
||||
private static readonly Dictionary<Key, LocaleKeys> _keysMap = new()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
@@ -18,10 +19,15 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
internal class TitleUpdateLabelConverter : IMultiValueConverter
|
||||
{
|
||||
public static readonly TitleUpdateLabelConverter Instance = new();
|
||||
public static TitleUpdateLabelConverter Instance = new();
|
||||
|
||||
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
internal class XCITrimmerFileSpaceSavingsConverter : IValueConverter
|
||||
{
|
||||
private const long _bytesPerMB = 1024 * 1024;
|
||||
public static readonly XCITrimmerFileSpaceSavingsConverter Instance = new();
|
||||
public static XCITrimmerFileSpaceSavingsConverter Instance = new();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Ryujinx.Ava.UI.Models
|
||||
{
|
||||
private bool _isEnabled = false;
|
||||
public ObservableCollection<CheatNode> SubNodes { get; } = [];
|
||||
public string CleanName => Name.Length > 0 ? Name[1..^7] : Name;
|
||||
public string CleanName => Name[1..^7];
|
||||
public string BuildIdKey => $"{BuildId}-{Name}";
|
||||
public bool IsRootNode { get; }
|
||||
public string Name { get; }
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:ControllerInputViewModel />
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<helpers:KeyValueConverter x:Key="Key" />
|
||||
</UserControl.Resources>
|
||||
<UserControl.Styles>
|
||||
<Style Selector="ToggleButton">
|
||||
<Setter Property="Width" Value="90" />
|
||||
@@ -75,7 +78,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonZl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonZl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -91,7 +94,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonL">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonL, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -107,7 +110,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonMinus">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonMinus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -141,7 +144,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickButton">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -158,7 +161,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftJoystick" Tag="stick">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftJoystick, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftJoystick, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -251,7 +254,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadUp">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -268,7 +271,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadDown">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -285,7 +288,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadLeft">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -302,7 +305,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadRight">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -365,7 +368,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftButtonSr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -383,7 +386,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftButtonSl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -401,7 +404,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightButtonSr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -419,7 +422,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightButtonSl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -547,7 +550,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonZr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonZr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -565,7 +568,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonR">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonR, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -583,7 +586,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonPlus">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonPlus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -618,7 +621,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonA">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonA, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -635,7 +638,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonB">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonB, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -652,7 +655,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonX">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonX, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -669,7 +672,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonY">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonY, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -703,7 +706,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickButton">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -721,7 +724,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightJoystick" Tag="stick">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightJoystick, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightJoystick, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:KeyboardInputViewModel />
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<helpers:KeyValueConverter x:Key="Key" />
|
||||
</UserControl.Resources>
|
||||
<UserControl.Styles>
|
||||
<Style Selector="ToggleButton">
|
||||
<Setter Property="Width" Value="90" />
|
||||
@@ -73,7 +76,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonZl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonZl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -89,7 +92,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonL">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonL, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -105,7 +108,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonMinus">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonMinus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -140,7 +143,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickButton">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -157,7 +160,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickUp">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickUp, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -174,7 +177,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickDown">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickDown, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -191,7 +194,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickLeft">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickLeft, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -208,7 +211,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftStickRight">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftStickRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftStickRight, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -244,7 +247,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadUp">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -261,7 +264,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadDown">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -278,7 +281,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadLeft">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -295,7 +298,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="DpadRight">
|
||||
<TextBlock
|
||||
Text="{Binding Config.DpadRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -338,7 +341,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftButtonSr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -356,7 +359,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="LeftButtonSl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.LeftButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -374,7 +377,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightButtonSr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -392,7 +395,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightButtonSl">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -434,7 +437,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonZr">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonZr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -452,7 +455,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonR">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonR, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -470,7 +473,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonPlus">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonPlus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -505,7 +508,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonA">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonA, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -522,7 +525,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonB">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonB, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -539,7 +542,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonX">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonX, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -556,7 +559,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="ButtonY">
|
||||
<TextBlock
|
||||
Text="{Binding Config.ButtonY, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -591,7 +594,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickButton">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -608,7 +611,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickUp">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickUp, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -625,7 +628,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickDown">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickDown, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -642,7 +645,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickLeft">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickLeft, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
@@ -659,7 +662,7 @@
|
||||
TextAlignment="Center" />
|
||||
<ToggleButton Name="RightStickRight">
|
||||
<TextBlock
|
||||
Text="{Binding Config.RightStickRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
|
||||
Text="{Binding Config.RightStickRight, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:SettingsViewModel />
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<helpers:KeyValueConverter x:Key="Key" />
|
||||
</UserControl.Resources>
|
||||
<UserControl.Styles>
|
||||
<Style Selector="StackPanel > StackPanel">
|
||||
<Setter Property="Margin" Value="10, 0, 0, 0" />
|
||||
@@ -49,67 +52,67 @@
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
|
||||
<ToggleButton Name="ToggleVSyncMode">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" />
|
||||
<ToggleButton Name="Screenshot">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" />
|
||||
<ToggleButton Name="ShowUI">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" />
|
||||
<ToggleButton Name="Pause">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" />
|
||||
<ToggleButton Name="ToggleMute">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" />
|
||||
<ToggleButton Name="ResScaleUp">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" />
|
||||
<ToggleButton Name="ResScaleDown">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" />
|
||||
<ToggleButton Name="VolumeUp">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" />
|
||||
<ToggleButton Name="VolumeDown">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
|
||||
<ToggleButton Name="CustomVSyncIntervalIncrement">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
|
||||
<ToggleButton Name="CustomVSyncIntervalDecrement">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={StaticResource Key}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
@@ -7,26 +7,23 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||
{
|
||||
public partial class SettingsNetworkView : UserControl
|
||||
{
|
||||
private readonly Random _random;
|
||||
|
||||
public SettingsViewModel ViewModel;
|
||||
|
||||
public SettingsNetworkView()
|
||||
{
|
||||
_random = new Random();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void GenLdnPassButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
byte[] code = new byte[4];
|
||||
_random.NextBytes(code);
|
||||
new Random().NextBytes(code);
|
||||
ViewModel.LdnPassphrase = $"Ryujinx-{BitConverter.ToUInt32(code):x8}";
|
||||
}
|
||||
|
||||
private void ClearLdnPassButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.LdnPassphrase = string.Empty;
|
||||
ViewModel.LdnPassphrase = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
mc:Ignorable="d"
|
||||
x:DataType="viewModels:SettingsViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:TimeZoneConverter x:Key="TimeZone" />
|
||||
</UserControl.Resources>
|
||||
<Design.DataContext>
|
||||
<viewModels:SettingsViewModel />
|
||||
</Design.DataContext>
|
||||
@@ -159,7 +162,7 @@
|
||||
Text="{Binding Path=TimeZone, Mode=OneWay}"
|
||||
TextChanged="TimeZoneBox_OnTextChanged"
|
||||
ToolTip.Tip="{ext:Locale TimezoneTooltip}"
|
||||
ValueMemberBinding="{Binding Mode=OneWay, Converter={x:Static helpers:TimeZoneConverter.Instance}}" />
|
||||
ValueMemberBinding="{Binding Mode=OneWay, Converter={StaticResource TimeZone}}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Margin="0,0,0,10"
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
mc:Ignorable="d"
|
||||
Focusable="True"
|
||||
x:DataType="models:TempProfile">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -71,7 +74,7 @@
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
</Panel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:UserFirmwareAvatarSelectorViewModel />
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
@@ -59,7 +62,7 @@
|
||||
<Panel
|
||||
Background="{Binding BackgroundColor}"
|
||||
Margin="5">
|
||||
<Image Source="{Binding Data, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
<Image Source="{Binding Data, Converter={StaticResource ByteImage}}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:UserSaveManagerViewModel />
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -144,7 +147,7 @@
|
||||
IsVisible="{Binding InGameList}"
|
||||
Width="42"
|
||||
Height="42"
|
||||
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
||||
<TextBlock
|
||||
MaxLines="3"
|
||||
Width="320"
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
mc:Ignorable="d"
|
||||
Focusable="True"
|
||||
x:DataType="viewModels:UserProfileViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Design.DataContext>
|
||||
<viewModels:UserProfileViewModel />
|
||||
</Design.DataContext>
|
||||
@@ -71,7 +74,7 @@
|
||||
Height="96"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
MaxWidth="90"
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
|
||||
Width="600"
|
||||
Height="750"
|
||||
Width="500"
|
||||
Height="500"
|
||||
MinWidth="500"
|
||||
MinHeight="500"
|
||||
x:DataType="window:CheatWindow"
|
||||
|
||||
@@ -34,9 +34,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
|
||||
{
|
||||
MinWidth = 500;
|
||||
MinHeight = 650;
|
||||
|
||||
LoadedCheats = [];
|
||||
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
||||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
<Design.DataContext>
|
||||
<viewModels:MainWindowViewModel />
|
||||
</Design.DataContext>
|
||||
<Window.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</Window.Resources>
|
||||
<Window.KeyBindings>
|
||||
<KeyBinding Gesture="Alt+Return" Command="{Binding ToggleFullscreen}" />
|
||||
<KeyBinding Gesture="F11" Command="{Binding ToggleFullscreen}" />
|
||||
@@ -118,7 +121,7 @@
|
||||
Width="256"
|
||||
Height="256"
|
||||
IsVisible="{Binding ShowLoadProgress}"
|
||||
Source="{Binding SelectedIcon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||
Source="{Binding SelectedIcon, Converter={StaticResource ByteImage}}" />
|
||||
</Border>
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
mc:Ignorable="d"
|
||||
x:DataType="viewModels:TitleUpdateViewModel"
|
||||
Focusable="True">
|
||||
<UserControl.Resources>
|
||||
<helpers:TitleUpdateLabelConverter x:Key="TitleUpdateLabel" />
|
||||
</UserControl.Resources>
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
@@ -54,7 +57,7 @@
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{x:Static helpers:TitleUpdateLabelConverter.Instance}">
|
||||
<MultiBinding Converter="{StaticResource TitleUpdateLabel}">
|
||||
<Binding Path="DisplayVersion" />
|
||||
<Binding Path="IsBundled" />
|
||||
</MultiBinding>
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
x:DataType="viewModels:XCITrimmerViewModel"
|
||||
Focusable="True"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<helpers:XCITrimmerFileStatusConverter x:Key="StatusLabel" />
|
||||
<helpers:XCITrimmerFileStatusDetailConverter x:Key="StatusDetailLabel" />
|
||||
<helpers:XCITrimmerFileSpaceSavingsConverter x:Key="SpaceSavingsLabel" />
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="20 0 20 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -181,7 +186,7 @@
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusConverter.Instance}}">
|
||||
Text="{Binding ., Converter={StaticResource StatusLabel}}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel
|
||||
IsVisible="{Binding IsFailed}">
|
||||
@@ -189,7 +194,7 @@
|
||||
Classes="h1"
|
||||
Text="{ext:Locale XCITrimmerTitleStatusFailed}" />
|
||||
<TextBlock
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusDetailConverter.Instance}}"
|
||||
Text="{Binding ., Converter={StaticResource StatusDetailLabel}}"
|
||||
MaxLines="5"
|
||||
MaxWidth="200"
|
||||
MaxHeight="100"
|
||||
@@ -204,7 +209,7 @@
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileSpaceSavingsConverter.Instance}}">>
|
||||
Text="{Binding ., Converter={StaticResource SpaceSavingsLabel}}">>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -204,8 +204,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
Multiplayer.LanInterfaceId.Value = "0";
|
||||
Multiplayer.Mode.Value = MultiplayerMode.Disabled;
|
||||
Multiplayer.DisableP2p.Value = false;
|
||||
Multiplayer.LdnPassphrase.Value = string.Empty;
|
||||
Multiplayer.LdnServer.Value = string.Empty;
|
||||
Multiplayer.LdnPassphrase.Value = "";
|
||||
Multiplayer.LdnServer.Value = "";
|
||||
UI.GuiColumns.FavColumn.Value = true;
|
||||
UI.GuiColumns.IconColumn.Value = true;
|
||||
UI.GuiColumns.AppColumn.Value = true;
|
||||
|
||||
Reference in New Issue
Block a user