Compare commits
13 Commits
07d0da859c
...
11353be3ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11353be3ba | ||
|
|
c140e9b23c | ||
|
|
9c8055440e | ||
|
|
c03cd50fa3 | ||
|
|
069f630776 | ||
|
|
49ed30fa2a | ||
|
|
d96f89ec37 | ||
|
|
e0acefeeef | ||
|
|
b5604311cb | ||
|
|
2c53242b31 | ||
|
|
2874c40ee9 | ||
|
|
91518acf30 | ||
|
|
2af9a33979 |
@@ -1070,6 +1070,7 @@
|
||||
010017B0102A8000,"Emma: Lost in Memories",nvdec,playable,2021-01-28 16:19:10
|
||||
010068300E08E000,"Enchanted in the Moonlight - Kiryu, Chikage & Yukinojo -",gpu;nvdec,ingame,2022-11-20 16:18:45
|
||||
01007A4008486000,"Enchanting Mahjong Match",gpu,ingame,2020-04-17 22:01:31
|
||||
0100EF901E552000,"ENDER MAGNOLIA: Bloom in the Mist",deadlock,boots,2025-01-22 17:59:00
|
||||
01004F3011F92000,"Endless Fables: Dark Moor",gpu;nvdec,ingame,2021-03-07 15:31:03
|
||||
010067B017588000,"Endless Ocean™ Luminous",services-horizon;crash,ingame,2024-05-30 02:05:57
|
||||
0100B8700BD14000,"Energy Cycle Edge",services,ingame,2021-11-30 05:02:31
|
||||
|
||||
|
@@ -3,6 +3,7 @@ using ARMeilleure.CodeGen.Linking;
|
||||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Common;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
@@ -29,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 = 6998; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const uint InternalVersion = 7007; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
@@ -183,6 +184,36 @@ 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";
|
||||
@@ -531,7 +562,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
public void LoadTranslations(Translator translator)
|
||||
{
|
||||
if (AreCarriersEmpty())
|
||||
if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -834,10 +865,18 @@ namespace ARMeilleure.Translation.PTC
|
||||
while (profiledFuncsToTranslate.TryDequeue(out var item))
|
||||
{
|
||||
ulong address = item.address;
|
||||
ExecutionMode executionMode = item.funcProfile.Mode;
|
||||
bool highCq = item.funcProfile.HighCq;
|
||||
|
||||
Debug.Assert(Profiler.IsAddressInStaticCodeRange(address));
|
||||
|
||||
TranslatedFunction func = translator.Translate(address, item.funcProfile.Mode, item.funcProfile.HighCq);
|
||||
TranslatedFunction func = translator.Translate(address, executionMode, highCq);
|
||||
|
||||
if (func == null)
|
||||
{
|
||||
Profiler.UpdateEntry(address, executionMode, true, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isAddressUnique = translator.Functions.TryAdd(address, func.GuestSize, func);
|
||||
|
||||
@@ -884,7 +923,14 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
|
||||
|
||||
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
|
||||
if (_translateCount == _translateTotalCount)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | {_translateTotalCount - _translateCount} function{(_translateTotalCount - _translateCount != 1 ? "s" : "")} blacklisted | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
|
||||
}
|
||||
|
||||
Thread preSaveThread = new(PreSave)
|
||||
{
|
||||
|
||||
@@ -24,10 +24,11 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
|
||||
|
||||
private const uint InternalVersion = 5518; //! Not to be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private static readonly uint[] _migrateInternalVersions = {
|
||||
1866,
|
||||
5518,
|
||||
};
|
||||
|
||||
private const int SaveInterval = 30; // Seconds.
|
||||
@@ -76,20 +77,30 @@ 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)
|
||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
|
||||
{
|
||||
if (IsAddressInStaticCodeRange(address))
|
||||
{
|
||||
Debug.Assert(!highCq);
|
||||
|
||||
lock (_lock)
|
||||
if (blacklist)
|
||||
{
|
||||
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false));
|
||||
lock (_lock)
|
||||
{
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: false, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||
public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq, bool? blacklist = null)
|
||||
{
|
||||
if (IsAddressInStaticCodeRange(address))
|
||||
{
|
||||
@@ -99,7 +110,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
Debug.Assert(ProfiledFuncs.ContainsKey(address));
|
||||
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: true);
|
||||
ProfiledFuncs[address] = new FuncProfile(mode, highCq: true, blacklist ?? ProfiledFuncs[address].Blacklist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +126,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
foreach (var profiledFunc in ProfiledFuncs)
|
||||
{
|
||||
if (!funcs.ContainsKey(profiledFunc.Key))
|
||||
if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist)
|
||||
{
|
||||
profiledFuncsToTranslate.Enqueue((profiledFunc.Key, profiledFunc.Value));
|
||||
}
|
||||
@@ -130,6 +141,24 @@ 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;
|
||||
@@ -220,13 +249,18 @@ namespace ARMeilleure.Translation.PTC
|
||||
return false;
|
||||
}
|
||||
|
||||
Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null;
|
||||
|
||||
switch (outerHeader.InfoFileVersion)
|
||||
{
|
||||
case InternalVersion:
|
||||
ProfiledFuncs = Deserialize(stream);
|
||||
break;
|
||||
case 1866:
|
||||
ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile));
|
||||
migrateEntryFunc = (address, profile) => (address + 0x500000UL, profile);
|
||||
goto case 5518;
|
||||
case 5518:
|
||||
ProfiledFuncs = DeserializeAddBlacklist(stream, migrateEntryFunc);
|
||||
break;
|
||||
default:
|
||||
Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache.");
|
||||
@@ -256,6 +290,16 @@ 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);
|
||||
@@ -387,13 +431,35 @@ namespace ARMeilleure.Translation.PTC
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 6*/)]
|
||||
public struct FuncProfile
|
||||
{
|
||||
public ExecutionMode Mode;
|
||||
public bool HighCq;
|
||||
public bool Blacklist;
|
||||
|
||||
public FuncProfile(ExecutionMode mode, bool highCq)
|
||||
public FuncProfile(ExecutionMode mode, bool highCq, bool blacklist)
|
||||
{
|
||||
Mode = mode;
|
||||
HighCq = highCq;
|
||||
Blacklist = blacklist;
|
||||
}
|
||||
|
||||
public FuncProfile(FuncProfilePreBlacklist fp)
|
||||
{
|
||||
Mode = fp.Mode;
|
||||
HighCq = fp.HighCq;
|
||||
Blacklist = false;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
|
||||
public struct FuncProfilePreBlacklist
|
||||
{
|
||||
public ExecutionMode Mode;
|
||||
public bool HighCq;
|
||||
|
||||
public FuncProfilePreBlacklist(ExecutionMode mode, bool highCq)
|
||||
{
|
||||
Mode = mode;
|
||||
HighCq = highCq;
|
||||
|
||||
@@ -249,6 +249,11 @@ 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);
|
||||
@@ -407,6 +412,11 @@ namespace ARMeilleure.Translation
|
||||
if (opCode.Instruction.Emitter != null)
|
||||
{
|
||||
opCode.Instruction.Emitter(context);
|
||||
if (opCode.Instruction.Name == InstName.Und && blkIndex == 0)
|
||||
{
|
||||
range = new Range(rangeStart, rangeEnd);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -78,5 +78,10 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
/// Controller Rumble Settings
|
||||
/// </summary>
|
||||
public RumbleConfigController Rumble { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller LED Settings
|
||||
/// </summary>
|
||||
public LedConfigController Led { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class LedConfigController
|
||||
{
|
||||
/// <summary>
|
||||
/// Packed RGB int of the color
|
||||
/// </summary>
|
||||
public uint LedColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable LED color changing by the emulator
|
||||
/// </summary>
|
||||
public bool EnableLed { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -710,9 +710,8 @@ namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
|
||||
}
|
||||
else
|
||||
else if (updateNcas.TryAdd(nca.Header.TitleId, new List<(NcaContentType, string)>()))
|
||||
{
|
||||
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
|
||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
|
||||
}
|
||||
}
|
||||
@@ -898,9 +897,8 @@ namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
updateNcasItem.Add((nca.Header.ContentType, entry.FullPath));
|
||||
}
|
||||
else
|
||||
else if (updateNcas.TryAdd(nca.Header.TitleId, new List<(NcaContentType, string)>()))
|
||||
{
|
||||
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
|
||||
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullPath));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Ryujinx.HLE.HOS
|
||||
private readonly string _titleIdText;
|
||||
private readonly string _displayVersion;
|
||||
private readonly bool _diskCacheEnabled;
|
||||
private readonly string _diskCacheSelector;
|
||||
private readonly ulong _codeAddress;
|
||||
private readonly ulong _codeSize;
|
||||
|
||||
@@ -31,6 +32,7 @@ namespace Ryujinx.HLE.HOS
|
||||
string titleIdText,
|
||||
string displayVersion,
|
||||
bool diskCacheEnabled,
|
||||
string diskCacheSelector,
|
||||
ulong codeAddress,
|
||||
ulong codeSize)
|
||||
{
|
||||
@@ -39,6 +41,7 @@ namespace Ryujinx.HLE.HOS
|
||||
_titleIdText = titleIdText;
|
||||
_displayVersion = displayVersion;
|
||||
_diskCacheEnabled = diskCacheEnabled;
|
||||
_diskCacheSelector = diskCacheSelector;
|
||||
_codeAddress = codeAddress;
|
||||
_codeSize = codeSize;
|
||||
}
|
||||
@@ -114,7 +117,7 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
}
|
||||
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, "default"); //Ready for exefs profiles
|
||||
DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, _diskCacheSelector ?? "default");
|
||||
|
||||
return processContext;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using LibHac.FsSystem;
|
||||
using LibHac.Loader;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.RomFs;
|
||||
using LibHac.Util;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Utilities;
|
||||
@@ -18,6 +19,7 @@ using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
@@ -580,6 +582,7 @@ namespace Ryujinx.HLE.HOS
|
||||
public BitVector32 Stubs;
|
||||
public BitVector32 Replaces;
|
||||
public MetaLoader Npdm;
|
||||
public string Hash;
|
||||
|
||||
public bool Modified => (Stubs.Data | Replaces.Data) != 0;
|
||||
}
|
||||
@@ -590,8 +593,11 @@ namespace Ryujinx.HLE.HOS
|
||||
{
|
||||
Stubs = new BitVector32(),
|
||||
Replaces = new BitVector32(),
|
||||
Hash = null,
|
||||
};
|
||||
|
||||
string tempHash = string.Empty;
|
||||
|
||||
if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.ExefsDirs.Count == 0)
|
||||
{
|
||||
return modLoadResult;
|
||||
@@ -627,8 +633,16 @@ namespace Ryujinx.HLE.HOS
|
||||
|
||||
modLoadResult.Replaces[1 << i] = true;
|
||||
|
||||
nsos[i] = new NsoExecutable(nsoFile.OpenRead().AsStorage(), nsoName);
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced");
|
||||
using (FileStream stream = nsoFile.OpenRead())
|
||||
{
|
||||
nsos[i] = new NsoExecutable(stream.AsStorage(), nsoName);
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"NSO '{nsoName}' replaced");
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
tempHash += BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modLoadResult.Stubs[1 << i] |= File.Exists(Path.Combine(mod.Path.FullName, nsoName + StubExtension));
|
||||
@@ -660,6 +674,14 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(tempHash))
|
||||
{
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
modLoadResult.Hash += BitConverter.ToString(md5.ComputeHash(tempHash.ToBytes())).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
return modLoadResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,13 +84,6 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
||||
// Apply Nsos patches.
|
||||
device.Configuration.VirtualFileSystem.ModLoader.ApplyNsoPatches(programId, nsoExecutables);
|
||||
|
||||
// Don't use PTC if ExeFS files have been replaced.
|
||||
bool enablePtc = device.System.EnablePtc && !modLoadResult.Modified;
|
||||
if (!enablePtc)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Ptc, "Detected unsupported ExeFs modifications. PTC disabled.");
|
||||
}
|
||||
|
||||
string programName = string.Empty;
|
||||
|
||||
if (!isHomebrew && programId > 0x010000000000FFFF)
|
||||
@@ -117,7 +110,8 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
||||
device.System.KernelContext,
|
||||
metaLoader,
|
||||
nacpData,
|
||||
enablePtc,
|
||||
device.System.EnablePtc,
|
||||
modLoadResult.Hash,
|
||||
true,
|
||||
programName,
|
||||
metaLoader.GetProgramId(),
|
||||
|
||||
@@ -235,6 +235,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
dummyExeFs.GetNpdm(),
|
||||
nacpData,
|
||||
diskCacheEnabled: false,
|
||||
diskCacheSelector: null,
|
||||
allowCodeMemoryForJit: true,
|
||||
programName,
|
||||
programId,
|
||||
|
||||
@@ -186,6 +186,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
false,
|
||||
null,
|
||||
codeAddress,
|
||||
codeSize);
|
||||
|
||||
@@ -226,6 +227,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
MetaLoader metaLoader,
|
||||
BlitStruct<ApplicationControlProperty> applicationControlProperties,
|
||||
bool diskCacheEnabled,
|
||||
string diskCacheSelector,
|
||||
bool allowCodeMemoryForJit,
|
||||
string name,
|
||||
ulong programId,
|
||||
@@ -379,6 +381,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
$"{programId:x16}",
|
||||
displayVersion,
|
||||
diskCacheEnabled,
|
||||
diskCacheSelector,
|
||||
codeStart,
|
||||
codeSize);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ryujinx.Common.Configuration.Hid;
|
||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
using Ryujinx.Common.Logging;
|
||||
using SDL2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
@@ -118,6 +119,11 @@ namespace Ryujinx.Input.SDL2
|
||||
result |= GamepadFeaturesFlag.Rumble;
|
||||
}
|
||||
|
||||
if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE)
|
||||
{
|
||||
result |= GamepadFeaturesFlag.Led;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,5 +24,10 @@ namespace Ryujinx.Input
|
||||
/// <remarks>Also named sixaxis</remarks>
|
||||
/// </summary>
|
||||
Motion,
|
||||
|
||||
/// <summary>
|
||||
/// The LED on the back of modern PlayStation controllers (DualSense & DualShock 4).
|
||||
/// </summary>
|
||||
Led,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2022,6 +2022,56 @@
|
||||
"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": {
|
||||
@@ -7622,6 +7672,31 @@
|
||||
"zh_TW": "陀螺儀無感帶:"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "ControllerSettingsLedColor",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Custom LED",
|
||||
"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": "ControllerSettingsSave",
|
||||
"Translations": {
|
||||
@@ -12847,6 +12922,31 @@
|
||||
"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": {
|
||||
@@ -22973,4 +23073,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Ryujinx.Headless
|
||||
IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
|
||||
|
||||
if (NeedsOverride(nameof(IgnoreControllerApplet)))
|
||||
IgnoreControllerApplet = configurationState.IgnoreApplet;
|
||||
IgnoreControllerApplet = configurationState.System.IgnoreApplet;
|
||||
|
||||
return;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
@@ -42,7 +41,7 @@ namespace Ryujinx.Ava.UI.Applet
|
||||
|
||||
bool okPressed = false;
|
||||
|
||||
if (ConfigurationState.Instance.IgnoreApplet)
|
||||
if (ConfigurationState.Instance.System.IgnoreApplet)
|
||||
return false;
|
||||
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
|
||||
@@ -81,6 +81,11 @@
|
||||
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,6 +175,52 @@ 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 })
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Avalonia.Media;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Common.Configuration.Hid;
|
||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
@@ -387,6 +388,30 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enableLedChanging;
|
||||
|
||||
public bool EnableLedChanging
|
||||
{
|
||||
get => _enableLedChanging;
|
||||
set
|
||||
{
|
||||
_enableLedChanging = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private Color _ledColor;
|
||||
|
||||
public Color LedColor
|
||||
{
|
||||
get => _ledColor;
|
||||
set
|
||||
{
|
||||
_ledColor = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enableMotion;
|
||||
public bool EnableMotion
|
||||
{
|
||||
@@ -483,12 +508,23 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||
WeakRumble = controllerInput.Rumble.WeakRumble;
|
||||
StrongRumble = controllerInput.Rumble.StrongRumble;
|
||||
}
|
||||
|
||||
if (controllerInput.Led != null)
|
||||
{
|
||||
EnableLedChanging = controllerInput.Led.EnableLed;
|
||||
uint rawColor = controllerInput.Led.LedColor;
|
||||
byte alpha = (byte)(rawColor >> 24);
|
||||
byte red = (byte)(rawColor >> 16);
|
||||
byte green = (byte)(rawColor >> 8);
|
||||
byte blue = (byte)(rawColor % 256);
|
||||
LedColor = new Color(alpha, red, green, blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public InputConfig GetConfig()
|
||||
{
|
||||
var config = new StandardControllerInputConfig
|
||||
StandardControllerInputConfig config = new()
|
||||
{
|
||||
Id = Id,
|
||||
Backend = InputBackendType.GamepadSDL2,
|
||||
@@ -540,6 +576,11 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||
WeakRumble = WeakRumble,
|
||||
StrongRumble = StrongRumble,
|
||||
},
|
||||
Led = new LedConfigController
|
||||
{
|
||||
EnableLed = EnableLedChanging,
|
||||
LedColor = LedColor.ToUInt32()
|
||||
},
|
||||
Version = InputConfig.CurrentVersion,
|
||||
DeadzoneLeft = DeadzoneLeft,
|
||||
DeadzoneRight = DeadzoneRight,
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
[ObservableProperty] private SvgImage _image;
|
||||
|
||||
public readonly InputViewModel ParentModel;
|
||||
public InputViewModel ParentModel { get; }
|
||||
|
||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
||||
{
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
public bool IsRight { get; set; }
|
||||
public bool IsLeft { get; set; }
|
||||
|
||||
public bool HasLed => false; //temporary
|
||||
//SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
|
||||
|
||||
public bool IsModified { get; set; }
|
||||
public event Action NotifyChangesEvent;
|
||||
|
||||
|
||||
@@ -488,7 +488,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
||||
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
||||
ShowConfirmExit = config.ShowConfirmExit;
|
||||
IgnoreApplet = config.IgnoreApplet;
|
||||
RememberWindowState = config.RememberWindowState;
|
||||
ShowTitleBar = config.ShowTitleBar;
|
||||
HideCursor = (int)config.HideCursor.Value;
|
||||
@@ -532,6 +531,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
|
||||
DramSize = config.System.DramSize;
|
||||
IgnoreMissingServices = config.System.IgnoreMissingServices;
|
||||
IgnoreApplet = config.System.IgnoreApplet;
|
||||
|
||||
// CPU
|
||||
EnablePptc = config.System.EnablePtc;
|
||||
@@ -591,7 +591,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
||||
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
||||
config.ShowConfirmExit.Value = ShowConfirmExit;
|
||||
config.IgnoreApplet.Value = IgnoreApplet;
|
||||
config.RememberWindowState.Value = RememberWindowState;
|
||||
config.ShowTitleBar.Value = ShowTitleBar;
|
||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||
@@ -632,12 +631,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
|
||||
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
|
||||
config.Graphics.VSyncMode.Value = VSyncMode;
|
||||
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
|
||||
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
|
||||
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
|
||||
config.System.DramSize.Value = DramSize;
|
||||
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
|
||||
config.System.IgnoreApplet.Value = IgnoreApplet;
|
||||
|
||||
// CPU
|
||||
config.System.EnablePtc.Value = EnablePptc;
|
||||
@@ -646,6 +643,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.System.UseHypervisor.Value = UseHypervisor;
|
||||
|
||||
// Graphics
|
||||
config.Graphics.VSyncMode.Value = VSyncMode;
|
||||
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
|
||||
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
|
||||
config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex;
|
||||
config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex);
|
||||
config.Graphics.EnableShaderCache.Value = EnableShaderCache;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
@@ -486,6 +487,37 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="0,-1,0,0">
|
||||
<Grid IsVisible="{Binding ParentModel.HasLed}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox
|
||||
Margin="10"
|
||||
MinWidth="0"
|
||||
Grid.Column="0"
|
||||
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
|
||||
<TextBlock Text="{ext:Locale ControllerSettingsLedColor}" />
|
||||
</CheckBox>
|
||||
<ui:ColorPickerButton
|
||||
Grid.Column="1"
|
||||
Margin="10"
|
||||
IsMoreButtonVisible="False"
|
||||
UseColorPalette="False"
|
||||
UseColorTriangle="False"
|
||||
UseColorWheel="False"
|
||||
ShowAcceptDismissButtons="False"
|
||||
IsAlphaEnabled="False"
|
||||
Color="{Binding Config.LedColor, Mode=TwoWay}">
|
||||
</ui:ColorPickerButton>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<!-- Right Controls -->
|
||||
|
||||
@@ -4,14 +4,11 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.LogicalTree;
|
||||
using DiscordRPC;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Input.Assigner;
|
||||
using System;
|
||||
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 60;
|
||||
public const int CurrentVersion = 61;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the configuration file format
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
||||
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
|
||||
ShowConfirmExit.Value = cff.ShowConfirmExit;
|
||||
IgnoreApplet.Value = cff.IgnoreApplet;
|
||||
RememberWindowState.Value = cff.RememberWindowState;
|
||||
ShowTitleBar.Value = cff.ShowTitleBar;
|
||||
EnableHardwareAcceleration.Value = cff.EnableHardwareAcceleration;
|
||||
@@ -97,6 +96,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
System.MemoryManagerMode.Value = cff.MemoryManagerMode;
|
||||
System.DramSize.Value = cff.DramSize;
|
||||
System.IgnoreMissingServices.Value = cff.IgnoreMissingServices;
|
||||
System.IgnoreApplet.Value = cff.IgnoreApplet;
|
||||
System.UseHypervisor.Value = cff.UseHypervisor;
|
||||
|
||||
UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn;
|
||||
@@ -263,15 +263,12 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
}),
|
||||
(30, static cff =>
|
||||
{
|
||||
foreach (InputConfig config in cff.InputConfig)
|
||||
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
|
||||
{
|
||||
if (config is StandardControllerInputConfig controllerConfig)
|
||||
config.Rumble = new RumbleConfigController
|
||||
{
|
||||
controllerConfig.Rumble = new RumbleConfigController
|
||||
{
|
||||
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
|
||||
};
|
||||
}
|
||||
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
|
||||
};
|
||||
}
|
||||
}),
|
||||
(31, static cff => cff.BackendThreading = BackendThreading.Auto),
|
||||
@@ -416,7 +413,18 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
|
||||
cff.IgnoreApplet = false;
|
||||
}),
|
||||
(60, static cff => cff.StartNoUI = false)
|
||||
(60, static cff => cff.StartNoUI = false),
|
||||
(61, static cff =>
|
||||
{
|
||||
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
|
||||
{
|
||||
config.Led = new LedConfigController
|
||||
{
|
||||
EnableLed = false,
|
||||
LedColor = 328189
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,6 +366,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
/// Enable or disable ignoring missing services
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ignore Controller Applet
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> IgnoreApplet { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Uses Hypervisor over JIT if available
|
||||
@@ -404,6 +409,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
DramSize.LogChangesToValue(nameof(DramSize));
|
||||
IgnoreMissingServices = new ReactiveObject<bool>();
|
||||
IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices));
|
||||
IgnoreApplet = new ReactiveObject<bool>();
|
||||
IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet));
|
||||
AudioVolume = new ReactiveObject<float>();
|
||||
AudioVolume.LogChangesToValue(nameof(AudioVolume));
|
||||
UseHypervisor = new ReactiveObject<bool>();
|
||||
@@ -745,11 +752,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ignore Applet
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> IgnoreApplet { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables save window size, position and state on close.
|
||||
/// </summary>
|
||||
@@ -782,8 +784,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
EnableDiscordIntegration = new ReactiveObject<bool>();
|
||||
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
||||
ShowConfirmExit = new ReactiveObject<bool>();
|
||||
IgnoreApplet = new ReactiveObject<bool>();
|
||||
IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet));
|
||||
RememberWindowState = new ReactiveObject<bool>();
|
||||
ShowTitleBar = new ReactiveObject<bool>();
|
||||
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
EnableDiscordIntegration = EnableDiscordIntegration,
|
||||
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
||||
ShowConfirmExit = ShowConfirmExit,
|
||||
IgnoreApplet = IgnoreApplet,
|
||||
RememberWindowState = RememberWindowState,
|
||||
ShowTitleBar = ShowTitleBar,
|
||||
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
||||
@@ -78,6 +77,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
MemoryManagerMode = System.MemoryManagerMode,
|
||||
DramSize = System.DramSize,
|
||||
IgnoreMissingServices = System.IgnoreMissingServices,
|
||||
IgnoreApplet = System.IgnoreApplet,
|
||||
UseHypervisor = System.UseHypervisor,
|
||||
GuiColumns = new GuiColumns
|
||||
{
|
||||
@@ -176,7 +176,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
EnableDiscordIntegration.Value = true;
|
||||
CheckUpdatesOnStart.Value = true;
|
||||
ShowConfirmExit.Value = true;
|
||||
IgnoreApplet.Value = false;
|
||||
RememberWindowState.Value = true;
|
||||
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
||||
EnableHardwareAcceleration.Value = true;
|
||||
@@ -200,6 +199,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
|
||||
System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB;
|
||||
System.IgnoreMissingServices.Value = false;
|
||||
System.IgnoreApplet.Value = false;
|
||||
System.UseHypervisor.Value = true;
|
||||
Multiplayer.LanInterfaceId.Value = "0";
|
||||
Multiplayer.Mode.Value = MultiplayerMode.Disabled;
|
||||
|
||||
Reference in New Issue
Block a user