Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4d804ed45e | ||
|
4a27d29412 | ||
|
5bd2c58ad6 | ||
|
cf4c78b9c8 | ||
|
52aa4b6c22 | ||
|
5a02433080 | ||
|
915a0f7173 | ||
|
0cc266ff19 | ||
|
9a1b74799d | ||
|
638f3761f3 | ||
|
193ca3c9a2 |
8
.github/assign/audio.yml
vendored
Normal file
8
.github/assign/audio.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- audio
|
11
.github/assign/cpu.yml
vendored
Normal file
11
.github/assign/cpu.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
- LDj3SNuD
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- cpu
|
4
.github/assign/global.yml
vendored
Normal file
4
.github/assign/global.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ryujinx/developers
|
10
.github/assign/gpu.yml
vendored
Normal file
10
.github/assign/gpu.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gpu
|
11
.github/assign/gui.yml
vendored
Normal file
11
.github/assign/gui.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ack77
|
||||
- emmauss
|
||||
- TSRBerry
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gui
|
11
.github/assign/horizon.yml
vendored
Normal file
11
.github/assign/horizon.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- Ack77
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- horizon
|
9
.github/assign/infra.yml
vendored
Normal file
9
.github/assign/infra.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- infra
|
33
.github/labeler.yml
vendored
Normal file
33
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
audio: 'src/Ryujinx.Audio*/**'
|
||||
|
||||
cpu:
|
||||
- 'src/ARMeilleure/**'
|
||||
- 'src/Ryujinx.Cpu/**'
|
||||
- 'src/Ryujinx.Memory/**'
|
||||
|
||||
gpu:
|
||||
- 'src/Ryujinx.Graphics.*/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
- 'src/Ryujinx.ShaderTools/**'
|
||||
|
||||
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
|
||||
'graphics-backend:vulkan':
|
||||
- 'src/Ryujinx.Graphics.Vulkan/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
|
||||
gui:
|
||||
- 'src/Ryujinx/**'
|
||||
- 'src/Ryujinx.Ui.Common/**'
|
||||
- 'src/Ryujinx.Ui.LocaleGenerator/**'
|
||||
- 'src/Ryujinx.Ava/**'
|
||||
|
||||
horizon:
|
||||
- 'src/Ryujinx.HLE/**'
|
||||
- 'src/Ryujinx.Horizon*/**'
|
||||
|
||||
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
|
||||
|
||||
infra:
|
||||
- '.github/**'
|
||||
- 'distribution/**'
|
||||
- 'Directory.Packages.props'
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -3,19 +3,13 @@ name: Build job
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
#push:
|
||||
# branches: [ master ]
|
||||
# paths-ignore:
|
||||
# - '.github/*'
|
||||
# - '.github/ISSUE_TEMPLATE/**'
|
||||
# - '*.yml'
|
||||
# - 'README.md'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency:
|
||||
|
54
.github/workflows/pr_triage.yml
vendored
Normal file
54
.github/workflows/pr_triage.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: "Pull Request Triage"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, ready_for_review]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Update labels based on changes
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
sync-labels: true
|
||||
dot: true
|
||||
|
||||
- name: Auto Assign [Audio]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/audio.yml'
|
||||
|
||||
- name: Auto Assign [CPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/cpu.yml'
|
||||
|
||||
- name: Auto Assign [GPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gpu.yml'
|
||||
|
||||
- name: Auto Assign [GUI]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gui.yml'
|
||||
|
||||
- name: Auto Assign [Horizon]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/horizon.yml'
|
||||
|
||||
- name: Auto Assign [Infra]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/infra.yml'
|
||||
|
||||
- name: Auto Assign [Global]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/global.yml'
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -6,9 +6,10 @@ on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency: release
|
||||
|
@@ -168,8 +168,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
Logger.StartPass(PassName.CodeGeneration);
|
||||
|
||||
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
|
||||
|
||||
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
||||
|
||||
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
||||
|
@@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
(uint)operation.GetSource(2).AsInt32());
|
||||
break;
|
||||
|
||||
case IntrinsicType.Vector128Unary:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(0));
|
||||
break;
|
||||
case IntrinsicType.Vector128Binary:
|
||||
GenerateVectorBinary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(0),
|
||||
operation.GetSource(1));
|
||||
break;
|
||||
case IntrinsicType.Vector128BinaryRd:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(1));
|
||||
break;
|
||||
|
||||
case IntrinsicType.VectorUnary:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
|
@@ -19,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
||||
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
||||
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
||||
|
@@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
ScalarTernaryShlRd,
|
||||
ScalarTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
Vector128BinaryRd,
|
||||
|
||||
VectorUnary,
|
||||
VectorUnaryBitwise,
|
||||
VectorUnaryByElem,
|
||||
@@ -50,9 +54,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
VectorTernaryShlRd,
|
||||
VectorTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
|
||||
GetRegister,
|
||||
SetRegister
|
||||
}
|
||||
|
@@ -746,6 +746,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
@@ -13,6 +13,7 @@ namespace ARMeilleure
|
||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||
|
||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||
public static bool UseArm64PmullIfAvailable { get; set; } = true;
|
||||
|
||||
public static bool UseSseIfAvailable { get; set; } = true;
|
||||
@@ -41,6 +42,7 @@ namespace ARMeilleure
|
||||
}
|
||||
|
||||
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
||||
internal static bool UseArm64Aes => UseArm64AesIfAvailable && Arm64HardwareCapabilities.SupportsAes;
|
||||
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
||||
|
||||
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
||||
|
@@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 4661; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 5281; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
@@ -40,6 +40,7 @@ using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -475,11 +476,20 @@ namespace Ryujinx.Ava
|
||||
_windowsMultimediaTimerResolution = null;
|
||||
}
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent();
|
||||
if (_rendererHost.EmbeddedWindow is EmbeddedWindowOpenGL openGlWindow)
|
||||
{
|
||||
// Try to bind the OpenGL context before calling the shutdown event.
|
||||
openGlWindow.MakeCurrent(false, false);
|
||||
|
||||
Device.DisposeGpu();
|
||||
Device.DisposeGpu();
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||
// Unbind context and destroy everything.
|
||||
openGlWindow.MakeCurrent(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Device.DisposeGpu();
|
||||
}
|
||||
}
|
||||
|
||||
private void HideCursorState_Changed(object sender, ReactiveEventArgs<HideCursorMode> state)
|
||||
@@ -930,7 +940,7 @@ namespace Ryujinx.Ava
|
||||
_gpuDoneEvent.Set();
|
||||
});
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||
}
|
||||
|
||||
public void UpdateStatus()
|
||||
@@ -1044,7 +1054,7 @@ namespace Ryujinx.Ava
|
||||
ScreenshotRequested = true;
|
||||
break;
|
||||
case KeyboardHotkeyState.ShowUi:
|
||||
_viewModel.ShowMenuAndStatusBar = true;
|
||||
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
||||
break;
|
||||
case KeyboardHotkeyState.Pause:
|
||||
if (_viewModel.IsPaused)
|
||||
|
@@ -123,7 +123,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
}
|
||||
else
|
||||
{
|
||||
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
|
||||
X11Window = PlatformHelper.CreateOpenGLWindow(new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false), 0, 0, 100, 100) as GLXWindow;
|
||||
}
|
||||
|
||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||
|
@@ -1,9 +1,11 @@
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
using SPB.Platform.WGL;
|
||||
@@ -18,8 +20,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
|
||||
public OpenGLContextBase Context { get; set; }
|
||||
|
||||
public EmbeddedWindowOpenGL() { }
|
||||
|
||||
protected override void OnWindowDestroying()
|
||||
{
|
||||
Context.Dispose();
|
||||
@@ -62,14 +62,21 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
Context.MakeCurrent(null);
|
||||
}
|
||||
|
||||
public void MakeCurrent()
|
||||
public void MakeCurrent(bool unbind = false, bool shouldThrow = true)
|
||||
{
|
||||
Context?.MakeCurrent(_window);
|
||||
}
|
||||
try
|
||||
{
|
||||
Context?.MakeCurrent(!unbind ? _window : null);
|
||||
}
|
||||
catch (ContextException e)
|
||||
{
|
||||
if (shouldThrow)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
public void MakeCurrent(NativeWindowBase window)
|
||||
{
|
||||
Context?.MakeCurrent(window);
|
||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void SwapBuffers()
|
||||
|
@@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool TryRead<T>(out T value) where T : unmanaged
|
||||
{
|
||||
int valueSize = Unsafe.SizeOf<T>();
|
||||
|
||||
if (valueSize > _input.Length)
|
||||
{
|
||||
value = default;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
value = MemoryMarshal.Cast<byte, T>(_input)[0];
|
||||
|
||||
_input = _input.Slice(valueSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> GetSpan(int size)
|
||||
{
|
||||
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
||||
|
@@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
|
||||
private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId)
|
||||
=> contentsDir.EnumerateDirectories($"{titleId}*", DirEnumOptions).FirstOrDefault();
|
||||
=> contentsDir.EnumerateDirectories(titleId, DirEnumOptions).FirstOrDefault();
|
||||
|
||||
private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId)
|
||||
{
|
||||
|
@@ -1,8 +1,29 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
[Service("hidbus")]
|
||||
class IHidbusServer : IpcService
|
||||
{
|
||||
public IHidbusServer(ServiceCtx context) { }
|
||||
|
||||
[CommandCmif(1)]
|
||||
// GetBusHandle(nn::hid::NpadIdType, nn::hidbus::BusType, nn::applet::AppletResourceUserId) -> (bool HasHandle, nn::hidbus::BusHandle)
|
||||
public ResultCode GetBusHandle(ServiceCtx context)
|
||||
{
|
||||
NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
|
||||
context.RequestData.BaseStream.Position += 4; // Padding
|
||||
BusType busType = (BusType)context.RequestData.ReadInt64();
|
||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||
|
||||
context.ResponseData.Write(false);
|
||||
context.ResponseData.BaseStream.Position += 7; // Padding
|
||||
context.ResponseData.WriteStruct(new BusHandle());
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadIdType, busType, appletResourceUserId });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct BusHandle
|
||||
{
|
||||
public int AbstractedPadId;
|
||||
public byte InternalIndex;
|
||||
public byte PlayerNumber;
|
||||
public byte BusTypeId;
|
||||
public byte IsValid;
|
||||
}
|
||||
}
|
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
public enum BusType : long
|
||||
{
|
||||
LeftJoyRail = 0,
|
||||
RightJoyRail = 1,
|
||||
InternalBus = 2
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
private const int MessageLengthLimit = 5000;
|
||||
|
||||
private readonly LogService _log;
|
||||
private readonly ulong _pid;
|
||||
private readonly ulong _pid;
|
||||
|
||||
private LogPacket _logPacket;
|
||||
|
||||
@@ -74,8 +74,12 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
|
||||
private bool LogImpl(ReadOnlySpan<byte> message)
|
||||
{
|
||||
SpanReader reader = new(message);
|
||||
LogPacketHeader header = reader.Read<LogPacketHeader>();
|
||||
SpanReader reader = new(message);
|
||||
|
||||
if (!reader.TryRead(out LogPacketHeader header))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
|
||||
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
|
||||
@@ -84,8 +88,10 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
|
||||
while (reader.Length > 0)
|
||||
{
|
||||
int type = ReadUleb128(ref reader);
|
||||
int size = ReadUleb128(ref reader);
|
||||
if (!TryReadUleb128(ref reader, out int type) || !TryReadUleb128(ref reader, out int size))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LogDataChunkKey key = (LogDataChunkKey)type;
|
||||
|
||||
@@ -101,15 +107,24 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
}
|
||||
else if (key == LogDataChunkKey.Line)
|
||||
{
|
||||
_logPacket.Line = reader.Read<int>();
|
||||
if (!reader.TryRead<int>(out _logPacket.Line))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.DropCount)
|
||||
{
|
||||
_logPacket.DropCount = reader.Read<long>();
|
||||
if (!reader.TryRead<long>(out _logPacket.DropCount))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.Time)
|
||||
{
|
||||
_logPacket.Time = reader.Read<long>();
|
||||
if (!reader.TryRead<long>(out _logPacket.Time))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.Message)
|
||||
{
|
||||
@@ -154,23 +169,25 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
return isTailPacket;
|
||||
}
|
||||
|
||||
private static int ReadUleb128(ref SpanReader reader)
|
||||
private static bool TryReadUleb128(ref SpanReader reader, out int result)
|
||||
{
|
||||
int result = 0;
|
||||
int count = 0;
|
||||
|
||||
result = 0;
|
||||
int count = 0;
|
||||
byte encoded;
|
||||
|
||||
do
|
||||
{
|
||||
encoded = reader.Read<byte>();
|
||||
if (!reader.TryRead<byte>(out encoded))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result += (encoded & 0x7F) << (7 * count);
|
||||
|
||||
count++;
|
||||
} while ((encoded & 0x80) != 0);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper
|
||||
{
|
||||
public static partial class FileAssociationHelper
|
||||
{
|
||||
private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" };
|
||||
private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" };
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
||||
private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
||||
|
||||
private const int SHCNE_ASSOCCHANGED = 0x8000000;
|
||||
private const int SHCNF_FLUSH = 0x1000;
|
||||
@@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper
|
||||
{
|
||||
string installKeyword = uninstall ? "uninstall" : "install";
|
||||
|
||||
if (!AreMimeTypesRegisteredLinux())
|
||||
if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
|
||||
{
|
||||
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
||||
string additionalArgs = !uninstall ? "--novendor" : "";
|
||||
@@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper
|
||||
return false;
|
||||
}
|
||||
|
||||
key.OpenSubKey(@"shell\open\command");
|
||||
var openCmd = key.OpenSubKey(@"shell\open\command");
|
||||
|
||||
string keyValue = (string)key.GetValue("");
|
||||
string keyValue = (string)openCmd.GetValue("");
|
||||
|
||||
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
|
||||
}
|
||||
@@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper
|
||||
|
||||
if (uninstall)
|
||||
{
|
||||
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
||||
if (!AreMimeTypesRegisteredWindows())
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
|
||||
Registry.CurrentUser.DeleteSubKeyTree(keyString);
|
||||
Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
|
||||
}
|
||||
else
|
||||
{
|
||||
RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
|
||||
using var key = Registry.CurrentUser.CreateSubKey(keyString);
|
||||
|
||||
if (key is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
key.CreateSubKey(@"shell\open\command");
|
||||
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
|
||||
using var openCmd = key.CreateSubKey(@"shell\open\command");
|
||||
openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
|
||||
|
||||
key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||
key.Close();
|
||||
}
|
||||
|
||||
// Notify Explorer the file association has been changed.
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper
|
||||
registered |= RegisterExtension(ext, uninstall);
|
||||
}
|
||||
|
||||
// Notify Explorer the file association has been changed.
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
return registered;
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,10 @@
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Input.HLE;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
using SPB.Platform.GLX;
|
||||
@@ -112,24 +114,30 @@ namespace Ryujinx.Ui
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
// Try to bind the OpenGL context before calling the shutdown event
|
||||
// Try to bind the OpenGL context before calling the shutdown event.
|
||||
try
|
||||
{
|
||||
_openGLContext?.MakeCurrent(_nativeWindow);
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (ContextException e)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to bind OpenGL context: {e}");
|
||||
}
|
||||
|
||||
Device?.DisposeGpu();
|
||||
NpadManager.Dispose();
|
||||
|
||||
// Unbind context and destroy everything
|
||||
// Unbind context and destroy everything.
|
||||
try
|
||||
{
|
||||
_openGLContext?.MakeCurrent(null);
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (ContextException e)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to unbind OpenGL context: {e}");
|
||||
}
|
||||
|
||||
_openGLContext?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user