mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-03-13 01:51:09 +00:00
Compare commits
17 Commits
Canary-1.3
...
Canary-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4444ecae41 | ||
|
|
4f5a236c21 | ||
|
|
db31ff15c7 | ||
|
|
e70cd08c9a | ||
|
|
60b9723df4 | ||
|
|
1900924a78 | ||
|
|
5fb0b5e7ec | ||
|
|
8d0e28ed9d | ||
|
|
a4eafd01f5 | ||
|
|
f55aa87ab9 | ||
|
|
bb4f8d8749 | ||
|
|
a6cb681f10 | ||
|
|
00ff3e6b1b | ||
|
|
12510a5396 | ||
|
|
ea30a0ed24 | ||
|
|
df40a69872 | ||
|
|
b000f91dad |
5
.github/workflows/canary.yml
vendored
5
.github/workflows/canary.yml
vendored
@@ -134,16 +134,13 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
pushd publish_appimage
|
||||
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||
popd
|
||||
|
||||
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
shell: bash
|
||||
|
||||
macos_release:
|
||||
|
||||
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -125,16 +125,13 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
pushd publish_appimage
|
||||
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||
popd
|
||||
|
||||
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
shell: bash
|
||||
|
||||
macos_release:
|
||||
|
||||
3141
assets/locales.json
3141
assets/locales.json
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@ cd "$ROOTDIR"
|
||||
|
||||
BUILDDIR=${BUILDDIR:-publish}
|
||||
OUTDIR=${OUTDIR:-publish_appimage}
|
||||
UFLAG=${UFLAG:-"gh-releases-zsync|Ryubing|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||
|
||||
rm -rf AppDir
|
||||
mkdir -p AppDir/usr/bin
|
||||
@@ -24,10 +23,4 @@ chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
|
||||
mkdir -p "$OUTDIR"
|
||||
|
||||
appimagetool -n --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
|
||||
-u "$UFLAG" \
|
||||
AppDir "$OUTDIR"/Ryujinx.AppImage
|
||||
|
||||
# Move zsync file needed for delta updates
|
||||
if [ "$RELEASE" = "1" ]; then
|
||||
mv ./*.AppImage.zsync "$OUTDIR"
|
||||
fi
|
||||
|
||||
@@ -1175,6 +1175,7 @@
|
||||
0100EB100AB42000,"FINAL FANTASY XII THE ZODIAC AGE",opengl;vulkan-backend-bug,playable,2024-08-11 07:01:54
|
||||
010068F00AA78000,"FINAL FANTASY XV POCKET EDITION HD",,playable,2021-01-05 17:52:08
|
||||
0100CE4010AAC000,"FINAL FANTASY® CRYSTAL CHRONICLES™ Remastered Edition",,playable,2023-04-02 23:39:12
|
||||
010038B015560000,FINAL FANTASY TACTICS - The Ivalice Chronicles,gpu,boots,2024-09-30 02:59:00
|
||||
01001BA00AE4E000,"Final Light, The Prison",,playable,2020-07-31 21:48:44
|
||||
0100FF100FB68000,"Finding Teddy 2 : Definitive Edition",gpu,ingame,2024-04-19 16:51:33
|
||||
0100F4E013AAE000,"Fire & Water",,playable,2020-12-15 15:43:20
|
||||
@@ -2271,6 +2272,7 @@
|
||||
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
||||
01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20
|
||||
0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
||||
010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
||||
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
|
||||
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
|
||||
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
|
||||
@@ -2707,6 +2709,8 @@
|
||||
01008F701C074000,"SONIC SUPERSTARS",gpu;nvdec,ingame,2023-10-28 17:48:07
|
||||
010088801C150000,"Sonic Superstars Digital Art Book with Mini Digital Soundtrack",,playable,2024-08-20 13:26:56
|
||||
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
|
||||
010064B0242BE000,"Sonic Racing: CrossWorlds - Demo",gpu;vulkan-backend-bug;demo,ingame,2024-09-25 11:27:53
|
||||
01006E001823C000,"Sonic Racing: CrossWorlds",gpu;vulkan-backend-bug;ldn-broken,ingame,2024-09-30 17:23:00
|
||||
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
|
||||
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
|
||||
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken;vulkan-backend-bug;gpu,ingame,2025-01-21 17:35:10
|
||||
@@ -2864,11 +2868,13 @@
|
||||
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
|
||||
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
|
||||
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
|
||||
010099C022B96000,"Super Mario Galaxy",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug,ingame,2025-10-01 15:30:00
|
||||
0100FD8022DAA000,"Super Mario Galaxy 2",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug;deadlock,ingame,2025-10-04 18:50:00
|
||||
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
|
||||
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
|
||||
01009C200D60E000,"Super Meat Boy Forever",gpu,boots,2021-04-26 14:25:39
|
||||
0100BDD00EC5C000,"Super Mega Space Blaster Special Turbo",online,playable,2020-08-06 12:13:25
|
||||
010031F019294000,"Super Monkey Ball Banana Rumble",,playable,2024-06-28 10:39:18
|
||||
010031F019294000,"Super Monkey Ball Banana Rumble",ldn-broken,playable,2025-10-01 18:03:00
|
||||
0100B2A00E1E0000,"Super Monkey Ball: Banana Blitz HD",online-broken,playable,2022-09-16 13:16:25
|
||||
01006D000D2A0000,"Super Mutant Alien Assault",,playable,2020-06-07 23:32:45
|
||||
01004D600AC14000,"Super Neptunia RPG",nvdec,playable,2022-08-17 16:38:52
|
||||
@@ -2934,6 +2940,7 @@
|
||||
0100B76011DAA000,"Taxi Chaos",slow;online-broken;UE4,playable,2022-10-25 19:13:00
|
||||
0100F43011E5A000,"Tcheco in the Castle of Lucio",,playable,2020-06-27 13:35:43
|
||||
010092B0091D0000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
|
||||
010084B00B36E000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
|
||||
0100FE701475A000,"Teenage Mutant Ninja Turtles: Shredder's Revenge",deadlock;crash,boots,2024-09-28 09:31:39
|
||||
01005CF01E784000,"Teenage Mutant Ninja Turtles: Splintered Fate",,playable,2024-08-03 13:50:42
|
||||
0100FDB0154E4000,"Teenage Mutant Ninja Turtles: The Cowabunga Collection",,playable,2024-01-22 19:39:04
|
||||
@@ -3220,6 +3227,7 @@
|
||||
010038400C2FE000,"TY the Tasmanian Tiger™ HD",32-bit;crash;nvdec,menus,2020-12-17 21:15:00
|
||||
010073A00C4B2000,"Tyd wag vir Niemand",,playable,2021-03-02 13:39:53
|
||||
0100D5B00D6DA000,"Type:Rider",,playable,2021-01-06 13:12:55
|
||||
01008AF01AD22000,"The Patrick Star Game",,playable,2025-10-01 17:55:30
|
||||
010040D01222C000,"UBERMOSH: SANTICIDE",,playable,2020-11-27 15:05:01
|
||||
0100992010BF8000,"Ubongo",,playable,2021-02-04 21:15:01
|
||||
010079000B56C000,"UglyDolls: An Imperfect Adventure",nvdec;UE4,playable,2022-08-25 14:42:16
|
||||
@@ -3466,3 +3474,6 @@
|
||||
0100F4401940A000,"超探偵事件簿 レインコード (Master Detective Archives: Rain Code)",crash,ingame,2024-02-12 20:58:31
|
||||
010064801A01C000,"超次元ゲイム ネプテューヌ GameMaker R:Evolution",crash,nothing,2023-10-30 22:37:40
|
||||
0100F3400332C000,"ゼノブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
|
||||
010075000ECBE000,"超级马力欧 奥德赛",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
|
||||
010075100E8EC000,"马力欧卡丁车8 豪华版",32-bit;ldn-works;LAN;amd-vendor-bug,playable,2024-09-19 11:55:17
|
||||
0100E8C00F506000,"新 超级马力欧兄弟U 豪华版",32-bit,playable,2023-10-08 02:06:37
|
||||
|
||||
|
@@ -46,10 +46,11 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
// PS5 touchpad button
|
||||
Touchpad,
|
||||
|
||||
// Virtual buttons for single joycon
|
||||
// Virtual buttons for single joycon (left)
|
||||
SingleLeftTrigger0,
|
||||
SingleRightTrigger0,
|
||||
|
||||
// Virtual buttons for single joycon (right)
|
||||
SingleLeftTrigger1,
|
||||
SingleRightTrigger1,
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ namespace Ryujinx.Common
|
||||
"010049900F546002", // Super Mario Sunshine
|
||||
"0100a3900c3e2000", // Paper Mario: The Origami King
|
||||
"0100ecd018ebe000", // Paper Mario: The Thousand-Year Door
|
||||
"01009cC022b96000", // Super Mario Galaxy
|
||||
"0100fd8022daa000", // Super Mario Galaxy 2
|
||||
|
||||
//Pikmin Franchise
|
||||
"0100aa80194b0000", // Pikmin 1
|
||||
@@ -158,6 +160,8 @@ namespace Ryujinx.Common
|
||||
"01009aa000faa000", // Sonic Mania
|
||||
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
||||
"01005ea01c0fc001", // ^
|
||||
"01006e001823c000", // Sonic Racing: CrossWorlds
|
||||
"010064b0242be000", // Sonic Racing: CrossWorlds - Demo
|
||||
|
||||
//Xenoblade Franchise
|
||||
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
|
||||
|
||||
@@ -149,6 +149,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
B8G8R8A8Srgb,
|
||||
B10G10R10A2Unorm,
|
||||
X8UintD24Unorm,
|
||||
A8B8G8R8Uint,
|
||||
}
|
||||
|
||||
public static class FormatExtensions
|
||||
|
||||
@@ -359,6 +359,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
A2B10G10R10Sint = (A2B10G10R10 << 21) | (Sint << 27), // 0x1e000000
|
||||
A2B10G10R10Uscaled = (A2B10G10R10 << 21) | (Uscaled << 27), // 0x2e000000
|
||||
A2B10G10R10Sscaled = (A2B10G10R10 << 21) | (Sscaled << 27), // 0x36000000
|
||||
A8B8G8R8Uint = (A8B8G8R8 << 21) | (Uint << 27), // 0x25E00040
|
||||
}
|
||||
|
||||
private static readonly Dictionary<TextureFormat, FormatInfo> _textureFormats = new()
|
||||
@@ -554,6 +555,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{ VertexAttributeFormat.A2B10G10R10Sint, Format.R10G10B10A2Sint },
|
||||
{ VertexAttributeFormat.A2B10G10R10Uscaled, Format.R10G10B10A2Uscaled },
|
||||
{ VertexAttributeFormat.A2B10G10R10Sscaled, Format.R10G10B10A2Sscaled },
|
||||
{ VertexAttributeFormat.A8B8G8R8Uint, Format.A8B8G8R8Uint },
|
||||
};
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
|
||||
@@ -487,10 +487,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="stage">The type of usage that created the buffer</param>
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage)
|
||||
{
|
||||
Buffer newBuffer = null;
|
||||
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size);
|
||||
|
||||
if (overlaps.Length > 0)
|
||||
if (overlaps.Length != 0)
|
||||
{
|
||||
// The buffer already exists. We can just return the existing buffer
|
||||
// if the buffer we need is fully contained inside the overlapping buffer.
|
||||
@@ -530,13 +532,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
address = Math.Min(address, overlaps[0].Address);
|
||||
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
|
||||
|
||||
RangeItem<Buffer>[] overlapsArray = overlaps.ToArray();
|
||||
|
||||
for (int i = 0; i < overlaps.Length; i++)
|
||||
{
|
||||
anySparseCompatible |= overlaps[i].Value.SparseCompatible;
|
||||
}
|
||||
|
||||
RangeItem<Buffer>[] overlapsArray = overlaps.ToArray();
|
||||
|
||||
_buffers.RemoveRange(overlaps[0], overlaps[^1]);
|
||||
|
||||
@@ -544,22 +546,29 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlapsArray);
|
||||
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlapsArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, []);
|
||||
|
||||
_buffers.Add(buffer);
|
||||
newBuffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, []);
|
||||
}
|
||||
|
||||
if (newBuffer is not null)
|
||||
{
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -574,11 +583,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, ulong alignment)
|
||||
{
|
||||
bool sparseAligned = alignment >= SparseBufferAlignmentSize;
|
||||
Buffer newBuffer = null;
|
||||
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
Span<RangeItem<Buffer>> overlaps = _buffers.FindOverlapsAsSpan(address, size);
|
||||
|
||||
if (overlaps.Length > 0)
|
||||
if (overlaps.Length != 0)
|
||||
{
|
||||
// If the buffer already exists, make sure if covers the entire range,
|
||||
// and make sure it is properly aligned, otherwise sparse mapping may fail.
|
||||
@@ -595,19 +605,20 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// overlaps more buffers, so try again after each extension
|
||||
// and ensure we cover all overlaps.
|
||||
|
||||
RangeItem<Buffer> oldFirst;
|
||||
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
|
||||
|
||||
int oldOverlapCount;
|
||||
|
||||
do
|
||||
{
|
||||
address = Math.Min(address, overlaps[0].Address);
|
||||
endAddress = Math.Max(endAddress, overlaps[^1].EndAddress);
|
||||
|
||||
address &= ~(alignment - 1);
|
||||
|
||||
oldFirst = overlaps[0];
|
||||
oldOverlapCount = overlaps.Length;
|
||||
overlaps = _buffers.FindOverlapsAsSpan(address, endAddress - address);
|
||||
}
|
||||
while (oldFirst != overlaps[0]);
|
||||
while (oldOverlapCount != overlaps.Length);
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
@@ -617,22 +628,29 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlapsArray);
|
||||
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlapsArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, []);
|
||||
|
||||
_buffers.Add(buffer);
|
||||
newBuffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, []);
|
||||
}
|
||||
|
||||
if (newBuffer is not null)
|
||||
{
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -879,7 +897,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
MemoryRange subRange = range.GetSubRange(i);
|
||||
|
||||
Buffer subBuffer = _buffers.FindOverlapFast(subRange.Address, subRange.Size).Value;
|
||||
Buffer subBuffer = _buffers.FindOverlap(subRange.Address, subRange.Size).Value;
|
||||
|
||||
subBuffer.SynchronizeMemory(subRange.Address, subRange.Size);
|
||||
|
||||
@@ -977,7 +995,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
Buffer buffer = _buffers.FindOverlapFast(address, size).Value;
|
||||
Buffer buffer = _buffers.FindOverlap(address, size).Value;
|
||||
|
||||
if (copyBackVirtual)
|
||||
{
|
||||
|
||||
@@ -473,6 +473,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ranges._migrationTarget = this;
|
||||
|
||||
Lock.EnterWriteLock();
|
||||
|
||||
foreach (BufferModifiedRange range in inheritRanges)
|
||||
{
|
||||
Add(range);
|
||||
|
||||
@@ -211,6 +211,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
case Format.R16G16B16Uint:
|
||||
format = VkFormat.R16G16B16A16Uint;
|
||||
break;
|
||||
case Format.A8B8G8R8Uint:
|
||||
format = VkFormat.A8B8G8R8UintPack32;
|
||||
break;
|
||||
default:
|
||||
Logger.Error?.Print(LogClass.Gpu, $"Format {srcFormat} is not supported by the host.");
|
||||
break;
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private static bool HasPushDescriptorsBug(VulkanRenderer gd)
|
||||
{
|
||||
// Those GPUs/drivers do not work properly with push descriptors, so we must force disable them.
|
||||
return gd.IsNvidiaPreTuring || (gd.IsIntelArc && gd.IsIntelWindows);
|
||||
return gd.IsNvidiaPreTuring || (gd.IsIntelArc && (gd.IsIntelWindows || gd.IsIntelLinux));
|
||||
}
|
||||
|
||||
private static bool CanUsePushDescriptors(VulkanRenderer gd, ResourceLayout layout, bool isCompute)
|
||||
|
||||
@@ -91,6 +91,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
internal Vendor Vendor { get; private set; }
|
||||
internal bool IsAmdWindows { get; private set; }
|
||||
internal bool IsIntelWindows { get; private set; }
|
||||
internal bool IsIntelLinux { get; private set; }
|
||||
internal bool IsAmdGcn { get; private set; }
|
||||
internal bool IsAmdRdna3 { get; private set; }
|
||||
internal bool IsNvidiaPreTuring { get; private set; }
|
||||
@@ -359,6 +360,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
IsAmdWindows = Vendor == Vendor.Amd && OperatingSystem.IsWindows();
|
||||
IsIntelWindows = Vendor == Vendor.Intel && OperatingSystem.IsWindows();
|
||||
IsIntelLinux = Vendor == Vendor.Intel && OperatingSystem.IsLinux();
|
||||
IsTBDR =
|
||||
Vendor is Vendor.Apple or
|
||||
Vendor.Qualcomm or
|
||||
@@ -398,7 +400,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else if (Vendor == Vendor.Intel)
|
||||
{
|
||||
IsIntelArc = GpuRenderer.StartsWith("Intel(R) Arc(TM)");
|
||||
IsIntelArc = GpuRenderer.StartsWithIgnoreCase("Intel(R) Arc(TM)");
|
||||
}
|
||||
|
||||
IsQualcommProprietary = hasDriverProperties && driverProperties.DriverID == DriverId.QualcommProprietary;
|
||||
|
||||
@@ -1105,7 +1105,7 @@ namespace Ryujinx.HLE.Debugger
|
||||
{
|
||||
var image = images[i];
|
||||
ulong endAddress = image.BaseAddress + image.Size - 1;
|
||||
string name = debugger.GetGuessedNsoNameFromIndex(i);
|
||||
string name = image.Name;
|
||||
sb.AppendLine($" 0x{image.BaseAddress:x10} - 0x{endAddress:x10} {name}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
public class Image
|
||||
{
|
||||
public string Name { get; internal set; }
|
||||
public ulong BaseAddress { get; }
|
||||
public ulong Size { get; }
|
||||
public ulong EndAddress => BaseAddress + Size;
|
||||
@@ -31,6 +32,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
BaseAddress = baseAddress;
|
||||
Size = size;
|
||||
Symbols = symbols;
|
||||
Name = "(unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +62,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
if (!String.IsNullOrEmpty(ThreadName))
|
||||
{
|
||||
trace.AppendLine($"Thread ID: {thread.ThreadUid} ({ThreadName})");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
trace.AppendLine($"Thread ID: {thread.ThreadUid}");
|
||||
}
|
||||
|
||||
@@ -254,11 +258,66 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
info.SubName = string.Empty;
|
||||
}
|
||||
|
||||
info.ImageName = GetGuessedNsoNameFromIndex(imageIndex);
|
||||
info.ImageName = image.Name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool GetModuleName(out string moduleName, Image image)
|
||||
{
|
||||
moduleName = string.Empty;
|
||||
|
||||
var rodataStart = image.BaseAddress + image.Size;
|
||||
|
||||
KMemoryInfo roInfo = _owner.MemoryManager.QueryMemory(rodataStart);
|
||||
if (roInfo.Permission != KMemoryPermission.Read)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var rwdataStart = roInfo.Address + roInfo.Size;
|
||||
|
||||
try
|
||||
{
|
||||
Span<byte> rodataBuf = stackalloc byte[0x208];
|
||||
_owner.CpuMemory.Read(rodataStart, rodataBuf);
|
||||
|
||||
ulong deprecatedRwDataOffset = BitConverter.ToUInt64(rodataBuf);
|
||||
// no name if using old format
|
||||
if (image.BaseAddress + deprecatedRwDataOffset == rwdataStart)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint zero = BitConverter.ToUInt32(rodataBuf);
|
||||
int pathLength = BitConverter.ToInt32(rodataBuf.Slice(4));
|
||||
if (zero != 0 || pathLength <= 0)
|
||||
{
|
||||
// try again with 12 byte offset, 20.0.0+
|
||||
_owner.CpuMemory.Read(rodataStart + 12, rodataBuf);
|
||||
zero = BitConverter.ToUInt32(rodataBuf);
|
||||
pathLength = BitConverter.ToInt32(rodataBuf.Slice(4));
|
||||
}
|
||||
|
||||
if (zero != 0 || pathLength <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pathLength = Math.Min(pathLength, rodataBuf.Length - 8);
|
||||
var pathBuf = rodataBuf.Slice(8, pathLength);
|
||||
int lastSlash = pathBuf.LastIndexOfAny(new byte[] { (byte)'\\', (byte)'/' });
|
||||
|
||||
moduleName = Encoding.ASCII.GetString(pathBuf.Slice(lastSlash + 1).TrimEnd((byte)0));
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (InvalidMemoryRegionException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool AnalyzePointerFromStack(out PointerInfo info, ulong address, KThread thread)
|
||||
{
|
||||
info = default;
|
||||
@@ -293,31 +352,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetGuessedNsoNameFromIndex(int index)
|
||||
{
|
||||
if ((uint)index > 11)
|
||||
{
|
||||
return "???";
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
return "rtld";
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
return "main";
|
||||
}
|
||||
else if (index == GetImagesCount() - 1)
|
||||
{
|
||||
return "sdk";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "subsdk" + (index - 2);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetImagesCount()
|
||||
{
|
||||
lock (_images)
|
||||
@@ -329,7 +363,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
public List<Image> GetLoadedImages()
|
||||
{
|
||||
EnsureLoaded();
|
||||
|
||||
|
||||
lock (_images)
|
||||
{
|
||||
return [.. _images];
|
||||
@@ -449,7 +483,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
lock (_images)
|
||||
{
|
||||
_images.Add(new Image(textOffset, textSize, symbols.OrderBy(x => x.Value).ToArray()));
|
||||
var image = new Image(textOffset, textSize, symbols.OrderBy(x => x.Value).ToArray());
|
||||
|
||||
string moduleName;
|
||||
if (!GetModuleName(out moduleName, image))
|
||||
{
|
||||
var newIndex = _images.Count;
|
||||
moduleName = $"(unknown{newIndex})";
|
||||
}
|
||||
image.Name = moduleName;
|
||||
|
||||
_images.Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,6 @@ namespace Ryujinx.Memory.Range
|
||||
/// <typeparam name="T">Type of the range.</typeparam>
|
||||
public unsafe class NonOverlappingRangeList<T> : RangeListBase<T> where T : class, INonOverlappingRange
|
||||
{
|
||||
// private readonly Dictionary<ulong, RangeItem<T>> _quickAccess = new(AddressEqualityComparer.Comparer);
|
||||
// private readonly Dictionary<ulong, RangeItem<T>> _fastQuickAccess = new(AddressEqualityComparer.Comparer);
|
||||
|
||||
public readonly ReaderWriterLockSlim Lock = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -44,8 +41,6 @@ namespace Ryujinx.Memory.Range
|
||||
RangeItem<T> rangeItem = new(item);
|
||||
|
||||
Insert(index, rangeItem);
|
||||
|
||||
// _quickAccess.Add(item.Address, rangeItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,15 +66,7 @@ namespace Ryujinx.Memory.Range
|
||||
Items[index + 1].Previous = rangeItem;
|
||||
}
|
||||
|
||||
// foreach (ulong addr in Items[index].QuickAccessAddresses)
|
||||
// {
|
||||
// _quickAccess.Remove(addr);
|
||||
// _fastQuickAccess.Remove(addr);
|
||||
// }
|
||||
|
||||
Items[index] = rangeItem;
|
||||
|
||||
// _quickAccess[item.Address] = rangeItem;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -108,19 +95,8 @@ namespace Ryujinx.Memory.Range
|
||||
Items[index + 1].Previous = rangeItem;
|
||||
}
|
||||
|
||||
// foreach (ulong addr in item.QuickAccessAddresses)
|
||||
// {
|
||||
// _quickAccess.Remove(addr);
|
||||
// _fastQuickAccess.Remove(addr);
|
||||
// }
|
||||
|
||||
Items[index] = rangeItem;
|
||||
|
||||
// if (item.Address != rangeItem.Address)
|
||||
// _quickAccess.Remove(item.Address);
|
||||
//
|
||||
// _quickAccess[rangeItem.Address] = rangeItem;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -196,14 +172,6 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
if (index >= 0 && Items[index].Value.Equals(item))
|
||||
{
|
||||
// _quickAccess.Remove(item.Address);
|
||||
//
|
||||
// foreach (ulong addr in Items[index].QuickAccessAddresses)
|
||||
// {
|
||||
// _quickAccess.Remove(addr);
|
||||
// _fastQuickAccess.Remove(addr);
|
||||
// }
|
||||
|
||||
RemoveAt(index);
|
||||
|
||||
return true;
|
||||
@@ -232,16 +200,6 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
(int startIndex, int endIndex) = BinarySearchEdges(startItem.Address, endItem.EndAddress);
|
||||
|
||||
// for (int i = startIndex; i < endIndex; i++)
|
||||
// {
|
||||
// _quickAccess.Remove(Items[i].Address);
|
||||
// foreach (ulong addr in Items[i].QuickAccessAddresses)
|
||||
// {
|
||||
// _quickAccess.Remove(addr);
|
||||
// _fastQuickAccess.Remove(addr);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (endIndex < Count)
|
||||
{
|
||||
Items[endIndex].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
|
||||
@@ -279,13 +237,6 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
while (Items[endIndex] is not null && Items[endIndex].Address < address + size)
|
||||
{
|
||||
// _quickAccess.Remove(Items[endIndex].Address);
|
||||
// foreach (ulong addr in Items[endIndex].QuickAccessAddresses)
|
||||
// {
|
||||
// _quickAccess.Remove(addr);
|
||||
// _fastQuickAccess.Remove(addr);
|
||||
// }
|
||||
|
||||
if (endIndex == Count - 1)
|
||||
{
|
||||
break;
|
||||
@@ -322,8 +273,6 @@ namespace Ryujinx.Memory.Range
|
||||
Lock.EnterWriteLock();
|
||||
Count = 0;
|
||||
Lock.ExitWriteLock();
|
||||
// _quickAccess.Clear();
|
||||
// _fastQuickAccess.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -436,11 +385,6 @@ namespace Ryujinx.Memory.Range
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override RangeItem<T> FindOverlap(ulong address, ulong size)
|
||||
{
|
||||
// if (_quickAccess.TryGetValue(address, out RangeItem<T> overlap))
|
||||
// {
|
||||
// return overlap;
|
||||
// }
|
||||
|
||||
int index = BinarySearchLeftEdge(address, address + size);
|
||||
|
||||
if (index < 0)
|
||||
@@ -448,12 +392,6 @@ namespace Ryujinx.Memory.Range
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (Items[index].Address < address)
|
||||
// {
|
||||
// _quickAccess.TryAdd(address, Items[index]);
|
||||
// Items[index].QuickAccessAddresses.Add(address);
|
||||
// }
|
||||
|
||||
return Items[index];
|
||||
}
|
||||
|
||||
@@ -466,28 +404,12 @@ namespace Ryujinx.Memory.Range
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override RangeItem<T> FindOverlapFast(ulong address, ulong size)
|
||||
{
|
||||
// if (_quickAccess.TryGetValue(address, out RangeItem<T> overlap) || _fastQuickAccess.TryGetValue(address, out overlap))
|
||||
// {
|
||||
// return overlap;
|
||||
// }
|
||||
|
||||
int index = BinarySearch(address, address + size);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (Items[index].Address < address)
|
||||
// {
|
||||
// _quickAccess.TryAdd(address, Items[index]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _fastQuickAccess.TryAdd(address, Items[index]);
|
||||
// }
|
||||
//
|
||||
// Items[index].QuickAccessAddresses.Add(address);
|
||||
|
||||
return Items[index];
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||
<Color x:Key="Custom">#6483F5</Color>
|
||||
<Color x:Key="Warning">#800080</Color>
|
||||
<Color x:Key="CustomConfig">#00B5B8</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
||||
@@ -38,6 +39,7 @@
|
||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||
<Color x:Key="Custom">#6483F5</Color>
|
||||
<Color x:Key="Warning">#800080</Color>
|
||||
<Color x:Key="CustomConfig">#00B5B8</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
||||
@@ -57,6 +59,7 @@
|
||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||
<Color x:Key="Custom">#6483F5</Color>
|
||||
<Color x:Key="Warning">#FFA500</Color>
|
||||
<Color x:Key="CustomConfig">#00B5B8</Color>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -174,8 +174,8 @@ namespace Ryujinx.Headless
|
||||
ButtonMinus = ConfigGamepadInputId.Minus,
|
||||
ButtonL = ConfigGamepadInputId.LeftShoulder,
|
||||
ButtonZl = ConfigGamepadInputId.LeftTrigger,
|
||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||
ButtonSl = ConfigGamepadInputId.SingleLeftTrigger0,
|
||||
ButtonSr = ConfigGamepadInputId.SingleRightTrigger0,
|
||||
},
|
||||
|
||||
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
@@ -196,8 +196,8 @@ namespace Ryujinx.Headless
|
||||
ButtonPlus = ConfigGamepadInputId.Plus,
|
||||
ButtonR = ConfigGamepadInputId.RightShoulder,
|
||||
ButtonZr = ConfigGamepadInputId.RightTrigger,
|
||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||
ButtonSl = ConfigGamepadInputId.SingleLeftTrigger1,
|
||||
ButtonSr = ConfigGamepadInputId.SingleRightTrigger1,
|
||||
},
|
||||
|
||||
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
|
||||
@@ -428,7 +428,7 @@ namespace Ryujinx.Headless
|
||||
[Option("enable-gdb-stub", Required = false, Default = false, HelpText = "Enables the GDB stub so that a developer can attach a debugger to the emulated process.")]
|
||||
public bool EnableGdbStub { get; set; }
|
||||
|
||||
[Option("gdb-stub-port", Required = false, Default = 55555, HelpText = "Specifies which TCP port the GDB stub listens on.")]
|
||||
[Option("gdb-stub-port", Required = false, Default = (ushort)55555, HelpText = "Specifies which TCP port the GDB stub listens on.")]
|
||||
public ushort GdbStubPort { get; set; }
|
||||
|
||||
[Option("suspend-on-start", Required = false, Default = false, HelpText = "Suspend execution when starting an application.")]
|
||||
|
||||
@@ -101,8 +101,8 @@ namespace Ryujinx.Ava.Systems
|
||||
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
string newVersionString = ReleaseInformation.IsCanaryBuild
|
||||
? $"Canary {currentVersion} -> Canary {newVersion}"
|
||||
: $"{currentVersion} -> {newVersion}";
|
||||
? $"Canary {currentVersion} → Canary {newVersion}"
|
||||
: $"{currentVersion} → {newVersion}";
|
||||
|
||||
Logger.Info?.Print(LogClass.Application, $"Version found: {newVersionString}");
|
||||
|
||||
|
||||
@@ -114,16 +114,20 @@
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgePptc}"
|
||||
Icon="{ext:Icon fa-solid fa-arrow-rotate-right}"
|
||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
|
||||
<Separator/>
|
||||
<MenuItem
|
||||
Command="{Binding NukePtcCache}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementNukePptc}"
|
||||
Icon="{ext:Icon fa-solid fa-trash-can}" />
|
||||
Icon="{ext:Icon fa-solid fa-trash-can}"
|
||||
IsEnabled="{Binding HasPtcCacheFiles}" />
|
||||
<MenuItem
|
||||
Command="{Binding PurgeShaderCache}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
|
||||
Icon="{ext:Icon fa-solid fa-trash-can}" />
|
||||
Icon="{ext:Icon fa-solid fa-trash-can}"
|
||||
IsEnabled="{Binding HasShaderCacheFiles}" />
|
||||
<Separator/>
|
||||
<MenuItem
|
||||
Command="{Binding OpenPtcDirectory}"
|
||||
CommandParameter="{Binding}"
|
||||
|
||||
@@ -354,8 +354,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
primary,
|
||||
secondaryText,
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
||||
(int)Symbol.Help,
|
||||
UserResult.Yes);
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
{ Glyph.List, char.ConvertFromUtf32((int)Symbol.List) },
|
||||
{ Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll) },
|
||||
{ Glyph.Chip, char.ConvertFromUtf32(59748) },
|
||||
{ Glyph.Device, char.ConvertFromUtf32(0xE7F7) },
|
||||
{ Glyph.Bug, char.ConvertFromUtf32(0xEBE8) },
|
||||
{ Glyph.Important, char.ConvertFromUtf32((int)Symbol.Important) },
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
List,
|
||||
Grid,
|
||||
Chip,
|
||||
Device,
|
||||
Bug,
|
||||
Important,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,8 +732,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
ButtonMinus = ConfigGamepadInputId.Minus,
|
||||
ButtonL = ConfigGamepadInputId.LeftShoulder,
|
||||
ButtonZl = ConfigGamepadInputId.LeftTrigger,
|
||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||
ButtonSl = ConfigGamepadInputId.SingleLeftTrigger0,
|
||||
ButtonSr = ConfigGamepadInputId.SingleRightTrigger0,
|
||||
},
|
||||
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
{
|
||||
@@ -751,8 +751,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
ButtonPlus = ConfigGamepadInputId.Plus,
|
||||
ButtonR = ConfigGamepadInputId.RightShoulder,
|
||||
ButtonZr = ConfigGamepadInputId.RightTrigger,
|
||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||
ButtonSl = ConfigGamepadInputId.SingleLeftTrigger1,
|
||||
ButtonSr = ConfigGamepadInputId.SingleRightTrigger1,
|
||||
},
|
||||
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
{
|
||||
|
||||
@@ -1897,7 +1897,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
secondaryText,
|
||||
LocaleManager.Instance[LocaleKeys.Continue],
|
||||
LocaleManager.Instance[LocaleKeys.Cancel],
|
||||
LocaleManager.Instance[LocaleKeys.TrimXCIFileDialogTitle]
|
||||
LocaleManager.Instance[LocaleKeys.GameListContextMenuTrimXCI]
|
||||
);
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
@@ -2121,7 +2121,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
});
|
||||
|
||||
public static AsyncRelayCommand<MainWindowViewModel> NukePtcCache { get; } =
|
||||
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
|
||||
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null &&
|
||||
vm.HasPtcCacheFiles(),
|
||||
async viewModel =>
|
||||
{
|
||||
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
|
||||
@@ -2170,8 +2171,22 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
});
|
||||
|
||||
private bool HasPtcCacheFiles()
|
||||
{
|
||||
if (this.SelectedApplication == null) return false;
|
||||
|
||||
DirectoryInfo mainDir = new DirectoryInfo(Path.Combine(AppDataManager.GamesDirPath,
|
||||
this.SelectedApplication.IdString, "cache", "cpu", "0"));
|
||||
DirectoryInfo backupDir = new DirectoryInfo(Path.Combine(AppDataManager.GamesDirPath,
|
||||
this.SelectedApplication.IdString, "cache", "cpu", "1"));
|
||||
|
||||
return (mainDir.Exists && (mainDir.EnumerateFiles("*.cache").Any() || mainDir.EnumerateFiles("*.info").Any())) ||
|
||||
(backupDir.Exists && (backupDir.EnumerateFiles("*.cache").Any() || backupDir.EnumerateFiles("*.info").Any()));
|
||||
}
|
||||
|
||||
public static AsyncRelayCommand<MainWindowViewModel> PurgeShaderCache { get; } =
|
||||
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
|
||||
Commands.CreateConditional<MainWindowViewModel>(
|
||||
vm => vm?.SelectedApplication != null && vm.HasShaderCacheFiles(),
|
||||
async viewModel =>
|
||||
{
|
||||
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
|
||||
@@ -2228,6 +2243,20 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
});
|
||||
|
||||
private bool HasShaderCacheFiles()
|
||||
{
|
||||
if (this.SelectedApplication == null) return false;
|
||||
|
||||
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath,
|
||||
this.SelectedApplication.IdString, "cache", "shader"));
|
||||
|
||||
if (!shaderCacheDir.Exists) return false;
|
||||
|
||||
return shaderCacheDir.EnumerateDirectories("*").Any() ||
|
||||
shaderCacheDir.GetFiles("*.toc").Any() ||
|
||||
shaderCacheDir.GetFiles("*.data").Any();
|
||||
}
|
||||
|
||||
public static RelayCommand<MainWindowViewModel> OpenPtcDirectory { get; } =
|
||||
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
|
||||
viewModel =>
|
||||
|
||||
@@ -27,11 +27,6 @@
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="10,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale CommonSort}" />
|
||||
<DropDownButton
|
||||
Width="150"
|
||||
HorizontalAlignment="Left"
|
||||
|
||||
@@ -235,11 +235,6 @@
|
||||
Name="AboutWindowMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpAbout}"
|
||||
Icon="{ext:Icon fa-solid fa-circle-info}" />
|
||||
<MenuItem
|
||||
Name="UpdateMenuItem"
|
||||
IsEnabled="{Binding CanUpdate}"
|
||||
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
||||
Icon="{ext:Icon fa-solid fa-rotate}" />
|
||||
<MenuItem
|
||||
Name="CompatibilityListMenuItem"
|
||||
Header="{ext:Locale CompatibilityListOpen}"
|
||||
@@ -255,21 +250,24 @@
|
||||
Name="SetupGuideMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpSetup}"
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.SetupGuideWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
||||
CommandParameter="{x:Static common:SharedConstants.SetupGuideWikiUrl}" />
|
||||
<MenuItem
|
||||
Name="LdnGuideMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.MultiplayerWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
||||
CommandParameter="{x:Static common:SharedConstants.MultiplayerWikiUrl}" />
|
||||
<MenuItem
|
||||
Name="FaqMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpFaq}"
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.FaqWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||
CommandParameter="{x:Static common:SharedConstants.FaqWikiUrl}" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Name="UpdateMenuItem"
|
||||
IsEnabled="{Binding CanUpdate}"
|
||||
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
||||
Icon="{ext:Icon fa-solid fa-rotate}" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</DockPanel>
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
|
||||
Glyph="{helpers:GlyphValueConverter Grid}" />
|
||||
</Button>
|
||||
<TextBlock
|
||||
Margin="10,0,5,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale IconSize}" />
|
||||
<controls:SliderScroll
|
||||
Width="150"
|
||||
Height="35"
|
||||
@@ -171,11 +167,5 @@
|
||||
</Flyout>
|
||||
</DropDownButton.Flyout>
|
||||
</DropDownButton>
|
||||
<TextBlock
|
||||
Margin="10,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right"
|
||||
Text="{ext:Locale CommonSort}" />
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="5" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="CornerRadius" Value="15" />
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
||||
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).GridItemSelectorSize}" />
|
||||
@@ -53,7 +53,7 @@
|
||||
Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
|
||||
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="4">
|
||||
CornerRadius="12.5">
|
||||
<Grid RowDefinitions="Auto,Auto">
|
||||
<Image
|
||||
Grid.Row="0"
|
||||
@@ -72,42 +72,26 @@
|
||||
Text="{Binding Name}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ui:SymbolIcon
|
||||
Margin="5,5,0,0"
|
||||
Margin="2.5,2.5,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
FontSize="18"
|
||||
FontSize="23"
|
||||
Foreground="{DynamicResource FavoriteApplicationIconColor}"
|
||||
IsVisible="{Binding Favorite}"
|
||||
Symbol="StarFilled" />
|
||||
<Grid IsVisible="{Binding !$parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ShowNames}">
|
||||
<Border
|
||||
Margin="15,35,5,15"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Width="90"
|
||||
Height="20"
|
||||
CornerRadius="4"
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Background="{DynamicResource ThemeContentBackgroundColor}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</Border>
|
||||
</Grid>
|
||||
<ui:SymbolIcon
|
||||
Margin="0,2.5,2.5,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
FontSize="23"
|
||||
Foreground="{DynamicResource CustomConfig}"
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Symbol="SettingsFilled" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="CornerRadius" Value="15" />
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
||||
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ListItemSelectorSize}" />
|
||||
</Style>
|
||||
@@ -46,9 +49,11 @@
|
||||
Padding="10"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="5">
|
||||
ClipToBounds="True">
|
||||
<Grid ColumnDefinitions="Auto,10,*,150,100">
|
||||
<Border
|
||||
ClipToBounds="True"
|
||||
CornerRadius="7">
|
||||
<Image
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
@@ -58,6 +63,8 @@
|
||||
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}}" />
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
Margin="0,0,5,0"
|
||||
@@ -91,7 +98,7 @@
|
||||
IsVisible="{Binding HasPlayabilityInfo}"
|
||||
Background="{DynamicResource AppListBackgroundColor}"
|
||||
Margin="-1, 0, 0, 0"
|
||||
Padding="0">
|
||||
Padding="1.5">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock
|
||||
@@ -175,7 +182,7 @@
|
||||
Text="{ext:Locale GameSpecificConfigurationHeader}"
|
||||
TextAlignment="Start"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Warning}" />
|
||||
Foreground="{DynamicResource CustomConfig}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Grid.Column="4"
|
||||
@@ -203,13 +210,23 @@
|
||||
<ui:SymbolIcon
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="-5,-5,0,0"
|
||||
Margin="-7.5,-7.5,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
FontSize="16"
|
||||
FontSize="18"
|
||||
Foreground="{DynamicResource FavoriteApplicationIconColor}"
|
||||
IsVisible="{Binding Favorite}"
|
||||
Symbol="StarFilled" />
|
||||
<ui:SymbolIcon
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="0,-7.5,-7.5,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
FontSize="18"
|
||||
Foreground="{DynamicResource CustomConfig}"
|
||||
IsVisible="{Binding HasIndependentConfiguration}"
|
||||
Symbol="SettingsFilled" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@@ -27,13 +27,6 @@
|
||||
Spacing="10">
|
||||
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGeneral}" />
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Vertical">
|
||||
<CheckBox IsChecked="{Binding EnableDiscordIntegration}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}"
|
||||
Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" />
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
<CheckBox
|
||||
IsEnabled="{Binding !IsGameTitleNotNull}"
|
||||
Opacity="{Binding PanelOpacity}"
|
||||
@@ -62,6 +55,13 @@
|
||||
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
<CheckBox IsChecked="{Binding EnableDiscordIntegration}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}"
|
||||
Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" />
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
<StackPanel
|
||||
Margin="0, 15, 0, 0"
|
||||
Orientation="Horizontal">
|
||||
@@ -101,7 +101,7 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
MinWidth="100">
|
||||
<ComboBoxItem>
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchOff}" />
|
||||
<TextBlock Text="{ext:Locale CommonOff}" />
|
||||
</ComboBoxItem>
|
||||
<ComboBoxItem>
|
||||
<TextBlock
|
||||
@@ -123,7 +123,7 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
MinWidth="100">
|
||||
<ComboBoxItem>
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorNever}" />
|
||||
<TextBlock Text="{ext:Locale Never}" />
|
||||
</ComboBoxItem>
|
||||
<ComboBoxItem>
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorOnIdle}" />
|
||||
@@ -146,7 +146,7 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
MinWidth="100">
|
||||
<ComboBoxItem>
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeAuto}" />
|
||||
<TextBlock Text="{ext:Locale CommonAuto}" />
|
||||
</ComboBoxItem>
|
||||
<ComboBoxItem>
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeLight}" />
|
||||
@@ -198,14 +198,13 @@
|
||||
<TextBox
|
||||
Name="GameDirPathBox"
|
||||
Margin="0"
|
||||
ToolTip.Tip="{ext:Locale AddGameDirBoxTooltip}"
|
||||
Watermark="{ext:Locale AddGameDirBoxTooltip}"
|
||||
VerticalAlignment="Stretch" />
|
||||
<Button
|
||||
Name="AddGameDirButton"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0"
|
||||
ToolTip.Tip="{ext:Locale AddGameDirTooltip}">
|
||||
Margin="10,0,0,0">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
@@ -213,8 +212,7 @@
|
||||
Name="RemoveGameDirButton"
|
||||
Grid.Column="2"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0"
|
||||
ToolTip.Tip="{ext:Locale RemoveGameDirTooltip}"
|
||||
Margin="5,0,0,0"
|
||||
Click="RemoveGameDirButton_OnClick">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralRemove}" />
|
||||
@@ -252,14 +250,13 @@
|
||||
<TextBox
|
||||
Name="AutoloadDirPathBox"
|
||||
Margin="0"
|
||||
ToolTip.Tip="{ext:Locale AddAutoloadDirBoxTooltip}"
|
||||
Watermark="{ext:Locale AddGameDirBoxTooltip}"
|
||||
VerticalAlignment="Stretch" />
|
||||
<Button
|
||||
Name="AddAutoloadDirButton"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0"
|
||||
ToolTip.Tip="{ext:Locale AddAutoloadDirTooltip}">
|
||||
Margin="10,0,0,0">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
@@ -267,8 +264,7 @@
|
||||
Name="RemoveAutoloadDirButton"
|
||||
Grid.Column="2"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0"
|
||||
ToolTip.Tip="{ext:Locale RemoveAutoloadDirTooltip}"
|
||||
Margin="5,0,0,0"
|
||||
Click="RemoveAutoloadDirButton_OnClick">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralRemove}" />
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center">
|
||||
<Label Content="{ext:Locale CommonSort}" VerticalAlignment="Center" />
|
||||
<ComboBox SelectedIndex="{Binding SortIndex}" Width="100">
|
||||
<ComboBoxItem>
|
||||
<Label
|
||||
|
||||
@@ -32,12 +32,6 @@
|
||||
Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}"
|
||||
TextChanged="TextBox_OnTextChanged"/>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="10, 5, 0, 5">
|
||||
<TextBlock
|
||||
Margin="10,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right"
|
||||
Text="{ext:Locale CommonSort}" />
|
||||
<DropDownButton
|
||||
Width="150"
|
||||
HorizontalAlignment="Right"
|
||||
@@ -102,12 +96,6 @@
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto,Auto" Name="NormalControls">
|
||||
<TextBox Name="SearchBoxNormal" Grid.Column="0" Margin="15, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" />
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="10, 5, 5, 5">
|
||||
<TextBlock
|
||||
Margin="10,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right"
|
||||
Text="{ext:Locale CommonSort}" />
|
||||
<DropDownButton
|
||||
Width="150"
|
||||
HorizontalAlignment="Right"
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
<Grid Name="Pages" IsVisible="False" Grid.Row="3">
|
||||
<settings:SettingsUiView Name="UiPage" />
|
||||
<settings:SettingsInputView Name="InputPage" />
|
||||
<settings:SettingsHotkeysView Name="HotkeysPage" />
|
||||
<settings:SettingsSystemView Name="SystemPage" />
|
||||
<settings:SettingsCPUView Name="CpuPage" />
|
||||
<settings:SettingsGraphicsView Name="GraphicsPage" />
|
||||
<settings:SettingsAudioView Name="AudioPage" />
|
||||
<settings:SettingsHotkeysView Name="HotkeysPage" />
|
||||
<settings:SettingsNetworkView Name="NetworkPage" />
|
||||
<settings:SettingsLoggingView Name="LoggingPage" />
|
||||
<settings:SettingsDebugView Name="DebugPage" />
|
||||
@@ -54,7 +54,7 @@
|
||||
IsSettingsVisible="False"
|
||||
Name="NavPanel"
|
||||
IsBackEnabled="False"
|
||||
Margin="10,10,10,0"
|
||||
Margin="10,0,10,0"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
OpenPaneLength="200">
|
||||
@@ -62,16 +62,17 @@
|
||||
<ui:NavigationViewItem
|
||||
IsSelected="True"
|
||||
Content="{ext:Locale SettingsTabGeneral}"
|
||||
Tag="UiPage"
|
||||
IconSource="New" />
|
||||
Tag="UiPage">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ui:FontIconSource
|
||||
FontFamily="avares://Ryujinx/Assets/Fonts#Segoe Fluent Icons"
|
||||
Glyph="{helpers:GlyphValueConverter Device}" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabInput}"
|
||||
Tag="InputPage"
|
||||
IconSource="Games" />
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabHotkeys}"
|
||||
Tag="HotkeysPage"
|
||||
IconSource="Keyboard" />
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabSystem}"
|
||||
Tag="SystemPage"
|
||||
@@ -93,6 +94,10 @@
|
||||
Content="{ext:Locale SettingsTabAudio}"
|
||||
IconSource="Audio"
|
||||
Tag="AudioPage" />
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabHotkeys}"
|
||||
Tag="HotkeysPage"
|
||||
IconSource="Keyboard" />
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabNetwork}"
|
||||
Tag="NetworkPage"
|
||||
@@ -103,8 +108,13 @@
|
||||
IconSource="Document" />
|
||||
<ui:NavigationViewItem
|
||||
Content="{ext:Locale SettingsTabDebug}"
|
||||
Tag="DebugPage"
|
||||
IconSource="Star" />
|
||||
Tag="DebugPage">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ui:FontIconSource
|
||||
FontFamily="avares://Ryujinx/Assets/Fonts#Segoe Fluent Icons"
|
||||
Glyph="{helpers:GlyphValueConverter Bug}" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
IsVisible="{Binding ShowDirtyHacks}"
|
||||
Content="Dirty Hacks"
|
||||
|
||||
Reference in New Issue
Block a user