diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 3100671e9..c17b06046 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -21,9 +21,9 @@ env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 RYUJINX_BASE_VERSION: "1.2" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary" - RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev" + RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing" RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx" - RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary" + RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases" RELEASE: 1 jobs: @@ -43,8 +43,8 @@ jobs: with: script: | github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}", + repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}", ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}', sha: context.sha }) @@ -64,7 +64,7 @@ jobs: | Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) | | Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) | | Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | - | macOS | [Canary macOS artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | + | macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }} omitBodyDuringUpdate: true @@ -196,16 +196,16 @@ jobs: body: | # Canary builds: - These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with. - + These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with. + | Platform | Artifact | |--|--| - | Windows 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip | - | Linux 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz | - | Linux ARM 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz | - | macOS | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz | + | Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) | + | Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) | + | Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | + | macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | - "**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}" + **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }} omitBodyDuringUpdate: true allowUpdates: true replacesArtifacts: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 59c31c71b..a24b58a5d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 RYUJINX_BASE_VERSION: "1.2" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release" - RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev" + RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing" RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx" RELEASE: 1 @@ -42,8 +42,8 @@ jobs: with: script: | github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}", + repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}", ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', sha: context.sha }) @@ -54,13 +54,13 @@ jobs: name: ${{ steps.version_info.outputs.build_version }} tag: ${{ steps.version_info.outputs.build_version }} body: | - # Regular builds: + # Stable builds: | Platform | Artifact | |--|--| - | Windows 64-bit | [Release Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) | - | Linux 64-bit | [Release Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) | - | Linux ARM 64-bit | [Release Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | - | macOS | [Release macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | + | Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) | + | Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) | + | Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | + | macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }} omitBodyDuringUpdate: true @@ -186,15 +186,15 @@ jobs: artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*" tag: ${{ steps.version_info.outputs.build_version }} body: | - # Regular builds: + # Stable builds: | Platform | Artifact | |--|--| - | Windows 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip | - | Linux 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz | - | Linux ARM 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz | - | macOS | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz | - - "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}" + | Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) | + | Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) | + | Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | + | macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | + + **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }} omitBodyDuringUpdate: true allowUpdates: true replacesArtifacts: true diff --git a/Ryujinx.sln b/Ryujinx.sln index 71d5f6dd9..e9f57df39 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -80,11 +80,16 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Generators", "src\Ryujinx.Horizon.Kernel.Generators\Ryujinx.Horizon.Kernel.Generators.csproj", "{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal", "src\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj", "{C08931FA-1191-417A-864F-3882D93E683B}" ProjectSection(ProjectDependencies) = postProject {A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E} = {A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal.SharpMetalExtensions", "src/Ryujinx.Graphics.Metal.SharpMetalExtensions\Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj", "{81EA598C-DBA1-40B0-8DA4-4796B78F2037}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig @@ -94,8 +99,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -265,6 +268,10 @@ Global {C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU {C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU + {81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Ryujinx.Graphics.GAL/IWindow.cs b/src/Ryujinx.Graphics.GAL/IWindow.cs index 12686cb28..48144f0b0 100644 --- a/src/Ryujinx.Graphics.GAL/IWindow.cs +++ b/src/Ryujinx.Graphics.GAL/IWindow.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Configuration; using System; namespace Ryujinx.Graphics.GAL diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs index 102fdb1bb..7a4836982 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL.Multithreading.Commands.Window; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; diff --git a/src/Ryujinx.Graphics.GAL/VSyncMode.cs b/src/Ryujinx.Graphics.GAL/VSyncMode.cs deleted file mode 100644 index c5794b8f7..000000000 --- a/src/Ryujinx.Graphics.GAL/VSyncMode.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.GAL -{ - public enum VSyncMode - { - Switch, - Unbounded, - Custom - } -} diff --git a/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/CAMetalLayerExtensions.cs b/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/CAMetalLayerExtensions.cs new file mode 100644 index 000000000..0d29a502b --- /dev/null +++ b/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/CAMetalLayerExtensions.cs @@ -0,0 +1,30 @@ +using SharpMetal; +using SharpMetal.ObjectiveCCore; +using SharpMetal.QuartzCore; +using System.Runtime.Versioning; +// ReSharper disable InconsistentNaming + +namespace Ryujinx.Graphics.Metal.SharpMetalExtensions +{ + [SupportedOSPlatform("macOS")] + public static class CAMetalLayerExtensions + { + private static readonly Selector sel_displaySyncEnabled = "displaySyncEnabled"; + private static readonly Selector sel_setDisplaySyncEnabled = "setDisplaySyncEnabled:"; + + private static readonly Selector sel_developerHUDProperties = "developerHUDProperties"; + private static readonly Selector sel_setDeveloperHUDProperties = "setDeveloperHUDProperties:"; + + public static bool IsDisplaySyncEnabled(this CAMetalLayer metalLayer) + => ObjectiveCRuntime.bool_objc_msgSend(metalLayer.NativePtr, sel_displaySyncEnabled); + + public static void SetDisplaySyncEnabled(this CAMetalLayer metalLayer, bool enabled) + => ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDisplaySyncEnabled, enabled); + + public static nint GetDeveloperHudProperties(this CAMetalLayer metalLayer) + => ObjectiveCRuntime.IntPtr_objc_msgSend(metalLayer.NativePtr, sel_developerHUDProperties); + + public static void SetDeveloperHudProperties(this CAMetalLayer metalLayer, nint dictionaryPointer) + => ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDeveloperHUDProperties, dictionaryPointer); + } +} diff --git a/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj b/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj new file mode 100644 index 000000000..9836063a3 --- /dev/null +++ b/src/Ryujinx.Graphics.Metal.SharpMetalExtensions/Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj @@ -0,0 +1,10 @@ + + + enable + enable + + + + + + diff --git a/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj b/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj index 02afb150a..364aa5a8b 100644 --- a/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj +++ b/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj @@ -5,12 +5,9 @@ - - - - - - + + + diff --git a/src/Ryujinx.Graphics.Metal/Window.cs b/src/Ryujinx.Graphics.Metal/Window.cs index 65a47d217..203a29ebc 100644 --- a/src/Ryujinx.Graphics.Metal/Window.cs +++ b/src/Ryujinx.Graphics.Metal/Window.cs @@ -1,10 +1,14 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Metal.Effects; +using Ryujinx.Graphics.Metal.SharpMetalExtensions; using SharpMetal.ObjectiveCCore; using SharpMetal.QuartzCore; using System; using System.Runtime.Versioning; +using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing; +using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter; namespace Ryujinx.Graphics.Metal { @@ -140,7 +144,15 @@ namespace Ryujinx.Graphics.Metal public void ChangeVSyncMode(VSyncMode vSyncMode) { - //_vSyncMode = vSyncMode; + switch (vSyncMode) + { + case VSyncMode.Unbounded: + _metalLayer.SetDisplaySyncEnabled(false); + break; + case VSyncMode.Switch: + _metalLayer.SetDisplaySyncEnabled(true); + break; + } } public void SetAntiAliasing(AntiAliasing effect) diff --git a/src/Ryujinx.Graphics.OpenGL/Window.cs b/src/Ryujinx.Graphics.OpenGL/Window.cs index 1dc8a51f6..8c35663ab 100644 --- a/src/Ryujinx.Graphics.OpenGL/Window.cs +++ b/src/Ryujinx.Graphics.OpenGL/Window.cs @@ -1,9 +1,12 @@ using OpenTK.Graphics.OpenGL; +using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.OpenGL.Effects; using Ryujinx.Graphics.OpenGL.Effects.Smaa; using Ryujinx.Graphics.OpenGL.Image; using System; +using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing; +using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter; namespace Ryujinx.Graphics.OpenGL { diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs index 3e8d3b375..d135d0076 100644 --- a/src/Ryujinx.Graphics.Vulkan/Window.cs +++ b/src/Ryujinx.Graphics.Vulkan/Window.cs @@ -1,9 +1,12 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan.Effects; using Silk.NET.Vulkan; using Silk.NET.Vulkan.Extensions.KHR; using System; using System.Linq; +using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing; +using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter; using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs index ca06ec0b8..807bb65e5 100644 --- a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs @@ -1,5 +1,8 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL; using System; +using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing; +using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.HLE/HLEConfiguration.cs b/src/Ryujinx.HLE/HLEConfiguration.cs index f75ead588..52c2b3da4 100644 --- a/src/Ryujinx.HLE/HLEConfiguration.cs +++ b/src/Ryujinx.HLE/HLEConfiguration.cs @@ -9,7 +9,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.UI; using System; -using VSyncMode = Ryujinx.Common.Configuration.VSyncMode; namespace Ryujinx.HLE { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs index 23bf8bcfc..935e9895e 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; -using VSyncMode = Ryujinx.Common.Configuration.VSyncMode; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.UI.Common/App/ApplicationData.cs b/src/Ryujinx.UI.Common/App/ApplicationData.cs index 657b9a022..ee5545dde 100644 --- a/src/Ryujinx.UI.Common/App/ApplicationData.cs +++ b/src/Ryujinx.UI.Common/App/ApplicationData.cs @@ -36,6 +36,8 @@ namespace Ryujinx.UI.App.Common public string Path { get; set; } public BlitStruct ControlHolder { get; set; } + public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0; + public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed); public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n") ?? LocalizedNever(); diff --git a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs index cb6467f5e..e78af3121 100644 --- a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs +++ b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs @@ -789,16 +789,15 @@ namespace Ryujinx.UI.App.Common using HttpClient httpClient = new HttpClient(); string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games"); ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData); - var evt = new LdnGameDataReceivedEventArgs + LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs { LdnData = ldnGameDataArray - }; - LdnGameDataReceived?.Invoke(null, evt); + }); } catch (Exception ex) { Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}"); - LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs() + LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs { LdnData = Array.Empty() }); @@ -806,7 +805,7 @@ namespace Ryujinx.UI.App.Common } else { - LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs() + LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs { LdnData = Array.Empty() }); diff --git a/src/Ryujinx.UI.Common/App/LdnGameData.cs b/src/Ryujinx.UI.Common/App/LdnGameData.cs index 6c784c991..f7a98e136 100644 --- a/src/Ryujinx.UI.Common/App/LdnGameData.cs +++ b/src/Ryujinx.UI.Common/App/LdnGameData.cs @@ -1,4 +1,7 @@ +using LibHac.Ns; +using System; using System.Collections.Generic; +using System.Linq; namespace Ryujinx.UI.App.Common { @@ -12,5 +15,28 @@ namespace Ryujinx.UI.App.Common public string Mode { get; set; } public string Status { get; set; } public IEnumerable Players { get; set; } + + public static Array GetArrayForApp( + IEnumerable receivedData, ref ApplicationControlProperty acp) + { + LibHac.Common.FixedArrays.Array8 communicationId = acp.LocalCommunicationId; + + return new Array(receivedData.Where(game => + communicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16)) + )); + } + + public class Array + { + private readonly LdnGameData[] _ldnDatas; + + internal Array(IEnumerable receivedData) + { + _ldnDatas = receivedData.ToArray(); + } + + public int PlayerCount => _ldnDatas.Sum(it => it.PlayerCount); + public int GameCount => _ldnDatas.Length; + } } } diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index f976ecdf1..9a9c1d226 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -311,7 +311,7 @@ namespace Ryujinx.Ava Device.VSyncMode = e.NewValue; Device.UpdateVSyncInterval(); } - _renderer.Window?.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)e.NewValue); + _renderer.Window?.ChangeVSyncMode(e.NewValue); _viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom); } @@ -1074,7 +1074,7 @@ namespace Ryujinx.Ava Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - _renderer.Window.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)Device.VSyncMode); + _renderer.Window.ChangeVSyncMode(Device.VSyncMode); while (_isActive) { diff --git a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs index 7982c17a6..2d26bd090 100644 --- a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs +++ b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs @@ -19,7 +19,7 @@ namespace Ryujinx.Ava.UI.Helpers AvaLogger.Sink = new LoggerAdapter(); } - private static RyuLogger.Log? GetLog(AvaLogLevel level) + private static RyuLogger.Log? GetLog(AvaLogLevel level, string area) { return level switch { @@ -27,7 +27,7 @@ namespace Ryujinx.Ava.UI.Helpers AvaLogLevel.Debug => RyuLogger.Debug, AvaLogLevel.Information => RyuLogger.Debug, AvaLogLevel.Warning => RyuLogger.Debug, - AvaLogLevel.Error => RyuLogger.Error, + AvaLogLevel.Error => area is "IME" ? RyuLogger.Debug : RyuLogger.Error, AvaLogLevel.Fatal => RyuLogger.Error, _ => throw new ArgumentOutOfRangeException(nameof(level), level, null), }; @@ -35,17 +35,17 @@ namespace Ryujinx.Ava.UI.Helpers public bool IsEnabled(AvaLogLevel level, string area) { - return GetLog(level) != null; + return GetLog(level, area) != null; } public void Log(AvaLogLevel level, string area, object source, string messageTemplate) { - GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, null)); + GetLog(level, area)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, null)); } public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues) { - GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, propertyValues)); + GetLog(level, area)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, propertyValues)); } private static string Format(AvaLogLevel level, string area, string template, object source, object[] v) diff --git a/src/Ryujinx/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs index cfc397c6e..578538d21 100644 --- a/src/Ryujinx/UI/Models/SaveModel.cs +++ b/src/Ryujinx/UI/Models/SaveModel.cs @@ -1,3 +1,4 @@ +using Gommon; using LibHac.Fs; using LibHac.Ncm; using Ryujinx.Ava.UI.ViewModels; @@ -47,7 +48,7 @@ namespace Ryujinx.Ava.UI.Models TitleId = info.ProgramId; UserId = info.UserId; - var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase)); + var appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.EqualsIgnoreCase(TitleIdString)); InGameList = appData != null; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 04881b58d..2f1800290 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -9,6 +9,7 @@ using Avalonia.Threading; using DynamicData; using DynamicData.Binding; using FluentAvalonia.UI.Controls; +using Gommon; using LibHac.Common; using LibHac.Ns; using Ryujinx.Ava.Common; @@ -124,8 +125,9 @@ namespace Ryujinx.Ava.UI.ViewModels public ApplicationData ListSelectedApplication; public ApplicationData GridSelectedApplication; - - public IEnumerable LastLdnGameData; + + // Key is Title ID + public SafeDictionary LdnData = []; // The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions. // For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left. diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 7504147b2..9feaaba9b 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -750,7 +750,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.ToFileFormat().SaveConfig(Program.ConfigurationPath); MainWindow.UpdateGraphicsConfig(); - MainWindow.MainWindowViewModel.VSyncModeSettingChanged(); + RyujinxApp.MainWindow.ViewModel.VSyncModeSettingChanged(); SaveSettingsEvent?.Invoke(); diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml index 8207f8e03..2c07bd8ef 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -17,8 +17,7 @@ Margin="7, 0" Height="25" Width="25" - ToolTip.Tip="{Binding Title}" - Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx_AntiAlias.png?assembly=Ryujinx.UI.Common" /> + ToolTip.Tip="{Binding Title}" /> { - var ldnGameDataArray = e.LdnData; - ViewModel.LastLdnGameData = ldnGameDataArray; + var ldnGameDataArray = e.LdnData.ToList(); + ViewModel.LdnData.Clear(); foreach (var application in ViewModel.Applications) { + ref var controlHolder = ref application.ControlHolder.Value; + + ViewModel.LdnData[application.IdString] = + LdnGameData.GetArrayForApp( + ldnGameDataArray, + ref controlHolder + ); + UpdateApplicationWithLdnData(application); } + ViewModel.RefreshView(); }); } private void UpdateApplicationWithLdnData(ApplicationData application) { - if (application.ControlHolder.ByteSpan.Length > 0 && ViewModel.LastLdnGameData != null) + if (application.HasControlHolder && ViewModel.LdnData.TryGetValue(application.IdString, out var ldnGameDatas)) { - IEnumerable ldnGameData = ViewModel.LastLdnGameData.Where(game => application.ControlHolder.Value.LocalCommunicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16))); - - application.PlayerCount = ldnGameData.Sum(game => game.PlayerCount); - application.GameCount = ldnGameData.Count(); + application.PlayerCount = ldnGameDatas.PlayerCount; + application.GameCount = ldnGameDatas.GameCount; } else {