From 76cfded3a47b0995388d596a25dc665dbe82c4d7 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 21 Feb 2025 20:31:21 -0600 Subject: [PATCH 1/3] Revert "EXPERIMENTAL: Metal backend (#441)" This reverts commit 85282310 --- Directory.Packages.props | 33 +- Ryujinx.sln | 32 +- .../Configuration/GraphicsBackend.cs | 2 - src/Ryujinx.Graphics.GAL/ComputeSize.cs | 18 - src/Ryujinx.Graphics.GAL/Format.cs | 78 - src/Ryujinx.Graphics.GAL/ShaderInfo.cs | 17 +- .../Threed/ComputeDraw/VtgAsComputeContext.cs | 19 +- .../Threed/ComputeDraw/VtgAsComputeState.cs | 18 + .../Shader/DiskCache/DiskCacheHostStorage.cs | 13 +- .../DiskCache/ParallelDiskCacheLoader.cs | 7 +- .../Shader/GpuAccessor.cs | 8 +- .../Shader/GpuAccessorBase.cs | 8 +- .../Shader/GpuChannelComputeState.cs | 11 - .../Shader/ShaderCache.cs | 54 +- .../Shader/ShaderInfoBuilder.cs | 51 +- src/Ryujinx.Graphics.Metal/Auto.cs | 146 - .../BackgroundResources.cs | 107 - src/Ryujinx.Graphics.Metal/BitMap.cs | 157 - src/Ryujinx.Graphics.Metal/BufferHolder.cs | 385 -- src/Ryujinx.Graphics.Metal/BufferManager.cs | 237 - .../BufferUsageBitmap.cs | 85 - src/Ryujinx.Graphics.Metal/CacheByRange.cs | 294 - .../CommandBufferEncoder.cs | 170 - .../CommandBufferPool.cs | 289 - .../CommandBufferScoped.cs | 43 - src/Ryujinx.Graphics.Metal/Constants.cs | 41 - src/Ryujinx.Graphics.Metal/CounterEvent.cs | 22 - .../DepthStencilCache.cs | 68 - .../DisposableBuffer.cs | 26 - .../DisposableSampler.cs | 22 - .../Effects/IPostProcessingEffect.cs | 10 - .../Effects/IScalingFilter.cs | 18 - .../EncoderResources.cs | 63 - src/Ryujinx.Graphics.Metal/EncoderState.cs | 206 - .../EncoderStateManager.cs | 1790 ------ src/Ryujinx.Graphics.Metal/EnumConversion.cs | 292 - src/Ryujinx.Graphics.Metal/FenceHolder.cs | 77 - src/Ryujinx.Graphics.Metal/FormatConverter.cs | 49 - src/Ryujinx.Graphics.Metal/FormatTable.cs | 196 - src/Ryujinx.Graphics.Metal/HardwareInfo.cs | 82 - src/Ryujinx.Graphics.Metal/HashTableSlim.cs | 143 - src/Ryujinx.Graphics.Metal/HelperShader.cs | 868 --- src/Ryujinx.Graphics.Metal/IdList.cs | 121 - src/Ryujinx.Graphics.Metal/ImageArray.cs | 74 - .../IndexBufferPattern.cs | 118 - .../IndexBufferState.cs | 103 - src/Ryujinx.Graphics.Metal/MetalRenderer.cs | 312 - .../MultiFenceHolder.cs | 262 - .../PersistentFlushBuffer.cs | 100 - src/Ryujinx.Graphics.Metal/Pipeline.cs | 877 --- src/Ryujinx.Graphics.Metal/Program.cs | 286 - .../ResourceBindingSegment.cs | 22 - .../ResourceLayoutBuilder.cs | 59 - .../Ryujinx.Graphics.Metal.csproj | 27 - src/Ryujinx.Graphics.Metal/SamplerHolder.cs | 90 - src/Ryujinx.Graphics.Metal/Shaders/Blit.metal | 43 - .../Shaders/BlitMs.metal | 45 - .../Shaders/ChangeBufferStride.metal | 72 - .../Shaders/ColorClear.metal | 38 - .../Shaders/ConvertD32S8ToD24S8.metal | 66 - .../Shaders/ConvertIndexBuffer.metal | 59 - .../Shaders/DepthBlit.metal | 27 - .../Shaders/DepthBlitMs.metal | 29 - .../Shaders/DepthStencilClear.metal | 42 - .../Shaders/StencilBlit.metal | 27 - .../Shaders/StencilBlitMs.metal | 29 - src/Ryujinx.Graphics.Metal/StagingBuffer.cs | 288 - .../State/DepthStencilUid.cs | 110 - .../State/PipelineState.cs | 341 -- .../State/PipelineUid.cs | 208 - src/Ryujinx.Graphics.Metal/StateCache.cs | 42 - src/Ryujinx.Graphics.Metal/StringHelper.cs | 30 - src/Ryujinx.Graphics.Metal/SyncManager.cs | 214 - src/Ryujinx.Graphics.Metal/Texture.cs | 654 -- src/Ryujinx.Graphics.Metal/TextureArray.cs | 93 - src/Ryujinx.Graphics.Metal/TextureBase.cs | 67 - src/Ryujinx.Graphics.Metal/TextureBuffer.cs | 132 - src/Ryujinx.Graphics.Metal/TextureCopy.cs | 265 - .../VertexBufferState.cs | 60 - src/Ryujinx.Graphics.Metal/Window.cs | 234 - .../CodeGen/Msl/CodeGenContext.cs | 108 - .../CodeGen/Msl/Declarations.cs | 577 -- .../CodeGen/Msl/Defaults.cs | 34 - .../CodeGen/Msl/HelperFunctions/FindLSB.metal | 5 - .../Msl/HelperFunctions/FindMSBS32.metal | 5 - .../Msl/HelperFunctions/FindMSBU32.metal | 6 - .../HelperFunctions/HelperFunctionNames.cs | 10 - .../CodeGen/Msl/HelperFunctions/Precise.metal | 14 - .../Msl/HelperFunctions/SwizzleAdd.metal | 7 - .../CodeGen/Msl/Instructions/InstGen.cs | 186 - .../CodeGen/Msl/Instructions/InstGenBallot.cs | 30 - .../Msl/Instructions/InstGenBarrier.cs | 15 - .../CodeGen/Msl/Instructions/InstGenCall.cs | 60 - .../CodeGen/Msl/Instructions/InstGenHelper.cs | 222 - .../CodeGen/Msl/Instructions/InstGenMemory.cs | 672 -- .../CodeGen/Msl/Instructions/InstGenVector.cs | 32 - .../CodeGen/Msl/Instructions/InstInfo.cs | 18 - .../CodeGen/Msl/Instructions/InstType.cs | 35 - .../CodeGen/Msl/Instructions/IoMap.cs | 83 - .../CodeGen/Msl/MslGenerator.cs | 286 - .../CodeGen/Msl/NumberFormatter.cs | 94 - .../CodeGen/Msl/OperandManager.cs | 176 - .../CodeGen/Msl/TypeConversion.cs | 93 - .../Ryujinx.Graphics.Shader.csproj | 7 - src/Ryujinx.Graphics.Shader/SamplerType.cs | 46 - .../StructuredIr/HelperFunctionsMask.cs | 7 - .../StructuredIr/StructuredProgram.cs | 17 +- .../StructuredIr/StructuredProgramContext.cs | 3 +- .../StructuredIr/StructuredProgramInfo.cs | 11 +- .../Translation/FeatureFlags.cs | 1 - .../Translation/ResourceManager.cs | 153 +- .../Translation/TargetApi.cs | 1 - .../Translation/TargetLanguage.cs | 2 +- .../Transforms/ForcePreciseEnable.cs | 2 - .../Translation/TranslatorContext.cs | 114 +- .../Ryujinx.Headless.SDL2.csproj | 72 + src/Ryujinx.ShaderTools/Program.cs | 2 +- src/Ryujinx/AppHost.cs | 176 +- src/Ryujinx/Assets/locales.json | 5449 +++++------------ src/Ryujinx/Headless/HeadlessRyujinx.cs | 467 +- src/Ryujinx/Headless/Windows/MetalWindow.cs | 47 - src/Ryujinx/Program.cs | 1 - src/Ryujinx/Ryujinx.csproj | 51 +- .../UI/Renderer/EmbeddedWindowMetal.cs | 19 - src/Ryujinx/UI/Renderer/RendererHost.cs | 64 +- .../UI/ViewModels/MainWindowViewModel.cs | 2 +- .../UI/ViewModels/SettingsViewModel.cs | 217 +- .../UI/Views/Settings/SettingsCPUView.axaml | 3 +- .../Views/Settings/SettingsGraphicsView.axaml | 17 +- .../UI/Windows/SettingsWindow.axaml.cs | 18 +- .../Configuration/ConfigurationState.cs | 19 +- 131 files changed, 2390 insertions(+), 19287 deletions(-) delete mode 100644 src/Ryujinx.Graphics.GAL/ComputeSize.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Auto.cs delete mode 100644 src/Ryujinx.Graphics.Metal/BackgroundResources.cs delete mode 100644 src/Ryujinx.Graphics.Metal/BitMap.cs delete mode 100644 src/Ryujinx.Graphics.Metal/BufferHolder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/BufferManager.cs delete mode 100644 src/Ryujinx.Graphics.Metal/BufferUsageBitmap.cs delete mode 100644 src/Ryujinx.Graphics.Metal/CacheByRange.cs delete mode 100644 src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/CommandBufferPool.cs delete mode 100644 src/Ryujinx.Graphics.Metal/CommandBufferScoped.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Constants.cs delete mode 100644 src/Ryujinx.Graphics.Metal/CounterEvent.cs delete mode 100644 src/Ryujinx.Graphics.Metal/DepthStencilCache.cs delete mode 100644 src/Ryujinx.Graphics.Metal/DisposableBuffer.cs delete mode 100644 src/Ryujinx.Graphics.Metal/DisposableSampler.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Effects/IPostProcessingEffect.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Effects/IScalingFilter.cs delete mode 100644 src/Ryujinx.Graphics.Metal/EncoderResources.cs delete mode 100644 src/Ryujinx.Graphics.Metal/EncoderState.cs delete mode 100644 src/Ryujinx.Graphics.Metal/EncoderStateManager.cs delete mode 100644 src/Ryujinx.Graphics.Metal/EnumConversion.cs delete mode 100644 src/Ryujinx.Graphics.Metal/FenceHolder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/FormatConverter.cs delete mode 100644 src/Ryujinx.Graphics.Metal/FormatTable.cs delete mode 100644 src/Ryujinx.Graphics.Metal/HardwareInfo.cs delete mode 100644 src/Ryujinx.Graphics.Metal/HashTableSlim.cs delete mode 100644 src/Ryujinx.Graphics.Metal/HelperShader.cs delete mode 100644 src/Ryujinx.Graphics.Metal/IdList.cs delete mode 100644 src/Ryujinx.Graphics.Metal/ImageArray.cs delete mode 100644 src/Ryujinx.Graphics.Metal/IndexBufferPattern.cs delete mode 100644 src/Ryujinx.Graphics.Metal/IndexBufferState.cs delete mode 100644 src/Ryujinx.Graphics.Metal/MetalRenderer.cs delete mode 100644 src/Ryujinx.Graphics.Metal/MultiFenceHolder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/PersistentFlushBuffer.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Pipeline.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Program.cs delete mode 100644 src/Ryujinx.Graphics.Metal/ResourceBindingSegment.cs delete mode 100644 src/Ryujinx.Graphics.Metal/ResourceLayoutBuilder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj delete mode 100644 src/Ryujinx.Graphics.Metal/SamplerHolder.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/Blit.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/ChangeBufferStride.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/ColorClear.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/ConvertD32S8ToD24S8.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/ConvertIndexBuffer.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/DepthBlit.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/DepthBlitMs.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/DepthStencilClear.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/StencilBlit.metal delete mode 100644 src/Ryujinx.Graphics.Metal/Shaders/StencilBlitMs.metal delete mode 100644 src/Ryujinx.Graphics.Metal/StagingBuffer.cs delete mode 100644 src/Ryujinx.Graphics.Metal/State/DepthStencilUid.cs delete mode 100644 src/Ryujinx.Graphics.Metal/State/PipelineState.cs delete mode 100644 src/Ryujinx.Graphics.Metal/State/PipelineUid.cs delete mode 100644 src/Ryujinx.Graphics.Metal/StateCache.cs delete mode 100644 src/Ryujinx.Graphics.Metal/StringHelper.cs delete mode 100644 src/Ryujinx.Graphics.Metal/SyncManager.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Texture.cs delete mode 100644 src/Ryujinx.Graphics.Metal/TextureArray.cs delete mode 100644 src/Ryujinx.Graphics.Metal/TextureBase.cs delete mode 100644 src/Ryujinx.Graphics.Metal/TextureBuffer.cs delete mode 100644 src/Ryujinx.Graphics.Metal/TextureCopy.cs delete mode 100644 src/Ryujinx.Graphics.Metal/VertexBufferState.cs delete mode 100644 src/Ryujinx.Graphics.Metal/Window.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Defaults.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindLSB.metal delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBS32.metal delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBallot.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBarrier.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenCall.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstInfo.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstType.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/IoMap.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/NumberFormatter.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs delete mode 100644 src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs create mode 100644 src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj delete mode 100644 src/Ryujinx/Headless/Windows/MetalWindow.cs delete mode 100644 src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 64867fc5b..34655164e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,13 +3,13 @@ true - - - - - - - + + + + + + + @@ -17,8 +17,7 @@ - - + @@ -26,7 +25,7 @@ - + @@ -42,17 +41,15 @@ - + - - - - - - - + + + + + diff --git a/Ryujinx.sln b/Ryujinx.sln index 9e197e85f..c3cb5a2b0 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -57,10 +57,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}" @@ -77,15 +81,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene 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 @@ -95,6 +90,8 @@ 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 @@ -209,6 +206,10 @@ Global {D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU {D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU {D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU + {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -217,6 +218,10 @@ Global {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU + {BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -249,16 +254,9 @@ Global {B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU {B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU {B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU - {C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {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 {4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = 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.Common/Configuration/GraphicsBackend.cs b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs index 9d399d560..e3b4f91b0 100644 --- a/src/Ryujinx.Common/Configuration/GraphicsBackend.cs +++ b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs @@ -6,9 +6,7 @@ namespace Ryujinx.Common.Configuration [JsonConverter(typeof(TypedStringEnumConverter))] public enum GraphicsBackend { - Auto, Vulkan, OpenGl, - Metal } } diff --git a/src/Ryujinx.Graphics.GAL/ComputeSize.cs b/src/Ryujinx.Graphics.GAL/ComputeSize.cs deleted file mode 100644 index c8d89c0fe..000000000 --- a/src/Ryujinx.Graphics.GAL/ComputeSize.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.GAL -{ - public readonly struct ComputeSize - { - public readonly static ComputeSize VtgAsCompute = new(32, 32, 1); - - public readonly int X; - public readonly int Y; - public readonly int Z; - - public ComputeSize(int x, int y, int z) - { - X = x; - Y = y; - Z = z; - } - } -} diff --git a/src/Ryujinx.Graphics.GAL/Format.cs b/src/Ryujinx.Graphics.GAL/Format.cs index b1eb68f72..17c42d2d4 100644 --- a/src/Ryujinx.Graphics.GAL/Format.cs +++ b/src/Ryujinx.Graphics.GAL/Format.cs @@ -339,84 +339,6 @@ namespace Ryujinx.Graphics.GAL return 1; } - /// - /// Get bytes per element for this format. - /// - /// Texture format - /// Byte size for an element of this format (pixel, vertex attribute, etc) - public static int GetBytesPerElement(this Format format) - { - int scalarSize = format.GetScalarSize(); - - switch (format) - { - case Format.R8G8Unorm: - case Format.R8G8Snorm: - case Format.R8G8Uint: - case Format.R8G8Sint: - case Format.R8G8Uscaled: - case Format.R8G8Sscaled: - case Format.R16G16Float: - case Format.R16G16Unorm: - case Format.R16G16Snorm: - case Format.R16G16Uint: - case Format.R16G16Sint: - case Format.R16G16Uscaled: - case Format.R16G16Sscaled: - case Format.R32G32Float: - case Format.R32G32Uint: - case Format.R32G32Sint: - case Format.R32G32Uscaled: - case Format.R32G32Sscaled: - return 2 * scalarSize; - - case Format.R8G8B8Unorm: - case Format.R8G8B8Snorm: - case Format.R8G8B8Uint: - case Format.R8G8B8Sint: - case Format.R8G8B8Uscaled: - case Format.R8G8B8Sscaled: - case Format.R16G16B16Float: - case Format.R16G16B16Unorm: - case Format.R16G16B16Snorm: - case Format.R16G16B16Uint: - case Format.R16G16B16Sint: - case Format.R16G16B16Uscaled: - case Format.R16G16B16Sscaled: - case Format.R32G32B32Float: - case Format.R32G32B32Uint: - case Format.R32G32B32Sint: - case Format.R32G32B32Uscaled: - case Format.R32G32B32Sscaled: - return 3 * scalarSize; - - case Format.R8G8B8A8Unorm: - case Format.R8G8B8A8Snorm: - case Format.R8G8B8A8Uint: - case Format.R8G8B8A8Sint: - case Format.R8G8B8A8Srgb: - case Format.R8G8B8A8Uscaled: - case Format.R8G8B8A8Sscaled: - case Format.B8G8R8A8Unorm: - case Format.B8G8R8A8Srgb: - case Format.R16G16B16A16Float: - case Format.R16G16B16A16Unorm: - case Format.R16G16B16A16Snorm: - case Format.R16G16B16A16Uint: - case Format.R16G16B16A16Sint: - case Format.R16G16B16A16Uscaled: - case Format.R16G16B16A16Sscaled: - case Format.R32G32B32A32Float: - case Format.R32G32B32A32Uint: - case Format.R32G32B32A32Sint: - case Format.R32G32B32A32Uscaled: - case Format.R32G32B32A32Sscaled: - return 4 * scalarSize; - } - - return scalarSize; - } - /// /// Checks if the texture format is a depth or depth-stencil format. /// diff --git a/src/Ryujinx.Graphics.GAL/ShaderInfo.cs b/src/Ryujinx.Graphics.GAL/ShaderInfo.cs index c7965a03d..2fd3227dc 100644 --- a/src/Ryujinx.Graphics.GAL/ShaderInfo.cs +++ b/src/Ryujinx.Graphics.GAL/ShaderInfo.cs @@ -4,22 +4,23 @@ namespace Ryujinx.Graphics.GAL { public int FragmentOutputMap { get; } public ResourceLayout ResourceLayout { get; } - public ComputeSize ComputeLocalSize { get; } public ProgramPipelineState? State { get; } public bool FromCache { get; set; } - public ShaderInfo( - int fragmentOutputMap, - ResourceLayout resourceLayout, - ComputeSize computeLocalSize, - ProgramPipelineState? state, - bool fromCache = false) + public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, ProgramPipelineState state, bool fromCache = false) { FragmentOutputMap = fragmentOutputMap; ResourceLayout = resourceLayout; - ComputeLocalSize = computeLocalSize; State = state; FromCache = fromCache; } + + public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, bool fromCache = false) + { + FragmentOutputMap = fragmentOutputMap; + ResourceLayout = resourceLayout; + State = null; + FromCache = fromCache; + } } } diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeContext.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeContext.cs index 15f1a4a33..eba1b6030 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeContext.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeContext.cs @@ -11,6 +11,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw /// class VtgAsComputeContext : IDisposable { + private const int DummyBufferSize = 16; + private readonly GpuContext _context; /// @@ -46,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw 1, 1, 1, - format.GetBytesPerElement(), + 1, format, DepthStencilMode.Depth, Target.TextureBuffer, @@ -519,6 +521,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write); } + /// + /// Gets the range for a dummy 16 bytes buffer, filled with zeros. + /// + /// Dummy buffer range + public BufferRange GetDummyBufferRange() + { + if (_dummyBuffer == BufferHandle.Null) + { + _dummyBuffer = _context.Renderer.CreateBuffer(DummyBufferSize, BufferAccess.DeviceMemory); + _context.Renderer.Pipeline.ClearBuffer(_dummyBuffer, 0, DummyBufferSize, 0); + } + + return new BufferRange(_dummyBuffer, 0, DummyBufferSize); + } + /// /// Gets the range for a sequential index buffer, with ever incrementing index values. /// diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs index 16a19debe..0d59275ff 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs @@ -147,6 +147,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw { _vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount); _vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0); + SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format); continue; } @@ -162,12 +163,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw { _vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount); _vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0); + SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format); continue; } int vbStride = vertexBuffer.UnpackStride(); ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count); + ulong oldVbSize = vbSize; + ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset(); int componentSize = format.GetScalarSize(); @@ -340,6 +344,20 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw return maxOutputVertices / verticesPerPrimitive; } + /// + /// Binds a dummy buffer as vertex buffer into a buffer texture. + /// + /// Shader resource binding reservations + /// Buffer texture index + /// Buffer texture format + private readonly void SetDummyBufferTexture(ResourceReservations reservations, int index, Format format) + { + ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format); + bufferTexture.SetStorage(_vacContext.GetDummyBufferRange()); + + _context.Renderer.Pipeline.SetTextureAndSampler(ShaderStage.Compute, reservations.GetVertexBufferTextureBinding(index), bufferTexture, null); + } + /// /// Binds a vertex buffer into a buffer texture. /// diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 4ef0caced..22ffe4812 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -324,11 +324,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache bool loadHostCache = header.CodeGenVersion == CodeGenVersion; - if (context.Capabilities.Api == TargetApi.Metal) - { - loadHostCache = false; - } - int programIndex = 0; DataEntry entry = new(); @@ -397,8 +392,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache context, shaders, specState.PipelineState, - specState.TransformFeedbackDescriptors != null, - specState.ComputeState.GetLocalSize()); + specState.TransformFeedbackDescriptors != null); IProgram hostProgram; @@ -635,10 +629,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache return; } - if (context.Capabilities.Api != TargetApi.Metal) - { - WriteHostCode(context, hostCode, program.Shaders, streams, timestamp); - } + WriteHostCode(context, hostCode, program.Shaders, streams, timestamp); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs index f8cb6c56b..ea79e41c9 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs @@ -494,12 +494,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache { ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length]; - ref GpuChannelComputeState computeState = ref compilation.SpecializationState.ComputeState; - - ShaderInfoBuilder shaderInfoBuilder = new( - _context, - compilation.SpecializationState.TransformFeedbackDescriptors != null, - computeLocalSize: computeState.GetLocalSize()); + ShaderInfoBuilder shaderInfoBuilder = new(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null); for (int index = 0; index < compilation.TranslatedStages.Length; index++) { diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index c7d86a47e..393584bd4 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Gpu.Shader private readonly GpuAccessorState _state; private readonly int _stageIndex; private readonly bool _compute; - private readonly bool _isOpenGL; + private readonly bool _isVulkan; private readonly bool _hasGeometryShader; private readonly bool _supportsQuads; @@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Shader _channel = channel; _state = state; _stageIndex = stageIndex; - _isOpenGL = context.Capabilities.Api == TargetApi.OpenGL; + _isVulkan = context.Capabilities.Api == TargetApi.Vulkan; _hasGeometryShader = hasGeometryShader; _supportsQuads = context.Capabilities.SupportsQuads; @@ -117,10 +117,10 @@ namespace Ryujinx.Graphics.Gpu.Shader public GpuGraphicsState QueryGraphicsState() { return _state.GraphicsState.CreateShaderGraphicsState( - _isOpenGL, + !_isVulkan, _supportsQuads, _hasGeometryShader, - !_isOpenGL || _state.GraphicsState.YNegateEnabled); + _isVulkan || _state.GraphicsState.YNegateEnabled); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs index 701ff764a..d89eebabf 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs @@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { int binding; - if (_context.Capabilities.Api != TargetApi.OpenGL) + if (_context.Capabilities.Api == TargetApi.Vulkan) { binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer"); } @@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { int binding; - if (_context.Capabilities.Api != TargetApi.OpenGL) + if (_context.Capabilities.Api == TargetApi.Vulkan) { if (count == 1) { @@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { int binding; - if (_context.Capabilities.Api != TargetApi.OpenGL) + if (_context.Capabilities.Api == TargetApi.Vulkan) { binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer"); } @@ -119,7 +119,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { int binding; - if (_context.Capabilities.Api != TargetApi.OpenGL) + if (_context.Capabilities.Api == TargetApi.Vulkan) { if (count == 1) { diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs index 720f7e796..d8cdbc348 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs @@ -1,5 +1,3 @@ -using Ryujinx.Graphics.GAL; - namespace Ryujinx.Graphics.Gpu.Shader { /// @@ -63,14 +61,5 @@ namespace Ryujinx.Graphics.Gpu.Shader SharedMemorySize = sharedMemorySize; HasUnalignedStorageBuffer = hasUnalignedStorageBuffer; } - - /// - /// Gets the local group size of the shader in a GAL compatible struct. - /// - /// Local group size - public ComputeSize GetLocalSize() - { - return new ComputeSize(LocalSizeX, LocalSizeY, LocalSizeZ); - } } } diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 476ae3d82..4fc66c4c0 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -117,7 +117,7 @@ namespace Ryujinx.Graphics.Gpu.Shader private static string GetDiskCachePath() { return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null - ? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId.ToLower(), "cache", "shader") + ? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId, "cache", "shader") : null; } @@ -204,7 +204,7 @@ namespace Ryujinx.Graphics.Gpu.Shader GpuChannelComputeState computeState, ulong gpuVa) { - if (_cpPrograms.TryGetValue(gpuVa, out CachedShaderProgram cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa)) + if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa)) { return cpShader; } @@ -223,11 +223,8 @@ namespace Ryujinx.Graphics.Gpu.Shader TranslatorContext translatorContext = DecodeComputeShader(gpuAccessor, _context.Capabilities.Api, gpuVa); TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false); - ShaderSource[] shaderSourcesArray = [CreateShaderSource(translatedShader.Program)]; - ShaderInfo info = ShaderInfoBuilder.BuildForCompute( - _context, - translatedShader.Program.Info, - computeState.GetLocalSize()); + ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) }; + ShaderInfo info = ShaderInfoBuilder.BuildForCompute(_context, translatedShader.Program.Info); IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info); cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader); @@ -254,8 +251,8 @@ namespace Ryujinx.Graphics.Gpu.Shader { channel.TextureManager.UpdateRenderTargets(); - RtControl rtControl = state.RtControl; - TextureMsaaMode msaaMode = state.RtMsaaMode; + var rtControl = state.RtControl; + var msaaMode = state.RtMsaaMode; pipeline.SamplesCount = msaaMode.SamplesInX() * msaaMode.SamplesInY(); @@ -265,7 +262,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { int rtIndex = rtControl.UnpackPermutationIndex(index); - RtColorState colorState = state.RtColorState[rtIndex]; + var colorState = state.RtColorState[rtIndex]; if (index >= count || colorState.Format == 0 || colorState.WidthOrStride == 0) { @@ -310,12 +307,12 @@ namespace Ryujinx.Graphics.Gpu.Shader ref GpuChannelGraphicsState graphicsState, ShaderAddresses addresses) { - if (_gpPrograms.TryGetValue(addresses, out CachedShaderProgram gpShaders) && IsShaderEqual(channel, ref poolState, ref graphicsState, gpShaders, addresses)) + if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, ref poolState, ref graphicsState, gpShaders, addresses)) { return gpShaders; } - if (_graphicsShaderCache.TryFind(channel, ref poolState, ref graphicsState, addresses, out gpShaders, out CachedGraphicsGuestCode cachedGuestCode)) + if (_graphicsShaderCache.TryFind(channel, ref poolState, ref graphicsState, addresses, out gpShaders, out var cachedGuestCode)) { _gpPrograms[addresses] = gpShaders; return gpShaders; @@ -368,7 +365,7 @@ namespace Ryujinx.Graphics.Gpu.Shader bool geometryToCompute = ShouldConvertGeometryToCompute(_context, geometryHasStore); CachedShaderStage[] shaders = new CachedShaderStage[Constants.ShaderStages + 1]; - List shaderSources = []; + List shaderSources = new(); TranslatorContext previousStage = null; ShaderInfoBuilder infoBuilder = new(_context, transformFeedbackDescriptors != null, vertexToCompute); @@ -428,8 +425,7 @@ namespace Ryujinx.Graphics.Gpu.Shader TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage; - (program, ShaderProgramInfo vacInfo) = lastInVertexPipeline.GenerateVertexPassthroughForCompute(); - infoBuilder.AddStageInfoVac(vacInfo); + program = lastInVertexPipeline.GenerateVertexPassthroughForCompute(); } else { @@ -534,9 +530,9 @@ namespace Ryujinx.Graphics.Gpu.Shader private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled) { ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language); - ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled); + ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled); - return new(_context.Renderer.CreateProgram([source], info), program.Info, context.GetResourceReservations()); + return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations()); } /// @@ -586,7 +582,7 @@ namespace Ryujinx.Graphics.Gpu.Shader for (int i = 0; i < Constants.TotalTransformFeedbackBuffers; i++) { - TfState tf = state.TfState[i]; + var tf = state.TfState[i]; descs[i] = new TransformFeedbackDescriptor( tf.BufferIndex, @@ -692,7 +688,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// The generated translator context public static TranslatorContext DecodeComputeShader(IGpuAccessor gpuAccessor, TargetApi api, ulong gpuVa) { - TranslationOptions options = CreateTranslationOptions(api, DefaultFlags | TranslationFlags.Compute); + var options = CreateTranslationOptions(api, DefaultFlags | TranslationFlags.Compute); return Translator.CreateContext(gpuVa, gpuAccessor, options); } @@ -709,7 +705,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// The generated translator context public static TranslatorContext DecodeGraphicsShader(IGpuAccessor gpuAccessor, TargetApi api, TranslationFlags flags, ulong gpuVa) { - TranslationOptions options = CreateTranslationOptions(api, flags); + var options = CreateTranslationOptions(api, flags); return Translator.CreateContext(gpuVa, gpuAccessor, options); } @@ -735,7 +731,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { ulong cb1DataAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(0, 1); - MemoryManager memoryManager = channel.MemoryManager; + var memoryManager = channel.MemoryManager; codeA ??= memoryManager.GetSpan(vertexA.Address, vertexA.Size).ToArray(); codeB ??= memoryManager.GetSpan(currentStage.Address, currentStage.Size).ToArray(); @@ -773,7 +769,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Compiled graphics shader code private static TranslatedShader TranslateShader(ShaderDumper dumper, GpuChannel channel, TranslatorContext context, byte[] code, bool asCompute) { - MemoryManager memoryManager = channel.MemoryManager; + var memoryManager = channel.MemoryManager; ulong cb1DataAddress = context.Stage == ShaderStage.Compute ? channel.BufferManager.GetComputeUniformBufferAddress(1) @@ -801,7 +797,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { if (address == MemoryManager.PteUnmapped || size == 0) { - return []; + return Array.Empty(); } return memoryManager.Physical.GetSpan(address, size).ToArray(); @@ -826,20 +822,16 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// Creates shader translation options with the requested graphics API and flags. - /// The shader language is chosen based on the current configuration and graphics API. + /// The shader language is choosen based on the current configuration and graphics API. /// /// Target graphics API /// Translation flags /// Translation options private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags) { - TargetLanguage lang = api switch - { - TargetApi.OpenGL => TargetLanguage.Glsl, - TargetApi.Vulkan => GraphicsConfig.EnableSpirvCompilationOnVulkan ? TargetLanguage.Spirv : TargetLanguage.Glsl, - TargetApi.Metal => TargetLanguage.Msl, - _ => throw new NotImplementedException() - }; + TargetLanguage lang = GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan + ? TargetLanguage.Spirv + : TargetLanguage.Glsl; return new TranslationOptions(lang, api, flags); } diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs index 8aa48e0ce..c74c612a5 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs @@ -22,7 +22,6 @@ namespace Ryujinx.Graphics.Gpu.Shader ResourceStages.Geometry; private readonly GpuContext _context; - private readonly ComputeSize _computeLocalSize; private int _fragmentOutputMap; @@ -40,11 +39,9 @@ namespace Ryujinx.Graphics.Gpu.Shader /// GPU context that owns the shaders that will be added to the builder /// Indicates if the graphics shader is used with transform feedback enabled /// Indicates that the vertex shader will be emulated on a compute shader - /// Indicates the local thread size for a compute shader - public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false, ComputeSize computeLocalSize = default) + public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false) { _context = context; - _computeLocalSize = computeLocalSize; _fragmentOutputMap = -1; @@ -98,7 +95,7 @@ namespace Ryujinx.Graphics.Gpu.Shader private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false) { AddDescriptor(stages, type, setIndex, start, count); - // AddUsage(stages, type, setIndex, start, count, write); + AddUsage(stages, type, setIndex, start, count, write); } /// @@ -162,25 +159,6 @@ namespace Ryujinx.Graphics.Gpu.Shader AddUsage(info.Images, stages, isImage: true); } - public void AddStageInfoVac(ShaderProgramInfo info) - { - ResourceStages stages = info.Stage switch - { - ShaderStage.Compute => ResourceStages.Compute, - ShaderStage.Vertex => ResourceStages.Vertex, - ShaderStage.TessellationControl => ResourceStages.TessellationControl, - ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation, - ShaderStage.Geometry => ResourceStages.Geometry, - ShaderStage.Fragment => ResourceStages.Fragment, - _ => ResourceStages.None, - }; - - AddUsage(info.CBuffers, stages, isStorage: false); - AddUsage(info.SBuffers, stages, isStorage: true); - AddUsage(info.Textures, stages, isImage: false); - AddUsage(info.Images, stages, isImage: true); - } - /// /// Adds a resource descriptor to the list of descriptors. /// @@ -383,7 +361,14 @@ namespace Ryujinx.Graphics.Gpu.Shader ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly()); - return new ShaderInfo(_fragmentOutputMap, resourceLayout, _computeLocalSize, pipeline, fromCache); + if (pipeline.HasValue) + { + return new ShaderInfo(_fragmentOutputMap, resourceLayout, pipeline.Value, fromCache); + } + else + { + return new ShaderInfo(_fragmentOutputMap, resourceLayout, fromCache); + } } /// @@ -393,16 +378,14 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Shaders from the disk cache /// Optional pipeline for background compilation /// Indicates if the graphics shader is used with transform feedback enabled - /// Compute local thread size /// Shader information public static ShaderInfo BuildForCache( GpuContext context, IEnumerable programs, ProgramPipelineState? pipeline, - bool tfEnabled, - ComputeSize computeLocalSize) + bool tfEnabled) { - ShaderInfoBuilder builder = new(context, tfEnabled, computeLocalSize: computeLocalSize); + ShaderInfoBuilder builder = new(context, tfEnabled); foreach (CachedShaderStage program in programs) { @@ -420,12 +403,11 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// GPU context that owns the shader /// Compute shader information - /// Compute local thread size /// True if the compute shader comes from a disk cache, false otherwise /// Shader information - public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, ComputeSize computeLocalSize, bool fromCache = false) + public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false) { - ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false, computeLocalSize: computeLocalSize); + ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false); builder.AddStageInfo(info); @@ -440,11 +422,10 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Indicates if the graphics shader is used with transform feedback enabled /// True if the compute shader comes from a disk cache, false otherwise /// Shader information - public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false) + public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false) { - ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute); + ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true); - builder.AddStageInfoVac(info2); builder.AddStageInfo(info, vertexAsCompute: true); return builder.Build(null, fromCache); diff --git a/src/Ryujinx.Graphics.Metal/Auto.cs b/src/Ryujinx.Graphics.Metal/Auto.cs deleted file mode 100644 index 7e79ecbc3..000000000 --- a/src/Ryujinx.Graphics.Metal/Auto.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - interface IAuto - { - bool HasCommandBufferDependency(CommandBufferScoped cbs); - - void IncrementReferenceCount(); - void DecrementReferenceCount(int cbIndex); - void DecrementReferenceCount(); - } - - interface IAutoPrivate : IAuto - { - void AddCommandBufferDependencies(CommandBufferScoped cbs); - } - - [SupportedOSPlatform("macos")] - class Auto : IAutoPrivate, IDisposable where T : IDisposable - { - private int _referenceCount; - private T _value; - - private readonly BitMap _cbOwnership; - private readonly MultiFenceHolder _waitable; - - private bool _disposed; - private bool _destroyed; - - public Auto(T value) - { - _referenceCount = 1; - _value = value; - _cbOwnership = new BitMap(CommandBufferPool.MaxCommandBuffers); - } - - public Auto(T value, MultiFenceHolder waitable) : this(value) - { - _waitable = waitable; - } - - public T Get(CommandBufferScoped cbs, int offset, int size, bool write = false) - { - _waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, write); - return Get(cbs); - } - - public T GetUnsafe() - { - return _value; - } - - public T Get(CommandBufferScoped cbs) - { - if (!_destroyed) - { - AddCommandBufferDependencies(cbs); - } - - return _value; - } - - public bool HasCommandBufferDependency(CommandBufferScoped cbs) - { - return _cbOwnership.IsSet(cbs.CommandBufferIndex); - } - - public bool HasRentedCommandBufferDependency(CommandBufferPool cbp) - { - return _cbOwnership.AnySet(); - } - - public void AddCommandBufferDependencies(CommandBufferScoped cbs) - { - // We don't want to add a reference to this object to the command buffer - // more than once, so if we detect that the command buffer already has ownership - // of this object, then we can just return without doing anything else. - if (_cbOwnership.Set(cbs.CommandBufferIndex)) - { - if (_waitable != null) - { - cbs.AddWaitable(_waitable); - } - - cbs.AddDependant(this); - } - } - - public bool TryIncrementReferenceCount() - { - int lastValue; - do - { - lastValue = _referenceCount; - - if (lastValue == 0) - { - return false; - } - } - while (Interlocked.CompareExchange(ref _referenceCount, lastValue + 1, lastValue) != lastValue); - - return true; - } - - public void IncrementReferenceCount() - { - if (Interlocked.Increment(ref _referenceCount) == 1) - { - Interlocked.Decrement(ref _referenceCount); - throw new InvalidOperationException("Attempted to increment the reference count of an object that was already destroyed."); - } - } - - public void DecrementReferenceCount(int cbIndex) - { - _cbOwnership.Clear(cbIndex); - DecrementReferenceCount(); - } - - public void DecrementReferenceCount() - { - if (Interlocked.Decrement(ref _referenceCount) == 0) - { - _value.Dispose(); - _value = default; - _destroyed = true; - } - - Debug.Assert(_referenceCount >= 0); - } - - public void Dispose() - { - if (!_disposed) - { - DecrementReferenceCount(); - _disposed = true; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/BackgroundResources.cs b/src/Ryujinx.Graphics.Metal/BackgroundResources.cs deleted file mode 100644 index e38b877a6..000000000 --- a/src/Ryujinx.Graphics.Metal/BackgroundResources.cs +++ /dev/null @@ -1,107 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class BackgroundResource : IDisposable - { - private readonly MetalRenderer _renderer; - - private CommandBufferPool _pool; - private PersistentFlushBuffer _flushBuffer; - - public BackgroundResource(MetalRenderer renderer) - { - _renderer = renderer; - } - - public CommandBufferPool GetPool() - { - if (_pool == null) - { - MTLCommandQueue queue = _renderer.BackgroundQueue; - _pool = new CommandBufferPool(queue, true); - _pool.Initialize(null); // TODO: Proper encoder factory for background render/compute - } - - return _pool; - } - - public PersistentFlushBuffer GetFlushBuffer() - { - _flushBuffer ??= new PersistentFlushBuffer(_renderer); - - return _flushBuffer; - } - - public void Dispose() - { - _pool?.Dispose(); - _flushBuffer?.Dispose(); - } - } - - [SupportedOSPlatform("macos")] - class BackgroundResources : IDisposable - { - private readonly MetalRenderer _renderer; - - private readonly Dictionary _resources; - - public BackgroundResources(MetalRenderer renderer) - { - _renderer = renderer; - - _resources = new Dictionary(); - } - - private void Cleanup() - { - lock (_resources) - { - foreach (KeyValuePair tuple in _resources) - { - if (!tuple.Key.IsAlive) - { - tuple.Value.Dispose(); - _resources.Remove(tuple.Key); - } - } - } - } - - public BackgroundResource Get() - { - Thread thread = Thread.CurrentThread; - - lock (_resources) - { - if (!_resources.TryGetValue(thread, out BackgroundResource resource)) - { - Cleanup(); - - resource = new BackgroundResource(_renderer); - - _resources[thread] = resource; - } - - return resource; - } - } - - public void Dispose() - { - lock (_resources) - { - foreach (BackgroundResource resource in _resources.Values) - { - resource.Dispose(); - } - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/BitMap.cs b/src/Ryujinx.Graphics.Metal/BitMap.cs deleted file mode 100644 index 4ddc438c1..000000000 --- a/src/Ryujinx.Graphics.Metal/BitMap.cs +++ /dev/null @@ -1,157 +0,0 @@ -namespace Ryujinx.Graphics.Metal -{ - readonly struct BitMap - { - public const int IntSize = 64; - - private const int IntShift = 6; - private const int IntMask = IntSize - 1; - - private readonly long[] _masks; - - public BitMap(int count) - { - _masks = new long[(count + IntMask) / IntSize]; - } - - public bool AnySet() - { - for (int i = 0; i < _masks.Length; i++) - { - if (_masks[i] != 0) - { - return true; - } - } - - return false; - } - - public bool IsSet(int bit) - { - int wordIndex = bit >> IntShift; - int wordBit = bit & IntMask; - - long wordMask = 1L << wordBit; - - return (_masks[wordIndex] & wordMask) != 0; - } - - public bool IsSet(int start, int end) - { - if (start == end) - { - return IsSet(start); - } - - int startIndex = start >> IntShift; - int startBit = start & IntMask; - long startMask = -1L << startBit; - - int endIndex = end >> IntShift; - int endBit = end & IntMask; - long endMask = (long)(ulong.MaxValue >> (IntMask - endBit)); - - if (startIndex == endIndex) - { - return (_masks[startIndex] & startMask & endMask) != 0; - } - - if ((_masks[startIndex] & startMask) != 0) - { - return true; - } - - for (int i = startIndex + 1; i < endIndex; i++) - { - if (_masks[i] != 0) - { - return true; - } - } - - if ((_masks[endIndex] & endMask) != 0) - { - return true; - } - - return false; - } - - public bool Set(int bit) - { - int wordIndex = bit >> IntShift; - int wordBit = bit & IntMask; - - long wordMask = 1L << wordBit; - - if ((_masks[wordIndex] & wordMask) != 0) - { - return false; - } - - _masks[wordIndex] |= wordMask; - - return true; - } - - public void SetRange(int start, int end) - { - if (start == end) - { - Set(start); - return; - } - - int startIndex = start >> IntShift; - int startBit = start & IntMask; - long startMask = -1L << startBit; - - int endIndex = end >> IntShift; - int endBit = end & IntMask; - long endMask = (long)(ulong.MaxValue >> (IntMask - endBit)); - - if (startIndex == endIndex) - { - _masks[startIndex] |= startMask & endMask; - } - else - { - _masks[startIndex] |= startMask; - - for (int i = startIndex + 1; i < endIndex; i++) - { - _masks[i] |= -1; - } - - _masks[endIndex] |= endMask; - } - } - - public void Clear(int bit) - { - int wordIndex = bit >> IntShift; - int wordBit = bit & IntMask; - - long wordMask = 1L << wordBit; - - _masks[wordIndex] &= ~wordMask; - } - - public void Clear() - { - for (int i = 0; i < _masks.Length; i++) - { - _masks[i] = 0; - } - } - - public void ClearInt(int start, int end) - { - for (int i = start; i <= end; i++) - { - _masks[i] = 0; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/BufferHolder.cs b/src/Ryujinx.Graphics.Metal/BufferHolder.cs deleted file mode 100644 index 630571658..000000000 --- a/src/Ryujinx.Graphics.Metal/BufferHolder.cs +++ /dev/null @@ -1,385 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class BufferHolder : IDisposable - { - private CacheByRange _cachedConvertedBuffers; - - public int Size { get; } - - private readonly IntPtr _map; - private readonly MetalRenderer _renderer; - private readonly Pipeline _pipeline; - - private readonly MultiFenceHolder _waitable; - private readonly Auto _buffer; - - private readonly ReaderWriterLockSlim _flushLock; - private FenceHolder _flushFence; - private int _flushWaiting; - - public BufferHolder(MetalRenderer renderer, Pipeline pipeline, MTLBuffer buffer, int size) - { - _renderer = renderer; - _pipeline = pipeline; - _map = buffer.Contents; - _waitable = new MultiFenceHolder(size); - _buffer = new Auto(new(buffer), _waitable); - - _flushLock = new ReaderWriterLockSlim(); - - Size = size; - } - - public Auto GetBuffer() - { - return _buffer; - } - - public Auto GetBuffer(bool isWrite) - { - if (isWrite) - { - SignalWrite(0, Size); - } - - return _buffer; - } - - public Auto GetBuffer(int offset, int size, bool isWrite) - { - if (isWrite) - { - SignalWrite(offset, size); - } - - return _buffer; - } - - public void SignalWrite(int offset, int size) - { - if (offset == 0 && size == Size) - { - _cachedConvertedBuffers.Clear(); - } - else - { - _cachedConvertedBuffers.ClearRange(offset, size); - } - } - - private void ClearFlushFence() - { - // Assumes _flushLock is held as writer. - - if (_flushFence != null) - { - if (_flushWaiting == 0) - { - _flushFence.Put(); - } - - _flushFence = null; - } - } - - private void WaitForFlushFence() - { - if (_flushFence == null) - { - return; - } - - // If storage has changed, make sure the fence has been reached so that the data is in place. - _flushLock.ExitReadLock(); - _flushLock.EnterWriteLock(); - - if (_flushFence != null) - { - FenceHolder fence = _flushFence; - Interlocked.Increment(ref _flushWaiting); - - // Don't wait in the lock. - - _flushLock.ExitWriteLock(); - - fence.Wait(); - - _flushLock.EnterWriteLock(); - - if (Interlocked.Decrement(ref _flushWaiting) == 0) - { - fence.Put(); - } - - _flushFence = null; - } - - // Assumes the _flushLock is held as reader, returns in same state. - _flushLock.ExitWriteLock(); - _flushLock.EnterReadLock(); - } - - public PinnedSpan GetData(int offset, int size) - { - _flushLock.EnterReadLock(); - - WaitForFlushFence(); - - Span result; - - if (_map != IntPtr.Zero) - { - result = GetDataStorage(offset, size); - - // Need to be careful here, the buffer can't be unmapped while the data is being used. - _buffer.IncrementReferenceCount(); - - _flushLock.ExitReadLock(); - - return PinnedSpan.UnsafeFromSpan(result, _buffer.DecrementReferenceCount); - } - - throw new InvalidOperationException("The buffer is not mapped"); - } - - public unsafe Span GetDataStorage(int offset, int size) - { - int mappingSize = Math.Min(size, Size - offset); - - if (_map != IntPtr.Zero) - { - return new Span((void*)(_map + offset), mappingSize); - } - - throw new InvalidOperationException("The buffer is not mapped."); - } - - public unsafe void SetData(int offset, ReadOnlySpan data, CommandBufferScoped? cbs = null, bool allowCbsWait = true) - { - int dataSize = Math.Min(data.Length, Size - offset); - if (dataSize == 0) - { - return; - } - - if (_map != IntPtr.Zero) - { - // If persistently mapped, set the data directly if the buffer is not currently in use. - bool isRented = _buffer.HasRentedCommandBufferDependency(_renderer.CommandBufferPool); - - // If the buffer is rented, take a little more time and check if the use overlaps this handle. - bool needsFlush = isRented && _waitable.IsBufferRangeInUse(offset, dataSize, false); - - if (!needsFlush) - { - WaitForFences(offset, dataSize); - - data[..dataSize].CopyTo(new Span((void*)(_map + offset), dataSize)); - - SignalWrite(offset, dataSize); - - return; - } - } - - if (cbs != null && - cbs.Value.Encoders.CurrentEncoderType == EncoderType.Render && - !(_buffer.HasCommandBufferDependency(cbs.Value) && - _waitable.IsBufferRangeInUse(cbs.Value.CommandBufferIndex, offset, dataSize))) - { - // If the buffer hasn't been used on the command buffer yet, try to preload the data. - // This avoids ending and beginning render passes on each buffer data upload. - - cbs = _pipeline.GetPreloadCommandBuffer(); - } - - if (allowCbsWait) - { - _renderer.BufferManager.StagingBuffer.PushData(_renderer.CommandBufferPool, cbs, this, offset, data); - } - else - { - bool rentCbs = cbs == null; - if (rentCbs) - { - cbs = _renderer.CommandBufferPool.Rent(); - } - - if (!_renderer.BufferManager.StagingBuffer.TryPushData(cbs.Value, this, offset, data)) - { - // Need to do a slow upload. - BufferHolder srcHolder = _renderer.BufferManager.Create(dataSize); - srcHolder.SetDataUnchecked(0, data); - - Auto srcBuffer = srcHolder.GetBuffer(); - Auto dstBuffer = this.GetBuffer(true); - - Copy(cbs.Value, srcBuffer, dstBuffer, 0, offset, dataSize); - - srcHolder.Dispose(); - } - - if (rentCbs) - { - cbs.Value.Dispose(); - } - } - } - - public unsafe void SetDataUnchecked(int offset, ReadOnlySpan data) - { - int dataSize = Math.Min(data.Length, Size - offset); - if (dataSize == 0) - { - return; - } - - if (_map != IntPtr.Zero) - { - data[..dataSize].CopyTo(new Span((void*)(_map + offset), dataSize)); - } - } - - public void SetDataUnchecked(int offset, ReadOnlySpan data) where T : unmanaged - { - SetDataUnchecked(offset, MemoryMarshal.AsBytes(data)); - } - - public static void Copy( - CommandBufferScoped cbs, - Auto src, - Auto dst, - int srcOffset, - int dstOffset, - int size, - bool registerSrcUsage = true) - { - MTLBuffer srcBuffer = registerSrcUsage ? src.Get(cbs, srcOffset, size).Value : src.GetUnsafe().Value; - MTLBuffer dstbuffer = dst.Get(cbs, dstOffset, size, true).Value; - - cbs.Encoders.EnsureBlitEncoder().CopyFromBuffer( - srcBuffer, - (ulong)srcOffset, - dstbuffer, - (ulong)dstOffset, - (ulong)size); - } - - public void WaitForFences() - { - _waitable.WaitForFences(); - } - - public void WaitForFences(int offset, int size) - { - _waitable.WaitForFences(offset, size); - } - - private bool BoundToRange(int offset, ref int size) - { - if (offset >= Size) - { - return false; - } - - size = Math.Min(Size - offset, size); - - return true; - } - - public Auto GetBufferI8ToI16(CommandBufferScoped cbs, int offset, int size) - { - if (!BoundToRange(offset, ref size)) - { - return null; - } - - I8ToI16CacheKey key = new(_renderer); - - if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder)) - { - holder = _renderer.BufferManager.Create((size * 2 + 3) & ~3); - - _renderer.HelperShader.ConvertI8ToI16(cbs, this, holder, offset, size); - - key.SetBuffer(holder.GetBuffer()); - - _cachedConvertedBuffers.Add(offset, size, key, holder); - } - - return holder.GetBuffer(); - } - - public Auto GetBufferTopologyConversion(CommandBufferScoped cbs, int offset, int size, IndexBufferPattern pattern, int indexSize) - { - if (!BoundToRange(offset, ref size)) - { - return null; - } - - TopologyConversionCacheKey key = new(_renderer, pattern, indexSize); - - if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder)) - { - // The destination index size is always I32. - - int indexCount = size / indexSize; - - int convertedCount = pattern.GetConvertedCount(indexCount); - - holder = _renderer.BufferManager.Create(convertedCount * 4); - - _renderer.HelperShader.ConvertIndexBuffer(cbs, this, holder, pattern, indexSize, offset, indexCount); - - key.SetBuffer(holder.GetBuffer()); - - _cachedConvertedBuffers.Add(offset, size, key, holder); - } - - return holder.GetBuffer(); - } - - public bool TryGetCachedConvertedBuffer(int offset, int size, ICacheKey key, out BufferHolder holder) - { - return _cachedConvertedBuffers.TryGetValue(offset, size, key, out holder); - } - - public void AddCachedConvertedBuffer(int offset, int size, ICacheKey key, BufferHolder holder) - { - _cachedConvertedBuffers.Add(offset, size, key, holder); - } - - public void AddCachedConvertedBufferDependency(int offset, int size, ICacheKey key, Dependency dependency) - { - _cachedConvertedBuffers.AddDependency(offset, size, key, dependency); - } - - public void RemoveCachedConvertedBuffer(int offset, int size, ICacheKey key) - { - _cachedConvertedBuffers.Remove(offset, size, key); - } - - - public void Dispose() - { - _pipeline.FlushCommandsIfWeightExceeding(_buffer, (ulong)Size); - - _buffer.Dispose(); - _cachedConvertedBuffers.Dispose(); - - _flushLock.EnterWriteLock(); - - ClearFlushFence(); - - _flushLock.ExitWriteLock(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/BufferManager.cs b/src/Ryujinx.Graphics.Metal/BufferManager.cs deleted file mode 100644 index 73a8d6fe7..000000000 --- a/src/Ryujinx.Graphics.Metal/BufferManager.cs +++ /dev/null @@ -1,237 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly struct ScopedTemporaryBuffer : IDisposable - { - private readonly BufferManager _bufferManager; - private readonly bool _isReserved; - - public readonly BufferRange Range; - public readonly BufferHolder Holder; - - public BufferHandle Handle => Range.Handle; - public int Offset => Range.Offset; - - public ScopedTemporaryBuffer(BufferManager bufferManager, BufferHolder holder, BufferHandle handle, int offset, int size, bool isReserved) - { - _bufferManager = bufferManager; - - Range = new BufferRange(handle, offset, size); - Holder = holder; - - _isReserved = isReserved; - } - - public void Dispose() - { - if (!_isReserved) - { - _bufferManager.Delete(Range.Handle); - } - } - } - - [SupportedOSPlatform("macos")] - class BufferManager : IDisposable - { - private readonly IdList _buffers; - - private readonly MTLDevice _device; - private readonly MetalRenderer _renderer; - private readonly Pipeline _pipeline; - - public int BufferCount { get; private set; } - - public StagingBuffer StagingBuffer { get; } - - public BufferManager(MTLDevice device, MetalRenderer renderer, Pipeline pipeline) - { - _device = device; - _renderer = renderer; - _pipeline = pipeline; - _buffers = new IdList(); - - StagingBuffer = new StagingBuffer(_renderer, this); - } - - public BufferHandle Create(nint pointer, int size) - { - // TODO: This is the wrong Metal method, we need no-copy which SharpMetal isn't giving us. - MTLBuffer buffer = _device.NewBuffer(pointer, (ulong)size, MTLResourceOptions.ResourceStorageModeShared); - - if (buffer == IntPtr.Zero) - { - Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create buffer with size 0x{size:X}, and pointer 0x{pointer:X}."); - - return BufferHandle.Null; - } - - BufferHolder holder = new(_renderer, _pipeline, buffer, size); - - BufferCount++; - - ulong handle64 = (uint)_buffers.Add(holder); - - return Unsafe.As(ref handle64); - } - - public BufferHandle CreateWithHandle(int size) - { - return CreateWithHandle(size, out _); - } - - public BufferHandle CreateWithHandle(int size, out BufferHolder holder) - { - holder = Create(size); - - if (holder == null) - { - return BufferHandle.Null; - } - - BufferCount++; - - ulong handle64 = (uint)_buffers.Add(holder); - - return Unsafe.As(ref handle64); - } - - public ScopedTemporaryBuffer ReserveOrCreate(CommandBufferScoped cbs, int size) - { - StagingBufferReserved? result = StagingBuffer.TryReserveData(cbs, size); - - if (result.HasValue) - { - return new ScopedTemporaryBuffer(this, result.Value.Buffer, StagingBuffer.Handle, result.Value.Offset, result.Value.Size, true); - } - else - { - // Create a temporary buffer. - BufferHandle handle = CreateWithHandle(size, out BufferHolder holder); - - return new ScopedTemporaryBuffer(this, holder, handle, 0, size, false); - } - } - - public BufferHolder Create(int size) - { - MTLBuffer buffer = _device.NewBuffer((ulong)size, MTLResourceOptions.ResourceStorageModeShared); - - if (buffer != IntPtr.Zero) - { - return new BufferHolder(_renderer, _pipeline, buffer, size); - } - - Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create buffer with size 0x{size:X}."); - - return null; - } - - public Auto GetBuffer(BufferHandle handle, bool isWrite, out int size) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - size = holder.Size; - return holder.GetBuffer(isWrite); - } - - size = 0; - return null; - } - - public Auto GetBuffer(BufferHandle handle, int offset, int size, bool isWrite) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - return holder.GetBuffer(offset, size, isWrite); - } - - return null; - } - - public Auto GetBuffer(BufferHandle handle, bool isWrite) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - return holder.GetBuffer(isWrite); - } - - return null; - } - - public Auto GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - return holder.GetBufferI8ToI16(cbs, offset, size); - } - - return null; - } - - public Auto GetBufferTopologyConversion(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, IndexBufferPattern pattern, int indexSize) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - return holder.GetBufferTopologyConversion(cbs, offset, size, pattern, indexSize); - } - - return null; - } - - public PinnedSpan GetData(BufferHandle handle, int offset, int size) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - return holder.GetData(offset, size); - } - - return new PinnedSpan(); - } - - public void SetData(BufferHandle handle, int offset, ReadOnlySpan data) where T : unmanaged - { - SetData(handle, offset, MemoryMarshal.Cast(data), null); - } - - public void SetData(BufferHandle handle, int offset, ReadOnlySpan data, CommandBufferScoped? cbs) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - holder.SetData(offset, data, cbs); - } - } - - public void Delete(BufferHandle handle) - { - if (TryGetBuffer(handle, out BufferHolder holder)) - { - holder.Dispose(); - _buffers.Remove((int)Unsafe.As(ref handle)); - } - } - - private bool TryGetBuffer(BufferHandle handle, out BufferHolder holder) - { - return _buffers.TryGetValue((int)Unsafe.As(ref handle), out holder); - } - - public void Dispose() - { - StagingBuffer.Dispose(); - - foreach (BufferHolder buffer in _buffers) - { - buffer.Dispose(); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/BufferUsageBitmap.cs b/src/Ryujinx.Graphics.Metal/BufferUsageBitmap.cs deleted file mode 100644 index 379e27407..000000000 --- a/src/Ryujinx.Graphics.Metal/BufferUsageBitmap.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - internal class BufferUsageBitmap - { - private readonly BitMap _bitmap; - private readonly int _size; - private readonly int _granularity; - private readonly int _bits; - private readonly int _writeBitOffset; - - private readonly int _intsPerCb; - private readonly int _bitsPerCb; - - public BufferUsageBitmap(int size, int granularity) - { - _size = size; - _granularity = granularity; - - // There are two sets of bits - one for read tracking, and the other for write. - int bits = (size + (granularity - 1)) / granularity; - _writeBitOffset = bits; - _bits = bits << 1; - - _intsPerCb = (_bits + (BitMap.IntSize - 1)) / BitMap.IntSize; - _bitsPerCb = _intsPerCb * BitMap.IntSize; - - _bitmap = new BitMap(_bitsPerCb * CommandBufferPool.MaxCommandBuffers); - } - - public void Add(int cbIndex, int offset, int size, bool write) - { - if (size == 0) - { - return; - } - - // Some usages can be out of bounds (vertex buffer on amd), so bound if necessary. - if (offset + size > _size) - { - size = _size - offset; - } - - int cbBase = cbIndex * _bitsPerCb + (write ? _writeBitOffset : 0); - int start = cbBase + offset / _granularity; - int end = cbBase + (offset + size - 1) / _granularity; - - _bitmap.SetRange(start, end); - } - - public bool OverlapsWith(int cbIndex, int offset, int size, bool write = false) - { - if (size == 0) - { - return false; - } - - int cbBase = cbIndex * _bitsPerCb + (write ? _writeBitOffset : 0); - int start = cbBase + offset / _granularity; - int end = cbBase + (offset + size - 1) / _granularity; - - return _bitmap.IsSet(start, end); - } - - public bool OverlapsWith(int offset, int size, bool write) - { - for (int i = 0; i < CommandBufferPool.MaxCommandBuffers; i++) - { - if (OverlapsWith(i, offset, size, write)) - { - return true; - } - } - - return false; - } - - public void Clear(int cbIndex) - { - _bitmap.ClearInt(cbIndex * _intsPerCb, (cbIndex + 1) * _intsPerCb - 1); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/CacheByRange.cs b/src/Ryujinx.Graphics.Metal/CacheByRange.cs deleted file mode 100644 index 2002eeba4..000000000 --- a/src/Ryujinx.Graphics.Metal/CacheByRange.cs +++ /dev/null @@ -1,294 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - interface ICacheKey : IDisposable - { - bool KeyEqual(ICacheKey other); - } - - [SupportedOSPlatform("macos")] - struct I8ToI16CacheKey : ICacheKey - { - // Used to notify the pipeline that bindings have invalidated on dispose. - // private readonly MetalRenderer _renderer; - // private Auto _buffer; - - public I8ToI16CacheKey(MetalRenderer renderer) - { - // _renderer = renderer; - // _buffer = null; - } - - public readonly bool KeyEqual(ICacheKey other) - { - return other is I8ToI16CacheKey; - } - - public readonly void SetBuffer(Auto buffer) - { - // _buffer = buffer; - } - - public readonly void Dispose() - { - // TODO: Tell pipeline buffer is dirty! - // _renderer.PipelineInternal.DirtyIndexBuffer(_buffer); - } - } - - [SupportedOSPlatform("macos")] - readonly struct TopologyConversionCacheKey : ICacheKey - { - private readonly IndexBufferPattern _pattern; - private readonly int _indexSize; - - // Used to notify the pipeline that bindings have invalidated on dispose. - // private readonly MetalRenderer _renderer; - // private Auto _buffer; - - public TopologyConversionCacheKey(MetalRenderer renderer, IndexBufferPattern pattern, int indexSize) - { - // _renderer = renderer; - // _buffer = null; - _pattern = pattern; - _indexSize = indexSize; - } - - public readonly bool KeyEqual(ICacheKey other) - { - return other is TopologyConversionCacheKey entry && - entry._pattern == _pattern && - entry._indexSize == _indexSize; - } - - public void SetBuffer(Auto buffer) - { - // _buffer = buffer; - } - - public readonly void Dispose() - { - // TODO: Tell pipeline buffer is dirty! - // _renderer.PipelineInternal.DirtyVertexBuffer(_buffer); - } - } - - [SupportedOSPlatform("macos")] - readonly struct Dependency - { - private readonly BufferHolder _buffer; - private readonly int _offset; - private readonly int _size; - private readonly ICacheKey _key; - - public Dependency(BufferHolder buffer, int offset, int size, ICacheKey key) - { - _buffer = buffer; - _offset = offset; - _size = size; - _key = key; - } - - public void RemoveFromOwner() - { - _buffer.RemoveCachedConvertedBuffer(_offset, _size, _key); - } - } - - [SupportedOSPlatform("macos")] - struct CacheByRange where T : IDisposable - { - private struct Entry - { - public readonly ICacheKey Key; - public readonly T Value; - public List DependencyList; - - public Entry(ICacheKey key, T value) - { - Key = key; - Value = value; - DependencyList = null; - } - - public readonly void InvalidateDependencies() - { - if (DependencyList != null) - { - foreach (Dependency dependency in DependencyList) - { - dependency.RemoveFromOwner(); - } - - DependencyList.Clear(); - } - } - } - - private Dictionary> _ranges; - - public void Add(int offset, int size, ICacheKey key, T value) - { - List entries = GetEntries(offset, size); - - entries.Add(new Entry(key, value)); - } - - public void AddDependency(int offset, int size, ICacheKey key, Dependency dependency) - { - List entries = GetEntries(offset, size); - - for (int i = 0; i < entries.Count; i++) - { - Entry entry = entries[i]; - - if (entry.Key.KeyEqual(key)) - { - if (entry.DependencyList == null) - { - entry.DependencyList = []; - entries[i] = entry; - } - - entry.DependencyList.Add(dependency); - - break; - } - } - } - - public void Remove(int offset, int size, ICacheKey key) - { - List entries = GetEntries(offset, size); - - for (int i = 0; i < entries.Count; i++) - { - Entry entry = entries[i]; - - if (entry.Key.KeyEqual(key)) - { - entries.RemoveAt(i--); - - DestroyEntry(entry); - } - } - - if (entries.Count == 0) - { - _ranges.Remove(PackRange(offset, size)); - } - } - - public bool TryGetValue(int offset, int size, ICacheKey key, out T value) - { - List entries = GetEntries(offset, size); - - foreach (Entry entry in entries) - { - if (entry.Key.KeyEqual(key)) - { - value = entry.Value; - - return true; - } - } - - value = default; - return false; - } - - public void Clear() - { - if (_ranges != null) - { - foreach (List entries in _ranges.Values) - { - foreach (Entry entry in entries) - { - DestroyEntry(entry); - } - } - - _ranges.Clear(); - _ranges = null; - } - } - - public readonly void ClearRange(int offset, int size) - { - if (_ranges != null && _ranges.Count > 0) - { - int end = offset + size; - - List toRemove = null; - - foreach (KeyValuePair> range in _ranges) - { - (int rOffset, int rSize) = UnpackRange(range.Key); - - int rEnd = rOffset + rSize; - - if (rEnd > offset && rOffset < end) - { - List entries = range.Value; - - foreach (Entry entry in entries) - { - DestroyEntry(entry); - } - - (toRemove ??= []).Add(range.Key); - } - } - - if (toRemove != null) - { - foreach (ulong range in toRemove) - { - _ranges.Remove(range); - } - } - } - } - - private List GetEntries(int offset, int size) - { - _ranges ??= new Dictionary>(); - - ulong key = PackRange(offset, size); - - if (!_ranges.TryGetValue(key, out List value)) - { - value = []; - _ranges.Add(key, value); - } - - return value; - } - - private static void DestroyEntry(Entry entry) - { - entry.Key.Dispose(); - entry.Value?.Dispose(); - entry.InvalidateDependencies(); - } - - private static ulong PackRange(int offset, int size) - { - return (uint)offset | ((ulong)size << 32); - } - - private static (int offset, int size) UnpackRange(ulong range) - { - return ((int)range, (int)(range >> 32)); - } - - public void Dispose() - { - Clear(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs b/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs deleted file mode 100644 index 3bc30e239..000000000 --- a/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs +++ /dev/null @@ -1,170 +0,0 @@ -using Ryujinx.Graphics.Metal; -using SharpMetal.Metal; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.Versioning; - -interface IEncoderFactory -{ - MTLRenderCommandEncoder CreateRenderCommandEncoder(); - MTLComputeCommandEncoder CreateComputeCommandEncoder(); -} - -/// -/// Tracks active encoder object for a command buffer. -/// -[SupportedOSPlatform("macos")] -class CommandBufferEncoder -{ - public EncoderType CurrentEncoderType { get; private set; } = EncoderType.None; - - public MTLBlitCommandEncoder BlitEncoder => new(CurrentEncoder.Value); - - public MTLComputeCommandEncoder ComputeEncoder => new(CurrentEncoder.Value); - - public MTLRenderCommandEncoder RenderEncoder => new(CurrentEncoder.Value); - - internal MTLCommandEncoder? CurrentEncoder { get; private set; } - - private MTLCommandBuffer _commandBuffer; - private IEncoderFactory _encoderFactory; - - public void Initialize(MTLCommandBuffer commandBuffer, IEncoderFactory encoderFactory) - { - _commandBuffer = commandBuffer; - _encoderFactory = encoderFactory; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MTLRenderCommandEncoder EnsureRenderEncoder() - { - if (CurrentEncoderType != EncoderType.Render) - { - return BeginRenderPass(); - } - - return RenderEncoder; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MTLBlitCommandEncoder EnsureBlitEncoder() - { - if (CurrentEncoderType != EncoderType.Blit) - { - return BeginBlitPass(); - } - - return BlitEncoder; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MTLComputeCommandEncoder EnsureComputeEncoder() - { - if (CurrentEncoderType != EncoderType.Compute) - { - return BeginComputePass(); - } - - return ComputeEncoder; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetRenderEncoder(out MTLRenderCommandEncoder encoder) - { - if (CurrentEncoderType != EncoderType.Render) - { - encoder = default; - return false; - } - - encoder = RenderEncoder; - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetBlitEncoder(out MTLBlitCommandEncoder encoder) - { - if (CurrentEncoderType != EncoderType.Blit) - { - encoder = default; - return false; - } - - encoder = BlitEncoder; - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetComputeEncoder(out MTLComputeCommandEncoder encoder) - { - if (CurrentEncoderType != EncoderType.Compute) - { - encoder = default; - return false; - } - - encoder = ComputeEncoder; - return true; - } - - public void EndCurrentPass() - { - if (CurrentEncoder != null) - { - switch (CurrentEncoderType) - { - case EncoderType.Blit: - BlitEncoder.EndEncoding(); - CurrentEncoder = null; - break; - case EncoderType.Compute: - ComputeEncoder.EndEncoding(); - CurrentEncoder = null; - break; - case EncoderType.Render: - RenderEncoder.EndEncoding(); - CurrentEncoder = null; - break; - default: - throw new InvalidOperationException(); - } - - CurrentEncoderType = EncoderType.None; - } - } - - private MTLRenderCommandEncoder BeginRenderPass() - { - EndCurrentPass(); - - MTLRenderCommandEncoder renderCommandEncoder = _encoderFactory.CreateRenderCommandEncoder(); - - CurrentEncoder = renderCommandEncoder; - CurrentEncoderType = EncoderType.Render; - - return renderCommandEncoder; - } - - private MTLBlitCommandEncoder BeginBlitPass() - { - EndCurrentPass(); - - using MTLBlitPassDescriptor descriptor = new(); - MTLBlitCommandEncoder blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor); - - CurrentEncoder = blitCommandEncoder; - CurrentEncoderType = EncoderType.Blit; - return blitCommandEncoder; - } - - private MTLComputeCommandEncoder BeginComputePass() - { - EndCurrentPass(); - - MTLComputeCommandEncoder computeCommandEncoder = _encoderFactory.CreateComputeCommandEncoder(); - - CurrentEncoder = computeCommandEncoder; - CurrentEncoderType = EncoderType.Compute; - return computeCommandEncoder; - } -} diff --git a/src/Ryujinx.Graphics.Metal/CommandBufferPool.cs b/src/Ryujinx.Graphics.Metal/CommandBufferPool.cs deleted file mode 100644 index d8c35b757..000000000 --- a/src/Ryujinx.Graphics.Metal/CommandBufferPool.cs +++ /dev/null @@ -1,289 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class CommandBufferPool : IDisposable - { - public const int MaxCommandBuffers = 16; - - private readonly int _totalCommandBuffers; - private readonly int _totalCommandBuffersMask; - private readonly MTLCommandQueue _queue; - private readonly Thread _owner; - private IEncoderFactory _defaultEncoderFactory; - - public bool OwnedByCurrentThread => _owner == Thread.CurrentThread; - - [SupportedOSPlatform("macos")] - private struct ReservedCommandBuffer - { - public bool InUse; - public bool InConsumption; - public int SubmissionCount; - public MTLCommandBuffer CommandBuffer; - public CommandBufferEncoder Encoders; - public FenceHolder Fence; - - public List Dependants; - public List Waitables; - - public void Use(MTLCommandQueue queue, IEncoderFactory stateManager) - { - MTLCommandBufferDescriptor descriptor = new(); -#if DEBUG - descriptor.ErrorOptions = MTLCommandBufferErrorOption.EncoderExecutionStatus; -#endif - - CommandBuffer = queue.CommandBuffer(descriptor); - Fence = new FenceHolder(CommandBuffer); - - Encoders.Initialize(CommandBuffer, stateManager); - - InUse = true; - } - - public void Initialize() - { - Dependants = []; - Waitables = []; - Encoders = new CommandBufferEncoder(); - } - } - - private readonly ReservedCommandBuffer[] _commandBuffers; - - private readonly int[] _queuedIndexes; - private int _queuedIndexesPtr; - private int _queuedCount; - private int _inUseCount; - - public CommandBufferPool(MTLCommandQueue queue, bool isLight = false) - { - _queue = queue; - _owner = Thread.CurrentThread; - - _totalCommandBuffers = isLight ? 2 : MaxCommandBuffers; - _totalCommandBuffersMask = _totalCommandBuffers - 1; - - _commandBuffers = new ReservedCommandBuffer[_totalCommandBuffers]; - - _queuedIndexes = new int[_totalCommandBuffers]; - _queuedIndexesPtr = 0; - _queuedCount = 0; - } - - public void Initialize(IEncoderFactory encoderFactory) - { - _defaultEncoderFactory = encoderFactory; - - for (int i = 0; i < _totalCommandBuffers; i++) - { - _commandBuffers[i].Initialize(); - WaitAndDecrementRef(i); - } - } - - public void AddDependant(int cbIndex, IAuto dependant) - { - dependant.IncrementReferenceCount(); - _commandBuffers[cbIndex].Dependants.Add(dependant); - } - - public void AddWaitable(MultiFenceHolder waitable) - { - lock (_commandBuffers) - { - for (int i = 0; i < _totalCommandBuffers; i++) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[i]; - - if (entry.InConsumption) - { - AddWaitable(i, waitable); - } - } - } - } - - public void AddInUseWaitable(MultiFenceHolder waitable) - { - lock (_commandBuffers) - { - for (int i = 0; i < _totalCommandBuffers; i++) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[i]; - - if (entry.InUse) - { - AddWaitable(i, waitable); - } - } - } - } - - public void AddWaitable(int cbIndex, MultiFenceHolder waitable) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex]; - if (waitable.AddFence(cbIndex, entry.Fence)) - { - entry.Waitables.Add(waitable); - } - } - - public bool IsFenceOnRentedCommandBuffer(FenceHolder fence) - { - lock (_commandBuffers) - { - for (int i = 0; i < _totalCommandBuffers; i++) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[i]; - - if (entry.InUse && entry.Fence == fence) - { - return true; - } - } - } - - return false; - } - - public FenceHolder GetFence(int cbIndex) - { - return _commandBuffers[cbIndex].Fence; - } - - public int GetSubmissionCount(int cbIndex) - { - return _commandBuffers[cbIndex].SubmissionCount; - } - - private int FreeConsumed(bool wait) - { - int freeEntry = 0; - - while (_queuedCount > 0) - { - int index = _queuedIndexes[_queuedIndexesPtr]; - - ref ReservedCommandBuffer entry = ref _commandBuffers[index]; - - if (wait || !entry.InConsumption || entry.Fence.IsSignaled()) - { - WaitAndDecrementRef(index); - - wait = false; - freeEntry = index; - - _queuedCount--; - _queuedIndexesPtr = (_queuedIndexesPtr + 1) % _totalCommandBuffers; - } - else - { - break; - } - } - - return freeEntry; - } - - public CommandBufferScoped ReturnAndRent(CommandBufferScoped cbs) - { - Return(cbs); - return Rent(); - } - - public CommandBufferScoped Rent() - { - lock (_commandBuffers) - { - int cursor = FreeConsumed(_inUseCount + _queuedCount == _totalCommandBuffers); - - for (int i = 0; i < _totalCommandBuffers; i++) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[cursor]; - - if (!entry.InUse && !entry.InConsumption) - { - entry.Use(_queue, _defaultEncoderFactory); - - _inUseCount++; - - return new CommandBufferScoped(this, entry.CommandBuffer, entry.Encoders, cursor); - } - - cursor = (cursor + 1) & _totalCommandBuffersMask; - } - } - - throw new InvalidOperationException($"Out of command buffers (In use: {_inUseCount}, queued: {_queuedCount}, total: {_totalCommandBuffers})"); - } - - public void Return(CommandBufferScoped cbs) - { - // Ensure the encoder is committed. - cbs.Encoders.EndCurrentPass(); - - lock (_commandBuffers) - { - int cbIndex = cbs.CommandBufferIndex; - - ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex]; - - Debug.Assert(entry.InUse); - Debug.Assert(entry.CommandBuffer.NativePtr == cbs.CommandBuffer.NativePtr); - entry.InUse = false; - entry.InConsumption = true; - entry.SubmissionCount++; - _inUseCount--; - - MTLCommandBuffer commandBuffer = entry.CommandBuffer; - commandBuffer.Commit(); - - int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers; - _queuedIndexes[ptr] = cbIndex; - _queuedCount++; - } - } - - private void WaitAndDecrementRef(int cbIndex) - { - ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex]; - - if (entry.InConsumption) - { - entry.Fence.Wait(); - entry.InConsumption = false; - } - - foreach (IAuto dependant in entry.Dependants) - { - dependant.DecrementReferenceCount(cbIndex); - } - - foreach (MultiFenceHolder waitable in entry.Waitables) - { - waitable.RemoveFence(cbIndex); - waitable.RemoveBufferUses(cbIndex); - } - - entry.Dependants.Clear(); - entry.Waitables.Clear(); - entry.Fence?.Dispose(); - } - - public void Dispose() - { - for (int i = 0; i < _totalCommandBuffers; i++) - { - WaitAndDecrementRef(i); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/CommandBufferScoped.cs b/src/Ryujinx.Graphics.Metal/CommandBufferScoped.cs deleted file mode 100644 index 822f69b46..000000000 --- a/src/Ryujinx.Graphics.Metal/CommandBufferScoped.cs +++ /dev/null @@ -1,43 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly struct CommandBufferScoped : IDisposable - { - private readonly CommandBufferPool _pool; - public MTLCommandBuffer CommandBuffer { get; } - public CommandBufferEncoder Encoders { get; } - public int CommandBufferIndex { get; } - - public CommandBufferScoped(CommandBufferPool pool, MTLCommandBuffer commandBuffer, CommandBufferEncoder encoders, int commandBufferIndex) - { - _pool = pool; - CommandBuffer = commandBuffer; - Encoders = encoders; - CommandBufferIndex = commandBufferIndex; - } - - public void AddDependant(IAuto dependant) - { - _pool.AddDependant(CommandBufferIndex, dependant); - } - - public void AddWaitable(MultiFenceHolder waitable) - { - _pool.AddWaitable(CommandBufferIndex, waitable); - } - - public FenceHolder GetFence() - { - return _pool.GetFence(CommandBufferIndex); - } - - public void Dispose() - { - _pool?.Return(this); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Constants.cs b/src/Ryujinx.Graphics.Metal/Constants.cs deleted file mode 100644 index 43baf722a..000000000 --- a/src/Ryujinx.Graphics.Metal/Constants.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Ryujinx.Graphics.Metal -{ - static class Constants - { - public const int MaxShaderStages = 5; - public const int MaxVertexBuffers = 16; - public const int MaxUniformBuffersPerStage = 18; - public const int MaxStorageBuffersPerStage = 16; - public const int MaxTexturesPerStage = 64; - public const int MaxImagesPerStage = 16; - - public const int MaxUniformBufferBindings = MaxUniformBuffersPerStage * MaxShaderStages; - public const int MaxStorageBufferBindings = MaxStorageBuffersPerStage * MaxShaderStages; - public const int MaxTextureBindings = MaxTexturesPerStage * MaxShaderStages; - public const int MaxImageBindings = MaxImagesPerStage * MaxShaderStages; - public const int MaxColorAttachments = 8; - public const int MaxViewports = 16; - // TODO: Check this value - public const int MaxVertexAttributes = 31; - - public const int MinResourceAlignment = 16; - - // Must match constants set in shader generation - public const uint ZeroBufferIndex = MaxVertexBuffers; - public const uint BaseSetIndex = MaxVertexBuffers + 1; - - public const uint ConstantBuffersIndex = BaseSetIndex; - public const uint StorageBuffersIndex = BaseSetIndex + 1; - public const uint TexturesIndex = BaseSetIndex + 2; - public const uint ImagesIndex = BaseSetIndex + 3; - - public const uint ConstantBuffersSetIndex = 0; - public const uint StorageBuffersSetIndex = 1; - public const uint TexturesSetIndex = 2; - public const uint ImagesSetIndex = 3; - - public const uint MaximumBufferArgumentTableEntries = 31; - - public const uint MaximumExtraSets = MaximumBufferArgumentTableEntries - ImagesIndex; - } -} diff --git a/src/Ryujinx.Graphics.Metal/CounterEvent.cs b/src/Ryujinx.Graphics.Metal/CounterEvent.cs deleted file mode 100644 index 46b04997e..000000000 --- a/src/Ryujinx.Graphics.Metal/CounterEvent.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.Metal -{ - class CounterEvent : ICounterEvent - { - public CounterEvent() - { - Invalid = false; - } - - public bool Invalid { get; set; } - public bool ReserveForHostAccess() - { - return true; - } - - public void Flush() { } - - public void Dispose() { } - } -} diff --git a/src/Ryujinx.Graphics.Metal/DepthStencilCache.cs b/src/Ryujinx.Graphics.Metal/DepthStencilCache.cs deleted file mode 100644 index 47d996010..000000000 --- a/src/Ryujinx.Graphics.Metal/DepthStencilCache.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Ryujinx.Graphics.Metal.State; -using SharpMetal.Metal; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class DepthStencilCache : StateCache - { - private readonly MTLDevice _device; - - public DepthStencilCache(MTLDevice device) - { - _device = device; - } - - protected override DepthStencilUid GetHash(DepthStencilUid descriptor) - { - return descriptor; - } - - protected override MTLDepthStencilState CreateValue(DepthStencilUid descriptor) - { - // Create descriptors - - ref StencilUid frontUid = ref descriptor.FrontFace; - - using MTLStencilDescriptor frontFaceStencil = new() - { - StencilFailureOperation = frontUid.StencilFailureOperation, - DepthFailureOperation = frontUid.DepthFailureOperation, - DepthStencilPassOperation = frontUid.DepthStencilPassOperation, - StencilCompareFunction = frontUid.StencilCompareFunction, - ReadMask = frontUid.ReadMask, - WriteMask = frontUid.WriteMask - }; - - ref StencilUid backUid = ref descriptor.BackFace; - - using MTLStencilDescriptor backFaceStencil = new() - { - StencilFailureOperation = backUid.StencilFailureOperation, - DepthFailureOperation = backUid.DepthFailureOperation, - DepthStencilPassOperation = backUid.DepthStencilPassOperation, - StencilCompareFunction = backUid.StencilCompareFunction, - ReadMask = backUid.ReadMask, - WriteMask = backUid.WriteMask - }; - - MTLDepthStencilDescriptor mtlDescriptor = new() - { - DepthCompareFunction = descriptor.DepthCompareFunction, - DepthWriteEnabled = descriptor.DepthWriteEnabled - }; - - if (descriptor.StencilTestEnabled) - { - mtlDescriptor.BackFaceStencil = backFaceStencil; - mtlDescriptor.FrontFaceStencil = frontFaceStencil; - } - - using (mtlDescriptor) - { - return _device.NewDepthStencilState(mtlDescriptor); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/DisposableBuffer.cs b/src/Ryujinx.Graphics.Metal/DisposableBuffer.cs deleted file mode 100644 index a2d2247c4..000000000 --- a/src/Ryujinx.Graphics.Metal/DisposableBuffer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly struct DisposableBuffer : IDisposable - { - public MTLBuffer Value { get; } - - public DisposableBuffer(MTLBuffer buffer) - { - Value = buffer; - } - - public void Dispose() - { - if (Value != IntPtr.Zero) - { - Value.SetPurgeableState(MTLPurgeableState.Empty); - Value.Dispose(); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/DisposableSampler.cs b/src/Ryujinx.Graphics.Metal/DisposableSampler.cs deleted file mode 100644 index ba041be89..000000000 --- a/src/Ryujinx.Graphics.Metal/DisposableSampler.cs +++ /dev/null @@ -1,22 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly struct DisposableSampler : IDisposable - { - public MTLSamplerState Value { get; } - - public DisposableSampler(MTLSamplerState sampler) - { - Value = sampler; - } - - public void Dispose() - { - Value.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Effects/IPostProcessingEffect.cs b/src/Ryujinx.Graphics.Metal/Effects/IPostProcessingEffect.cs deleted file mode 100644 index d575d521f..000000000 --- a/src/Ryujinx.Graphics.Metal/Effects/IPostProcessingEffect.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Metal.Effects -{ - internal interface IPostProcessingEffect : IDisposable - { - const int LocalGroupSize = 64; - Texture Run(Texture view, int width, int height); - } -} diff --git a/src/Ryujinx.Graphics.Metal/Effects/IScalingFilter.cs b/src/Ryujinx.Graphics.Metal/Effects/IScalingFilter.cs deleted file mode 100644 index 19f1a3c3d..000000000 --- a/src/Ryujinx.Graphics.Metal/Effects/IScalingFilter.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System; - -namespace Ryujinx.Graphics.Metal.Effects -{ - internal interface IScalingFilter : IDisposable - { - float Level { get; set; } - void Run( - Texture view, - Texture destinationTexture, - Format format, - int width, - int height, - Extents2D source, - Extents2D destination); - } -} diff --git a/src/Ryujinx.Graphics.Metal/EncoderResources.cs b/src/Ryujinx.Graphics.Metal/EncoderResources.cs deleted file mode 100644 index 8b856c1ce..000000000 --- a/src/Ryujinx.Graphics.Metal/EncoderResources.cs +++ /dev/null @@ -1,63 +0,0 @@ -using SharpMetal.Metal; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Metal -{ - public struct RenderEncoderBindings - { - public List Resources = []; - public List VertexBuffers = []; - public List FragmentBuffers = []; - - public RenderEncoderBindings() { } - - public readonly void Clear() - { - Resources.Clear(); - VertexBuffers.Clear(); - FragmentBuffers.Clear(); - } - } - - public struct ComputeEncoderBindings - { - public List Resources = []; - public List Buffers = []; - - public ComputeEncoderBindings() { } - - public readonly void Clear() - { - Resources.Clear(); - Buffers.Clear(); - } - } - - public struct BufferResource - { - public MTLBuffer Buffer; - public ulong Offset; - public ulong Binding; - - public BufferResource(MTLBuffer buffer, ulong offset, ulong binding) - { - Buffer = buffer; - Offset = offset; - Binding = binding; - } - } - - public struct Resource - { - public MTLResource MtlResource; - public MTLResourceUsage ResourceUsage; - public MTLRenderStages Stages; - - public Resource(MTLResource resource, MTLResourceUsage resourceUsage, MTLRenderStages stages) - { - MtlResource = resource; - ResourceUsage = resourceUsage; - Stages = stages; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/EncoderState.cs b/src/Ryujinx.Graphics.Metal/EncoderState.cs deleted file mode 100644 index 64c50d71b..000000000 --- a/src/Ryujinx.Graphics.Metal/EncoderState.cs +++ /dev/null @@ -1,206 +0,0 @@ -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Metal.State; -using Ryujinx.Graphics.Shader; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [Flags] - enum DirtyFlags - { - None = 0, - RenderPipeline = 1 << 0, - ComputePipeline = 1 << 1, - DepthStencil = 1 << 2, - DepthClamp = 1 << 3, - DepthBias = 1 << 4, - CullMode = 1 << 5, - FrontFace = 1 << 6, - StencilRef = 1 << 7, - Viewports = 1 << 8, - Scissors = 1 << 9, - Uniforms = 1 << 10, - Storages = 1 << 11, - Textures = 1 << 12, - Images = 1 << 13, - - ArgBuffers = Uniforms | Storages | Textures | Images, - - RenderAll = RenderPipeline | DepthStencil | DepthClamp | DepthBias | CullMode | FrontFace | StencilRef | Viewports | Scissors | ArgBuffers, - ComputeAll = ComputePipeline | ArgBuffers, - All = RenderAll | ComputeAll, - } - - record struct BufferRef - { - public Auto Buffer; - public BufferRange? Range; - - public BufferRef(Auto buffer) - { - Buffer = buffer; - } - - public BufferRef(Auto buffer, ref BufferRange range) - { - Buffer = buffer; - Range = range; - } - } - - record struct TextureRef - { - public ShaderStage Stage; - public TextureBase Storage; - public Auto Sampler; - public Format ImageFormat; - - public TextureRef(ShaderStage stage, TextureBase storage, Auto sampler) - { - Stage = stage; - Storage = storage; - Sampler = sampler; - } - } - - record struct ImageRef - { - public ShaderStage Stage; - public Texture Storage; - - public ImageRef(ShaderStage stage, Texture storage) - { - Stage = stage; - Storage = storage; - } - } - - struct PredrawState - { - public MTLCullMode CullMode; - public DepthStencilUid DepthStencilUid; - public PrimitiveTopology Topology; - public MTLViewport[] Viewports; - } - - struct RenderTargetCopy - { - public MTLScissorRect[] Scissors; - public Texture DepthStencil; - public Texture[] RenderTargets; - } - - [SupportedOSPlatform("macos")] - class EncoderState - { - public Program RenderProgram = null; - public Program ComputeProgram = null; - - public PipelineState Pipeline; - public DepthStencilUid DepthStencilUid; - - public readonly record struct ArrayRef(ShaderStage Stage, T Array); - - public readonly BufferRef[] UniformBufferRefs = new BufferRef[Constants.MaxUniformBufferBindings]; - public readonly BufferRef[] StorageBufferRefs = new BufferRef[Constants.MaxStorageBufferBindings]; - public readonly TextureRef[] TextureRefs = new TextureRef[Constants.MaxTextureBindings * 2]; - public readonly ImageRef[] ImageRefs = new ImageRef[Constants.MaxImageBindings * 2]; - - public ArrayRef[] TextureArrayRefs = []; - public ArrayRef[] ImageArrayRefs = []; - - public ArrayRef[] TextureArrayExtraRefs = []; - public ArrayRef[] ImageArrayExtraRefs = []; - - public IndexBufferState IndexBuffer = default; - - public MTLDepthClipMode DepthClipMode = MTLDepthClipMode.Clip; - - public float DepthBias; - public float SlopeScale; - public float Clamp; - - public int BackRefValue = 0; - public int FrontRefValue = 0; - - public PrimitiveTopology Topology = PrimitiveTopology.Triangles; - public MTLCullMode CullMode = MTLCullMode.None; - public MTLWinding Winding = MTLWinding.CounterClockwise; - public bool CullBoth = false; - - public MTLViewport[] Viewports = new MTLViewport[Constants.MaxViewports]; - public MTLScissorRect[] Scissors = new MTLScissorRect[Constants.MaxViewports]; - - // Changes to attachments take recreation! - public Texture DepthStencil; - public Texture[] RenderTargets = new Texture[Constants.MaxColorAttachments]; - public ITexture PreMaskDepthStencil = default; - public ITexture[] PreMaskRenderTargets; - public bool FramebufferUsingColorWriteMask; - - public Array8 StoredBlend; - public ColorF BlendColor = new(); - - public readonly VertexBufferState[] VertexBuffers = new VertexBufferState[Constants.MaxVertexBuffers]; - public readonly VertexAttribDescriptor[] VertexAttribs = new VertexAttribDescriptor[Constants.MaxVertexAttributes]; - // Dirty flags - public DirtyFlags Dirty = DirtyFlags.None; - - // Only to be used for present - public bool ClearLoadAction = false; - - public RenderEncoderBindings RenderEncoderBindings = new(); - public ComputeEncoderBindings ComputeEncoderBindings = new(); - - public EncoderState() - { - Pipeline.Initialize(); - DepthStencilUid.DepthCompareFunction = MTLCompareFunction.Always; - } - - public RenderTargetCopy InheritForClear(EncoderState other, bool depth, int singleIndex = -1) - { - // Inherit render target related information without causing a render encoder split. - - RenderTargetCopy oldState = new() - { - Scissors = other.Scissors, - RenderTargets = other.RenderTargets, - DepthStencil = other.DepthStencil - }; - - Scissors = other.Scissors; - RenderTargets = other.RenderTargets; - DepthStencil = other.DepthStencil; - - Pipeline.ColorBlendAttachmentStateCount = other.Pipeline.ColorBlendAttachmentStateCount; - Pipeline.Internal.ColorBlendState = other.Pipeline.Internal.ColorBlendState; - Pipeline.DepthStencilFormat = other.Pipeline.DepthStencilFormat; - - ref Array8 blendStates = ref Pipeline.Internal.ColorBlendState; - - // Mask out irrelevant attachments. - for (int i = 0; i < blendStates.Length; i++) - { - if (depth || (singleIndex != -1 && singleIndex != i)) - { - blendStates[i].WriteMask = MTLColorWriteMask.None; - } - } - - return oldState; - } - - public void Restore(RenderTargetCopy copy) - { - Scissors = copy.Scissors; - RenderTargets = copy.RenderTargets; - DepthStencil = copy.DepthStencil; - - Pipeline.Internal.ResetColorState(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs deleted file mode 100644 index 7901e5a52..000000000 --- a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs +++ /dev/null @@ -1,1790 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Metal.State; -using Ryujinx.Graphics.Shader; -using SharpMetal.Metal; -using System; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using BufferAssignment = Ryujinx.Graphics.GAL.BufferAssignment; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - struct EncoderStateManager : IDisposable - { - private const int ArrayGrowthSize = 16; - - private readonly MTLDevice _device; - private readonly Pipeline _pipeline; - private readonly BufferManager _bufferManager; - - private readonly DepthStencilCache _depthStencilCache; - private readonly MTLDepthStencilState _defaultState; - - private readonly EncoderState _mainState = new(); - private EncoderState _currentState; - - public readonly IndexBufferState IndexBuffer => _currentState.IndexBuffer; - public readonly PrimitiveTopology Topology => _currentState.Topology; - public readonly Texture[] RenderTargets => _currentState.RenderTargets; - public readonly Texture DepthStencil => _currentState.DepthStencil; - public readonly ComputeSize ComputeLocalSize => _currentState.ComputeProgram.ComputeLocalSize; - - // RGBA32F is the biggest format - private const int ZeroBufferSize = 4 * 4; - private readonly BufferHandle _zeroBuffer; - - public unsafe EncoderStateManager(MTLDevice device, BufferManager bufferManager, Pipeline pipeline) - { - _device = device; - _pipeline = pipeline; - _bufferManager = bufferManager; - - _depthStencilCache = new(device); - _currentState = _mainState; - - _defaultState = _depthStencilCache.GetOrCreate(_currentState.DepthStencilUid); - - // Zero buffer - byte[] zeros = new byte[ZeroBufferSize]; - fixed (byte* ptr = zeros) - { - _zeroBuffer = _bufferManager.Create((IntPtr)ptr, ZeroBufferSize); - } - } - - public readonly void Dispose() - { - _depthStencilCache.Dispose(); - } - - private readonly void SignalDirty(DirtyFlags flags) - { - _currentState.Dirty |= flags; - } - - public readonly void SignalRenderDirty() - { - SignalDirty(DirtyFlags.RenderAll); - } - - public readonly void SignalComputeDirty() - { - SignalDirty(DirtyFlags.ComputeAll); - } - - public EncoderState SwapState(EncoderState state, DirtyFlags flags = DirtyFlags.All) - { - _currentState = state ?? _mainState; - - SignalDirty(flags); - - return _mainState; - } - - public PredrawState SavePredrawState() - { - return new PredrawState - { - CullMode = _currentState.CullMode, - DepthStencilUid = _currentState.DepthStencilUid, - Topology = _currentState.Topology, - Viewports = _currentState.Viewports.ToArray(), - }; - } - - public readonly void RestorePredrawState(PredrawState state) - { - _currentState.CullMode = state.CullMode; - _currentState.DepthStencilUid = state.DepthStencilUid; - _currentState.Topology = state.Topology; - _currentState.Viewports = state.Viewports; - - SignalDirty(DirtyFlags.CullMode | DirtyFlags.DepthStencil | DirtyFlags.Viewports); - } - - public readonly void SetClearLoadAction(bool clear) - { - _currentState.ClearLoadAction = clear; - } - - public readonly void DirtyTextures() - { - SignalDirty(DirtyFlags.Textures); - } - - public readonly void DirtyImages() - { - SignalDirty(DirtyFlags.Images); - } - - public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder() - { - // Initialise Pass & State - using MTLRenderPassDescriptor renderPassDescriptor = new(); - - for (int i = 0; i < Constants.MaxColorAttachments; i++) - { - if (_currentState.RenderTargets[i] is Texture tex) - { - MTLRenderPassColorAttachmentDescriptor passAttachment = renderPassDescriptor.ColorAttachments.Object((ulong)i); - tex.PopulateRenderPassAttachment(passAttachment); - passAttachment.LoadAction = _currentState.ClearLoadAction ? MTLLoadAction.Clear : MTLLoadAction.Load; - passAttachment.StoreAction = MTLStoreAction.Store; - } - } - - MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment; - MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment; - - if (_currentState.DepthStencil != null) - { - switch (_currentState.DepthStencil.GetHandle().PixelFormat) - { - // Depth Only Attachment - case MTLPixelFormat.Depth16Unorm: - case MTLPixelFormat.Depth32Float: - depthAttachment.Texture = _currentState.DepthStencil.GetHandle(); - depthAttachment.LoadAction = MTLLoadAction.Load; - depthAttachment.StoreAction = MTLStoreAction.Store; - break; - - // Stencil Only Attachment - case MTLPixelFormat.Stencil8: - stencilAttachment.Texture = _currentState.DepthStencil.GetHandle(); - stencilAttachment.LoadAction = MTLLoadAction.Load; - stencilAttachment.StoreAction = MTLStoreAction.Store; - break; - - // Combined Attachment - case MTLPixelFormat.Depth24UnormStencil8: - case MTLPixelFormat.Depth32FloatStencil8: - depthAttachment.Texture = _currentState.DepthStencil.GetHandle(); - depthAttachment.LoadAction = MTLLoadAction.Load; - depthAttachment.StoreAction = MTLStoreAction.Store; - - stencilAttachment.Texture = _currentState.DepthStencil.GetHandle(); - stencilAttachment.LoadAction = MTLLoadAction.Load; - stencilAttachment.StoreAction = MTLStoreAction.Store; - break; - default: - Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {_currentState.DepthStencil.GetHandle().PixelFormat}!"); - break; - } - } - - // Initialise Encoder - MTLRenderCommandEncoder renderCommandEncoder = _pipeline.CommandBuffer.RenderCommandEncoder(renderPassDescriptor); - - return renderCommandEncoder; - } - - public readonly MTLComputeCommandEncoder CreateComputeCommandEncoder() - { - using MTLComputePassDescriptor descriptor = new(); - MTLComputeCommandEncoder computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor); - - return computeCommandEncoder; - } - - public readonly void RenderResourcesPrepass() - { - _currentState.RenderEncoderBindings.Clear(); - - if ((_currentState.Dirty & DirtyFlags.RenderPipeline) != 0) - { - SetVertexBuffers(_currentState.VertexBuffers, ref _currentState.RenderEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0) - { - UpdateAndBind(_currentState.RenderProgram, Constants.ConstantBuffersSetIndex, ref _currentState.RenderEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Storages) != 0) - { - UpdateAndBind(_currentState.RenderProgram, Constants.StorageBuffersSetIndex, ref _currentState.RenderEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Textures) != 0) - { - UpdateAndBind(_currentState.RenderProgram, Constants.TexturesSetIndex, ref _currentState.RenderEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Images) != 0) - { - UpdateAndBind(_currentState.RenderProgram, Constants.ImagesSetIndex, ref _currentState.RenderEncoderBindings); - } - } - - public readonly void ComputeResourcesPrepass() - { - _currentState.ComputeEncoderBindings.Clear(); - - if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0) - { - UpdateAndBind(_currentState.ComputeProgram, Constants.ConstantBuffersSetIndex, ref _currentState.ComputeEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Storages) != 0) - { - UpdateAndBind(_currentState.ComputeProgram, Constants.StorageBuffersSetIndex, ref _currentState.ComputeEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Textures) != 0) - { - UpdateAndBind(_currentState.ComputeProgram, Constants.TexturesSetIndex, ref _currentState.ComputeEncoderBindings); - } - - if ((_currentState.Dirty & DirtyFlags.Images) != 0) - { - UpdateAndBind(_currentState.ComputeProgram, Constants.ImagesSetIndex, ref _currentState.ComputeEncoderBindings); - } - } - - public void RebindRenderState(MTLRenderCommandEncoder renderCommandEncoder) - { - if ((_currentState.Dirty & DirtyFlags.RenderPipeline) != 0) - { - SetRenderPipelineState(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.DepthStencil) != 0) - { - SetDepthStencilState(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.DepthClamp) != 0) - { - SetDepthClamp(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.DepthBias) != 0) - { - SetDepthBias(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.CullMode) != 0) - { - SetCullMode(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.FrontFace) != 0) - { - SetFrontFace(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.StencilRef) != 0) - { - SetStencilRefValue(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.Viewports) != 0) - { - SetViewports(renderCommandEncoder); - } - - if ((_currentState.Dirty & DirtyFlags.Scissors) != 0) - { - SetScissors(renderCommandEncoder); - } - - foreach (Resource resource in _currentState.RenderEncoderBindings.Resources) - { - renderCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage, resource.Stages); - } - - foreach (BufferResource buffer in _currentState.RenderEncoderBindings.VertexBuffers) - { - renderCommandEncoder.SetVertexBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); - } - - foreach (BufferResource buffer in _currentState.RenderEncoderBindings.FragmentBuffers) - { - renderCommandEncoder.SetFragmentBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); - } - - _currentState.Dirty &= ~DirtyFlags.RenderAll; - } - - public readonly void RebindComputeState(MTLComputeCommandEncoder computeCommandEncoder) - { - if ((_currentState.Dirty & DirtyFlags.ComputePipeline) != 0) - { - SetComputePipelineState(computeCommandEncoder); - } - - foreach (Resource resource in _currentState.ComputeEncoderBindings.Resources) - { - computeCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage); - } - - foreach (BufferResource buffer in _currentState.ComputeEncoderBindings.Buffers) - { - computeCommandEncoder.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); - } - - _currentState.Dirty &= ~DirtyFlags.ComputeAll; - } - - private readonly void SetRenderPipelineState(MTLRenderCommandEncoder renderCommandEncoder) - { - MTLRenderPipelineState pipelineState = _currentState.Pipeline.CreateRenderPipeline(_device, _currentState.RenderProgram); - - renderCommandEncoder.SetRenderPipelineState(pipelineState); - - renderCommandEncoder.SetBlendColor( - _currentState.BlendColor.Red, - _currentState.BlendColor.Green, - _currentState.BlendColor.Blue, - _currentState.BlendColor.Alpha); - } - - private readonly void SetComputePipelineState(MTLComputeCommandEncoder computeCommandEncoder) - { - if (_currentState.ComputeProgram == null) - { - return; - } - - MTLComputePipelineState pipelineState = PipelineState.CreateComputePipeline(_device, _currentState.ComputeProgram); - - computeCommandEncoder.SetComputePipelineState(pipelineState); - } - - public readonly void UpdateIndexBuffer(BufferRange buffer, IndexType type) - { - if (buffer.Handle != BufferHandle.Null) - { - _currentState.IndexBuffer = new IndexBufferState(buffer.Handle, buffer.Offset, buffer.Size, type); - } - else - { - _currentState.IndexBuffer = IndexBufferState.Null; - } - } - - public readonly void UpdatePrimitiveTopology(PrimitiveTopology topology) - { - _currentState.Topology = topology; - } - - public readonly void UpdateProgram(IProgram program) - { - Program prg = (Program)program; - - if (prg.VertexFunction == IntPtr.Zero && prg.ComputeFunction == IntPtr.Zero) - { - if (prg.FragmentFunction == IntPtr.Zero) - { - Logger.Error?.PrintMsg(LogClass.Gpu, "No compute function"); - } - else - { - Logger.Error?.PrintMsg(LogClass.Gpu, "No vertex function"); - } - return; - } - - if (prg.VertexFunction != IntPtr.Zero) - { - _currentState.RenderProgram = prg; - - SignalDirty(DirtyFlags.RenderPipeline | DirtyFlags.ArgBuffers); - } - else if (prg.ComputeFunction != IntPtr.Zero) - { - _currentState.ComputeProgram = prg; - - SignalDirty(DirtyFlags.ComputePipeline | DirtyFlags.ArgBuffers); - } - } - - public readonly void UpdateRasterizerDiscard(bool discard) - { - _currentState.Pipeline.RasterizerDiscardEnable = discard; - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public readonly void UpdateRenderTargets(ITexture[] colors, ITexture depthStencil) - { - _currentState.FramebufferUsingColorWriteMask = false; - UpdateRenderTargetsInternal(colors, depthStencil); - } - - public readonly void UpdateRenderTargetColorMasks(ReadOnlySpan componentMask) - { - ref Array8 blendState = ref _currentState.Pipeline.Internal.ColorBlendState; - - for (int i = 0; i < componentMask.Length; i++) - { - bool red = (componentMask[i] & (0x1 << 0)) != 0; - bool green = (componentMask[i] & (0x1 << 1)) != 0; - bool blue = (componentMask[i] & (0x1 << 2)) != 0; - bool alpha = (componentMask[i] & (0x1 << 3)) != 0; - - MTLColorWriteMask mask = MTLColorWriteMask.None; - - mask |= red ? MTLColorWriteMask.Red : 0; - mask |= green ? MTLColorWriteMask.Green : 0; - mask |= blue ? MTLColorWriteMask.Blue : 0; - mask |= alpha ? MTLColorWriteMask.Alpha : 0; - - ref ColorBlendStateUid mtlBlend = ref blendState[i]; - - // When color write mask is 0, remove all blend state to help the pipeline cache. - // Restore it when the mask becomes non-zero. - if (mtlBlend.WriteMask != mask) - { - if (mask == 0) - { - _currentState.StoredBlend[i] = mtlBlend; - - mtlBlend.Swap(new ColorBlendStateUid()); - } - else if (mtlBlend.WriteMask == 0) - { - mtlBlend.Swap(_currentState.StoredBlend[i]); - } - } - - blendState[i].WriteMask = mask; - } - - if (_currentState.FramebufferUsingColorWriteMask) - { - UpdateRenderTargetsInternal(_currentState.PreMaskRenderTargets, _currentState.PreMaskDepthStencil); - } - else - { - // Requires recreating pipeline - if (_pipeline.CurrentEncoderType == EncoderType.Render) - { - _pipeline.EndCurrentPass(); - } - } - } - - private readonly void UpdateRenderTargetsInternal(ITexture[] colors, ITexture depthStencil) - { - // TBDR GPUs don't work properly if the same attachment is bound to multiple targets, - // due to each attachment being a copy of the real attachment, rather than a direct write. - // - // Just try to remove duplicate attachments. - // Save a copy of the array to rebind when mask changes. - - // Look for textures that are masked out. - - ref PipelineState pipeline = ref _currentState.Pipeline; - ref Array8 blendState = ref pipeline.Internal.ColorBlendState; - - pipeline.ColorBlendAttachmentStateCount = (uint)colors.Length; - - for (int i = 0; i < colors.Length; i++) - { - if (colors[i] == null) - { - continue; - } - - MTLColorWriteMask mtlMask = blendState[i].WriteMask; - - for (int j = 0; j < i; j++) - { - // Check each binding for a duplicate binding before it. - - if (colors[i] == colors[j]) - { - // Prefer the binding with no write mask. - - MTLColorWriteMask mtlMask2 = blendState[j].WriteMask; - - if (mtlMask == 0) - { - colors[i] = null; - MaskOut(colors, depthStencil); - } - else if (mtlMask2 == 0) - { - colors[j] = null; - MaskOut(colors, depthStencil); - } - } - } - } - - _currentState.RenderTargets = new Texture[Constants.MaxColorAttachments]; - - for (int i = 0; i < colors.Length; i++) - { - if (colors[i] is not Texture tex) - { - blendState[i].PixelFormat = MTLPixelFormat.Invalid; - - continue; - } - - blendState[i].PixelFormat = tex.GetHandle().PixelFormat; // TODO: cache this - _currentState.RenderTargets[i] = tex; - } - - if (depthStencil is Texture depthTexture) - { - pipeline.DepthStencilFormat = depthTexture.GetHandle().PixelFormat; // TODO: cache this - _currentState.DepthStencil = depthTexture; - } - else if (depthStencil == null) - { - pipeline.DepthStencilFormat = MTLPixelFormat.Invalid; - _currentState.DepthStencil = null; - } - - // Requires recreating pipeline - if (_pipeline.CurrentEncoderType == EncoderType.Render) - { - _pipeline.EndCurrentPass(); - } - } - - private readonly void MaskOut(ITexture[] colors, ITexture depthStencil) - { - if (!_currentState.FramebufferUsingColorWriteMask) - { - _currentState.PreMaskRenderTargets = colors; - _currentState.PreMaskDepthStencil = depthStencil; - } - - // If true, then the framebuffer must be recreated when the mask changes. - _currentState.FramebufferUsingColorWriteMask = true; - } - - public readonly void UpdateVertexAttribs(ReadOnlySpan vertexAttribs) - { - vertexAttribs.CopyTo(_currentState.VertexAttribs); - - // Update the buffers on the pipeline - UpdatePipelineVertexState(_currentState.VertexBuffers, _currentState.VertexAttribs); - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public readonly void UpdateBlendDescriptors(int index, BlendDescriptor blend) - { - ref ColorBlendStateUid blendState = ref _currentState.Pipeline.Internal.ColorBlendState[index]; - - blendState.Enable = blend.Enable; - blendState.AlphaBlendOperation = blend.AlphaOp.Convert(); - blendState.RgbBlendOperation = blend.ColorOp.Convert(); - blendState.SourceAlphaBlendFactor = blend.AlphaSrcFactor.Convert(); - blendState.DestinationAlphaBlendFactor = blend.AlphaDstFactor.Convert(); - blendState.SourceRGBBlendFactor = blend.ColorSrcFactor.Convert(); - blendState.DestinationRGBBlendFactor = blend.ColorDstFactor.Convert(); - - if (blendState.WriteMask == 0) - { - _currentState.StoredBlend[index] = blendState; - - blendState.Swap(new ColorBlendStateUid()); - } - - _currentState.BlendColor = blend.BlendConstant; - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public void UpdateStencilState(StencilTestDescriptor stencilTest) - { - ref DepthStencilUid uid = ref _currentState.DepthStencilUid; - - uid.FrontFace = new StencilUid - { - StencilFailureOperation = stencilTest.FrontSFail.Convert(), - DepthFailureOperation = stencilTest.FrontDpFail.Convert(), - DepthStencilPassOperation = stencilTest.FrontDpPass.Convert(), - StencilCompareFunction = stencilTest.FrontFunc.Convert(), - ReadMask = (uint)stencilTest.FrontFuncMask, - WriteMask = (uint)stencilTest.FrontMask - }; - - uid.BackFace = new StencilUid - { - StencilFailureOperation = stencilTest.BackSFail.Convert(), - DepthFailureOperation = stencilTest.BackDpFail.Convert(), - DepthStencilPassOperation = stencilTest.BackDpPass.Convert(), - StencilCompareFunction = stencilTest.BackFunc.Convert(), - ReadMask = (uint)stencilTest.BackFuncMask, - WriteMask = (uint)stencilTest.BackMask - }; - - uid.StencilTestEnabled = stencilTest.TestEnable; - - UpdateStencilRefValue(stencilTest.FrontFuncRef, stencilTest.BackFuncRef); - - SignalDirty(DirtyFlags.DepthStencil); - } - - public readonly void UpdateDepthState(DepthTestDescriptor depthTest) - { - ref DepthStencilUid uid = ref _currentState.DepthStencilUid; - - uid.DepthCompareFunction = depthTest.TestEnable ? depthTest.Func.Convert() : MTLCompareFunction.Always; - uid.DepthWriteEnabled = depthTest.TestEnable && depthTest.WriteEnable; - - SignalDirty(DirtyFlags.DepthStencil); - } - - public readonly void UpdateDepthClamp(bool clamp) - { - _currentState.DepthClipMode = clamp ? MTLDepthClipMode.Clamp : MTLDepthClipMode.Clip; - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetDepthClamp(renderCommandEncoder); - return; - } - - SignalDirty(DirtyFlags.DepthClamp); - } - - public readonly void UpdateDepthBias(float depthBias, float slopeScale, float clamp) - { - _currentState.DepthBias = depthBias; - _currentState.SlopeScale = slopeScale; - _currentState.Clamp = clamp; - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetDepthBias(renderCommandEncoder); - return; - } - - SignalDirty(DirtyFlags.DepthBias); - } - - public readonly void UpdateLogicOpState(bool enable, LogicalOp op) - { - _currentState.Pipeline.LogicOpEnable = enable; - _currentState.Pipeline.LogicOp = op.Convert(); - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public readonly void UpdateMultisampleState(MultisampleDescriptor multisample) - { - _currentState.Pipeline.AlphaToCoverageEnable = multisample.AlphaToCoverageEnable; - _currentState.Pipeline.AlphaToOneEnable = multisample.AlphaToOneEnable; - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public void UpdateScissors(ReadOnlySpan> regions) - { - for (int i = 0; i < regions.Length; i++) - { - Rectangle region = regions[i]; - - _currentState.Scissors[i] = new MTLScissorRect - { - height = (ulong)region.Height, - width = (ulong)region.Width, - x = (ulong)region.X, - y = (ulong)region.Y - }; - } - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetScissors(renderCommandEncoder); - return; - } - - SignalDirty(DirtyFlags.Scissors); - } - - public void UpdateViewports(ReadOnlySpan viewports) - { - static float Clamp(float value) - { - return Math.Clamp(value, 0f, 1f); - } - - for (int i = 0; i < viewports.Length; i++) - { - Viewport viewport = viewports[i]; - // Y coordinate is inverted - _currentState.Viewports[i] = new MTLViewport - { - originX = viewport.Region.X, - originY = viewport.Region.Y + viewport.Region.Height, - width = viewport.Region.Width, - height = -viewport.Region.Height, - znear = Clamp(viewport.DepthNear), - zfar = Clamp(viewport.DepthFar) - }; - } - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetViewports(renderCommandEncoder); - return; - } - - SignalDirty(DirtyFlags.Viewports); - } - - public readonly void UpdateVertexBuffers(ReadOnlySpan vertexBuffers) - { - for (int i = 0; i < Constants.MaxVertexBuffers; i++) - { - if (i < vertexBuffers.Length) - { - VertexBufferDescriptor vertexBuffer = vertexBuffers[i]; - - _currentState.VertexBuffers[i] = new VertexBufferState( - vertexBuffer.Buffer.Handle, - vertexBuffer.Buffer.Offset, - vertexBuffer.Buffer.Size, - vertexBuffer.Divisor, - vertexBuffer.Stride); - } - else - { - _currentState.VertexBuffers[i] = VertexBufferState.Null; - } - } - - // Update the buffers on the pipeline - UpdatePipelineVertexState(_currentState.VertexBuffers, _currentState.VertexAttribs); - - SignalDirty(DirtyFlags.RenderPipeline); - } - - public readonly void UpdateUniformBuffers(ReadOnlySpan buffers) - { - foreach (BufferAssignment assignment in buffers) - { - BufferRange buffer = assignment.Range; - int index = assignment.Binding; - - Auto mtlBuffer = buffer.Handle == BufferHandle.Null - ? null - : _bufferManager.GetBuffer(buffer.Handle, buffer.Write); - - _currentState.UniformBufferRefs[index] = new BufferRef(mtlBuffer, ref buffer); - } - - SignalDirty(DirtyFlags.Uniforms); - } - - public readonly void UpdateStorageBuffers(ReadOnlySpan buffers) - { - foreach (BufferAssignment assignment in buffers) - { - BufferRange buffer = assignment.Range; - int index = assignment.Binding; - - Auto mtlBuffer = buffer.Handle == BufferHandle.Null - ? null - : _bufferManager.GetBuffer(buffer.Handle, buffer.Write); - - _currentState.StorageBufferRefs[index] = new BufferRef(mtlBuffer, ref buffer); - } - - SignalDirty(DirtyFlags.Storages); - } - - public readonly void UpdateStorageBuffers(int first, ReadOnlySpan> buffers) - { - for (int i = 0; i < buffers.Length; i++) - { - Auto mtlBuffer = buffers[i]; - int index = first + i; - - _currentState.StorageBufferRefs[index] = new BufferRef(mtlBuffer); - } - - SignalDirty(DirtyFlags.Storages); - } - - public void UpdateCullMode(bool enable, Face face) - { - bool dirtyScissor = (face == Face.FrontAndBack) != _currentState.CullBoth; - - _currentState.CullMode = enable ? face.Convert() : MTLCullMode.None; - _currentState.CullBoth = face == Face.FrontAndBack; - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetCullMode(renderCommandEncoder); - SetScissors(renderCommandEncoder); - return; - } - - // Mark dirty - SignalDirty(DirtyFlags.CullMode); - - if (dirtyScissor) - { - SignalDirty(DirtyFlags.Scissors); - } - } - - public readonly void UpdateFrontFace(FrontFace frontFace) - { - _currentState.Winding = frontFace.Convert(); - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetFrontFace(renderCommandEncoder); - return; - } - - SignalDirty(DirtyFlags.FrontFace); - } - - private readonly void UpdateStencilRefValue(int frontRef, int backRef) - { - _currentState.FrontRefValue = frontRef; - _currentState.BackRefValue = backRef; - - // Inline update - if (_pipeline.Encoders.TryGetRenderEncoder(out MTLRenderCommandEncoder renderCommandEncoder)) - { - SetStencilRefValue(renderCommandEncoder); - } - - SignalDirty(DirtyFlags.StencilRef); - } - - public readonly void UpdateTextureAndSampler(ShaderStage stage, int binding, TextureBase texture, SamplerHolder samplerHolder) - { - if (texture != null) - { - _currentState.TextureRefs[binding] = new(stage, texture, samplerHolder?.GetSampler()); - } - else - { - _currentState.TextureRefs[binding] = default; - } - - SignalDirty(DirtyFlags.Textures); - } - - public readonly void UpdateImage(ShaderStage stage, int binding, TextureBase image) - { - if (image is Texture view) - { - _currentState.ImageRefs[binding] = new(stage, view); - } - else - { - _currentState.ImageRefs[binding] = default; - } - - SignalDirty(DirtyFlags.Images); - } - - public readonly void UpdateTextureArray(ShaderStage stage, int binding, TextureArray array) - { - ref EncoderState.ArrayRef arrayRef = ref GetArrayRef(ref _currentState.TextureArrayRefs, binding, ArrayGrowthSize); - - if (arrayRef.Stage != stage || arrayRef.Array != array) - { - arrayRef = new EncoderState.ArrayRef(stage, array); - - SignalDirty(DirtyFlags.Textures); - } - } - - public readonly void UpdateTextureArraySeparate(ShaderStage stage, int setIndex, TextureArray array) - { - ref EncoderState.ArrayRef arrayRef = ref GetArrayRef(ref _currentState.TextureArrayExtraRefs, setIndex - MetalRenderer.TotalSets); - - if (arrayRef.Stage != stage || arrayRef.Array != array) - { - arrayRef = new EncoderState.ArrayRef(stage, array); - - SignalDirty(DirtyFlags.Textures); - } - } - - public readonly void UpdateImageArray(ShaderStage stage, int binding, ImageArray array) - { - ref EncoderState.ArrayRef arrayRef = ref GetArrayRef(ref _currentState.ImageArrayRefs, binding, ArrayGrowthSize); - - if (arrayRef.Stage != stage || arrayRef.Array != array) - { - arrayRef = new EncoderState.ArrayRef(stage, array); - - SignalDirty(DirtyFlags.Images); - } - } - - public readonly void UpdateImageArraySeparate(ShaderStage stage, int setIndex, ImageArray array) - { - ref EncoderState.ArrayRef arrayRef = ref GetArrayRef(ref _currentState.ImageArrayExtraRefs, setIndex - MetalRenderer.TotalSets); - - if (arrayRef.Stage != stage || arrayRef.Array != array) - { - arrayRef = new EncoderState.ArrayRef(stage, array); - - SignalDirty(DirtyFlags.Images); - } - } - - private static ref EncoderState.ArrayRef GetArrayRef(ref EncoderState.ArrayRef[] array, int index, int growthSize = 1) - { - ArgumentOutOfRangeException.ThrowIfNegative(index); - - if (array.Length <= index) - { - Array.Resize(ref array, index + growthSize); - } - - return ref array[index]; - } - - private readonly void SetDepthStencilState(MTLRenderCommandEncoder renderCommandEncoder) - { - if (DepthStencil != null) - { - MTLDepthStencilState state = _depthStencilCache.GetOrCreate(_currentState.DepthStencilUid); - - renderCommandEncoder.SetDepthStencilState(state); - } - else - { - renderCommandEncoder.SetDepthStencilState(_defaultState); - } - } - - private readonly void SetDepthClamp(MTLRenderCommandEncoder renderCommandEncoder) - { - renderCommandEncoder.SetDepthClipMode(_currentState.DepthClipMode); - } - - private readonly void SetDepthBias(MTLRenderCommandEncoder renderCommandEncoder) - { - renderCommandEncoder.SetDepthBias(_currentState.DepthBias, _currentState.SlopeScale, _currentState.Clamp); - } - - private unsafe void SetScissors(MTLRenderCommandEncoder renderCommandEncoder) - { - bool isTriangles = (_currentState.Topology == PrimitiveTopology.Triangles) || - (_currentState.Topology == PrimitiveTopology.TriangleStrip); - - if (_currentState.CullBoth && isTriangles) - { - renderCommandEncoder.SetScissorRect(new MTLScissorRect { x = 0, y = 0, width = 0, height = 0 }); - } - else - { - if (_currentState.Scissors.Length > 0) - { - fixed (MTLScissorRect* pMtlScissors = _currentState.Scissors) - { - renderCommandEncoder.SetScissorRects((IntPtr)pMtlScissors, (ulong)_currentState.Scissors.Length); - } - } - } - } - - private readonly unsafe void SetViewports(MTLRenderCommandEncoder renderCommandEncoder) - { - if (_currentState.Viewports.Length > 0) - { - fixed (MTLViewport* pMtlViewports = _currentState.Viewports) - { - renderCommandEncoder.SetViewports((IntPtr)pMtlViewports, (ulong)_currentState.Viewports.Length); - } - } - } - - private readonly void UpdatePipelineVertexState(VertexBufferState[] bufferDescriptors, VertexAttribDescriptor[] attribDescriptors) - { - ref PipelineState pipeline = ref _currentState.Pipeline; - uint indexMask = 0; - - for (int i = 0; i < attribDescriptors.Length; i++) - { - ref VertexInputAttributeUid attrib = ref pipeline.Internal.VertexAttributes[i]; - - if (attribDescriptors[i].IsZero) - { - attrib.Format = attribDescriptors[i].Format.Convert(); - indexMask |= 1u << (int)Constants.ZeroBufferIndex; - attrib.BufferIndex = Constants.ZeroBufferIndex; - attrib.Offset = 0; - } - else - { - attrib.Format = attribDescriptors[i].Format.Convert(); - indexMask |= 1u << attribDescriptors[i].BufferIndex; - attrib.BufferIndex = (ulong)attribDescriptors[i].BufferIndex; - attrib.Offset = (ulong)attribDescriptors[i].Offset; - } - } - - for (int i = 0; i < bufferDescriptors.Length; i++) - { - ref VertexInputLayoutUid layout = ref pipeline.Internal.VertexBindings[i]; - - if ((indexMask & (1u << i)) != 0) - { - layout.Stride = (uint)bufferDescriptors[i].Stride; - - if (layout.Stride == 0) - { - layout.Stride = 1; - layout.StepFunction = MTLVertexStepFunction.Constant; - layout.StepRate = 0; - } - else - { - if (bufferDescriptors[i].Divisor > 0) - { - layout.StepFunction = MTLVertexStepFunction.PerInstance; - layout.StepRate = (uint)bufferDescriptors[i].Divisor; - } - else - { - layout.StepFunction = MTLVertexStepFunction.PerVertex; - layout.StepRate = 1; - } - } - } - else - { - layout = new(); - } - } - - ref VertexInputLayoutUid zeroBufLayout = ref pipeline.Internal.VertexBindings[(int)Constants.ZeroBufferIndex]; - - // Zero buffer - if ((indexMask & (1u << (int)Constants.ZeroBufferIndex)) != 0) - { - zeroBufLayout.Stride = 1; - zeroBufLayout.StepFunction = MTLVertexStepFunction.Constant; - zeroBufLayout.StepRate = 0; - } - else - { - zeroBufLayout = new(); - } - - pipeline.VertexAttributeDescriptionsCount = (uint)attribDescriptors.Length; - pipeline.VertexBindingDescriptionsCount = Constants.ZeroBufferIndex + 1; // TODO: move this out? - } - - private readonly void SetVertexBuffers(VertexBufferState[] bufferStates, ref readonly RenderEncoderBindings bindings) - { - for (int i = 0; i < bufferStates.Length; i++) - { - (MTLBuffer mtlBuffer, int offset) = bufferStates[i].GetVertexBuffer(_bufferManager, _pipeline.Cbs); - - if (mtlBuffer.NativePtr != IntPtr.Zero) - { - bindings.VertexBuffers.Add(new BufferResource(mtlBuffer, (ulong)offset, (ulong)i)); - } - } - - Auto autoZeroBuffer = _zeroBuffer == BufferHandle.Null - ? null - : _bufferManager.GetBuffer(_zeroBuffer, false); - - if (autoZeroBuffer == null) - { - return; - } - - MTLBuffer zeroMtlBuffer = autoZeroBuffer.Get(_pipeline.Cbs).Value; - bindings.VertexBuffers.Add(new BufferResource(zeroMtlBuffer, 0, Constants.ZeroBufferIndex)); - } - - private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForBuffer(ref BufferRef buffer) - { - ulong gpuAddress = 0; - IntPtr nativePtr = IntPtr.Zero; - - BufferRange? range = buffer.Range; - Auto autoBuffer = buffer.Buffer; - - if (autoBuffer != null) - { - int offset = 0; - MTLBuffer mtlBuffer; - - if (range.HasValue) - { - offset = range.Value.Offset; - mtlBuffer = autoBuffer.Get(_pipeline.Cbs, offset, range.Value.Size, range.Value.Write).Value; - } - else - { - mtlBuffer = autoBuffer.Get(_pipeline.Cbs).Value; - } - - gpuAddress = mtlBuffer.GpuAddress + (ulong)offset; - nativePtr = mtlBuffer.NativePtr; - } - - return (gpuAddress, nativePtr); - } - - private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForTexture(ref TextureRef texture) - { - TextureBase storage = texture.Storage; - - ulong gpuAddress = 0; - IntPtr nativePtr = IntPtr.Zero; - - if (storage != null) - { - if (storage is TextureBuffer textureBuffer) - { - textureBuffer.RebuildStorage(false); - } - - MTLTexture mtlTexture = storage.GetHandle(); - - gpuAddress = mtlTexture.GpuResourceID._impl; - nativePtr = mtlTexture.NativePtr; - } - - return (gpuAddress, nativePtr); - } - - private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForImage(ref ImageRef image) - { - Texture storage = image.Storage; - - ulong gpuAddress = 0; - IntPtr nativePtr = IntPtr.Zero; - - if (storage != null) - { - MTLTexture mtlTexture = storage.GetHandle(); - - gpuAddress = mtlTexture.GpuResourceID._impl; - nativePtr = mtlTexture.NativePtr; - } - - return (gpuAddress, nativePtr); - } - - private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForTextureBuffer(ref TextureBuffer bufferTexture) - { - ulong gpuAddress = 0; - IntPtr nativePtr = IntPtr.Zero; - - if (bufferTexture != null) - { - bufferTexture.RebuildStorage(false); - - MTLTexture mtlTexture = bufferTexture.GetHandle(); - - gpuAddress = mtlTexture.GpuResourceID._impl; - nativePtr = mtlTexture.NativePtr; - } - - return (gpuAddress, nativePtr); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AddResource(IntPtr resourcePointer, MTLResourceUsage usage, MTLRenderStages stages, ref readonly RenderEncoderBindings bindings) - { - if (resourcePointer != IntPtr.Zero) - { - bindings.Resources.Add(new Resource(new MTLResource(resourcePointer), usage, stages)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AddResource(IntPtr resourcePointer, MTLResourceUsage usage, ref readonly ComputeEncoderBindings bindings) - { - if (resourcePointer != IntPtr.Zero) - { - bindings.Resources.Add(new Resource(new MTLResource(resourcePointer), usage, 0)); - } - } - - private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly RenderEncoderBindings bindings) - { - ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex]; - - if (bindingSegments.Length == 0) - { - return; - } - - ScopedTemporaryBuffer vertArgBuffer = default; - ScopedTemporaryBuffer fragArgBuffer = default; - - if (program.ArgumentBufferSizes[setIndex] > 0) - { - vertArgBuffer = _bufferManager.ReserveOrCreate(_pipeline.Cbs, program.ArgumentBufferSizes[setIndex] * sizeof(ulong)); - } - - if (program.FragArgumentBufferSizes[setIndex] > 0) - { - fragArgBuffer = _bufferManager.ReserveOrCreate(_pipeline.Cbs, program.FragArgumentBufferSizes[setIndex] * sizeof(ulong)); - } - - Span vertResourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]]; - Span fragResourceIds = stackalloc ulong[program.FragArgumentBufferSizes[setIndex]]; - - int vertResourceIdIndex = 0; - int fragResourceIdIndex = 0; - - foreach (ResourceBindingSegment segment in bindingSegments) - { - int binding = segment.Binding; - int count = segment.Count; - - switch (setIndex) - { - case Constants.ConstantBuffersSetIndex: - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref BufferRef buffer = ref _currentState.UniformBufferRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); - } - break; - case Constants.StorageBuffersSetIndex: - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref BufferRef buffer = ref _currentState.StorageBufferRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); - } - break; - case Constants.TexturesSetIndex: - if (!segment.IsArray) - { - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref TextureRef texture = ref _currentState.TextureRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - - if (texture.Sampler != null) - { - vertResourceIds[vertResourceIdIndex] = texture.Sampler.Get(_pipeline.Cbs).Value.GpuResourceID._impl; - vertResourceIdIndex++; - } - - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - - if (texture.Sampler != null) - { - fragResourceIds[fragResourceIdIndex] = texture.Sampler.Get(_pipeline.Cbs).Value.GpuResourceID._impl; - fragResourceIdIndex++; - } - - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); - } - } - else - { - TextureArray textureArray = _currentState.TextureArrayRefs[binding].Array; - - if (segment.Type != ResourceType.BufferTexture) - { - TextureRef[] textures = textureArray.GetTextureRefs(); - Auto[] samplers = new Auto[textures.Length]; - - for (int i = 0; i < textures.Length; i++) - { - TextureRef texture = textures[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture); - - samplers[i] = texture.Sampler; - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); - } - - foreach (Auto sampler in samplers) - { - ulong gpuAddress = 0; - - if (sampler != null) - { - gpuAddress = sampler.Get(_pipeline.Cbs).Value.GpuResourceID._impl; - } - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - } - } - } - else - { - TextureBuffer[] bufferTextures = textureArray.GetBufferTextureRefs(); - - for (int i = 0; i < bufferTextures.Length; i++) - { - TextureBuffer bufferTexture = bufferTextures[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref bufferTexture); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); - } - } - } - break; - case Constants.ImagesSetIndex: - if (!segment.IsArray) - { - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref ImageRef image = ref _currentState.ImageRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForImage(ref image); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages, in bindings); - } - } - else - { - ImageArray imageArray = _currentState.ImageArrayRefs[binding].Array; - - if (segment.Type != ResourceType.BufferImage) - { - TextureRef[] images = imageArray.GetTextureRefs(); - - for (int i = 0; i < images.Length; i++) - { - TextureRef image = images[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref image); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages, in bindings); - } - } - else - { - TextureBuffer[] bufferImages = imageArray.GetBufferTextureRefs(); - - for (int i = 0; i < bufferImages.Length; i++) - { - TextureBuffer image = bufferImages[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref image); - - MTLRenderStages renderStages = 0; - - if ((segment.Stages & ResourceStages.Vertex) != 0) - { - vertResourceIds[vertResourceIdIndex] = gpuAddress; - vertResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageVertex; - } - - if ((segment.Stages & ResourceStages.Fragment) != 0) - { - fragResourceIds[fragResourceIdIndex] = gpuAddress; - fragResourceIdIndex++; - renderStages |= MTLRenderStages.RenderStageFragment; - } - - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages, in bindings); - } - } - } - break; - } - } - - if (program.ArgumentBufferSizes[setIndex] > 0) - { - vertArgBuffer.Holder.SetDataUnchecked(vertArgBuffer.Offset, MemoryMarshal.AsBytes(vertResourceIds)); - MTLBuffer mtlVertArgBuffer = _bufferManager.GetBuffer(vertArgBuffer.Handle, false).Get(_pipeline.Cbs).Value; - bindings.VertexBuffers.Add(new BufferResource(mtlVertArgBuffer, (uint)vertArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); - } - - if (program.FragArgumentBufferSizes[setIndex] > 0) - { - fragArgBuffer.Holder.SetDataUnchecked(fragArgBuffer.Offset, MemoryMarshal.AsBytes(fragResourceIds)); - MTLBuffer mtlFragArgBuffer = _bufferManager.GetBuffer(fragArgBuffer.Handle, false).Get(_pipeline.Cbs).Value; - bindings.FragmentBuffers.Add(new BufferResource(mtlFragArgBuffer, (uint)fragArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); - } - } - - private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly ComputeEncoderBindings bindings) - { - ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex]; - - if (bindingSegments.Length == 0) - { - return; - } - - ScopedTemporaryBuffer argBuffer = default; - - if (program.ArgumentBufferSizes[setIndex] > 0) - { - argBuffer = _bufferManager.ReserveOrCreate(_pipeline.Cbs, program.ArgumentBufferSizes[setIndex] * sizeof(ulong)); - } - - Span resourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]]; - int resourceIdIndex = 0; - - foreach (ResourceBindingSegment segment in bindingSegments) - { - int binding = segment.Binding; - int count = segment.Count; - - switch (setIndex) - { - case Constants.ConstantBuffersSetIndex: - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref BufferRef buffer = ref _currentState.UniformBufferRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read, in bindings); - bindings.Resources.Add(new Resource(new MTLResource(nativePtr), MTLResourceUsage.Read, 0)); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - break; - case Constants.StorageBuffersSetIndex: - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref BufferRef buffer = ref _currentState.StorageBufferRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - break; - case Constants.TexturesSetIndex: - if (!segment.IsArray) - { - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref TextureRef texture = ref _currentState.TextureRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - - if (texture.Sampler != null) - { - resourceIds[resourceIdIndex] = texture.Sampler.Get(_pipeline.Cbs).Value.GpuResourceID._impl; - resourceIdIndex++; - } - } - } - } - else - { - TextureArray textureArray = _currentState.TextureArrayRefs[binding].Array; - - if (segment.Type != ResourceType.BufferTexture) - { - TextureRef[] textures = textureArray.GetTextureRefs(); - Auto[] samplers = new Auto[textures.Length]; - - for (int i = 0; i < textures.Length; i++) - { - TextureRef texture = textures[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - - samplers[i] = texture.Sampler; - } - } - - foreach (Auto sampler in samplers) - { - if (sampler != null) - { - resourceIds[resourceIdIndex] = sampler.Get(_pipeline.Cbs).Value.GpuResourceID._impl; - resourceIdIndex++; - } - } - } - else - { - TextureBuffer[] bufferTextures = textureArray.GetBufferTextureRefs(); - - for (int i = 0; i < bufferTextures.Length; i++) - { - TextureBuffer bufferTexture = bufferTextures[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref bufferTexture); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - } - } - break; - case Constants.ImagesSetIndex: - if (!segment.IsArray) - { - for (int i = 0; i < count; i++) - { - int index = binding + i; - - ref ImageRef image = ref _currentState.ImageRefs[index]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForImage(ref image); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - } - else - { - ImageArray imageArray = _currentState.ImageArrayRefs[binding].Array; - - if (segment.Type != ResourceType.BufferImage) - { - TextureRef[] images = imageArray.GetTextureRefs(); - - for (int i = 0; i < images.Length; i++) - { - TextureRef image = images[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref image); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - } - else - { - TextureBuffer[] bufferImages = imageArray.GetBufferTextureRefs(); - - for (int i = 0; i < bufferImages.Length; i++) - { - TextureBuffer image = bufferImages[i]; - (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref image); - - if ((segment.Stages & ResourceStages.Compute) != 0) - { - AddResource(nativePtr, MTLResourceUsage.Read | MTLResourceUsage.Write, in bindings); - resourceIds[resourceIdIndex] = gpuAddress; - resourceIdIndex++; - } - } - } - } - break; - } - } - - if (program.ArgumentBufferSizes[setIndex] > 0) - { - argBuffer.Holder.SetDataUnchecked(argBuffer.Offset, MemoryMarshal.AsBytes(resourceIds)); - MTLBuffer mtlArgBuffer = _bufferManager.GetBuffer(argBuffer.Handle, false).Get(_pipeline.Cbs).Value; - bindings.Buffers.Add(new BufferResource(mtlArgBuffer, (uint)argBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); - } - } - - private static uint SetIndexToBindingIndex(uint setIndex) - { - return setIndex switch - { - Constants.ConstantBuffersSetIndex => Constants.ConstantBuffersIndex, - Constants.StorageBuffersSetIndex => Constants.StorageBuffersIndex, - Constants.TexturesSetIndex => Constants.TexturesIndex, - Constants.ImagesSetIndex => Constants.ImagesIndex, - _ => throw new NotImplementedException() - }; - } - - private readonly void SetCullMode(MTLRenderCommandEncoder renderCommandEncoder) - { - renderCommandEncoder.SetCullMode(_currentState.CullMode); - } - - private readonly void SetFrontFace(MTLRenderCommandEncoder renderCommandEncoder) - { - renderCommandEncoder.SetFrontFacingWinding(_currentState.Winding); - } - - private readonly void SetStencilRefValue(MTLRenderCommandEncoder renderCommandEncoder) - { - renderCommandEncoder.SetStencilReferenceValues((uint)_currentState.FrontRefValue, (uint)_currentState.BackRefValue); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/EnumConversion.cs b/src/Ryujinx.Graphics.Metal/EnumConversion.cs deleted file mode 100644 index 7cfb5cbd4..000000000 --- a/src/Ryujinx.Graphics.Metal/EnumConversion.cs +++ /dev/null @@ -1,292 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - static class EnumConversion - { - public static MTLSamplerAddressMode Convert(this AddressMode mode) - { - return mode switch - { - AddressMode.Clamp => MTLSamplerAddressMode.ClampToEdge, // TODO: Should be clamp. - AddressMode.Repeat => MTLSamplerAddressMode.Repeat, - AddressMode.MirrorClamp => MTLSamplerAddressMode.MirrorClampToEdge, // TODO: Should be mirror clamp. - AddressMode.MirroredRepeat => MTLSamplerAddressMode.MirrorRepeat, - AddressMode.ClampToBorder => MTLSamplerAddressMode.ClampToBorderColor, - AddressMode.ClampToEdge => MTLSamplerAddressMode.ClampToEdge, - AddressMode.MirrorClampToEdge => MTLSamplerAddressMode.MirrorClampToEdge, - AddressMode.MirrorClampToBorder => MTLSamplerAddressMode.ClampToBorderColor, // TODO: Should be mirror clamp to border. - _ => LogInvalidAndReturn(mode, nameof(AddressMode), MTLSamplerAddressMode.ClampToEdge) // TODO: Should be clamp. - }; - } - - public static MTLBlendFactor Convert(this BlendFactor factor) - { - return factor switch - { - BlendFactor.Zero or BlendFactor.ZeroGl => MTLBlendFactor.Zero, - BlendFactor.One or BlendFactor.OneGl => MTLBlendFactor.One, - BlendFactor.SrcColor or BlendFactor.SrcColorGl => MTLBlendFactor.SourceColor, - BlendFactor.OneMinusSrcColor or BlendFactor.OneMinusSrcColorGl => MTLBlendFactor.OneMinusSourceColor, - BlendFactor.SrcAlpha or BlendFactor.SrcAlphaGl => MTLBlendFactor.SourceAlpha, - BlendFactor.OneMinusSrcAlpha or BlendFactor.OneMinusSrcAlphaGl => MTLBlendFactor.OneMinusSourceAlpha, - BlendFactor.DstAlpha or BlendFactor.DstAlphaGl => MTLBlendFactor.DestinationAlpha, - BlendFactor.OneMinusDstAlpha or BlendFactor.OneMinusDstAlphaGl => MTLBlendFactor.OneMinusDestinationAlpha, - BlendFactor.DstColor or BlendFactor.DstColorGl => MTLBlendFactor.DestinationColor, - BlendFactor.OneMinusDstColor or BlendFactor.OneMinusDstColorGl => MTLBlendFactor.OneMinusDestinationColor, - BlendFactor.SrcAlphaSaturate or BlendFactor.SrcAlphaSaturateGl => MTLBlendFactor.SourceAlphaSaturated, - BlendFactor.Src1Color or BlendFactor.Src1ColorGl => MTLBlendFactor.Source1Color, - BlendFactor.OneMinusSrc1Color or BlendFactor.OneMinusSrc1ColorGl => MTLBlendFactor.OneMinusSource1Color, - BlendFactor.Src1Alpha or BlendFactor.Src1AlphaGl => MTLBlendFactor.Source1Alpha, - BlendFactor.OneMinusSrc1Alpha or BlendFactor.OneMinusSrc1AlphaGl => MTLBlendFactor.OneMinusSource1Alpha, - BlendFactor.ConstantColor => MTLBlendFactor.BlendColor, - BlendFactor.OneMinusConstantColor => MTLBlendFactor.OneMinusBlendColor, - BlendFactor.ConstantAlpha => MTLBlendFactor.BlendAlpha, - BlendFactor.OneMinusConstantAlpha => MTLBlendFactor.OneMinusBlendAlpha, - _ => LogInvalidAndReturn(factor, nameof(BlendFactor), MTLBlendFactor.Zero) - }; - } - - public static MTLBlendOperation Convert(this BlendOp op) - { - return op switch - { - BlendOp.Add or BlendOp.AddGl => MTLBlendOperation.Add, - BlendOp.Subtract or BlendOp.SubtractGl => MTLBlendOperation.Subtract, - BlendOp.ReverseSubtract or BlendOp.ReverseSubtractGl => MTLBlendOperation.ReverseSubtract, - BlendOp.Minimum => MTLBlendOperation.Min, - BlendOp.Maximum => MTLBlendOperation.Max, - _ => LogInvalidAndReturn(op, nameof(BlendOp), MTLBlendOperation.Add) - }; - } - - public static MTLCompareFunction Convert(this CompareOp op) - { - return op switch - { - CompareOp.Never or CompareOp.NeverGl => MTLCompareFunction.Never, - CompareOp.Less or CompareOp.LessGl => MTLCompareFunction.Less, - CompareOp.Equal or CompareOp.EqualGl => MTLCompareFunction.Equal, - CompareOp.LessOrEqual or CompareOp.LessOrEqualGl => MTLCompareFunction.LessEqual, - CompareOp.Greater or CompareOp.GreaterGl => MTLCompareFunction.Greater, - CompareOp.NotEqual or CompareOp.NotEqualGl => MTLCompareFunction.NotEqual, - CompareOp.GreaterOrEqual or CompareOp.GreaterOrEqualGl => MTLCompareFunction.GreaterEqual, - CompareOp.Always or CompareOp.AlwaysGl => MTLCompareFunction.Always, - _ => LogInvalidAndReturn(op, nameof(CompareOp), MTLCompareFunction.Never) - }; - } - - public static MTLCullMode Convert(this Face face) - { - return face switch - { - Face.Back => MTLCullMode.Back, - Face.Front => MTLCullMode.Front, - Face.FrontAndBack => MTLCullMode.None, - _ => LogInvalidAndReturn(face, nameof(Face), MTLCullMode.Back) - }; - } - - public static MTLWinding Convert(this FrontFace frontFace) - { - // The viewport is flipped vertically, therefore we need to switch the winding order as well - return frontFace switch - { - FrontFace.Clockwise => MTLWinding.CounterClockwise, - FrontFace.CounterClockwise => MTLWinding.Clockwise, - _ => LogInvalidAndReturn(frontFace, nameof(FrontFace), MTLWinding.Clockwise) - }; - } - - public static MTLIndexType Convert(this IndexType type) - { - return type switch - { - IndexType.UShort => MTLIndexType.UInt16, - IndexType.UInt => MTLIndexType.UInt32, - _ => LogInvalidAndReturn(type, nameof(IndexType), MTLIndexType.UInt16) - }; - } - - public static MTLLogicOperation Convert(this LogicalOp op) - { - return op switch - { - LogicalOp.Clear => MTLLogicOperation.Clear, - LogicalOp.And => MTLLogicOperation.And, - LogicalOp.AndReverse => MTLLogicOperation.AndReverse, - LogicalOp.Copy => MTLLogicOperation.Copy, - LogicalOp.AndInverted => MTLLogicOperation.AndInverted, - LogicalOp.Noop => MTLLogicOperation.Noop, - LogicalOp.Xor => MTLLogicOperation.Xor, - LogicalOp.Or => MTLLogicOperation.Or, - LogicalOp.Nor => MTLLogicOperation.Nor, - LogicalOp.Equiv => MTLLogicOperation.Equivalence, - LogicalOp.Invert => MTLLogicOperation.Invert, - LogicalOp.OrReverse => MTLLogicOperation.OrReverse, - LogicalOp.CopyInverted => MTLLogicOperation.CopyInverted, - LogicalOp.OrInverted => MTLLogicOperation.OrInverted, - LogicalOp.Nand => MTLLogicOperation.Nand, - LogicalOp.Set => MTLLogicOperation.Set, - _ => LogInvalidAndReturn(op, nameof(LogicalOp), MTLLogicOperation.And) - }; - } - - public static MTLSamplerMinMagFilter Convert(this MagFilter filter) - { - return filter switch - { - MagFilter.Nearest => MTLSamplerMinMagFilter.Nearest, - MagFilter.Linear => MTLSamplerMinMagFilter.Linear, - _ => LogInvalidAndReturn(filter, nameof(MagFilter), MTLSamplerMinMagFilter.Nearest) - }; - } - - public static (MTLSamplerMinMagFilter, MTLSamplerMipFilter) Convert(this MinFilter filter) - { - return filter switch - { - MinFilter.Nearest => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest), - MinFilter.Linear => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Linear), - MinFilter.NearestMipmapNearest => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest), - MinFilter.LinearMipmapNearest => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Nearest), - MinFilter.NearestMipmapLinear => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Linear), - MinFilter.LinearMipmapLinear => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Linear), - _ => LogInvalidAndReturn(filter, nameof(MinFilter), (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest)) - - }; - } - - public static MTLPrimitiveType Convert(this PrimitiveTopology topology) - { - return topology switch - { - PrimitiveTopology.Points => MTLPrimitiveType.Point, - PrimitiveTopology.Lines => MTLPrimitiveType.Line, - PrimitiveTopology.LineStrip => MTLPrimitiveType.LineStrip, - PrimitiveTopology.Triangles => MTLPrimitiveType.Triangle, - PrimitiveTopology.TriangleStrip => MTLPrimitiveType.TriangleStrip, - _ => LogInvalidAndReturn(topology, nameof(PrimitiveTopology), MTLPrimitiveType.Triangle) - }; - } - - public static MTLStencilOperation Convert(this StencilOp op) - { - return op switch - { - StencilOp.Keep or StencilOp.KeepGl => MTLStencilOperation.Keep, - StencilOp.Zero or StencilOp.ZeroGl => MTLStencilOperation.Zero, - StencilOp.Replace or StencilOp.ReplaceGl => MTLStencilOperation.Replace, - StencilOp.IncrementAndClamp or StencilOp.IncrementAndClampGl => MTLStencilOperation.IncrementClamp, - StencilOp.DecrementAndClamp or StencilOp.DecrementAndClampGl => MTLStencilOperation.DecrementClamp, - StencilOp.Invert or StencilOp.InvertGl => MTLStencilOperation.Invert, - StencilOp.IncrementAndWrap or StencilOp.IncrementAndWrapGl => MTLStencilOperation.IncrementWrap, - StencilOp.DecrementAndWrap or StencilOp.DecrementAndWrapGl => MTLStencilOperation.DecrementWrap, - _ => LogInvalidAndReturn(op, nameof(StencilOp), MTLStencilOperation.Keep) - }; - } - - public static MTLTextureType Convert(this Target target) - { - return target switch - { - Target.TextureBuffer => MTLTextureType.TextureBuffer, - Target.Texture1D => MTLTextureType.Type1D, - Target.Texture1DArray => MTLTextureType.Type1DArray, - Target.Texture2D => MTLTextureType.Type2D, - Target.Texture2DArray => MTLTextureType.Type2DArray, - Target.Texture2DMultisample => MTLTextureType.Type2DMultisample, - Target.Texture2DMultisampleArray => MTLTextureType.Type2DMultisampleArray, - Target.Texture3D => MTLTextureType.Type3D, - Target.Cubemap => MTLTextureType.Cube, - Target.CubemapArray => MTLTextureType.CubeArray, - _ => LogInvalidAndReturn(target, nameof(Target), MTLTextureType.Type2D) - }; - } - - public static MTLTextureSwizzle Convert(this SwizzleComponent swizzleComponent) - { - return swizzleComponent switch - { - SwizzleComponent.Zero => MTLTextureSwizzle.Zero, - SwizzleComponent.One => MTLTextureSwizzle.One, - SwizzleComponent.Red => MTLTextureSwizzle.Red, - SwizzleComponent.Green => MTLTextureSwizzle.Green, - SwizzleComponent.Blue => MTLTextureSwizzle.Blue, - SwizzleComponent.Alpha => MTLTextureSwizzle.Alpha, - _ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), MTLTextureSwizzle.Zero) - }; - } - - public static MTLVertexFormat Convert(this Format format) - { - return format switch - { - Format.R16Float => MTLVertexFormat.Half, - Format.R16G16Float => MTLVertexFormat.Half2, - Format.R16G16B16Float => MTLVertexFormat.Half3, - Format.R16G16B16A16Float => MTLVertexFormat.Half4, - Format.R32Float => MTLVertexFormat.Float, - Format.R32G32Float => MTLVertexFormat.Float2, - Format.R32G32B32Float => MTLVertexFormat.Float3, - Format.R11G11B10Float => MTLVertexFormat.FloatRG11B10, - Format.R32G32B32A32Float => MTLVertexFormat.Float4, - Format.R8Uint => MTLVertexFormat.UChar, - Format.R8G8Uint => MTLVertexFormat.UChar2, - Format.R8G8B8Uint => MTLVertexFormat.UChar3, - Format.R8G8B8A8Uint => MTLVertexFormat.UChar4, - Format.R16Uint => MTLVertexFormat.UShort, - Format.R16G16Uint => MTLVertexFormat.UShort2, - Format.R16G16B16Uint => MTLVertexFormat.UShort3, - Format.R16G16B16A16Uint => MTLVertexFormat.UShort4, - Format.R32Uint => MTLVertexFormat.UInt, - Format.R32G32Uint => MTLVertexFormat.UInt2, - Format.R32G32B32Uint => MTLVertexFormat.UInt3, - Format.R32G32B32A32Uint => MTLVertexFormat.UInt4, - Format.R8Sint => MTLVertexFormat.Char, - Format.R8G8Sint => MTLVertexFormat.Char2, - Format.R8G8B8Sint => MTLVertexFormat.Char3, - Format.R8G8B8A8Sint => MTLVertexFormat.Char4, - Format.R16Sint => MTLVertexFormat.Short, - Format.R16G16Sint => MTLVertexFormat.Short2, - Format.R16G16B16Sint => MTLVertexFormat.Short3, - Format.R16G16B16A16Sint => MTLVertexFormat.Short4, - Format.R32Sint => MTLVertexFormat.Int, - Format.R32G32Sint => MTLVertexFormat.Int2, - Format.R32G32B32Sint => MTLVertexFormat.Int3, - Format.R32G32B32A32Sint => MTLVertexFormat.Int4, - Format.R8Unorm => MTLVertexFormat.UCharNormalized, - Format.R8G8Unorm => MTLVertexFormat.UChar2Normalized, - Format.R8G8B8Unorm => MTLVertexFormat.UChar3Normalized, - Format.R8G8B8A8Unorm => MTLVertexFormat.UChar4Normalized, - Format.R16Unorm => MTLVertexFormat.UShortNormalized, - Format.R16G16Unorm => MTLVertexFormat.UShort2Normalized, - Format.R16G16B16Unorm => MTLVertexFormat.UShort3Normalized, - Format.R16G16B16A16Unorm => MTLVertexFormat.UShort4Normalized, - Format.R10G10B10A2Unorm => MTLVertexFormat.UInt1010102Normalized, - Format.R8Snorm => MTLVertexFormat.CharNormalized, - Format.R8G8Snorm => MTLVertexFormat.Char2Normalized, - Format.R8G8B8Snorm => MTLVertexFormat.Char3Normalized, - Format.R8G8B8A8Snorm => MTLVertexFormat.Char4Normalized, - Format.R16Snorm => MTLVertexFormat.ShortNormalized, - Format.R16G16Snorm => MTLVertexFormat.Short2Normalized, - Format.R16G16B16Snorm => MTLVertexFormat.Short3Normalized, - Format.R16G16B16A16Snorm => MTLVertexFormat.Short4Normalized, - Format.R10G10B10A2Snorm => MTLVertexFormat.Int1010102Normalized, - - _ => LogInvalidAndReturn(format, nameof(Format), MTLVertexFormat.Float4) - }; - } - - private static T2 LogInvalidAndReturn(T1 value, string name, T2 defaultValue = default) - { - Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}."); - - return defaultValue; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/FenceHolder.cs b/src/Ryujinx.Graphics.Metal/FenceHolder.cs deleted file mode 100644 index a8dd28c0d..000000000 --- a/src/Ryujinx.Graphics.Metal/FenceHolder.cs +++ /dev/null @@ -1,77 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class FenceHolder : IDisposable - { - private MTLCommandBuffer _fence; - private int _referenceCount; - private bool _disposed; - - public FenceHolder(MTLCommandBuffer fence) - { - _fence = fence; - _referenceCount = 1; - } - - public MTLCommandBuffer GetUnsafe() - { - return _fence; - } - - public bool TryGet(out MTLCommandBuffer fence) - { - int lastValue; - do - { - lastValue = _referenceCount; - - if (lastValue == 0) - { - fence = default; - return false; - } - } while (Interlocked.CompareExchange(ref _referenceCount, lastValue + 1, lastValue) != lastValue); - - fence = _fence; - return true; - } - - public MTLCommandBuffer Get() - { - Interlocked.Increment(ref _referenceCount); - return _fence; - } - - public void Put() - { - if (Interlocked.Decrement(ref _referenceCount) == 0) - { - _fence = default; - } - } - - public void Wait() - { - _fence.WaitUntilCompleted(); - } - - public bool IsSignaled() - { - return _fence.Status == MTLCommandBufferStatus.Completed; - } - - public void Dispose() - { - if (!_disposed) - { - Put(); - _disposed = true; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/FormatConverter.cs b/src/Ryujinx.Graphics.Metal/FormatConverter.cs deleted file mode 100644 index e099187b8..000000000 --- a/src/Ryujinx.Graphics.Metal/FormatConverter.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.Metal -{ - class FormatConverter - { - public static void ConvertD24S8ToD32FS8(Span output, ReadOnlySpan input) - { - const float UnormToFloat = 1f / 0xffffff; - - Span outputUint = MemoryMarshal.Cast(output); - ReadOnlySpan inputUint = MemoryMarshal.Cast(input); - - int i = 0; - - for (; i < inputUint.Length; i++) - { - uint depthStencil = inputUint[i]; - uint depth = depthStencil >> 8; - uint stencil = depthStencil & 0xff; - - int j = i * 2; - - outputUint[j] = (uint)BitConverter.SingleToInt32Bits(depth * UnormToFloat); - outputUint[j + 1] = stencil; - } - } - - public static void ConvertD32FS8ToD24S8(Span output, ReadOnlySpan input) - { - Span outputUint = MemoryMarshal.Cast(output); - ReadOnlySpan inputUint = MemoryMarshal.Cast(input); - - int i = 0; - - for (; i < inputUint.Length; i += 2) - { - float depth = BitConverter.Int32BitsToSingle((int)inputUint[i]); - uint stencil = inputUint[i + 1]; - uint depthStencil = (Math.Clamp((uint)(depth * 0xffffff), 0, 0xffffff) << 8) | (stencil & 0xff); - - int j = i >> 1; - - outputUint[j] = depthStencil; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/FormatTable.cs b/src/Ryujinx.Graphics.Metal/FormatTable.cs deleted file mode 100644 index 10c8b435c..000000000 --- a/src/Ryujinx.Graphics.Metal/FormatTable.cs +++ /dev/null @@ -1,196 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - static class FormatTable - { - private static readonly MTLPixelFormat[] _table; - - static FormatTable() - { - _table = new MTLPixelFormat[Enum.GetNames(typeof(Format)).Length]; - - Add(Format.R8Unorm, MTLPixelFormat.R8Unorm); - Add(Format.R8Snorm, MTLPixelFormat.R8Snorm); - Add(Format.R8Uint, MTLPixelFormat.R8Uint); - Add(Format.R8Sint, MTLPixelFormat.R8Sint); - Add(Format.R16Float, MTLPixelFormat.R16Float); - Add(Format.R16Unorm, MTLPixelFormat.R16Unorm); - Add(Format.R16Snorm, MTLPixelFormat.R16Snorm); - Add(Format.R16Uint, MTLPixelFormat.R16Uint); - Add(Format.R16Sint, MTLPixelFormat.R16Sint); - Add(Format.R32Float, MTLPixelFormat.R32Float); - Add(Format.R32Uint, MTLPixelFormat.R32Uint); - Add(Format.R32Sint, MTLPixelFormat.R32Sint); - Add(Format.R8G8Unorm, MTLPixelFormat.RG8Unorm); - Add(Format.R8G8Snorm, MTLPixelFormat.RG8Snorm); - Add(Format.R8G8Uint, MTLPixelFormat.RG8Uint); - Add(Format.R8G8Sint, MTLPixelFormat.RG8Sint); - Add(Format.R16G16Float, MTLPixelFormat.RG16Float); - Add(Format.R16G16Unorm, MTLPixelFormat.RG16Unorm); - Add(Format.R16G16Snorm, MTLPixelFormat.RG16Snorm); - Add(Format.R16G16Uint, MTLPixelFormat.RG16Uint); - Add(Format.R16G16Sint, MTLPixelFormat.RG16Sint); - Add(Format.R32G32Float, MTLPixelFormat.RG32Float); - Add(Format.R32G32Uint, MTLPixelFormat.RG32Uint); - Add(Format.R32G32Sint, MTLPixelFormat.RG32Sint); - // Add(Format.R8G8B8Unorm, MTLPixelFormat.R8G8B8Unorm); - // Add(Format.R8G8B8Snorm, MTLPixelFormat.R8G8B8Snorm); - // Add(Format.R8G8B8Uint, MTLPixelFormat.R8G8B8Uint); - // Add(Format.R8G8B8Sint, MTLPixelFormat.R8G8B8Sint); - // Add(Format.R16G16B16Float, MTLPixelFormat.R16G16B16Float); - // Add(Format.R16G16B16Unorm, MTLPixelFormat.R16G16B16Unorm); - // Add(Format.R16G16B16Snorm, MTLPixelFormat.R16G16B16SNorm); - // Add(Format.R16G16B16Uint, MTLPixelFormat.R16G16B16Uint); - // Add(Format.R16G16B16Sint, MTLPixelFormat.R16G16B16Sint); - // Add(Format.R32G32B32Float, MTLPixelFormat.R32G32B32Sfloat); - // Add(Format.R32G32B32Uint, MTLPixelFormat.R32G32B32Uint); - // Add(Format.R32G32B32Sint, MTLPixelFormat.R32G32B32Sint); - Add(Format.R8G8B8A8Unorm, MTLPixelFormat.RGBA8Unorm); - Add(Format.R8G8B8A8Snorm, MTLPixelFormat.RGBA8Snorm); - Add(Format.R8G8B8A8Uint, MTLPixelFormat.RGBA8Uint); - Add(Format.R8G8B8A8Sint, MTLPixelFormat.RGBA8Sint); - Add(Format.R16G16B16A16Float, MTLPixelFormat.RGBA16Float); - Add(Format.R16G16B16A16Unorm, MTLPixelFormat.RGBA16Unorm); - Add(Format.R16G16B16A16Snorm, MTLPixelFormat.RGBA16Snorm); - Add(Format.R16G16B16A16Uint, MTLPixelFormat.RGBA16Uint); - Add(Format.R16G16B16A16Sint, MTLPixelFormat.RGBA16Sint); - Add(Format.R32G32B32A32Float, MTLPixelFormat.RGBA32Float); - Add(Format.R32G32B32A32Uint, MTLPixelFormat.RGBA32Uint); - Add(Format.R32G32B32A32Sint, MTLPixelFormat.RGBA32Sint); - Add(Format.S8Uint, MTLPixelFormat.Stencil8); - Add(Format.D16Unorm, MTLPixelFormat.Depth16Unorm); - Add(Format.S8UintD24Unorm, MTLPixelFormat.Depth24UnormStencil8); - Add(Format.X8UintD24Unorm, MTLPixelFormat.Depth24UnormStencil8); - Add(Format.D32Float, MTLPixelFormat.Depth32Float); - Add(Format.D24UnormS8Uint, MTLPixelFormat.Depth24UnormStencil8); - Add(Format.D32FloatS8Uint, MTLPixelFormat.Depth32FloatStencil8); - Add(Format.R8G8B8A8Srgb, MTLPixelFormat.RGBA8UnormsRGB); - // Add(Format.R4G4Unorm, MTLPixelFormat.R4G4Unorm); - Add(Format.R4G4B4A4Unorm, MTLPixelFormat.RGBA8Unorm); - // Add(Format.R5G5B5X1Unorm, MTLPixelFormat.R5G5B5X1Unorm); - Add(Format.R5G5B5A1Unorm, MTLPixelFormat.BGR5A1Unorm); - Add(Format.R5G6B5Unorm, MTLPixelFormat.B5G6R5Unorm); - Add(Format.R10G10B10A2Unorm, MTLPixelFormat.RGB10A2Unorm); - Add(Format.R10G10B10A2Uint, MTLPixelFormat.RGB10A2Uint); - Add(Format.R11G11B10Float, MTLPixelFormat.RG11B10Float); - Add(Format.R9G9B9E5Float, MTLPixelFormat.RGB9E5Float); - Add(Format.Bc1RgbaUnorm, MTLPixelFormat.BC1RGBA); - Add(Format.Bc2Unorm, MTLPixelFormat.BC2RGBA); - Add(Format.Bc3Unorm, MTLPixelFormat.BC3RGBA); - Add(Format.Bc1RgbaSrgb, MTLPixelFormat.BC1RGBAsRGB); - Add(Format.Bc2Srgb, MTLPixelFormat.BC2RGBAsRGB); - Add(Format.Bc3Srgb, MTLPixelFormat.BC3RGBAsRGB); - Add(Format.Bc4Unorm, MTLPixelFormat.BC4RUnorm); - Add(Format.Bc4Snorm, MTLPixelFormat.BC4RSnorm); - Add(Format.Bc5Unorm, MTLPixelFormat.BC5RGUnorm); - Add(Format.Bc5Snorm, MTLPixelFormat.BC5RGSnorm); - Add(Format.Bc7Unorm, MTLPixelFormat.BC7RGBAUnorm); - Add(Format.Bc7Srgb, MTLPixelFormat.BC7RGBAUnormsRGB); - Add(Format.Bc6HSfloat, MTLPixelFormat.BC6HRGBFloat); - Add(Format.Bc6HUfloat, MTLPixelFormat.BC6HRGBUfloat); - Add(Format.Etc2RgbUnorm, MTLPixelFormat.ETC2RGB8); - // Add(Format.Etc2RgbaUnorm, MTLPixelFormat.ETC2RGBA8); - Add(Format.Etc2RgbPtaUnorm, MTLPixelFormat.ETC2RGB8A1); - Add(Format.Etc2RgbSrgb, MTLPixelFormat.ETC2RGB8sRGB); - // Add(Format.Etc2RgbaSrgb, MTLPixelFormat.ETC2RGBA8sRGB); - Add(Format.Etc2RgbPtaSrgb, MTLPixelFormat.ETC2RGB8A1sRGB); - // Add(Format.R8Uscaled, MTLPixelFormat.R8Uscaled); - // Add(Format.R8Sscaled, MTLPixelFormat.R8Sscaled); - // Add(Format.R16Uscaled, MTLPixelFormat.R16Uscaled); - // Add(Format.R16Sscaled, MTLPixelFormat.R16Sscaled); - // Add(Format.R32Uscaled, MTLPixelFormat.R32Uscaled); - // Add(Format.R32Sscaled, MTLPixelFormat.R32Sscaled); - // Add(Format.R8G8Uscaled, MTLPixelFormat.R8G8Uscaled); - // Add(Format.R8G8Sscaled, MTLPixelFormat.R8G8Sscaled); - // Add(Format.R16G16Uscaled, MTLPixelFormat.R16G16Uscaled); - // Add(Format.R16G16Sscaled, MTLPixelFormat.R16G16Sscaled); - // Add(Format.R32G32Uscaled, MTLPixelFormat.R32G32Uscaled); - // Add(Format.R32G32Sscaled, MTLPixelFormat.R32G32Sscaled); - // Add(Format.R8G8B8Uscaled, MTLPixelFormat.R8G8B8Uscaled); - // Add(Format.R8G8B8Sscaled, MTLPixelFormat.R8G8B8Sscaled); - // Add(Format.R16G16B16Uscaled, MTLPixelFormat.R16G16B16Uscaled); - // Add(Format.R16G16B16Sscaled, MTLPixelFormat.R16G16B16Sscaled); - // Add(Format.R32G32B32Uscaled, MTLPixelFormat.R32G32B32Uscaled); - // Add(Format.R32G32B32Sscaled, MTLPixelFormat.R32G32B32Sscaled); - // Add(Format.R8G8B8A8Uscaled, MTLPixelFormat.R8G8B8A8Uscaled); - // Add(Format.R8G8B8A8Sscaled, MTLPixelFormat.R8G8B8A8Sscaled); - // Add(Format.R16G16B16A16Uscaled, MTLPixelFormat.R16G16B16A16Uscaled); - // Add(Format.R16G16B16A16Sscaled, MTLPixelFormat.R16G16B16A16Sscaled); - // Add(Format.R32G32B32A32Uscaled, MTLPixelFormat.R32G32B32A32Uscaled); - // Add(Format.R32G32B32A32Sscaled, MTLPixelFormat.R32G32B32A32Sscaled); - // Add(Format.R10G10B10A2Snorm, MTLPixelFormat.A2B10G10R10SNormPack32); - // Add(Format.R10G10B10A2Sint, MTLPixelFormat.A2B10G10R10SintPack32); - // Add(Format.R10G10B10A2Uscaled, MTLPixelFormat.A2B10G10R10UscaledPack32); - // Add(Format.R10G10B10A2Sscaled, MTLPixelFormat.A2B10G10R10SscaledPack32); - Add(Format.Astc4x4Unorm, MTLPixelFormat.ASTC4x4LDR); - Add(Format.Astc5x4Unorm, MTLPixelFormat.ASTC5x4LDR); - Add(Format.Astc5x5Unorm, MTLPixelFormat.ASTC5x5LDR); - Add(Format.Astc6x5Unorm, MTLPixelFormat.ASTC6x5LDR); - Add(Format.Astc6x6Unorm, MTLPixelFormat.ASTC6x6LDR); - Add(Format.Astc8x5Unorm, MTLPixelFormat.ASTC8x5LDR); - Add(Format.Astc8x6Unorm, MTLPixelFormat.ASTC8x6LDR); - Add(Format.Astc8x8Unorm, MTLPixelFormat.ASTC8x8LDR); - Add(Format.Astc10x5Unorm, MTLPixelFormat.ASTC10x5LDR); - Add(Format.Astc10x6Unorm, MTLPixelFormat.ASTC10x6LDR); - Add(Format.Astc10x8Unorm, MTLPixelFormat.ASTC10x8LDR); - Add(Format.Astc10x10Unorm, MTLPixelFormat.ASTC10x10LDR); - Add(Format.Astc12x10Unorm, MTLPixelFormat.ASTC12x10LDR); - Add(Format.Astc12x12Unorm, MTLPixelFormat.ASTC12x12LDR); - Add(Format.Astc4x4Srgb, MTLPixelFormat.ASTC4x4sRGB); - Add(Format.Astc5x4Srgb, MTLPixelFormat.ASTC5x4sRGB); - Add(Format.Astc5x5Srgb, MTLPixelFormat.ASTC5x5sRGB); - Add(Format.Astc6x5Srgb, MTLPixelFormat.ASTC6x5sRGB); - Add(Format.Astc6x6Srgb, MTLPixelFormat.ASTC6x6sRGB); - Add(Format.Astc8x5Srgb, MTLPixelFormat.ASTC8x5sRGB); - Add(Format.Astc8x6Srgb, MTLPixelFormat.ASTC8x6sRGB); - Add(Format.Astc8x8Srgb, MTLPixelFormat.ASTC8x8sRGB); - Add(Format.Astc10x5Srgb, MTLPixelFormat.ASTC10x5sRGB); - Add(Format.Astc10x6Srgb, MTLPixelFormat.ASTC10x6sRGB); - Add(Format.Astc10x8Srgb, MTLPixelFormat.ASTC10x8sRGB); - Add(Format.Astc10x10Srgb, MTLPixelFormat.ASTC10x10sRGB); - Add(Format.Astc12x10Srgb, MTLPixelFormat.ASTC12x10sRGB); - Add(Format.Astc12x12Srgb, MTLPixelFormat.ASTC12x12sRGB); - Add(Format.B5G6R5Unorm, MTLPixelFormat.B5G6R5Unorm); - Add(Format.B5G5R5A1Unorm, MTLPixelFormat.BGR5A1Unorm); - Add(Format.A1B5G5R5Unorm, MTLPixelFormat.A1BGR5Unorm); - Add(Format.B8G8R8A8Unorm, MTLPixelFormat.BGRA8Unorm); - Add(Format.B8G8R8A8Srgb, MTLPixelFormat.BGRA8UnormsRGB); - } - - private static void Add(Format format, MTLPixelFormat mtlFormat) - { - _table[(int)format] = mtlFormat; - } - - public static MTLPixelFormat GetFormat(Format format) - { - MTLPixelFormat mtlFormat = _table[(int)format]; - - if (IsD24S8(format)) - { - if (!MTLDevice.CreateSystemDefaultDevice().Depth24Stencil8PixelFormatSupported) - { - mtlFormat = MTLPixelFormat.Depth32FloatStencil8; - } - } - - if (mtlFormat == MTLPixelFormat.Invalid) - { - Logger.Error?.PrintMsg(LogClass.Gpu, $"Format {format} is not supported by the host."); - } - - return mtlFormat; - } - - public static bool IsD24S8(Format format) - { - return format == Format.D24UnormS8Uint || format == Format.S8UintD24Unorm || format == Format.X8UintD24Unorm; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/HardwareInfo.cs b/src/Ryujinx.Graphics.Metal/HardwareInfo.cs deleted file mode 100644 index f6a132f09..000000000 --- a/src/Ryujinx.Graphics.Metal/HardwareInfo.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.Metal -{ - static partial class HardwareInfoTools - { - - private readonly static IntPtr _kCFAllocatorDefault = IntPtr.Zero; - private readonly static UInt32 _kCFStringEncodingASCII = 0x0600; - private const string IOKit = "/System/Library/Frameworks/IOKit.framework/IOKit"; - private const string CoreFoundation = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"; - - [LibraryImport(IOKit, StringMarshalling = StringMarshalling.Utf8)] - private static partial IntPtr IOServiceMatching(string name); - - [LibraryImport(IOKit)] - private static partial IntPtr IOServiceGetMatchingService(IntPtr mainPort, IntPtr matching); - - [LibraryImport(IOKit)] - private static partial IntPtr IORegistryEntryCreateCFProperty(IntPtr entry, IntPtr key, IntPtr allocator, UInt32 options); - - [LibraryImport(CoreFoundation, StringMarshalling = StringMarshalling.Utf8)] - private static partial IntPtr CFStringCreateWithCString(IntPtr allocator, string cString, UInt32 encoding); - - [LibraryImport(CoreFoundation)] - [return: MarshalAs(UnmanagedType.U1)] - public static partial bool CFStringGetCString(IntPtr theString, IntPtr buffer, long bufferSizes, UInt32 encoding); - - [LibraryImport(CoreFoundation)] - public static partial IntPtr CFDataGetBytePtr(IntPtr theData); - - static string GetNameFromId(uint id) - { - return id switch - { - 0x1002 => "AMD", - 0x106B => "Apple", - 0x10DE => "NVIDIA", - 0x13B5 => "ARM", - 0x8086 => "Intel", - _ => $"0x{id:X}" - }; - } - - public static string GetVendor() - { - IntPtr serviceDict = IOServiceMatching("IOGPU"); - IntPtr service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict); - IntPtr cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "vendor-id", _kCFStringEncodingASCII); - IntPtr cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0); - - byte[] buffer = new byte[4]; - IntPtr bufferPtr = CFDataGetBytePtr(cfProperty); - Marshal.Copy(bufferPtr, buffer, 0, buffer.Length); - - uint vendorId = BitConverter.ToUInt32(buffer); - - return GetNameFromId(vendorId); - } - - public static string GetModel() - { - IntPtr serviceDict = IOServiceMatching("IOGPU"); - IntPtr service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict); - IntPtr cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "model", _kCFStringEncodingASCII); - IntPtr cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0); - - char[] buffer = new char[64]; - IntPtr bufferPtr = Marshal.AllocHGlobal(buffer.Length); - - if (CFStringGetCString(cfProperty, bufferPtr, buffer.Length, _kCFStringEncodingASCII)) - { - string model = Marshal.PtrToStringUTF8(bufferPtr); - Marshal.FreeHGlobal(bufferPtr); - return model; - } - - return string.Empty; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/HashTableSlim.cs b/src/Ryujinx.Graphics.Metal/HashTableSlim.cs deleted file mode 100644 index 267acc6f4..000000000 --- a/src/Ryujinx.Graphics.Metal/HashTableSlim.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace Ryujinx.Graphics.Metal -{ - interface IRefEquatable - { - bool Equals(ref T other); - } - - class HashTableSlim where TKey : IRefEquatable - { - private const int TotalBuckets = 16; // Must be power of 2 - private const int TotalBucketsMask = TotalBuckets - 1; - - private struct Entry - { - public int Hash; - public TKey Key; - public TValue Value; - } - - private struct Bucket - { - public int Length; - public Entry[] Entries; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly Span AsSpan() - { - return Entries == null ? Span.Empty : Entries.AsSpan(0, Length); - } - } - - private readonly Bucket[] _hashTable = new Bucket[TotalBuckets]; - - public IEnumerable Keys - { - get - { - foreach (Bucket bucket in _hashTable) - { - for (int i = 0; i < bucket.Length; i++) - { - yield return bucket.Entries[i].Key; - } - } - } - } - - public IEnumerable Values - { - get - { - foreach (Bucket bucket in _hashTable) - { - for (int i = 0; i < bucket.Length; i++) - { - yield return bucket.Entries[i].Value; - } - } - } - } - - public void Add(ref TKey key, TValue value) - { - Entry entry = new() - { - Hash = key.GetHashCode(), - Key = key, - Value = value, - }; - - int hashCode = key.GetHashCode(); - int bucketIndex = hashCode & TotalBucketsMask; - - ref Bucket bucket = ref _hashTable[bucketIndex]; - if (bucket.Entries != null) - { - int index = bucket.Length; - - if (index >= bucket.Entries.Length) - { - Array.Resize(ref bucket.Entries, index + 1); - } - - bucket.Entries[index] = entry; - } - else - { - bucket.Entries = - [ - entry - ]; - } - - bucket.Length++; - } - - public bool Remove(ref TKey key) - { - int hashCode = key.GetHashCode(); - - ref Bucket bucket = ref _hashTable[hashCode & TotalBucketsMask]; - Span entries = bucket.AsSpan(); - for (int i = 0; i < entries.Length; i++) - { - ref Entry entry = ref entries[i]; - - if (entry.Hash == hashCode && entry.Key.Equals(ref key)) - { - entries[(i + 1)..].CopyTo(entries[i..]); - bucket.Length--; - - return true; - } - } - - return false; - } - - public bool TryGetValue(ref TKey key, out TValue value) - { - int hashCode = key.GetHashCode(); - - Span entries = _hashTable[hashCode & TotalBucketsMask].AsSpan(); - for (int i = 0; i < entries.Length; i++) - { - ref Entry entry = ref entries[i]; - - if (entry.Hash == hashCode && entry.Key.Equals(ref key)) - { - value = entry.Value; - return true; - } - } - - value = default; - return false; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/HelperShader.cs b/src/Ryujinx.Graphics.Metal/HelperShader.cs deleted file mode 100644 index 2638a6eac..000000000 --- a/src/Ryujinx.Graphics.Metal/HelperShader.cs +++ /dev/null @@ -1,868 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; -using Ryujinx.Graphics.Shader.Translation; -using SharpMetal.Metal; -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class HelperShader : IDisposable - { - private const int ConvertElementsPerWorkgroup = 32 * 100; // Work group size of 32 times 100 elements. - private const string ShadersSourcePath = "/Ryujinx.Graphics.Metal/Shaders"; - private readonly MetalRenderer _renderer; - private readonly Pipeline _pipeline; - private MTLDevice _device; - - private readonly ISampler _samplerLinear; - private readonly ISampler _samplerNearest; - private readonly IProgram _programColorBlitF; - private readonly IProgram _programColorBlitI; - private readonly IProgram _programColorBlitU; - private readonly IProgram _programColorBlitMsF; - private readonly IProgram _programColorBlitMsI; - private readonly IProgram _programColorBlitMsU; - private readonly List _programsColorClearF = []; - private readonly List _programsColorClearI = []; - private readonly List _programsColorClearU = []; - private readonly IProgram _programDepthStencilClear; - private readonly IProgram _programStrideChange; - private readonly IProgram _programConvertD32S8ToD24S8; - private readonly IProgram _programConvertIndexBuffer; - private readonly IProgram _programDepthBlit; - private readonly IProgram _programDepthBlitMs; - private readonly IProgram _programStencilBlit; - private readonly IProgram _programStencilBlitMs; - - private readonly EncoderState _helperShaderState = new(); - - public HelperShader(MTLDevice device, MetalRenderer renderer, Pipeline pipeline) - { - _device = device; - _renderer = renderer; - _pipeline = pipeline; - - _samplerNearest = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest)); - _samplerLinear = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear)); - - ResourceLayout blitResourceLayout = new ResourceLayoutBuilder() - .Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 0) - .Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build(); - - string blitSource = ReadMsl("Blit.metal"); - - string blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal); - _programColorBlitF = new Program(renderer, device, [ - new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string blitSourceI = blitSource.Replace("FORMAT", "int"); - _programColorBlitI = new Program(renderer, device, [ - new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string blitSourceU = blitSource.Replace("FORMAT", "uint"); - _programColorBlitU = new Program(renderer, device, [ - new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string blitMsSource = ReadMsl("BlitMs.metal"); - - string blitMsSourceF = blitMsSource.Replace("FORMAT", "float"); - _programColorBlitMsF = new Program(renderer, device, [ - new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string blitMsSourceI = blitMsSource.Replace("FORMAT", "int"); - _programColorBlitMsI = new Program(renderer, device, [ - new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string blitMsSourceU = blitMsSource.Replace("FORMAT", "uint"); - _programColorBlitMsU = new Program(renderer, device, [ - new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - ResourceLayout colorClearResourceLayout = new ResourceLayoutBuilder() - .Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build(); - - string colorClearSource = ReadMsl("ColorClear.metal"); - - for (int i = 0; i < Constants.MaxColorAttachments; i++) - { - string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float"); - _programsColorClearF.Add(new Program(renderer, device, [ - new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) - ], colorClearResourceLayout)); - } - - for (int i = 0; i < Constants.MaxColorAttachments; i++) - { - string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int"); - _programsColorClearI.Add(new Program(renderer, device, [ - new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) - ], colorClearResourceLayout)); - } - - for (int i = 0; i < Constants.MaxColorAttachments; i++) - { - string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint"); - _programsColorClearU.Add(new Program(renderer, device, [ - new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) - ], colorClearResourceLayout)); - } - - string depthStencilClearSource = ReadMsl("DepthStencilClear.metal"); - _programDepthStencilClear = new Program(renderer, device, [ - new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl) - ], colorClearResourceLayout); - - ResourceLayout strideChangeResourceLayout = new ResourceLayoutBuilder() - .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); - - string strideChangeSource = ReadMsl("ChangeBufferStride.metal"); - _programStrideChange = new Program(renderer, device, [ - new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl) - ], strideChangeResourceLayout, new ComputeSize(64, 1, 1)); - - ResourceLayout convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder() - .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); - - string convertD32S8ToD24S8Source = ReadMsl("ConvertD32S8ToD24S8.metal"); - _programConvertD32S8ToD24S8 = new Program(renderer, device, [ - new ShaderSource(convertD32S8ToD24S8Source, ShaderStage.Compute, TargetLanguage.Msl) - ], convertD32S8ToD24S8ResourceLayout, new ComputeSize(64, 1, 1)); - - ResourceLayout convertIndexBufferLayout = new ResourceLayoutBuilder() - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true) - .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 3).Build(); - - string convertIndexBufferSource = ReadMsl("ConvertIndexBuffer.metal"); - _programConvertIndexBuffer = new Program(renderer, device, [ - new ShaderSource(convertIndexBufferSource, ShaderStage.Compute, TargetLanguage.Msl) - ], convertIndexBufferLayout, new ComputeSize(16, 1, 1)); - - string depthBlitSource = ReadMsl("DepthBlit.metal"); - _programDepthBlit = new Program(renderer, device, [ - new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string depthBlitMsSource = ReadMsl("DepthBlitMs.metal"); - _programDepthBlitMs = new Program(renderer, device, [ - new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string stencilBlitSource = ReadMsl("StencilBlit.metal"); - _programStencilBlit = new Program(renderer, device, [ - new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - - string stencilBlitMsSource = ReadMsl("StencilBlitMs.metal"); - _programStencilBlitMs = new Program(renderer, device, [ - new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), - new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) - ], blitResourceLayout); - } - - private static string ReadMsl(string fileName) - { - string msl = EmbeddedResources.ReadAllText(string.Join('/', ShadersSourcePath, fileName)); - -#pragma warning disable IDE0055 // Disable formatting - msl = msl.Replace("CONSTANT_BUFFERS_INDEX", $"{Constants.ConstantBuffersIndex}") - .Replace("STORAGE_BUFFERS_INDEX", $"{Constants.StorageBuffersIndex}") - .Replace("TEXTURES_INDEX", $"{Constants.TexturesIndex}") - .Replace("IMAGES_INDEX", $"{Constants.ImagesIndex}"); -#pragma warning restore IDE0055 - - return msl; - } - - public unsafe void BlitColor( - CommandBufferScoped cbs, - Texture src, - Texture dst, - Extents2D srcRegion, - Extents2D dstRegion, - bool linearFilter, - bool clear = false) - { - _pipeline.SwapState(_helperShaderState); - - const int RegionBufferSize = 16; - - ISampler sampler = linearFilter ? _samplerLinear : _samplerNearest; - - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, sampler); - - Span region = stackalloc float[RegionBufferSize / sizeof(float)]; - - region[0] = srcRegion.X1 / (float)src.Width; - region[1] = srcRegion.X2 / (float)src.Width; - region[2] = srcRegion.Y1 / (float)src.Height; - region[3] = srcRegion.Y2 / (float)src.Height; - - if (dstRegion.X1 > dstRegion.X2) - { - (region[0], region[1]) = (region[1], region[0]); - } - - if (dstRegion.Y1 > dstRegion.Y2) - { - (region[2], region[3]) = (region[3], region[2]); - } - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, region); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Rectangle rect = new( - MathF.Min(dstRegion.X1, dstRegion.X2), - MathF.Min(dstRegion.Y1, dstRegion.Y2), - MathF.Abs(dstRegion.X2 - dstRegion.X1), - MathF.Abs(dstRegion.Y2 - dstRegion.Y1)); - - Span viewports = stackalloc Viewport[16]; - - viewports[0] = new Viewport( - rect, - ViewportSwizzle.PositiveX, - ViewportSwizzle.PositiveY, - ViewportSwizzle.PositiveZ, - ViewportSwizzle.PositiveW, - 0f, - 1f); - - bool dstIsDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); - - if (dstIsDepthOrStencil) - { - // TODO: Depth & stencil blit! - Logger.Warning?.PrintMsg(LogClass.Gpu, "Requested a depth or stencil blit!"); - _pipeline.SwapState(null); - return; - } - - string debugGroupName = "Blit Color "; - - if (src.Info.Target.IsMultisample()) - { - if (dst.Info.Format.IsSint()) - { - debugGroupName += "MS Int"; - _pipeline.SetProgram(_programColorBlitMsI); - } - else if (dst.Info.Format.IsUint()) - { - debugGroupName += "MS UInt"; - _pipeline.SetProgram(_programColorBlitMsU); - } - else - { - debugGroupName += "MS Float"; - _pipeline.SetProgram(_programColorBlitMsF); - } - } - else - { - if (dst.Info.Format.IsSint()) - { - debugGroupName += "Int"; - _pipeline.SetProgram(_programColorBlitI); - } - else if (dst.Info.Format.IsUint()) - { - debugGroupName += "UInt"; - _pipeline.SetProgram(_programColorBlitU); - } - else - { - debugGroupName += "Float"; - _pipeline.SetProgram(_programColorBlitF); - } - } - - int dstWidth = dst.Width; - int dstHeight = dst.Height; - - Span> scissors = stackalloc Rectangle[16]; - - scissors[0] = new Rectangle(0, 0, dstWidth, dstHeight); - - _pipeline.SetRenderTargets([dst], null); - _pipeline.SetScissors(scissors); - - _pipeline.SetClearLoadAction(clear); - - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.Draw(4, 1, 0, 0, debugGroupName); - - // Cleanup - if (clear) - { - _pipeline.SetClearLoadAction(false); - } - - // Restore previous state - _pipeline.SwapState(null); - } - - public unsafe void BlitDepthStencil( - CommandBufferScoped cbs, - Texture src, - Texture dst, - Extents2D srcRegion, - Extents2D dstRegion) - { - _pipeline.SwapState(_helperShaderState); - - const int RegionBufferSize = 16; - - Span region = stackalloc float[RegionBufferSize / sizeof(float)]; - - region[0] = srcRegion.X1 / (float)src.Width; - region[1] = srcRegion.X2 / (float)src.Width; - region[2] = srcRegion.Y1 / (float)src.Height; - region[3] = srcRegion.Y2 / (float)src.Height; - - if (dstRegion.X1 > dstRegion.X2) - { - (region[0], region[1]) = (region[1], region[0]); - } - - if (dstRegion.Y1 > dstRegion.Y2) - { - (region[2], region[3]) = (region[3], region[2]); - } - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, region); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Span viewports = stackalloc Viewport[16]; - - Rectangle rect = new( - MathF.Min(dstRegion.X1, dstRegion.X2), - MathF.Min(dstRegion.Y1, dstRegion.Y2), - MathF.Abs(dstRegion.X2 - dstRegion.X1), - MathF.Abs(dstRegion.Y2 - dstRegion.Y1)); - - viewports[0] = new Viewport( - rect, - ViewportSwizzle.PositiveX, - ViewportSwizzle.PositiveY, - ViewportSwizzle.PositiveZ, - ViewportSwizzle.PositiveW, - 0f, - 1f); - - int dstWidth = dst.Width; - int dstHeight = dst.Height; - - Span> scissors = stackalloc Rectangle[16]; - - scissors[0] = new Rectangle(0, 0, dstWidth, dstHeight); - - _pipeline.SetRenderTargets([], dst); - _pipeline.SetScissors(scissors); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - - if (src.Info.Format is - Format.D16Unorm or - Format.D32Float or - Format.X8UintD24Unorm or - Format.D24UnormS8Uint or - Format.D32FloatS8Uint or - Format.S8UintD24Unorm) - { - Texture depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth); - - BlitDepthStencilDraw(depthTexture, isDepth: true); - - if (depthTexture != src) - { - depthTexture.Release(); - } - } - - if (src.Info.Format is - Format.S8Uint or - Format.D24UnormS8Uint or - Format.D32FloatS8Uint or - Format.S8UintD24Unorm) - { - Texture stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil); - - BlitDepthStencilDraw(stencilTexture, isDepth: false); - - if (stencilTexture != src) - { - stencilTexture.Release(); - } - } - - // Restore previous state - _pipeline.SwapState(null); - } - - private static Texture CreateDepthOrStencilView(Texture depthStencilTexture, DepthStencilMode depthStencilMode) - { - if (depthStencilTexture.Info.DepthStencilMode == depthStencilMode) - { - return depthStencilTexture; - } - - return (Texture)depthStencilTexture.CreateView(new TextureCreateInfo( - depthStencilTexture.Info.Width, - depthStencilTexture.Info.Height, - depthStencilTexture.Info.Depth, - depthStencilTexture.Info.Levels, - depthStencilTexture.Info.Samples, - depthStencilTexture.Info.BlockWidth, - depthStencilTexture.Info.BlockHeight, - depthStencilTexture.Info.BytesPerPixel, - depthStencilTexture.Info.Format, - depthStencilMode, - depthStencilTexture.Info.Target, - SwizzleComponent.Red, - SwizzleComponent.Green, - SwizzleComponent.Blue, - SwizzleComponent.Alpha), 0, 0); - } - - private void BlitDepthStencilDraw(Texture src, bool isDepth) - { - // TODO: Check this https://github.com/Ryujinx/Ryujinx/pull/5003/ - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, _samplerNearest); - - string debugGroupName; - - if (isDepth) - { - debugGroupName = "Depth Blit"; - _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); - _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always)); - } - else - { - debugGroupName = "Stencil Blit"; - _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programStencilBlitMs : _programStencilBlit); - _pipeline.SetStencilTest(CreateStencilTestDescriptor(true)); - } - - _pipeline.Draw(4, 1, 0, 0, debugGroupName); - - if (isDepth) - { - _pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always)); - } - else - { - _pipeline.SetStencilTest(CreateStencilTestDescriptor(false)); - } - } - - public unsafe void DrawTexture( - ITexture src, - ISampler srcSampler, - Extents2DF srcRegion, - Extents2DF dstRegion) - { - // Save current state - PredrawState state = _pipeline.SavePredrawState(); - - _pipeline.SetFaceCulling(false, Face.Front); - _pipeline.SetStencilTest(new StencilTestDescriptor()); - _pipeline.SetDepthTest(new DepthTestDescriptor()); - - const int RegionBufferSize = 16; - - _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, srcSampler); - - Span region = stackalloc float[RegionBufferSize / sizeof(float)]; - - region[0] = srcRegion.X1 / src.Width; - region[1] = srcRegion.X2 / src.Width; - region[2] = srcRegion.Y1 / src.Height; - region[3] = srcRegion.Y2 / src.Height; - - if (dstRegion.X1 > dstRegion.X2) - { - (region[0], region[1]) = (region[1], region[0]); - } - - if (dstRegion.Y1 > dstRegion.Y2) - { - (region[2], region[3]) = (region[3], region[2]); - } - - BufferHandle bufferHandle = _renderer.BufferManager.CreateWithHandle(RegionBufferSize); - _renderer.BufferManager.SetData(bufferHandle, 0, region); - _pipeline.SetUniformBuffers([new BufferAssignment(0, new BufferRange(bufferHandle, 0, RegionBufferSize))]); - - Span viewports = stackalloc Viewport[16]; - - Rectangle rect = new( - MathF.Min(dstRegion.X1, dstRegion.X2), - MathF.Min(dstRegion.Y1, dstRegion.Y2), - MathF.Abs(dstRegion.X2 - dstRegion.X1), - MathF.Abs(dstRegion.Y2 - dstRegion.Y1)); - - viewports[0] = new Viewport( - rect, - ViewportSwizzle.PositiveX, - ViewportSwizzle.PositiveY, - ViewportSwizzle.PositiveZ, - ViewportSwizzle.PositiveW, - 0f, - 1f); - - _pipeline.SetProgram(_programColorBlitF); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.Draw(4, 1, 0, 0, "Draw Texture"); - - _renderer.BufferManager.Delete(bufferHandle); - - // Restore previous state - _pipeline.RestorePredrawState(state); - } - - public void ConvertI8ToI16(CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size) - { - ChangeStride(cbs, src, dst, srcOffset, size, 1, 2); - } - - public unsafe void ChangeStride( - CommandBufferScoped cbs, - BufferHolder src, - BufferHolder dst, - int srcOffset, - int size, - int stride, - int newStride) - { - int elems = size / stride; - - Auto srcBuffer = src.GetBuffer(); - Auto dstBuffer = dst.GetBuffer(); - - const int ParamsBufferSize = 4 * sizeof(int); - - // Save current state - _pipeline.SwapState(_helperShaderState); - - Span shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)]; - - shaderParams[0] = stride; - shaderParams[1] = newStride; - shaderParams[2] = size; - shaderParams[3] = srcOffset; - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Span> sbRanges = new Auto[2]; - - sbRanges[0] = srcBuffer; - sbRanges[1] = dstBuffer; - _pipeline.SetStorageBuffers(1, sbRanges); - - _pipeline.SetProgram(_programStrideChange); - _pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1, "Change Stride"); - - // Restore previous state - _pipeline.SwapState(null); - } - - public unsafe void ConvertD32S8ToD24S8(CommandBufferScoped cbs, BufferHolder src, Auto dstBuffer, int pixelCount, int dstOffset) - { - int inSize = pixelCount * 2 * sizeof(int); - - Auto srcBuffer = src.GetBuffer(); - - const int ParamsBufferSize = sizeof(int) * 2; - - // Save current state - _pipeline.SwapState(_helperShaderState); - - Span shaderParams = stackalloc int[2]; - - shaderParams[0] = pixelCount; - shaderParams[1] = dstOffset; - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Span> sbRanges = new Auto[2]; - - sbRanges[0] = srcBuffer; - sbRanges[1] = dstBuffer; - _pipeline.SetStorageBuffers(1, sbRanges); - - _pipeline.SetProgram(_programConvertD32S8ToD24S8); - _pipeline.DispatchCompute(1 + inSize / ConvertElementsPerWorkgroup, 1, 1, "D32S8 to D24S8 Conversion"); - - // Restore previous state - _pipeline.SwapState(null); - } - - public void ConvertIndexBuffer( - CommandBufferScoped cbs, - BufferHolder src, - BufferHolder dst, - IndexBufferPattern pattern, - int indexSize, - int srcOffset, - int indexCount) - { - // TODO: Support conversion with primitive restart enabled. - - int primitiveCount = pattern.GetPrimitiveCount(indexCount); - int outputIndexSize = 4; - - Auto srcBuffer = src.GetBuffer(); - Auto dstBuffer = dst.GetBuffer(); - - const int ParamsBufferSize = 16 * sizeof(int); - - // Save current state - _pipeline.SwapState(_helperShaderState); - - Span shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)]; - - shaderParams[8] = pattern.PrimitiveVertices; - shaderParams[9] = pattern.PrimitiveVerticesOut; - shaderParams[10] = indexSize; - shaderParams[11] = outputIndexSize; - shaderParams[12] = pattern.BaseIndex; - shaderParams[13] = pattern.IndexStride; - shaderParams[14] = srcOffset; - shaderParams[15] = primitiveCount; - - pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]); - - using ScopedTemporaryBuffer patternScoped = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); - patternScoped.Holder.SetDataUnchecked(patternScoped.Offset, shaderParams); - - Span> sbRanges = new Auto[2]; - - sbRanges[0] = srcBuffer; - sbRanges[1] = dstBuffer; - _pipeline.SetStorageBuffers(1, sbRanges); - _pipeline.SetStorageBuffers([new BufferAssignment(3, patternScoped.Range)]); - - _pipeline.SetProgram(_programConvertIndexBuffer); - _pipeline.DispatchCompute(BitUtils.DivRoundUp(primitiveCount, 16), 1, 1, "Convert Index Buffer"); - - // Restore previous state - _pipeline.SwapState(null); - } - - public unsafe void ClearColor( - int index, - ReadOnlySpan clearColor, - uint componentMask, - int dstWidth, - int dstHeight, - Format format) - { - // Keep original scissor - DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors); - - // Save current state - EncoderState originalState = _pipeline.SwapState(_helperShaderState, clearFlags, false); - - // Inherit some state without fully recreating render pipeline. - RenderTargetCopy save = _helperShaderState.InheritForClear(originalState, false, index); - - const int ClearColorBufferSize = 16; - - // TODO: Flush - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearColorBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Span viewports = stackalloc Viewport[16]; - - // TODO: Set exact viewport! - viewports[0] = new Viewport( - new Rectangle(0, 0, dstWidth, dstHeight), - ViewportSwizzle.PositiveX, - ViewportSwizzle.PositiveY, - ViewportSwizzle.PositiveZ, - ViewportSwizzle.PositiveW, - 0f, - 1f); - - Span componentMasks = stackalloc uint[index + 1]; - componentMasks[index] = componentMask; - - string debugGroupName = "Clear Color "; - - if (format.IsSint()) - { - debugGroupName += "Int"; - _pipeline.SetProgram(_programsColorClearI[index]); - } - else if (format.IsUint()) - { - debugGroupName += "UInt"; - _pipeline.SetProgram(_programsColorClearU[index]); - } - else - { - debugGroupName += "Float"; - _pipeline.SetProgram(_programsColorClearF[index]); - } - - _pipeline.SetBlendState(index, new BlendDescriptor()); - _pipeline.SetFaceCulling(false, Face.Front); - _pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always)); - _pipeline.SetRenderTargetColorMasks(componentMasks); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.Draw(4, 1, 0, 0, debugGroupName); - - // Restore previous state - _pipeline.SwapState(null, clearFlags, false); - - _helperShaderState.Restore(save); - } - - public unsafe void ClearDepthStencil( - float depthValue, - bool depthMask, - int stencilValue, - int stencilMask, - int dstWidth, - int dstHeight) - { - // Keep original scissor - DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors); - MTLScissorRect[] helperScissors = _helperShaderState.Scissors; - - // Save current state - EncoderState originalState = _pipeline.SwapState(_helperShaderState, clearFlags, false); - - // Inherit some state without fully recreating render pipeline. - RenderTargetCopy save = _helperShaderState.InheritForClear(originalState, true); - - const int ClearDepthBufferSize = 16; - - using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearDepthBufferSize); - buffer.Holder.SetDataUnchecked(buffer.Offset, new ReadOnlySpan(ref depthValue)); - _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - - Span viewports = stackalloc Viewport[1]; - - viewports[0] = new Viewport( - new Rectangle(0, 0, dstWidth, dstHeight), - ViewportSwizzle.PositiveX, - ViewportSwizzle.PositiveY, - ViewportSwizzle.PositiveZ, - ViewportSwizzle.PositiveW, - 0f, - 1f); - - _pipeline.SetProgram(_programDepthStencilClear); - _pipeline.SetFaceCulling(false, Face.Front); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.SetViewports(viewports); - _pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always)); - _pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xFF, stencilMask)); - _pipeline.Draw(4, 1, 0, 0, "Clear Depth Stencil"); - - // Cleanup - _pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always)); - _pipeline.SetStencilTest(CreateStencilTestDescriptor(false)); - - // Restore previous state - _pipeline.SwapState(null, clearFlags, false); - - _helperShaderState.Restore(save); - } - - private static StencilTestDescriptor CreateStencilTestDescriptor( - bool enabled, - int refValue = 0, - int compareMask = 0xff, - int writeMask = 0xff) - { - return new StencilTestDescriptor( - enabled, - CompareOp.Always, - StencilOp.Replace, - StencilOp.Replace, - StencilOp.Replace, - refValue, - compareMask, - writeMask, - CompareOp.Always, - StencilOp.Replace, - StencilOp.Replace, - StencilOp.Replace, - refValue, - compareMask, - writeMask); - } - - public void Dispose() - { - _programColorBlitF.Dispose(); - _programColorBlitI.Dispose(); - _programColorBlitU.Dispose(); - _programColorBlitMsF.Dispose(); - _programColorBlitMsI.Dispose(); - _programColorBlitMsU.Dispose(); - - foreach (IProgram programColorClear in _programsColorClearF) - { - programColorClear.Dispose(); - } - - foreach (IProgram programColorClear in _programsColorClearU) - { - programColorClear.Dispose(); - } - - foreach (IProgram programColorClear in _programsColorClearI) - { - programColorClear.Dispose(); - } - - _programDepthStencilClear.Dispose(); - _pipeline.Dispose(); - _samplerLinear.Dispose(); - _samplerNearest.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/IdList.cs b/src/Ryujinx.Graphics.Metal/IdList.cs deleted file mode 100644 index 72c9d5fcc..000000000 --- a/src/Ryujinx.Graphics.Metal/IdList.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Metal -{ - class IdList where T : class - { - private readonly List _list; - private int _freeMin; - - public IdList() - { - _list = []; - _freeMin = 0; - } - - public int Add(T value) - { - int id; - int count = _list.Count; - id = _list.IndexOf(null, _freeMin); - - if ((uint)id < (uint)count) - { - _list[id] = value; - } - else - { - id = count; - _freeMin = id + 1; - - _list.Add(value); - } - - return id + 1; - } - - public void Remove(int id) - { - id--; - - int count = _list.Count; - - if ((uint)id >= (uint)count) - { - return; - } - - if (id + 1 == count) - { - // Trim unused items. - int removeIndex = id; - - while (removeIndex > 0 && _list[removeIndex - 1] == null) - { - removeIndex--; - } - - _list.RemoveRange(removeIndex, count - removeIndex); - - if (_freeMin > removeIndex) - { - _freeMin = removeIndex; - } - } - else - { - _list[id] = null; - - if (_freeMin > id) - { - _freeMin = id; - } - } - } - - public bool TryGetValue(int id, out T value) - { - id--; - - try - { - if ((uint)id < (uint)_list.Count) - { - value = _list[id]; - return value != null; - } - - value = null; - return false; - } - catch (ArgumentOutOfRangeException) - { - value = null; - return false; - } - catch (IndexOutOfRangeException) - { - value = null; - return false; - } - } - - public void Clear() - { - _list.Clear(); - _freeMin = 0; - } - - public IEnumerator GetEnumerator() - { - for (int i = 0; i < _list.Count; i++) - { - if (_list[i] != null) - { - yield return _list[i]; - } - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/ImageArray.cs b/src/Ryujinx.Graphics.Metal/ImageArray.cs deleted file mode 100644 index 9fa0df09d..000000000 --- a/src/Ryujinx.Graphics.Metal/ImageArray.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - internal class ImageArray : IImageArray - { - private readonly TextureRef[] _textureRefs; - private readonly TextureBuffer[] _bufferTextureRefs; - - private readonly bool _isBuffer; - private readonly Pipeline _pipeline; - - public ImageArray(int size, bool isBuffer, Pipeline pipeline) - { - if (isBuffer) - { - _bufferTextureRefs = new TextureBuffer[size]; - } - else - { - _textureRefs = new TextureRef[size]; - } - - _isBuffer = isBuffer; - _pipeline = pipeline; - } - - public void SetImages(int index, ITexture[] images) - { - for (int i = 0; i < images.Length; i++) - { - ITexture image = images[i]; - - if (image is TextureBuffer textureBuffer) - { - _bufferTextureRefs[index + i] = textureBuffer; - } - else if (image is Texture texture) - { - _textureRefs[index + i].Storage = texture; - } - else if (!_isBuffer) - { - _textureRefs[index + i].Storage = null; - } - else - { - _bufferTextureRefs[index + i] = null; - } - } - - SetDirty(); - } - - public TextureRef[] GetTextureRefs() - { - return _textureRefs; - } - - public TextureBuffer[] GetBufferTextureRefs() - { - return _bufferTextureRefs; - } - - private void SetDirty() - { - _pipeline.DirtyImages(); - } - - public void Dispose() { } - } -} diff --git a/src/Ryujinx.Graphics.Metal/IndexBufferPattern.cs b/src/Ryujinx.Graphics.Metal/IndexBufferPattern.cs deleted file mode 100644 index 24e3222fe..000000000 --- a/src/Ryujinx.Graphics.Metal/IndexBufferPattern.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - internal class IndexBufferPattern : IDisposable - { - public int PrimitiveVertices { get; } - public int PrimitiveVerticesOut { get; } - public int BaseIndex { get; } - public int[] OffsetIndex { get; } - public int IndexStride { get; } - public bool RepeatStart { get; } - - private readonly MetalRenderer _renderer; - private int _currentSize; - private BufferHandle _repeatingBuffer; - - public IndexBufferPattern(MetalRenderer renderer, - int primitiveVertices, - int primitiveVerticesOut, - int baseIndex, - int[] offsetIndex, - int indexStride, - bool repeatStart) - { - PrimitiveVertices = primitiveVertices; - PrimitiveVerticesOut = primitiveVerticesOut; - BaseIndex = baseIndex; - OffsetIndex = offsetIndex; - IndexStride = indexStride; - RepeatStart = repeatStart; - - _renderer = renderer; - } - - public int GetPrimitiveCount(int vertexCount) - { - return Math.Max(0, (vertexCount - BaseIndex) / IndexStride); - } - - public int GetConvertedCount(int indexCount) - { - int primitiveCount = GetPrimitiveCount(indexCount); - return primitiveCount * OffsetIndex.Length; - } - - public BufferHandle GetRepeatingBuffer(int vertexCount, out int indexCount) - { - int primitiveCount = GetPrimitiveCount(vertexCount); - indexCount = primitiveCount * PrimitiveVerticesOut; - - int expectedSize = primitiveCount * OffsetIndex.Length; - - if (expectedSize <= _currentSize && _repeatingBuffer != BufferHandle.Null) - { - return _repeatingBuffer; - } - - // Expand the repeating pattern to the number of requested primitives. - BufferHandle newBuffer = _renderer.BufferManager.CreateWithHandle(expectedSize * sizeof(int)); - - // Copy the old data to the new one. - if (_repeatingBuffer != BufferHandle.Null) - { - _renderer.Pipeline.CopyBuffer(_repeatingBuffer, newBuffer, 0, 0, _currentSize * sizeof(int)); - _renderer.BufferManager.Delete(_repeatingBuffer); - } - - _repeatingBuffer = newBuffer; - - // Add the additional repeats on top. - int newPrimitives = primitiveCount; - int oldPrimitives = (_currentSize) / OffsetIndex.Length; - - int[] newData; - - newPrimitives -= oldPrimitives; - newData = new int[expectedSize - _currentSize]; - - int outOffset = 0; - int index = oldPrimitives * IndexStride + BaseIndex; - - for (int i = 0; i < newPrimitives; i++) - { - if (RepeatStart) - { - // Used for triangle fan - newData[outOffset++] = 0; - } - - for (int j = RepeatStart ? 1 : 0; j < OffsetIndex.Length; j++) - { - newData[outOffset++] = index + OffsetIndex[j]; - } - - index += IndexStride; - } - - _renderer.SetBufferData(newBuffer, _currentSize * sizeof(int), MemoryMarshal.Cast(newData)); - _currentSize = expectedSize; - - return newBuffer; - } - - public void Dispose() - { - if (_repeatingBuffer != BufferHandle.Null) - { - _renderer.BufferManager.Delete(_repeatingBuffer); - _repeatingBuffer = BufferHandle.Null; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/IndexBufferState.cs b/src/Ryujinx.Graphics.Metal/IndexBufferState.cs deleted file mode 100644 index 02c9ff9ef..000000000 --- a/src/Ryujinx.Graphics.Metal/IndexBufferState.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly internal struct IndexBufferState - { - public static IndexBufferState Null => new(BufferHandle.Null, 0, 0); - - private readonly int _offset; - private readonly int _size; - private readonly IndexType _type; - - private readonly BufferHandle _handle; - - public IndexBufferState(BufferHandle handle, int offset, int size, IndexType type = IndexType.UInt) - { - _handle = handle; - _offset = offset; - _size = size; - _type = type; - } - - public (MTLBuffer, int, MTLIndexType) GetIndexBuffer(MetalRenderer renderer, CommandBufferScoped cbs) - { - Auto autoBuffer; - int offset, size; - MTLIndexType type; - - if (_type == IndexType.UByte) - { - // Index type is not supported. Convert to I16. - autoBuffer = renderer.BufferManager.GetBufferI8ToI16(cbs, _handle, _offset, _size); - - type = MTLIndexType.UInt16; - offset = 0; - size = _size * 2; - } - else - { - autoBuffer = renderer.BufferManager.GetBuffer(_handle, false, out int bufferSize); - - if (_offset >= bufferSize) - { - autoBuffer = null; - } - - type = _type.Convert(); - offset = _offset; - size = _size; - } - - if (autoBuffer != null) - { - DisposableBuffer buffer = autoBuffer.Get(cbs, offset, size); - - return (buffer.Value, offset, type); - } - - return (new MTLBuffer(IntPtr.Zero), 0, MTLIndexType.UInt16); - } - - public (MTLBuffer, int, MTLIndexType) GetConvertedIndexBuffer( - MetalRenderer renderer, - CommandBufferScoped cbs, - int firstIndex, - int indexCount, - int convertedCount, - IndexBufferPattern pattern) - { - // Convert the index buffer using the given pattern. - int indexSize = GetIndexSize(); - - int firstIndexOffset = firstIndex * indexSize; - - Auto autoBuffer = renderer.BufferManager.GetBufferTopologyConversion(cbs, _handle, _offset + firstIndexOffset, indexCount * indexSize, pattern, indexSize); - - int size = convertedCount * 4; - - if (autoBuffer != null) - { - DisposableBuffer buffer = autoBuffer.Get(cbs, 0, size); - - return (buffer.Value, 0, MTLIndexType.UInt32); - } - - return (new MTLBuffer(IntPtr.Zero), 0, MTLIndexType.UInt32); - } - - private int GetIndexSize() - { - return _type switch - { - IndexType.UInt => 4, - IndexType.UShort => 2, - _ => 1, - }; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/MetalRenderer.cs b/src/Ryujinx.Graphics.Metal/MetalRenderer.cs deleted file mode 100644 index 86e2451b3..000000000 --- a/src/Ryujinx.Graphics.Metal/MetalRenderer.cs +++ /dev/null @@ -1,312 +0,0 @@ -using Ryujinx.Common.Configuration; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader.Translation; -using SharpMetal.Metal; -using SharpMetal.QuartzCore; -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - public sealed class MetalRenderer : IRenderer - { - public const int TotalSets = 4; - - private readonly MTLDevice _device; - private readonly MTLCommandQueue _queue; - private readonly Func _getMetalLayer; - - private Pipeline _pipeline; - private Window _window; - - public uint ProgramCount { get; set; } - -#pragma warning disable CS0067 // The event is never used - public event EventHandler ScreenCaptured; -#pragma warning restore CS0067 - - public bool PreferThreading => true; - public IPipeline Pipeline => _pipeline; - public IWindow Window => _window; - - internal MTLCommandQueue BackgroundQueue { get; private set; } - internal HelperShader HelperShader { get; private set; } - internal BufferManager BufferManager { get; private set; } - internal CommandBufferPool CommandBufferPool { get; private set; } - internal BackgroundResources BackgroundResources { get; private set; } - internal Action InterruptAction { get; private set; } - internal SyncManager SyncManager { get; private set; } - - internal HashSet Programs { get; } - internal HashSet Samplers { get; } - - public MetalRenderer(Func metalLayer) - { - _device = MTLDevice.CreateSystemDefaultDevice(); - Programs = []; - Samplers = []; - - if (_device.ArgumentBuffersSupport != MTLArgumentBuffersTier.Tier2) - { - throw new NotSupportedException("Metal backend requires Tier 2 Argument Buffer support."); - } - - _queue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers + 1); - BackgroundQueue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers); - - _getMetalLayer = metalLayer; - } - - public void Initialize(GraphicsDebugLevel logLevel) - { - CAMetalLayer layer = _getMetalLayer(); - layer.Device = _device; - layer.FramebufferOnly = false; - - CommandBufferPool = new CommandBufferPool(_queue); - _window = new Window(this, layer); - _pipeline = new Pipeline(_device, this); - BufferManager = new BufferManager(_device, this, _pipeline); - - _pipeline.InitEncoderStateManager(BufferManager); - - BackgroundResources = new BackgroundResources(this); - HelperShader = new HelperShader(_device, this, _pipeline); - SyncManager = new SyncManager(this); - } - - public void BackgroundContextAction(Action action, bool alwaysBackground = false) - { - // GetData methods should be thread safe, so we can call this directly. - // Texture copy (scaled) may also happen in here, so that should also be thread safe. - - action(); - } - - public BufferHandle CreateBuffer(int size, BufferAccess access) - { - return BufferManager.CreateWithHandle(size); - } - - public BufferHandle CreateBuffer(IntPtr pointer, int size) - { - return BufferManager.Create(pointer, size); - } - - public BufferHandle CreateBufferSparse(ReadOnlySpan storageBuffers) - { - throw new NotImplementedException(); - } - - public IImageArray CreateImageArray(int size, bool isBuffer) - { - return new ImageArray(size, isBuffer, _pipeline); - } - - public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info) - { - ProgramCount++; - return new Program(this, _device, shaders, info.ResourceLayout, info.ComputeLocalSize); - } - - public ISampler CreateSampler(SamplerCreateInfo info) - { - return new SamplerHolder(this, _device, info); - } - - public ITexture CreateTexture(TextureCreateInfo info) - { - if (info.Target == Target.TextureBuffer) - { - return new TextureBuffer(_device, this, _pipeline, info); - } - - return new Texture(_device, this, _pipeline, info); - } - - public ITextureArray CreateTextureArray(int size, bool isBuffer) - { - return new TextureArray(size, isBuffer, _pipeline); - } - - public bool PrepareHostMapping(IntPtr address, ulong size) - { - // TODO: Metal Host Mapping - return false; - } - - public void CreateSync(ulong id, bool strict) - { - SyncManager.Create(id, strict); - } - - public void DeleteBuffer(BufferHandle buffer) - { - BufferManager.Delete(buffer); - } - - public PinnedSpan GetBufferData(BufferHandle buffer, int offset, int size) - { - return BufferManager.GetData(buffer, offset, size); - } - - public Capabilities GetCapabilities() - { - // TODO: Finalize these values - return new Capabilities( - api: TargetApi.Metal, - vendorName: HardwareInfoTools.GetVendor(), - SystemMemoryType.UnifiedMemory, - hasFrontFacingBug: false, - hasVectorIndexingBug: false, - needsFragmentOutputSpecialization: true, - reduceShaderPrecision: true, - supportsAstcCompression: true, - supportsBc123Compression: true, - supportsBc45Compression: true, - supportsBc67Compression: true, - supportsEtc2Compression: true, - supports3DTextureCompression: true, - supportsBgraFormat: true, - supportsR4G4Format: false, - supportsR4G4B4A4Format: true, - supportsScaledVertexFormats: false, - supportsSnormBufferTextureFormat: true, - supportsSparseBuffer: false, - supports5BitComponentFormat: true, - supportsBlendEquationAdvanced: false, - supportsFragmentShaderInterlock: true, - supportsFragmentShaderOrderingIntel: false, - supportsGeometryShader: false, - supportsGeometryShaderPassthrough: false, - supportsTransformFeedback: false, - supportsImageLoadFormatted: false, - supportsLayerVertexTessellation: false, - supportsMismatchingViewFormat: true, - supportsCubemapView: true, - supportsNonConstantTextureOffset: false, - supportsQuads: false, - supportsSeparateSampler: true, - supportsShaderBallot: false, - supportsShaderBarrierDivergence: false, - supportsShaderFloat64: false, - supportsTextureGatherOffsets: false, - supportsTextureShadowLod: false, - supportsVertexStoreAndAtomics: false, - supportsViewportIndexVertexTessellation: false, - supportsViewportMask: false, - supportsViewportSwizzle: false, - supportsIndirectParameters: true, - supportsDepthClipControl: false, - uniformBufferSetIndex: (int)Constants.ConstantBuffersSetIndex, - storageBufferSetIndex: (int)Constants.StorageBuffersSetIndex, - textureSetIndex: (int)Constants.TexturesSetIndex, - imageSetIndex: (int)Constants.ImagesSetIndex, - extraSetBaseIndex: TotalSets, - maximumExtraSets: (int)Constants.MaximumExtraSets, - maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage, - maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage, - maximumTexturesPerStage: Constants.MaxTexturesPerStage, - maximumImagesPerStage: Constants.MaxImagesPerStage, - maximumComputeSharedMemorySize: (int)_device.MaxThreadgroupMemoryLength, - maximumSupportedAnisotropy: 16, - shaderSubgroupSize: 256, - storageBufferOffsetAlignment: 16, - textureBufferOffsetAlignment: 16, - gatherBiasPrecision: 0, - maximumGpuMemory: 0 - ); - } - - public ulong GetCurrentSync() - { - return SyncManager.GetCurrent(); - } - - public HardwareInfo GetHardwareInfo() - { - return new HardwareInfo(HardwareInfoTools.GetVendor(), HardwareInfoTools.GetModel(), "Apple"); - } - - public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info) - { - throw new NotImplementedException(); - } - - public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan data) - { - BufferManager.SetData(buffer, offset, data, _pipeline.Cbs); - } - - public void UpdateCounters() - { - // https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/creating_a_counter_sample_buffer_to_store_a_gpu_s_counter_data_during_a_pass?language=objc - } - - public void PreFrame() - { - SyncManager.Cleanup(); - } - - public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved) - { - // https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/creating_a_counter_sample_buffer_to_store_a_gpu_s_counter_data_during_a_pass?language=objc - CounterEvent counterEvent = new(); - resultHandler?.Invoke(counterEvent, type == CounterType.SamplesPassed ? (ulong)1 : 0); - return counterEvent; - } - - public void ResetCounter(CounterType type) - { - // https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/creating_a_counter_sample_buffer_to_store_a_gpu_s_counter_data_during_a_pass?language=objc - } - - public void WaitSync(ulong id) - { - SyncManager.Wait(id); - } - - public void FlushAllCommands() - { - _pipeline.FlushCommandsImpl(); - } - - public void RegisterFlush() - { - SyncManager.RegisterFlush(); - - // Periodically free unused regions of the staging buffer to avoid doing it all at once. - BufferManager.StagingBuffer.FreeCompleted(); - } - - public void SetInterruptAction(Action interruptAction) - { - InterruptAction = interruptAction; - } - - public void Screenshot() - { - // TODO: Screenshots - } - - public void Dispose() - { - BackgroundResources.Dispose(); - - foreach (Program program in Programs) - { - program.Dispose(); - } - - foreach (SamplerHolder sampler in Samplers) - { - sampler.Dispose(); - } - - _pipeline.Dispose(); - _window.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/MultiFenceHolder.cs b/src/Ryujinx.Graphics.Metal/MultiFenceHolder.cs deleted file mode 100644 index 89ae1fa77..000000000 --- a/src/Ryujinx.Graphics.Metal/MultiFenceHolder.cs +++ /dev/null @@ -1,262 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - /// - /// Holder for multiple host GPU fences. - /// - [SupportedOSPlatform("macos")] - class MultiFenceHolder - { - private const int BufferUsageTrackingGranularity = 4096; - - private readonly FenceHolder[] _fences; - private readonly BufferUsageBitmap _bufferUsageBitmap; - - /// - /// Creates a new instance of the multiple fence holder. - /// - public MultiFenceHolder() - { - _fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers]; - } - - /// - /// Creates a new instance of the multiple fence holder, with a given buffer size in mind. - /// - /// Size of the buffer - public MultiFenceHolder(int size) - { - _fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers]; - _bufferUsageBitmap = new BufferUsageBitmap(size, BufferUsageTrackingGranularity); - } - - /// - /// Adds read/write buffer usage information to the uses list. - /// - /// Index of the command buffer where the buffer is used - /// Offset of the buffer being used - /// Size of the buffer region being used, in bytes - /// Whether the access is a write or not - public void AddBufferUse(int cbIndex, int offset, int size, bool write) - { - _bufferUsageBitmap.Add(cbIndex, offset, size, false); - - if (write) - { - _bufferUsageBitmap.Add(cbIndex, offset, size, true); - } - } - - /// - /// Removes all buffer usage information for a given command buffer. - /// - /// Index of the command buffer where the buffer is used - public void RemoveBufferUses(int cbIndex) - { - _bufferUsageBitmap?.Clear(cbIndex); - } - - /// - /// Checks if a given range of a buffer is being used by a command buffer still being processed by the GPU. - /// - /// Index of the command buffer where the buffer is used - /// Offset of the buffer being used - /// Size of the buffer region being used, in bytes - /// True if in use, false otherwise - public bool IsBufferRangeInUse(int cbIndex, int offset, int size) - { - return _bufferUsageBitmap.OverlapsWith(cbIndex, offset, size); - } - - /// - /// Checks if a given range of a buffer is being used by any command buffer still being processed by the GPU. - /// - /// Offset of the buffer being used - /// Size of the buffer region being used, in bytes - /// True if only write usages should count - /// True if in use, false otherwise - public bool IsBufferRangeInUse(int offset, int size, bool write) - { - return _bufferUsageBitmap.OverlapsWith(offset, size, write); - } - - /// - /// Adds a fence to the holder. - /// - /// Command buffer index of the command buffer that owns the fence - /// Fence to be added - /// True if the command buffer's previous fence value was null - public bool AddFence(int cbIndex, FenceHolder fence) - { - ref FenceHolder fenceRef = ref _fences[cbIndex]; - - if (fenceRef == null) - { - fenceRef = fence; - return true; - } - - return false; - } - - /// - /// Removes a fence from the holder. - /// - /// Command buffer index of the command buffer that owns the fence - public void RemoveFence(int cbIndex) - { - _fences[cbIndex] = null; - } - - /// - /// Determines if a fence referenced on the given command buffer. - /// - /// Index of the command buffer to check if it's used - /// True if referenced, false otherwise - public bool HasFence(int cbIndex) - { - return _fences[cbIndex] != null; - } - - /// - /// Wait until all the fences on the holder are signaled. - /// - public void WaitForFences() - { - WaitForFencesImpl(0, 0, true); - } - - /// - /// Wait until all the fences on the holder with buffer uses overlapping the specified range are signaled. - /// - /// Start offset of the buffer range - /// Size of the buffer range in bytes - public void WaitForFences(int offset, int size) - { - WaitForFencesImpl(offset, size, true); - } - - /// - /// Wait until all the fences on the holder with buffer uses overlapping the specified range are signaled. - /// - - // TODO: Add a proper timeout! - public bool WaitForFences(bool indefinite) - { - return WaitForFencesImpl(0, 0, indefinite); - } - - /// - /// Wait until all the fences on the holder with buffer uses overlapping the specified range are signaled. - /// - /// Start offset of the buffer range - /// Size of the buffer range in bytes - /// Indicates if this should wait indefinitely - /// True if all fences were signaled before the timeout expired, false otherwise - private bool WaitForFencesImpl(int offset, int size, bool indefinite) - { - Span fenceHolders = new FenceHolder[CommandBufferPool.MaxCommandBuffers]; - - int count = size != 0 ? GetOverlappingFences(fenceHolders, offset, size) : GetFences(fenceHolders); - Span fences = stackalloc MTLCommandBuffer[count]; - - int fenceCount = 0; - - for (int i = 0; i < count; i++) - { - if (fenceHolders[i].TryGet(out MTLCommandBuffer fence)) - { - fences[fenceCount] = fence; - - if (fenceCount < i) - { - fenceHolders[fenceCount] = fenceHolders[i]; - } - - fenceCount++; - } - } - - if (fenceCount == 0) - { - return true; - } - - bool signaled = true; - - if (indefinite) - { - foreach (MTLCommandBuffer fence in fences) - { - fence.WaitUntilCompleted(); - } - } - else - { - foreach (MTLCommandBuffer fence in fences) - { - if (fence.Status != MTLCommandBufferStatus.Completed) - { - signaled = false; - } - } - } - - for (int i = 0; i < fenceCount; i++) - { - fenceHolders[i].Put(); - } - - return signaled; - } - - /// - /// Gets fences to wait for. - /// - /// Span to store fences in - /// Number of fences placed in storage - private int GetFences(Span storage) - { - int count = 0; - - for (int i = 0; i < _fences.Length; i++) - { - FenceHolder fence = _fences[i]; - - if (fence != null) - { - storage[count++] = fence; - } - } - - return count; - } - - /// - /// Gets fences to wait for use of a given buffer region. - /// - /// Span to store overlapping fences in - /// Offset of the range - /// Size of the range in bytes - /// Number of fences for the specified region placed in storage - private int GetOverlappingFences(Span storage, int offset, int size) - { - int count = 0; - - for (int i = 0; i < _fences.Length; i++) - { - FenceHolder fence = _fences[i]; - - if (fence != null && _bufferUsageBitmap.OverlapsWith(i, offset, size)) - { - storage[count++] = fence; - } - } - - return count; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/PersistentFlushBuffer.cs b/src/Ryujinx.Graphics.Metal/PersistentFlushBuffer.cs deleted file mode 100644 index fc79a40a9..000000000 --- a/src/Ryujinx.Graphics.Metal/PersistentFlushBuffer.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - internal class PersistentFlushBuffer : IDisposable - { - private readonly MetalRenderer _renderer; - - private BufferHolder _flushStorage; - - public PersistentFlushBuffer(MetalRenderer renderer) - { - _renderer = renderer; - } - - private BufferHolder ResizeIfNeeded(int size) - { - BufferHolder flushStorage = _flushStorage; - - if (flushStorage == null || size > _flushStorage.Size) - { - flushStorage?.Dispose(); - - flushStorage = _renderer.BufferManager.Create(size); - _flushStorage = flushStorage; - } - - return flushStorage; - } - - public Span GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size) - { - BufferHolder flushStorage = ResizeIfNeeded(size); - Auto srcBuffer; - - using (CommandBufferScoped cbs = cbp.Rent()) - { - srcBuffer = buffer.GetBuffer(); - Auto dstBuffer = flushStorage.GetBuffer(); - - if (srcBuffer.TryIncrementReferenceCount()) - { - BufferHolder.Copy(cbs, srcBuffer, dstBuffer, offset, 0, size, registerSrcUsage: false); - } - else - { - // Source buffer is no longer alive, don't copy anything to flush storage. - srcBuffer = null; - } - } - - flushStorage.WaitForFences(); - srcBuffer?.DecrementReferenceCount(); - return flushStorage.GetDataStorage(0, size); - } - - public Span GetTextureData(CommandBufferPool cbp, Texture view, int size) - { - TextureCreateInfo info = view.Info; - - BufferHolder flushStorage = ResizeIfNeeded(size); - - using (CommandBufferScoped cbs = cbp.Rent()) - { - MTLBuffer buffer = flushStorage.GetBuffer().Get(cbs).Value; - MTLTexture image = view.GetHandle(); - - view.CopyFromOrToBuffer(cbs, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false); - } - - flushStorage.WaitForFences(); - return flushStorage.GetDataStorage(0, size); - } - - public Span GetTextureData(CommandBufferPool cbp, Texture view, int size, int layer, int level) - { - BufferHolder flushStorage = ResizeIfNeeded(size); - - using (CommandBufferScoped cbs = cbp.Rent()) - { - MTLBuffer buffer = flushStorage.GetBuffer().Get(cbs).Value; - MTLTexture image = view.GetHandle(); - - view.CopyFromOrToBuffer(cbs, buffer, image, size, true, layer, level, 1, 1, singleSlice: true); - } - - flushStorage.WaitForFences(); - return flushStorage.GetDataStorage(0, size); - } - - public void Dispose() - { - _flushStorage.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Pipeline.cs b/src/Ryujinx.Graphics.Metal/Pipeline.cs deleted file mode 100644 index aebcb5493..000000000 --- a/src/Ryujinx.Graphics.Metal/Pipeline.cs +++ /dev/null @@ -1,877 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; -using SharpMetal.Foundation; -using SharpMetal.Metal; -using SharpMetal.QuartzCore; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - public enum EncoderType - { - Blit, - Compute, - Render, - None - } - - [SupportedOSPlatform("macos")] - class Pipeline : IPipeline, IEncoderFactory, IDisposable - { - private const ulong MinByteWeightForFlush = 256 * 1024 * 1024; // MiB - - private readonly MTLDevice _device; - private readonly MetalRenderer _renderer; - private EncoderStateManager _encoderStateManager; - private ulong _byteWeight; - - public MTLCommandBuffer CommandBuffer; - - public IndexBufferPattern QuadsToTrisPattern; - public IndexBufferPattern TriFanToTrisPattern; - - internal CommandBufferScoped? PreloadCbs { get; private set; } - internal CommandBufferScoped Cbs { get; private set; } - internal CommandBufferEncoder Encoders => Cbs.Encoders; - internal EncoderType CurrentEncoderType => Encoders.CurrentEncoderType; - - public Pipeline(MTLDevice device, MetalRenderer renderer) - { - _device = device; - _renderer = renderer; - - renderer.CommandBufferPool.Initialize(this); - - CommandBuffer = (Cbs = _renderer.CommandBufferPool.Rent()).CommandBuffer; - } - - internal void InitEncoderStateManager(BufferManager bufferManager) - { - _encoderStateManager = new EncoderStateManager(_device, bufferManager, this); - - QuadsToTrisPattern = new IndexBufferPattern(_renderer, 4, 6, 0, [0, 1, 2, 0, 2, 3], 4, false); - TriFanToTrisPattern = new IndexBufferPattern(_renderer, 3, 3, 2, [int.MinValue, -1, 0], 1, true); - } - - public EncoderState SwapState(EncoderState state, DirtyFlags flags = DirtyFlags.All, bool endRenderPass = true) - { - if (endRenderPass && CurrentEncoderType == EncoderType.Render) - { - EndCurrentPass(); - } - - return _encoderStateManager.SwapState(state, flags); - } - - public PredrawState SavePredrawState() - { - return _encoderStateManager.SavePredrawState(); - } - - public void RestorePredrawState(PredrawState state) - { - _encoderStateManager.RestorePredrawState(state); - } - - public void SetClearLoadAction(bool clear) - { - _encoderStateManager.SetClearLoadAction(clear); - } - - public MTLRenderCommandEncoder GetOrCreateRenderEncoder(bool forDraw = false) - { - // Mark all state as dirty to ensure it is set on the new encoder - if (Cbs.Encoders.CurrentEncoderType != EncoderType.Render) - { - _encoderStateManager.SignalRenderDirty(); - } - - if (forDraw) - { - _encoderStateManager.RenderResourcesPrepass(); - } - - MTLRenderCommandEncoder renderCommandEncoder = Cbs.Encoders.EnsureRenderEncoder(); - - if (forDraw) - { - _encoderStateManager.RebindRenderState(renderCommandEncoder); - } - - return renderCommandEncoder; - } - - public MTLBlitCommandEncoder GetOrCreateBlitEncoder() - { - return Cbs.Encoders.EnsureBlitEncoder(); - } - - public MTLComputeCommandEncoder GetOrCreateComputeEncoder(bool forDispatch = false) - { - // Mark all state as dirty to ensure it is set on the new encoder - if (Cbs.Encoders.CurrentEncoderType != EncoderType.Compute) - { - _encoderStateManager.SignalComputeDirty(); - } - - if (forDispatch) - { - _encoderStateManager.ComputeResourcesPrepass(); - } - - MTLComputeCommandEncoder computeCommandEncoder = Cbs.Encoders.EnsureComputeEncoder(); - - if (forDispatch) - { - _encoderStateManager.RebindComputeState(computeCommandEncoder); - } - - return computeCommandEncoder; - } - - public void EndCurrentPass() - { - Cbs.Encoders.EndCurrentPass(); - } - - public MTLRenderCommandEncoder CreateRenderCommandEncoder() - { - return _encoderStateManager.CreateRenderCommandEncoder(); - } - - public MTLComputeCommandEncoder CreateComputeCommandEncoder() - { - return _encoderStateManager.CreateComputeCommandEncoder(); - } - - public void Present(CAMetalDrawable drawable, Texture src, Extents2D srcRegion, Extents2D dstRegion, bool isLinear) - { - // TODO: Clean this up - TextureCreateInfo textureInfo = new((int)drawable.Texture.Width, (int)drawable.Texture.Height, (int)drawable.Texture.Depth, (int)drawable.Texture.MipmapLevelCount, (int)drawable.Texture.SampleCount, 0, 0, 0, Format.B8G8R8A8Unorm, 0, Target.Texture2D, SwizzleComponent.Red, SwizzleComponent.Green, SwizzleComponent.Blue, SwizzleComponent.Alpha); - Texture dst = new(_device, _renderer, this, textureInfo, drawable.Texture, 0, 0); - - _renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, isLinear, true); - - EndCurrentPass(); - - Cbs.CommandBuffer.PresentDrawable(drawable); - - FlushCommandsImpl(); - - // TODO: Auto flush counting - _renderer.SyncManager.GetAndResetWaitTicks(); - - // Cleanup - dst.Dispose(); - } - - public CommandBufferScoped GetPreloadCommandBuffer() - { - PreloadCbs ??= _renderer.CommandBufferPool.Rent(); - - return PreloadCbs.Value; - } - - public void FlushCommandsIfWeightExceeding(IAuto disposedResource, ulong byteWeight) - { - bool usedByCurrentCb = disposedResource.HasCommandBufferDependency(Cbs); - - if (PreloadCbs != null && !usedByCurrentCb) - { - usedByCurrentCb = disposedResource.HasCommandBufferDependency(PreloadCbs.Value); - } - - if (usedByCurrentCb) - { - // Since we can only free memory after the command buffer that uses a given resource was executed, - // keeping the command buffer might cause a high amount of memory to be in use. - // To prevent that, we force submit command buffers if the memory usage by resources - // in use by the current command buffer is above a given limit, and those resources were disposed. - _byteWeight += byteWeight; - - if (_byteWeight >= MinByteWeightForFlush) - { - FlushCommandsImpl(); - } - } - } - - public void FlushCommandsImpl() - { - EndCurrentPass(); - - _byteWeight = 0; - - if (PreloadCbs != null) - { - PreloadCbs.Value.Dispose(); - PreloadCbs = null; - } - - CommandBuffer = (Cbs = _renderer.CommandBufferPool.ReturnAndRent(Cbs)).CommandBuffer; - _renderer.RegisterFlush(); - } - - public void DirtyTextures() - { - _encoderStateManager.DirtyTextures(); - } - - public void DirtyImages() - { - _encoderStateManager.DirtyImages(); - } - - public void Blit( - Texture src, - Texture dst, - Extents2D srcRegion, - Extents2D dstRegion, - bool isDepthOrStencil, - bool linearFilter) - { - if (isDepthOrStencil) - { - _renderer.HelperShader.BlitDepthStencil(Cbs, src, dst, srcRegion, dstRegion); - } - else - { - _renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, linearFilter); - } - } - - public void Barrier() - { - switch (CurrentEncoderType) - { - case EncoderType.Render: - { - MTLBarrierScope scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets; - MTLRenderStages stages = MTLRenderStages.RenderStageVertex | MTLRenderStages.RenderStageFragment; - Encoders.RenderEncoder.MemoryBarrier(scope, stages, stages); - break; - } - case EncoderType.Compute: - { - MTLBarrierScope scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets; - Encoders.ComputeEncoder.MemoryBarrier(scope); - break; - } - } - } - - public void ClearBuffer(BufferHandle destination, int offset, int size, uint value) - { - MTLBlitCommandEncoder blitCommandEncoder = GetOrCreateBlitEncoder(); - - MTLBuffer mtlBuffer = _renderer.BufferManager.GetBuffer(destination, offset, size, true).Get(Cbs, offset, size, true).Value; - - // Might need a closer look, range's count, lower, and upper bound - // must be a multiple of 4 - blitCommandEncoder.FillBuffer(mtlBuffer, - new NSRange - { - location = (ulong)offset, - length = (ulong)size - }, - (byte)value); - } - - public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color) - { - float[] colors = [color.Red, color.Green, color.Blue, color.Alpha]; - Texture dst = _encoderStateManager.RenderTargets[index]; - - // TODO: Remove workaround for Wonder which has an invalid texture due to unsupported format - if (dst == null) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, "Attempted to clear invalid render target!"); - return; - } - - _renderer.HelperShader.ClearColor(index, colors, componentMask, dst.Width, dst.Height, dst.Info.Format); - } - - public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask) - { - Texture depthStencil = _encoderStateManager.DepthStencil; - - if (depthStencil == null) - { - return; - } - - _renderer.HelperShader.ClearDepthStencil(depthValue, depthMask, stencilValue, stencilMask, depthStencil.Width, depthStencil.Height); - } - - public void CommandBufferBarrier() - { - Barrier(); - } - - public void CopyBuffer(BufferHandle src, BufferHandle dst, int srcOffset, int dstOffset, int size) - { - Auto srcBuffer = _renderer.BufferManager.GetBuffer(src, srcOffset, size, false); - Auto dstBuffer = _renderer.BufferManager.GetBuffer(dst, dstOffset, size, true); - - BufferHolder.Copy(Cbs, srcBuffer, dstBuffer, srcOffset, dstOffset, size); - } - - public void PushDebugGroup(string name) - { - MTLCommandEncoder? encoder = Encoders.CurrentEncoder; - NSString debugGroupName = StringHelper.NSString(name); - - if (encoder == null) - { - return; - } - - switch (Encoders.CurrentEncoderType) - { - case EncoderType.Render: - encoder.Value.PushDebugGroup(debugGroupName); - break; - case EncoderType.Blit: - encoder.Value.PushDebugGroup(debugGroupName); - break; - case EncoderType.Compute: - encoder.Value.PushDebugGroup(debugGroupName); - break; - } - } - - public void PopDebugGroup() - { - MTLCommandEncoder? encoder = Encoders.CurrentEncoder; - - if (encoder == null) - { - return; - } - - switch (Encoders.CurrentEncoderType) - { - case EncoderType.Render: - encoder.Value.PopDebugGroup(); - break; - case EncoderType.Blit: - encoder.Value.PopDebugGroup(); - break; - case EncoderType.Compute: - encoder.Value.PopDebugGroup(); - break; - } - } - - public void DispatchCompute(int groupsX, int groupsY, int groupsZ) - { - DispatchCompute(groupsX, groupsY, groupsZ, String.Empty); - } - - public void DispatchCompute(int groupsX, int groupsY, int groupsZ, string debugGroupName) - { - MTLComputeCommandEncoder computeCommandEncoder = GetOrCreateComputeEncoder(true); - - ComputeSize localSize = _encoderStateManager.ComputeLocalSize; - - if (debugGroupName != String.Empty) - { - PushDebugGroup(debugGroupName); - } - - computeCommandEncoder.DispatchThreadgroups( - new MTLSize { width = (ulong)groupsX, height = (ulong)groupsY, depth = (ulong)groupsZ }, - new MTLSize { width = (ulong)localSize.X, height = (ulong)localSize.Y, depth = (ulong)localSize.Z }); - - if (debugGroupName != String.Empty) - { - PopDebugGroup(); - } - } - - public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) - { - Draw(vertexCount, instanceCount, firstVertex, firstInstance, String.Empty); - } - - public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance, string debugGroupName) - { - if (vertexCount == 0) - { - return; - } - - MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); - - if (TopologyUnsupported(_encoderStateManager.Topology)) - { - IndexBufferPattern pattern = GetIndexBufferPattern(); - - BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount); - Auto buffer = _renderer.BufferManager.GetBuffer(handle, false); - MTLBuffer mtlBuffer = buffer.Get(Cbs, 0, indexCount * sizeof(int)).Value; - - MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true); - - renderCommandEncoder.DrawIndexedPrimitives( - primitiveType, - (ulong)indexCount, - MTLIndexType.UInt32, - mtlBuffer, - 0); - } - else - { - MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true); - - if (debugGroupName != String.Empty) - { - PushDebugGroup(debugGroupName); - } - - renderCommandEncoder.DrawPrimitives( - primitiveType, - (ulong)firstVertex, - (ulong)vertexCount, - (ulong)instanceCount, - (ulong)firstInstance); - - if (debugGroupName != String.Empty) - { - PopDebugGroup(); - } - } - } - - private IndexBufferPattern GetIndexBufferPattern() - { - return _encoderStateManager.Topology switch - { - PrimitiveTopology.Quads => QuadsToTrisPattern, - PrimitiveTopology.TriangleFan or PrimitiveTopology.Polygon => TriFanToTrisPattern, - _ => throw new NotSupportedException($"Unsupported topology: {_encoderStateManager.Topology}"), - }; - } - - private PrimitiveTopology TopologyRemap(PrimitiveTopology topology) - { - return topology switch - { - PrimitiveTopology.Quads => PrimitiveTopology.Triangles, - PrimitiveTopology.QuadStrip => PrimitiveTopology.TriangleStrip, - PrimitiveTopology.TriangleFan or PrimitiveTopology.Polygon => PrimitiveTopology.Triangles, - _ => topology, - }; - } - - private bool TopologyUnsupported(PrimitiveTopology topology) - { - return topology switch - { - PrimitiveTopology.Quads or PrimitiveTopology.TriangleFan or PrimitiveTopology.Polygon => true, - _ => false, - }; - } - - public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance) - { - if (indexCount == 0) - { - return; - } - - MTLBuffer mtlBuffer; - int offset; - MTLIndexType type; - int finalIndexCount = indexCount; - - MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); - - if (TopologyUnsupported(_encoderStateManager.Topology)) - { - IndexBufferPattern pattern = GetIndexBufferPattern(); - int convertedCount = pattern.GetConvertedCount(indexCount); - - finalIndexCount = convertedCount; - - (mtlBuffer, offset, type) = _encoderStateManager.IndexBuffer.GetConvertedIndexBuffer(_renderer, Cbs, firstIndex, indexCount, convertedCount, pattern); - } - else - { - (mtlBuffer, offset, type) = _encoderStateManager.IndexBuffer.GetIndexBuffer(_renderer, Cbs); - } - - if (mtlBuffer.NativePtr != IntPtr.Zero) - { - MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true); - - renderCommandEncoder.DrawIndexedPrimitives( - primitiveType, - (ulong)finalIndexCount, - type, - mtlBuffer, - (ulong)offset, - (ulong)instanceCount, - firstVertex, - (ulong)firstInstance); - } - } - - public void DrawIndexedIndirect(BufferRange indirectBuffer) - { - DrawIndexedIndirectOffset(indirectBuffer); - } - - public void DrawIndexedIndirectOffset(BufferRange indirectBuffer, int offset = 0) - { - // TODO: Reindex unsupported topologies - if (TopologyUnsupported(_encoderStateManager.Topology)) - { - Logger.Warning?.Print(LogClass.Gpu, $"Drawing indexed with unsupported topology: {_encoderStateManager.Topology}"); - } - - MTLBuffer buffer = _renderer.BufferManager - .GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) - .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; - - MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); - - (MTLBuffer indexBuffer, int indexOffset, MTLIndexType type) = _encoderStateManager.IndexBuffer.GetIndexBuffer(_renderer, Cbs); - - if (indexBuffer.NativePtr != IntPtr.Zero && buffer.NativePtr != IntPtr.Zero) - { - MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true); - - renderCommandEncoder.DrawIndexedPrimitives( - primitiveType, - type, - indexBuffer, - (ulong)indexOffset, - buffer, - (ulong)(indirectBuffer.Offset + offset)); - } - } - - public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) - { - for (int i = 0; i < maxDrawCount; i++) - { - DrawIndexedIndirectOffset(indirectBuffer, stride * i); - } - } - - public void DrawIndirect(BufferRange indirectBuffer) - { - DrawIndirectOffset(indirectBuffer); - } - - public void DrawIndirectOffset(BufferRange indirectBuffer, int offset = 0) - { - if (TopologyUnsupported(_encoderStateManager.Topology)) - { - // TODO: Reindex unsupported topologies - Logger.Warning?.Print(LogClass.Gpu, $"Drawing indirect with unsupported topology: {_encoderStateManager.Topology}"); - } - - MTLBuffer buffer = _renderer.BufferManager - .GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) - .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; - - MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); - MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true); - - renderCommandEncoder.DrawPrimitives( - primitiveType, - buffer, - (ulong)(indirectBuffer.Offset + offset)); - } - - public void DrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) - { - for (int i = 0; i < maxDrawCount; i++) - { - DrawIndirectOffset(indirectBuffer, stride * i); - } - } - - public void DrawTexture(ITexture texture, ISampler sampler, Extents2DF srcRegion, Extents2DF dstRegion) - { - _renderer.HelperShader.DrawTexture(texture, sampler, srcRegion, dstRegion); - } - - public void SetAlphaTest(bool enable, float reference, CompareOp op) - { - // This is currently handled using shader specialization, as Metal does not support alpha test. - // In the future, we may want to use this to write the reference value into the support buffer, - // to avoid creating one version of the shader per reference value used. - } - - public void SetBlendState(AdvancedBlendDescriptor blend) - { - // Metal does not support advanced blend. - } - - public void SetBlendState(int index, BlendDescriptor blend) - { - _encoderStateManager.UpdateBlendDescriptors(index, blend); - } - - public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp) - { - if (enables == 0) - { - _encoderStateManager.UpdateDepthBias(0, 0, 0); - } - else - { - _encoderStateManager.UpdateDepthBias(units, factor, clamp); - } - } - - public void SetDepthClamp(bool clamp) - { - _encoderStateManager.UpdateDepthClamp(clamp); - } - - public void SetDepthMode(DepthMode mode) - { - // Metal does not support depth clip control. - } - - public void SetDepthTest(DepthTestDescriptor depthTest) - { - _encoderStateManager.UpdateDepthState(depthTest); - } - - public void SetFaceCulling(bool enable, Face face) - { - _encoderStateManager.UpdateCullMode(enable, face); - } - - public void SetFrontFace(FrontFace frontFace) - { - _encoderStateManager.UpdateFrontFace(frontFace); - } - - public void SetIndexBuffer(BufferRange buffer, IndexType type) - { - _encoderStateManager.UpdateIndexBuffer(buffer, type); - } - - public void SetImage(ShaderStage stage, int binding, ITexture image) - { - if (image is TextureBase img) - { - _encoderStateManager.UpdateImage(stage, binding, img); - } - } - - public void SetImageArray(ShaderStage stage, int binding, IImageArray array) - { - if (array is ImageArray imageArray) - { - _encoderStateManager.UpdateImageArray(stage, binding, imageArray); - } - } - - public void SetImageArraySeparate(ShaderStage stage, int setIndex, IImageArray array) - { - if (array is ImageArray imageArray) - { - _encoderStateManager.UpdateImageArraySeparate(stage, setIndex, imageArray); - } - } - - public void SetLineParameters(float width, bool smooth) - { - // Metal does not support wide-lines. - } - - public void SetLogicOpState(bool enable, LogicalOp op) - { - _encoderStateManager.UpdateLogicOpState(enable, op); - } - - public void SetMultisampleState(MultisampleDescriptor multisample) - { - _encoderStateManager.UpdateMultisampleState(multisample); - } - - public void SetPatchParameters(int vertices, ReadOnlySpan defaultOuterLevel, ReadOnlySpan defaultInnerLevel) - { - Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!"); - } - - public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin) - { - Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!"); - } - - public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode) - { - // Metal does not support polygon mode. - } - - public void SetPrimitiveRestart(bool enable, int index) - { - // Always active for LineStrip and TriangleStrip - // https://github.com/gpuweb/gpuweb/issues/1220#issuecomment-732483263 - // https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515520-drawindexedprimitives - // https://stackoverflow.com/questions/70813665/how-to-render-multiple-trianglestrips-using-metal - - // Emulating disabling this is very difficult. It's unlikely for an index buffer to use the largest possible index, - // so it's fine nearly all of the time. - } - - public void SetPrimitiveTopology(PrimitiveTopology topology) - { - _encoderStateManager.UpdatePrimitiveTopology(topology); - } - - public void SetProgram(IProgram program) - { - _encoderStateManager.UpdateProgram(program); - } - - public void SetRasterizerDiscard(bool discard) - { - _encoderStateManager.UpdateRasterizerDiscard(discard); - } - - public void SetRenderTargetColorMasks(ReadOnlySpan componentMask) - { - _encoderStateManager.UpdateRenderTargetColorMasks(componentMask); - } - - public void SetRenderTargets(ITexture[] colors, ITexture depthStencil) - { - _encoderStateManager.UpdateRenderTargets(colors, depthStencil); - } - - public void SetScissors(ReadOnlySpan> regions) - { - _encoderStateManager.UpdateScissors(regions); - } - - public void SetStencilTest(StencilTestDescriptor stencilTest) - { - _encoderStateManager.UpdateStencilState(stencilTest); - } - - public void SetUniformBuffers(ReadOnlySpan buffers) - { - _encoderStateManager.UpdateUniformBuffers(buffers); - } - - public void SetStorageBuffers(ReadOnlySpan buffers) - { - _encoderStateManager.UpdateStorageBuffers(buffers); - } - - internal void SetStorageBuffers(int first, ReadOnlySpan> buffers) - { - _encoderStateManager.UpdateStorageBuffers(first, buffers); - } - - public void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler) - { - if (texture is TextureBase tex) - { - if (sampler == null || sampler is SamplerHolder) - { - _encoderStateManager.UpdateTextureAndSampler(stage, binding, tex, (SamplerHolder)sampler); - } - } - } - - public void SetTextureArray(ShaderStage stage, int binding, ITextureArray array) - { - if (array is TextureArray textureArray) - { - _encoderStateManager.UpdateTextureArray(stage, binding, textureArray); - } - } - - public void SetTextureArraySeparate(ShaderStage stage, int setIndex, ITextureArray array) - { - if (array is TextureArray textureArray) - { - _encoderStateManager.UpdateTextureArraySeparate(stage, setIndex, textureArray); - } - } - - public void SetUserClipDistance(int index, bool enableClip) - { - // TODO. Same as Vulkan - } - - public void SetVertexAttribs(ReadOnlySpan vertexAttribs) - { - _encoderStateManager.UpdateVertexAttribs(vertexAttribs); - } - - public void SetVertexBuffers(ReadOnlySpan vertexBuffers) - { - _encoderStateManager.UpdateVertexBuffers(vertexBuffers); - } - - public void SetViewports(ReadOnlySpan viewports) - { - _encoderStateManager.UpdateViewports(viewports); - } - - public void TextureBarrier() - { - if (CurrentEncoderType == EncoderType.Render) - { - Encoders.RenderEncoder.MemoryBarrier(MTLBarrierScope.Textures, MTLRenderStages.RenderStageFragment, MTLRenderStages.RenderStageFragment); - } - } - - public void TextureBarrierTiled() - { - TextureBarrier(); - } - - public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual) - { - // TODO: Implementable via indirect draw commands - return false; - } - - public bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual) - { - // TODO: Implementable via indirect draw commands - return false; - } - - public void EndHostConditionalRendering() - { - // TODO: Implementable via indirect draw commands - } - - public void BeginTransformFeedback(PrimitiveTopology topology) - { - // Metal does not support transform feedback. - } - - public void EndTransformFeedback() - { - // Metal does not support transform feedback. - } - - public void SetTransformFeedbackBuffers(ReadOnlySpan buffers) - { - // Metal does not support transform feedback. - } - - public void Dispose() - { - EndCurrentPass(); - _encoderStateManager.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Program.cs b/src/Ryujinx.Graphics.Metal/Program.cs deleted file mode 100644 index 721ee56a7..000000000 --- a/src/Ryujinx.Graphics.Metal/Program.cs +++ /dev/null @@ -1,286 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; -using SharpMetal.Foundation; -using SharpMetal.Metal; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class Program : IProgram - { - private ProgramLinkStatus _status; - private readonly ShaderSource[] _shaders; - private readonly GCHandle[] _handles; - private int _successCount; - - private readonly MetalRenderer _renderer; - - public MTLFunction VertexFunction; - public MTLFunction FragmentFunction; - public MTLFunction ComputeFunction; - public ComputeSize ComputeLocalSize { get; } - - private HashTableSlim _graphicsPipelineCache; - private MTLComputePipelineState? _computePipelineCache; - private bool _firstBackgroundUse; - - public ResourceBindingSegment[][] BindingSegments { get; } - // Argument buffer sizes for Vertex or Compute stages - public int[] ArgumentBufferSizes { get; } - // Argument buffer sizes for Fragment stage - public int[] FragArgumentBufferSizes { get; } - - public Program( - MetalRenderer renderer, - MTLDevice device, - ShaderSource[] shaders, - ResourceLayout resourceLayout, - ComputeSize computeLocalSize = default) - { - _renderer = renderer; - renderer.Programs.Add(this); - - ComputeLocalSize = computeLocalSize; - _shaders = shaders; - _handles = new GCHandle[_shaders.Length]; - - _status = ProgramLinkStatus.Incomplete; - - for (int i = 0; i < _shaders.Length; i++) - { - ShaderSource shader = _shaders[i]; - - using MTLCompileOptions compileOptions = new() - { - PreserveInvariance = true, - LanguageVersion = MTLLanguageVersion.Version31, - }; - int index = i; - - _handles[i] = device.NewLibrary(StringHelper.NSString(shader.Code), compileOptions, (library, error) => CompilationResultHandler(library, error, index)); - } - - (BindingSegments, ArgumentBufferSizes, FragArgumentBufferSizes) = BuildBindingSegments(resourceLayout.SetUsages); - } - - public void CompilationResultHandler(MTLLibrary library, NSError error, int index) - { - ShaderSource shader = _shaders[index]; - - if (_handles[index].IsAllocated) - { - _handles[index].Free(); - } - - if (error != IntPtr.Zero) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, shader.Code); - Logger.Warning?.Print(LogClass.Gpu, $"{shader.Stage} shader linking failed: \n{StringHelper.String(error.LocalizedDescription)}"); - _status = ProgramLinkStatus.Failure; - return; - } - - switch (shader.Stage) - { - case ShaderStage.Compute: - ComputeFunction = library.NewFunction(StringHelper.NSString("kernelMain")); - break; - case ShaderStage.Vertex: - VertexFunction = library.NewFunction(StringHelper.NSString("vertexMain")); - break; - case ShaderStage.Fragment: - FragmentFunction = library.NewFunction(StringHelper.NSString("fragmentMain")); - break; - default: - Logger.Warning?.Print(LogClass.Gpu, $"Cannot handle stage {shader.Stage}!"); - break; - } - - _successCount++; - - if (_successCount >= _shaders.Length && _status != ProgramLinkStatus.Failure) - { - _status = ProgramLinkStatus.Success; - } - } - - private static (ResourceBindingSegment[][], int[], int[]) BuildBindingSegments(ReadOnlyCollection setUsages) - { - ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][]; - int[] argBufferSizes = new int[setUsages.Count]; - int[] fragArgBufferSizes = new int[setUsages.Count]; - - for (int setIndex = 0; setIndex < setUsages.Count; setIndex++) - { - List currentSegments = []; - - ResourceUsage currentUsage = default; - int currentCount = 0; - - for (int index = 0; index < setUsages[setIndex].Usages.Count; index++) - { - ResourceUsage usage = setUsages[setIndex].Usages[index]; - - if (currentUsage.Binding + currentCount != usage.Binding || - currentUsage.Type != usage.Type || - currentUsage.Stages != usage.Stages || - currentUsage.ArrayLength > 1 || - usage.ArrayLength > 1) - { - if (currentCount != 0) - { - currentSegments.Add(new ResourceBindingSegment( - currentUsage.Binding, - currentCount, - currentUsage.Type, - currentUsage.Stages, - currentUsage.ArrayLength > 1)); - - int size = currentCount * ResourcePointerSize(currentUsage.Type); - if (currentUsage.Stages.HasFlag(ResourceStages.Fragment)) - { - fragArgBufferSizes[setIndex] += size; - } - - if (currentUsage.Stages.HasFlag(ResourceStages.Vertex) || - currentUsage.Stages.HasFlag(ResourceStages.Compute)) - { - argBufferSizes[setIndex] += size; - } - } - - currentUsage = usage; - currentCount = usage.ArrayLength; - } - else - { - currentCount++; - } - } - - if (currentCount != 0) - { - currentSegments.Add(new ResourceBindingSegment( - currentUsage.Binding, - currentCount, - currentUsage.Type, - currentUsage.Stages, - currentUsage.ArrayLength > 1)); - - int size = currentCount * ResourcePointerSize(currentUsage.Type); - if (currentUsage.Stages.HasFlag(ResourceStages.Fragment)) - { - fragArgBufferSizes[setIndex] += size; - } - - if (currentUsage.Stages.HasFlag(ResourceStages.Vertex) || - currentUsage.Stages.HasFlag(ResourceStages.Compute)) - { - argBufferSizes[setIndex] += size; - } - } - - segments[setIndex] = currentSegments.ToArray(); - } - - return (segments, argBufferSizes, fragArgBufferSizes); - } - - private static int ResourcePointerSize(ResourceType type) - { - return (type == ResourceType.TextureAndSampler ? 2 : 1); - } - - public ProgramLinkStatus CheckProgramLink(bool blocking) - { - if (blocking) - { - while (_status == ProgramLinkStatus.Incomplete) - { } - - return _status; - } - - return _status; - } - - public byte[] GetBinary() - { - return []; - } - - public void AddGraphicsPipeline(ref PipelineUid key, MTLRenderPipelineState pipeline) - { - (_graphicsPipelineCache ??= new()).Add(ref key, pipeline); - } - - public void AddComputePipeline(MTLComputePipelineState pipeline) - { - _computePipelineCache = pipeline; - } - - public bool TryGetGraphicsPipeline(ref PipelineUid key, out MTLRenderPipelineState pipeline) - { - if (_graphicsPipelineCache == null) - { - pipeline = default; - return false; - } - - if (!_graphicsPipelineCache.TryGetValue(ref key, out pipeline)) - { - if (_firstBackgroundUse) - { - Logger.Warning?.Print(LogClass.Gpu, "Background pipeline compile missed on draw - incorrect pipeline state?"); - _firstBackgroundUse = false; - } - - return false; - } - - _firstBackgroundUse = false; - - return true; - } - - public bool TryGetComputePipeline(out MTLComputePipelineState pipeline) - { - if (_computePipelineCache.HasValue) - { - pipeline = _computePipelineCache.Value; - return true; - } - - pipeline = default; - return false; - } - - public void Dispose() - { - if (!_renderer.Programs.Remove(this)) - { - return; - } - - if (_graphicsPipelineCache != null) - { - foreach (MTLRenderPipelineState pipeline in _graphicsPipelineCache.Values) - { - pipeline.Dispose(); - } - } - - _computePipelineCache?.Dispose(); - - VertexFunction.Dispose(); - FragmentFunction.Dispose(); - ComputeFunction.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/ResourceBindingSegment.cs b/src/Ryujinx.Graphics.Metal/ResourceBindingSegment.cs deleted file mode 100644 index 8e6d88c4b..000000000 --- a/src/Ryujinx.Graphics.Metal/ResourceBindingSegment.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.Metal -{ - readonly struct ResourceBindingSegment - { - public readonly int Binding; - public readonly int Count; - public readonly ResourceType Type; - public readonly ResourceStages Stages; - public readonly bool IsArray; - - public ResourceBindingSegment(int binding, int count, ResourceType type, ResourceStages stages, bool isArray) - { - Binding = binding; - Count = count; - Type = type; - Stages = stages; - IsArray = isArray; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/ResourceLayoutBuilder.cs b/src/Ryujinx.Graphics.Metal/ResourceLayoutBuilder.cs deleted file mode 100644 index 623f91612..000000000 --- a/src/Ryujinx.Graphics.Metal/ResourceLayoutBuilder.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class ResourceLayoutBuilder - { - private const int TotalSets = MetalRenderer.TotalSets; - - private readonly List[] _resourceDescriptors; - private readonly List[] _resourceUsages; - - public ResourceLayoutBuilder() - { - _resourceDescriptors = new List[TotalSets]; - _resourceUsages = new List[TotalSets]; - - for (int index = 0; index < TotalSets; index++) - { - _resourceDescriptors[index] = []; - _resourceUsages[index] = []; - } - } - - public ResourceLayoutBuilder Add(ResourceStages stages, ResourceType type, int binding, bool write = false) - { - uint setIndex = type switch - { - ResourceType.UniformBuffer => Constants.ConstantBuffersSetIndex, - ResourceType.StorageBuffer => Constants.StorageBuffersSetIndex, - ResourceType.TextureAndSampler or ResourceType.BufferTexture => Constants.TexturesSetIndex, - ResourceType.Image or ResourceType.BufferImage => Constants.ImagesSetIndex, - _ => throw new ArgumentException($"Invalid resource type \"{type}\"."), - }; - - _resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages)); - _resourceUsages[setIndex].Add(new ResourceUsage(binding, 1, type, stages, write)); - - return this; - } - - public ResourceLayout Build() - { - ResourceDescriptorCollection[] descriptors = new ResourceDescriptorCollection[TotalSets]; - ResourceUsageCollection[] usages = new ResourceUsageCollection[TotalSets]; - - for (int index = 0; index < TotalSets; index++) - { - descriptors[index] = new ResourceDescriptorCollection(_resourceDescriptors[index].ToArray().AsReadOnly()); - usages[index] = new ResourceUsageCollection(_resourceUsages[index].ToArray().AsReadOnly()); - } - - return new ResourceLayout(descriptors.AsReadOnly(), usages.AsReadOnly()); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj b/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj deleted file mode 100644 index 364aa5a8b..000000000 --- a/src/Ryujinx.Graphics.Metal/Ryujinx.Graphics.Metal.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - true - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Ryujinx.Graphics.Metal/SamplerHolder.cs b/src/Ryujinx.Graphics.Metal/SamplerHolder.cs deleted file mode 100644 index a448b26fe..000000000 --- a/src/Ryujinx.Graphics.Metal/SamplerHolder.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class SamplerHolder : ISampler - { - private readonly MetalRenderer _renderer; - private readonly Auto _sampler; - - public SamplerHolder(MetalRenderer renderer, MTLDevice device, SamplerCreateInfo info) - { - _renderer = renderer; - - renderer.Samplers.Add(this); - - (MTLSamplerMinMagFilter minFilter, MTLSamplerMipFilter mipFilter) = info.MinFilter.Convert(); - - MTLSamplerBorderColor borderColor = GetConstrainedBorderColor(info.BorderColor, out _); - - using MTLSamplerDescriptor descriptor = new() - { - BorderColor = borderColor, - MinFilter = minFilter, - MagFilter = info.MagFilter.Convert(), - MipFilter = mipFilter, - CompareFunction = info.CompareOp.Convert(), - LodMinClamp = info.MinLod, - LodMaxClamp = info.MaxLod, - LodAverage = false, - MaxAnisotropy = Math.Max((uint)info.MaxAnisotropy, 1), - SAddressMode = info.AddressU.Convert(), - TAddressMode = info.AddressV.Convert(), - RAddressMode = info.AddressP.Convert(), - SupportArgumentBuffers = true - }; - - MTLSamplerState sampler = device.NewSamplerState(descriptor); - - _sampler = new Auto(new DisposableSampler(sampler)); - } - - private static MTLSamplerBorderColor GetConstrainedBorderColor(ColorF arbitraryBorderColor, out bool cantConstrain) - { - float r = arbitraryBorderColor.Red; - float g = arbitraryBorderColor.Green; - float b = arbitraryBorderColor.Blue; - float a = arbitraryBorderColor.Alpha; - - if (r == 0f && g == 0f && b == 0f) - { - if (a == 1f) - { - cantConstrain = false; - return MTLSamplerBorderColor.OpaqueBlack; - } - - if (a == 0f) - { - cantConstrain = false; - return MTLSamplerBorderColor.TransparentBlack; - } - } - else if (r == 1f && g == 1f && b == 1f && a == 1f) - { - cantConstrain = false; - return MTLSamplerBorderColor.OpaqueWhite; - } - - cantConstrain = true; - return MTLSamplerBorderColor.OpaqueBlack; - } - - public Auto GetSampler() - { - return _sampler; - } - - public void Dispose() - { - if (_renderer.Samplers.Remove(this)) - { - _sampler.Dispose(); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/Blit.metal b/src/Ryujinx.Graphics.Metal/Shaders/Blit.metal deleted file mode 100644 index 887878499..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/Blit.metal +++ /dev/null @@ -1,43 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct TexCoords { - float data[4]; -}; - -struct ConstantBuffers { - constant TexCoords* tex_coord; -}; - -struct Textures -{ - texture2d texture; - sampler sampler; -}; - -vertex CopyVertexOut vertexMain(uint vid [[vertex_id]], - constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]]) { - CopyVertexOut out; - - int low = vid & 1; - int high = vid >> 1; - out.uv.x = constant_buffers.tex_coord->data[low]; - out.uv.y = constant_buffers.tex_coord->data[2 + high]; - out.position.x = (float(low) - 0.5f) * 2.0f; - out.position.y = (float(high) - 0.5f) * 2.0f; - out.position.z = 0.0f; - out.position.w = 1.0f; - - return out; -} - -fragment FORMAT4 fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]]) { - return textures.texture.sample(textures.sampler, in.uv); -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal b/src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal deleted file mode 100644 index 1077b6cea..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/BlitMs.metal +++ /dev/null @@ -1,45 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct TexCoords { - float data[4]; -}; - -struct ConstantBuffers { - constant TexCoords* tex_coord; -}; - -struct Textures -{ - texture2d_ms texture; -}; - -vertex CopyVertexOut vertexMain(uint vid [[vertex_id]], - constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]]) { - CopyVertexOut out; - - int low = vid & 1; - int high = vid >> 1; - out.uv.x = constant_buffers.tex_coord->data[low]; - out.uv.y = constant_buffers.tex_coord->data[2 + high]; - out.position.x = (float(low) - 0.5f) * 2.0f; - out.position.y = (float(high) - 0.5f) * 2.0f; - out.position.z = 0.0f; - out.position.w = 1.0f; - - return out; -} - -fragment FORMAT4 fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]], - uint sample_id [[sample_id]]) { - uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height()); - uint2 tex_coord = uint2(in.uv * float2(tex_size)); - return textures.texture.read(tex_coord, sample_id); -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/ChangeBufferStride.metal b/src/Ryujinx.Graphics.Metal/Shaders/ChangeBufferStride.metal deleted file mode 100644 index 1a7d2c574..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/ChangeBufferStride.metal +++ /dev/null @@ -1,72 +0,0 @@ -#include - -using namespace metal; - -struct StrideArguments { - int4 data; -}; - -struct InData { - uint8_t data[1]; -}; - -struct OutData { - uint8_t data[1]; -}; - -struct ConstantBuffers { - constant StrideArguments* stride_arguments; -}; - -struct StorageBuffers { - device InData* in_data; - device OutData* out_data; -}; - -kernel void kernelMain(constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]], - device StorageBuffers &storage_buffers [[buffer(STORAGE_BUFFERS_INDEX)]], - uint3 thread_position_in_grid [[thread_position_in_grid]], - uint3 threads_per_threadgroup [[threads_per_threadgroup]], - uint3 threadgroups_per_grid [[threadgroups_per_grid]]) -{ - // Determine what slice of the stride copies this invocation will perform. - - int sourceStride = constant_buffers.stride_arguments->data.x; - int targetStride = constant_buffers.stride_arguments->data.y; - int bufferSize = constant_buffers.stride_arguments->data.z; - int sourceOffset = constant_buffers.stride_arguments->data.w; - - int strideRemainder = targetStride - sourceStride; - int invocations = int(threads_per_threadgroup.x * threadgroups_per_grid.x); - - int copiesRequired = bufferSize / sourceStride; - - // Find the copies that this invocation should perform. - - // - Copies that all invocations perform. - int allInvocationCopies = copiesRequired / invocations; - - // - Extra remainder copy that this invocation performs. - int index = int(thread_position_in_grid.x); - int extra = (index < (copiesRequired % invocations)) ? 1 : 0; - - int copyCount = allInvocationCopies + extra; - - // Finally, get the starting offset. Make sure to count extra copies. - - int startCopy = allInvocationCopies * index + min(copiesRequired % invocations, index); - - int srcOffset = sourceOffset + startCopy * sourceStride; - int dstOffset = startCopy * targetStride; - - // Perform the copies for this region - for (int i = 0; i < copyCount; i++) { - for (int j = 0; j < sourceStride; j++) { - storage_buffers.out_data->data[dstOffset++] = storage_buffers.in_data->data[srcOffset++]; - } - - for (int j = 0; j < strideRemainder; j++) { - storage_buffers.out_data->data[dstOffset++] = uint8_t(0); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/ColorClear.metal b/src/Ryujinx.Graphics.Metal/Shaders/ColorClear.metal deleted file mode 100644 index 46a57e035..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/ColorClear.metal +++ /dev/null @@ -1,38 +0,0 @@ -#include - -using namespace metal; - -struct VertexOut { - float4 position [[position]]; -}; - -struct ClearColor { - FORMAT4 data; -}; - -struct ConstantBuffers { - constant ClearColor* clear_color; -}; - -vertex VertexOut vertexMain(ushort vid [[vertex_id]]) { - int low = vid & 1; - int high = vid >> 1; - - VertexOut out; - - out.position.x = (float(low) - 0.5f) * 2.0f; - out.position.y = (float(high) - 0.5f) * 2.0f; - out.position.z = 0.0f; - out.position.w = 1.0f; - - return out; -} - -struct FragmentOut { - FORMAT4 color [[color(COLOR_ATTACHMENT_INDEX)]]; -}; - -fragment FragmentOut fragmentMain(VertexOut in [[stage_in]], - constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]]) { - return {constant_buffers.clear_color->data}; -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/ConvertD32S8ToD24S8.metal b/src/Ryujinx.Graphics.Metal/Shaders/ConvertD32S8ToD24S8.metal deleted file mode 100644 index 870ac3d78..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/ConvertD32S8ToD24S8.metal +++ /dev/null @@ -1,66 +0,0 @@ -#include - -using namespace metal; - -struct StrideArguments { - int pixelCount; - int dstStartOffset; -}; - -struct InData { - uint data[1]; -}; - -struct OutData { - uint data[1]; -}; - -struct ConstantBuffers { - constant StrideArguments* stride_arguments; -}; - -struct StorageBuffers { - device InData* in_data; - device OutData* out_data; -}; - -kernel void kernelMain(constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]], - device StorageBuffers &storage_buffers [[buffer(STORAGE_BUFFERS_INDEX)]], - uint3 thread_position_in_grid [[thread_position_in_grid]], - uint3 threads_per_threadgroup [[threads_per_threadgroup]], - uint3 threadgroups_per_grid [[threadgroups_per_grid]]) -{ - // Determine what slice of the stride copies this invocation will perform. - int invocations = int(threads_per_threadgroup.x * threadgroups_per_grid.x); - - int copiesRequired = constant_buffers.stride_arguments->pixelCount; - - // Find the copies that this invocation should perform. - - // - Copies that all invocations perform. - int allInvocationCopies = copiesRequired / invocations; - - // - Extra remainder copy that this invocation performs. - int index = int(thread_position_in_grid.x); - int extra = (index < (copiesRequired % invocations)) ? 1 : 0; - - int copyCount = allInvocationCopies + extra; - - // Finally, get the starting offset. Make sure to count extra copies. - - int startCopy = allInvocationCopies * index + min(copiesRequired % invocations, index); - - int srcOffset = startCopy * 2; - int dstOffset = constant_buffers.stride_arguments->dstStartOffset + startCopy; - - // Perform the conversion for this region. - for (int i = 0; i < copyCount; i++) - { - float depth = as_type(storage_buffers.in_data->data[srcOffset++]); - uint stencil = storage_buffers.in_data->data[srcOffset++]; - - uint rescaledDepth = uint(clamp(depth, 0.0, 1.0) * 16777215.0); - - storage_buffers.out_data->data[dstOffset++] = (rescaledDepth << 8) | (stencil & 0xff); - } -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/ConvertIndexBuffer.metal b/src/Ryujinx.Graphics.Metal/Shaders/ConvertIndexBuffer.metal deleted file mode 100644 index c8fee5818..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/ConvertIndexBuffer.metal +++ /dev/null @@ -1,59 +0,0 @@ -#include - -using namespace metal; - -struct IndexBufferPattern { - int pattern[8]; - int primitiveVertices; - int primitiveVerticesOut; - int indexSize; - int indexSizeOut; - int baseIndex; - int indexStride; - int srcOffset; - int totalPrimitives; -}; - -struct InData { - uint8_t data[1]; -}; - -struct OutData { - uint8_t data[1]; -}; - -struct StorageBuffers { - device InData* in_data; - device OutData* out_data; - constant IndexBufferPattern* index_buffer_pattern; -}; - -kernel void kernelMain(device StorageBuffers &storage_buffers [[buffer(STORAGE_BUFFERS_INDEX)]], - uint3 thread_position_in_grid [[thread_position_in_grid]]) -{ - int primitiveIndex = int(thread_position_in_grid.x); - if (primitiveIndex >= storage_buffers.index_buffer_pattern->totalPrimitives) - { - return; - } - - int inOffset = primitiveIndex * storage_buffers.index_buffer_pattern->indexStride; - int outOffset = primitiveIndex * storage_buffers.index_buffer_pattern->primitiveVerticesOut; - - for (int i = 0; i < storage_buffers.index_buffer_pattern->primitiveVerticesOut; i++) - { - int j; - int io = max(0, inOffset + storage_buffers.index_buffer_pattern->baseIndex + storage_buffers.index_buffer_pattern->pattern[i]) * storage_buffers.index_buffer_pattern->indexSize; - int oo = (outOffset + i) * storage_buffers.index_buffer_pattern->indexSizeOut; - - for (j = 0; j < storage_buffers.index_buffer_pattern->indexSize; j++) - { - storage_buffers.out_data->data[oo + j] = storage_buffers.in_data->data[storage_buffers.index_buffer_pattern->srcOffset + io + j]; - } - - for(; j < storage_buffers.index_buffer_pattern->indexSizeOut; j++) - { - storage_buffers.out_data->data[oo + j] = uint8_t(0); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/DepthBlit.metal b/src/Ryujinx.Graphics.Metal/Shaders/DepthBlit.metal deleted file mode 100644 index 8b8467c2f..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/DepthBlit.metal +++ /dev/null @@ -1,27 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct Textures -{ - texture2d texture; - sampler sampler; -}; - -struct FragmentOut { - float depth [[depth(any)]]; -}; - -fragment FragmentOut fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]]) { - FragmentOut out; - - out.depth = textures.texture.sample(textures.sampler, in.uv).r; - - return out; -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/DepthBlitMs.metal b/src/Ryujinx.Graphics.Metal/Shaders/DepthBlitMs.metal deleted file mode 100644 index 10791f636..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/DepthBlitMs.metal +++ /dev/null @@ -1,29 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct Textures -{ - texture2d_ms texture; -}; - -struct FragmentOut { - float depth [[depth(any)]]; -}; - -fragment FragmentOut fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]], - uint sample_id [[sample_id]]) { - FragmentOut out; - - uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height()); - uint2 tex_coord = uint2(in.uv * float2(tex_size)); - out.depth = textures.texture.read(tex_coord, sample_id).r; - - return out; -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/DepthStencilClear.metal b/src/Ryujinx.Graphics.Metal/Shaders/DepthStencilClear.metal deleted file mode 100644 index 7e50f2ce7..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/DepthStencilClear.metal +++ /dev/null @@ -1,42 +0,0 @@ -#include - -using namespace metal; - -struct VertexOut { - float4 position [[position]]; -}; - -struct FragmentOut { - float depth [[depth(any)]]; -}; - -struct ClearDepth { - float data; -}; - -struct ConstantBuffers { - constant ClearDepth* clear_depth; -}; - -vertex VertexOut vertexMain(ushort vid [[vertex_id]]) { - int low = vid & 1; - int high = vid >> 1; - - VertexOut out; - - out.position.x = (float(low) - 0.5f) * 2.0f; - out.position.y = (float(high) - 0.5f) * 2.0f; - out.position.z = 0.0f; - out.position.w = 1.0f; - - return out; -} - -fragment FragmentOut fragmentMain(VertexOut in [[stage_in]], - constant ConstantBuffers &constant_buffers [[buffer(CONSTANT_BUFFERS_INDEX)]]) { - FragmentOut out; - - out.depth = constant_buffers.clear_depth->data; - - return out; -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/StencilBlit.metal b/src/Ryujinx.Graphics.Metal/Shaders/StencilBlit.metal deleted file mode 100644 index 0b25f322d..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/StencilBlit.metal +++ /dev/null @@ -1,27 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct Textures -{ - texture2d texture; - sampler sampler; -}; - -struct FragmentOut { - uint stencil [[stencil]]; -}; - -fragment FragmentOut fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]]) { - FragmentOut out; - - out.stencil = textures.texture.sample(textures.sampler, in.uv).r; - - return out; -} diff --git a/src/Ryujinx.Graphics.Metal/Shaders/StencilBlitMs.metal b/src/Ryujinx.Graphics.Metal/Shaders/StencilBlitMs.metal deleted file mode 100644 index e7f2d20b7..000000000 --- a/src/Ryujinx.Graphics.Metal/Shaders/StencilBlitMs.metal +++ /dev/null @@ -1,29 +0,0 @@ -#include - -using namespace metal; - -struct CopyVertexOut { - float4 position [[position]]; - float2 uv; -}; - -struct Textures -{ - texture2d_ms texture; -}; - -struct FragmentOut { - uint stencil [[stencil]]; -}; - -fragment FragmentOut fragmentMain(CopyVertexOut in [[stage_in]], - constant Textures &textures [[buffer(TEXTURES_INDEX)]], - uint sample_id [[sample_id]]) { - FragmentOut out; - - uint2 tex_size = uint2(textures.texture.get_width(), textures.texture.get_height()); - uint2 tex_coord = uint2(in.uv * float2(tex_size)); - out.stencil = textures.texture.read(tex_coord, sample_id).r; - - return out; -} diff --git a/src/Ryujinx.Graphics.Metal/StagingBuffer.cs b/src/Ryujinx.Graphics.Metal/StagingBuffer.cs deleted file mode 100644 index b4838ee33..000000000 --- a/src/Ryujinx.Graphics.Metal/StagingBuffer.cs +++ /dev/null @@ -1,288 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - readonly struct StagingBufferReserved - { - public readonly BufferHolder Buffer; - public readonly int Offset; - public readonly int Size; - - public StagingBufferReserved(BufferHolder buffer, int offset, int size) - { - Buffer = buffer; - Offset = offset; - Size = size; - } - } - - [SupportedOSPlatform("macos")] - class StagingBuffer : IDisposable - { - private const int BufferSize = 32 * 1024 * 1024; - - private int _freeOffset; - private int _freeSize; - - private readonly MetalRenderer _renderer; - private readonly BufferHolder _buffer; - private readonly int _resourceAlignment; - - public readonly BufferHandle Handle; - - private readonly struct PendingCopy - { - public FenceHolder Fence { get; } - public int Size { get; } - - public PendingCopy(FenceHolder fence, int size) - { - Fence = fence; - Size = size; - fence.Get(); - } - } - - private readonly Queue _pendingCopies; - - public StagingBuffer(MetalRenderer renderer, BufferManager bufferManager) - { - _renderer = renderer; - - Handle = bufferManager.CreateWithHandle(BufferSize, out _buffer); - _pendingCopies = new Queue(); - _freeSize = BufferSize; - _resourceAlignment = Constants.MinResourceAlignment; - } - - public void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, BufferHolder dst, int dstOffset, ReadOnlySpan data) - { - bool isRender = cbs != null; - CommandBufferScoped scoped = cbs ?? cbp.Rent(); - - // Must push all data to the buffer. If it can't fit, split it up. - - while (data.Length > 0) - { - if (_freeSize < data.Length) - { - FreeCompleted(); - } - - while (_freeSize == 0) - { - if (!WaitFreeCompleted(cbp)) - { - if (isRender) - { - _renderer.FlushAllCommands(); - scoped = cbp.Rent(); - isRender = false; - } - else - { - scoped = cbp.ReturnAndRent(scoped); - } - } - } - - int chunkSize = Math.Min(_freeSize, data.Length); - - PushDataImpl(scoped, dst, dstOffset, data[..chunkSize]); - - dstOffset += chunkSize; - data = data[chunkSize..]; - } - - if (!isRender) - { - scoped.Dispose(); - } - } - - private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan data) - { - Auto srcBuffer = _buffer.GetBuffer(); - Auto dstBuffer = dst.GetBuffer(dstOffset, data.Length, true); - - int offset = _freeOffset; - int capacity = BufferSize - offset; - if (capacity < data.Length) - { - _buffer.SetDataUnchecked(offset, data[..capacity]); - _buffer.SetDataUnchecked(0, data[capacity..]); - - BufferHolder.Copy(cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity); - BufferHolder.Copy(cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity); - } - else - { - _buffer.SetDataUnchecked(offset, data); - - BufferHolder.Copy(cbs, srcBuffer, dstBuffer, offset, dstOffset, data.Length); - } - - _freeOffset = (offset + data.Length) & (BufferSize - 1); - _freeSize -= data.Length; - Debug.Assert(_freeSize >= 0); - - _pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length)); - } - - public bool TryPushData(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan data) - { - if (data.Length > BufferSize) - { - return false; - } - - if (_freeSize < data.Length) - { - FreeCompleted(); - - if (_freeSize < data.Length) - { - return false; - } - } - - PushDataImpl(cbs, dst, dstOffset, data); - - return true; - } - - private StagingBufferReserved ReserveDataImpl(CommandBufferScoped cbs, int size, int alignment) - { - // Assumes the caller has already determined that there is enough space. - int offset = BitUtils.AlignUp(_freeOffset, alignment); - int padding = offset - _freeOffset; - - int capacity = Math.Min(_freeSize, BufferSize - offset); - int reservedLength = size + padding; - if (capacity < size) - { - offset = 0; // Place at start. - reservedLength += capacity; - } - - _freeOffset = (_freeOffset + reservedLength) & (BufferSize - 1); - _freeSize -= reservedLength; - Debug.Assert(_freeSize >= 0); - - _pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), reservedLength)); - - return new StagingBufferReserved(_buffer, offset, size); - } - - private int GetContiguousFreeSize(int alignment) - { - int alignedFreeOffset = BitUtils.AlignUp(_freeOffset, alignment); - int padding = alignedFreeOffset - _freeOffset; - - // Free regions: - // - Aligned free offset to end (minimum free size - padding) - // - 0 to _freeOffset + freeSize wrapped (only if free area contains 0) - - int endOffset = (_freeOffset + _freeSize) & (BufferSize - 1); - - return Math.Max( - Math.Min(_freeSize - padding, BufferSize - alignedFreeOffset), - endOffset <= _freeOffset ? Math.Min(_freeSize, endOffset) : 0 - ); - } - - /// - /// Reserve a range on the staging buffer for the current command buffer and upload data to it. - /// - /// Command buffer to reserve the data on - /// The minimum size the reserved data requires - /// The required alignment for the buffer offset - /// The reserved range of the staging buffer - public StagingBufferReserved? TryReserveData(CommandBufferScoped cbs, int size, int alignment) - { - if (size > BufferSize) - { - return null; - } - - // Temporary reserved data cannot be fragmented. - - if (GetContiguousFreeSize(alignment) < size) - { - FreeCompleted(); - - if (GetContiguousFreeSize(alignment) < size) - { - Logger.Debug?.PrintMsg(LogClass.Gpu, $"Staging buffer out of space to reserve data of size {size}."); - return null; - } - } - - return ReserveDataImpl(cbs, size, alignment); - } - - /// - /// Reserve a range on the staging buffer for the current command buffer and upload data to it. - /// Uses the most permissive byte alignment. - /// - /// Command buffer to reserve the data on - /// The minimum size the reserved data requires - /// The reserved range of the staging buffer - public StagingBufferReserved? TryReserveData(CommandBufferScoped cbs, int size) - { - return TryReserveData(cbs, size, _resourceAlignment); - } - - private bool WaitFreeCompleted(CommandBufferPool cbp) - { - if (_pendingCopies.TryPeek(out PendingCopy pc)) - { - if (!pc.Fence.IsSignaled()) - { - if (cbp.IsFenceOnRentedCommandBuffer(pc.Fence)) - { - return false; - } - - pc.Fence.Wait(); - } - - PendingCopy dequeued = _pendingCopies.Dequeue(); - Debug.Assert(dequeued.Fence == pc.Fence); - _freeSize += pc.Size; - pc.Fence.Put(); - } - - return true; - } - - public void FreeCompleted() - { - FenceHolder signalledFence = null; - while (_pendingCopies.TryPeek(out PendingCopy pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled())) - { - signalledFence = pc.Fence; // Already checked - don't need to do it again. - PendingCopy dequeued = _pendingCopies.Dequeue(); - Debug.Assert(dequeued.Fence == pc.Fence); - _freeSize += pc.Size; - pc.Fence.Put(); - } - } - - public void Dispose() - { - _renderer.BufferManager.Delete(Handle); - - while (_pendingCopies.TryDequeue(out PendingCopy pc)) - { - pc.Fence.Put(); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/State/DepthStencilUid.cs b/src/Ryujinx.Graphics.Metal/State/DepthStencilUid.cs deleted file mode 100644 index 63b1d8ef4..000000000 --- a/src/Ryujinx.Graphics.Metal/State/DepthStencilUid.cs +++ /dev/null @@ -1,110 +0,0 @@ -using SharpMetal.Metal; -using System; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; - -namespace Ryujinx.Graphics.Metal.State -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct StencilUid - { - public uint ReadMask; - public uint WriteMask; - public ushort Operations; - - public MTLStencilOperation StencilFailureOperation - { - readonly get => (MTLStencilOperation)((Operations >> 0) & 0xF); - set => Operations = (ushort)((Operations & 0xFFF0) | ((int)value << 0)); - } - - public MTLStencilOperation DepthFailureOperation - { - readonly get => (MTLStencilOperation)((Operations >> 4) & 0xF); - set => Operations = (ushort)((Operations & 0xFF0F) | ((int)value << 4)); - } - - public MTLStencilOperation DepthStencilPassOperation - { - readonly get => (MTLStencilOperation)((Operations >> 8) & 0xF); - set => Operations = (ushort)((Operations & 0xF0FF) | ((int)value << 8)); - } - - public MTLCompareFunction StencilCompareFunction - { - readonly get => (MTLCompareFunction)((Operations >> 12) & 0xF); - set => Operations = (ushort)((Operations & 0x0FFF) | ((int)value << 12)); - } - } - - - [StructLayout(LayoutKind.Explicit, Size = 24)] - internal struct DepthStencilUid : IEquatable - { - [FieldOffset(0)] - public StencilUid FrontFace; - - [FieldOffset(10)] - public ushort DepthState; - - [FieldOffset(12)] - public StencilUid BackFace; - - [FieldOffset(22)] - private readonly ushort _padding; - - // Quick access aliases -#pragma warning disable IDE0044 // Add readonly modifier - [FieldOffset(0)] - private ulong _id0; - [FieldOffset(8)] - private ulong _id1; - [FieldOffset(0)] - private Vector128 _id01; - [FieldOffset(16)] - private ulong _id2; -#pragma warning restore IDE0044 // Add readonly modifier - - public MTLCompareFunction DepthCompareFunction - { - readonly get => (MTLCompareFunction)((DepthState >> 0) & 0xF); - set => DepthState = (ushort)((DepthState & 0xFFF0) | ((int)value << 0)); - } - - public bool StencilTestEnabled - { - readonly get => ((DepthState >> 4) & 0x1) != 0; - set => DepthState = (ushort)((DepthState & 0xFFEF) | ((value ? 1 : 0) << 4)); - } - - public bool DepthWriteEnabled - { - readonly get => ((DepthState >> 15) & 0x1) != 0; - set => DepthState = (ushort)((DepthState & 0x7FFF) | ((value ? 1 : 0) << 15)); - } - - public readonly override bool Equals(object obj) - { - return obj is DepthStencilUid other && EqualsRef(ref other); - } - - public readonly bool EqualsRef(ref DepthStencilUid other) - { - return _id01.Equals(other._id01) && _id2 == other._id2; - } - - public readonly bool Equals(DepthStencilUid other) - { - return EqualsRef(ref other); - } - - public readonly override int GetHashCode() - { - ulong hash64 = _id0 * 23 ^ - _id1 * 23 ^ - _id2 * 23; - - return (int)hash64 ^ ((int)(hash64 >> 32) * 17); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/State/PipelineState.cs b/src/Ryujinx.Graphics.Metal/State/PipelineState.cs deleted file mode 100644 index 14073dbe1..000000000 --- a/src/Ryujinx.Graphics.Metal/State/PipelineState.cs +++ /dev/null @@ -1,341 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using SharpMetal.Foundation; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - struct PipelineState - { - public PipelineUid Internal; - - public uint StagesCount - { - readonly get => (byte)((Internal.Id0 >> 0) & 0xFF); - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0); - } - - public uint VertexAttributeDescriptionsCount - { - readonly get => (byte)((Internal.Id0 >> 8) & 0xFF); - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8); - } - - public uint VertexBindingDescriptionsCount - { - readonly get => (byte)((Internal.Id0 >> 16) & 0xFF); - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFFFF00FFFF) | ((ulong)value << 16); - } - - public uint ColorBlendAttachmentStateCount - { - readonly get => (byte)((Internal.Id0 >> 24) & 0xFF); - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF00FFFFFF) | ((ulong)value << 24); - } - - /* - * Can be an input to a pipeline, but not sure what the situation for that is. - public PrimitiveTopology Topology - { - readonly get => (PrimitiveTopology)((Internal.Id6 >> 16) & 0xF); - set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16); - } - */ - - public MTLLogicOperation LogicOp - { - readonly get => (MTLLogicOperation)((Internal.Id0 >> 32) & 0xF); - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFF0FFFFFFFF) | ((ulong)value << 32); - } - - //? - public bool PrimitiveRestartEnable - { - readonly get => ((Internal.Id0 >> 36) & 0x1) != 0UL; - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFEFFFFFFFFF) | ((value ? 1UL : 0UL) << 36); - } - - public bool RasterizerDiscardEnable - { - readonly get => ((Internal.Id0 >> 37) & 0x1) != 0UL; - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFDFFFFFFFFF) | ((value ? 1UL : 0UL) << 37); - } - - public bool LogicOpEnable - { - readonly get => ((Internal.Id0 >> 38) & 0x1) != 0UL; - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFBFFFFFFFFF) | ((value ? 1UL : 0UL) << 38); - } - - public bool AlphaToCoverageEnable - { - readonly get => ((Internal.Id0 >> 40) & 0x1) != 0UL; - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFEFFFFFFFFFF) | ((value ? 1UL : 0UL) << 40); - } - - public bool AlphaToOneEnable - { - readonly get => ((Internal.Id0 >> 41) & 0x1) != 0UL; - set => Internal.Id0 = (Internal.Id0 & 0xFFFFFDFFFFFFFFFF) | ((value ? 1UL : 0UL) << 41); - } - - public MTLPixelFormat DepthStencilFormat - { - readonly get => (MTLPixelFormat)(Internal.Id0 >> 48); - set => Internal.Id0 = (Internal.Id0 & 0x0000FFFFFFFFFFFF) | ((ulong)value << 48); - } - - // Not sure how to appropriately use this, but it does need to be passed for tess. - public uint PatchControlPoints - { - readonly get => (uint)((Internal.Id1 >> 0) & 0xFFFFFFFF); - set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF00000000) | ((ulong)value << 0); - } - - public uint SamplesCount - { - readonly get => (uint)((Internal.Id1 >> 32) & 0xFFFFFFFF); - set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF) | ((ulong)value << 32); - } - - // Advanced blend not supported - - private readonly void BuildColorAttachment(MTLRenderPipelineColorAttachmentDescriptor descriptor, ColorBlendStateUid blendState) - { - descriptor.PixelFormat = blendState.PixelFormat; - descriptor.SetBlendingEnabled(blendState.Enable); - descriptor.AlphaBlendOperation = blendState.AlphaBlendOperation; - descriptor.RgbBlendOperation = blendState.RgbBlendOperation; - descriptor.SourceAlphaBlendFactor = blendState.SourceAlphaBlendFactor; - descriptor.DestinationAlphaBlendFactor = blendState.DestinationAlphaBlendFactor; - descriptor.SourceRGBBlendFactor = blendState.SourceRGBBlendFactor; - descriptor.DestinationRGBBlendFactor = blendState.DestinationRGBBlendFactor; - descriptor.WriteMask = blendState.WriteMask; - } - - private readonly MTLVertexDescriptor BuildVertexDescriptor() - { - MTLVertexDescriptor vertexDescriptor = new(); - - for (int i = 0; i < VertexAttributeDescriptionsCount; i++) - { - VertexInputAttributeUid uid = Internal.VertexAttributes[i]; - - MTLVertexAttributeDescriptor attrib = vertexDescriptor.Attributes.Object((ulong)i); - attrib.Format = uid.Format; - attrib.Offset = uid.Offset; - attrib.BufferIndex = uid.BufferIndex; - } - - for (int i = 0; i < VertexBindingDescriptionsCount; i++) - { - VertexInputLayoutUid uid = Internal.VertexBindings[i]; - - MTLVertexBufferLayoutDescriptor layout = vertexDescriptor.Layouts.Object((ulong)i); - - layout.StepFunction = uid.StepFunction; - layout.StepRate = uid.StepRate; - layout.Stride = uid.Stride; - } - - return vertexDescriptor; - } - - private MTLRenderPipelineDescriptor CreateRenderDescriptor(Program program) - { - MTLRenderPipelineDescriptor renderPipelineDescriptor = new(); - - for (int i = 0; i < Constants.MaxColorAttachments; i++) - { - ColorBlendStateUid blendState = Internal.ColorBlendState[i]; - - if (blendState.PixelFormat != MTLPixelFormat.Invalid) - { - MTLRenderPipelineColorAttachmentDescriptor pipelineAttachment = renderPipelineDescriptor.ColorAttachments.Object((ulong)i); - - BuildColorAttachment(pipelineAttachment, blendState); - } - } - - MTLPixelFormat dsFormat = DepthStencilFormat; - if (dsFormat != MTLPixelFormat.Invalid) - { - switch (dsFormat) - { - // Depth Only Attachment - case MTLPixelFormat.Depth16Unorm: - case MTLPixelFormat.Depth32Float: - renderPipelineDescriptor.DepthAttachmentPixelFormat = dsFormat; - break; - - // Stencil Only Attachment - case MTLPixelFormat.Stencil8: - renderPipelineDescriptor.StencilAttachmentPixelFormat = dsFormat; - break; - - // Combined Attachment - case MTLPixelFormat.Depth24UnormStencil8: - case MTLPixelFormat.Depth32FloatStencil8: - renderPipelineDescriptor.DepthAttachmentPixelFormat = dsFormat; - renderPipelineDescriptor.StencilAttachmentPixelFormat = dsFormat; - break; - default: - Logger.Error?.PrintMsg(LogClass.Gpu, $"Unsupported Depth/Stencil Format: {dsFormat}!"); - break; - } - } - - renderPipelineDescriptor.LogicOperationEnabled = LogicOpEnable; - renderPipelineDescriptor.LogicOperation = LogicOp; - renderPipelineDescriptor.AlphaToCoverageEnabled = AlphaToCoverageEnable; - renderPipelineDescriptor.AlphaToOneEnabled = AlphaToOneEnable; - renderPipelineDescriptor.RasterizationEnabled = !RasterizerDiscardEnable; - renderPipelineDescriptor.SampleCount = Math.Max(1, SamplesCount); - - MTLVertexDescriptor vertexDescriptor = BuildVertexDescriptor(); - renderPipelineDescriptor.VertexDescriptor = vertexDescriptor; - - renderPipelineDescriptor.VertexFunction = program.VertexFunction; - - if (program.FragmentFunction.NativePtr != 0) - { - renderPipelineDescriptor.FragmentFunction = program.FragmentFunction; - } - - return renderPipelineDescriptor; - } - - public MTLRenderPipelineState CreateRenderPipeline(MTLDevice device, Program program) - { - if (program.TryGetGraphicsPipeline(ref Internal, out MTLRenderPipelineState pipelineState)) - { - return pipelineState; - } - - using MTLRenderPipelineDescriptor descriptor = CreateRenderDescriptor(program); - - NSError error = new(IntPtr.Zero); - pipelineState = device.NewRenderPipelineState(descriptor, ref error); - if (error != IntPtr.Zero) - { - Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Render Pipeline State: {StringHelper.String(error.LocalizedDescription)}"); - } - - program.AddGraphicsPipeline(ref Internal, pipelineState); - - return pipelineState; - } - - public static MTLComputePipelineDescriptor CreateComputeDescriptor(Program program) - { - ComputeSize localSize = program.ComputeLocalSize; - - uint maxThreads = (uint)(localSize.X * localSize.Y * localSize.Z); - - if (maxThreads == 0) - { - throw new InvalidOperationException($"Local thread size for compute cannot be 0 in any dimension."); - } - - MTLComputePipelineDescriptor descriptor = new() - { - ComputeFunction = program.ComputeFunction, - MaxTotalThreadsPerThreadgroup = maxThreads, - ThreadGroupSizeIsMultipleOfThreadExecutionWidth = true, - }; - - return descriptor; - } - - public static MTLComputePipelineState CreateComputePipeline(MTLDevice device, Program program) - { - if (program.TryGetComputePipeline(out MTLComputePipelineState pipelineState)) - { - return pipelineState; - } - - using MTLComputePipelineDescriptor descriptor = CreateComputeDescriptor(program); - - NSError error = new(IntPtr.Zero); - pipelineState = device.NewComputePipelineState(descriptor, MTLPipelineOption.None, 0, ref error); - if (error != IntPtr.Zero) - { - Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Compute Pipeline State: {StringHelper.String(error.LocalizedDescription)}"); - } - - program.AddComputePipeline(pipelineState); - - return pipelineState; - } - - public void Initialize() - { - SamplesCount = 1; - - Internal.ResetColorState(); - } - - /* - * TODO, this is from vulkan. - - private void UpdateVertexAttributeDescriptions(VulkanRenderer gd) - { - // Vertex attributes exceeding the stride are invalid. - // In metal, they cause glitches with the vertex shader fetching incorrect values. - // To work around this, we reduce the format to something that doesn't exceed the stride if possible. - // The assumption is that the exceeding components are not actually accessed on the shader. - - for (int index = 0; index < VertexAttributeDescriptionsCount; index++) - { - var attribute = Internal.VertexAttributeDescriptions[index]; - int vbIndex = GetVertexBufferIndex(attribute.Binding); - - if (vbIndex >= 0) - { - ref var vb = ref Internal.VertexBindingDescriptions[vbIndex]; - - Format format = attribute.Format; - - while (vb.Stride != 0 && attribute.Offset + FormatTable.GetAttributeFormatSize(format) > vb.Stride) - { - Format newFormat = FormatTable.DropLastComponent(format); - - if (newFormat == format) - { - // That case means we failed to find a format that fits within the stride, - // so just restore the original format and give up. - format = attribute.Format; - break; - } - - format = newFormat; - } - - if (attribute.Format != format && gd.FormatCapabilities.BufferFormatSupports(FormatFeatureFlags.VertexBufferBit, format)) - { - attribute.Format = format; - } - } - - _vertexAttributeDescriptions2[index] = attribute; - } - } - - private int GetVertexBufferIndex(uint binding) - { - for (int index = 0; index < VertexBindingDescriptionsCount; index++) - { - if (Internal.VertexBindingDescriptions[index].Binding == binding) - { - return index; - } - } - - return -1; - } - */ - } -} diff --git a/src/Ryujinx.Graphics.Metal/State/PipelineUid.cs b/src/Ryujinx.Graphics.Metal/State/PipelineUid.cs deleted file mode 100644 index 5b514c2c9..000000000 --- a/src/Ryujinx.Graphics.Metal/State/PipelineUid.cs +++ /dev/null @@ -1,208 +0,0 @@ -using Ryujinx.Common.Memory; -using SharpMetal.Metal; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - struct VertexInputAttributeUid - { - public ulong Id0; - - public ulong Offset - { - readonly get => (uint)((Id0 >> 0) & 0xFFFFFFFF); - set => Id0 = (Id0 & 0xFFFFFFFF00000000) | ((ulong)value << 0); - } - - public MTLVertexFormat Format - { - readonly get => (MTLVertexFormat)((Id0 >> 32) & 0xFFFF); - set => Id0 = (Id0 & 0xFFFF0000FFFFFFFF) | ((ulong)value << 32); - } - - public ulong BufferIndex - { - readonly get => ((Id0 >> 48) & 0xFFFF); - set => Id0 = (Id0 & 0x0000FFFFFFFFFFFF) | ((ulong)value << 48); - } - } - - struct VertexInputLayoutUid - { - public ulong Id0; - - public uint Stride - { - readonly get => (uint)((Id0 >> 0) & 0xFFFFFFFF); - set => Id0 = (Id0 & 0xFFFFFFFF00000000) | ((ulong)value << 0); - } - - public uint StepRate - { - readonly get => (uint)((Id0 >> 32) & 0x1FFFFFFF); - set => Id0 = (Id0 & 0xE0000000FFFFFFFF) | ((ulong)value << 32); - } - - public MTLVertexStepFunction StepFunction - { - readonly get => (MTLVertexStepFunction)((Id0 >> 61) & 0x7); - set => Id0 = (Id0 & 0x1FFFFFFFFFFFFFFF) | ((ulong)value << 61); - } - } - - struct ColorBlendStateUid - { - public ulong Id0; - - public MTLPixelFormat PixelFormat - { - readonly get => (MTLPixelFormat)((Id0 >> 0) & 0xFFFF); - set => Id0 = (Id0 & 0xFFFFFFFFFFFF0000) | ((ulong)value << 0); - } - - public MTLBlendFactor SourceRGBBlendFactor - { - readonly get => (MTLBlendFactor)((Id0 >> 16) & 0xFF); - set => Id0 = (Id0 & 0xFFFFFFFFFF00FFFF) | ((ulong)value << 16); - } - - public MTLBlendFactor DestinationRGBBlendFactor - { - readonly get => (MTLBlendFactor)((Id0 >> 24) & 0xFF); - set => Id0 = (Id0 & 0xFFFFFFFF00FFFFFF) | ((ulong)value << 24); - } - - public MTLBlendOperation RgbBlendOperation - { - readonly get => (MTLBlendOperation)((Id0 >> 32) & 0xF); - set => Id0 = (Id0 & 0xFFFFFFF0FFFFFFFF) | ((ulong)value << 32); - } - - public MTLBlendOperation AlphaBlendOperation - { - readonly get => (MTLBlendOperation)((Id0 >> 36) & 0xF); - set => Id0 = (Id0 & 0xFFFFFF0FFFFFFFFF) | ((ulong)value << 36); - } - - public MTLBlendFactor SourceAlphaBlendFactor - { - readonly get => (MTLBlendFactor)((Id0 >> 40) & 0xFF); - set => Id0 = (Id0 & 0xFFFF00FFFFFFFFFF) | ((ulong)value << 40); - } - - public MTLBlendFactor DestinationAlphaBlendFactor - { - readonly get => (MTLBlendFactor)((Id0 >> 48) & 0xFF); - set => Id0 = (Id0 & 0xFF00FFFFFFFFFFFF) | ((ulong)value << 48); - } - - public MTLColorWriteMask WriteMask - { - readonly get => (MTLColorWriteMask)((Id0 >> 56) & 0xF); - set => Id0 = (Id0 & 0xF0FFFFFFFFFFFFFF) | ((ulong)value << 56); - } - - public bool Enable - { - readonly get => ((Id0 >> 63) & 0x1) != 0UL; - set => Id0 = (Id0 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63); - } - - public void Swap(ColorBlendStateUid uid) - { - MTLPixelFormat format = PixelFormat; - - this = uid; - PixelFormat = format; - } - } - - [SupportedOSPlatform("macos")] - struct PipelineUid : IRefEquatable - { - public ulong Id0; - public ulong Id1; - - private readonly uint VertexAttributeDescriptionsCount => (byte)((Id0 >> 8) & 0xFF); - private readonly uint VertexBindingDescriptionsCount => (byte)((Id0 >> 16) & 0xFF); - private readonly uint ColorBlendAttachmentStateCount => (byte)((Id0 >> 24) & 0xFF); - - public Array32 VertexAttributes; - public Array33 VertexBindings; - public Array8 ColorBlendState; - public uint AttachmentIntegerFormatMask; - public bool LogicOpsAllowed; - - public void ResetColorState() - { - ColorBlendState = new(); - - for (int i = 0; i < ColorBlendState.Length; i++) - { - ColorBlendState[i].WriteMask = MTLColorWriteMask.All; - } - } - - public readonly override bool Equals(object obj) - { - return obj is PipelineUid other && Equals(other); - } - - public bool Equals(ref PipelineUid other) - { - if (!Unsafe.As>(ref Id0).Equals(Unsafe.As>(ref other.Id0))) - { - return false; - } - - if (!SequenceEqual(VertexAttributes.AsSpan(), other.VertexAttributes.AsSpan(), VertexAttributeDescriptionsCount)) - { - return false; - } - - if (!SequenceEqual(VertexBindings.AsSpan(), other.VertexBindings.AsSpan(), VertexBindingDescriptionsCount)) - { - return false; - } - - if (!SequenceEqual(ColorBlendState.AsSpan(), other.ColorBlendState.AsSpan(), ColorBlendAttachmentStateCount)) - { - return false; - } - - return true; - } - - private static bool SequenceEqual(ReadOnlySpan x, ReadOnlySpan y, uint count) where T : unmanaged - { - return MemoryMarshal.Cast(x[..(int)count]).SequenceEqual(MemoryMarshal.Cast(y[..(int)count])); - } - - public override int GetHashCode() - { - ulong hash64 = Id0 * 23 ^ - Id1 * 23; - - for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++) - { - hash64 ^= VertexAttributes[i].Id0 * 23; - } - - for (int i = 0; i < (int)VertexBindingDescriptionsCount; i++) - { - hash64 ^= VertexBindings[i].Id0 * 23; - } - - for (int i = 0; i < (int)ColorBlendAttachmentStateCount; i++) - { - hash64 ^= ColorBlendState[i].Id0 * 23; - } - - return (int)hash64 ^ ((int)(hash64 >> 32) * 17); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/StateCache.cs b/src/Ryujinx.Graphics.Metal/StateCache.cs deleted file mode 100644 index 8a9d175f1..000000000 --- a/src/Ryujinx.Graphics.Metal/StateCache.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - abstract class StateCache : IDisposable where T : IDisposable - { - private readonly Dictionary _cache = new(); - - protected abstract THash GetHash(TDescriptor descriptor); - - protected abstract T CreateValue(TDescriptor descriptor); - - public void Dispose() - { - foreach (T value in _cache.Values) - { - value.Dispose(); - } - - GC.SuppressFinalize(this); - } - - public T GetOrCreate(TDescriptor descriptor) - { - THash hash = GetHash(descriptor); - if (_cache.TryGetValue(hash, out T value)) - { - return value; - } - else - { - T newValue = CreateValue(descriptor); - _cache.Add(hash, newValue); - - return newValue; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/StringHelper.cs b/src/Ryujinx.Graphics.Metal/StringHelper.cs deleted file mode 100644 index 46e8ad2e9..000000000 --- a/src/Ryujinx.Graphics.Metal/StringHelper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using SharpMetal.Foundation; -using SharpMetal.ObjectiveCCore; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class StringHelper - { - public static NSString NSString(string source) - { - return new(ObjectiveC.IntPtr_objc_msgSend(new ObjectiveCClass("NSString"), "stringWithUTF8String:", source)); - } - - public static unsafe string String(NSString source) - { - char[] sourceBuffer = new char[source.Length]; - fixed (char* pSourceBuffer = sourceBuffer) - { - ObjectiveC.bool_objc_msgSend(source, - "getCString:maxLength:encoding:", - pSourceBuffer, - source.MaximumLengthOfBytes(NSStringEncoding.UTF16) + 1, - (ulong)NSStringEncoding.UTF16); - } - - return new string(sourceBuffer); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/SyncManager.cs b/src/Ryujinx.Graphics.Metal/SyncManager.cs deleted file mode 100644 index f2f26fd91..000000000 --- a/src/Ryujinx.Graphics.Metal/SyncManager.cs +++ /dev/null @@ -1,214 +0,0 @@ -using Ryujinx.Common.Logging; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class SyncManager - { - private class SyncHandle - { - public ulong ID; - public MultiFenceHolder Waitable; - public ulong FlushId; - public bool Signalled; - - public bool NeedsFlush(ulong currentFlushId) - { - return (long)(FlushId - currentFlushId) >= 0; - } - } - - private ulong _firstHandle; - - private readonly MetalRenderer _renderer; - private readonly List _handles; - private ulong _flushId; - private long _waitTicks; - - public SyncManager(MetalRenderer renderer) - { - _renderer = renderer; - _handles = []; - } - - public void RegisterFlush() - { - _flushId++; - } - - public void Create(ulong id, bool strict) - { - ulong flushId = _flushId; - MultiFenceHolder waitable = new(); - if (strict || _renderer.InterruptAction == null) - { - _renderer.FlushAllCommands(); - _renderer.CommandBufferPool.AddWaitable(waitable); - } - else - { - // Don't flush commands, instead wait for the current command buffer to finish. - // If this sync is waited on before the command buffer is submitted, interrupt the gpu thread and flush it manually. - - _renderer.CommandBufferPool.AddInUseWaitable(waitable); - } - - SyncHandle handle = new() - { - ID = id, - Waitable = waitable, - FlushId = flushId, - }; - - lock (_handles) - { - _handles.Add(handle); - } - } - - public ulong GetCurrent() - { - lock (_handles) - { - ulong lastHandle = _firstHandle; - - foreach (SyncHandle handle in _handles) - { - lock (handle) - { - if (handle.Waitable == null) - { - continue; - } - - if (handle.ID > lastHandle) - { - bool signaled = handle.Signalled || handle.Waitable.WaitForFences(false); - if (signaled) - { - lastHandle = handle.ID; - handle.Signalled = true; - } - } - } - } - - return lastHandle; - } - } - - public void Wait(ulong id) - { - SyncHandle result = null; - - lock (_handles) - { - if ((long)(_firstHandle - id) > 0) - { - return; // The handle has already been signalled or deleted. - } - - foreach (SyncHandle handle in _handles) - { - if (handle.ID == id) - { - result = handle; - break; - } - } - } - - if (result != null) - { - if (result.Waitable == null) - { - return; - } - - long beforeTicks = Stopwatch.GetTimestamp(); - - if (result.NeedsFlush(_flushId)) - { - _renderer.InterruptAction(() => - { - if (result.NeedsFlush(_flushId)) - { - _renderer.FlushAllCommands(); - } - }); - } - - lock (result) - { - if (result.Waitable == null) - { - return; - } - - bool signaled = result.Signalled || result.Waitable.WaitForFences(true); - - if (!signaled) - { - Logger.Error?.PrintMsg(LogClass.Gpu, $"Metal Sync Object {result.ID} failed to signal within 1000ms. Continuing..."); - } - else - { - _waitTicks += Stopwatch.GetTimestamp() - beforeTicks; - result.Signalled = true; - } - } - } - } - - public void Cleanup() - { - // Iterate through handles and remove any that have already been signalled. - - while (true) - { - SyncHandle first = null; - lock (_handles) - { - first = _handles.FirstOrDefault(); - } - - if (first == null || first.NeedsFlush(_flushId)) - { - break; - } - - bool signaled = first.Waitable.WaitForFences(false); - if (signaled) - { - // Delete the sync object. - lock (_handles) - { - lock (first) - { - _firstHandle = first.ID + 1; - _handles.RemoveAt(0); - first.Waitable = null; - } - } - } - else - { - // This sync handle and any following have not been reached yet. - break; - } - } - } - - public long GetAndResetWaitTicks() - { - long result = _waitTicks; - _waitTicks = 0; - - return result; - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Texture.cs b/src/Ryujinx.Graphics.Metal/Texture.cs deleted file mode 100644 index 754bf1742..000000000 --- a/src/Ryujinx.Graphics.Metal/Texture.cs +++ /dev/null @@ -1,654 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using SharpMetal.Foundation; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class Texture : TextureBase, ITexture - { - private MTLTexture _identitySwizzleHandle; - private readonly bool _identityIsDifferent; - - public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info) - { - MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format); - - MTLTextureDescriptor descriptor = new() - { - PixelFormat = pixelFormat, - Usage = MTLTextureUsage.Unknown, - SampleCount = (ulong)Info.Samples, - TextureType = Info.Target.Convert(), - Width = (ulong)Info.Width, - Height = (ulong)Info.Height, - MipmapLevelCount = (ulong)Info.Levels - }; - - if (info.Target == Target.Texture3D) - { - descriptor.Depth = (ulong)Info.Depth; - } - else if (info.Target != Target.Cubemap) - { - if (info.Target == Target.CubemapArray) - { - descriptor.ArrayLength = (ulong)(Info.Depth / 6); - } - else - { - descriptor.ArrayLength = (ulong)Info.Depth; - } - } - - MTLTextureSwizzleChannels swizzle = GetSwizzle(info, descriptor.PixelFormat); - - _identitySwizzleHandle = Device.NewTexture(descriptor); - - if (SwizzleIsIdentity(swizzle)) - { - MtlTexture = _identitySwizzleHandle; - } - else - { - MtlTexture = CreateDefaultView(_identitySwizzleHandle, swizzle, descriptor); - _identityIsDifferent = true; - } - - MtlFormat = pixelFormat; - descriptor.Dispose(); - } - - public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info, MTLTexture sourceTexture, int firstLayer, int firstLevel) : base(device, renderer, pipeline, info) - { - MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format); - - if (info.DepthStencilMode == DepthStencilMode.Stencil) - { - pixelFormat = pixelFormat switch - { - MTLPixelFormat.Depth32FloatStencil8 => MTLPixelFormat.X32Stencil8, - MTLPixelFormat.Depth24UnormStencil8 => MTLPixelFormat.X24Stencil8, - _ => pixelFormat - }; - } - - MTLTextureType textureType = Info.Target.Convert(); - NSRange levels; - levels.location = (ulong)firstLevel; - levels.length = (ulong)Info.Levels; - NSRange slices; - slices.location = (ulong)firstLayer; - slices.length = textureType == MTLTextureType.Type3D ? 1 : (ulong)info.GetDepthOrLayers(); - - MTLTextureSwizzleChannels swizzle = GetSwizzle(info, pixelFormat); - - _identitySwizzleHandle = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices); - - if (SwizzleIsIdentity(swizzle)) - { - MtlTexture = _identitySwizzleHandle; - } - else - { - MtlTexture = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices, swizzle); - _identityIsDifferent = true; - } - - MtlFormat = pixelFormat; - FirstLayer = firstLayer; - FirstLevel = firstLevel; - } - - public void PopulateRenderPassAttachment(MTLRenderPassColorAttachmentDescriptor descriptor) - { - descriptor.Texture = _identitySwizzleHandle; - } - - private MTLTexture CreateDefaultView(MTLTexture texture, MTLTextureSwizzleChannels swizzle, MTLTextureDescriptor descriptor) - { - NSRange levels; - levels.location = 0; - levels.length = (ulong)Info.Levels; - NSRange slices; - slices.location = 0; - slices.length = Info.Target == Target.Texture3D ? 1 : (ulong)Info.GetDepthOrLayers(); - - return texture.NewTextureView(descriptor.PixelFormat, descriptor.TextureType, levels, slices, swizzle); - } - - private bool SwizzleIsIdentity(MTLTextureSwizzleChannels swizzle) - { - return swizzle.red == MTLTextureSwizzle.Red && - swizzle.green == MTLTextureSwizzle.Green && - swizzle.blue == MTLTextureSwizzle.Blue && - swizzle.alpha == MTLTextureSwizzle.Alpha; - } - - private MTLTextureSwizzleChannels GetSwizzle(TextureCreateInfo info, MTLPixelFormat pixelFormat) - { - MTLTextureSwizzle swizzleR = Info.SwizzleR.Convert(); - MTLTextureSwizzle swizzleG = Info.SwizzleG.Convert(); - MTLTextureSwizzle swizzleB = Info.SwizzleB.Convert(); - MTLTextureSwizzle swizzleA = Info.SwizzleA.Convert(); - - if (info.Format == Format.R5G5B5A1Unorm || - info.Format == Format.R5G5B5X1Unorm || - info.Format == Format.R5G6B5Unorm) - { - (swizzleB, swizzleR) = (swizzleR, swizzleB); - } - else if (pixelFormat == MTLPixelFormat.ABGR4Unorm || info.Format == Format.A1B5G5R5Unorm) - { - MTLTextureSwizzle tempB = swizzleB; - MTLTextureSwizzle tempA = swizzleA; - - swizzleB = swizzleG; - swizzleA = swizzleR; - swizzleR = tempA; - swizzleG = tempB; - } - - return new MTLTextureSwizzleChannels - { - red = swizzleR, - green = swizzleG, - blue = swizzleB, - alpha = swizzleA - }; - } - - public void CopyTo(ITexture destination, int firstLayer, int firstLevel) - { - CommandBufferScoped cbs = Pipeline.Cbs; - - TextureBase src = this; - TextureBase dst = (TextureBase)destination; - - if (!Valid || !dst.Valid) - { - return; - } - - MTLTexture srcImage = GetHandle(); - MTLTexture dstImage = dst.GetHandle(); - - if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) - { - // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); - - // _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, 0, firstLayer, layers); - } - else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) - { - // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); - - // _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, 0, firstLayer, layers); - } - else if (dst.Info.BytesPerPixel != Info.BytesPerPixel) - { - // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); - // int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); - - // _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, 0, firstLayer, 0, firstLevel, layers, levels); - } - else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) - { - // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); - // int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); - - // TODO: depth copy? - // _gd.HelperShader.CopyColor(_gd, cbs, src, dst, 0, firstLayer, 0, FirstLevel, layers, levels); - } - else - { - TextureCopy.Copy( - cbs, - srcImage, - dstImage, - src.Info, - dst.Info, - 0, - firstLayer, - 0, - firstLevel); - } - } - - public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) - { - CommandBufferScoped cbs = Pipeline.Cbs; - - TextureBase src = this; - TextureBase dst = (TextureBase)destination; - - if (!Valid || !dst.Valid) - { - return; - } - - MTLTexture srcImage = GetHandle(); - MTLTexture dstImage = dst.GetHandle(); - - if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) - { - // _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); - } - else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) - { - // _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); - } - else if (dst.Info.BytesPerPixel != Info.BytesPerPixel) - { - // _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); - } - else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) - { - // _gd.HelperShader.CopyColor(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); - } - else - { - TextureCopy.Copy( - cbs, - srcImage, - dstImage, - src.Info, - dst.Info, - srcLayer, - dstLayer, - srcLevel, - dstLevel, - 1, - 1); - } - } - - public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) - { - if (!Renderer.CommandBufferPool.OwnedByCurrentThread) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, "Metal doesn't currently support scaled blit on background thread."); - - return; - } - - Texture dst = (Texture)destination; - - bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); - - Pipeline.Blit(this, dst, srcRegion, dstRegion, isDepthOrStencil, linearFilter); - } - - public void CopyTo(BufferRange range, int layer, int level, int stride) - { - CommandBufferScoped cbs = Pipeline.Cbs; - - int outSize = Info.GetMipSize(level); - int hostSize = GetBufferDataLength(outSize); - - int offset = range.Offset; - - Auto autoBuffer = Renderer.BufferManager.GetBuffer(range.Handle, true); - MTLBuffer mtlBuffer = autoBuffer.Get(cbs, range.Offset, outSize).Value; - - if (PrepareOutputBuffer(cbs, hostSize, mtlBuffer, out MTLBuffer copyToBuffer, out BufferHolder tempCopyHolder)) - { - offset = 0; - } - - CopyFromOrToBuffer(cbs, copyToBuffer, MtlTexture, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride); - - if (tempCopyHolder != null) - { - CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset); - tempCopyHolder.Dispose(); - } - } - - public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - return new Texture(Device, Renderer, Pipeline, info, _identitySwizzleHandle, firstLayer, firstLevel); - } - - private void CopyDataToBuffer(Span storage, ReadOnlySpan input) - { - if (NeedsD24S8Conversion()) - { - FormatConverter.ConvertD24S8ToD32FS8(storage, input); - return; - } - - input.CopyTo(storage); - } - - private ReadOnlySpan GetDataFromBuffer(ReadOnlySpan storage, int size, Span output) - { - if (NeedsD24S8Conversion()) - { - if (output.IsEmpty) - { - output = new byte[GetBufferDataLength(size)]; - } - - FormatConverter.ConvertD32FS8ToD24S8(output, storage); - return output; - } - - return storage; - } - - private bool PrepareOutputBuffer(CommandBufferScoped cbs, int hostSize, MTLBuffer target, out MTLBuffer copyTarget, out BufferHolder copyTargetHolder) - { - if (NeedsD24S8Conversion()) - { - copyTargetHolder = Renderer.BufferManager.Create(hostSize); - copyTarget = copyTargetHolder.GetBuffer().Get(cbs, 0, hostSize).Value; - - return true; - } - - copyTarget = target; - copyTargetHolder = null; - - return false; - } - - private void CopyDataToOutputBuffer(CommandBufferScoped cbs, BufferHolder hostData, Auto copyTarget, int hostSize, int dstOffset) - { - if (NeedsD24S8Conversion()) - { - Renderer.HelperShader.ConvertD32S8ToD24S8(cbs, hostData, copyTarget, hostSize / (2 * sizeof(int)), dstOffset); - } - } - - private bool NeedsD24S8Conversion() - { - return FormatTable.IsD24S8(Info.Format) && MtlFormat == MTLPixelFormat.Depth32FloatStencil8; - } - - public void CopyFromOrToBuffer( - CommandBufferScoped cbs, - MTLBuffer buffer, - MTLTexture image, - int size, - bool to, - int dstLayer, - int dstLevel, - int dstLayers, - int dstLevels, - bool singleSlice, - int offset = 0, - int stride = 0) - { - MTLBlitCommandEncoder blitCommandEncoder = cbs.Encoders.EnsureBlitEncoder(); - - bool is3D = Info.Target == Target.Texture3D; - int width = Math.Max(1, Info.Width >> dstLevel); - int height = Math.Max(1, Info.Height >> dstLevel); - int depth = is3D && !singleSlice ? Math.Max(1, Info.Depth >> dstLevel) : 1; - int layers = dstLayers; - int levels = dstLevels; - - for (int oLevel = 0; oLevel < levels; oLevel++) - { - int level = oLevel + dstLevel; - int mipSize = Info.GetMipSize2D(level); - - int mipSizeLevel = GetBufferDataLength(is3D && !singleSlice - ? Info.GetMipSize(level) - : mipSize * dstLayers); - - int endOffset = offset + mipSizeLevel; - - if ((uint)endOffset > (uint)size) - { - break; - } - - for (int oLayer = 0; oLayer < layers; oLayer++) - { - int layer = !is3D ? dstLayer + oLayer : 0; - int z = is3D ? dstLayer + oLayer : 0; - - if (to) - { - blitCommandEncoder.CopyFromTexture( - image, - (ulong)layer, - (ulong)level, - new MTLOrigin { z = (ulong)z }, - new MTLSize { width = (ulong)width, height = (ulong)height, depth = 1 }, - buffer, - (ulong)offset, - (ulong)Info.GetMipStride(level), - (ulong)mipSize - ); - } - else - { - blitCommandEncoder.CopyFromBuffer( - buffer, - (ulong)offset, - (ulong)Info.GetMipStride(level), - (ulong)mipSize, - new MTLSize { width = (ulong)width, height = (ulong)height, depth = 1 }, - image, - (ulong)(layer + oLayer), - (ulong)level, - new MTLOrigin { z = (ulong)z } - ); - } - - offset += mipSize; - } - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (Info.Target == Target.Texture3D) - { - depth = Math.Max(1, depth >> 1); - } - } - } - - private ReadOnlySpan GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer) - { - int size = 0; - - for (int level = 0; level < Info.Levels; level++) - { - size += Info.GetMipSize(level); - } - - size = GetBufferDataLength(size); - - Span result = flushBuffer.GetTextureData(cbp, this, size); - - return GetDataFromBuffer(result, size, result); - } - - private ReadOnlySpan GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer, int layer, int level) - { - int size = GetBufferDataLength(Info.GetMipSize(level)); - - Span result = flushBuffer.GetTextureData(cbp, this, size, layer, level); - - return GetDataFromBuffer(result, size, result); - } - - public PinnedSpan GetData() - { - BackgroundResource resources = Renderer.BackgroundResources.Get(); - - if (Renderer.CommandBufferPool.OwnedByCurrentThread) - { - Renderer.FlushAllCommands(); - - return PinnedSpan.UnsafeFromSpan(GetData(Renderer.CommandBufferPool, resources.GetFlushBuffer())); - } - - return PinnedSpan.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer())); - } - - public PinnedSpan GetData(int layer, int level) - { - BackgroundResource resources = Renderer.BackgroundResources.Get(); - - if (Renderer.CommandBufferPool.OwnedByCurrentThread) - { - Renderer.FlushAllCommands(); - - return PinnedSpan.UnsafeFromSpan(GetData(Renderer.CommandBufferPool, resources.GetFlushBuffer(), layer, level)); - } - - return PinnedSpan.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level)); - } - - public void SetData(MemoryOwner data) - { - MTLBlitCommandEncoder blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder(); - - Span dataSpan = data.Memory.Span; - - BufferHolder buffer = Renderer.BufferManager.Create(dataSpan.Length); - buffer.SetDataUnchecked(0, dataSpan); - MTLBuffer mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value; - - int width = Info.Width; - int height = Info.Height; - int depth = Info.Depth; - int levels = Info.Levels; - int layers = Info.GetLayers(); - bool is3D = Info.Target == Target.Texture3D; - - int offset = 0; - - for (int level = 0; level < levels; level++) - { - int mipSize = Info.GetMipSize2D(level); - int endOffset = offset + mipSize; - - if ((uint)endOffset > (uint)dataSpan.Length) - { - return; - } - - for (int layer = 0; layer < layers; layer++) - { - blitCommandEncoder.CopyFromBuffer( - mtlBuffer, - (ulong)offset, - (ulong)Info.GetMipStride(level), - (ulong)mipSize, - new MTLSize { width = (ulong)width, height = (ulong)height, depth = is3D ? (ulong)depth : 1 }, - MtlTexture, - (ulong)layer, - (ulong)level, - new MTLOrigin() - ); - - offset += mipSize; - } - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (is3D) - { - depth = Math.Max(1, depth >> 1); - } - } - - // Cleanup - buffer.Dispose(); - } - - private void SetData(ReadOnlySpan data, int layer, int level, int layers, int levels, bool singleSlice) - { - int bufferDataLength = GetBufferDataLength(data.Length); - - using BufferHolder bufferHolder = Renderer.BufferManager.Create(bufferDataLength); - - // TODO: loadInline logic - - CommandBufferScoped cbs = Pipeline.Cbs; - - CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data); - - MTLBuffer buffer = bufferHolder.GetBuffer().Get(cbs).Value; - MTLTexture image = GetHandle(); - - CopyFromOrToBuffer(cbs, buffer, image, bufferDataLength, false, layer, level, layers, levels, singleSlice); - } - - public void SetData(MemoryOwner data, int layer, int level) - { - SetData(data.Memory.Span, layer, level, 1, 1, singleSlice: true); - - data.Dispose(); - } - - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) - { - MTLBlitCommandEncoder blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder(); - - ulong bytesPerRow = (ulong)Info.GetMipStride(level); - ulong bytesPerImage = 0; - if (MtlTexture.TextureType == MTLTextureType.Type3D) - { - bytesPerImage = bytesPerRow * (ulong)Info.Height; - } - - Span dataSpan = data.Memory.Span; - - BufferHolder buffer = Renderer.BufferManager.Create(dataSpan.Length); - buffer.SetDataUnchecked(0, dataSpan); - MTLBuffer mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value; - - blitCommandEncoder.CopyFromBuffer( - mtlBuffer, - 0, - bytesPerRow, - bytesPerImage, - new MTLSize { width = (ulong)region.Width, height = (ulong)region.Height, depth = 1 }, - MtlTexture, - (ulong)layer, - (ulong)level, - new MTLOrigin { x = (ulong)region.X, y = (ulong)region.Y } - ); - - // Cleanup - buffer.Dispose(); - } - - private int GetBufferDataLength(int length) - { - if (NeedsD24S8Conversion()) - { - return length * 2; - } - - return length; - } - - public void SetStorage(BufferRange buffer) - { - throw new NotImplementedException(); - } - - public override void Release() - { - if (_identityIsDifferent) - { - _identitySwizzleHandle.Dispose(); - } - - base.Release(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/TextureArray.cs b/src/Ryujinx.Graphics.Metal/TextureArray.cs deleted file mode 100644 index ea2c74420..000000000 --- a/src/Ryujinx.Graphics.Metal/TextureArray.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - internal class TextureArray : ITextureArray - { - private readonly TextureRef[] _textureRefs; - private readonly TextureBuffer[] _bufferTextureRefs; - - private readonly bool _isBuffer; - private readonly Pipeline _pipeline; - - public TextureArray(int size, bool isBuffer, Pipeline pipeline) - { - if (isBuffer) - { - _bufferTextureRefs = new TextureBuffer[size]; - } - else - { - _textureRefs = new TextureRef[size]; - } - - _isBuffer = isBuffer; - _pipeline = pipeline; - } - - public void SetSamplers(int index, ISampler[] samplers) - { - for (int i = 0; i < samplers.Length; i++) - { - ISampler sampler = samplers[i]; - - if (sampler is SamplerHolder samp) - { - _textureRefs[index + i].Sampler = samp.GetSampler(); - } - else - { - _textureRefs[index + i].Sampler = default; - } - } - - SetDirty(); - } - - public void SetTextures(int index, ITexture[] textures) - { - for (int i = 0; i < textures.Length; i++) - { - ITexture texture = textures[i]; - - if (texture is TextureBuffer textureBuffer) - { - _bufferTextureRefs[index + i] = textureBuffer; - } - else if (texture is Texture tex) - { - _textureRefs[index + i].Storage = tex; - } - else if (!_isBuffer) - { - _textureRefs[index + i].Storage = null; - } - else - { - _bufferTextureRefs[index + i] = null; - } - } - - SetDirty(); - } - - public TextureRef[] GetTextureRefs() - { - return _textureRefs; - } - - public TextureBuffer[] GetBufferTextureRefs() - { - return _bufferTextureRefs; - } - - private void SetDirty() - { - _pipeline.DirtyTextures(); - } - - public void Dispose() { } - } -} diff --git a/src/Ryujinx.Graphics.Metal/TextureBase.cs b/src/Ryujinx.Graphics.Metal/TextureBase.cs deleted file mode 100644 index fecd64958..000000000 --- a/src/Ryujinx.Graphics.Metal/TextureBase.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; -using System.Threading; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - abstract class TextureBase : IDisposable - { - private int _isValid = 1; - - public bool Valid => Volatile.Read(ref _isValid) != 0; - - protected readonly Pipeline Pipeline; - protected readonly MTLDevice Device; - protected readonly MetalRenderer Renderer; - - protected MTLTexture MtlTexture; - - public readonly TextureCreateInfo Info; - public int Width => Info.Width; - public int Height => Info.Height; - public int Depth => Info.Depth; - - public MTLPixelFormat MtlFormat { get; protected set; } - public int FirstLayer { get; protected set; } - public int FirstLevel { get; protected set; } - - public TextureBase(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) - { - Device = device; - Renderer = renderer; - Pipeline = pipeline; - Info = info; - } - - public MTLTexture GetHandle() - { - if (_isValid == 0) - { - return new MTLTexture(IntPtr.Zero); - } - - return MtlTexture; - } - - public virtual void Release() - { - Dispose(); - } - - public void Dispose() - { - bool wasValid = Interlocked.Exchange(ref _isValid, 0) != 0; - - if (wasValid) - { - if (MtlTexture != IntPtr.Zero) - { - MtlTexture.Dispose(); - } - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/TextureBuffer.cs b/src/Ryujinx.Graphics.Metal/TextureBuffer.cs deleted file mode 100644 index 483cef28b..000000000 --- a/src/Ryujinx.Graphics.Metal/TextureBuffer.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class TextureBuffer : TextureBase, ITexture - { - private MTLTextureDescriptor _descriptor; - private BufferHandle _bufferHandle; - private int _offset; - private int _size; - - private int _bufferCount; - private Auto _buffer; - - public TextureBuffer(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info) - { - MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format); - - _descriptor = new MTLTextureDescriptor - { - PixelFormat = pixelFormat, - Usage = MTLTextureUsage.Unknown, - TextureType = MTLTextureType.TextureBuffer, - Width = (ulong)Info.Width, - Height = (ulong)Info.Height, - }; - - MtlFormat = pixelFormat; - } - - public void RebuildStorage(bool write) - { - if (MtlTexture != IntPtr.Zero) - { - MtlTexture.Dispose(); - } - - if (_buffer == null) - { - MtlTexture = default; - } - else - { - DisposableBuffer buffer = _buffer.Get(Pipeline.Cbs, _offset, _size, write); - - _descriptor.Width = (uint)(_size / Info.BytesPerPixel); - MtlTexture = buffer.Value.NewTexture(_descriptor, (ulong)_offset, (ulong)_size); - } - } - - public void CopyTo(ITexture destination, int firstLayer, int firstLevel) - { - throw new NotSupportedException(); - } - - public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) - { - throw new NotSupportedException(); - } - - public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) - { - throw new NotSupportedException(); - } - - public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - throw new NotSupportedException(); - } - - public PinnedSpan GetData() - { - return Renderer.GetBufferData(_bufferHandle, _offset, _size); - } - - public PinnedSpan GetData(int layer, int level) - { - return GetData(); - } - - public void CopyTo(BufferRange range, int layer, int level, int stride) - { - throw new NotImplementedException(); - } - - public void SetData(MemoryOwner data) - { - Renderer.SetBufferData(_bufferHandle, _offset, data.Memory.Span); - data.Dispose(); - } - - public void SetData(MemoryOwner data, int layer, int level) - { - throw new NotSupportedException(); - } - - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) - { - throw new NotSupportedException(); - } - - public void SetStorage(BufferRange buffer) - { - if (_bufferHandle == buffer.Handle && - _offset == buffer.Offset && - _size == buffer.Size && - _bufferCount == Renderer.BufferManager.BufferCount) - { - return; - } - - _bufferHandle = buffer.Handle; - _offset = buffer.Offset; - _size = buffer.Size; - _bufferCount = Renderer.BufferManager.BufferCount; - - _buffer = Renderer.BufferManager.GetBuffer(_bufferHandle, false); - } - - public override void Release() - { - _descriptor.Dispose(); - - base.Release(); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/TextureCopy.cs b/src/Ryujinx.Graphics.Metal/TextureCopy.cs deleted file mode 100644 index afd3e961f..000000000 --- a/src/Ryujinx.Graphics.Metal/TextureCopy.cs +++ /dev/null @@ -1,265 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - static class TextureCopy - { - public static ulong CopyFromOrToBuffer( - CommandBufferScoped cbs, - MTLBuffer buffer, - MTLTexture image, - TextureCreateInfo info, - bool to, - int dstLayer, - int dstLevel, - int x, - int y, - int width, - int height, - ulong offset = 0) - { - MTLBlitCommandEncoder blitCommandEncoder = cbs.Encoders.EnsureBlitEncoder(); - - bool is3D = info.Target == Target.Texture3D; - - int blockWidth = BitUtils.DivRoundUp(width, info.BlockWidth); - int blockHeight = BitUtils.DivRoundUp(height, info.BlockHeight); - ulong bytesPerRow = (ulong)BitUtils.AlignUp(blockWidth * info.BytesPerPixel, 4); - ulong bytesPerImage = bytesPerRow * (ulong)blockHeight; - - MTLOrigin origin = new() { x = (ulong)x, y = (ulong)y, z = is3D ? (ulong)dstLayer : 0 }; - MTLSize region = new() { width = (ulong)width, height = (ulong)height, depth = 1 }; - - uint layer = is3D ? 0 : (uint)dstLayer; - - if (to) - { - blitCommandEncoder.CopyFromTexture( - image, - layer, - (ulong)dstLevel, - origin, - region, - buffer, - offset, - bytesPerRow, - bytesPerImage); - } - else - { - blitCommandEncoder.CopyFromBuffer(buffer, offset, bytesPerRow, bytesPerImage, region, image, layer, (ulong)dstLevel, origin); - } - - return offset + bytesPerImage; - } - - public static void Copy( - CommandBufferScoped cbs, - MTLTexture srcImage, - MTLTexture dstImage, - TextureCreateInfo srcInfo, - TextureCreateInfo dstInfo, - int srcLayer, - int dstLayer, - int srcLevel, - int dstLevel) - { - int srcDepth = srcInfo.GetDepthOrLayers(); - int srcLevels = srcInfo.Levels; - - int dstDepth = dstInfo.GetDepthOrLayers(); - int dstLevels = dstInfo.Levels; - - if (dstInfo.Target == Target.Texture3D) - { - dstDepth = Math.Max(1, dstDepth >> dstLevel); - } - - int depth = Math.Min(srcDepth, dstDepth); - int levels = Math.Min(srcLevels, dstLevels); - - Copy( - cbs, - srcImage, - dstImage, - srcInfo, - dstInfo, - srcLayer, - dstLayer, - srcLevel, - dstLevel, - depth, - levels); - } - - public static void Copy( - CommandBufferScoped cbs, - MTLTexture srcImage, - MTLTexture dstImage, - TextureCreateInfo srcInfo, - TextureCreateInfo dstInfo, - int srcDepthOrLayer, - int dstDepthOrLayer, - int srcLevel, - int dstLevel, - int depthOrLayers, - int levels) - { - MTLBlitCommandEncoder blitCommandEncoder = cbs.Encoders.EnsureBlitEncoder(); - - int srcZ; - int srcLayer; - int srcDepth; - int srcLayers; - - if (srcInfo.Target == Target.Texture3D) - { - srcZ = srcDepthOrLayer; - srcLayer = 0; - srcDepth = depthOrLayers; - srcLayers = 1; - } - else - { - srcZ = 0; - srcLayer = srcDepthOrLayer; - srcDepth = 1; - srcLayers = depthOrLayers; - } - - int dstZ; - int dstLayer; - int dstLayers; - - if (dstInfo.Target == Target.Texture3D) - { - dstZ = dstDepthOrLayer; - dstLayer = 0; - dstLayers = 1; - } - else - { - dstZ = 0; - dstLayer = dstDepthOrLayer; - dstLayers = depthOrLayers; - } - - int srcWidth = srcInfo.Width; - int srcHeight = srcInfo.Height; - - int dstWidth = dstInfo.Width; - int dstHeight = dstInfo.Height; - - srcWidth = Math.Max(1, srcWidth >> srcLevel); - srcHeight = Math.Max(1, srcHeight >> srcLevel); - - dstWidth = Math.Max(1, dstWidth >> dstLevel); - dstHeight = Math.Max(1, dstHeight >> dstLevel); - - int blockWidth = 1; - int blockHeight = 1; - bool sizeInBlocks = false; - - MTLBuffer tempBuffer = default; - - if (srcInfo.Format != dstInfo.Format && (srcInfo.IsCompressed || dstInfo.IsCompressed)) - { - // Compressed alias copies need to happen through a temporary buffer. - // The data is copied from the source to the buffer, then the buffer to the destination. - // The length of the buffer should be the maximum slice size for the destination. - - tempBuffer = blitCommandEncoder.Device.NewBuffer((ulong)dstInfo.GetMipSize2D(0), MTLResourceOptions.ResourceStorageModePrivate); - } - - // When copying from a compressed to a non-compressed format, - // the non-compressed texture will have the size of the texture - // in blocks (not in texels), so we must adjust that size to - // match the size in texels of the compressed texture. - if (!srcInfo.IsCompressed && dstInfo.IsCompressed) - { - srcWidth *= dstInfo.BlockWidth; - srcHeight *= dstInfo.BlockHeight; - blockWidth = dstInfo.BlockWidth; - blockHeight = dstInfo.BlockHeight; - - sizeInBlocks = true; - } - else if (srcInfo.IsCompressed && !dstInfo.IsCompressed) - { - dstWidth *= srcInfo.BlockWidth; - dstHeight *= srcInfo.BlockHeight; - blockWidth = srcInfo.BlockWidth; - blockHeight = srcInfo.BlockHeight; - } - - int width = Math.Min(srcWidth, dstWidth); - int height = Math.Min(srcHeight, dstHeight); - - for (int level = 0; level < levels; level++) - { - // Stop copy if we are already out of the levels range. - if (level >= srcInfo.Levels || dstLevel + level >= dstInfo.Levels) - { - break; - } - - int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width; - int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height; - - int layers = Math.Max(dstLayers - dstLayer, srcLayers); - - for (int layer = 0; layer < layers; layer++) - { - if (tempBuffer.NativePtr != 0) - { - // Copy through the temp buffer - CopyFromOrToBuffer(cbs, tempBuffer, srcImage, srcInfo, true, srcLayer + layer, srcLevel + level, 0, 0, copyWidth, copyHeight); - - int dstBufferWidth = sizeInBlocks ? copyWidth * blockWidth : BitUtils.DivRoundUp(copyWidth, blockWidth); - int dstBufferHeight = sizeInBlocks ? copyHeight * blockHeight : BitUtils.DivRoundUp(copyHeight, blockHeight); - - CopyFromOrToBuffer(cbs, tempBuffer, dstImage, dstInfo, false, dstLayer + layer, dstLevel + level, 0, 0, dstBufferWidth, dstBufferHeight); - } - else if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples) - { - // TODO - - Logger.Warning?.PrintMsg(LogClass.Gpu, "Unsupported mismatching sample count copy"); - } - else - { - blitCommandEncoder.CopyFromTexture( - srcImage, - (ulong)(srcLayer + layer), - (ulong)(srcLevel + level), - new MTLOrigin { z = (ulong)srcZ }, - new MTLSize { width = (ulong)copyWidth, height = (ulong)copyHeight, depth = (ulong)srcDepth }, - dstImage, - (ulong)(dstLayer + layer), - (ulong)(dstLevel + level), - new MTLOrigin { z = (ulong)dstZ }); - } - } - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (srcInfo.Target == Target.Texture3D) - { - srcDepth = Math.Max(1, srcDepth >> 1); - } - } - - if (tempBuffer.NativePtr != 0) - { - tempBuffer.Dispose(); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/VertexBufferState.cs b/src/Ryujinx.Graphics.Metal/VertexBufferState.cs deleted file mode 100644 index 8fb48ef79..000000000 --- a/src/Ryujinx.Graphics.Metal/VertexBufferState.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Ryujinx.Graphics.GAL; -using SharpMetal.Metal; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - readonly internal struct VertexBufferState - { - public static VertexBufferState Null => new(BufferHandle.Null, 0, 0, 0); - - private readonly BufferHandle _handle; - private readonly int _offset; - private readonly int _size; - - public readonly int Stride; - public readonly int Divisor; - - public VertexBufferState(BufferHandle handle, int offset, int size, int divisor, int stride = 0) - { - _handle = handle; - _offset = offset; - _size = size; - - Stride = stride; - Divisor = divisor; - } - - public (MTLBuffer, int) GetVertexBuffer(BufferManager bufferManager, CommandBufferScoped cbs) - { - Auto autoBuffer = null; - - if (_handle != BufferHandle.Null) - { - // TODO: Handle restride if necessary - - autoBuffer = bufferManager.GetBuffer(_handle, false, out int size); - - // The original stride must be reapplied in case it was rewritten. - // TODO: Handle restride if necessary - - if (_offset >= size) - { - autoBuffer = null; - } - } - - if (autoBuffer != null) - { - int offset = _offset; - MTLBuffer buffer = autoBuffer.Get(cbs, offset, _size).Value; - - return (buffer, offset); - } - - return (new MTLBuffer(IntPtr.Zero), 0); - } - } -} diff --git a/src/Ryujinx.Graphics.Metal/Window.cs b/src/Ryujinx.Graphics.Metal/Window.cs deleted file mode 100644 index 0b6c6c4d2..000000000 --- a/src/Ryujinx.Graphics.Metal/Window.cs +++ /dev/null @@ -1,234 +0,0 @@ -using Ryujinx.Common.Configuration; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Metal.Effects; -using SharpMetal.ObjectiveCCore; -using SharpMetal.QuartzCore; -using System; -using System.Runtime.Versioning; - -namespace Ryujinx.Graphics.Metal -{ - [SupportedOSPlatform("macos")] - class Window : IWindow, IDisposable - { - public bool ScreenCaptureRequested { get; set; } - - private readonly MetalRenderer _renderer; - private CAMetalLayer _metalLayer; - - private int _width; - private int _height; - - private int _requestedWidth; - private int _requestedHeight; - - private AntiAliasing _currentAntiAliasing; - private bool _updateEffect; - private IPostProcessingEffect _effect; - private IScalingFilter _scalingFilter; - private bool _isLinear; - - public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled; - - // private float _scalingFilterLevel; - private bool _updateScalingFilter; - private ScalingFilter _currentScalingFilter; - // private bool _colorSpacePassthroughEnabled; - - public Window(MetalRenderer renderer, CAMetalLayer metalLayer) - { - _renderer = renderer; - _metalLayer = metalLayer; - } - - private void ResizeIfNeeded() - { - if (_requestedWidth != 0 && _requestedHeight != 0) - { - // TODO: This is actually a CGSize, but there is no overload for that, so fill the first two fields of rect with the size. - NSRect rect = new(_requestedWidth, _requestedHeight, 0, 0); - - ObjectiveC.objc_msgSend(_metalLayer, "setDrawableSize:", rect); - - _requestedWidth = 0; - _requestedHeight = 0; - } - } - - public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) - { - if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex) - { - ResizeIfNeeded(); - - CAMetalDrawable drawable = new(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable")); - - _width = (int)drawable.Texture.Width; - _height = (int)drawable.Texture.Height; - - UpdateEffect(); - - if (_effect != null) - { - // TODO: Run Effects - // view = _effect.Run() - } - - int srcX0, srcX1, srcY0, srcY1; - - if (crop.Left == 0 && crop.Right == 0) - { - srcX0 = 0; - srcX1 = tex.Width; - } - else - { - srcX0 = crop.Left; - srcX1 = crop.Right; - } - - if (crop.Top == 0 && crop.Bottom == 0) - { - srcY0 = 0; - srcY1 = tex.Height; - } - else - { - srcY0 = crop.Top; - srcY1 = crop.Bottom; - } - - if (ScreenCaptureRequested) - { - // TODO: Support screen captures - - ScreenCaptureRequested = false; - } - - float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); - float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); - - int dstWidth = (int)(_width * ratioX); - int dstHeight = (int)(_height * ratioY); - - int dstPaddingX = (_width - dstWidth) / 2; - int dstPaddingY = (_height - dstHeight) / 2; - - int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; - int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX; - - int dstY0 = crop.FlipY ? _height - dstPaddingY : dstPaddingY; - int dstY1 = crop.FlipY ? dstPaddingY : _height - dstPaddingY; - - if (_scalingFilter != null) - { - // TODO: Run scaling filter - } - - pipeline.Present( - drawable, - tex, - new Extents2D(srcX0, srcY0, srcX1, srcY1), - new Extents2D(dstX0, dstY0, dstX1, dstY1), - _isLinear); - } - } - - public void SetSize(int width, int height) - { - _requestedWidth = width; - _requestedHeight = height; - } - - public void ChangeVSyncMode(VSyncMode vSyncMode) - { - _metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch; - } - - public void SetAntiAliasing(AntiAliasing effect) - { - if (_currentAntiAliasing == effect && _effect != null) - { - return; - } - - _currentAntiAliasing = effect; - - _updateEffect = true; - } - - public void SetScalingFilter(ScalingFilter type) - { - if (_currentScalingFilter == type && _effect != null) - { - return; - } - - _currentScalingFilter = type; - - _updateScalingFilter = true; - } - - public void SetScalingFilterLevel(float level) - { - // _scalingFilterLevel = level; - _updateScalingFilter = true; - } - - public void SetColorSpacePassthrough(bool colorSpacePassThroughEnabled) - { - // _colorSpacePassthroughEnabled = colorSpacePassThroughEnabled; - } - - private void UpdateEffect() - { - if (_updateEffect) - { - _updateEffect = false; - - switch (_currentAntiAliasing) - { - case AntiAliasing.Fxaa: - _effect?.Dispose(); - Logger.Warning?.PrintMsg(LogClass.Gpu, "FXAA not implemented for Metal backend!"); - break; - case AntiAliasing.None: - _effect?.Dispose(); - _effect = null; - break; - case AntiAliasing.SmaaLow: - case AntiAliasing.SmaaMedium: - case AntiAliasing.SmaaHigh: - case AntiAliasing.SmaaUltra: - // var quality = _currentAntiAliasing - AntiAliasing.SmaaLow; - Logger.Warning?.PrintMsg(LogClass.Gpu, "SMAA not implemented for Metal backend!"); - break; - } - } - - if (_updateScalingFilter) - { - _updateScalingFilter = false; - - switch (_currentScalingFilter) - { - case ScalingFilter.Bilinear: - case ScalingFilter.Nearest: - _scalingFilter?.Dispose(); - _scalingFilter = null; - _isLinear = _currentScalingFilter == ScalingFilter.Bilinear; - break; - case ScalingFilter.Fsr: - Logger.Warning?.PrintMsg(LogClass.Gpu, "FSR not implemented for Metal backend!"); - break; - } - } - } - - public void Dispose() - { - _metalLayer.Dispose(); - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs deleted file mode 100644 index 2fa188ea9..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System.Text; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - class CodeGenContext - { - public const string Tab = " "; - - // The number of additional arguments that every function (except for the main one) must have (for instance support_buffer) - public const int AdditionalArgCount = 2; - - public StructuredFunction CurrentFunction { get; set; } - - public StructuredProgramInfo Info { get; } - - public AttributeUsage AttributeUsage { get; } - public ShaderDefinitions Definitions { get; } - public ShaderProperties Properties { get; } - public HostCapabilities HostCapabilities { get; } - public ILogger Logger { get; } - public TargetApi TargetApi { get; } - - public OperandManager OperandManager { get; } - - private readonly StringBuilder _sb; - - private int _level; - - private string _indentation; - - public CodeGenContext(StructuredProgramInfo info, CodeGenParameters parameters) - { - Info = info; - AttributeUsage = parameters.AttributeUsage; - Definitions = parameters.Definitions; - Properties = parameters.Properties; - HostCapabilities = parameters.HostCapabilities; - Logger = parameters.Logger; - TargetApi = parameters.TargetApi; - - OperandManager = new OperandManager(); - - _sb = new StringBuilder(); - } - - public void AppendLine() - { - _sb.AppendLine(); - } - - public void AppendLine(string str) - { - _sb.AppendLine(_indentation + str); - } - - public string GetCode() - { - return _sb.ToString(); - } - - public void EnterScope(string prefix = "") - { - AppendLine(prefix + "{"); - - _level++; - - UpdateIndentation(); - } - - public void LeaveScope(string suffix = "") - { - if (_level == 0) - { - return; - } - - _level--; - - UpdateIndentation(); - - AppendLine("}" + suffix); - } - - public StructuredFunction GetFunction(int id) - { - return Info.Functions[id]; - } - - private void UpdateIndentation() - { - _indentation = GetIndentation(_level); - } - - private static string GetIndentation(int level) - { - string indentation = string.Empty; - - for (int index = 0; index < level; index++) - { - indentation += Tab; - } - - return indentation; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs deleted file mode 100644 index a9464834a..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs +++ /dev/null @@ -1,577 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class Declarations - { - /* - * Description of MSL Binding Model - * - * There are a few fundamental differences between how GLSL and MSL handle I/O. - * This comment will set out to describe the reasons why things are done certain ways - * and to describe the overall binding model that we're striving for here. - * - * Main I/O Structs - * - * Each stage has a main input and output struct (if applicable) labeled as [Stage][In/Out], i.e VertexIn. - * Every field within these structs is labeled with an [[attribute(n)]] property, - * and the overall struct is labeled with [[stage_in]] for input structs, and defined as the - * output type of the main shader function for the output struct. This struct also contains special - * attribute-based properties like [[position]] that would be "built-ins" in a GLSL context. - * - * These structs are passed as inputs to all inline functions due to containing "built-ins" - * that inline functions assume access to. - * - * Vertex & Zero Buffers - * - * Binding indices 0-16 are reserved for vertex buffers, and binding 18 is reserved for the zero buffer. - * - * Uniforms & Storage Buffers - * - * Uniforms and storage buffers are tightly packed into their respective argument buffers - * (effectively ignoring binding indices at shader level), with each pointer to the corresponding - * struct that defines the layout and fields of these buffers (usually just a single data array), laid - * out one after the other in ascending order of their binding index. - * - * The uniforms argument buffer is always bound at a fixed index of 20. - * The storage buffers argument buffer is always bound at a fixed index of 21. - * - * These structs are passed as inputs to all inline functions as in GLSL or SPIRV, - * uniforms and storage buffers would be globals, and inline functions assume access to these buffers. - * - * Samplers & Textures - * - * Metal does not have a combined image sampler like sampler2D in GLSL, as a result we need to bind - * an individual texture and a sampler object for each instance of a combined image sampler. - * Samplers and textures are bound in a shared argument buffer. This argument buffer is tightly packed - * (effectively ignoring binding indices at shader level), with texture and their samplers (if present) - * laid out one after the other in ascending order of their binding index. - * - * The samplers and textures argument buffer is always bound at a fixed index of 22. - * - */ - - public static int[] Declare(CodeGenContext context, StructuredProgramInfo info) - { - // TODO: Re-enable this warning - context.AppendLine("#pragma clang diagnostic ignored \"-Wunused-variable\""); - context.AppendLine(); - context.AppendLine("#include "); - context.AppendLine("#include "); - context.AppendLine(); - context.AppendLine("using namespace metal;"); - context.AppendLine(); - - bool fsi = (info.HelperFunctionsMask & HelperFunctionsMask.FSI) != 0; - - DeclareInputAttributes(context, info.IoDefinitions.Where(x => IsUserDefined(x, StorageKind.Input))); - context.AppendLine(); - DeclareOutputAttributes(context, info.IoDefinitions.Where(x => x.StorageKind == StorageKind.Output)); - context.AppendLine(); - DeclareBufferStructures(context, context.Properties.ConstantBuffers.Values.OrderBy(x => x.Binding).ToArray(), true, fsi); - DeclareBufferStructures(context, context.Properties.StorageBuffers.Values.OrderBy(x => x.Binding).ToArray(), false, fsi); - - // We need to declare each set as a new struct - Dictionary textureDefinitions = context.Properties.Textures.Values - .GroupBy(x => x.Set) - .ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray()); - - Dictionary imageDefinitions = context.Properties.Images.Values - .GroupBy(x => x.Set) - .ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray()); - - int[] textureSets = textureDefinitions.Keys.ToArray(); - int[] imageSets = imageDefinitions.Keys.ToArray(); - - int[] sets = textureSets.Union(imageSets).ToArray(); - - foreach (KeyValuePair set in textureDefinitions) - { - DeclareTextures(context, set.Value, set.Key); - } - - foreach (KeyValuePair set in imageDefinitions) - { - DeclareImages(context, set.Value, set.Key, fsi); - } - - if ((info.HelperFunctionsMask & HelperFunctionsMask.FindLSB) != 0) - { - AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindLSB.metal"); - } - - if ((info.HelperFunctionsMask & HelperFunctionsMask.FindMSBS32) != 0) - { - AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBS32.metal"); - } - - if ((info.HelperFunctionsMask & HelperFunctionsMask.FindMSBU32) != 0) - { - AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal"); - } - - if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0) - { - AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal"); - } - - if ((info.HelperFunctionsMask & HelperFunctionsMask.Precise) != 0) - { - AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal"); - } - - return sets; - } - - static bool IsUserDefined(IoDefinition ioDefinition, StorageKind storageKind) - { - return ioDefinition.StorageKind == storageKind && ioDefinition.IoVariable == IoVariable.UserDefined; - } - - public static void DeclareLocals(CodeGenContext context, StructuredFunction function, ShaderStage stage, bool isMainFunc = false) - { - if (isMainFunc) - { - // TODO: Support OaIndexing - if (context.Definitions.IaIndexing) - { - context.EnterScope($"array {Defaults.IAttributePrefix} = "); - - for (int i = 0; i < Constants.MaxAttributes; i++) - { - context.AppendLine($"in.{Defaults.IAttributePrefix}{i},"); - } - - context.LeaveScope(";"); - } - - DeclareMemories(context, context.Properties.LocalMemories.Values, isShared: false); - DeclareMemories(context, context.Properties.SharedMemories.Values, isShared: true); - - switch (stage) - { - case ShaderStage.Vertex: - context.AppendLine("VertexOut out = {};"); - // TODO: Only add if necessary - context.AppendLine("uint instance_index = instance_id + base_instance;"); - break; - case ShaderStage.Fragment: - context.AppendLine("FragmentOut out = {};"); - break; - } - - // TODO: Only add if necessary - if (stage != ShaderStage.Compute) - { - // MSL does not give us access to [[thread_index_in_simdgroup]] - // outside compute. But we may still need to provide this value in frag/vert. - context.AppendLine("uint thread_index_in_simdgroup = simd_prefix_exclusive_sum(1);"); - } - } - - foreach (AstOperand decl in function.Locals) - { - string name = context.OperandManager.DeclareLocal(decl); - - context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";"); - } - } - - public static string GetVarTypeName(AggregateType type, bool atomic = false) - { - string s32 = atomic ? "atomic_int" : "int"; - string u32 = atomic ? "atomic_uint" : "uint"; - - return type switch - { - AggregateType.Void => "void", - AggregateType.Bool => "bool", - AggregateType.FP32 => "float", - AggregateType.S32 => s32, - AggregateType.U32 => u32, - AggregateType.Vector2 | AggregateType.Bool => "bool2", - AggregateType.Vector2 | AggregateType.FP32 => "float2", - AggregateType.Vector2 | AggregateType.S32 => "int2", - AggregateType.Vector2 | AggregateType.U32 => "uint2", - AggregateType.Vector3 | AggregateType.Bool => "bool3", - AggregateType.Vector3 | AggregateType.FP32 => "float3", - AggregateType.Vector3 | AggregateType.S32 => "int3", - AggregateType.Vector3 | AggregateType.U32 => "uint3", - AggregateType.Vector4 | AggregateType.Bool => "bool4", - AggregateType.Vector4 | AggregateType.FP32 => "float4", - AggregateType.Vector4 | AggregateType.S32 => "int4", - AggregateType.Vector4 | AggregateType.U32 => "uint4", - _ => throw new ArgumentException($"Invalid variable type \"{type}\"."), - }; - } - - private static void DeclareMemories(CodeGenContext context, IEnumerable memories, bool isShared) - { - string prefix = isShared ? "threadgroup " : string.Empty; - - foreach (MemoryDefinition memory in memories) - { - string arraySize = string.Empty; - if ((memory.Type & AggregateType.Array) != 0) - { - arraySize = $"[{memory.ArrayLength}]"; - } - string typeName = GetVarTypeName(memory.Type & ~AggregateType.Array); - context.AppendLine($"{prefix}{typeName} {memory.Name}{arraySize};"); - } - } - - private static void DeclareBufferStructures(CodeGenContext context, BufferDefinition[] buffers, bool constant, bool fsi) - { - string name = constant ? "ConstantBuffers" : "StorageBuffers"; - string addressSpace = constant ? "constant" : "device"; - - string[] bufferDec = new string[buffers.Length]; - - for (int i = 0; i < buffers.Length; i++) - { - BufferDefinition buffer = buffers[i]; - - bool needsPadding = buffer.Layout == BufferLayout.Std140; - string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : string.Empty; - - bufferDec[i] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name}{fsiSuffix};"; - - context.AppendLine($"struct {Defaults.StructPrefix}_{buffer.Name}"); - context.EnterScope(); - - foreach (StructureField field in buffer.Type.Fields) - { - AggregateType type = field.Type; - type |= (needsPadding && (field.Type & AggregateType.Array) != 0) - ? AggregateType.Vector4 - : AggregateType.Invalid; - - type &= ~AggregateType.Array; - - string typeName = GetVarTypeName(type); - string arraySuffix = string.Empty; - - if (field.Type.HasFlag(AggregateType.Array)) - { - if (field.ArrayLength > 0) - { - arraySuffix = $"[{field.ArrayLength}]"; - } - else - { - // Probably UB, but this is the approach that MVK takes - arraySuffix = "[1]"; - } - } - - context.AppendLine($"{typeName} {field.Name}{arraySuffix};"); - } - - context.LeaveScope(";"); - context.AppendLine(); - } - - context.AppendLine($"struct {name}"); - context.EnterScope(); - - foreach (string declaration in bufferDec) - { - context.AppendLine(declaration); - } - - context.LeaveScope(";"); - context.AppendLine(); - } - - private static void DeclareTextures(CodeGenContext context, TextureDefinition[] textures, int set) - { - string setName = GetNameForSet(set); - context.AppendLine($"struct {setName}"); - context.EnterScope(); - - List textureDec = []; - - foreach (TextureDefinition texture in textures) - { - if (texture.Type != SamplerType.None) - { - string textureTypeName = texture.Type.ToMslTextureType(texture.Format.GetComponentType()); - - if (texture.ArrayLength > 1) - { - textureTypeName = $"array<{textureTypeName}, {texture.ArrayLength}>"; - } - - textureDec.Add($"{textureTypeName} tex_{texture.Name};"); - } - - if (!texture.Separate && texture.Type != SamplerType.TextureBuffer) - { - string samplerType = "sampler"; - - if (texture.ArrayLength > 1) - { - samplerType = $"array<{samplerType}, {texture.ArrayLength}>"; - } - - textureDec.Add($"{samplerType} samp_{texture.Name};"); - } - } - - foreach (string declaration in textureDec) - { - context.AppendLine(declaration); - } - - context.LeaveScope(";"); - context.AppendLine(); - } - - private static void DeclareImages(CodeGenContext context, TextureDefinition[] images, int set, bool fsi) - { - string setName = GetNameForSet(set); - context.AppendLine($"struct {setName}"); - context.EnterScope(); - - string[] imageDec = new string[images.Length]; - - for (int i = 0; i < images.Length; i++) - { - TextureDefinition image = images[i]; - - string imageTypeName = image.Type.ToMslTextureType(image.Format.GetComponentType(), true); - if (image.ArrayLength > 1) - { - imageTypeName = $"array<{imageTypeName}, {image.ArrayLength}>"; - } - - string fsiSuffix = fsi ? " [[raster_order_group(0)]]" : string.Empty; - - imageDec[i] = $"{imageTypeName} {image.Name}{fsiSuffix};"; - } - - foreach (string declaration in imageDec) - { - context.AppendLine(declaration); - } - - context.LeaveScope(";"); - context.AppendLine(); - } - - private static void DeclareInputAttributes(CodeGenContext context, IEnumerable inputs) - { - if (context.Definitions.Stage == ShaderStage.Compute) - { - return; - } - - switch (context.Definitions.Stage) - { - case ShaderStage.Vertex: - context.AppendLine("struct VertexIn"); - break; - case ShaderStage.Fragment: - context.AppendLine("struct FragmentIn"); - break; - } - - context.EnterScope(); - - if (context.Definitions.Stage == ShaderStage.Fragment) - { - // TODO: check if it's needed - context.AppendLine("float4 position [[position, invariant]];"); - context.AppendLine("bool front_facing [[front_facing]];"); - context.AppendLine("float2 point_coord [[point_coord]];"); - context.AppendLine("uint primitive_id [[primitive_id]];"); - } - - if (context.Definitions.IaIndexing) - { - // MSL does not support arrays in stage I/O - // We need to use the SPIRV-Cross workaround - for (int i = 0; i < Constants.MaxAttributes; i++) - { - string suffix = context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{i})]]" : $"[[attribute({i})]]"; - context.AppendLine($"float4 {Defaults.IAttributePrefix}{i} {suffix};"); - } - } - - if (inputs.Any()) - { - foreach (IoDefinition ioDefinition in inputs.OrderBy(x => x.Location)) - { - if (context.Definitions.IaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined) - { - continue; - } - - string iq = string.Empty; - - if (context.Definitions.Stage == ShaderStage.Fragment) - { - iq = context.Definitions.ImapTypes[ioDefinition.Location].GetFirstUsedType() switch - { - PixelImap.Constant => "[[flat]] ", - PixelImap.ScreenLinear => "[[center_no_perspective]] ", - _ => string.Empty, - }; - } - - string type = ioDefinition.IoVariable switch - { - // IoVariable.Position => "float4", - IoVariable.GlobalId => "uint3", - IoVariable.VertexId => "uint", - IoVariable.VertexIndex => "uint", - // IoVariable.PointCoord => "float2", - _ => GetVarTypeName(context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: false)) - }; - string name = ioDefinition.IoVariable switch - { - // IoVariable.Position => "position", - IoVariable.GlobalId => "global_id", - IoVariable.VertexId => "vertex_id", - IoVariable.VertexIndex => "vertex_index", - // IoVariable.PointCoord => "point_coord", - _ => $"{Defaults.IAttributePrefix}{ioDefinition.Location}" - }; - string suffix = ioDefinition.IoVariable switch - { - // IoVariable.Position => "[[position, invariant]]", - IoVariable.GlobalId => "[[thread_position_in_grid]]", - IoVariable.VertexId => "[[vertex_id]]", - // TODO: Avoid potential redeclaration - IoVariable.VertexIndex => "[[vertex_id]]", - // IoVariable.PointCoord => "[[point_coord]]", - IoVariable.UserDefined => context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{ioDefinition.Location})]]" : $"[[attribute({ioDefinition.Location})]]", - _ => string.Empty - }; - - context.AppendLine($"{type} {name} {iq}{suffix};"); - } - } - - context.LeaveScope(";"); - } - - private static void DeclareOutputAttributes(CodeGenContext context, IEnumerable outputs) - { - switch (context.Definitions.Stage) - { - case ShaderStage.Vertex: - context.AppendLine("struct VertexOut"); - break; - case ShaderStage.Fragment: - context.AppendLine("struct FragmentOut"); - break; - case ShaderStage.Compute: - context.AppendLine("struct KernelOut"); - break; - } - - context.EnterScope(); - - if (context.Definitions.OaIndexing) - { - // MSL does not support arrays in stage I/O - // We need to use the SPIRV-Cross workaround - for (int i = 0; i < Constants.MaxAttributes; i++) - { - context.AppendLine($"float4 {Defaults.OAttributePrefix}{i} [[user(loc{i})]];"); - } - } - - if (outputs.Any()) - { - outputs = outputs.OrderBy(x => x.Location); - - if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend) - { - IoDefinition firstOutput = outputs.ElementAtOrDefault(0); - IoDefinition secondOutput = outputs.ElementAtOrDefault(1); - - string type1 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(firstOutput.Location)); - string type2 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(secondOutput.Location)); - - string name1 = $"color{firstOutput.Location}"; - string name2 = $"color{firstOutput.Location + 1}"; - - context.AppendLine($"{type1} {name1} [[color({firstOutput.Location}), index(0)]];"); - context.AppendLine($"{type2} {name2} [[color({firstOutput.Location}), index(1)]];"); - - outputs = outputs.Skip(2); - } - - foreach (IoDefinition ioDefinition in outputs) - { - if (context.Definitions.OaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined) - { - continue; - } - - string type = ioDefinition.IoVariable switch - { - IoVariable.Position => "float4", - IoVariable.PointSize => "float", - IoVariable.FragmentOutputColor => GetVarTypeName(context.Definitions.GetFragmentOutputColorType(ioDefinition.Location)), - IoVariable.FragmentOutputDepth => "float", - IoVariable.ClipDistance => "float", - _ => GetVarTypeName(context.Definitions.GetUserDefinedType(ioDefinition.Location, isOutput: true)) - }; - string name = ioDefinition.IoVariable switch - { - IoVariable.Position => "position", - IoVariable.PointSize => "point_size", - IoVariable.FragmentOutputColor => $"color{ioDefinition.Location}", - IoVariable.FragmentOutputDepth => "depth", - IoVariable.ClipDistance => "clip_distance", - _ => $"{Defaults.OAttributePrefix}{ioDefinition.Location}" - }; - string suffix = ioDefinition.IoVariable switch - { - IoVariable.Position => "[[position, invariant]]", - IoVariable.PointSize => "[[point_size]]", - IoVariable.UserDefined => $"[[user(loc{ioDefinition.Location})]]", - IoVariable.FragmentOutputColor => $"[[color({ioDefinition.Location})]]", - IoVariable.FragmentOutputDepth => "[[depth(any)]]", - IoVariable.ClipDistance => $"[[clip_distance]][{Defaults.TotalClipDistances}]", - _ => string.Empty - }; - - context.AppendLine($"{type} {name} {suffix};"); - } - } - - context.LeaveScope(";"); - } - - private static void AppendHelperFunction(CodeGenContext context, string filename) - { - string code = EmbeddedResources.ReadAllText(filename); - - code = code.Replace("\t", CodeGenContext.Tab); - - context.AppendLine(code); - context.AppendLine(); - } - - public static string GetNameForSet(int set, bool forVar = false) - { - return (uint)set switch - { - Defaults.TexturesSetIndex => forVar ? "textures" : "Textures", - Defaults.ImagesSetIndex => forVar ? "images" : "Images", - _ => $"{(forVar ? "set" : "Set")}{set}" - }; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Defaults.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Defaults.cs deleted file mode 100644 index 511a2f606..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Defaults.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class Defaults - { - public const string LocalNamePrefix = "temp"; - - public const string PerPatchAttributePrefix = "patchAttr"; - public const string IAttributePrefix = "inAttr"; - public const string OAttributePrefix = "outAttr"; - - public const string StructPrefix = "struct"; - - public const string ArgumentNamePrefix = "a"; - - public const string UndefinedName = "0"; - - public const int MaxVertexBuffers = 16; - - public const uint ZeroBufferIndex = MaxVertexBuffers; - public const uint BaseSetIndex = MaxVertexBuffers + 1; - - public const uint ConstantBuffersIndex = BaseSetIndex; - public const uint StorageBuffersIndex = BaseSetIndex + 1; - public const uint TexturesIndex = BaseSetIndex + 2; - public const uint ImagesIndex = BaseSetIndex + 3; - - public const uint ConstantBuffersSetIndex = 0; - public const uint StorageBuffersSetIndex = 1; - public const uint TexturesSetIndex = 2; - public const uint ImagesSetIndex = 3; - - public const int TotalClipDistances = 8; - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindLSB.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindLSB.metal deleted file mode 100644 index ad786adb3..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindLSB.metal +++ /dev/null @@ -1,5 +0,0 @@ -template -inline T findLSB(T x) -{ - return select(ctz(x), T(-1), x == T(0)); -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBS32.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBS32.metal deleted file mode 100644 index af4eb6cbd..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBS32.metal +++ /dev/null @@ -1,5 +0,0 @@ -template -inline T findMSBS32(T x) -{ - return select(clz(T(0)) - (clz(x) + T(1)), T(-1), x == T(0)); -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal deleted file mode 100644 index 6d97c41a9..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal +++ /dev/null @@ -1,6 +0,0 @@ -template -inline T findMSBU32(T x) -{ - T v = select(x, T(-1) - x, x < T(0)); - return select(clz(T(0)) - (clz(v) + T(1)), T(-1), v == T(0)); -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs deleted file mode 100644 index 370159a0e..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class HelperFunctionNames - { - public static string FindLSB = "findLSB"; - public static string FindMSBS32 = "findMSBS32"; - public static string FindMSBU32 = "findMSBU32"; - public static string SwizzleAdd = "swizzleAdd"; - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal deleted file mode 100644 index 366bea1ac..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal +++ /dev/null @@ -1,14 +0,0 @@ -template -[[clang::optnone]] T PreciseFAdd(T l, T r) { - return fma(T(1), l, r); -} - -template -[[clang::optnone]] T PreciseFSub(T l, T r) { - return fma(T(-1), r, l); -} - -template -[[clang::optnone]] T PreciseFMul(T l, T r) { - return fma(l, r, T(0)); -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal deleted file mode 100644 index 22a079b01..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal +++ /dev/null @@ -1,7 +0,0 @@ -float swizzleAdd(float x, float y, int mask, uint thread_index_in_simdgroup) -{ - float4 xLut = float4(1.0, -1.0, 1.0, 0.0); - float4 yLut = float4(1.0, 1.0, -1.0, 1.0); - int lutIdx = (mask >> (int(thread_index_in_simdgroup & 3u) * 2)) & 3; - return x * xLut[lutIdx] + y * yLut[lutIdx]; -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs deleted file mode 100644 index 0be6035b6..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs +++ /dev/null @@ -1,186 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Text; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenBallot; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenBarrier; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenCall; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenMemory; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenVector; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGen - { - public static string GetExpression(CodeGenContext context, IAstNode node) - { - if (node is AstOperation operation) - { - return GetExpression(context, operation); - } - else if (node is AstOperand operand) - { - return context.OperandManager.GetExpression(context, operand); - } - - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - - private static string GetExpression(CodeGenContext context, AstOperation operation) - { - Instruction inst = operation.Inst; - - InstInfo info = GetInstructionInfo(inst); - - if ((info.Type & InstType.Call) != 0) - { - bool atomic = (info.Type & InstType.Atomic) != 0; - - int arity = (int)(info.Type & InstType.ArityMask); - - StringBuilder builder = new(); - - if (atomic && (operation.StorageKind == StorageKind.StorageBuffer || operation.StorageKind == StorageKind.SharedMemory)) - { - AggregateType dstType = operation.Inst == Instruction.AtomicMaxS32 || operation.Inst == Instruction.AtomicMinS32 - ? AggregateType.S32 - : AggregateType.U32; - - bool shared = operation.StorageKind == StorageKind.SharedMemory; - - builder.Append($"({(shared ? "threadgroup" : "device")} {Declarations.GetVarTypeName(dstType, true)}*)&{GenerateLoadOrStore(context, operation, isStore: false)}"); - - for (int argIndex = operation.SourcesCount - arity + 2; argIndex < operation.SourcesCount; argIndex++) - { - builder.Append($", {GetSourceExpr(context, operation.GetSource(argIndex), dstType)}, memory_order_relaxed"); - } - } - else - { - for (int argIndex = 0; argIndex < arity; argIndex++) - { - if (argIndex != 0) - { - builder.Append(", "); - } - - AggregateType dstType = GetSrcVarType(inst, argIndex); - - builder.Append(GetSourceExpr(context, operation.GetSource(argIndex), dstType)); - } - - if ((operation.Inst & Instruction.Mask) == Instruction.SwizzleAdd) - { - // SwizzleAdd takes one last argument, the thread_index_in_simdgroup - builder.Append(", thread_index_in_simdgroup"); - } - } - - return $"{info.OpName}({builder})"; - } - else if ((info.Type & InstType.Op) != 0) - { - string op = info.OpName; - - if (inst == Instruction.Return && operation.SourcesCount != 0) - { - return $"{op} {GetSourceExpr(context, operation.GetSource(0), context.CurrentFunction.ReturnType)}"; - } - if (inst == Instruction.Return && context.Definitions.Stage is ShaderStage.Vertex or ShaderStage.Fragment) - { - return $"{op} out"; - } - - int arity = (int)(info.Type & InstType.ArityMask); - - string[] expr = new string[arity]; - - for (int index = 0; index < arity; index++) - { - IAstNode src = operation.GetSource(index); - - string srcExpr = GetSourceExpr(context, src, GetSrcVarType(inst, index)); - - bool isLhs = arity == 2 && index == 0; - - expr[index] = Enclose(srcExpr, src, inst, info, isLhs); - } - - switch (arity) - { - case 0: - return op; - - case 1: - return op + expr[0]; - - case 2: - if (operation.ForcePrecise) - { - string func = (inst & Instruction.Mask) switch - { - Instruction.Add => "PreciseFAdd", - Instruction.Subtract => "PreciseFSub", - Instruction.Multiply => "PreciseFMul", - _ => throw new NotImplementedException() - }; - - return $"{func}({expr[0]}, {expr[1]})"; - } - - return $"{expr[0]} {op} {expr[1]}"; - - case 3: - return $"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}"; - } - } - else if ((info.Type & InstType.Special) != 0) - { - switch (inst & Instruction.Mask) - { - case Instruction.Ballot: - return Ballot(context, operation); - case Instruction.Call: - return Call(context, operation); - case Instruction.FSIBegin: - case Instruction.FSIEnd: - return "// FSI implemented with raster order groups in MSL"; - case Instruction.GroupMemoryBarrier: - case Instruction.MemoryBarrier: - case Instruction.Barrier: - return Barrier(context, operation); - case Instruction.ImageLoad: - case Instruction.ImageStore: - case Instruction.ImageAtomic: - return ImageLoadOrStore(context, operation); - case Instruction.Load: - return Load(context, operation); - case Instruction.Lod: - return Lod(context, operation); - case Instruction.Store: - return Store(context, operation); - case Instruction.TextureSample: - return TextureSample(context, operation); - case Instruction.TextureQuerySamples: - return TextureQuerySamples(context, operation); - case Instruction.TextureQuerySize: - return TextureQuerySize(context, operation); - case Instruction.PackHalf2x16: - return PackHalf2x16(context, operation); - case Instruction.UnpackHalf2x16: - return UnpackHalf2x16(context, operation); - case Instruction.VectorExtract: - return VectorExtract(context, operation); - case Instruction.VoteAllEqual: - return VoteAllEqual(context, operation); - } - } - - // TODO: Return this to being an error - return $"Unexpected instruction type \"{info.Type}\"."; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBallot.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBallot.cs deleted file mode 100644 index 19a065d77..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBallot.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenBallot - { - public static string Ballot(CodeGenContext context, AstOperation operation) - { - AggregateType dstType = GetSrcVarType(operation.Inst, 0); - - string arg = GetSourceExpr(context, operation.GetSource(0), dstType); - char component = "xyzw"[operation.Index]; - - return $"uint4(as_type((simd_vote::vote_t)simd_ballot({arg})), 0, 0).{component}"; - } - - public static string VoteAllEqual(CodeGenContext context, AstOperation operation) - { - AggregateType dstType = GetSrcVarType(operation.Inst, 0); - - string arg = GetSourceExpr(context, operation.GetSource(0), dstType); - - return $"simd_all({arg}) || !simd_any({arg})"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBarrier.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBarrier.cs deleted file mode 100644 index 198b701d6..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenBarrier.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenBarrier - { - public static string Barrier(CodeGenContext context, AstOperation operation) - { - bool device = (operation.Inst & Instruction.Mask) == Instruction.MemoryBarrier; - - return $"threadgroup_barrier(mem_flags::mem_{(device ? "device" : "threadgroup")})"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenCall.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenCall.cs deleted file mode 100644 index 98a8a140e..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenCall.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenCall - { - public static string Call(CodeGenContext context, AstOperation operation) - { - AstOperand funcId = (AstOperand)operation.GetSource(0); - - StructuredFunction function = context.GetFunction(funcId.Value); - - int argCount = operation.SourcesCount - 1; - int additionalArgCount = CodeGenContext.AdditionalArgCount + (context.Definitions.Stage != ShaderStage.Compute ? 1 : 0); - bool needsThreadIndex = false; - - // TODO: Replace this with a proper flag - if (function.Name.Contains("Shuffle")) - { - needsThreadIndex = true; - additionalArgCount++; - } - - string[] args = new string[argCount + additionalArgCount]; - - // Additional arguments - if (context.Definitions.Stage != ShaderStage.Compute) - { - args[0] = "in"; - args[1] = "constant_buffers"; - args[2] = "storage_buffers"; - - if (needsThreadIndex) - { - args[3] = "thread_index_in_simdgroup"; - } - } - else - { - args[0] = "constant_buffers"; - args[1] = "storage_buffers"; - - if (needsThreadIndex) - { - args[2] = "thread_index_in_simdgroup"; - } - } - - int argIndex = additionalArgCount; - for (int i = 0; i < argCount; i++) - { - args[argIndex++] = GetSourceExpr(context, operation.GetSource(i + 1), function.GetArgumentType(i)); - } - - return $"{function.Name}({string.Join(", ", args)})"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs deleted file mode 100644 index 49f3c63aa..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs +++ /dev/null @@ -1,222 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.CodeGen.Msl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenHelper - { - private static readonly InstInfo[] _infoTable; - - static InstGenHelper() - { - _infoTable = new InstInfo[(int)Instruction.Count]; - -#pragma warning disable IDE0055 // Disable formatting - Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomic_fetch_add_explicit"); - Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomic_fetch_and_explicit"); - Add(Instruction.AtomicCompareAndSwap, InstType.AtomicBinary, "atomic_compare_exchange_weak_explicit"); - Add(Instruction.AtomicMaxU32, InstType.AtomicBinary, "atomic_fetch_max_explicit"); - Add(Instruction.AtomicMinU32, InstType.AtomicBinary, "atomic_fetch_min_explicit"); - Add(Instruction.AtomicOr, InstType.AtomicBinary, "atomic_fetch_or_explicit"); - Add(Instruction.AtomicSwap, InstType.AtomicBinary, "atomic_exchange_explicit"); - Add(Instruction.AtomicXor, InstType.AtomicBinary, "atomic_fetch_xor_explicit"); - Add(Instruction.Absolute, InstType.CallUnary, "abs"); - Add(Instruction.Add, InstType.OpBinaryCom, "+", 2); - Add(Instruction.Ballot, InstType.Special); - Add(Instruction.Barrier, InstType.Special); - Add(Instruction.BitCount, InstType.CallUnary, "popcount"); - Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "extract_bits"); - Add(Instruction.BitfieldExtractU32, InstType.CallTernary, "extract_bits"); - Add(Instruction.BitfieldInsert, InstType.CallQuaternary, "insert_bits"); - Add(Instruction.BitfieldReverse, InstType.CallUnary, "reverse_bits"); - Add(Instruction.BitwiseAnd, InstType.OpBinaryCom, "&", 6); - Add(Instruction.BitwiseExclusiveOr, InstType.OpBinaryCom, "^", 7); - Add(Instruction.BitwiseNot, InstType.OpUnary, "~", 0); - Add(Instruction.BitwiseOr, InstType.OpBinaryCom, "|", 8); - Add(Instruction.Call, InstType.Special); - Add(Instruction.Ceiling, InstType.CallUnary, "ceil"); - Add(Instruction.Clamp, InstType.CallTernary, "clamp"); - Add(Instruction.ClampU32, InstType.CallTernary, "clamp"); - Add(Instruction.CompareEqual, InstType.OpBinaryCom, "==", 5); - Add(Instruction.CompareGreater, InstType.OpBinary, ">", 4); - Add(Instruction.CompareGreaterOrEqual, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterOrEqualU32, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterU32, InstType.OpBinary, ">", 4); - Add(Instruction.CompareLess, InstType.OpBinary, "<", 4); - Add(Instruction.CompareLessOrEqual, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessOrEqualU32, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessU32, InstType.OpBinary, "<", 4); - Add(Instruction.CompareNotEqual, InstType.OpBinaryCom, "!=", 5); - Add(Instruction.ConditionalSelect, InstType.OpTernary, "?:", 12); - Add(Instruction.ConvertFP32ToFP64, 0); // MSL does not have a 64-bit FP - Add(Instruction.ConvertFP64ToFP32, 0); // MSL does not have a 64-bit FP - Add(Instruction.ConvertFP32ToS32, InstType.CallUnary, "int"); - Add(Instruction.ConvertFP32ToU32, InstType.CallUnary, "uint"); - Add(Instruction.ConvertFP64ToS32, 0); // MSL does not have a 64-bit FP - Add(Instruction.ConvertFP64ToU32, 0); // MSL does not have a 64-bit FP - Add(Instruction.ConvertS32ToFP32, InstType.CallUnary, "float"); - Add(Instruction.ConvertS32ToFP64, 0); // MSL does not have a 64-bit FP - Add(Instruction.ConvertU32ToFP32, InstType.CallUnary, "float"); - Add(Instruction.ConvertU32ToFP64, 0); // MSL does not have a 64-bit FP - Add(Instruction.Cosine, InstType.CallUnary, "cos"); - Add(Instruction.Ddx, InstType.CallUnary, "dfdx"); - Add(Instruction.Ddy, InstType.CallUnary, "dfdy"); - Add(Instruction.Discard, InstType.CallNullary, "discard_fragment"); - Add(Instruction.Divide, InstType.OpBinary, "/", 1); - Add(Instruction.EmitVertex, 0); // MSL does not have geometry shaders - Add(Instruction.EndPrimitive, 0); // MSL does not have geometry shaders - Add(Instruction.ExponentB2, InstType.CallUnary, "exp2"); - Add(Instruction.FSIBegin, InstType.Special); - Add(Instruction.FSIEnd, InstType.Special); - Add(Instruction.FindLSB, InstType.CallUnary, HelperFunctionNames.FindLSB); - Add(Instruction.FindMSBS32, InstType.CallUnary, HelperFunctionNames.FindMSBS32); - Add(Instruction.FindMSBU32, InstType.CallUnary, HelperFunctionNames.FindMSBU32); - Add(Instruction.Floor, InstType.CallUnary, "floor"); - Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma"); - Add(Instruction.GroupMemoryBarrier, InstType.Special); - Add(Instruction.ImageLoad, InstType.Special); - Add(Instruction.ImageStore, InstType.Special); - Add(Instruction.ImageAtomic, InstType.Special); // Metal 3.1+ - Add(Instruction.IsNan, InstType.CallUnary, "isnan"); - Add(Instruction.Load, InstType.Special); - Add(Instruction.Lod, InstType.Special); - Add(Instruction.LogarithmB2, InstType.CallUnary, "log2"); - Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9); - Add(Instruction.LogicalExclusiveOr, InstType.OpBinaryCom, "^", 10); - Add(Instruction.LogicalNot, InstType.OpUnary, "!", 0); - Add(Instruction.LogicalOr, InstType.OpBinaryCom, "||", 11); - Add(Instruction.LoopBreak, InstType.OpNullary, "break"); - Add(Instruction.LoopContinue, InstType.OpNullary, "continue"); - Add(Instruction.PackDouble2x32, 0); // MSL does not have a 64-bit FP - Add(Instruction.PackHalf2x16, InstType.Special); - Add(Instruction.Maximum, InstType.CallBinary, "max"); - Add(Instruction.MaximumU32, InstType.CallBinary, "max"); - Add(Instruction.MemoryBarrier, InstType.Special); - Add(Instruction.Minimum, InstType.CallBinary, "min"); - Add(Instruction.MinimumU32, InstType.CallBinary, "min"); - Add(Instruction.Modulo, InstType.CallBinary, "fmod"); - Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1); - Add(Instruction.MultiplyHighS32, InstType.CallBinary, "mulhi"); - Add(Instruction.MultiplyHighU32, InstType.CallBinary, "mulhi"); - Add(Instruction.Negate, InstType.OpUnary, "-"); - Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "rsqrt"); - Add(Instruction.Return, InstType.OpNullary, "return"); - Add(Instruction.Round, InstType.CallUnary, "round"); - Add(Instruction.ShiftLeft, InstType.OpBinary, "<<", 3); - Add(Instruction.ShiftRightS32, InstType.OpBinary, ">>", 3); - Add(Instruction.ShiftRightU32, InstType.OpBinary, ">>", 3); - Add(Instruction.Shuffle, InstType.CallBinary, "simd_shuffle"); - Add(Instruction.ShuffleDown, InstType.CallBinary, "simd_shuffle_down"); - Add(Instruction.ShuffleUp, InstType.CallBinary, "simd_shuffle_up"); - Add(Instruction.ShuffleXor, InstType.CallBinary, "simd_shuffle_xor"); - Add(Instruction.Sine, InstType.CallUnary, "sin"); - Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt"); - Add(Instruction.Store, InstType.Special); - Add(Instruction.Subtract, InstType.OpBinary, "-", 2); - Add(Instruction.SwizzleAdd, InstType.CallTernary, HelperFunctionNames.SwizzleAdd); - Add(Instruction.TextureSample, InstType.Special); - Add(Instruction.TextureQuerySamples, InstType.Special); - Add(Instruction.TextureQuerySize, InstType.Special); - Add(Instruction.Truncate, InstType.CallUnary, "trunc"); - Add(Instruction.UnpackDouble2x32, 0); // MSL does not have a 64-bit FP - Add(Instruction.UnpackHalf2x16, InstType.Special); - Add(Instruction.VectorExtract, InstType.Special); - Add(Instruction.VoteAll, InstType.CallUnary, "simd_all"); - Add(Instruction.VoteAllEqual, InstType.Special); - Add(Instruction.VoteAny, InstType.CallUnary, "simd_any"); -#pragma warning restore IDE0055 - } - - private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0) - { - _infoTable[(int)inst] = new InstInfo(flags, opName, precedence); - } - - public static InstInfo GetInstructionInfo(Instruction inst) - { - return _infoTable[(int)(inst & Instruction.Mask)]; - } - - public static string GetSourceExpr(CodeGenContext context, IAstNode node, AggregateType dstType) - { - return ReinterpretCast(context, node, OperandManager.GetNodeDestType(context, node), dstType); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, bool isLhs) - { - InstInfo pInfo = GetInstructionInfo(pInst); - - return Enclose(expr, node, pInst, pInfo, isLhs); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs = false) - { - if (NeedsParenthesis(node, pInst, pInfo, isLhs)) - { - expr = "(" + expr + ")"; - } - - return expr; - } - - public static bool NeedsParenthesis(IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs) - { - // If the node isn't an operation, then it can only be an operand, - // and those never needs to be surrounded in parentheses. - if (node is not AstOperation operation) - { - // This is sort of a special case, if this is a negative constant, - // and it is consumed by a unary operation, we need to put on the parenthesis, - // as in MSL, while a sequence like ~-1 is valid, --2 is not. - if (IsNegativeConst(node) && pInfo.Type == InstType.OpUnary) - { - return true; - } - - return false; - } - - if ((pInfo.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - InstInfo info = _infoTable[(int)(operation.Inst & Instruction.Mask)]; - - if ((info.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - if (info.Precedence < pInfo.Precedence) - { - return false; - } - - if (info.Precedence == pInfo.Precedence && isLhs) - { - return false; - } - - if (pInst == operation.Inst && info.Type == InstType.OpBinaryCom) - { - return false; - } - - return true; - } - - private static bool IsNegativeConst(IAstNode node) - { - if (node is not AstOperand operand) - { - return false; - } - - return operand.Type == OperandType.Constant && operand.Value < 0; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs deleted file mode 100644 index a84a75e4f..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs +++ /dev/null @@ -1,672 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Text; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenMemory - { - public static string GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore) - { - StorageKind storageKind = operation.StorageKind; - - string varName; - AggregateType varType; - int srcIndex = 0; - bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic(); - int inputsCount = isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount; - bool fieldHasPadding = false; - - if (operation.Inst == Instruction.AtomicCompareAndSwap) - { - inputsCount--; - } - - string fieldName = string.Empty; - switch (storageKind) - { - case StorageKind.ConstantBuffer: - case StorageKind.StorageBuffer: - if (operation.GetSource(srcIndex++) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand."); - } - - int binding = bindingIndex.Value; - BufferDefinition buffer = storageKind == StorageKind.ConstantBuffer - ? context.Properties.ConstantBuffers[binding] - : context.Properties.StorageBuffers[binding]; - - if (operation.GetSource(srcIndex++) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand."); - } - - StructureField field = buffer.Type.Fields[fieldIndex.Value]; - - fieldHasPadding = buffer.Layout == BufferLayout.Std140 - && ((field.Type & AggregateType.Vector4) == 0) - && ((field.Type & AggregateType.Array) != 0); - - varName = storageKind == StorageKind.ConstantBuffer - ? "constant_buffers" - : "storage_buffers"; - varName += "." + buffer.Name; - varName += "->" + field.Name; - varType = field.Type; - break; - - case StorageKind.LocalMemory: - case StorageKind.SharedMemory: - if (operation.GetSource(srcIndex++) is not AstOperand { Type: OperandType.Constant } bindingId) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand."); - } - - MemoryDefinition memory = storageKind == StorageKind.LocalMemory - ? context.Properties.LocalMemories[bindingId.Value] - : context.Properties.SharedMemories[bindingId.Value]; - - varName = memory.Name; - varType = memory.Type; - break; - - case StorageKind.Input: - case StorageKind.InputPerPatch: - case StorageKind.Output: - case StorageKind.OutputPerPatch: - if (operation.GetSource(srcIndex++) is not AstOperand varId || varId.Type != OperandType.Constant) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand."); - } - - IoVariable ioVariable = (IoVariable)varId.Value; - bool isOutput = storageKind.IsOutput(); - bool isPerPatch = storageKind.IsPerPatch(); - int location = -1; - int component = 0; - - if (context.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput)) - { - if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand."); - } - - location = vecIndex.Value; - - if (operation.SourcesCount > srcIndex && - operation.GetSource(srcIndex) is AstOperand elemIndex && - elemIndex.Type == OperandType.Constant && - context.Definitions.HasPerLocationInputOrOutputComponent(ioVariable, vecIndex.Value, elemIndex.Value, isOutput)) - { - component = elemIndex.Value; - srcIndex++; - } - } - - (varName, varType) = IoMap.GetMslBuiltIn( - context.Definitions, - ioVariable, - location, - component, - isOutput, - isPerPatch); - break; - - default: - throw new InvalidOperationException($"Invalid storage kind {storageKind}."); - } - - for (; srcIndex < inputsCount; srcIndex++) - { - IAstNode src = operation.GetSource(srcIndex); - - if ((varType & AggregateType.ElementCountMask) != 0 && - srcIndex == inputsCount - 1 && - src is AstOperand elementIndex && - elementIndex.Type == OperandType.Constant) - { - varName += "." + "xyzw"[elementIndex.Value & 3]; - } - else - { - varName += $"[{GetSourceExpr(context, src, AggregateType.S32)}]"; - } - } - varName += fieldName; - varName += fieldHasPadding ? ".x" : string.Empty; - - if (isStore) - { - varType &= AggregateType.ElementTypeMask; - varName = $"{varName} = {GetSourceExpr(context, operation.GetSource(srcIndex), varType)}"; - } - - return varName; - } - - public static string ImageLoadOrStore(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isArray = (texOp.Type & SamplerType.Array) != 0; - - StringBuilder texCallBuilder = new(); - - int srcIndex = 0; - - string Src(AggregateType type) - { - return GetSourceExpr(context, texOp.GetSource(srcIndex++), type); - } - - string imageName = GetImageName(context, texOp, ref srcIndex); - texCallBuilder.Append(imageName); - texCallBuilder.Append('.'); - - if (texOp.Inst == Instruction.ImageAtomic) - { - texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch - { - TextureFlags.Add => "atomic_fetch_add", - TextureFlags.Minimum => "atomic_min", - TextureFlags.Maximum => "atomic_max", - TextureFlags.Increment => "atomic_fetch_add", - TextureFlags.Decrement => "atomic_fetch_sub", - TextureFlags.BitwiseAnd => "atomic_fetch_and", - TextureFlags.BitwiseOr => "atomic_fetch_or", - TextureFlags.BitwiseXor => "atomic_fetch_xor", - TextureFlags.Swap => "atomic_exchange", - TextureFlags.CAS => "atomic_compare_exchange_weak", - _ => "atomic_fetch_add", - }); - } - else - { - texCallBuilder.Append(texOp.Inst == Instruction.ImageLoad ? "read" : "write"); - } - - texCallBuilder.Append('('); - - StringBuilder coordsBuilder = new(); - - int coordsCount = texOp.Type.GetDimensions(); - - if (coordsCount > 1) - { - string[] elems = new string[coordsCount]; - - for (int index = 0; index < coordsCount; index++) - { - elems[index] = Src(AggregateType.S32); - } - - coordsBuilder.Append($"uint{coordsCount}({string.Join(", ", elems)})"); - } - else - { - coordsBuilder.Append($"uint({Src(AggregateType.S32)})"); - } - - if (isArray) - { - coordsBuilder.Append(", "); - coordsBuilder.Append(Src(AggregateType.S32)); - } - - if (texOp.Inst == Instruction.ImageStore) - { - AggregateType type = texOp.Format.GetComponentType(); - - string[] cElems = new string[4]; - - for (int index = 0; index < 4; index++) - { - if (srcIndex < texOp.SourcesCount) - { - cElems[index] = Src(type); - } - else - { - cElems[index] = type switch - { - AggregateType.S32 => NumberFormatter.FormatInt(0), - AggregateType.U32 => NumberFormatter.FormatUint(0), - _ => NumberFormatter.FormatFloat(0), - }; - } - } - - string prefix = type switch - { - AggregateType.S32 => "int", - AggregateType.U32 => "uint", - AggregateType.FP32 => "float", - _ => string.Empty, - }; - - texCallBuilder.Append($"{prefix}4({string.Join(", ", cElems)})"); - texCallBuilder.Append(", "); - } - - texCallBuilder.Append(coordsBuilder); - - if (texOp.Inst == Instruction.ImageAtomic) - { - texCallBuilder.Append(", "); - - AggregateType type = texOp.Format.GetComponentType(); - - if ((texOp.Flags & TextureFlags.AtomicMask) == TextureFlags.CAS) - { - texCallBuilder.Append(Src(type)); // Compare value. - } - - string value = (texOp.Flags & TextureFlags.AtomicMask) switch - { - TextureFlags.Increment => NumberFormatter.FormatInt(1, type), // TODO: Clamp value - TextureFlags.Decrement => NumberFormatter.FormatInt(-1, type), // TODO: Clamp value - _ => Src(type), - }; - - texCallBuilder.Append(value); - // This doesn't match what the MSL spec document says so either - // it is wrong or the MSL compiler has a bug. - texCallBuilder.Append(")[0]"); - } - else - { - texCallBuilder.Append(')'); - - if (texOp.Inst == Instruction.ImageLoad) - { - texCallBuilder.Append(GetMaskMultiDest(texOp.Index)); - } - } - - return texCallBuilder.ToString(); - } - - public static string Load(CodeGenContext context, AstOperation operation) - { - return GenerateLoadOrStore(context, operation, isStore: false); - } - - public static string Lod(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - int coordsCount = texOp.Type.GetDimensions(); - int coordsIndex = 0; - - string textureName = GetTextureName(context, texOp, ref coordsIndex); - string samplerName = GetSamplerName(context, texOp, ref coordsIndex); - - string coordsExpr; - - if (coordsCount > 1) - { - string[] elems = new string[coordsCount]; - - for (int index = 0; index < coordsCount; index++) - { - elems[index] = GetSourceExpr(context, texOp.GetSource(coordsIndex + index), AggregateType.FP32); - } - - coordsExpr = "float" + coordsCount + "(" + string.Join(", ", elems) + ")"; - } - else - { - coordsExpr = GetSourceExpr(context, texOp.GetSource(coordsIndex), AggregateType.FP32); - } - - string clamped = $"{textureName}.calculate_clamped_lod({samplerName}, {coordsExpr})"; - string unclamped = $"{textureName}.calculate_unclamped_lod({samplerName}, {coordsExpr})"; - - return $"float2({clamped}, {unclamped}){GetMask(texOp.Index)}"; - } - - public static string Store(CodeGenContext context, AstOperation operation) - { - return GenerateLoadOrStore(context, operation, isStore: true); - } - - public static string TextureSample(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isGather = (texOp.Flags & TextureFlags.Gather) != 0; - bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0; - bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0; - bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0; - bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0; - bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0; - bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0; - - bool isArray = (texOp.Type & SamplerType.Array) != 0; - bool isShadow = (texOp.Type & SamplerType.Shadow) != 0; - - StringBuilder texCallBuilder = new(); - - bool colorIsVector = isGather || !isShadow; - - int srcIndex = 0; - - string Src(AggregateType type) - { - return GetSourceExpr(context, texOp.GetSource(srcIndex++), type); - } - - string textureName = GetTextureName(context, texOp, ref srcIndex); - string samplerName = GetSamplerName(context, texOp, ref srcIndex); - - texCallBuilder.Append(textureName); - texCallBuilder.Append('.'); - - if (intCoords) - { - texCallBuilder.Append("read("); - } - else - { - if (isGather) - { - texCallBuilder.Append("gather"); - } - else - { - texCallBuilder.Append("sample"); - } - - if (isShadow) - { - texCallBuilder.Append("_compare"); - } - - texCallBuilder.Append($"({samplerName}, "); - } - - int coordsCount = texOp.Type.GetDimensions(); - - int pCount = coordsCount; - - bool appended = false; - void Append(string str) - { - if (appended) - { - texCallBuilder.Append(", "); - } - else - { - appended = true; - } - - texCallBuilder.Append(str); - } - - AggregateType coordType = intCoords ? AggregateType.S32 : AggregateType.FP32; - - string AssemblePVector(int count) - { - string coords; - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - elems[index] = Src(coordType); - } - - coords = string.Join(", ", elems); - } - else - { - coords = Src(coordType); - } - - string prefix = intCoords ? "uint" : "float"; - - return prefix + (count > 1 ? count : string.Empty) + "(" + coords + ")"; - } - - Append(AssemblePVector(pCount)); - - if (isArray) - { - Append(Src(AggregateType.S32)); - } - - if (isShadow) - { - Append(Src(AggregateType.FP32)); - } - - if (hasDerivatives) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, "Unused sampler derivatives!"); - } - - if (hasLodBias) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, "Unused sample LOD bias!"); - } - - if (hasLodLevel) - { - if (intCoords) - { - Append(Src(coordType)); - } - else - { - Append($"level({Src(coordType)})"); - } - } - - string AssembleOffsetVector(int count) - { - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - elems[index] = Src(AggregateType.S32); - } - - return "int" + count + "(" + string.Join(", ", elems) + ")"; - } - else - { - return Src(AggregateType.S32); - } - } - - // TODO: Support reads with offsets - if (!intCoords) - { - if (hasOffset) - { - Append(AssembleOffsetVector(coordsCount)); - } - else if (hasOffsets) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, "Multiple offsets on gathers are not yet supported!"); - } - } - - texCallBuilder.Append(')'); - texCallBuilder.Append(colorIsVector ? GetMaskMultiDest(texOp.Index) : string.Empty); - - return texCallBuilder.ToString(); - } - - private static string GetTextureName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex) - { - TextureDefinition textureDefinition = context.Properties.Textures[texOp.GetTextureSetAndBinding()]; - string name = textureDefinition.Name; - string setName = Declarations.GetNameForSet(textureDefinition.Set, true); - - if (textureDefinition.ArrayLength != 1) - { - name = $"{name}[{GetSourceExpr(context, texOp.GetSource(srcIndex++), AggregateType.S32)}]"; - } - - return $"{setName}.tex_{name}"; - } - - private static string GetSamplerName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex) - { - SetBindingPair index = texOp.IsSeparate ? texOp.GetSamplerSetAndBinding() : texOp.GetTextureSetAndBinding(); - int sourceIndex = texOp.IsSeparate ? srcIndex++ : srcIndex + 1; - - TextureDefinition samplerDefinition = context.Properties.Textures[index]; - string name = samplerDefinition.Name; - string setName = Declarations.GetNameForSet(samplerDefinition.Set, true); - - if (samplerDefinition.ArrayLength != 1) - { - name = $"{name}[{GetSourceExpr(context, texOp.GetSource(sourceIndex), AggregateType.S32)}]"; - } - - return $"{setName}.samp_{name}"; - } - - private static string GetImageName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex) - { - TextureDefinition imageDefinition = context.Properties.Images[texOp.GetTextureSetAndBinding()]; - string name = imageDefinition.Name; - string setName = Declarations.GetNameForSet(imageDefinition.Set, true); - - if (imageDefinition.ArrayLength != 1) - { - name = $"{name}[{GetSourceExpr(context, texOp.GetSource(srcIndex++), AggregateType.S32)}]"; - } - - return $"{setName}.{name}"; - } - - private static string GetMaskMultiDest(int mask) - { - if (mask == 0x0) - { - return string.Empty; - } - - string swizzle = "."; - - for (int i = 0; i < 4; i++) - { - if ((mask & (1 << i)) != 0) - { - swizzle += "xyzw"[i]; - } - } - - return swizzle; - } - - public static string TextureQuerySamples(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - int srcIndex = 0; - - string textureName = GetTextureName(context, texOp, ref srcIndex); - - return $"{textureName}.get_num_samples()"; - } - - public static string TextureQuerySize(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - StringBuilder texCallBuilder = new(); - - int srcIndex = 0; - - string textureName = GetTextureName(context, texOp, ref srcIndex); - texCallBuilder.Append(textureName); - texCallBuilder.Append('.'); - - if (texOp.Index == 3) - { - texCallBuilder.Append("get_num_mip_levels()"); - } - else - { - context.Properties.Textures.TryGetValue(texOp.GetTextureSetAndBinding(), out TextureDefinition definition); - bool hasLod = !definition.Type.HasFlag(SamplerType.Multisample) && (definition.Type & SamplerType.Mask) != SamplerType.TextureBuffer; - bool isArray = definition.Type.HasFlag(SamplerType.Array); - texCallBuilder.Append("get_"); - - if (texOp.Index == 0) - { - texCallBuilder.Append("width"); - } - else if (texOp.Index == 1) - { - texCallBuilder.Append("height"); - } - else - { - if (isArray) - { - texCallBuilder.Append("array_size"); - } - else - { - texCallBuilder.Append("depth"); - } - } - - texCallBuilder.Append('('); - - if (hasLod && !isArray) - { - IAstNode lod = operation.GetSource(0); - string lodExpr = GetSourceExpr(context, lod, GetSrcVarType(operation.Inst, 0)); - - texCallBuilder.Append(lodExpr); - } - - texCallBuilder.Append(')'); - } - - return texCallBuilder.ToString(); - } - - public static string PackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src0 = operation.GetSource(0); - IAstNode src1 = operation.GetSource(1); - - string src0Expr = GetSourceExpr(context, src0, GetSrcVarType(operation.Inst, 0)); - string src1Expr = GetSourceExpr(context, src1, GetSrcVarType(operation.Inst, 1)); - - return $"as_type(half2({src0Expr}, {src1Expr}))"; - } - - public static string UnpackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src = operation.GetSource(0); - - string srcExpr = GetSourceExpr(context, src, GetSrcVarType(operation.Inst, 0)); - - return $"float2(as_type({srcExpr})){GetMask(operation.Index)}"; - } - - private static string GetMask(int index) - { - return $".{"xy".AsSpan(index, 1)}"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs deleted file mode 100644 index 9d8dae543..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class InstGenVector - { - public static string VectorExtract(CodeGenContext context, AstOperation operation) - { - IAstNode vector = operation.GetSource(0); - IAstNode index = operation.GetSource(1); - - string vectorExpr = GetSourceExpr(context, vector, OperandManager.GetNodeDestType(context, vector)); - - if (index is AstOperand indexOperand && indexOperand.Type == OperandType.Constant) - { - char elem = "xyzw"[indexOperand.Value]; - - return $"{vectorExpr}.{elem}"; - } - else - { - string indexExpr = GetSourceExpr(context, index, GetSrcVarType(operation.Inst, 1)); - - return $"{vectorExpr}[{indexExpr}]"; - } - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstInfo.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstInfo.cs deleted file mode 100644 index 5e5d04d6b..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - readonly struct InstInfo - { - public InstType Type { get; } - - public string OpName { get; } - - public int Precedence { get; } - - public InstInfo(InstType type, string opName, int precedence) - { - Type = type; - OpName = opName; - Precedence = precedence; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstType.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstType.cs deleted file mode 100644 index d8f6bfed1..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstType.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - [Flags] - [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")] - public enum InstType - { - OpNullary = Op | 0, - OpUnary = Op | 1, - OpBinary = Op | 2, - OpBinaryCom = Op | 2 | Commutative, - OpTernary = Op | 3, - - CallNullary = Call | 0, - CallUnary = Call | 1, - CallBinary = Call | 2, - CallTernary = Call | 3, - CallQuaternary = Call | 4, - - // The atomic instructions have one extra operand, - // for the storage slot and offset pair. - AtomicBinary = Call | Atomic | 3, - AtomicTernary = Call | Atomic | 4, - - Commutative = 1 << 8, - Op = 1 << 9, - Call = 1 << 10, - Atomic = 1 << 11, - Special = 1 << 12, - - ArityMask = 0xff, - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/IoMap.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/IoMap.cs deleted file mode 100644 index 118612c66..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/IoMap.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Globalization; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions -{ - static class IoMap - { - public static (string, AggregateType) GetMslBuiltIn( - ShaderDefinitions definitions, - IoVariable ioVariable, - int location, - int component, - bool isOutput, - bool isPerPatch) - { - (string, AggregateType) returnValue = ioVariable switch - { - IoVariable.BaseInstance => ("base_instance", AggregateType.U32), - IoVariable.BaseVertex => ("base_vertex", AggregateType.U32), - IoVariable.CtaId => ("threadgroup_position_in_grid", AggregateType.Vector3 | AggregateType.U32), - IoVariable.ClipDistance => ("out.clip_distance", AggregateType.Array | AggregateType.FP32), - IoVariable.FragmentOutputColor => ($"out.color{location}", definitions.GetFragmentOutputColorType(location)), - IoVariable.FragmentOutputDepth => ("out.depth", AggregateType.FP32), - IoVariable.FrontFacing => ("in.front_facing", AggregateType.Bool), - IoVariable.GlobalId => ("thread_position_in_grid", AggregateType.Vector3 | AggregateType.U32), - IoVariable.InstanceId => ("instance_id", AggregateType.U32), - IoVariable.InstanceIndex => ("instance_index", AggregateType.U32), - IoVariable.InvocationId => ("INVOCATION_ID", AggregateType.S32), - IoVariable.PointCoord => ("in.point_coord", AggregateType.Vector2 | AggregateType.FP32), - IoVariable.PointSize => ("out.point_size", AggregateType.FP32), - IoVariable.Position => ("out.position", AggregateType.Vector4 | AggregateType.FP32), - IoVariable.PrimitiveId => ("in.primitive_id", AggregateType.U32), - IoVariable.SubgroupEqMask => ("thread_index_in_simdgroup >= 32 ? uint4(0, (1 << (thread_index_in_simdgroup - 32)), uint2(0)) : uint4(1 << thread_index_in_simdgroup, uint3(0))", AggregateType.Vector4 | AggregateType.U32), - IoVariable.SubgroupGeMask => ("uint4(insert_bits(0u, 0xFFFFFFFF, thread_index_in_simdgroup, 32 - thread_index_in_simdgroup), uint3(0)) & (uint4((uint)((simd_vote::vote_t)simd_ballot(true) & 0xFFFFFFFF), (uint)(((simd_vote::vote_t)simd_ballot(true) >> 32) & 0xFFFFFFFF), 0, 0))", AggregateType.Vector4 | AggregateType.U32), - IoVariable.SubgroupGtMask => ("uint4(insert_bits(0u, 0xFFFFFFFF, thread_index_in_simdgroup + 1, 32 - thread_index_in_simdgroup - 1), uint3(0)) & (uint4((uint)((simd_vote::vote_t)simd_ballot(true) & 0xFFFFFFFF), (uint)(((simd_vote::vote_t)simd_ballot(true) >> 32) & 0xFFFFFFFF), 0, 0))", AggregateType.Vector4 | AggregateType.U32), - IoVariable.SubgroupLaneId => ("thread_index_in_simdgroup", AggregateType.U32), - IoVariable.SubgroupLeMask => ("uint4(extract_bits(0xFFFFFFFF, 0, min(thread_index_in_simdgroup + 1, 32u)), extract_bits(0xFFFFFFFF, 0, (uint)max((int)thread_index_in_simdgroup + 1 - 32, 0)), uint2(0))", AggregateType.Vector4 | AggregateType.U32), - IoVariable.SubgroupLtMask => ("uint4(extract_bits(0xFFFFFFFF, 0, min(thread_index_in_simdgroup, 32u)), extract_bits(0xFFFFFFFF, 0, (uint)max((int)thread_index_in_simdgroup - 32, 0)), uint2(0))", AggregateType.Vector4 | AggregateType.U32), - IoVariable.ThreadKill => ("simd_is_helper_thread()", AggregateType.Bool), - IoVariable.UserDefined => GetUserDefinedVariableName(definitions, location, component, isOutput, isPerPatch), - IoVariable.ThreadId => ("thread_position_in_threadgroup", AggregateType.Vector3 | AggregateType.U32), - IoVariable.VertexId => ("vertex_id", AggregateType.S32), - // gl_VertexIndex does not have a direct equivalent in MSL - IoVariable.VertexIndex => ("vertex_id", AggregateType.U32), - IoVariable.ViewportIndex => ("viewport_array_index", AggregateType.S32), - IoVariable.FragmentCoord => ("in.position", AggregateType.Vector4 | AggregateType.FP32), - _ => (null, AggregateType.Invalid), - }; - - if (returnValue.Item2 == AggregateType.Invalid) - { - Logger.Warning?.PrintMsg(LogClass.Gpu, $"Unable to find type for IoVariable {ioVariable}!"); - } - - return returnValue; - } - - private static (string, AggregateType) GetUserDefinedVariableName(ShaderDefinitions definitions, int location, int component, bool isOutput, bool isPerPatch) - { - string name = isPerPatch - ? Defaults.PerPatchAttributePrefix - : (isOutput ? Defaults.OAttributePrefix : Defaults.IAttributePrefix); - - if (location < 0) - { - return (name, definitions.GetUserDefinedType(0, isOutput)); - } - - name += location.ToString(CultureInfo.InvariantCulture); - - if (definitions.HasPerLocationInputOrOutputComponent(IoVariable.UserDefined, location, component, isOutput)) - { - name += "_" + "xyzw"[component & 3]; - } - - string prefix = isOutput ? "out" : "in"; - - return (prefix + "." + name, definitions.GetUserDefinedType(location, isOutput)); - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs deleted file mode 100644 index 8ca24fcd3..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs +++ /dev/null @@ -1,286 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Linq; -using static Ryujinx.Graphics.Shader.CodeGen.Msl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class MslGenerator - { - public static string Generate(StructuredProgramInfo info, CodeGenParameters parameters) - { - if (parameters.Definitions.Stage is not (ShaderStage.Vertex or ShaderStage.Fragment or ShaderStage.Compute)) - { - Logger.Warning?.Print(LogClass.Gpu, $"Attempted to generate unsupported shader type {parameters.Definitions.Stage}!"); - return string.Empty; - } - - CodeGenContext context = new(info, parameters); - - int[] sets = Declarations.Declare(context, info); - - if (info.Functions.Count != 0) - { - for (int i = 1; i < info.Functions.Count; i++) - { - PrintFunction(context, info.Functions[i], parameters.Definitions.Stage, sets); - - context.AppendLine(); - } - } - - PrintFunction(context, info.Functions[0], parameters.Definitions.Stage, sets, true); - - return context.GetCode(); - } - - private static void PrintFunction(CodeGenContext context, StructuredFunction function, ShaderStage stage, int[] sets, bool isMainFunc = false) - { - context.CurrentFunction = function; - - context.AppendLine(GetFunctionSignature(context, function, stage, sets, isMainFunc)); - context.EnterScope(); - - Declarations.DeclareLocals(context, function, stage, isMainFunc); - - PrintBlock(context, function.MainBlock, isMainFunc); - - // In case the shader hasn't returned, return - if (isMainFunc && stage != ShaderStage.Compute) - { - context.AppendLine("return out;"); - } - - context.LeaveScope(); - } - - private static string GetFunctionSignature( - CodeGenContext context, - StructuredFunction function, - ShaderStage stage, - int[] sets, - bool isMainFunc = false) - { - int additionalArgCount = isMainFunc ? 0 : CodeGenContext.AdditionalArgCount + (context.Definitions.Stage != ShaderStage.Compute ? 1 : 0); - bool needsThreadIndex = false; - - // TODO: Replace this with a proper flag - if (function.Name.Contains("Shuffle")) - { - needsThreadIndex = true; - additionalArgCount++; - } - - string[] args = new string[additionalArgCount + function.InArguments.Length + function.OutArguments.Length]; - - // All non-main functions need to be able to access the support_buffer as well - if (!isMainFunc) - { - if (stage != ShaderStage.Compute) - { - args[0] = stage == ShaderStage.Vertex ? "VertexIn in" : "FragmentIn in"; - args[1] = "constant ConstantBuffers &constant_buffers"; - args[2] = "device StorageBuffers &storage_buffers"; - - if (needsThreadIndex) - { - args[3] = "uint thread_index_in_simdgroup"; - } - } - else - { - args[0] = "constant ConstantBuffers &constant_buffers"; - args[1] = "device StorageBuffers &storage_buffers"; - - if (needsThreadIndex) - { - args[2] = "uint thread_index_in_simdgroup"; - } - } - } - - int argIndex = additionalArgCount; - for (int i = 0; i < function.InArguments.Length; i++) - { - args[argIndex++] = $"{Declarations.GetVarTypeName(function.InArguments[i])} {OperandManager.GetArgumentName(i)}"; - } - - for (int i = 0; i < function.OutArguments.Length; i++) - { - int j = i + function.InArguments.Length; - - args[argIndex++] = $"thread {Declarations.GetVarTypeName(function.OutArguments[i])} &{OperandManager.GetArgumentName(j)}"; - } - - string funcKeyword = "inline"; - string funcName = null; - string returnType = Declarations.GetVarTypeName(function.ReturnType); - - if (isMainFunc) - { - if (stage == ShaderStage.Vertex) - { - funcKeyword = "vertex"; - funcName = "vertexMain"; - returnType = "VertexOut"; - } - else if (stage == ShaderStage.Fragment) - { - funcKeyword = "fragment"; - funcName = "fragmentMain"; - returnType = "FragmentOut"; - } - else if (stage == ShaderStage.Compute) - { - funcKeyword = "kernel"; - funcName = "kernelMain"; - returnType = "void"; - } - - if (stage == ShaderStage.Vertex) - { - args = args.Prepend("VertexIn in [[stage_in]]").ToArray(); - } - else if (stage == ShaderStage.Fragment) - { - args = args.Prepend("FragmentIn in [[stage_in]]").ToArray(); - } - - // TODO: add these only if they are used - if (stage == ShaderStage.Vertex) - { - args = args.Append("uint vertex_id [[vertex_id]]").ToArray(); - args = args.Append("uint instance_id [[instance_id]]").ToArray(); - args = args.Append("uint base_instance [[base_instance]]").ToArray(); - args = args.Append("uint base_vertex [[base_vertex]]").ToArray(); - } - else if (stage == ShaderStage.Compute) - { - args = args.Append("uint3 threadgroup_position_in_grid [[threadgroup_position_in_grid]]").ToArray(); - args = args.Append("uint3 thread_position_in_grid [[thread_position_in_grid]]").ToArray(); - args = args.Append("uint3 thread_position_in_threadgroup [[thread_position_in_threadgroup]]").ToArray(); - args = args.Append("uint thread_index_in_simdgroup [[thread_index_in_simdgroup]]").ToArray(); - } - - args = args.Append($"constant ConstantBuffers &constant_buffers [[buffer({Defaults.ConstantBuffersIndex})]]").ToArray(); - args = args.Append($"device StorageBuffers &storage_buffers [[buffer({Defaults.StorageBuffersIndex})]]").ToArray(); - - foreach (int set in sets) - { - long bindingIndex = set + Defaults.BaseSetIndex; - args = args.Append($"constant {Declarations.GetNameForSet(set)} &{Declarations.GetNameForSet(set, true)} [[buffer({bindingIndex})]]").ToArray(); - } - } - - string funcPrefix = $"{funcKeyword} {returnType} {funcName ?? function.Name}("; - string indent = new(' ', funcPrefix.Length); - - return $"{funcPrefix}{string.Join($", \n{indent}", args)})"; - } - - private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction) - { - AstBlockVisitor visitor = new(block); - - visitor.BlockEntered += (sender, e) => - { - switch (e.Block.Type) - { - case AstBlockType.DoWhile: - context.AppendLine("do"); - break; - - case AstBlockType.Else: - context.AppendLine("else"); - break; - - case AstBlockType.ElseIf: - context.AppendLine($"else if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - case AstBlockType.If: - context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - default: - throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\"."); - } - - context.EnterScope(); - }; - - visitor.BlockLeft += (sender, e) => - { - context.LeaveScope(); - - if (e.Block.Type == AstBlockType.DoWhile) - { - context.AppendLine($"while ({GetCondExpr(context, e.Block.Condition)});"); - } - }; - - bool supportsBarrierDivergence = context.HostCapabilities.SupportsShaderBarrierDivergence; - bool mayHaveReturned = false; - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstOperation operation) - { - if (!supportsBarrierDivergence) - { - if (operation.Inst == IntermediateRepresentation.Instruction.Barrier) - { - // Barrier on divergent control flow paths may cause the GPU to hang, - // so skip emitting the barrier for those cases. - if (visitor.Block.Type != AstBlockType.Main || mayHaveReturned || !isMainFunction) - { - context.Logger.Log($"Shader has barrier on potentially divergent block, the barrier will be removed."); - - continue; - } - } - else if (operation.Inst == IntermediateRepresentation.Instruction.Return) - { - mayHaveReturned = true; - } - } - - string expr = InstGen.GetExpression(context, operation); - - if (expr != null) - { - context.AppendLine(expr + ";"); - } - } - else if (node is AstAssignment assignment) - { - AggregateType dstType = OperandManager.GetNodeDestType(context, assignment.Destination); - AggregateType srcType = OperandManager.GetNodeDestType(context, assignment.Source); - - string dest = InstGen.GetExpression(context, assignment.Destination); - string src = ReinterpretCast(context, assignment.Source, srcType, dstType); - - context.AppendLine(dest + " = " + src + ";"); - } - else if (node is AstComment comment) - { - context.AppendLine("// " + comment.Comment); - } - else - { - throw new InvalidOperationException($"Found unexpected node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } - - private static string GetCondExpr(CodeGenContext context, IAstNode cond) - { - AggregateType srcType = OperandManager.GetNodeDestType(context, cond); - - return ReinterpretCast(context, cond, srcType, AggregateType.Bool); - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/NumberFormatter.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/NumberFormatter.cs deleted file mode 100644 index 86cdfc0e6..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/NumberFormatter.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Globalization; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class NumberFormatter - { - private const int MaxDecimal = 256; - - public static bool TryFormat(int value, AggregateType dstType, out string formatted) - { - switch (dstType) - { - case AggregateType.FP32: - return TryFormatFloat(BitConverter.Int32BitsToSingle(value), out formatted); - case AggregateType.S32: - formatted = FormatInt(value); - break; - case AggregateType.U32: - formatted = FormatUint((uint)value); - break; - case AggregateType.Bool: - formatted = value != 0 ? "true" : "false"; - break; - default: - throw new ArgumentException($"Invalid variable type \"{dstType}\"."); - } - - return true; - } - - public static string FormatFloat(float value) - { - if (!TryFormatFloat(value, out string formatted)) - { - throw new ArgumentException("Failed to convert float value to string."); - } - - return formatted; - } - - public static bool TryFormatFloat(float value, out string formatted) - { - if (float.IsNaN(value) || float.IsInfinity(value)) - { - formatted = null; - - return false; - } - - formatted = value.ToString("G9", CultureInfo.InvariantCulture); - - if (!(formatted.Contains('.') || - formatted.Contains('e') || - formatted.Contains('E'))) - { - formatted += ".0f"; - } - - return true; - } - - public static string FormatInt(int value, AggregateType dstType) - { - return dstType switch - { - AggregateType.S32 => FormatInt(value), - AggregateType.U32 => FormatUint((uint)value), - _ => throw new ArgumentException($"Invalid variable type \"{dstType}\".") - }; - } - - public static string FormatInt(int value) - { - if (value <= MaxDecimal && value >= -MaxDecimal) - { - return value.ToString(CultureInfo.InvariantCulture); - } - - return $"as_type(0x{value.ToString("X", CultureInfo.InvariantCulture)})"; - } - - public static string FormatUint(uint value) - { - if (value <= MaxDecimal && value >= 0) - { - return value.ToString(CultureInfo.InvariantCulture) + "u"; - } - - return $"as_type(0x{value.ToString("X", CultureInfo.InvariantCulture)})"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs deleted file mode 100644 index e131a645e..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - class OperandManager - { - private readonly Dictionary _locals; - - public OperandManager() - { - _locals = new Dictionary(); - } - - public string DeclareLocal(AstOperand operand) - { - string name = $"{Defaults.LocalNamePrefix}_{_locals.Count}"; - - _locals.Add(operand, name); - - return name; - } - - public string GetExpression(CodeGenContext context, AstOperand operand) - { - return operand.Type switch - { - OperandType.Argument => GetArgumentName(operand.Value), - OperandType.Constant => NumberFormatter.FormatInt(operand.Value), - OperandType.LocalVariable => _locals[operand], - OperandType.Undefined => Defaults.UndefinedName, - _ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."), - }; - } - - public static string GetArgumentName(int argIndex) - { - return $"{Defaults.ArgumentNamePrefix}{argIndex}"; - } - - public static AggregateType GetNodeDestType(CodeGenContext context, IAstNode node) - { - if (node is AstOperation operation) - { - if (operation.Inst == Instruction.Load || operation.Inst.IsAtomic()) - { - switch (operation.StorageKind) - { - case StorageKind.ConstantBuffer: - case StorageKind.StorageBuffer: - if (operation.GetSource(0) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); - } - - if (operation.GetSource(1) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); - } - - BufferDefinition buffer = operation.StorageKind == StorageKind.ConstantBuffer - ? context.Properties.ConstantBuffers[bindingIndex.Value] - : context.Properties.StorageBuffers[bindingIndex.Value]; - StructureField field = buffer.Type.Fields[fieldIndex.Value]; - - return field.Type & AggregateType.ElementTypeMask; - - case StorageKind.LocalMemory: - case StorageKind.SharedMemory: - if (operation.GetSource(0) is not AstOperand { Type: OperandType.Constant } bindingId) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); - } - - MemoryDefinition memory = operation.StorageKind == StorageKind.LocalMemory - ? context.Properties.LocalMemories[bindingId.Value] - : context.Properties.SharedMemories[bindingId.Value]; - - return memory.Type & AggregateType.ElementTypeMask; - - case StorageKind.Input: - case StorageKind.InputPerPatch: - case StorageKind.Output: - case StorageKind.OutputPerPatch: - if (operation.GetSource(0) is not AstOperand varId || varId.Type != OperandType.Constant) - { - throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); - } - - IoVariable ioVariable = (IoVariable)varId.Value; - bool isOutput = operation.StorageKind == StorageKind.Output || operation.StorageKind == StorageKind.OutputPerPatch; - bool isPerPatch = operation.StorageKind == StorageKind.InputPerPatch || operation.StorageKind == StorageKind.OutputPerPatch; - int location = 0; - int component = 0; - - if (context.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput)) - { - if (operation.GetSource(1) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant) - { - throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); - } - - location = vecIndex.Value; - - if (operation.SourcesCount > 2 && - operation.GetSource(2) is AstOperand elemIndex && - elemIndex.Type == OperandType.Constant && - context.Definitions.HasPerLocationInputOrOutputComponent(ioVariable, location, elemIndex.Value, isOutput)) - { - component = elemIndex.Value; - } - } - - (_, AggregateType varType) = IoMap.GetMslBuiltIn( - context.Definitions, - ioVariable, - location, - component, - isOutput, - isPerPatch); - - return varType & AggregateType.ElementTypeMask; - } - } - else if (operation.Inst == Instruction.Call) - { - AstOperand funcId = (AstOperand)operation.GetSource(0); - - Debug.Assert(funcId.Type == OperandType.Constant); - - return context.GetFunction(funcId.Value).ReturnType; - } - else if (operation.Inst == Instruction.VectorExtract) - { - return GetNodeDestType(context, operation.GetSource(0)) & ~AggregateType.ElementCountMask; - } - else if (operation is AstTextureOperation texOp) - { - if (texOp.Inst == Instruction.ImageLoad || - texOp.Inst == Instruction.ImageStore || - texOp.Inst == Instruction.ImageAtomic) - { - return texOp.GetVectorType(texOp.Format.GetComponentType()); - } - else if (texOp.Inst == Instruction.TextureSample) - { - return texOp.GetVectorType(GetDestVarType(operation.Inst)); - } - } - - return GetDestVarType(operation.Inst); - } - else if (node is AstOperand operand) - { - if (operand.Type == OperandType.Argument) - { - int argIndex = operand.Value; - - return context.CurrentFunction.GetArgumentType(argIndex); - } - - return OperandInfo.GetVarType(operand); - } - else - { - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs deleted file mode 100644 index e145bb8b0..000000000 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation; -using System; - -namespace Ryujinx.Graphics.Shader.CodeGen.Msl -{ - static class TypeConversion - { - public static string ReinterpretCast( - CodeGenContext context, - IAstNode node, - AggregateType srcType, - AggregateType dstType) - { - if (node is AstOperand operand && operand.Type == OperandType.Constant) - { - if (NumberFormatter.TryFormat(operand.Value, dstType, out string formatted)) - { - return formatted; - } - } - - string expr = InstGen.GetExpression(context, node); - - return ReinterpretCast(expr, node, srcType, dstType); - } - - private static string ReinterpretCast(string expr, IAstNode node, AggregateType srcType, AggregateType dstType) - { - if (srcType == dstType) - { - return expr; - } - - if (srcType == AggregateType.FP32) - { - switch (dstType) - { - case AggregateType.Bool: - return $"(as_type({expr}) != 0)"; - case AggregateType.S32: - return $"as_type({expr})"; - case AggregateType.U32: - return $"as_type({expr})"; - } - } - else if (dstType == AggregateType.FP32) - { - switch (srcType) - { - case AggregateType.Bool: - return $"as_type({ReinterpretBoolToInt(expr, node, AggregateType.S32)})"; - case AggregateType.S32: - return $"as_type({expr})"; - case AggregateType.U32: - return $"as_type({expr})"; - } - } - else if (srcType == AggregateType.Bool) - { - return ReinterpretBoolToInt(expr, node, dstType); - } - else if (dstType == AggregateType.Bool) - { - expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true); - - return $"({expr} != 0)"; - } - else if (dstType == AggregateType.S32) - { - return $"int({expr})"; - } - else if (dstType == AggregateType.U32) - { - return $"uint({expr})"; - } - - throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\"."); - } - - private static string ReinterpretBoolToInt(string expr, IAstNode node, AggregateType dstType) - { - string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType); - string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType); - - expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false); - - return $"({expr} ? {trueExpr} : {falseExpr})"; - } - } -} diff --git a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj index 8b05d8829..cfb188daf 100644 --- a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj +++ b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj @@ -15,11 +15,4 @@ - - - - - - - diff --git a/src/Ryujinx.Graphics.Shader/SamplerType.cs b/src/Ryujinx.Graphics.Shader/SamplerType.cs index f81d512fa..a693495fa 100644 --- a/src/Ryujinx.Graphics.Shader/SamplerType.cs +++ b/src/Ryujinx.Graphics.Shader/SamplerType.cs @@ -155,51 +155,5 @@ namespace Ryujinx.Graphics.Shader return typeName; } - - public static string ToMslTextureType(this SamplerType type, AggregateType aggregateType, bool image = false) - { - string typeName; - - if ((type & SamplerType.Shadow) != 0) - { - typeName = (type & SamplerType.Mask) switch - { - SamplerType.Texture2D => "depth2d", - SamplerType.TextureCube => "depthcube", - _ => throw new ArgumentException($"Invalid shadow texture type \"{type}\"."), - }; - } - else - { - typeName = (type & SamplerType.Mask) switch - { - SamplerType.Texture1D => "texture1d", - SamplerType.TextureBuffer => "texture_buffer", - SamplerType.Texture2D => "texture2d", - SamplerType.Texture3D => "texture3d", - SamplerType.TextureCube => "texturecube", - _ => throw new ArgumentException($"Invalid texture type \"{type}\"."), - }; - } - - if ((type & SamplerType.Multisample) != 0) - { - typeName += "_ms"; - } - - if ((type & SamplerType.Array) != 0) - { - typeName += "_array"; - } - - string format = aggregateType switch - { - AggregateType.S32 => "int", - AggregateType.U32 => "uint", - _ => "float" - }; - - return $"{typeName}<{format}{(image ? ", access::read_write" : string.Empty)}>"; - } } } diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs index b70def78c..2a3d65e75 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs @@ -7,14 +7,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { MultiplyHighS32 = 1 << 2, MultiplyHighU32 = 1 << 3, - - FindLSB = 1 << 5, - FindMSBS32 = 1 << 6, - FindMSBU32 = 1 << 7, - SwizzleAdd = 1 << 10, FSI = 1 << 11, - - Precise = 1 << 13 } } diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs index 1ae669aa9..824aea195 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs @@ -18,10 +18,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr ShaderDefinitions definitions, ResourceManager resourceManager, TargetLanguage targetLanguage, - bool precise, bool debugMode) { - StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, precise, debugMode); + StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, debugMode); for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++) { @@ -323,9 +322,8 @@ namespace Ryujinx.Graphics.Shader.StructuredIr } // Those instructions needs to be emulated by using helper functions, - // because they are NVIDIA specific or because the target language has - // no direct equivalent. Those flags helps the backend to decide which - // helper functions are needed on the final generated code. + // because they are NVIDIA specific. Those flags helps the backend to + // decide which helper functions are needed on the final generated code. switch (operation.Inst) { case Instruction.MultiplyHighS32: @@ -334,15 +332,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr case Instruction.MultiplyHighU32: context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32; break; - case Instruction.FindLSB: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.FindLSB; - break; - case Instruction.FindMSBS32: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.FindMSBS32; - break; - case Instruction.FindMSBU32: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.FindMSBU32; - break; case Instruction.SwizzleAdd: context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd; break; diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs index a5887e80d..60bdacc02 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs @@ -36,10 +36,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr AttributeUsage attributeUsage, ShaderDefinitions definitions, ResourceManager resourceManager, - bool precise, bool debugMode) { - Info = new StructuredProgramInfo(precise); + Info = new StructuredProgramInfo(); Definitions = definitions; ResourceManager = resourceManager; diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs index 2f8675069..ded2f2a89 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs @@ -10,16 +10,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr public HelperFunctionsMask HelperFunctionsMask { get; set; } - public StructuredProgramInfo(bool precise) + public StructuredProgramInfo() { - Functions = []; + Functions = new List(); - IoDefinitions = []; - - if (precise) - { - HelperFunctionsMask |= HelperFunctionsMask.Precise; - } + IoDefinitions = new HashSet(); } } } diff --git a/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs b/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs index 26c924e89..82a54db83 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs @@ -26,6 +26,5 @@ namespace Ryujinx.Graphics.Shader.Translation SharedMemory = 1 << 11, Store = 1 << 12, VtgAsCompute = 1 << 13, - Precise = 1 << 14, } } diff --git a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs index e10182747..94691a5b4 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation private const int DefaultLocalMemorySize = 128; private const int DefaultSharedMemorySize = 4096; - private static readonly string[] _stagePrefixes = ["cp", "vp", "tcp", "tep", "gp", "fp"]; + private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" }; private readonly IGpuAccessor _gpuAccessor; private readonly ShaderStage _stage; @@ -43,11 +43,6 @@ namespace Ryujinx.Graphics.Shader.Translation private readonly Dictionary _usedTextures; private readonly Dictionary _usedImages; - private readonly List _vacConstantBuffers; - private readonly List _vacStorageBuffers; - private readonly List _vacTextures; - private readonly List _vacImages; - public int LocalMemoryId { get; private set; } public int SharedMemoryId { get; private set; } @@ -78,16 +73,11 @@ namespace Ryujinx.Graphics.Shader.Translation _sbSlots = new(); _sbSlotsReverse = new(); - _usedConstantBufferBindings = []; + _usedConstantBufferBindings = new(); _usedTextures = new(); _usedImages = new(); - _vacConstantBuffers = []; - _vacStorageBuffers = []; - _vacTextures = []; - _vacImages = []; - Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType())); LocalMemoryId = -1; @@ -103,7 +93,7 @@ namespace Ryujinx.Graphics.Shader.Translation size = DefaultLocalMemorySize; } - MemoryDefinition lmem = new("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint))); + var lmem = new MemoryDefinition("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint))); LocalMemoryId = Properties.AddLocalMemory(lmem); } @@ -122,7 +112,7 @@ namespace Ryujinx.Graphics.Shader.Translation size = DefaultSharedMemorySize; } - MemoryDefinition smem = new("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint))); + var smem = new MemoryDefinition("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint))); SharedMemoryId = Properties.AddSharedMemory(smem); } @@ -283,16 +273,16 @@ namespace Ryujinx.Graphics.Shader.Translation bool coherent, bool separate) { - int dimensions = type == SamplerType.None ? 0 : type.GetDimensions(); - Dictionary dict = isImage ? _usedImages : _usedTextures; + var dimensions = type == SamplerType.None ? 0 : type.GetDimensions(); + var dict = isImage ? _usedImages : _usedTextures; - TextureUsageFlags usageFlags = TextureUsageFlags.None; + var usageFlags = TextureUsageFlags.None; if (intCoords) { usageFlags |= TextureUsageFlags.NeedsScaleValue; - bool canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2; + var canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2; if (!canScale) { @@ -314,9 +304,9 @@ namespace Ryujinx.Graphics.Shader.Translation // For array textures, we also want to use type as key, // since we may have texture handles stores in the same buffer, but for textures with different types. - SamplerType keyType = arrayLength > 1 ? type : SamplerType.None; - TextureInfo info = new(cbufSlot, handle, arrayLength, separate, keyType, format); - TextureMeta meta = new() + var keyType = arrayLength > 1 ? type : SamplerType.None; + var info = new TextureInfo(cbufSlot, handle, arrayLength, separate, keyType, format); + var meta = new TextureMeta() { AccurateType = accurateType, Type = type, @@ -326,7 +316,7 @@ namespace Ryujinx.Graphics.Shader.Translation int setIndex; int binding; - if (dict.TryGetValue(info, out TextureMeta existingMeta)) + if (dict.TryGetValue(info, out var existingMeta)) { dict[info] = MergeTextureMeta(meta, existingMeta); setIndex = existingMeta.Set; @@ -383,7 +373,7 @@ namespace Ryujinx.Graphics.Shader.Translation nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}"; } - TextureDefinition definition = new( + var definition = new TextureDefinition( setIndex, binding, arrayLength, @@ -443,8 +433,8 @@ namespace Ryujinx.Graphics.Shader.Translation { selectedMeta.UsageFlags |= TextureUsageFlags.NeedsScaleValue; - int dimensions = type.GetDimensions(); - bool canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2; + var dimensions = type.GetDimensions(); + var canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2; if (!canScale) { @@ -464,7 +454,7 @@ namespace Ryujinx.Graphics.Shader.Translation public BufferDescriptor[] GetConstantBufferDescriptors() { - BufferDescriptor[] descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count]; + var descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count]; int descriptorIndex = 0; @@ -488,7 +478,7 @@ namespace Ryujinx.Graphics.Shader.Translation public BufferDescriptor[] GetStorageBufferDescriptors() { - BufferDescriptor[] descriptors = new BufferDescriptor[_sbSlots.Count]; + var descriptors = new BufferDescriptor[_sbSlots.Count]; int descriptorIndex = 0; @@ -524,7 +514,7 @@ namespace Ryujinx.Graphics.Shader.Translation private static TextureDescriptor[] GetDescriptors(IReadOnlyDictionary usedResources, bool includeArrays) { - List descriptors = []; + List descriptors = new(); bool hasAnyArray = false; @@ -573,75 +563,6 @@ namespace Ryujinx.Graphics.Shader.Translation return descriptors.ToArray(); } - public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false) - { - BufferDescriptor[] cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count]; - int cbDescriptorIndex = 0; - - foreach (BufferDefinition definition in _vacConstantBuffers) - { - cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None); - } - - BufferDescriptor[] sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count]; - int sbDescriptorIndex = 0; - - foreach (BufferDefinition definition in _vacStorageBuffers) - { - sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write); - } - - TextureDescriptor[] tDescriptors = new TextureDescriptor[_vacTextures.Count]; - int tDescriptorIndex = 0; - - foreach (TextureDefinition definition in _vacTextures) - { - tDescriptors[tDescriptorIndex++] = new TextureDescriptor( - definition.Set, - definition.Binding, - definition.Type, - definition.Format, - 0, - 0, - definition.ArrayLength, - definition.Separate, - definition.Flags); - } - - TextureDescriptor[] iDescriptors = new TextureDescriptor[_vacImages.Count]; - int iDescriptorIndex = 0; - - foreach (TextureDefinition definition in _vacImages) - { - iDescriptors[iDescriptorIndex++] = new TextureDescriptor( - definition.Set, - definition.Binding, - definition.Type, - definition.Format, - 0, - 0, - definition.ArrayLength, - definition.Separate, - definition.Flags); - } - - return new ShaderProgramInfo( - cbDescriptors, - sbDescriptors, - tDescriptors, - iDescriptors, - isVertex ? ShaderStage.Vertex : ShaderStage.Compute, - 0, - 0, - 0, - false, - false, - false, - false, - 0, - 0); - } - public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle) { foreach ((TextureInfo info, TextureMeta meta) in _usedTextures) @@ -690,46 +611,24 @@ namespace Ryujinx.Graphics.Shader.Translation private void AddNewConstantBuffer(int setIndex, int binding, string name) { - StructureType type = new([ - new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16) - ]); + StructureType type = new(new[] + { + new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16), + }); Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, setIndex, binding, name, type)); } private void AddNewStorageBuffer(int setIndex, int binding, string name) { - StructureType type = new([ - new StructureField(AggregateType.Array | AggregateType.U32, "data", 0) - ]); + StructureType type = new(new[] + { + new StructureField(AggregateType.Array | AggregateType.U32, "data", 0), + }); Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type)); } - public void AddVertexAsComputeConstantBuffer(BufferDefinition definition) - { - _vacConstantBuffers.Add(definition); - Properties.AddOrUpdateConstantBuffer(definition); - } - - public void AddVertexAsComputeStorageBuffer(BufferDefinition definition) - { - _vacStorageBuffers.Add(definition); - Properties.AddOrUpdateStorageBuffer(definition); - } - - public void AddVertexAsComputeTexture(TextureDefinition definition) - { - _vacTextures.Add(definition); - Properties.AddOrUpdateTexture(definition); - } - - public void AddVertexAsComputeImage(TextureDefinition definition) - { - _vacImages.Add(definition); - Properties.AddOrUpdateImage(definition); - } - public static string GetShaderStagePrefix(ShaderStage stage) { uint index = (uint)stage; diff --git a/src/Ryujinx.Graphics.Shader/Translation/TargetApi.cs b/src/Ryujinx.Graphics.Shader/Translation/TargetApi.cs index 66ed3dd45..519600937 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/TargetApi.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/TargetApi.cs @@ -4,6 +4,5 @@ namespace Ryujinx.Graphics.Shader.Translation { OpenGL, Vulkan, - Metal } } diff --git a/src/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs b/src/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs index 9d58cb926..863c7447b 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs @@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.Shader.Translation { Glsl, Spirv, - Msl + Arb, } } diff --git a/src/Ryujinx.Graphics.Shader/Translation/Transforms/ForcePreciseEnable.cs b/src/Ryujinx.Graphics.Shader/Translation/Transforms/ForcePreciseEnable.cs index c774816a3..6b7e1410f 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Transforms/ForcePreciseEnable.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Transforms/ForcePreciseEnable.cs @@ -27,8 +27,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms addOp.Inst == (Instruction.FP32 | Instruction.Add) && addOp.GetSource(1).Type == OperandType.Constant) { - context.UsedFeatures |= FeatureFlags.Precise; - addOp.ForcePrecise = true; } diff --git a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs index ff8fb255a..a579433f9 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs @@ -1,6 +1,5 @@ using Ryujinx.Graphics.Shader.CodeGen; using Ryujinx.Graphics.Shader.CodeGen.Glsl; -using Ryujinx.Graphics.Shader.CodeGen.Msl; using Ryujinx.Graphics.Shader.CodeGen.Spirv; using Ryujinx.Graphics.Shader.Decoders; using Ryujinx.Graphics.Shader.IntermediateRepresentation; @@ -243,8 +242,8 @@ namespace Ryujinx.Graphics.Shader.Translation usedFeatures |= FeatureFlags.VtgAsCompute; } - ControlFlowGraph[] cfgs = new ControlFlowGraph[functions.Length]; - RegisterUsage.FunctionRegisterUsage[] frus = new RegisterUsage.FunctionRegisterUsage[functions.Length]; + var cfgs = new ControlFlowGraph[functions.Length]; + var frus = new RegisterUsage.FunctionRegisterUsage[functions.Length]; for (int i = 0; i < functions.Length; i++) { @@ -267,14 +266,14 @@ namespace Ryujinx.Graphics.Shader.Translation for (int i = 0; i < functions.Length; i++) { - ControlFlowGraph cfg = cfgs[i]; + var cfg = cfgs[i]; int inArgumentsCount = 0; int outArgumentsCount = 0; if (i != 0) { - RegisterUsage.FunctionRegisterUsage fru = frus[i]; + var fru = frus[i]; inArgumentsCount = fru.InArguments.Length; outArgumentsCount = fru.OutArguments.Length; @@ -326,13 +325,12 @@ namespace Ryujinx.Graphics.Shader.Translation FeatureFlags usedFeatures, byte clipDistancesWritten) { - StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram( + var sInfo = StructuredProgram.MakeStructuredProgram( funcs, attributeUsage, definitions, resourceManager, Options.TargetLanguage, - usedFeatures.HasFlag(FeatureFlags.Precise), Options.Flags.HasFlag(TranslationFlags.DebugMode)); int geometryVerticesPerPrimitive = Definitions.OutputTopology switch @@ -342,7 +340,7 @@ namespace Ryujinx.Graphics.Shader.Translation _ => 1 }; - ShaderProgramInfo info = new( + var info = new ShaderProgramInfo( resourceManager.GetConstantBufferDescriptors(), resourceManager.GetStorageBufferDescriptors(), resourceManager.GetTextureDescriptors(), @@ -358,7 +356,7 @@ namespace Ryujinx.Graphics.Shader.Translation clipDistancesWritten, originalDefinitions.OmapTargets); - HostCapabilities hostCapabilities = new( + var hostCapabilities = new HostCapabilities( GpuAccessor.QueryHostReducedPrecision(), GpuAccessor.QueryHostSupportsFragmentShaderInterlock(), GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(), @@ -369,13 +367,12 @@ namespace Ryujinx.Graphics.Shader.Translation GpuAccessor.QueryHostSupportsTextureShadowLod(), GpuAccessor.QueryHostSupportsViewportMask()); - CodeGenParameters parameters = new(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi); + var parameters = new CodeGenParameters(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi); return Options.TargetLanguage switch { TargetLanguage.Glsl => new ShaderProgram(info, TargetLanguage.Glsl, GlslGenerator.Generate(sInfo, parameters)), TargetLanguage.Spirv => new ShaderProgram(info, TargetLanguage.Spirv, SpirvGenerator.Generate(sInfo, parameters)), - TargetLanguage.Msl => new ShaderProgram(info, TargetLanguage.Msl, MslGenerator.Generate(sInfo, parameters)), _ => throw new NotImplementedException(Options.TargetLanguage.ToString()), }; } @@ -386,15 +383,16 @@ namespace Ryujinx.Graphics.Shader.Translation if (IsTransformFeedbackEmulated) { - StructureType tfeDataStruct = new([ - new(AggregateType.Array | AggregateType.U32, "data", 0) - ]); + StructureType tfeDataStruct = new(new StructureField[] + { + new StructureField(AggregateType.Array | AggregateType.U32, "data", 0) + }); for (int i = 0; i < ResourceReservations.TfeBuffersCount; i++) { int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i); BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct); - resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer); + resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer); } } @@ -402,21 +400,22 @@ namespace Ryujinx.Graphics.Shader.Translation { int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding; BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); - resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer); + resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); - StructureType vertexOutputStruct = new([ - new(AggregateType.Array | AggregateType.FP32, "data", 0) - ]); + StructureType vertexOutputStruct = new(new StructureField[] + { + new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0) + }); int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding; BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct); - resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer); + resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); if (Stage == ShaderStage.Vertex) { SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding(); TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer); - resourceManager.AddVertexAsComputeTexture(indexBuffer); + resourceManager.Properties.AddOrUpdateTexture(indexBuffer); int inputMap = _program.AttributeUsage.UsedInputAttributes; @@ -425,7 +424,7 @@ namespace Ryujinx.Graphics.Shader.Translation int location = BitOperations.TrailingZeroCount(inputMap); SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location); TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer); - resourceManager.AddVertexAsComputeTexture(vaBuffer); + resourceManager.Properties.AddOrUpdateTexture(vaBuffer); inputMap &= ~(1 << location); } @@ -434,19 +433,20 @@ namespace Ryujinx.Graphics.Shader.Translation { SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding(); TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer); - resourceManager.AddVertexAsComputeTexture(remapBuffer); + resourceManager.Properties.AddOrUpdateTexture(remapBuffer); int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding; BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct); - resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer); + resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer); - StructureType geometryIbOutputStruct = new([ - new(AggregateType.Array | AggregateType.U32, "data", 0) - ]); + StructureType geometryIbOutputStruct = new(new StructureField[] + { + new StructureField(AggregateType.Array | AggregateType.U32, "data", 0) + }); int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding; BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct); - resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer); + resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer); } resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology); @@ -479,40 +479,36 @@ namespace Ryujinx.Graphics.Shader.Translation return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage); } - public ShaderProgramInfo GetVertexAsComputeInfo() - { - return CreateResourceManager(true).GetVertexAsComputeInfo(); - } - public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext) { _vertexOutput = vertexContext._program.GetIoUsage(); } - public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute() + public ShaderProgram GenerateVertexPassthroughForCompute() { - AttributeUsage attributeUsage = new(GpuAccessor); - ResourceManager resourceManager = new(ShaderStage.Vertex, GpuAccessor); + var attributeUsage = new AttributeUsage(GpuAccessor); + var resourceManager = new ResourceManager(ShaderStage.Vertex, GpuAccessor); - ResourceReservations reservations = GetResourceReservations(); + var reservations = GetResourceReservations(); int vertexInfoCbBinding = reservations.VertexInfoConstantBufferBinding; if (Stage == ShaderStage.Vertex) { BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); - resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer); + resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); } - StructureType vertexInputStruct = new([ - new(AggregateType.Array | AggregateType.FP32, "data", 0) - ]); + StructureType vertexInputStruct = new(new StructureField[] + { + new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0) + }); int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding; BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct); - resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer); + resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); - EmitterContext context = new(); + var context = new EmitterContext(); Operand vertexIndex = Options.TargetApi == TargetApi.OpenGL ? context.Load(StorageKind.Input, IoVariable.VertexId) @@ -557,25 +553,25 @@ namespace Ryujinx.Graphics.Shader.Translation } } - Operation[] operations = context.GetOperations(); - ControlFlowGraph cfg = ControlFlowGraph.Create(operations); - Function function = new(cfg.Blocks, "main", false, 0, 0); + var operations = context.GetOperations(); + var cfg = ControlFlowGraph.Create(operations); + var function = new Function(cfg.Blocks, "main", false, 0, 0); - TransformFeedbackOutput[] transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap); + var transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap); - ShaderDefinitions definitions = new(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs) + var definitions = new ShaderDefinitions(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs) { LastInVertexPipeline = true }; - return (Generate( - [function], + return Generate( + new[] { function }, attributeUsage, definitions, definitions, resourceManager, FeatureFlags.None, - 0), resourceManager.GetVertexAsComputeInfo(isVertex: true)); + 0); } public ShaderProgram GenerateGeometryPassthrough() @@ -608,10 +604,10 @@ namespace Ryujinx.Graphics.Shader.Translation break; } - AttributeUsage attributeUsage = new(GpuAccessor); - ResourceManager resourceManager = new(ShaderStage.Geometry, GpuAccessor); + var attributeUsage = new AttributeUsage(GpuAccessor); + var resourceManager = new ResourceManager(ShaderStage.Geometry, GpuAccessor); - EmitterContext context = new(); + var context = new EmitterContext(); for (int v = 0; v < maxOutputVertices; v++) { @@ -652,11 +648,11 @@ namespace Ryujinx.Graphics.Shader.Translation context.EndPrimitive(); - Operation[] operations = context.GetOperations(); - ControlFlowGraph cfg = ControlFlowGraph.Create(operations); - Function function = new(cfg.Blocks, "main", false, 0, 0); + var operations = context.GetOperations(); + var cfg = ControlFlowGraph.Create(operations); + var function = new Function(cfg.Blocks, "main", false, 0, 0); - ShaderDefinitions definitions = new( + var definitions = new ShaderDefinitions( ShaderStage.Geometry, GpuAccessor.QueryGraphicsState(), false, @@ -665,7 +661,7 @@ namespace Ryujinx.Graphics.Shader.Translation maxOutputVertices); return Generate( - [function], + new[] { function }, attributeUsage, definitions, definitions, diff --git a/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj new file mode 100644 index 000000000..fe535e6d5 --- /dev/null +++ b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj @@ -0,0 +1,72 @@ + + + + win-x64;osx-x64;linux-x64 + Exe + true + 1.0.0-dirty + $(DefineConstants);$(ExtraDefineConstants) + - + true + $(DefaultItemExcludes);._* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + THIRDPARTY.md + + + Always + LICENSE.txt + + + + + + Always + + + + + + + + + + false + ..\Ryujinx\Ryujinx.ico + + + + true + true + partial + + diff --git a/src/Ryujinx.ShaderTools/Program.cs b/src/Ryujinx.ShaderTools/Program.cs index 564960c6f..a84d7b466 100644 --- a/src/Ryujinx.ShaderTools/Program.cs +++ b/src/Ryujinx.ShaderTools/Program.cs @@ -116,7 +116,7 @@ namespace Ryujinx.ShaderTools if (options.VertexPassthrough) { - (program, _) = translatorContext.GenerateVertexPassthroughForCompute(); + program = translatorContext.GenerateVertexPassthroughForCompute(); } else { diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 4147b8a5e..5872b278f 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -3,7 +3,6 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Threading; -using DiscordRPC; using LibHac.Common; using LibHac.Ns; using LibHac.Tools.FsSystem; @@ -20,20 +19,15 @@ using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Renderer; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; -using Ryujinx.Ava.Utilities; -using Ryujinx.Ava.Utilities.AppLibrary; -using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; using Ryujinx.Common.SystemInterop; -using Ryujinx.Common.UI; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.Gpu; -using Ryujinx.Graphics.Metal; using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; @@ -43,6 +37,11 @@ using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.SystemState; using Ryujinx.Input; using Ryujinx.Input.HLE; +using Ryujinx.UI.App.Common; +using Ryujinx.UI.Common; +using Ryujinx.UI.Common.Configuration; +using Ryujinx.UI.Common.Helper; +using Silk.NET.Vulkan; using SkiaSharp; using SPB.Graphics.Vulkan; using System; @@ -239,10 +238,10 @@ namespace Ryujinx.Ava _lastCursorMoveTime = Stopwatch.GetTimestamp(); } - Point point = e.GetCurrentPoint(window).Position; - Rect bounds = RendererHost.EmbeddedWindow.Bounds; - double windowYOffset = bounds.Y + window.MenuBarHeight; - double windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; + var point = e.GetCurrentPoint(window).Position; + var bounds = RendererHost.EmbeddedWindow.Bounds; + var windowYOffset = bounds.Y + window.MenuBarHeight; + var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; if (!_viewModel.ShowMenuAndStatusBar) { @@ -266,10 +265,10 @@ namespace Ryujinx.Ava if (sender is MainWindow window) { - Point point = e.GetCurrentPoint(window).Position; - Rect bounds = RendererHost.EmbeddedWindow.Bounds; - double windowYOffset = bounds.Y + window.MenuBarHeight; - double windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; + var point = e.GetCurrentPoint(window).Position; + var bounds = RendererHost.EmbeddedWindow.Bounds; + var windowYOffset = bounds.Y + window.MenuBarHeight; + var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; if (!_viewModel.ShowMenuAndStatusBar) { @@ -288,19 +287,19 @@ namespace Ryujinx.Ava private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); - _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); + _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); + _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); } private void UpdateScalingFilter(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); - _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); + _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); + _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); } private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough); + _renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value); } public void UpdateVSyncMode(object sender, ReactiveEventArgs e) @@ -310,21 +309,39 @@ namespace Ryujinx.Ava Device.VSyncMode = e.NewValue; Device.UpdateVSyncInterval(); } - - _renderer.Window?.ChangeVSyncMode(e.NewValue); + _renderer.Window?.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)e.NewValue); - _viewModel.UpdateVSyncIntervalPicker(); + _viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom); } public void VSyncModeToggle() { VSyncMode oldVSyncMode = Device.VSyncMode; + VSyncMode newVSyncMode = VSyncMode.Switch; bool customVSyncIntervalEnabled = ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Value; - UpdateVSyncMode(this, new ReactiveEventArgs( - oldVSyncMode, - oldVSyncMode.Next(customVSyncIntervalEnabled)) - ); + switch (oldVSyncMode) + { + case VSyncMode.Switch: + newVSyncMode = VSyncMode.Unbounded; + break; + case VSyncMode.Unbounded: + if (customVSyncIntervalEnabled) + { + newVSyncMode = VSyncMode.Custom; + } + else + { + newVSyncMode = VSyncMode.Switch; + } + + break; + case VSyncMode.Custom: + newVSyncMode = VSyncMode.Switch; + break; + } + + UpdateVSyncMode(this, new ReactiveEventArgs(oldVSyncMode, newVSyncMode)); } private void UpdateCustomVSyncIntervalValue(object sender, ReactiveEventArgs e) @@ -417,7 +434,7 @@ namespace Ryujinx.Ava return; } - SKColorType colorType = e.IsBgra ? SKColorType.Bgra8888 : SKColorType.Rgba8888; + var colorType = e.IsBgra ? SKColorType.Bgra8888 : SKColorType.Rgba8888; using SKBitmap bitmap = new(new SKImageInfo(e.Width, e.Height, colorType, SKAlphaType.Premul)); Marshal.Copy(e.Data, 0, bitmap.GetPixels(), e.Data.Length); @@ -430,7 +447,7 @@ namespace Ryujinx.Ava float scaleX = e.FlipX ? -1 : 1; float scaleY = e.FlipY ? -1 : 1; - SKMatrix matrix = SKMatrix.CreateScale(scaleX, scaleY, bitmap.Width / 2f, bitmap.Height / 2f); + var matrix = SKMatrix.CreateScale(scaleX, scaleY, bitmap.Width / 2f, bitmap.Height / 2f); canvas.SetMatrix(matrix); canvas.DrawBitmap(bitmap, SKPoint.Empty); @@ -449,8 +466,8 @@ namespace Ryujinx.Ava private static void SaveBitmapAsPng(SKBitmap bitmap, string path) { - using SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100); - using FileStream stream = File.OpenWrite(path); + using var data = bitmap.Encode(SKEncodedImageFormat.Png, 100); + using var stream = File.OpenWrite(path); data.SaveTo(stream); } @@ -471,7 +488,7 @@ namespace Ryujinx.Ava Dispatcher.UIThread.InvokeAsync(() => { - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version); }); _viewModel.SetUiProgressHandlers(Device); @@ -483,8 +500,6 @@ namespace Ryujinx.Ava _renderingThread.Start(); _viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value; - - Rainbow.Enable(); MainLoop(); @@ -509,7 +524,7 @@ namespace Ryujinx.Ava private void UpdateAntiAliasing(object sender, ReactiveEventArgs e) { - _renderer?.Window?.SetAntiAliasing(e.NewValue); + _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)e.NewValue); } private void UpdateDockedModeState(object sender, ReactiveEventArgs e) @@ -517,7 +532,7 @@ namespace Ryujinx.Ava Device?.System.ChangeDockedModeState(e.NewValue); } - public void UpdateAudioVolumeState(object sender, ReactiveEventArgs e) + private void UpdateAudioVolumeState(object sender, ReactiveEventArgs e) { Device?.SetVolume(e.NewValue); @@ -560,6 +575,7 @@ namespace Ryujinx.Ava public void Stop() { _isActive = false; + DiscordIntegrationModule.SwitchToMainState(); } private void Exit() @@ -571,17 +587,6 @@ namespace Ryujinx.Ava return; } - foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) - { - gamepad?.ClearLed(); - gamepad?.Dispose(); - } - - DiscordIntegrationModule.GuestAppStartedAt = null; - - Rainbow.Disable(); - Rainbow.Reset(); - _isStopped = true; Stop(); } @@ -669,9 +674,7 @@ namespace Ryujinx.Ava public async Task LoadGuestApplication(BlitStruct? customNacpData = null) { - DiscordIntegrationModule.GuestAppStartedAt = Timestamps.Now; - - InitEmulatedSwitch(); + InitializeSwitchInstance(); MainWindow.UpdateGraphicsConfig(); SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); @@ -754,8 +757,6 @@ namespace Ryujinx.Ava { romFsFiles = Directory.GetFiles(ApplicationPath, "*.romfs"); } - - Logger.Notice.Print(LogClass.Application, $"Loading unpacked content archive from '{ApplicationPath}'."); if (romFsFiles.Length > 0) { @@ -782,8 +783,6 @@ namespace Ryujinx.Ava } else if (File.Exists(ApplicationPath)) { - Logger.Notice.Print(LogClass.Application, $"Loading content archive from '{ApplicationPath}'."); - switch (Path.GetExtension(ApplicationPath).ToLowerInvariant()) { case ".xci": @@ -860,11 +859,13 @@ namespace Ryujinx.Ava return false; } - - ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, + + ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => appMetadata.UpdatePreGame() ); + DiscordIntegrationModule.SwitchToPlayingState(appMeta, Device.Processes.ActiveApplication); + return true; } @@ -873,7 +874,7 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(false); _viewModel.IsPaused = false; - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version); Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } @@ -882,34 +883,26 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(true); _viewModel.IsPaused = true; - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar, LocaleManager.Instance[LocaleKeys.Paused]); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, LocaleManager.Instance[LocaleKeys.Paused]); Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } - private void InitEmulatedSwitch() + private void InitializeSwitchInstance() { // Initialize KeySet. VirtualFileSystem.ReloadKeySet(); // Initialize Renderer. - GraphicsBackend backend = TitleIDs.SelectGraphicsBackend(ApplicationId.ToString("X16"), ConfigurationState.Instance.Graphics.GraphicsBackend); - - IRenderer renderer = backend switch - { -#pragma warning disable CA1416 // This call site is reachable on all platforms - // SelectGraphicsBackend does a check for Mac, on top of checking if it's an ARM Mac. This isn't a problem. - GraphicsBackend.Metal => new MetalRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowMetal)!.CreateSurface), -#pragma warning restore CA1416 - GraphicsBackend.Vulkan => VulkanRenderer.Create( + IRenderer renderer = ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl + ? new OpenGLRenderer() + : VulkanRenderer.Create( ConfigurationState.Instance.Graphics.PreferredGpu, (RendererHost.EmbeddedWindow as EmbeddedWindowVulkan)!.CreateSurface, - VulkanHelper.GetRequiredInstanceExtensions), - _ => new OpenGLRenderer() - }; + VulkanHelper.GetRequiredInstanceExtensions); BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading; - bool isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); + var isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); if (isGALThreaded) { renderer = new ThreadedRenderer(renderer); @@ -918,9 +911,9 @@ namespace Ryujinx.Ava Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}"); // Initialize Configuration. - MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; + var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; - Device = new Switch(new HLEConfiguration( + Device = new HLE.Switch(new HLEConfiguration( VirtualFileSystem, _viewModel.LibHacHorizonManager, ContentManager, @@ -938,9 +931,7 @@ namespace Ryujinx.Ava ConfigurationState.Instance.System.EnableInternetAccess, ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, ConfigurationState.Instance.System.FsGlobalAccessLogMode, - ConfigurationState.Instance.System.MatchSystemTime - ? 0 - : ConfigurationState.Instance.System.SystemTimeOffset, + ConfigurationState.Instance.System.SystemTimeOffset, ConfigurationState.Instance.System.TimeZone, ConfigurationState.Instance.System.MemoryManagerMode, ConfigurationState.Instance.System.IgnoreMissingServices, @@ -951,20 +942,19 @@ namespace Ryujinx.Ava ConfigurationState.Instance.Multiplayer.Mode, ConfigurationState.Instance.Multiplayer.DisableP2p, ConfigurationState.Instance.Multiplayer.LdnPassphrase, - ConfigurationState.Instance.Multiplayer.GetLdnServer(), - ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value, - ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null)); + ConfigurationState.Instance.Multiplayer.LdnServer, + ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value)); } private static IHardwareDeviceDriver InitializeAudio() { - List availableBackends = - [ + var availableBackends = new List + { AudioBackend.SDL2, AudioBackend.SoundIo, AudioBackend.OpenAl, - AudioBackend.Dummy - ]; + AudioBackend.Dummy, + }; AudioBackend preferredBackend = ConfigurationState.Instance.System.AudioBackend.Value; @@ -1041,10 +1031,9 @@ namespace Ryujinx.Ava if (_viewModel.StartGamesInFullscreen) { _viewModel.WindowState = WindowState.FullScreen; - _viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true; } - if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI) + if (_viewModel.WindowState is WindowState.FullScreen) { _viewModel.ShowMenuAndStatusBar = false; } @@ -1058,10 +1047,10 @@ namespace Ryujinx.Ava Device.Gpu.Renderer.Initialize(_glLogLevel); - _renderer?.Window?.SetAntiAliasing(ConfigurationState.Instance.Graphics.AntiAliasing); - _renderer?.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); - _renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); - _renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough); + _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)ConfigurationState.Instance.Graphics.AntiAliasing.Value); + _renderer?.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); + _renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); + _renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value); Width = (int)RendererHost.Bounds.Width; Height = (int)RendererHost.Bounds.Height; @@ -1075,7 +1064,7 @@ namespace Ryujinx.Ava Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - _renderer.Window.ChangeVSyncMode(Device.VSyncMode); + _renderer.Window.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)Device.VSyncMode); while (_isActive) { @@ -1122,11 +1111,10 @@ namespace Ryujinx.Ava public void InitStatus() { - _viewModel.BackendText = RendererHost.Backend switch + _viewModel.BackendText = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch { GraphicsBackend.Vulkan => "Vulkan", GraphicsBackend.OpenGl => "OpenGL", - GraphicsBackend.Metal => "Metal", _ => throw new NotImplementedException() }; @@ -1151,8 +1139,8 @@ namespace Ryujinx.Ava LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%", dockedMode, ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), - Device.Statistics.FormatGameFrameRate(), - Device.Statistics.FormatFifoPercent(), + $"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", + $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %", _displayCount)); } diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index a48e294b9..2e86df0aa 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -14,7 +14,6 @@ "pl_PL", "pt_BR", "ru_RU", - "sv_SE", "th_TH", "tr_TR", "uk_UA", @@ -39,7 +38,6 @@ "pl_PL": "Polski", "pt_BR": "Português (BR)", "ru_RU": "Русский (RU)", - "sv_SE": "Svenska", "th_TH": "ภาษาไทย", "tr_TR": "Türkçe", "uk_UA": "Українська", @@ -64,7 +62,6 @@ "pl_PL": "Otwórz Aplet", "pt_BR": "Abrir Applet", "ru_RU": "Открыть апплет", - "sv_SE": "Öppna applet", "th_TH": "เปิด Applet", "tr_TR": "Applet'i Aç", "uk_UA": "Відкрити аплет", @@ -76,25 +73,24 @@ "ID": "MenuBarFileOpenAppletOpenMiiApplet", "Translations": { "ar_SA": "", - "de_DE": "Mii-Bearbeitungsapplet", + "de_DE": "", "el_GR": "", "en_US": "Mii Edit Applet", "es_ES": "Applet Editor Mii", "fr_FR": "Éditeur de Mii", "he_IL": "", - "it_IT": "Applet Editor Mii", + "it_IT": "", "ja_JP": "", "ko_KR": "Mii 편집 애플릿", "no_NO": "Mii-redigeringsapplet", "pl_PL": "", - "pt_BR": "Editor de Mii", - "ru_RU": "Апплет Mii Editor", - "sv_SE": "Redigera Mii-applet", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Аплет редагування Mii", - "zh_CN": "Mii 小程序", - "zh_TW": "Mii 編輯器小程式" + "uk_UA": "Аплет для редагування Mii", + "zh_CN": "", + "zh_TW": "" } }, { @@ -107,14 +103,13 @@ "es_ES": "Abre el editor de Mii en modo autónomo", "fr_FR": "Ouvrir l'éditeur Mii en mode Standalone", "he_IL": "פתח את יישומון עורך ה- Mii במצב עצמאי", - "it_IT": "Apri l'applet Editor Mii in modalità Standalone", + "it_IT": "Apri l'applet Mii Editor in modalità Standalone", "ja_JP": "スタンドアロンモードで Mii エディタアプレットを開きます", "ko_KR": "독립 실행형 모드로 Mii 편집기 애플릿 열기", "no_NO": "Åpne Mii Redigerings program i eget vindu", "pl_PL": "Otwórz aplet Mii Editor w trybie indywidualnym", - "pt_BR": "Abrir Editor de Mii em Modo Independente", + "pt_BR": "Abrir editor Mii em modo avulso", "ru_RU": "Открывает апплет Mii Editor в автономном режиме", - "sv_SE": "Öppna Mii Editor Applet i fristående läge", "th_TH": "เปิดโปรแกรม Mii Editor Applet", "tr_TR": "Mii Editör Applet'ini Bağımsız Mod'da Aç", "uk_UA": "Відкрити аплет Mii Editor в автономному режимі", @@ -137,12 +132,11 @@ "ko_KR": "마우스 직접 접근", "no_NO": "Direkte tilgang med Mus", "pl_PL": "Bezpośredni dostęp do myszy", - "pt_BR": "Acesso Direto ao Mouse", + "pt_BR": "Acesso direto ao mouse", "ru_RU": "Прямой ввод мыши", - "sv_SE": "Direkt musåtkomst", "th_TH": "เข้าถึงเมาส์ได้โดยตรง", "tr_TR": "Doğrudan Mouse Erişimi", - "uk_UA": "Пряме керування мишею", + "uk_UA": "Прямий доступ мишею", "zh_CN": "直通鼠标操作", "zh_TW": "滑鼠直接存取" } @@ -162,9 +156,8 @@ "ko_KR": "메모리 관리자 모드 :", "no_NO": "Memory Manager-modus", "pl_PL": "Tryb menedżera pamięci:", - "pt_BR": "Modo de Gerenciamento da Memória:", + "pt_BR": "Modo de gerenciamento de memória:", "ru_RU": "Режим менеджера памяти:", - "sv_SE": "Läge för minnehanterare:", "th_TH": "โหมดจัดการหน่วยความจำ:", "tr_TR": "Hafıza Yönetim Modu:", "uk_UA": "Режим диспетчера пам’яті:", @@ -176,7 +169,7 @@ "ID": "SettingsTabSystemMemoryManagerModeSoftware", "Translations": { "ar_SA": "البرنامج", - "de_DE": "Programme", + "de_DE": "", "el_GR": "Λογισμικό", "en_US": "Software", "es_ES": "", @@ -189,7 +182,6 @@ "pl_PL": "Oprogramowanie", "pt_BR": "", "ru_RU": "Программное обеспечение", - "sv_SE": "Programvara", "th_TH": "ซอฟต์แวร์", "tr_TR": "Yazılım", "uk_UA": "Програмне забезпечення", @@ -214,7 +206,6 @@ "pl_PL": "Gospodarz (szybki)", "pt_BR": "Hóspede (rápido)", "ru_RU": "Хост (быстро)", - "sv_SE": "Värd (snabb)", "th_TH": "โฮสต์ (เร็ว)", "tr_TR": "Host (hızlı)", "uk_UA": "Хост (швидко)", @@ -237,9 +228,8 @@ "ko_KR": "호스트 확인 안함(가장 빠르나 위험)", "no_NO": "Vert Ukontrollert (raskets, utrygt)", "pl_PL": "Gospodarza (NIESPRAWDZONY, najszybszy, niebezpieczne)", - "pt_BR": "Hóspede sem Verificação (mais rápido, inseguro)", + "pt_BR": "Hóspede sem verificação (mais rápido, inseguro)", "ru_RU": "Хост не установлен (самый быстрый, небезопасный)", - "sv_SE": "Värd inte kontrollerad (snabbaste, osäkert)", "th_TH": "ไม่ได้ตรวจสอบโฮสต์ (เร็วที่สุด, แต่ไม่ปลอดภัย)", "tr_TR": "Host Unchecked (en hızlısı, tehlikeli)", "uk_UA": "Неперевірений хост (найшвидший, небезпечний)", @@ -264,7 +254,6 @@ "pl_PL": "Użyj Hipernadzorcy", "pt_BR": "Usar Hipervisor", "ru_RU": "Использовать Hypervisor", - "sv_SE": "Använd Hypervisor", "th_TH": "ใช้งาน Hypervisor", "tr_TR": "Hypervisor Kullan", "uk_UA": "Використовувати гіпервізор", @@ -289,7 +278,6 @@ "pl_PL": "_Plik", "pt_BR": "_Arquivo", "ru_RU": "_Файл", - "sv_SE": "_Arkiv", "th_TH": "ไฟล์", "tr_TR": "_Dosya", "uk_UA": "_Файл", @@ -312,9 +300,8 @@ "ko_KR": "파일에서 앱 불러오기(_L)", "no_NO": "_Last inn program fra fil", "pl_PL": "_Załaduj aplikację z pliku", - "pt_BR": "_Abrir ROM do Jogo", + "pt_BR": "_Abrir ROM do jogo...", "ru_RU": "_Добавить приложение из файла", - "sv_SE": "_Läs in applikation från fil", "th_TH": "โหลดแอปพลิเคชั่นจากไฟล์", "tr_TR": "_Dosyadan Uygulama Aç", "uk_UA": "_Завантажити програму з файлу", @@ -326,20 +313,19 @@ "ID": "MenuBarFileOpenFromFileError", "Translations": { "ar_SA": "", - "de_DE": "Keine Anwendungen im ausgewählten Datei gefunden.", + "de_DE": "", "el_GR": "", "en_US": "No applications found in selected file.", "es_ES": "No se encontraron aplicaciones en el archivo seleccionado.", "fr_FR": "Aucun jeu trouvé dans le fichier sélectionné", "he_IL": "", - "it_IT": "Nessuna applicazione trovata nel file selezionato.", + "it_IT": "Nessuna applicazione trovata nel file selezionato", "ja_JP": "", "ko_KR": "선택한 파일에서 앱을 찾을 수 없습니다.", "no_NO": "Ingen apper ble funnet i valgt fil.", "pl_PL": "", "pt_BR": "Nenhum aplicativo encontrado no arquivo selecionado.", - "ru_RU": "Приложения в выбранном файле не найдены", - "sv_SE": "Inga applikationer hittades i vald fil.", + "ru_RU": "", "th_TH": "ไม่พบแอปพลิเคชั่นจากไฟล์ที่เลือก", "tr_TR": "", "uk_UA": "У вибраному файлі не знайдено жодних додатків.", @@ -362,9 +348,8 @@ "ko_KR": "압축 푼 게임 불러오기(_U)", "no_NO": "Last inn _Upakket spill", "pl_PL": "Załaduj _rozpakowaną grę", - "pt_BR": "Abrir Jogo _Extraído", + "pt_BR": "Abrir jogo _extraído...", "ru_RU": "Добавить _распакованную игру", - "sv_SE": "Läs in _uppackat spel", "th_TH": "โหลดเกมที่แตกไฟล์แล้ว", "tr_TR": "_Sıkıştırılmamış Oyun Aç", "uk_UA": "Завантажити _розпаковану гру", @@ -376,24 +361,23 @@ "ID": "MenuBarFileLoadDlcFromFolder", "Translations": { "ar_SA": "", - "de_DE": "DLC aus Ordner laden", + "de_DE": "", "el_GR": "", "en_US": "Load DLC From Folder", "es_ES": "Cargar DLC Desde Carpeta", "fr_FR": "Charger les DLC depuis le dossier des DLC", "he_IL": "", - "it_IT": "Carica DLC da una cartella", + "it_IT": "Carica DLC Da una Cartella", "ja_JP": "", "ko_KR": "폴더에서 DLC 불러오기", "no_NO": "Last inn DLC fra mappe", "pl_PL": "", "pt_BR": "Carregar DLC da Pasta", - "ru_RU": "Загрузить DLC из папки", - "sv_SE": "Läs in DLC från mapp", + "ru_RU": "", "th_TH": "โหลด DLC จากโฟลเดอร์", "tr_TR": "", "uk_UA": "Завантажити DLC з теки", - "zh_CN": "从文件夹加载 DLC", + "zh_CN": "从文件夹加载DLC", "zh_TW": "從資料夾中載入 DLC" } }, @@ -401,23 +385,22 @@ "ID": "MenuBarFileLoadTitleUpdatesFromFolder", "Translations": { "ar_SA": "", - "de_DE": "Titel-Updates aus Ordner laden", + "de_DE": "", "el_GR": "", "en_US": "Load Title Updates From Folder", "es_ES": "Cargar Actualizaciones de Títulos Desde Carpeta", "fr_FR": "Charger les mises à jour depuis le dossier des mises à jour", "he_IL": "", - "it_IT": "Carica aggiornamenti da una cartella", + "it_IT": "Carica Aggiornamenti Da una Cartella", "ja_JP": "", "ko_KR": "폴더에서 타이틀 업데이트 불러오기", "no_NO": "Last inn titteloppdateringer fra mappe", "pl_PL": "", "pt_BR": "Carregar Atualizações de Jogo da Pasta", - "ru_RU": "Загрузить обновления из папки", - "sv_SE": "Läs in titeluppdateringar från mapp", + "ru_RU": "", "th_TH": "โหลดไฟล์อัพเดตจากโฟลเดอร์", "tr_TR": "", - "uk_UA": "Завантажити оновлення ігор з теки", + "uk_UA": "Завантажити оновлення заголовків з теки", "zh_CN": "从文件夹加载游戏更新", "zh_TW": "從資料夾中載入遊戲更新" } @@ -437,9 +420,8 @@ "ko_KR": "Ryujinx 폴더 열기", "no_NO": "Åpne Ryujinx mappe", "pl_PL": "Otwórz folder Ryujinx", - "pt_BR": "Abrir Pasta do Ryujinx", + "pt_BR": "Abrir diretório do e_mulador...", "ru_RU": "Открыть папку Ryujinx", - "sv_SE": "Öppna Ryujinx-mapp", "th_TH": "เปิดโฟลเดอร์ Ryujinx", "tr_TR": "Ryujinx Klasörünü aç", "uk_UA": "Відкрити теку Ryujinx", @@ -447,31 +429,6 @@ "zh_TW": "開啟 Ryujinx 資料夾" } }, - { - "ID": "MenuBarFileOpenScreenshotsFolder", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Open Screenshots Folder", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "Abrir Pasta de Capturas de Tela", - "ru_RU": "Открыть папку со скриншотами", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Відкрити теку скріншотів", - "zh_CN": "", - "zh_TW": "" - } - }, { "ID": "MenuBarFileOpenLogsFolder", "Translations": { @@ -487,9 +444,8 @@ "ko_KR": "로그 폴더 열기", "no_NO": "Åpne Logg mappen", "pl_PL": "Otwórz folder plików dziennika zdarzeń", - "pt_BR": "Abrir Pasta de _Logs", + "pt_BR": "Abrir diretório de _logs...", "ru_RU": "Открыть папку с логами", - "sv_SE": "Öppna loggmapp", "th_TH": "เปิดโฟลเดอร์ Logs", "tr_TR": "Logs Klasörünü aç", "uk_UA": "Відкрити теку журналів змін", @@ -514,7 +470,6 @@ "pl_PL": "_Wyjdź", "pt_BR": "_Sair", "ru_RU": "_Выход", - "sv_SE": "A_vsluta", "th_TH": "_ออก", "tr_TR": "_Çıkış", "uk_UA": "_Вихід", @@ -539,7 +494,6 @@ "pl_PL": "_Opcje", "pt_BR": "_Opções", "ru_RU": "_Настройки", - "sv_SE": "I_nställningar", "th_TH": "_ตัวเลือก", "tr_TR": "_Seçenekler", "uk_UA": "_Параметри", @@ -562,9 +516,8 @@ "ko_KR": "전체 화면 전환", "no_NO": "Fullskjermsvisning av/på", "pl_PL": "Przełącz na tryb pełnoekranowy", - "pt_BR": "_Mudar para Tela Cheia", + "pt_BR": "_Mudar para tela cheia", "ru_RU": "Включить полноэкранный режим", - "sv_SE": "Växla helskärm", "th_TH": "สลับเป็นโหมดเต็มหน้าจอ", "tr_TR": "Tam Ekran Modunu Aç", "uk_UA": "На весь екран", @@ -587,9 +540,8 @@ "ko_KR": "전체 화면 모드로 게임 시작", "no_NO": "Start spill i Fullskjermmodus", "pl_PL": "Uruchamiaj gry w trybie pełnoekranowym", - "pt_BR": "Iniciar Jogos em Tela Cheia", + "pt_BR": "Iniciar jogos em tela cheia", "ru_RU": "Запускать игры в полноэкранном режиме", - "sv_SE": "Starta spel i helskärmsläge", "th_TH": "เริ่มเกมในโหมดเต็มหน้าจอ", "tr_TR": "Oyunları Tam Ekran Modunda Başlat", "uk_UA": "Запускати ігри на весь екран", @@ -597,31 +549,6 @@ "zh_TW": "使用全螢幕模式啟動遊戲" } }, - { - "ID": "MenuBarOptionsStartGamesWithoutUI", - "Translations": { - "ar_SA": "", - "de_DE": "Spiele ohne Benutzeroberfläche starten", - "el_GR": "", - "en_US": "Start Games with UI Hidden", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "UI를 숨긴 상태에서 게임 시작", - "no_NO": "Start Spillet med UI Gjemt", - "pl_PL": "", - "pt_BR": "Iniciar Jogos Ocultando a Interface", - "ru_RU": "Запускать игры скрывая интерфейс", - "sv_SE": "Starta spel med dolt användargränssnitt", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускати ігри з прихованим інтерфейсом", - "zh_CN": "启动游戏时隐藏 UI", - "zh_TW": "" - } - }, { "ID": "MenuBarOptionsStopEmulation", "Translations": { @@ -637,9 +564,8 @@ "ko_KR": "에뮬레이션 중지", "no_NO": "Stopp Emulering", "pl_PL": "Zatrzymaj emulację", - "pt_BR": "_Parar a Emulação", + "pt_BR": "_Encerrar emulação", "ru_RU": "Остановить эмуляцию", - "sv_SE": "Stoppa emulering", "th_TH": "หยุดการจำลอง", "tr_TR": "Emülasyonu Durdur", "uk_UA": "Зупинити емуляцію", @@ -664,7 +590,6 @@ "pl_PL": "_Ustawienia", "pt_BR": "_Configurações", "ru_RU": "_Параметры", - "sv_SE": "_Inställningar", "th_TH": "_ตั้งค่า", "tr_TR": "_Seçenekler", "uk_UA": "_Налаштування", @@ -687,9 +612,8 @@ "ko_KR": "사용자 프로필 관리(_M)", "no_NO": "_Administrere Brukerprofiler", "pl_PL": "_Zarządzaj profilami użytkowników", - "pt_BR": "_Gerenciar Perfis de Usuário", - "ru_RU": "_Менеджер учётных записей", - "sv_SE": "_Hantera användarprofiler", + "pt_BR": "_Gerenciar perfis de usuário", + "ru_RU": "_Менеджер учетных записей", "th_TH": "_จัดการโปรไฟล์ผู้ใช้งาน", "tr_TR": "_Kullanıcı Profillerini Yönet", "uk_UA": "_Керувати профілями користувачів", @@ -714,7 +638,6 @@ "pl_PL": "_Akcje", "pt_BR": "_Ações", "ru_RU": "_Действия", - "sv_SE": "Åt_gärder", "th_TH": "การดำเนินการ", "tr_TR": "_Eylemler", "uk_UA": "_Дії", @@ -737,9 +660,8 @@ "ko_KR": "웨이크업 메시지 시뮬레이션", "no_NO": "Simuler oppvåknings-melding", "pl_PL": "Symuluj wiadomość wybudzania", - "pt_BR": "_Simular Mensagem de Acordar o Console", + "pt_BR": "_Simular mensagem de acordar console", "ru_RU": "Имитировать сообщение пробуждения", - "sv_SE": "Simulera uppvakningsmeddelande", "th_TH": "จำลองข้อความปลุก", "tr_TR": "Uyandırma Mesajı Simüle Et", "uk_UA": "Симулювати повідомлення про пробудження", @@ -764,7 +686,6 @@ "pl_PL": "Skanuj Amiibo", "pt_BR": "Escanear um Amiibo", "ru_RU": "Сканировать Amiibo", - "sv_SE": "Skanna en Amiibo", "th_TH": "สแกนหา Amiibo", "tr_TR": "Bir Amiibo Tara", "uk_UA": "Сканувати Amiibo", @@ -776,29 +697,52 @@ "ID": "MenuBarActionsScanAmiiboBin", "Translations": { "ar_SA": "", - "de_DE": "Amiibo scannen (aus Bin-Datei)", + "de_DE": "", "el_GR": "", "en_US": "Scan An Amiibo (From Bin)", "es_ES": "", "fr_FR": "Scanner un Amiibo (à partir d'un .bin)", "he_IL": "", - "it_IT": "Scansiona un Amiibo (da file .bin)", + "it_IT": "", "ja_JP": "", "ko_KR": "Amiibo 스캔(빈에서)", "no_NO": "Skann en Amiibo (fra bin fil)", "pl_PL": "", - "pt_BR": "Escaneie um Amiibo (de um .bin)", - "ru_RU": "Сканировать Amiibo (из папки Bin)", - "sv_SE": "Skanna en Amiibo (från bin-fil)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Сканувати Amiibo (з теки Bin)", - "zh_CN": "扫描 Amiibo (从 bin 文件)", - "zh_TW": "掃瞄 Amiibo (從 Bin 檔案)" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { - "ID": "MenuBarActionsInstallFirmware", + "ID": "MenuBarTools", + "Translations": { + "ar_SA": "_الأدوات", + "de_DE": "", + "el_GR": "_Εργαλεία", + "en_US": "_Tools", + "es_ES": "_Herramientas", + "fr_FR": "_Outils", + "he_IL": "_כלים", + "it_IT": "_Strumenti", + "ja_JP": "ツール(_T)", + "ko_KR": "도구(_T)", + "no_NO": "_Verktøy", + "pl_PL": "_Narzędzia", + "pt_BR": "_Ferramentas", + "ru_RU": "_Инструменты", + "th_TH": "_เครื่องมือ", + "tr_TR": "_Araçlar", + "uk_UA": "_Інструменти", + "zh_CN": "工具(_T)", + "zh_TW": "工具(_T)" + } + }, + { + "ID": "MenuBarToolsInstallFirmware", "Translations": { "ar_SA": "تثبيت البرنامج الثابت", "de_DE": "Firmware installieren", @@ -812,18 +756,17 @@ "ko_KR": "펌웨어 설치", "no_NO": "Installer fastvare", "pl_PL": "Zainstaluj oprogramowanie", - "pt_BR": "_Instalar Firmware", + "pt_BR": "_Instalar firmware", "ru_RU": "Установка прошивки", - "sv_SE": "Installera firmware", "th_TH": "ติดตั้งเฟิร์มแวร์", "tr_TR": "Yazılım Yükle", - "uk_UA": "Встановити прошивку (Firmware)", + "uk_UA": "Установити прошивку", "zh_CN": "安装系统固件", "zh_TW": "安裝韌體" } }, { - "ID": "MenuBarActionsInstallFirmwareFromFile", + "ID": "MenuBarFileToolsInstallFirmwareFromFile", "Translations": { "ar_SA": "تثبيت برنامج ثابت من XCI أو ZIP", "de_DE": "Firmware von einer XCI- oder einer ZIP-Datei installieren", @@ -839,16 +782,15 @@ "pl_PL": "Zainstaluj oprogramowanie z XCI lub ZIP", "pt_BR": "Instalar firmware a partir de um arquivo ZIP/XCI", "ru_RU": "Установить прошивку из XCI или ZIP", - "sv_SE": "Installera en firmware från XCI eller ZIP", "th_TH": "ติดตั้งเฟิร์มแวร์จาก ไฟล์ XCI หรือ ไฟล์ ZIP", "tr_TR": "XCI veya ZIP'ten Yazılım Yükle", - "uk_UA": "Встановити прошивку з XCI або ZIP", - "zh_CN": "从 XCI 或 ZIP 文件安装系统固件", + "uk_UA": "Установити прошивку з XCI або ZIP", + "zh_CN": "从 XCI 或 ZIP 文件中安装系统固件", "zh_TW": "從 XCI 或 ZIP 安裝韌體" } }, { - "ID": "MenuBarActionsInstallFirmwareFromDirectory", + "ID": "MenuBarFileToolsInstallFirmwareFromDirectory", "Translations": { "ar_SA": "تثبيت برنامج ثابت من مجلد", "de_DE": "Firmware aus einem Verzeichnis installieren", @@ -857,98 +799,94 @@ "es_ES": "Instalar firmware desde una carpeta", "fr_FR": "Installer un firmware depuis un dossier", "he_IL": "התקן קושחה מתוך תקייה", - "it_IT": "Installa un firmware da una cartella", + "it_IT": "Installa un firmare da una cartella", "ja_JP": "ディレクトリからファームウェアをインストール", "ko_KR": "디렉터리에서 펌웨어 설치", "no_NO": "Installer en fastvare fra en mappe", "pl_PL": "Zainstaluj oprogramowanie z katalogu", "pt_BR": "Instalar firmware a partir de um diretório", "ru_RU": "Установить прошивку из папки", - "sv_SE": "Installera en firmware från en katalog", "th_TH": "ติดตั้งเฟิร์มแวร์จากไดเร็กทอรี", "tr_TR": "Bir Dizin Üzerinden Yazılım Yükle", - "uk_UA": "Встановити прошивку з теки", - "zh_CN": "从文件夹安装系统固件", + "uk_UA": "Установити прошивку з теки", + "zh_CN": "从文件夹中安装系统固件", "zh_TW": "從資料夾安裝韌體" } }, { - "ID": "MenuBarActionsInstallKeys", + "ID": "MenuBarToolsInstallKeys", "Translations": { "ar_SA": "", - "de_DE": "Schlüssel installieren", + "de_DE": "", "el_GR": "", "en_US": "Install Keys", "es_ES": "", "fr_FR": "Installer des clés", "he_IL": "", - "it_IT": "Installa chiavi", + "it_IT": "Installa Chiavi", "ja_JP": "", "ko_KR": "설치 키", "no_NO": "Installere nøkler", "pl_PL": "", - "pt_BR": "Instalar Chaves", - "ru_RU": "Установить ключи", - "sv_SE": "Installera nycklar", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Встановити ключі", - "zh_CN": "安装密匙", - "zh_TW": "安裝金鑰" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { - "ID": "MenuBarFileActionsInstallKeysFromFile", + "ID": "MenuBarFileToolsInstallKeysFromFile", "Translations": { "ar_SA": "", - "de_DE": "Schlüssel aus KEYS oder ZIP installieren", + "de_DE": "", "el_GR": "", "en_US": "Install keys from KEYS or ZIP", "es_ES": "Instalar keys de KEYS o ZIP", "fr_FR": "Installer des clés à partir de .KEYS or .ZIP", "he_IL": "", - "it_IT": "Installa chiavi da file KEYS o ZIP", + "it_IT": "Installa Chiavi da file KEYS o ZIP", "ja_JP": "", "ko_KR": "키나 ZIP에서 키 설치", "no_NO": "Installer nøkler fra KEYS eller ZIP", "pl_PL": "", - "pt_BR": "Instalar chaves de CHAVES ou ZIP", - "ru_RU": "Установить ключи из файла KEYS или ZIP", - "sv_SE": "Installera nycklar från KEYS eller ZIP", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Встановити ключі з файлу .KEYS або .ZIP", - "zh_CN": "从 .KEYS 文件或 .ZIP 压缩包安装密匙", - "zh_TW": "從 .KEYS 或 .ZIP 安裝金鑰" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { - "ID": "MenuBarFileActionsInstallKeysFromFolder", + "ID": "MenuBarFileToolsInstallKeysFromFolder", "Translations": { "ar_SA": "", - "de_DE": "Schlüssel aus einem Verzeichnis installieren", + "de_DE": "", "el_GR": "", "en_US": "Install keys from a directory", "es_ES": "Instalar keys de un directorio", "fr_FR": "Installer des clés à partir d'un dossier", "he_IL": "", - "it_IT": "Installa chiavi da una cartella", + "it_IT": "Installa Chiavi da una Cartella", "ja_JP": "", "ko_KR": "디렉터리에서 키 설치", "no_NO": "Installer nøkler fra en mappe", "pl_PL": "", - "pt_BR": "Instalar chaves de um diretório", - "ru_RU": "Установить ключи из папки", - "sv_SE": "Installera nycklar från en katalog", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Встановити ключі з теки", - "zh_CN": "从一个文件夹安装密匙", - "zh_TW": "從資料夾安裝金鑰" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { - "ID": "MenuBarActionsManageFileTypes", + "ID": "MenuBarToolsManageFileTypes", "Translations": { "ar_SA": "إدارة أنواع الملفات", "de_DE": "Dateitypen verwalten", @@ -962,9 +900,8 @@ "ko_KR": "파일 형식 관리", "no_NO": "Behandle filtyper", "pl_PL": "Zarządzaj rodzajami plików", - "pt_BR": "Gerenciar Tipos de Arquivos", + "pt_BR": "Gerenciar tipos de arquivo", "ru_RU": "Управление типами файлов", - "sv_SE": "Hantera filtyper", "th_TH": "จัดการประเภทไฟล์", "tr_TR": "Dosya uzantılarını yönet", "uk_UA": "Керувати типами файлів", @@ -973,7 +910,7 @@ } }, { - "ID": "MenuBarActionsInstallFileTypes", + "ID": "MenuBarToolsInstallFileTypes", "Translations": { "ar_SA": "تثبيت أنواع الملفات", "de_DE": "Dateitypen installieren", @@ -987,18 +924,17 @@ "ko_KR": "파일 형식 설치", "no_NO": "Installer filtyper", "pl_PL": "Typy plików instalacyjnych", - "pt_BR": "Instalar tipos de arquivos", + "pt_BR": "Instalar tipos de arquivo", "ru_RU": "Установить типы файлов", - "sv_SE": "Installera filtyper", "th_TH": "ติดตั้งประเภทไฟล์", "tr_TR": "Dosya uzantılarını yükle", - "uk_UA": "Встановити типи файлів", + "uk_UA": "Установити типи файлів", "zh_CN": "关联文件扩展名", "zh_TW": "安裝檔案類型" } }, { - "ID": "MenuBarActionsUninstallFileTypes", + "ID": "MenuBarToolsUninstallFileTypes", "Translations": { "ar_SA": "إزالة أنواع الملفات", "de_DE": "Dateitypen deinstallieren", @@ -1014,7 +950,6 @@ "pl_PL": "Typy plików dezinstalacyjnych", "pt_BR": "Desinstalar tipos de arquivos", "ru_RU": "Удалить типы файлов", - "sv_SE": "Avinstallera filtyper", "th_TH": "ถอนการติดตั้งประเภทไฟล์", "tr_TR": "Dosya uzantılarını kaldır", "uk_UA": "Видалити типи файлів", @@ -1023,28 +958,27 @@ } }, { - "ID": "MenuBarActionsXCITrimmer", + "ID": "MenuBarToolsXCITrimmer", "Translations": { "ar_SA": "", - "de_DE": "XCI-Dateien trimmen", + "de_DE": "", "el_GR": "", "en_US": "Trim XCI Files", "es_ES": "Recortar archivos XCI", "fr_FR": "Réduire les fichiers XCI", "he_IL": "", - "it_IT": "Riduci dimensioni dei file XCI", + "it_IT": "", "ja_JP": "", "ko_KR": "XCI 파일 트리머", "no_NO": "Trim XCI-filer", "pl_PL": "", - "pt_BR": "Reduzir Arquivos XCI", - "ru_RU": "Уменьшить размер XCI файлов", - "sv_SE": "Optimera XCI-filer", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізати XCI файли", - "zh_CN": "瘦身 XCI 文件", - "zh_TW": "修剪 XCI 檔案" + "zh_CN": "", + "zh_TW": "" } }, { @@ -1062,9 +996,8 @@ "ko_KR": "보기(_V)", "no_NO": "_Vis", "pl_PL": "", - "pt_BR": "Ver", + "pt_BR": "", "ru_RU": "_Вид", - "sv_SE": "_Visa", "th_TH": "_มุมมอง", "tr_TR": "_Görüntüle", "uk_UA": "_Вид", @@ -1082,14 +1015,13 @@ "es_ES": "Tamaño Ventana", "fr_FR": "Taille de la fenêtre", "he_IL": "", - "it_IT": "Dimensione finestra", + "it_IT": "Dimensione Finestra", "ja_JP": "", "ko_KR": "윈도 창", "no_NO": "Vindu størrelse", "pl_PL": "", - "pt_BR": "Tamanho da Janela", + "pt_BR": "", "ru_RU": "Размер окна", - "sv_SE": "Fönsterstorlek", "th_TH": "ขนาดหน้าต่าง", "tr_TR": "Pencere Boyutu", "uk_UA": "Розмір вікна", @@ -1110,11 +1042,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "720p", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1135,11 +1066,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "1080p", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1164,7 +1094,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1189,7 +1118,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1214,10 +1142,9 @@ "pl_PL": "_Pomoc", "pt_BR": "_Ajuda", "ru_RU": "_Помощь", - "sv_SE": "_Hjälp", "th_TH": "_ช่วยเหลือ", "tr_TR": "_Yardım", - "uk_UA": "_Довідка", + "uk_UA": "_Допомога", "zh_CN": "帮助(_H)", "zh_TW": "說明(_H)" } @@ -1237,9 +1164,8 @@ "ko_KR": "업데이트 확인", "no_NO": "Se etter oppdateringer", "pl_PL": "Sprawdź aktualizacje", - "pt_BR": "_Verificar Atualizações", + "pt_BR": "_Verificar se há atualizações", "ru_RU": "Проверить наличие обновлений", - "sv_SE": "Leta efter uppdateringar", "th_TH": "ตรวจสอบอัปเดต", "tr_TR": "Güncellemeleri Denetle", "uk_UA": "Перевірити оновлення", @@ -1251,175 +1177,168 @@ "ID": "MenuBarHelpFaqAndGuides", "Translations": { "ar_SA": "", - "de_DE": "FAQ & Anleitungen", + "de_DE": "", "el_GR": "", "en_US": "FAQ & Guides", "es_ES": "", "fr_FR": "", "he_IL": "", - "it_IT": "Guide e domande frequenti", + "it_IT": "", "ja_JP": "", - "ko_KR": "자주 묻는 질문(FAQ) 및 안내", - "no_NO": "Vanlige spørsmål og veiledninger", + "ko_KR": "", + "no_NO": "", "pl_PL": "", - "pt_BR": "FAQ & Guias", - "ru_RU": "FAQ и Руководства", - "sv_SE": "Frågor, svar och guider", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "FAQ та посібники", - "zh_CN": "问答与指南", - "zh_TW": "常見問題 (FAQ) 和指南" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpFaq", "Translations": { "ar_SA": "", - "de_DE": "FAQ & Fehlerbehebung Seite", + "de_DE": "", "el_GR": "", "en_US": "FAQ & Troubleshooting Page", "es_ES": "", "fr_FR": "Page de FAQ et de dépannage", "he_IL": "", - "it_IT": "Domande frequenti e risoluzione dei problemi", + "it_IT": "", "ja_JP": "", "ko_KR": "자주 묻는 질문(FAQ) 및 문제해결 페이지", "no_NO": "FAQ- og feilsøkingsside", "pl_PL": "", - "pt_BR": "FAQ e Solução de Problemas", - "ru_RU": "FAQ & Устранение неполадок", - "sv_SE": "Frågor, svar och felsökningssida", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "FAQ та усунення несправностей (eng)", - "zh_CN": "常见问题和问题排除页面", - "zh_TW": "常見問題 (FAQ) 和疑難排解頁面" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpFaqTooltip", "Translations": { "ar_SA": "", - "de_DE": "Öffnet die FAQ- und Fehlerbehebungsseite im offiziellen Ryujinx-Wiki", + "de_DE": "", "el_GR": "", "en_US": "Opens the FAQ and Troubleshooting page on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre la page de FAQ et de dépannage sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "Apre la pagina della wiki ufficiale di Ryujinx relativa alle domande frequenti e alla risoluzione dei problemi", + "it_IT": "", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 자주 묻는 질문(FAQ) 및 문제 해결 페이지 열기", "no_NO": "Åpner FAQ- og feilsøkingssiden på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "Abre a página de FAQ e solução de problemas no wiki oficial do Ryujinx", - "ru_RU": "Открывает страницы с FAQ и Устранением неполадок на официальной странице вики Ryujinx", - "sv_SE": "Öppnar Frågor, svar och felsökningssidan på den officiella Ryujinx-wikin", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Відкриває сторінку з Посібником по усуненню помилок та несправностей на офіційній вікі-сторінці Ryujinx (англійською)", - "zh_CN": "打开 Ryujinx 官方 Wiki 的常见问题和问题排除页面", - "zh_TW": "開啟官方 Ryujinx Wiki 常見問題 (FAQ) 和疑難排解頁面" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpSetup", "Translations": { "ar_SA": "", - "de_DE": "Setup- und Konfigurationsanleitung", + "de_DE": "", "el_GR": "", "en_US": "Setup & Configuration Guide", "es_ES": "", "fr_FR": "Guide d'Installation et de Configuration", "he_IL": "", - "it_IT": "Guida all'installazione e alla configurazione", + "it_IT": "", "ja_JP": "", "ko_KR": "설치 및 구성 안내", "no_NO": "Oppsett- og konfigurasjonsveiledning", "pl_PL": "", - "pt_BR": "Guia de Instalação e Configuração", - "ru_RU": "Руководство по установке и настройке", - "sv_SE": "Konfigurationsguide", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Посібник зі встановлення та налаштування (eng)", - "zh_CN": "安装与配置指南", - "zh_TW": "設定和配置指南" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpSetupTooltip", "Translations": { "ar_SA": "", - "de_DE": "Öffnet die Setup- und Konfigurationsanleitung im offiziellen Ryujinx-Wiki", + "de_DE": "", "el_GR": "", "en_US": "Opens the Setup & Configuration guide on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre le guide d'installation et de configuration sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "Apre la guida all'installazione e alla configurazione presente nella wiki ufficiale di Ryujinx", + "it_IT": "", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 설정 및 구성 안내 열기", "no_NO": "Åpner oppsett- og konfigurasjonsveiledningen på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "Abre o guia de instalação e configuração no wiki oficial do Ryujinx", - "ru_RU": "Открывает страницу Руководство по установке и настройке на официальной странице вики Ryujinx", - "sv_SE": "Öppnar konfigurationsguiden på den officiella Ryujinx-wikin", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Відкриває посібник з Налаштування та конфігурації на офіційній вікі-сторінці Ryujinx (англійською)", - "zh_CN": "打开 Ryujinx 官方 Wiki 的安装与配置指南", - "zh_TW": "開啟官方 Ryujinx Wiki 設定和配置指南" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpMultiplayer", "Translations": { "ar_SA": "", - "de_DE": "Multiplayer (LDN/LAN) Anleitung", + "de_DE": "", "el_GR": "", "en_US": "Multiplayer (LDN/LAN) Guide", "es_ES": "", "fr_FR": "Guide Multijoueur (LDN/LAN)", "he_IL": "", - "it_IT": "Guida alla modalità multigiocatore (LDN/LAN)", + "it_IT": "", "ja_JP": "", "ko_KR": "멀티플레이어(LDN/LAN) 안내", "no_NO": "Flerspillerveiledning (LDN/LAN)", "pl_PL": "", - "pt_BR": "Guia Multijogador (LDN/LAN)", - "ru_RU": "Гайд по мультиплееру (LDN/LAN)", - "sv_SE": "Flerspelarguide (LDN/LAN)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Посібник з мультиплеєру (LDN/LAN) (eng)", - "zh_CN": "多人游戏(LDN/LAN)指南", - "zh_TW": "多人遊戲 (LDN/LAN) 指南" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "MenuBarHelpMultiplayerTooltip", "Translations": { "ar_SA": "", - "de_DE": "Öffnet die Multiplayer-Anleitung im offiziellen Ryujinx-Wiki", + "de_DE": "", "el_GR": "", "en_US": "Opens the Multiplayer guide on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre le guide de Multijoueur sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "Apre la guida alla modalità multigiocatore presente nella wiki ufficiale di Ryujinx", + "it_IT": "", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 멀티플레이어 안내 열기", "no_NO": "Åpner flerspillerveiledningen på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "Abre o guia multijogador no wiki oficial do Ryujinx", - "ru_RU": "Открывает гайд по мультиплееру на официальной странице вики Ryujinx", - "sv_SE": "Öppnar flerspelarguiden på den officiella Ryujinx-wikin", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Відкриває посібник з налаштування Мультиплеєру на офіційній вікі-сторінці Ryujinx (англійською)", - "zh_CN": "打开 Ryujinx 官方 Wiki 的多人游戏指南", - "zh_TW": "開啟官方 Ryujinx Wiki 多人遊戲 (LDN/LAN) 指南" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -1439,7 +1358,6 @@ "pl_PL": "O programie", "pt_BR": "_Sobre", "ru_RU": "О программе", - "sv_SE": "Om", "th_TH": "เกี่ยวกับ", "tr_TR": "Hakkında", "uk_UA": "Про застосунок", @@ -1464,11 +1382,10 @@ "pl_PL": "Wyszukaj...", "pt_BR": "Buscar...", "ru_RU": "Поиск...", - "sv_SE": "Sök...", "th_TH": "กำลังค้นหา...", "tr_TR": "Ara...", "uk_UA": "Пошук...", - "zh_CN": "搜索...", + "zh_CN": "搜索…", "zh_TW": "搜尋..." } }, @@ -1485,11 +1402,10 @@ "it_IT": "Preferito", "ja_JP": "お気に入り", "ko_KR": "즐겨찾기", - "no_NO": "Favoritter", + "no_NO": "", "pl_PL": "Ulubione", "pt_BR": "Favorito", "ru_RU": "Избранное", - "sv_SE": "Favorit", "th_TH": "ชื่นชอบ", "tr_TR": "Favori", "uk_UA": "Обране", @@ -1514,7 +1430,6 @@ "pl_PL": "Ikona", "pt_BR": "Ícone", "ru_RU": "Значок", - "sv_SE": "Ikon", "th_TH": "ไอคอน", "tr_TR": "Simge", "uk_UA": "Значок", @@ -1539,7 +1454,6 @@ "pl_PL": "Nazwa", "pt_BR": "Nome", "ru_RU": "Название", - "sv_SE": "Namn", "th_TH": "ชื่อ", "tr_TR": "Oyun Adı", "uk_UA": "Назва", @@ -1549,156 +1463,6 @@ }, { "ID": "GameListHeaderDeveloper", - "Translations": { - "ar_SA": "", - "de_DE": "Entwickelt von {0}", - "el_GR": "", - "en_US": "Developed by {0}", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Utviklet av {0}", - "pl_PL": "", - "pt_BR": "Desenvolvido por {0}", - "ru_RU": "Разработана {0}", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Розроблено: {0}", - "zh_CN": "由 {0} 开发", - "zh_TW": "" - } - }, - { - "ID": "GameListHeaderVersion", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "Έκδοση: {0}", - "en_US": "Version: {0}", - "es_ES": "Versión: {0}", - "fr_FR": "", - "he_IL": "", - "it_IT": "Versione: {0}", - "ja_JP": "バージョン: {0}", - "ko_KR": "버전: {0}", - "no_NO": "Versjon: {0}", - "pl_PL": "Wersja: {0}", - "pt_BR": "Versão: {0}", - "ru_RU": "Версия: {0}", - "sv_SE": "", - "th_TH": "เวอร์ชั่น: {0}", - "tr_TR": "Sürüm: {0}", - "uk_UA": "Версія: {0}", - "zh_CN": "版本: {0}", - "zh_TW": "版本: {0}" - } - }, - { - "ID": "GameListHeaderTimePlayed", - "Translations": { - "ar_SA": "", - "de_DE": "Spielzeit:", - "el_GR": "Χρόνος:", - "en_US": "Play Time:", - "es_ES": "Tiempo jugado:", - "fr_FR": "Temps de jeu:", - "he_IL": "", - "it_IT": "Tempo di gioco:", - "ja_JP": "プレイ時間:", - "ko_KR": "플레이 타임:", - "no_NO": "Spilletid:", - "pl_PL": "Czas w grze:", - "pt_BR": "Tempo de Jogo:", - "ru_RU": "Время в игре:", - "sv_SE": "Speltid:", - "th_TH": "เล่นไปแล้ว:", - "tr_TR": "Oynama Süresi:", - "uk_UA": "Зіграно часу:", - "zh_CN": "游玩时长:", - "zh_TW": "遊玩時數:" - } - }, - { - "ID": "GameListHeaderLastPlayed", - "Translations": { - "ar_SA": "", - "de_DE": "Zuletzt gespielt: ", - "el_GR": "Παίχτηκε: ", - "en_US": "Last Played:", - "es_ES": "Jugado por última vez:", - "fr_FR": "Dernière partie jouée:", - "he_IL": "", - "it_IT": "Ultima partita:", - "ja_JP": "最終プレイ日時:", - "ko_KR": "마지막 플레이:", - "no_NO": "Sist Spilt:", - "pl_PL": "Ostatnio grane:", - "pt_BR": "Última vez Jogado:", - "ru_RU": "Последний запуск:", - "sv_SE": "Senast spelad:", - "th_TH": "เล่นล่าสุด:", - "tr_TR": "Son Oynama Tarihi:", - "uk_UA": "Востаннє зіграно:", - "zh_CN": "最近游玩:", - "zh_TW": "最近遊玩:" - } - }, - { - "ID": "GameListHeaderFileExtension", - "Translations": { - "ar_SA": "", - "de_DE": "Dateiformat: {0}", - "el_GR": "Κατάληξη: {0}", - "en_US": "Extension: {0}", - "es_ES": "Extensión: {0}", - "fr_FR": "Extension du Fichier: {0}", - "he_IL": "", - "it_IT": "Estensione: {0}", - "ja_JP": "ファイル拡張子: {0}", - "ko_KR": "파일 확장자: {0}", - "no_NO": "Fil Eks.: {0}", - "pl_PL": "Rozszerzenie pliku: {0}", - "pt_BR": "Extensão: {0}", - "ru_RU": "Расширение файла: {0}", - "sv_SE": "Filänd: {0}", - "th_TH": "นามสกุลไฟล์: {0}", - "tr_TR": "Dosya Uzantısı: {0}", - "uk_UA": "Розширення файлу: {0}", - "zh_CN": "扩展名: {0}", - "zh_TW": "副檔名: {0}" - } - }, - { - "ID": "GameListHeaderFileSize", - "Translations": { - "ar_SA": "", - "de_DE": "Dateigröße: {0}", - "el_GR": "Μέγεθος Αρχείου: {0}", - "en_US": "File Size: {0}", - "es_ES": "Tamaño del archivo: {0}", - "fr_FR": "Taille du Fichier: {0}", - "he_IL": "", - "it_IT": "Dimensione file: {0}", - "ja_JP": "ファイルサイズ: {0}", - "ko_KR": "파일 크기: {0}", - "no_NO": "Fil Størrelse: {0}", - "pl_PL": "Rozmiar pliku: {0}", - "pt_BR": "Tamanho: {0}", - "ru_RU": "Размер файла: {0}", - "sv_SE": "Filstorlek: {0}", - "th_TH": "ขนาดไฟล์: {0}", - "tr_TR": "Dosya Boyutu: {0}", - "uk_UA": "Розмір файлу: {0}", - "zh_CN": "大小: {0}", - "zh_TW": "檔案大小: {0}" - } - }, - { - "ID": "GameListSortDeveloper", "Translations": { "ar_SA": "المطور", "de_DE": "Entwickler", @@ -1714,7 +1478,6 @@ "pl_PL": "Twórca", "pt_BR": "Desenvolvedor", "ru_RU": "Разработчик", - "sv_SE": "Utvecklare", "th_TH": "ผู้พัฒนา", "tr_TR": "Geliştirici", "uk_UA": "Розробник", @@ -1723,7 +1486,31 @@ } }, { - "ID": "GameListSortTimePlayed", + "ID": "GameListHeaderVersion", + "Translations": { + "ar_SA": "الإصدار", + "de_DE": "", + "el_GR": "Έκδοση", + "en_US": "Version", + "es_ES": "Versión", + "fr_FR": "", + "he_IL": "גרסה", + "it_IT": "Versione", + "ja_JP": "バージョン", + "ko_KR": "버전", + "no_NO": "Versjon", + "pl_PL": "Wersja", + "pt_BR": "Versão", + "ru_RU": "Версия", + "th_TH": "เวอร์ชั่น", + "tr_TR": "Sürüm", + "uk_UA": "Версія", + "zh_CN": "版本", + "zh_TW": "版本" + } + }, + { + "ID": "GameListHeaderTimePlayed", "Translations": { "ar_SA": "وقت اللعب", "de_DE": "Spielzeit", @@ -1737,9 +1524,8 @@ "ko_KR": "플레이 타임", "no_NO": "Spilletid", "pl_PL": "Czas w grze:", - "pt_BR": "Tempo de Jogo", + "pt_BR": "Tempo de jogo", "ru_RU": "Время в игре", - "sv_SE": "Speltid", "th_TH": "เล่นไปแล้ว", "tr_TR": "Oynama Süresi", "uk_UA": "Зіграно часу", @@ -1748,7 +1534,7 @@ } }, { - "ID": "GameListSortLastPlayed", + "ID": "GameListHeaderLastPlayed", "Translations": { "ar_SA": "آخر مرة لُعبت", "de_DE": "Zuletzt gespielt", @@ -1762,9 +1548,8 @@ "ko_KR": "마지막 플레이", "no_NO": "Sist Spilt", "pl_PL": "Ostatnio grane", - "pt_BR": "Última vez Jogado", + "pt_BR": "Último jogo", "ru_RU": "Последний запуск", - "sv_SE": "Senast spelad", "th_TH": "เล่นล่าสุด", "tr_TR": "Son Oynama Tarihi", "uk_UA": "Востаннє зіграно", @@ -1773,7 +1558,7 @@ } }, { - "ID": "GameListSortFileExtension", + "ID": "GameListHeaderFileExtension", "Translations": { "ar_SA": "صيغة الملف", "de_DE": "Dateiformat", @@ -1789,7 +1574,6 @@ "pl_PL": "Rozszerzenie pliku", "pt_BR": "Extensão", "ru_RU": "Расширение файла", - "sv_SE": "Filänd", "th_TH": "นามสกุลไฟล์", "tr_TR": "Dosya Uzantısı", "uk_UA": "Розширення файлу", @@ -1798,7 +1582,7 @@ } }, { - "ID": "GameListSortFileSize", + "ID": "GameListHeaderFileSize", "Translations": { "ar_SA": "حجم الملف", "de_DE": "Dateigröße", @@ -1814,7 +1598,6 @@ "pl_PL": "Rozmiar pliku", "pt_BR": "Tamanho", "ru_RU": "Размер файла", - "sv_SE": "Filstorlek", "th_TH": "ขนาดไฟล์", "tr_TR": "Dosya Boyutu", "uk_UA": "Розмір файлу", @@ -1823,7 +1606,7 @@ } }, { - "ID": "GameListSortPath", + "ID": "GameListHeaderPath", "Translations": { "ar_SA": "المسار", "de_DE": "Pfad", @@ -1839,7 +1622,6 @@ "pl_PL": "Ścieżka", "pt_BR": "Caminho", "ru_RU": "Путь", - "sv_SE": "Sökväg", "th_TH": "ที่อยู่ไฟล์", "tr_TR": "Yol", "uk_UA": "Шлях", @@ -1847,106 +1629,6 @@ "zh_TW": "路徑" } }, - { - "ID": "GameListHeaderCompatibilityStatus", - "Translations": { - "ar_SA": "", - "de_DE": "Kompatibilität:", - "el_GR": "", - "en_US": "Compatibility:", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Kompatibilitet", - "pl_PL": "", - "pt_BR": "Compatibilidade:", - "ru_RU": "Совместимость:", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Сумісність:", - "zh_CN": "兼容性:", - "zh_TW": "" - } - }, - { - "ID": "GameListHeaderTitleId", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Title ID:", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Tittel ID:", - "pl_PL": "", - "pt_BR": "ID do Título:", - "ru_RU": "ID приложения", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "ID гри:", - "zh_CN": "标题 ID:", - "zh_TW": "" - } - }, - { - "ID": "GameListHeaderHostedGames", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Hosted Games: {0}", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Spill som Arrangeres: {0}", - "pl_PL": "", - "pt_BR": "Jogos Hospedados: {0}", - "ru_RU": "Запущенно игр: {0}", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Розміщені ігри: {0}", - "zh_CN": "服务的游戏: {0}", - "zh_TW": "" - } - }, - { - "ID": "GameListHeaderPlayerCount", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Online Players: {0}", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Online-spillere: {0}", - "pl_PL": "", - "pt_BR": "Jogadores Online: {0}", - "ru_RU": "Игроков онлайн: {0}", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Гравців онлайн: {0}", - "zh_CN": "在线玩家: {0}", - "zh_TW": "" - } - }, { "ID": "GameListContextMenuOpenUserSaveDirectory", "Translations": { @@ -1962,12 +1644,11 @@ "ko_KR": "사용자 저장 디렉터리 열기", "no_NO": "Åpne bruker lagrings mappe", "pl_PL": "Otwórz katalog zapisów użytkownika", - "pt_BR": "Abrir Diretório de Saves do Usuário", + "pt_BR": "Abrir diretório de saves do usuário", "ru_RU": "Открыть папку с сохранениями", - "sv_SE": "Öppna användarkatalog för sparningar", "th_TH": "เปิดไดเร็กทอรี่บันทึกของผู้ใช้", "tr_TR": "Kullanıcı Kayıt Dosyası Dizinini Aç", - "uk_UA": "Відкрити теку збережень користувача", + "uk_UA": "Відкрити теку збереження користувача", "zh_CN": "打开用户存档目录", "zh_TW": "開啟使用者存檔資料夾" } @@ -1989,10 +1670,9 @@ "pl_PL": "Otwiera katalog, który zawiera zapis użytkownika dla tej aplikacji", "pt_BR": "Abre o diretório que contém jogos salvos para o usuário atual", "ru_RU": "Открывает папку с пользовательскими сохранениями", - "sv_SE": "Öppnar katalogen som innehåller applikationens användarsparade spel", "th_TH": "เปิดไดเร็กทอรี่ซึ่งมีการบันทึกข้อมูลของผู้ใช้แอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває теку, яка містить збереження користувача", + "uk_UA": "Відкриває каталог, який містить збереження користувача програми", "zh_CN": "打开储存游戏用户存档的目录", "zh_TW": "開啟此應用程式的使用者存檔資料夾" } @@ -2012,12 +1692,11 @@ "ko_KR": "기기 저장 디렉터리 열기", "no_NO": "Åpne lagringsmappe for enheten", "pl_PL": "Otwórz katalog zapisów urządzenia", - "pt_BR": "Abrir Diretório de Saves de Dispositivo do Usuário", + "pt_BR": "Abrir diretório de saves de dispositivo do usuário", "ru_RU": "Открыть папку сохраненных устройств", - "sv_SE": "Öppna enhetens katalog för sparade spel", "th_TH": "เปิดไดเร็กทอรี่บันทึกของอุปกรณ์", "tr_TR": "Kullanıcı Cihaz Dizinini Aç", - "uk_UA": "Відкрити теку пристроїв користувача", + "uk_UA": "Відкрити каталог пристроїв користувача", "zh_CN": "打开系统数据目录", "zh_TW": "開啟裝置存檔資料夾" } @@ -2039,10 +1718,9 @@ "pl_PL": "Otwiera katalog, który zawiera zapis urządzenia dla tej aplikacji", "pt_BR": "Abre o diretório que contém saves do dispositivo para o usuário atual", "ru_RU": "Открывает папку, содержащую сохраненные устройства", - "sv_SE": "Öppnar katalogen som innehåller applikationens sparade spel på enheten", "th_TH": "เปิดไดเรกทอรี่ซึ่งมีบันทึกข้อมูลของอุปกรณ์ในแอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı Cihaz Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває теку, яка містить збережені пристрої", + "uk_UA": "Відкриває каталог, який містить збереження пристрою програми", "zh_CN": "打开储存游戏系统数据的目录", "zh_TW": "開啟此應用程式的裝置存檔資料夾" } @@ -2062,12 +1740,11 @@ "ko_KR": "BCAT 저장 디렉터리 열기", "no_NO": "Åpne BCAT lagringsmappe", "pl_PL": "Otwórz katalog zapisu BCAT obecnego użytkownika", - "pt_BR": "Abrir Diretório de Saves BCAT do Usuário", + "pt_BR": "Abrir diretório de saves BCAT do usuário", "ru_RU": "Открыть папку сохраненных BCAT", - "sv_SE": "Öppna katalog för BCAT-sparningar", "th_TH": "เปิดไดเรกทอรี่บันทึกของ BCAT", "tr_TR": "Kullanıcı BCAT Dizinini Aç", - "uk_UA": "Відкрити теку збережень BCAT", + "uk_UA": "Відкрити каталог користувача BCAT", "zh_CN": "打开 BCAT 数据目录", "zh_TW": "開啟 BCAT 存檔資料夾" } @@ -2089,10 +1766,9 @@ "pl_PL": "Otwiera katalog, który zawiera zapis BCAT dla tej aplikacji", "pt_BR": "Abre o diretório que contém saves BCAT para o usuário atual", "ru_RU": "Открывает папку, содержащую сохраненные BCAT", - "sv_SE": "Öppnar katalogen som innehåller applikationens BCAT-sparningar", "th_TH": "เปิดไดเรกทอรี่ซึ่งมีการบันทึกข้อมูลของ BCAT ในแอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı BCAT Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває теку, яка містить BCAT-збереження програми", + "uk_UA": "Відкриває каталог, який містить BCAT-збереження програми", "zh_CN": "打开储存游戏 BCAT 数据的目录", "zh_TW": "開啟此應用程式的 BCAT 存檔資料夾" } @@ -2112,12 +1788,11 @@ "ko_KR": "타이틀 업데이트 관리", "no_NO": "Administrer titteloppdateringer", "pl_PL": "Zarządzaj aktualizacjami", - "pt_BR": "Gerenciar Atualizações do Jogo", + "pt_BR": "Gerenciar atualizações do jogo", "ru_RU": "Управление обновлениями", - "sv_SE": "Hantera speluppdateringar", "th_TH": "จัดการเวอร์ชั่นอัปเดต", "tr_TR": "Oyun Güncellemelerini Yönet", - "uk_UA": "Керування оновленнями", + "uk_UA": "Керування оновленнями заголовків", "zh_CN": "管理游戏更新", "zh_TW": "管理遊戲更新" } @@ -2139,10 +1814,9 @@ "pl_PL": "Otwiera okno zarządzania aktualizacjami danej aplikacji", "pt_BR": "Abre a janela de gerenciamento de atualizações", "ru_RU": "Открывает окно управления обновлениями приложения", - "sv_SE": "Öppnar spelets hanteringsfönster för uppdateringar", "th_TH": "เปิดหน้าต่างการจัดการเวอร์ชั่นการอัพเดต", "tr_TR": "Oyun Güncelleme Yönetim Penceresini Açar", - "uk_UA": "Відкриває меню керування оновленнями до гри (застосунку)", + "uk_UA": "Відкриває вікно керування оновленням заголовка", "zh_CN": "打开游戏更新管理窗口", "zh_TW": "開啟遊戲更新管理視窗" } @@ -2164,7 +1838,6 @@ "pl_PL": "Zarządzaj dodatkową zawartością (DLC)", "pt_BR": "Gerenciar DLCs", "ru_RU": "Управление DLC", - "sv_SE": "Hantera DLC", "th_TH": "จัดการ DLC", "tr_TR": "DLC'leri Yönet", "uk_UA": "Керування DLC", @@ -2189,10 +1862,9 @@ "pl_PL": "Otwiera okno zarządzania dodatkową zawartością", "pt_BR": "Abre a janela de gerenciamento de DLCs", "ru_RU": "Открывает окно управления DLC", - "sv_SE": "Öppnar DLC-hanteringsfönstret", "th_TH": "เปิดหน้าต่างจัดการ DLC", "tr_TR": "DLC yönetim penceresini açar", - "uk_UA": "Відкриває меню керування DLC", + "uk_UA": "Відкриває вікно керування DLC", "zh_CN": "打开 DLC 管理窗口", "zh_TW": "開啟 DLC 管理視窗" } @@ -2212,9 +1884,8 @@ "ko_KR": "캐시 관리", "no_NO": "Cache administrasjon", "pl_PL": "Zarządzanie Cache", - "pt_BR": "Gerenciamento de Cache", + "pt_BR": "Gerenciamento de cache", "ru_RU": "Управление кэшем", - "sv_SE": "Cachehantering", "th_TH": "จัดการแคช", "tr_TR": "Önbellek Yönetimi", "uk_UA": "Керування кешем", @@ -2237,12 +1908,11 @@ "ko_KR": "대기열 PPTC 재구성", "no_NO": "Start PPTC gjenoppbygging", "pl_PL": "Zakolejkuj rekompilację PPTC", - "pt_BR": "Reconstruir Cache PPTC", + "pt_BR": "Limpar cache PPTC", "ru_RU": "Перестроить очередь PPTC", - "sv_SE": "Kölägg PPTC Rebuild", "th_TH": "เพิ่มคิวการสร้าง PPTC ใหม่", "tr_TR": "PPTC Yeniden Yapılandırmasını Başlat", - "uk_UA": "Додати до черги перекомпіляцію PPTC", + "uk_UA": "Очистити кеш PPTC", "zh_CN": "清除 PPTC 缓存文件", "zh_TW": "佇列 PPTC 重建" } @@ -2262,66 +1932,15 @@ "ko_KR": "다음 게임 실행 부팅 시, PPTC를 트리거하여 다시 구성", "no_NO": "Utløs PPTC for å gjenoppbygge ved oppstart av neste spill-start", "pl_PL": "Zainicjuj Rekompilację PPTC przy następnym uruchomieniu gry", - "pt_BR": "Aciona o PPTC para reconstruir o cache no momento da próxima inicialização do jogo", + "pt_BR": "Deleta o cache PPTC armazenado em disco do jogo", "ru_RU": "Запускает перестройку PPTC во время следующего запуска игры.", - "sv_SE": "Gör så att PPTC bygger om vid uppstart när nästa spel startas", "th_TH": "ให้ PPTC สร้างใหม่ในเวลาบูตเมื่อเปิดเกมครั้งถัดไป", "tr_TR": "Oyunun bir sonraki açılışında PPTC'yi yeniden yapılandır", - "uk_UA": "Видаляє кеш PPTC застосунку (гри)", + "uk_UA": "Видаляє кеш PPTC програми", "zh_CN": "删除游戏的 PPTC 缓存文件,下次启动游戏时重新编译生成 PPTC 缓存文件", "zh_TW": "下一次啟動遊戲時,觸發 PPTC 進行重建" } }, - { - "ID": "GameListContextMenuCacheManagementNukePptc", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Purge PPTC cache", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "PPTC 캐시 제거", - "no_NO": "Tøm PPTC-bufferen", - "pl_PL": "", - "pt_BR": "Limpar Cache PPTC", - "ru_RU": "Очистить кэш PPTC", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Очистити кеш PPTC", - "zh_CN": "清理 PPTC 缓存", - "zh_TW": "" - } - }, - { - "ID": "GameListContextMenuCacheManagementNukePptcToolTip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Deletes all PPTC cache files for the Application", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "앱의 모든 PPTC 캐시 파일 삭제", - "no_NO": "Sletter alle PPTC-cache-filer for applikasjonen", - "pl_PL": "", - "pt_BR": "Apaga os arquivos de cache PPTC do aplicativo", - "ru_RU": "Удаляет все файлы кэша PPTC для приложения", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Видаляє всі файли кешу PPTC для застосунку", - "zh_CN": "删除应用程序的所有 PPTC 缓存", - "zh_TW": "" - } - }, { "ID": "GameListContextMenuCacheManagementPurgeShaderCache", "Translations": { @@ -2337,9 +1956,8 @@ "ko_KR": "퍼지 셰이더 캐시", "no_NO": "Tøm shader cache", "pl_PL": "Wyczyść pamięć podręczną cieni", - "pt_BR": "Limpar Cache de Shader", + "pt_BR": "Limpar cache de Shader", "ru_RU": "Очистить кэш шейдеров", - "sv_SE": "Töm shader cache", "th_TH": "ล้างแคช แสงเงา", "tr_TR": "Shader Önbelleğini Temizle", "uk_UA": "Очистити кеш шейдерів", @@ -2362,12 +1980,11 @@ "ko_KR": "앱의 셰이더 캐시 삭제", "no_NO": "Sletter applikasjonens shader cache", "pl_PL": "Usuwa pamięć podręczną cieni danej aplikacji", - "pt_BR": "Deleta o cache de Shader do jogo armazenado em disco", + "pt_BR": "Deleta o cache de Shader armazenado em disco do jogo", "ru_RU": "Удаляет кеш шейдеров приложения", - "sv_SE": "Tar bort applikationens shader cache", "th_TH": "ลบแคช แสงเงา ของแอปพลิเคชัน", "tr_TR": "Uygulamanın shader önbelleğini temizler", - "uk_UA": "Видаляє кеш шейдерів застосунку (гри)", + "uk_UA": "Видаляє кеш шейдерів програми", "zh_CN": "删除游戏的着色器缓存文件,下次启动游戏时重新生成着色器缓存文件", "zh_TW": "刪除應用程式的著色器快取" } @@ -2387,12 +2004,11 @@ "ko_KR": "PPTC 디렉터리 열기", "no_NO": "Åpne PPTC mappe", "pl_PL": "Otwórz katalog PPTC", - "pt_BR": "Abrir Diretório de PPTC Cache", + "pt_BR": "Abrir diretório do cache PPTC", "ru_RU": "Открыть папку PPTC", - "sv_SE": "Öppna PPTC-katalog", "th_TH": "เปิดไดเรกทอรี่ PPTC", "tr_TR": "PPTC Dizinini Aç", - "uk_UA": "Відкрити теку PPTC", + "uk_UA": "Відкрити каталог PPTC", "zh_CN": "打开 PPTC 缓存目录", "zh_TW": "開啟 PPTC 資料夾" } @@ -2414,10 +2030,9 @@ "pl_PL": "Otwiera katalog, który zawiera pamięć podręczną PPTC aplikacji", "pt_BR": "Abre o diretório contendo os arquivos do cache PPTC", "ru_RU": "Открывает папку, содержащую PPTC кэш приложений и игр", - "sv_SE": "Öppnar katalogen som innehåller applikationens PPTC-cache", "th_TH": "เปิดไดเร็กทอรี่ของ แคช PPTC ในแอปพลิเคชัน", "tr_TR": "Uygulamanın PPTC Önbelleğinin bulunduğu dizini açar", - "uk_UA": "Відкриває теку, яка містить PPTC кеш застосунку (гри)", + "uk_UA": "Відкриває каталог, який містить кеш PPTC програми", "zh_CN": "打开储存游戏 PPTC 缓存文件的目录", "zh_TW": "開啟此應用程式的 PPTC 快取資料夾" } @@ -2437,12 +2052,11 @@ "ko_KR": "셰이더 캐시 디렉터리 열기", "no_NO": "Åpne Shader Cache-mappen", "pl_PL": "Otwórz katalog pamięci podręcznej cieni", - "pt_BR": "Abrir Diretório de Shader Cache", + "pt_BR": "Abrir diretório do cache de Shader", "ru_RU": "Открыть папку с кэшем шейдеров", - "sv_SE": "Öppna katalog för shader cache", "th_TH": "เปิดไดเรกทอรี่ แคช แสงเงา", "tr_TR": "Shader Önbelleği Dizinini Aç", - "uk_UA": "Відкрити теку з кешем шейдерів", + "uk_UA": "Відкрити каталог кешу шейдерів", "zh_CN": "打开着色器缓存目录", "zh_TW": "開啟著色器快取資料夾" } @@ -2464,10 +2078,9 @@ "pl_PL": "Otwiera katalog, który zawiera pamięć podręczną cieni aplikacji", "pt_BR": "Abre o diretório contendo os arquivos do cache de Shader", "ru_RU": "Открывает папку, содержащую кэш шейдеров приложений и игр", - "sv_SE": "Öppnar katalogen som innehåller applikationens shader cache", "th_TH": "เปิดไดเรกทอรี่ของ แคช แสงเงา ในแอปพลิเคชัน", "tr_TR": "Uygulamanın shader önbelleğinin bulunduğu dizini açar", - "uk_UA": "Відкриває теку, яка містить кеш шейдерів застосунку (гри)", + "uk_UA": "Відкриває каталог, який містить кеш шейдерів програми", "zh_CN": "打开储存游戏着色器缓存文件的目录", "zh_TW": "開啟此應用程式的著色器快取資料夾" } @@ -2487,9 +2100,8 @@ "ko_KR": "데이터 추출", "no_NO": "Hent ut data", "pl_PL": "Wypakuj dane", - "pt_BR": "Extrair Dados", + "pt_BR": "Extrair dados", "ru_RU": "Извлечь данные", - "sv_SE": "Extrahera data", "th_TH": "แยกส่วนข้อมูล", "tr_TR": "Veriyi Ayıkla", "uk_UA": "Видобути дані", @@ -2510,11 +2122,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "ExeFS", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -2532,14 +2143,13 @@ "es_ES": "Extraer la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section ExeFS du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", + "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します", "ko_KR": "앱의 현재 구성에서 ExeFS 추출(업데이트 포함)", "no_NO": "Pakk ut ExeFS seksjonen fra Programmets gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção ExeFS do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела ExeFS из текущих настроек приложения (включая обновления)", - "sv_SE": "Extrahera ExeFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน ExeFS ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัปเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)", "uk_UA": "Видобуває розділ ExeFS із поточної конфігурації програми (включаючи оновлення)", @@ -2560,11 +2170,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "RomFS", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -2582,71 +2191,20 @@ "es_ES": "Extraer la sección RomFS de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section RomFS du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-RomFS מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", + "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)から RomFS セクションを展開します", "ko_KR": "앱의 현재 구성에서 RomFS 추출(업데이트 포함)", "no_NO": "Pakk ut RomFS seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję RomFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção RomFS do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела RomFS из текущих настроек приложения (включая обновления)", - "sv_SE": "Extrahera RomFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน RomFS ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัพเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil)", - "uk_UA": "Видобуває розділ RomFS із поточної конфігурації застосунку (включно з оновленнями)", + "uk_UA": "Видобуває розділ RomFS із поточної конфігурації програми (включаючи оновлення)", "zh_CN": "从游戏的当前状态中提取 RomFS 分区 (包括更新)", "zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)" } }, - { - "ID": "GameListContextMenuExtractDataAocRomFS", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "DLC RomFS", - "es_ES": "", - "fr_FR": "RomFS de DLC", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "", - "ru_RU": "", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" - } - }, - { - "ID": "GameListContextMenuExtractDataAocRomFSToolTip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Extract the RomFS from a selected DLC file", - "es_ES": "", - "fr_FR": "Extraire les RomFS d'un fichier DLC choisi", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "선택한 DLC 파일에서 RomFS 추출", - "no_NO": "Pakk ut RomFS filene fra valgt DLC fil", - "pl_PL": "", - "pt_BR": "Extraia o RomFS de um arquivo DLC selecionado", - "ru_RU": "Извлекает файлы RomFS из выбранного файла DLC", - "sv_SE": "Extrahera RomFS från en vald DLC-fil", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Витягти RomFS з обраного файлу DLC", - "zh_CN": "从选定的 DLC 文件中解压 RomFS", - "zh_TW": "" - } - }, { "ID": "GameListContextMenuExtractDataLogo", "Translations": { @@ -2660,16 +2218,15 @@ "it_IT": "", "ja_JP": "ロゴ", "ko_KR": "로고", - "no_NO": "", + "no_NO": "Logo", "pl_PL": "", - "pt_BR": "Logotipo", - "ru_RU": "Лого", - "sv_SE": "Logotyp", + "pt_BR": "", + "ru_RU": "Логотип", "th_TH": "โลโก้", "tr_TR": "Simge", "uk_UA": "Логотип", "zh_CN": "图标", - "zh_TW": "圖示" + "zh_TW": "" } }, { @@ -2682,14 +2239,13 @@ "es_ES": "Extraer la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section Logo du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-Logo מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", + "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)からロゴセクションを展開します", "ko_KR": "앱의 현재 구성에서 로고 섹션 추출 (업데이트 포함)", "no_NO": "Pakk ut Logo-seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję z logiem z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção Logo do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела с логотипом из текущих настроек приложения (включая обновления)", - "sv_SE": "Extrahera Logo-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน โลโก้ ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัปเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil)", "uk_UA": "Видобуває розділ логотипу з поточної конфігурації програми (включаючи оновлення)", @@ -2712,9 +2268,8 @@ "ko_KR": "바로 가기 만들기", "no_NO": "Lag programsnarvei", "pl_PL": "Utwórz skrót aplikacji", - "pt_BR": "Criar Atalho da Aplicação", + "pt_BR": "Criar atalho da aplicação", "ru_RU": "Создать ярлык приложения", - "sv_SE": "Skapa genväg till applikation", "th_TH": "สร้างทางลัดของแอปพลิเคชัน", "tr_TR": "Uygulama Kısayolu Oluştur", "uk_UA": "Створити ярлик застосунку", @@ -2737,12 +2292,11 @@ "ko_KR": "선택한 앱을 실행하는 바탕 화면에 바로 가기를 생성", "no_NO": "Lag en snarvei på skrivebordet som starter den valgte Applikasjonen", "pl_PL": "Utwórz skrót na pulpicie, który uruchamia wybraną aplikację", - "pt_BR": "Criar um atalho na área de trabalho que inicia o aplicativo selecionado", + "pt_BR": "Criar um atalho de área de trabalho que inicia o aplicativo selecionado", "ru_RU": "Создает ярлык на рабочем столе, с помощью которого можно запустить игру или приложение", - "sv_SE": "Skapa en skrivbordsgenväg som startar vald applikation", "th_TH": "สร้างทางลัดบนเดสก์ท็อปสำหรับใช้แอปพลิเคชันที่เลือก", "tr_TR": "Seçilmiş uygulamayı çalıştıracak bir masaüstü kısayolu oluştur", - "uk_UA": "Створити ярлик на робочому столі, який запускатиме вибраний застосунок (гру)", + "uk_UA": "Створити ярлик на робочому столі, який запускає вибраний застосунок", "zh_CN": "创建一个直接启动此游戏的桌面快捷方式", "zh_TW": "建立桌面捷徑,啟動選取的應用程式" } @@ -2764,114 +2318,13 @@ "pl_PL": "Utwórz skrót w folderze 'Aplikacje' w systemie macOS, który uruchamia wybraną aplikację", "pt_BR": "Crie um atalho na pasta Aplicativos do macOS que abre o Aplicativo selecionado", "ru_RU": "Создает ярлык игры или приложения в папке Программы macOS", - "sv_SE": "Skapa en genväg i macOS-programmapp som startar vald applikation", "th_TH": "สร้างทางลัดในโฟลเดอร์ Applications ของ macOS สำหรับใช้แอปพลิเคชันที่เลือก", "tr_TR": "", - "uk_UA": "Створити ярлик у каталозі програм macOS, що запускатиме обраний застосунок (гру)", + "uk_UA": "Створити ярлик у каталозі macOS програм, що запускає обраний Додаток", "zh_CN": "在 macOS 的应用程序目录中创建一个直接启动此游戏的快捷方式", "zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式" } }, - { - "ID": "GameListContextMenuShowCompatEntry", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Show Compatibility Entry", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "호환성 항목 표시", - "no_NO": "Vis kompatibilitetsoppføring", - "pl_PL": "", - "pt_BR": "Mostrar Dados de Compatibilidade", - "ru_RU": "Показать записи о совместимости", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Iнформація про сумісність", - "zh_CN": "显示兼容性项目", - "zh_TW": "" - } - }, - { - "ID": "GameListContextMenuShowCompatEntryToolTip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Show the selected game in the Compatibility List you can normally access via the Help menu.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.", - "no_NO": "Vis det valgte spillet i kompatibilitetslisten, som du vanligvis får tilgang til via Hjelp-menyen.", - "pl_PL": "", - "pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.", - "ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.", - "zh_CN": "在兼容性列表中显示选定的游戏,您通常可以通过帮助菜单访问。", - "zh_TW": "" - } - }, - { - "ID": "GameListContextMenuShowGameData", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Show Game Info", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "게임 통계 표시", - "no_NO": "Vis Spill Info", - "pl_PL": "", - "pt_BR": "Mostrar Informações do Jogo", - "ru_RU": "Показать информацию об игре", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Інформація про гру", - "zh_CN": "显示游戏信息", - "zh_TW": "" - } - }, - { - "ID": "GameListContextMenuShowGameDataToolTip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Show stats & details about the currently selected game.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "그리드 보기 레이아웃에서 누락된 현재 선택된 게임에 대한 다양한 정보를 표시합니다.", - "no_NO": "Vis statistikk og detaljer om det valgte spillet.", - "pl_PL": "", - "pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.", - "ru_RU": "Показывать статистику и подробную информацию о выбранной игре.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Показати статистику та деталі обраної гри.", - "zh_CN": "显示当前选定游戏的状态与详细信息。", - "zh_TW": "" - } - }, { "ID": "GameListContextMenuOpenModsDirectory", "Translations": { @@ -2887,9 +2340,8 @@ "ko_KR": "모드 디렉터리 열기", "no_NO": "Åpne Modifikasjonsmappen", "pl_PL": "Otwórz katalog modów", - "pt_BR": "Abrir Pasta de Mods", + "pt_BR": "Abrir pasta de Mods", "ru_RU": "Открыть папку с модами", - "sv_SE": "Öppna Mods-katalog", "th_TH": "เปิดไดเร็กทอรี่ Mods", "tr_TR": "Mod Dizinini Aç", "uk_UA": "Відкрити теку з модами", @@ -2914,10 +2366,9 @@ "pl_PL": "Otwiera katalog zawierający mody dla danej aplikacji", "pt_BR": "Abre a pasta que contém os mods da aplicação ", "ru_RU": "Открывает папку, содержащую моды для приложений и игр", - "sv_SE": "Öppnar katalogen som innehåller applikationens Mods", "th_TH": "เปิดไดเร็กทอรี่ Mods ของแอปพลิเคชัน", "tr_TR": "", - "uk_UA": "Відкриває теку, яка містить модифікації застосунків (ігор)", + "uk_UA": "Відкриває каталог, який містить модифікації Додатків", "zh_CN": "打开存放游戏 MOD 的目录", "zh_TW": "開啟此應用程式模組的資料夾" } @@ -2937,12 +2388,11 @@ "ko_KR": "Atmosphere 모드 디렉터리 열기", "no_NO": "Åpne Atmosfære modifikasjons mappen", "pl_PL": "Otwórz katalog modów Atmosphere", - "pt_BR": "Abrir Diretório de Mods Atmosphere", + "pt_BR": "Abrir diretório de mods Atmosphere", "ru_RU": "Открыть папку с модами Atmosphere", - "sv_SE": "Öppna Atmosphere Mods-katalogen", "th_TH": "เปิดไดเร็กทอรี่ Mods Atmosphere", "tr_TR": "", - "uk_UA": "Відкрити теку модифікацій Atmosphere", + "uk_UA": "Відкрити каталог модифікацій Atmosphere", "zh_CN": "打开大气层系统 MOD 目录", "zh_TW": "開啟 Atmosphere 模組資料夾" } @@ -2962,12 +2412,11 @@ "ko_KR": "해당 게임의 모드가 포함된 대체 SD 카드 Atmosphere 디렉터리를 엽니다. 실제 하드웨어용으로 패키징된 모드에 유용합니다.", "no_NO": "Åpner den alternative SD-kortets Atmosfære-mappe som inneholder programmoduser. Nyttig for modifikasjoner som er pakket for ekte maskinvare.", "pl_PL": "Otwiera alternatywny katalog Atmosphere na karcie SD, który zawiera mody danej aplikacji. Przydatne dla modów przygotowanych pod prawdziwy sprzęt.", - "pt_BR": "Abre o diretório Atmosphere do cartão SD alternativo que contém os Mods do aplicativo. Útil para mods que são empacotados para hardware real.", + "pt_BR": "", "ru_RU": "Открывает папку Atmosphere на альтернативной SD-карте, которая содержит моды для приложений и игр. Полезно для модов, сделанных для реальной консоли.", - "sv_SE": "Öppnar den alternativa Atmosphere-katalogen på SD-kort som innehåller applikationens Mods. Användbart för Mods som är paketerade för riktig hårdvara.", "th_TH": "เปิดไดเร็กทอรี่ Atmosphere ของการ์ด SD สำรองซึ่งมี Mods ของแอปพลิเคชัน ซึ่งมีประโยชน์สำหรับ Mods ที่บรรจุมากับฮาร์ดแวร์จริง", "tr_TR": "", - "uk_UA": "Відкриває альтернативну теку SD-карти Atmosphere, що містить модифікації до застосунків або ігор. Корисно для модифікацій, зроблених для реального обладнання.", + "uk_UA": "Відкриває альтернативний каталог SD-карти Atmosphere, що містить модифікації Додатків. Корисно для модифікацій, зроблених для реального обладнання.", "zh_CN": "打开存放适用于大气层系统的游戏 MOD 的目录,对于为真实硬件打包的 MOD 非常有用", "zh_TW": "開啟此應用程式模組的另一個 SD 卡 Atmosphere 資料夾。適用於為真實硬體封裝的模組。" } @@ -2982,19 +2431,18 @@ "es_ES": "Verificar y recortar archivo XCI", "fr_FR": "Vérifier et réduire les fichiers XCI", "he_IL": "", - "it_IT": "Controlla e riduci la dimensione del file XCI", + "it_IT": "Controlla e Trimma i file XCI", "ja_JP": "", "ko_KR": "XCI 파일 확인 및 트림", "no_NO": "Kontroller og trim XCI-filen", "pl_PL": "", - "pt_BR": "Verificar e Reduzir o Arquivo XCI", - "ru_RU": "Проверить и обрезать XCI файл", - "sv_SE": "Kontrollera och optimera XCI-fil", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Перевірка та нарізка XCI Файлу", - "zh_CN": "检查并瘦身 XCI 文件", - "zh_TW": "檢查及修剪 XCI 檔案" + "uk_UA": "Перевірка та Нарізка XCI Файлів", + "zh_CN": "", + "zh_TW": "" } }, { @@ -3007,19 +2455,18 @@ "es_ES": "Verificar y recortar archivo XCI para ahorrar espacio en disco", "fr_FR": "Vérifier et réduire les fichiers XCI pour économiser de l'espace", "he_IL": "", - "it_IT": "Controlla e riduci la dimensione del file XCI per risparmiare spazio su disco", + "it_IT": "Controlla e Trimma i file XCI da Salvare Sullo Spazio del Disco", "ja_JP": "", "ko_KR": "디스크 공간을 절약하기 위해 XCI 파일 확인 및 트림", "no_NO": "Kontroller og trimm XCI-filen for å spare diskplass", "pl_PL": "", - "pt_BR": "Verifique e reduza o arquivo XCI para economizar espaço em disco", - "ru_RU": "Проверить и обрезать XCI файл для уменьшения его размера", - "sv_SE": "Kontrollera och optimera XCI-fil för att spara diskutrymme", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Перевірити та обрізати XCI Файл задля збереження місця на диску", - "zh_CN": "检查并瘦身 XCI 文件以节约磁盘空间", - "zh_TW": "檢查及修剪 XCI 檔案以節省儲存空間" + "uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску", + "zh_CN": "", + "zh_TW": "" } }, { @@ -3032,14 +2479,13 @@ "es_ES": "{0}/{1} juegos cargados", "fr_FR": "{0}/{1} Jeux chargés", "he_IL": "{1}/{0} משחקים נטענו", - "it_IT": "{0}/{1} giochi caricati", + "it_IT": "{0}/{1} Giochi Caricati", "ja_JP": "{0}/{1} ゲーム", "ko_KR": "{0}/{1}개의 게임 불러옴", "no_NO": "{0}/{1} Spill Lastet", "pl_PL": "{0}/{1} Załadowane gry", - "pt_BR": "{0}/{1} Jogos Carregados", + "pt_BR": "{0}/{1} jogos carregados", "ru_RU": "{0}/{1} игр загружено", - "sv_SE": "{0}/{1} spel inlästa", "th_TH": "เกมส์โหลดแล้ว {0}/{1}", "tr_TR": "{0}/{1} Oyun Yüklendi", "uk_UA": "{0}/{1} ігор завантажено", @@ -3057,19 +2503,18 @@ "es_ES": "", "fr_FR": "Version du Firmware: {0}", "he_IL": "", - "it_IT": "Versione firmware: {0}", + "it_IT": "", "ja_JP": "", - "ko_KR": "펌웨어 버전 : {0}", - "no_NO": "Fastvareversjon: {0}", + "ko_KR": "", + "no_NO": "", "pl_PL": "", - "pt_BR": "Versão do Firmware: {0}", + "pt_BR": "Versão do firmware: {0}", "ru_RU": "Версия прошивки: {0}", - "sv_SE": "Firmware-version: {0}", "th_TH": "", "tr_TR": "", - "uk_UA": "Версія прошивки: {0}", + "uk_UA": "", "zh_CN": "系统固件版本:{0}", - "zh_TW": "系統韌體版本: {0}" + "zh_TW": "" } }, { @@ -3082,19 +2527,18 @@ "es_ES": "Recortando el siguiente archivo XCI: '{0}'", "fr_FR": "Réduction du fichier XCI '{0}'", "he_IL": "", - "it_IT": "Riduzione della dimensione del file XCI '{0}'", + "it_IT": "Trimmando i file XCI '{0}'", "ja_JP": "", "ko_KR": "XCI 파일 '{0}' 트리밍", "no_NO": "Trimming av XCI-filen '{0}'", "pl_PL": "", - "pt_BR": "Reduzindo o Arquivo XCI '{0}'", - "ru_RU": "Обрезается XCI файл '{0}'", - "sv_SE": "Optimerar XCI-filen '{0}'", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Обрізається XCI Файлів '{0}'", - "zh_CN": "正在瘦身 XCI 文件 '{0}'", - "zh_TW": "正在修剪 XCI 檔案 '{0}'" + "uk_UA": "Обрізано XCI Файлів '{0}'", + "zh_CN": "", + "zh_TW": "" } }, { @@ -3112,9 +2556,8 @@ "ko_KR": "메모리 매핑 한계 감지", "no_NO": "Lav grense for minnetildelinger oppdaget", "pl_PL": "Wykryto niski limit dla przypisań pamięci", - "pt_BR": "Detectado limite baixo para mapeamentos de memória", + "pt_BR": "Limite baixo para mapeamentos de memória detectado", "ru_RU": "Обнаружен низкий лимит разметки памяти", - "sv_SE": "Låg gräns för minnesmappningar upptäcktes", "th_TH": "การตั้งค่าหน่วยความถึงขีดจำกัดต่ำสุดแล้ว", "tr_TR": "Bellek Haritaları İçin Düşük Limit Tespit Edildi ", "uk_UA": "Виявлено низьку межу для відображення памʼяті", @@ -3139,10 +2582,9 @@ "pl_PL": "Czy chcesz zwiększyć wartość vm.max_map_count do {0}", "pt_BR": "Você gostaria de aumentar o valor de vm.max_map_count para {0}", "ru_RU": "Хотите увеличить значение vm.max_map_count до {0}", - "sv_SE": "Vill du öka värdet för vm.max_map_count till {0}", "th_TH": "คุณต้องเพิ่มค่า vm.max_map_count ไปยัง {0}", "tr_TR": "vm.max_map_count değerini {0} sayısına yükseltmek ister misiniz", - "uk_UA": "Бажаєте збільшити значення vm.max_map_count до {0}", + "uk_UA": "Бажаєте збільшити значення vm.max_map_count на {0}", "zh_CN": "你想要将操作系统 vm.max_map_count 的值增加到 {0} 吗", "zh_TW": "您是否要將 vm.max_map_count 的數值增至 {0}?" } @@ -3164,10 +2606,9 @@ "pl_PL": "Niektóre gry mogą próbować przypisać sobie więcej pamięci niż obecnie, jest to dozwolone. Ryujinx ulegnie awarii, gdy limit zostanie przekroczony.", "pt_BR": "Alguns jogos podem tentar criar mais mapeamentos de memória do que o atualmente permitido. Ryujinx irá falhar assim que este limite for excedido.", "ru_RU": "Некоторые игры могут создавать большую разметку памяти, чем разрешено на данный момент по умолчанию. Ryujinx вылетит при превышении этого лимита.", - "sv_SE": "Vissa spel kan försöka att skapa fler minnesmappningar än vad som tillåts. Ryujinx kommer att krascha så snart som denna gräns överstigs.", "th_TH": "บางเกมอาจพยายามใช้งานหน่วยความจำมากกว่าที่ได้รับอนุญาตในปัจจุบัน Ryujinx จะปิดตัวลงเมื่อเกินขีดจำกัดนี้", "tr_TR": "Bazı oyunlar şu an izin verilen bellek haritası limitinden daha fazlasını yaratmaya çalışabilir. Ryujinx bu limitin geçildiği takdirde kendini kapatıcaktır.", - "uk_UA": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж це дозволено зараз. Ryujinx закриється (крашнеться), щойно цей ліміт буде перевищено.", + "uk_UA": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.", "zh_CN": "有些游戏可能会尝试创建超过当前系统允许的内存映射最大数量,若超过当前最大数量,Ryujinx 模拟器将会闪退。", "zh_TW": "某些遊戲可能會嘗試建立超過目前允許的記憶體映射。一旦超過此限制,Ryujinx 就會崩潰。" } @@ -3189,7 +2630,6 @@ "pl_PL": "Tak, do następnego ponownego uruchomienia", "pt_BR": "Sim, até a próxima reinicialização", "ru_RU": "Да, до следующего перезапуска", - "sv_SE": "Ja, tills nästa omstart", "th_TH": "ใช่, จนกว่าจะรีสตาร์ทครั้งถัดไป", "tr_TR": "Evet, bir sonraki yeniden başlatmaya kadar", "uk_UA": "Так, до наст. перезапуску", @@ -3214,10 +2654,9 @@ "pl_PL": "Tak, permanentnie ", "pt_BR": "Sim, permanentemente", "ru_RU": "Да, постоянно", - "sv_SE": "Ja, permanent", "th_TH": "ใช่, อย่างถาวร", "tr_TR": "Evet, kalıcı olarak", - "uk_UA": "Так, постійно", + "uk_UA": "Так, назавжди", "zh_CN": "确定,永久保存", "zh_TW": "是的,永久設定" } @@ -3239,10 +2678,9 @@ "pl_PL": "Maksymalna ilość przypisanej pamięci jest mniejsza niż zalecana.", "pt_BR": "A quantidade máxima de mapeamentos de memória é menor que a recomendada.", "ru_RU": "Максимальная разметка памяти меньше, чем рекомендуется.", - "sv_SE": "Maximal mängd minnesmappningar är lägre än rekommenderat.", "th_TH": "จำนวนสูงสุดของการจัดการหน่วยความจำ ต่ำกว่าที่แนะนำ", "tr_TR": "İzin verilen maksimum bellek haritası değeri tavsiye edildiğinden daha düşük. ", - "uk_UA": "Максимальний обсяг виділеної пам'яті менший за рекомендований.", + "uk_UA": "Максимальна кількість відображення памʼяті менша, ніж рекомендовано.", "zh_CN": "内存映射的最大数量低于推荐值。", "zh_TW": "記憶體映射的最大值低於建議值。" } @@ -3264,10 +2702,9 @@ "pl_PL": "Obecna wartość vm.max_map_count ({0}) jest mniejsza niż {1}. Niektóre gry mogą próbować stworzyć więcej mapowań pamięci niż obecnie jest to dozwolone. Ryujinx napotka crash, gdy dojdzie do takiej sytuacji.\n\nMożesz chcieć ręcznie zwiększyć limit lub zainstalować pkexec, co pozwala Ryujinx na pomoc w tym zakresie.", "pt_BR": "O valor atual de vm.max_map_count ({0}) é menor que {1}. Alguns jogos podem tentar criar mais mapeamentos de memória do que o permitido no momento. Ryujinx vai falhar assim que este limite for excedido.\n\nTalvez você queira aumentar o limite manualmente ou instalar pkexec, o que permite que Ryujinx ajude com isso.", "ru_RU": "Текущее значение vm.max_map_count ({0}) меньше, чем {1}. Некоторые игры могут попытаться создать большую разметку памяти, чем разрешено в данный момент. Ryujinx вылетит как только этот лимит будет превышен.\n\nВозможно, вам потребуется вручную увеличить лимит или установить pkexec, что позволит Ryujinx помочь справиться с превышением лимита.", - "sv_SE": "Det aktuella värdet för vm.max_map_count ({0}) är lägre än {1}. Vissa spel kan försöka att skapa fler minnesmappningar än vad som tillåts. Ryujinx kommer att krascha så snart som denna gräns överstigs.\n\nDu kanske vill manuellt öka gränsen eller installera pkexec, vilket tillåter att Ryujinx hjälper till med det.", "th_TH": "ค่าปัจจุบันของ vm.max_map_count ({0}) มีค่าต่ำกว่า {1} บางเกมอาจพยายามใช้หน่วยความจำมากกว่าที่ได้รับอนุญาตในปัจจุบัน Ryujinx จะปิดตัวลงเมื่อเกินขีดจำกัดนี้\n\nคุณอาจต้องการตั้งค่าเพิ่มขีดจำกัดด้วยตนเองหรือติดตั้ง pkexec ซึ่งอนุญาตให้ Ryujinx ช่วยเหลือคุณได้", "tr_TR": "Şu anki vm.max_map_count değeri {0}, bu {1} değerinden daha az. Bazı oyunlar şu an izin verilen bellek haritası limitinden daha fazlasını yaratmaya çalışabilir. Ryujinx bu limitin geçildiği takdirde kendini kapatıcaktır.\n\nManuel olarak bu limiti arttırmayı deneyebilir ya da pkexec'i yükleyebilirsiniz, bu da Ryujinx'in yardımcı olmasına izin verir.", - "uk_UA": "Поточне значення vm.max_map_count ({0}) менше за {1}. Деякі ігри можуть спробувати створити більше відображень пам’яті, ніж дозволено наразі. Ryujinx закриється (крашнеться), щойно цей ліміт буде перевищено.\n\nВи можете збільшити ліміт власноруч або встановити pkexec, який допоможе Ryujinx впоратися з перевищенням ліміту.", + "uk_UA": "Поточне значення vm.max_map_count ({0}) менше за {1}. Деякі ігри можуть спробувати створити більше відображень пам’яті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.\n\nВи можете збільшити ліміт вручну або встановити pkexec, який дозволяє Ryujinx допомогти з цим.", "zh_CN": "vm.max_map_count ({0}) 的当前值小于 {1}。 有些游戏可能会尝试创建超过当前系统允许的内存映射最大数量,若超过当前最大数量,Ryujinx 模拟器将会闪退。\n\n你可以手动增加内存映射最大数量,或者安装 pkexec,它可以辅助 Ryujinx 完成内存映射最大数量的修改操作。", "zh_TW": "目前 vm.max_map_count ({0}) 的數值小於 {1}。某些遊戲可能會嘗試建立比目前允許值更多的記憶體映射。一旦超過此限制,Ryujinx 就會崩潰。\n\n您可能需要手動提高上限,或者安裝 pkexec,讓 Ryujinx 協助提高上限。" } @@ -3289,7 +2726,6 @@ "pl_PL": "Ustawienia", "pt_BR": "Configurações", "ru_RU": "Параметры", - "sv_SE": "Inställningar", "th_TH": "ตั้งค่า", "tr_TR": "Ayarlar", "uk_UA": "Налаштування", @@ -3312,9 +2748,8 @@ "ko_KR": "사용자 인터페이스", "no_NO": "Brukergrensesnitt", "pl_PL": "Interfejs użytkownika", - "pt_BR": "Interface do Usuário", + "pt_BR": "Geral", "ru_RU": "Интерфейс", - "sv_SE": "Användargränssnitt", "th_TH": "หน้าจอผู้ใช้", "tr_TR": "Kullancı Arayüzü", "uk_UA": "Інтерфейс користувача", @@ -3339,7 +2774,6 @@ "pl_PL": "Ogólne", "pt_BR": "Geral", "ru_RU": "Общее", - "sv_SE": "Allmänt", "th_TH": "ทั่วไป", "tr_TR": "Genel", "uk_UA": "Загальні", @@ -3362,9 +2796,8 @@ "ko_KR": "디스코드 활동 상태 활성화", "no_NO": "Aktiver Discord Rik Tilstedeværelse", "pl_PL": "Włącz Bogatą Obecność Discord", - "pt_BR": "Habilitar Presença no Discord", + "pt_BR": "Habilitar Rich Presence do Discord", "ru_RU": "Статус активности в Discord", - "sv_SE": "Aktivera Discord Rich Presence", "th_TH": "เปิดใช้งาน Discord Rich Presence", "tr_TR": "Discord Zengin İçerik'i Etkinleştir", "uk_UA": "Увімкнути розширену присутність Discord", @@ -3375,251 +2808,25 @@ { "ID": "SettingsTabGeneralCheckUpdatesOnLaunch", "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Check for Updates:", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Se etter Oppdateringer:", - "pl_PL": "", - "pt_BR": "Verificar Atualizações:", - "ru_RU": "Проверка наличия обновлений", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Перевірка оновлень:", - "zh_CN": "检查更新", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralCheckUpdatesOnLaunchOff", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Off", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Av", - "pl_PL": "", - "pt_BR": "Desligado", - "ru_RU": "Отключить", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Вимкнути", - "zh_CN": "关闭", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Prompt", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Spør", - "pl_PL": "", - "pt_BR": "Ao Abrir", - "ru_RU": "При запуске", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запитувати щоразу", - "zh_CN": "提示", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralCheckUpdatesOnLaunchBackground", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Background", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Bakgrunn", - "pl_PL": "", - "pt_BR": "2° Plano", - "ru_RU": "В фоне", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Оновлювати в фоні", - "zh_CN": "背景", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossType", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "On Emulator Focus Lost:", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "På Emulator Fokus Tapt:", - "pl_PL": "", - "pt_BR": "Ao Perder o Foco:", - "ru_RU": "При выходе эмулятора из фокуса", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "При втраті фокуса емулятором:", - "zh_CN": "当模拟器在后台时:", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossTypeDoNothing", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Do Nothing", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Gjør Ingenting", - "pl_PL": "", - "pt_BR": "Não Fazer Nada", - "ru_RU": "Ничего не делать", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Нічого не робити", - "zh_CN": "什么事情也不做", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossTypeBlockInput", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Block Input", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Blokkinngang", - "pl_PL": "", - "pt_BR": "Bloquear Controles", - "ru_RU": "Блокировать управление", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Блокувати введення", - "zh_CN": "禁用输入", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossTypeMuteAudio", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Mute Volume", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Demp Lyd", - "pl_PL": "", - "pt_BR": "Ficar Mudo", - "ru_RU": "Отключить звук", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Вимкнути звук", - "zh_CN": "静音", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Block Input & Mute Volume", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Blokker Inputs og demp Volumet", - "pl_PL": "", - "pt_BR": "Bloquear Controles & Ficar Mudo", - "ru_RU": "Блокировать управление и отключить звук", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Блокувати введення та Вимкнути звук", - "zh_CN": "阻止输入且静音", - "zh_TW": "" - } - }, - { - "ID": "SettingsTabGeneralFocusLossTypePauseEmulation", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Pause Emulation", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Pause Emulatoren", - "pl_PL": "", - "pt_BR": "Pausar a Emulação", - "ru_RU": "Поставить паузу", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Поставити на паузу", - "zh_CN": "暂停模拟", - "zh_TW": "" + "ar_SA": "التحقق من وجود تحديثات عند التشغيل", + "de_DE": "Beim Start nach Updates suchen", + "el_GR": "Έλεγχος για Ενημερώσεις στην Εκκίνηση", + "en_US": "Check for Updates on Launch", + "es_ES": "Buscar actualizaciones al iniciar", + "fr_FR": "Vérifier les mises à jour au démarrage", + "he_IL": "בדוק אם קיימים עדכונים בהפעלה", + "it_IT": "Controlla aggiornamenti all'avvio", + "ja_JP": "起動時にアップデートを確認する", + "ko_KR": "시작 시, 업데이트 확인", + "no_NO": "Se etter oppdateringer ved oppstart", + "pl_PL": "Sprawdzaj aktualizacje przy uruchomieniu", + "pt_BR": "Verificar se há atualizações ao iniciar", + "ru_RU": "Проверять наличие обновлений при запуске", + "th_TH": "ตรวจหาการอัปเดตเมื่อเปิดโปรแกรม", + "tr_TR": "Her Açılışta Güncellemeleri Denetle", + "uk_UA": "Перевіряти наявність оновлень під час запуску", + "zh_CN": "启动时检查更新", + "zh_TW": "啟動時檢查更新" } }, { @@ -3637,9 +2844,8 @@ "ko_KR": "\"종료 확인\" 대화 상자 표시", "no_NO": "Vis \"Bekreft Avslutt\" vinduet", "pl_PL": "Pokazuj okno dialogowe \"Potwierdź wyjście\"", - "pt_BR": "Exibir \"Diálogo de confirmação\" ao Sair", + "pt_BR": "Exibir diálogo de confirmação ao sair", "ru_RU": "Подтверждать выход из приложения", - "sv_SE": "Visa \"Bekräfta avslut\"-dialog", "th_TH": "แสดง \"ปุ่มยืนยันการออก\" เมื่อออกเกม", "tr_TR": "\"Çıkışı Onayla\" Diyaloğunu Göster", "uk_UA": "Показати діалогове вікно «Підтвердити вихід».", @@ -3657,14 +2863,13 @@ "es_ES": "Recordar Tamaño/Posición de la Ventana", "fr_FR": "Mémoriser la taille/position de la fenêtre", "he_IL": "", - "it_IT": "Ricorda la dimensione e la posizione della finestra", + "it_IT": "Ricorda Dimensione/Posizione Finestra", "ja_JP": "", "ko_KR": "창 크기/위치 기억", "no_NO": "Husk vinduets størrelse/posisjon", "pl_PL": "", - "pt_BR": "Lembrar Tamanho e Posição da Janela", + "pt_BR": "Lembrar tamanho/posição da Janela", "ru_RU": "Запомнить размер/положение окна", - "sv_SE": "Kom ihåg fönstrets storlek/position", "th_TH": "จดจำ ขนาดหน้าต่างแอพพลิเคชั่น/คำแหน่ง", "tr_TR": "", "uk_UA": "Запам'ятати Розмір/Позицію вікна", @@ -3672,31 +2877,6 @@ "zh_TW": "記住視窗大小/位置" } }, - { - "ID": "SettingsTabGeneralDisableInputWhenOutOfFocus", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Disable Input when Out of Focus", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Deaktiver inndata når vinduet er ute av fokus", - "pl_PL": "", - "pt_BR": "Desativar Controles Quando Estiver Fora de Foco", - "ru_RU": "Отключает управление при выходе из фокуса", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "在后台时禁用输入", - "zh_TW": "" - } - }, { "ID": "SettingsTabGeneralShowTitleBar", "Translations": { @@ -3712,9 +2892,8 @@ "ko_KR": "제목 표시줄 표시(다시 시작해야 함)", "no_NO": "Vis tittellinje (krever omstart)", "pl_PL": "", - "pt_BR": "Mostrar Barra de Título (Requer reinicialização)", - "ru_RU": "Показать строку заголовка (требуется перезапуск)", - "sv_SE": "Visa titelrad (kräver omstart)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Показувати рядок заголовка (Потрібен перезапуск)", @@ -3737,12 +2916,11 @@ "ko_KR": "커서 숨기기 :", "no_NO": "Skjul musepeker:", "pl_PL": "Ukryj kursor:", - "pt_BR": "Esconder Cursor do Mouse:", + "pt_BR": "Esconder o cursor do mouse:", "ru_RU": "Скрывать курсор", - "sv_SE": "Dölj markör:", "th_TH": "ซ่อน เคอร์เซอร์:", "tr_TR": "İşaretçiyi Gizle:", - "uk_UA": "Сховати курсор:", + "uk_UA": "Сховати вказівник:", "zh_CN": "隐藏鼠标指针:", "zh_TW": "隱藏滑鼠游標:" } @@ -3764,7 +2942,6 @@ "pl_PL": "Nigdy", "pt_BR": "Nunca", "ru_RU": "Никогда", - "sv_SE": "Aldrig", "th_TH": "ไม่ต้อง", "tr_TR": "Hiçbir Zaman", "uk_UA": "Ніколи", @@ -3787,9 +2964,8 @@ "ko_KR": "유휴 상태", "no_NO": "Når inaktiv", "pl_PL": "Gdy bezczynny", - "pt_BR": "Quando Ocioso", + "pt_BR": "Esconder o cursor quando ocioso", "ru_RU": "В простое", - "sv_SE": "Vid overksam", "th_TH": "เมื่อไม่ได้ใช้งาน", "tr_TR": "Hareketsiz Durumda", "uk_UA": "Сховати у режимі очікування", @@ -3814,7 +2990,6 @@ "pl_PL": "Zawsze", "pt_BR": "Sempre", "ru_RU": "Всегда", - "sv_SE": "Alltid", "th_TH": "ตลอดเวลา", "tr_TR": "Her Zaman", "uk_UA": "Завжди", @@ -3837,9 +3012,8 @@ "ko_KR": "게임 데릭터리", "no_NO": "Spillmapper", "pl_PL": "Katalogi gier", - "pt_BR": "Pasta de Jogos", + "pt_BR": "Diretórios de jogo", "ru_RU": "Папки с играми", - "sv_SE": "Spelkataloger", "th_TH": "ไดเรกทอรี่ของเกม", "tr_TR": "Oyun Dizinleri", "uk_UA": "Тека ігор", @@ -3857,18 +3031,17 @@ "es_ES": "Carpetas de DLC/Actualizaciones para Carga Automática", "fr_FR": "Dossiers des mises à jour/DLC", "he_IL": "", - "it_IT": "Cartelle di caricamento automatico di DLC/aggiornamenti", + "it_IT": "Directory di Caricamento Automatico per DLC/Aggiornamenti", "ja_JP": "", "ko_KR": "DLC/업데이트 디렉터리 자동 불러오기", "no_NO": "Autoload DLC/Updates-mapper", "pl_PL": "", - "pt_BR": "Carregar Automaticamente Pasta de DLC e Atualizações", - "ru_RU": "Автозагрузка папки с DLC/Обновлениями", - "sv_SE": "Läs automatisk in DLC/speluppdateringar", + "pt_BR": "Carregar Automaticamente Diretórios de DLC/Atualizações", + "ru_RU": "", "th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ", "tr_TR": "", - "uk_UA": "Автозавантаження теки DLC/Оновлень", - "zh_CN": "自动加载 DLC 及 游戏更新 的目录", + "uk_UA": "Автозавантаження каталогів DLC/Оновлень", + "zh_CN": "自动加载DLC/游戏更新目录", "zh_TW": "自動載入 DLC/遊戲更新資料夾" } }, @@ -3882,18 +3055,17 @@ "es_ES": "DLC y Actualizaciones que hacen referencia a archivos ausentes serán desactivado automáticamente", "fr_FR": "Les DLC et les mises à jour faisant référence aux fichiers manquants seront automatiquement déchargés.", "he_IL": "", - "it_IT": "Aggiornamenti e DLC che fanno riferimento a file mancanti verranno disabilitati automaticamente", + "it_IT": "Aggiornamenti e DLC che collegano a file mancanti verranno disabilitati automaticamente", "ja_JP": "", - "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 불러오기 취소", + "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 언로드", "no_NO": "DLC og oppdateringer som henviser til manglende filer, vil bli lastet ned automatisk", "pl_PL": "", - "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão desabilitados automaticamente", - "ru_RU": "DLC и обновления, которые ссылаются на отсутствующие файлы, будут выгружаться автоматически", - "sv_SE": "DLC och speluppdateringar som refererar till saknade filer kommer inte att läsas in automatiskt", + "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão descarregadas automaticamente", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.", - "zh_CN": "DLC 及 游戏更新 可自动加载和卸载", + "zh_CN": "DLC/游戏更新可自动加载和卸载", "zh_TW": "遺失的 DLC 及遊戲更新檔案將會在自動載入中移除" } }, @@ -3914,7 +3086,6 @@ "pl_PL": "Dodaj", "pt_BR": "Adicionar", "ru_RU": "Добавить", - "sv_SE": "Lägg till", "th_TH": "เพิ่ม", "tr_TR": "Ekle", "uk_UA": "Додати", @@ -3939,7 +3110,6 @@ "pl_PL": "Usuń", "pt_BR": "Remover", "ru_RU": "Удалить", - "sv_SE": "Ta bort", "th_TH": "เอาออก", "tr_TR": "Kaldır", "uk_UA": "Видалити", @@ -3960,11 +3130,10 @@ "it_IT": "Sistema", "ja_JP": "システム", "ko_KR": "시스템", - "no_NO": "", + "no_NO": "System", "pl_PL": "", "pt_BR": "Sistema", "ru_RU": "Система", - "sv_SE": "", "th_TH": "ระบบ", "tr_TR": "Sistem", "uk_UA": "Система", @@ -3989,7 +3158,6 @@ "pl_PL": "Główne", "pt_BR": "Principal", "ru_RU": "Основные настройки", - "sv_SE": "Kärna", "th_TH": "แกนกลาง", "tr_TR": "Çekirdek", "uk_UA": "Ядро", @@ -4012,9 +3180,8 @@ "ko_KR": "시스템 지역 :", "no_NO": "System region:", "pl_PL": "Region systemu:", - "pt_BR": "Região do Sistema:", + "pt_BR": "Região do sistema:", "ru_RU": "Регион прошивки:", - "sv_SE": "Systemregion:", "th_TH": "ภูมิภาคของระบบ:", "tr_TR": "Sistem Bölgesi:", "uk_UA": "Регіон системи:", @@ -4035,11 +3202,10 @@ "it_IT": "Giappone", "ja_JP": "日本", "ko_KR": "일본", - "no_NO": "", + "no_NO": "Japan", "pl_PL": "Japonia", "pt_BR": "Japão", "ru_RU": "Япония", - "sv_SE": "", "th_TH": "ญี่ปุ่น", "tr_TR": "Japonya", "uk_UA": "Японія", @@ -4060,11 +3226,10 @@ "it_IT": "Stati Uniti d'America", "ja_JP": "アメリカ", "ko_KR": "미국", - "no_NO": "", + "no_NO": "USA", "pl_PL": "Stany Zjednoczone", "pt_BR": "EUA", "ru_RU": "США", - "sv_SE": "", "th_TH": "สหรัฐอเมริกา", "tr_TR": "ABD", "uk_UA": "США", @@ -4089,7 +3254,6 @@ "pl_PL": "Europa", "pt_BR": "Europa", "ru_RU": "Европа", - "sv_SE": "Europa", "th_TH": "ยุโรป", "tr_TR": "Avrupa", "uk_UA": "Європа", @@ -4110,11 +3274,10 @@ "it_IT": "", "ja_JP": "オーストラリア", "ko_KR": "호주", - "no_NO": "", + "no_NO": "Australia", "pl_PL": "", "pt_BR": "Austrália", "ru_RU": "Австралия", - "sv_SE": "Australien", "th_TH": "ออสเตรเลีย", "tr_TR": "Avustralya", "uk_UA": "Австралія", @@ -4139,7 +3302,6 @@ "pl_PL": "Chiny", "pt_BR": "", "ru_RU": "Китай", - "sv_SE": "Kina", "th_TH": "จีน", "tr_TR": "Çin", "uk_UA": "Китай", @@ -4160,11 +3322,10 @@ "it_IT": "Corea", "ja_JP": "韓国", "ko_KR": "한국", - "no_NO": "Koreansk", + "no_NO": "Korea", "pl_PL": "", "pt_BR": "Coreia", "ru_RU": "Корея", - "sv_SE": "", "th_TH": "เกาหลี", "tr_TR": "Kore", "uk_UA": "Корея", @@ -4185,11 +3346,10 @@ "it_IT": "", "ja_JP": "台湾", "ko_KR": "대만", - "no_NO": "", + "no_NO": "Taiwan", "pl_PL": "Tajwan", "pt_BR": "", "ru_RU": "Тайвань", - "sv_SE": "", "th_TH": "ไต้หวัน", "tr_TR": "Tayvan", "uk_UA": "Тайвань", @@ -4212,9 +3372,8 @@ "ko_KR": "시스템 언어 :", "no_NO": "Systemspråk", "pl_PL": "Język systemu:", - "pt_BR": "Idioma do Sistema:", - "ru_RU": "Язык системы:", - "sv_SE": "Systemspråk:", + "pt_BR": "Idioma do sistema:", + "ru_RU": "Язык прошивки:", "th_TH": "ภาษาของระบบ:", "tr_TR": "Sistem Dili:", "uk_UA": "Мова системи:", @@ -4239,7 +3398,6 @@ "pl_PL": "Japoński", "pt_BR": "Japonês", "ru_RU": "Японский", - "sv_SE": "Japanska", "th_TH": "ญี่ปุ่น", "tr_TR": "Japonca", "uk_UA": "Японська", @@ -4262,9 +3420,8 @@ "ko_KR": "미국 영어", "no_NO": "Amerikansk engelsk", "pl_PL": "Angielski (Stany Zjednoczone)", - "pt_BR": "Inglês Americano", + "pt_BR": "Inglês americano", "ru_RU": "Английский (США)", - "sv_SE": "Amerikansk engelska", "th_TH": "อังกฤษ (อเมริกัน)", "tr_TR": "Amerikan İngilizcesi", "uk_UA": "Англійська (США)", @@ -4289,7 +3446,6 @@ "pl_PL": "Francuski", "pt_BR": "Francês", "ru_RU": "Французский", - "sv_SE": "Franska", "th_TH": "ฝรั่งเศส", "tr_TR": "Fransızca", "uk_UA": "Французька", @@ -4313,8 +3469,7 @@ "no_NO": "Tysk", "pl_PL": "Niemiecki", "pt_BR": "Alemão", - "ru_RU": "Немецкий", - "sv_SE": "Tyska", + "ru_RU": "Германский", "th_TH": "เยอรมัน", "tr_TR": "Almanca", "uk_UA": "Німецька", @@ -4339,7 +3494,6 @@ "pl_PL": "Włoski", "pt_BR": "Italiano", "ru_RU": "Итальянский", - "sv_SE": "Italienska", "th_TH": "อิตาลี", "tr_TR": "İtalyanca", "uk_UA": "Італійська", @@ -4364,7 +3518,6 @@ "pl_PL": "Hiszpański", "pt_BR": "Espanhol", "ru_RU": "Испанский", - "sv_SE": "Spanska", "th_TH": "สเปน", "tr_TR": "İspanyolca", "uk_UA": "Іспанська", @@ -4389,7 +3542,6 @@ "pl_PL": "Chiński", "pt_BR": "Chinês", "ru_RU": "Китайский", - "sv_SE": "Kinesiska", "th_TH": "จีน", "tr_TR": "Çince", "uk_UA": "Китайська", @@ -4414,7 +3566,6 @@ "pl_PL": "Koreański", "pt_BR": "Coreano", "ru_RU": "Корейский", - "sv_SE": "Koreanska", "th_TH": "เกาหลี", "tr_TR": "Korece", "uk_UA": "Корейська", @@ -4439,7 +3590,6 @@ "pl_PL": "Holenderski", "pt_BR": "Holandês", "ru_RU": "Нидерландский", - "sv_SE": "Nederländska", "th_TH": "ดัตช์", "tr_TR": "Flemenkçe", "uk_UA": "Нідерландська", @@ -4464,7 +3614,6 @@ "pl_PL": "Portugalski", "pt_BR": "Português", "ru_RU": "Португальский", - "sv_SE": "Portugisiska", "th_TH": "โปรตุเกส", "tr_TR": "Portekizce", "uk_UA": "Португальська", @@ -4489,7 +3638,6 @@ "pl_PL": "Rosyjski", "pt_BR": "Russo", "ru_RU": "Русский", - "sv_SE": "Ryska", "th_TH": "รัสเซีย", "tr_TR": "Rusça", "uk_UA": "Російська", @@ -4513,8 +3661,7 @@ "no_NO": "Taiwansk", "pl_PL": "Tajwański", "pt_BR": "Taiwanês", - "ru_RU": "Тайваньский", - "sv_SE": "Taiwanesiska", + "ru_RU": "Тайванский", "th_TH": "จีนตัวเต็ม (ไต้หวัน)", "tr_TR": "Tayvanca", "uk_UA": "Тайванська", @@ -4537,9 +3684,8 @@ "ko_KR": "영국 영어", "no_NO": "Britisk engelsk", "pl_PL": "Angielski (Wielka Brytania)", - "pt_BR": "Inglês Britânico", - "ru_RU": "Английский (Великобритания)", - "sv_SE": "Brittisk engelska", + "pt_BR": "Inglês britânico", + "ru_RU": "Английский (Британия)", "th_TH": "อังกฤษ (บริติช)", "tr_TR": "İngiliz İngilizcesi", "uk_UA": "Англійська (Великобританія)", @@ -4562,9 +3708,8 @@ "ko_KR": "캐나다 프랑스어", "no_NO": "Canadisk Fransk", "pl_PL": "Kanadyjski Francuski", - "pt_BR": "Francês Canadense", + "pt_BR": "Francês canadense", "ru_RU": "Французский (Канада)", - "sv_SE": "Kanadensisk franska", "th_TH": "ฝรั่งเศส (แคนาดา)", "tr_TR": "Kanada Fransızcası", "uk_UA": "Французька (Канада)", @@ -4587,9 +3732,8 @@ "ko_KR": "남미 스페인어", "no_NO": "Latinamerikansk spansk", "pl_PL": "Hiszpański (Ameryka Łacińska)", - "pt_BR": "Espanhol Latino", + "pt_BR": "Espanhol latino", "ru_RU": "Испанский (Латинская Америка)", - "sv_SE": "Latinamerikansk spanska", "th_TH": "สเปน (ลาตินอเมริกา)", "tr_TR": "Latin Amerika İspanyolcası", "uk_UA": "Іспанська (Латиноамериканська)", @@ -4612,9 +3756,8 @@ "ko_KR": "중국어 간체", "no_NO": "Forenklet kinesisk", "pl_PL": "Chiński (Uproszczony)", - "pt_BR": "Chinês Simplificado", + "pt_BR": "Chinês simplificado", "ru_RU": "Китайский (упрощённый)", - "sv_SE": "Förenklad kinesiska", "th_TH": "จีน (ตัวย่อ)", "tr_TR": "Basitleştirilmiş Çince", "uk_UA": "Спрощена китайська", @@ -4637,9 +3780,8 @@ "ko_KR": "중국어 번체", "no_NO": "Tradisjonell Kinesisk", "pl_PL": "Chiński (Tradycyjny)", - "pt_BR": "Chinês Tradicional", + "pt_BR": "Chinês tradicional", "ru_RU": "Китайский (традиционный)", - "sv_SE": "Traditionell kinesiska", "th_TH": "จีน (ดั้งเดิม)", "tr_TR": "Geleneksel Çince", "uk_UA": "Традиційна китайська", @@ -4655,16 +3797,15 @@ "el_GR": "Ζώνη Ώρας Συστήματος:", "en_US": "System Time Zone:", "es_ES": "Zona horaria del sistema:", - "fr_FR": "Fuseau horaire du système\u00A0:", + "fr_FR": "Fuseau horaire du système :", "he_IL": "אזור זמן מערכת:", "it_IT": "Fuso orario del sistema:", "ja_JP": "タイムゾーン:", "ko_KR": "시스템 시간대 :", "no_NO": "System Tidssone:", "pl_PL": "Strefa czasowa systemu:", - "pt_BR": "Fuso Horário do Sistema:", - "ru_RU": "Часовой пояс системы:", - "sv_SE": "Systemets tidszon:", + "pt_BR": "Fuso horário do sistema:", + "ru_RU": "Часовой пояс прошивки:", "th_TH": "เขตเวลาของระบบ:", "tr_TR": "Sistem Saat Dilimi:", "uk_UA": "Часовий пояс системи:", @@ -4687,9 +3828,8 @@ "ko_KR": "시스템 시간 :", "no_NO": "System tid:", "pl_PL": "Czas systemu:", - "pt_BR": "Data e Hora do Sistema:", - "ru_RU": "Системное время:", - "sv_SE": "Systemtid:", + "pt_BR": "Hora do sistema:", + "ru_RU": "Системное время в прошивке:", "th_TH": "เวลาของระบบ:", "tr_TR": "Sistem Saati:", "uk_UA": "Час системи:", @@ -4703,22 +3843,21 @@ "ar_SA": "", "de_DE": "", "el_GR": "", - "en_US": "Match System Time", + "en_US": "Resync to PC Date & Time", "es_ES": "", - "fr_FR": "", + "fr_FR": "Resynchronier la Date à celle du PC", "he_IL": "", "it_IT": "", "ja_JP": "", - "ko_KR": "매치 시스템 시간", - "no_NO": "Match systemtid", + "ko_KR": "", + "no_NO": "", "pl_PL": "", - "pt_BR": "Sincronizar com o Sistema PC", - "ru_RU": "Соответствовать времени в системе", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "", - "zh_CN": "与系统时间同步", + "zh_CN": "", "zh_TW": "" } }, @@ -4737,9 +3876,8 @@ "ko_KR": "PPTC(프로파일된 영구 번역 캐시)", "no_NO": "PPTC (Profilert Vedvarende Oversettelseshurtigbuffer)", "pl_PL": "PPTC (Profilowana pamięć podręczna trwałych łłumaczeń)", - "pt_BR": "PPTC (Cache de Tradução Persistente de Perfil)", + "pt_BR": "Habilitar PPTC (Profiled Persistent Translation Cache)", "ru_RU": "Использовать PPTC (Profiled Persistent Translation Cache)", - "sv_SE": "PPTC (Profilerad bestående översättningscache)", "th_TH": "PPTC (แคชโปรไฟล์การแปลแบบถาวร)", "tr_TR": "PPTC (Profilli Sürekli Çeviri Önbelleği)", "uk_UA": "PPTC (профільований постійний кеш перекладу)", @@ -4757,14 +3895,13 @@ "es_ES": "Cache PPTC de bajo consumo", "fr_FR": "PPTC à faible puissance", "he_IL": "Low-power PPTC", - "it_IT": "Caricamento PPTC a basso consumo energetico", + "it_IT": "Low-power PPTC", "ja_JP": "Low-power PPTC", "ko_KR": "저전력 PPTC 캐시", "no_NO": "PPTC med lavt strømforbruk", "pl_PL": "Low-power PPTC", - "pt_BR": "Cache PPTC com Baixo Consumo de Energia", - "ru_RU": "PPTC с низким электропотреблением", - "sv_SE": "PPTC med låg strömförbrukning", + "pt_BR": "Low-power PPTC", + "ru_RU": "Low-power PPTC", "th_TH": "PPTC แบบพลังงานตํ่า", "tr_TR": "Low-power PPTC", "uk_UA": "Low-power PPTC", @@ -4787,14 +3924,13 @@ "ko_KR": "파일 시스템 무결성 검사", "no_NO": "FS Integritetssjekk", "pl_PL": "Sprawdzanie integralności systemu plików", - "pt_BR": "Verificações de Integridade do FS", + "pt_BR": "Habilitar verificação de integridade do sistema de arquivos", "ru_RU": "Проверка целостности файловой системы", - "sv_SE": "Integritetskontroller av filsystem", "th_TH": "ตรวจสอบความถูกต้องของ FS", "tr_TR": "FS Bütünlük Kontrolleri", "uk_UA": "Перевірка цілісності FS", "zh_CN": "启用文件系统完整性检查", - "zh_TW": "啟用檔案系統完整性檢查" + "zh_TW": "檔案系統完整性檢查" } }, { @@ -4812,9 +3948,8 @@ "ko_KR": "음향 후단부 :", "no_NO": "Lyd Backend:", "pl_PL": "Backend Dżwięku:", - "pt_BR": "Módulo de Áudio:", + "pt_BR": "Biblioteca de saída de áudio:", "ru_RU": "Аудио бэкенд:", - "sv_SE": "Ljudbakände:", "th_TH": "ระบบเสียงเบื้องหลัง:", "tr_TR": "Ses Motoru:", "uk_UA": "Аудіосистема:", @@ -4835,14 +3970,13 @@ "it_IT": "", "ja_JP": "ダミー", "ko_KR": "더미", - "no_NO": "", + "no_NO": "Dummy", "pl_PL": "Atrapa", - "pt_BR": "Nenhum", + "pt_BR": "Nenhuma", "ru_RU": "Без звука", - "sv_SE": "", "th_TH": "", "tr_TR": "Yapay", - "uk_UA": "Вимкнено", + "uk_UA": "", "zh_CN": "无", "zh_TW": "虛設 (Dummy)" } @@ -4860,11 +3994,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "OpenAL", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4889,7 +4022,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4910,11 +4042,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "SDL2", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4930,16 +4061,15 @@ "el_GR": "Μικροδιορθώσεις", "en_US": "Hacks", "es_ES": "", - "fr_FR": "", + "fr_FR": "Hacks", "he_IL": "האצות", "it_IT": "Espedienti", "ja_JP": "ハック", "ko_KR": "핵", - "no_NO": "", + "no_NO": "Hacks", "pl_PL": "Hacki", "pt_BR": "", "ru_RU": "Хаки", - "sv_SE": "Hack", "th_TH": "แฮ็ก", "tr_TR": "Hack'ler", "uk_UA": "Хитрощі", @@ -4962,9 +4092,8 @@ "ko_KR": "불안정성을 유발할 수 있음", "no_NO": "Kan forårsake ustabilitet", "pl_PL": " (mogą powodować niestabilność)", - "pt_BR": "Pode causar instabilidade", + "pt_BR": " (Pode causar instabilidade)", "ru_RU": "Возможна нестабильная работа", - "sv_SE": "Kan orsaka instabilitet", "th_TH": "อาจทำให้เกิดข้อผิดพลาดได้", "tr_TR": " (dengesizlik oluşturabilir)", "uk_UA": " (може викликати нестабільність)", @@ -4982,14 +4111,13 @@ "es_ES": "Tamaño DRAM:", "fr_FR": "Taille de la DRAM :", "he_IL": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)", - "it_IT": "Dimensione memoria DRAM:", + "it_IT": "Usa layout di memoria alternativo (per sviluppatori)", "ja_JP": "DRAMサイズ:", "ko_KR": "DRAM 크기 :", "no_NO": "DRAM Mengde", "pl_PL": "Użyj alternatywnego układu pamięci (Deweloperzy)", "pt_BR": "Tamanho da DRAM:", "ru_RU": "Использовать альтернативный макет памяти (для разработчиков)", - "sv_SE": "DRAM-storlek:", "th_TH": "ใช้หน่วยความจำสำรอง (โหมดนักพัฒนา)", "tr_TR": "Alternatif bellek düzeni kullan (Geliştirici)", "uk_UA": "Використовувати альтернативне розташування пам'яті (для розробників)", @@ -5012,9 +4140,8 @@ "ko_KR": "4GB", "no_NO": "4GB", "pl_PL": "", - "pt_BR": "4GB", - "ru_RU": "4ГиБ", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "4Гб", @@ -5037,9 +4164,8 @@ "ko_KR": "6GB", "no_NO": "6GB", "pl_PL": "", - "pt_BR": "6GB", - "ru_RU": "6ГиБ", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "6Гб", @@ -5062,9 +4188,8 @@ "ko_KR": "8GB", "no_NO": "8GB", "pl_PL": "", - "pt_BR": "8GB", - "ru_RU": "8ГиБ", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "8Гб", @@ -5087,9 +4212,8 @@ "ko_KR": "12GB", "no_NO": "12GB", "pl_PL": "", - "pt_BR": "12GB", - "ru_RU": "12ГиБ", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "12Гб", @@ -5112,9 +4236,8 @@ "ko_KR": "누락된 서비스 무시", "no_NO": "Ignorer manglende tjenester", "pl_PL": "Ignoruj Brakujące Usługi", - "pt_BR": "Ignorar Serviços Ausentes", + "pt_BR": "Ignorar serviços não implementados", "ru_RU": "Игнорировать отсутствующие службы", - "sv_SE": "Ignorera saknade tjänster", "th_TH": "เมินเฉยบริการที่หายไป", "tr_TR": "Eksik Servisleri Görmezden Gel", "uk_UA": "Ігнорувати відсутні служби", @@ -5123,28 +4246,27 @@ } }, { - "ID": "SettingsTabSystemIgnoreControllerApplet", + "ID": "SettingsTabSystemIgnoreApplet", "Translations": { "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Ignore Controller Applet", - "es_ES": "", - "fr_FR": "", + "de_DE": "Applet ignorieren", + "el_GR": "Αγνοήστε το Applet", + "en_US": "Ignore Applet", + "es_ES": "Ignorar el Applet", + "fr_FR": "Ignorer la déconnexion de la manette", "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "Ignorar Applet do Controlador", - "ru_RU": "Игнорировать апплет контроллера", - "sv_SE": "", - "th_TH": "", + "it_IT": "Ignora l'applet", + "ja_JP": "アプレットを無視する", + "ko_KR": "애플릿 무시", + "no_NO": "Ignorer appleten", + "pl_PL": "Ignoruj ​​aplet", + "pt_BR": "Ignorar applet", + "ru_RU": "Игнорировать Апплет", + "th_TH": "เมินเฉย Applet", "tr_TR": "", - "uk_UA": "Ігнорувати Аплет Контролера", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Ігнорувати Аплет", + "zh_CN": "忽略小程序", + "zh_TW": "忽略小程式" } }, { @@ -5164,7 +4286,6 @@ "pl_PL": "Grafika", "pt_BR": "Gráficos", "ru_RU": "Графика", - "sv_SE": "Grafik", "th_TH": "กราฟฟิก", "tr_TR": "Grafikler", "uk_UA": "Графіка", @@ -5189,7 +4310,6 @@ "pl_PL": "Graficzne API", "pt_BR": "API gráfica", "ru_RU": "Графические API", - "sv_SE": "Grafik-API", "th_TH": "API กราฟฟิก", "tr_TR": "Grafikler API", "uk_UA": "Графічний API", @@ -5212,9 +4332,8 @@ "ko_KR": "셰이더 캐시 활성화", "no_NO": "Aktiver Shader Cachen", "pl_PL": "Włącz pamięć podręczną cieni", - "pt_BR": "Habilitar Cache de Shader", + "pt_BR": "Habilitar cache de shader", "ru_RU": "Кэшировать шейдеры", - "sv_SE": "Aktivera Shader Cache", "th_TH": "เปิดใช้งาน แคชแสงเงา", "tr_TR": "Shader Önbelleğini Etkinleştir", "uk_UA": "Увімкнути кеш шейдерів", @@ -5237,9 +4356,8 @@ "ko_KR": "이방성 필터링 :", "no_NO": "Anisotropisk filtrering:", "pl_PL": "Filtrowanie anizotropowe:", - "pt_BR": "Filtro Anisotrópico:", + "pt_BR": "Filtragem anisotrópica:", "ru_RU": "Анизотропная фильтрация:", - "sv_SE": "Anisotropisk filtrering:", "th_TH": "ตัวกรองแบบ Anisotropic:", "tr_TR": "Eşyönsüz Doku Süzmesi:", "uk_UA": "Анізотропна фільтрація:", @@ -5257,14 +4375,13 @@ "es_ES": "Automático", "fr_FR": "", "he_IL": "אוטומטי", - "it_IT": "Automatico", + "it_IT": "", "ja_JP": "自動", "ko_KR": "자동", "no_NO": "Automatisk", "pl_PL": "Automatyczne", "pt_BR": "Automático", "ru_RU": "Автоматически", - "sv_SE": "Automatiskt", "th_TH": "อัตโนมัติ", "tr_TR": "Otomatik", "uk_UA": "Авто", @@ -5285,11 +4402,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "2배", - "no_NO": "", + "no_NO": "2x", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5310,11 +4426,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "4배", - "no_NO": "", + "no_NO": "4x", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5335,11 +4450,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "8배", - "no_NO": "", + "no_NO": "8x", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5360,11 +4474,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "16배", - "no_NO": "", + "no_NO": "16x", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5387,9 +4500,8 @@ "ko_KR": "해상도 배율 :", "no_NO": "Oppløsnings skala:", "pl_PL": "Skalowanie rozdzielczości:", - "pt_BR": "Escala de Resolução:", + "pt_BR": "Escala de resolução:", "ru_RU": "Масштабирование:", - "sv_SE": "Upplösningsskalning:", "th_TH": "อัตราส่วนความละเอียด:", "tr_TR": "Çözünürlük Ölçeği:", "uk_UA": "Роздільна здатність:", @@ -5412,9 +4524,8 @@ "ko_KR": "사용자 정의(권장하지 않음)", "no_NO": "Egendefinert (anbefales ikke)", "pl_PL": "Niestandardowa (Niezalecane)", - "pt_BR": "Customizada (Não recomendado)", + "pt_BR": "Customizada (não recomendado)", "ru_RU": "Пользовательское (не рекомендуется)", - "sv_SE": "Anpassad (rekommenderas inte)", "th_TH": "กำหนดเอง (ไม่แนะนำ)", "tr_TR": "Özel (Tavsiye Edilmez)", "uk_UA": "Користувацька (не рекомендовано)", @@ -5439,7 +4550,6 @@ "pl_PL": "Natywna (720p/1080p)", "pt_BR": "Nativa (720p/1080p)", "ru_RU": "Нативное (720p/1080p)", - "sv_SE": "Inbyggd (720p/1080p)", "th_TH": "พื้นฐานระบบ (720p/1080p)", "tr_TR": "Yerel (720p/1080p)", "uk_UA": "Стандартний (720p/1080p)", @@ -5460,11 +4570,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "2배(1440p/2160p)", - "no_NO": "", + "no_NO": "2x (1440p/2160p)", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5485,11 +4594,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "3배(2160p/3240p)", - "no_NO": "", + "no_NO": "3x (2160p/3240p)", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5512,9 +4620,8 @@ "ko_KR": "4배(2880p/4320p) (권장하지 않음)", "no_NO": "4x (2880p/4320p) (anbefales ikke)", "pl_PL": "4x (2880p/4320p) (niezalecane)", - "pt_BR": "4x (2880p/4320p) (Não recomendado)", + "pt_BR": "4x (2880p/4320p) (não recomendado)", "ru_RU": "4x (2880p/4320p) (не рекомендуется)", - "sv_SE": "4x (2880p/4320p) (rekommenderas inte)", "th_TH": "4x (2880p/4320p) (ไม่แนะนำ)", "tr_TR": "4x (2880p/4320p) (Tavsiye Edilmez)", "uk_UA": "4x (2880p/4320p) (Не рекомендується)", @@ -5537,9 +4644,8 @@ "ko_KR": "종횡비 :", "no_NO": "Bildeformat", "pl_PL": "Format obrazu:", - "pt_BR": "Proporção da Tela:", + "pt_BR": "Proporção:", "ru_RU": "Соотношение сторон:", - "sv_SE": "Bildförhållande:", "th_TH": "อัตราส่วนภาพ:", "tr_TR": "En-Boy Oranı:", "uk_UA": "Співвідношення сторін:", @@ -5560,11 +4666,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "4:3", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5585,11 +4690,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "16:9", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5610,11 +4714,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "16:10", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5635,11 +4738,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "21:9", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5660,11 +4762,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "32:9", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -5687,9 +4788,8 @@ "ko_KR": "창에 맞춰 늘리기", "no_NO": "Strekk for og Tilpasse vindu", "pl_PL": "Rozciągnij do Okna", - "pt_BR": "Esticar até Caber", + "pt_BR": "Esticar até caber", "ru_RU": "Растянуть до размеров окна", - "sv_SE": "Sträck ut för att passa fönster", "th_TH": "ยืดภาพเพื่อให้พอดีกับหน้าต่าง", "tr_TR": "Pencereye Sığdırmak İçin Genişlet", "uk_UA": "Розтягнути до розміру вікна", @@ -5714,7 +4814,6 @@ "pl_PL": "Opcje programisty", "pt_BR": "Opções do desenvolvedor", "ru_RU": "Параметры разработчика", - "sv_SE": "Utvecklarinställningar", "th_TH": "ตัวเลือกนักพัฒนา", "tr_TR": "Geliştirici Seçenekleri", "uk_UA": "Параметри розробника", @@ -5737,9 +4836,8 @@ "ko_KR": "그래픽 셰이더 덤프 경로 :", "no_NO": "Grafikk Shader Dump bane:", "pl_PL": "Ścieżka do zgranych cieni graficznych:", - "pt_BR": "Diretório para Despejo de Shaders:", + "pt_BR": "Diretório para despejo de shaders:", "ru_RU": "Путь дампа графических шейдеров", - "sv_SE": "Sökväg för Graphics Shader Dump:", "th_TH": "ที่เก็บ ดัมพ์ไฟล์ แสงเงา:", "tr_TR": "Grafik Shader Döküm Yolu:", "uk_UA": "Шлях скидання графічного шейдера:", @@ -5760,11 +4858,10 @@ "it_IT": "Log", "ja_JP": "ロギング", "ko_KR": "로그 기록", - "no_NO": "", + "no_NO": "Logging", "pl_PL": "Dziennik zdarzeń", "pt_BR": "Log", "ru_RU": "Журналирование", - "sv_SE": "Loggning", "th_TH": "ประวัติ", "tr_TR": "Loglama", "uk_UA": "Налагодження", @@ -5785,11 +4882,10 @@ "it_IT": "Log", "ja_JP": "ロギング", "ko_KR": "로그 기록", - "no_NO": "", + "no_NO": "Logging", "pl_PL": "Dziennik zdarzeń", "pt_BR": "Log", "ru_RU": "Журналирование", - "sv_SE": "Loggning", "th_TH": "ประวัติ", "tr_TR": "Loglama", "uk_UA": "Налагодження", @@ -5812,14 +4908,13 @@ "ko_KR": "파일에 로그 기록 활성화", "no_NO": "Aktiver logging til fil", "pl_PL": "Włącz rejestrowanie zdarzeń do pliku", - "pt_BR": "Salvar Logs em Arquivo", + "pt_BR": "Salvar logs em arquivo", "ru_RU": "Включить запись в файл", - "sv_SE": "Aktivera loggning till fil", "th_TH": "เปิดใช้งานการบันทึกประวัติ ไปยังไฟล์", "tr_TR": "Logları Dosyaya Kaydetmeyi Etkinleştir", "uk_UA": "Увімкнути налагодження у файл", "zh_CN": "将日志写入文件", - "zh_TW": "啟用日誌寫入到檔案" + "zh_TW": "啟用日誌到檔案" } }, { @@ -5837,9 +4932,8 @@ "ko_KR": "조각 기록 활성화", "no_NO": "Aktiver Stub-logger", "pl_PL": "Wlącz Skróty Logów", - "pt_BR": "Habilitar logs de Stub", + "pt_BR": "Habilitar logs de stub", "ru_RU": "Включить журнал-заглушку", - "sv_SE": "Aktivera stubbloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติ", "tr_TR": "Stub Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали заглушки", @@ -5862,9 +4956,8 @@ "ko_KR": "정보 기록 활성화", "no_NO": "Aktiver informasjonslogger", "pl_PL": "Włącz Logi Informacyjne", - "pt_BR": "Habilitar logs de Informação", + "pt_BR": "Habilitar logs de informação", "ru_RU": "Включить информационный журнал", - "sv_SE": "Aktivera informationsloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติการใช้งาน", "tr_TR": "Bilgi Loglarını Etkinleştir", "uk_UA": "Увімкнути інформаційні журнали", @@ -5887,9 +4980,8 @@ "ko_KR": "경고 기록 활성화", "no_NO": "Aktiver varsellogger", "pl_PL": "Włącz Logi Ostrzeżeń", - "pt_BR": "Habilitar Logs de Alerta", + "pt_BR": "Habilitar logs de alerta", "ru_RU": "Включить журнал предупреждений", - "sv_SE": "Aktivera varningsloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติคำเตือน", "tr_TR": "Uyarı Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали попереджень", @@ -5912,9 +5004,8 @@ "ko_KR": "오류 기록 활성화", "no_NO": "Aktiver feillogger", "pl_PL": "Włącz Logi Błędów", - "pt_BR": "Habilitar Logs de Erro", + "pt_BR": "Habilitar logs de erro", "ru_RU": "Включить журнал ошибок", - "sv_SE": "Aktivera felloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติข้อผิดพลาด", "tr_TR": "Hata Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали помилок", @@ -5937,9 +5028,8 @@ "ko_KR": "추적 기록 활성화", "no_NO": "Aktiver spor logger", "pl_PL": "Włącz Logi Śledzenia", - "pt_BR": "Habilitar Logs de Rastreamento", + "pt_BR": "Habilitar logs de rastreamento", "ru_RU": "Включить журнал трассировки", - "sv_SE": "Aktivera spårloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติการติดตาม", "tr_TR": "Trace Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали трасування", @@ -5962,9 +5052,8 @@ "ko_KR": "방문 기록 활성화", "no_NO": "Aktiver gjestelogger", "pl_PL": "Włącz Logi Gości", - "pt_BR": "Habilitar Logs de Convidados", + "pt_BR": "Habilitar logs do programa convidado", "ru_RU": "Включить гостевые журналы", - "sv_SE": "Aktivera gästloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติผู้เยี่ยมชม", "tr_TR": "Guest Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали гостей", @@ -5972,31 +5061,6 @@ "zh_TW": "啟用客體日誌" } }, - { - "ID": "SettingsTabLoggingEnableAvaloniaLogs", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Enable UI Logs", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Aktivere UI-logger", - "pl_PL": "", - "pt_BR": "Habilitar Logs da IU", - "ru_RU": "Включить журнал интерфейса", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Увімкнути журнали інтерфейсу", - "zh_CN": "启用 UI 日志", - "zh_TW": "" - } - }, { "ID": "SettingsTabLoggingEnableFsAccessLogs", "Translations": { @@ -6012,12 +5076,11 @@ "ko_KR": "파일 시스템 접속 기록 활성화", "no_NO": "Aktiver Fs tilgangslogger", "pl_PL": "Włącz Logi Dostępu do Systemu Plików", - "pt_BR": "Habilitar Logs de Acesso Fs", + "pt_BR": "Habilitar logs de acesso ao sistema de arquivos", "ru_RU": "Включить журналы доступа файловой системы", - "sv_SE": "Aktivera loggar för filsystemsåtkomst", "th_TH": "เปิดใช้งานการบันทึกประวัติการเข้าถึง Fs", "tr_TR": "Fs Erişim Loglarını Etkinleştir", - "uk_UA": "Увімкнути журнали доступу до файлової системи", + "uk_UA": "Увімкнути журнали доступу Fs", "zh_CN": "启用文件访问日志", "zh_TW": "啟用檔案系統存取日誌" } @@ -6037,12 +5100,11 @@ "ko_KR": "파일 시스템 전역 접속 로그 모드 :", "no_NO": "Fs Global Access-logg-modus:", "pl_PL": "Tryb globalnego dziennika zdarzeń systemu plików:", - "pt_BR": "Modo de Log de Acesso Global Fs:", + "pt_BR": "Modo global de logs do sistema de arquivos:", "ru_RU": "Режим журнала глобального доступа файловой системы:", - "sv_SE": "Loggläge för global filsystemsåtkomst:", "th_TH": "โหมด การเข้าถึงประวัติส่วนกลาง:", "tr_TR": "Fs Evrensel Erişim Log Modu:", - "uk_UA": "Режим журналу глобального доступу файлової системи:", + "uk_UA": "Режим журналу глобального доступу Fs:", "zh_CN": "文件系统全局访问日志模式:", "zh_TW": "檔案系統全域存取日誌模式:" } @@ -6062,9 +5124,8 @@ "ko_KR": "개발자 옵션", "no_NO": "Utvikleralternativer", "pl_PL": "Opcje programisty (UWAGA: wpływa na wydajność)", - "pt_BR": "Opções do desenvolvedor", + "pt_BR": "Opções do desenvolvedor (AVISO: Vai reduzir a performance)", "ru_RU": "Параметры разработчика", - "sv_SE": "Utvecklarinställningar", "th_TH": "ตัวเลือกนักพัฒนา", "tr_TR": "Geliştirici Seçenekleri (UYARI: Performansı düşürecektir)", "uk_UA": "Параметри розробника (УВАГА: шкодить продуктивності!)", @@ -6082,17 +5143,16 @@ "es_ES": "ADVERTENCIA: Reducirá el rendimiento", "fr_FR": "ATTENTION : Réduira les performances", "he_IL": "אזהרה: יפחית ביצועים", - "it_IT": "ATTENZIONE: ridurranno le prestazioni", + "it_IT": "ATTENZIONE: ridurrà le prestazioni", "ja_JP": "警告: パフォーマンスを低下させます", "ko_KR": "경고 : 성능이 감소합니다.", "no_NO": "Advarsel: Vil redusere ytelsen", "pl_PL": "UWAGA: Pogrorszy wydajność", "pt_BR": "AVISO: Reduzirá o desempenho", "ru_RU": "ВНИМАНИЕ: эти настройки снижают производительность", - "sv_SE": "VARNING: Kommer att reducera prestandan", "th_TH": "คำเตือน: จะทำให้ประสิทธิภาพลดลง", "tr_TR": "UYARI: Oyun performansı azalacak", - "uk_UA": "УВАГА: Зміна параметрів нижче має негативний вплив на продуктивність", + "uk_UA": "УВАГА: Зміна параметрів нижче негативно впливає на продуктивність", "zh_CN": "警告:会降低模拟器性能", "zh_TW": "警告: 會降低效能" } @@ -6112,12 +5172,11 @@ "ko_KR": "그래픽 후단부 기록 레벨 :", "no_NO": "Grafikk Backend-loggnivå:", "pl_PL": "Poziom rejestrowania do dziennika zdarzeń Backendu Graficznego:", - "pt_BR": "Nível de Log do Renderizador Gráfico:", + "pt_BR": "Nível de log do backend gráfico:", "ru_RU": "Уровень журнала бэкенда графики:", - "sv_SE": "Loggnivå för grafikbakände:", "th_TH": "ระดับการบันทึกประวัติ กราฟิกเบื้องหลัง:", "tr_TR": "Grafik Arka Uç Günlük Düzeyi", - "uk_UA": "Рівень журналу графічного бекенда:", + "uk_UA": "Рівень журналу графічного сервера:", "zh_CN": "图形引擎日志级别:", "zh_TW": "圖形後端日誌等級:" } @@ -6139,7 +5198,6 @@ "pl_PL": "Nic", "pt_BR": "Nenhum", "ru_RU": "Нет", - "sv_SE": "Ingen", "th_TH": "ไม่มี", "tr_TR": "Hiçbiri", "uk_UA": "Немає", @@ -6164,7 +5222,6 @@ "pl_PL": "Błędy", "pt_BR": "Erro", "ru_RU": "Ошибка", - "sv_SE": "Fel", "th_TH": "ผิดพลาด", "tr_TR": "Hata", "uk_UA": "Помилка", @@ -6189,7 +5246,6 @@ "pl_PL": "Spowolnienia", "pt_BR": "Lentidão", "ru_RU": "Замедления", - "sv_SE": "Långsamheter", "th_TH": "ช้าลง", "tr_TR": "Yavaşlamalar", "uk_UA": "Уповільнення", @@ -6214,7 +5270,6 @@ "pl_PL": "Wszystko", "pt_BR": "Todos", "ru_RU": "Всё", - "sv_SE": "Alla", "th_TH": "ทั้งหมด", "tr_TR": "Hepsi", "uk_UA": "Все", @@ -6237,9 +5292,8 @@ "ko_KR": "디버그 기록 활성화", "no_NO": "Aktiver feilsøkingslogger", "pl_PL": "Włącz dzienniki zdarzeń do debugowania", - "pt_BR": "Habilitar Logs de Depuração", + "pt_BR": "Habilitar logs de depuração", "ru_RU": "Включить журнал отладки", - "sv_SE": "Aktivera felsökningsloggar", "th_TH": "เปิดใช้งาน ประวัติข้อบกพร่อง", "tr_TR": "Hata Ayıklama Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали налагодження", @@ -6257,17 +5311,16 @@ "es_ES": "Entrada", "fr_FR": "Contrôles", "he_IL": "קלט", - "it_IT": "Comandi", + "it_IT": "", "ja_JP": "入力", "ko_KR": "입력", "no_NO": "Inndata", "pl_PL": "Sterowanie", "pt_BR": "Controle", "ru_RU": "Управление", - "sv_SE": "Inmatning", "th_TH": "ป้อนข้อมูล", "tr_TR": "Giriş Yöntemi", - "uk_UA": "Керування", + "uk_UA": "Введення", "zh_CN": "输入", "zh_TW": "輸入" } @@ -6287,9 +5340,8 @@ "ko_KR": "도킹 모드", "no_NO": "Forankret modus", "pl_PL": "Tryb zadokowany", - "pt_BR": "Modo TV", + "pt_BR": "Habilitar modo TV", "ru_RU": "Стационарный режим", - "sv_SE": "Dockat läge", "th_TH": "ด็อกโหมด", "tr_TR": "Docked Modu Etkinleştir", "uk_UA": "Режим док-станції", @@ -6312,9 +5364,8 @@ "ko_KR": "키보드 직접 접속", "no_NO": "Direkte tastaturtilgang", "pl_PL": "Bezpośredni dostęp do klawiatury", - "pt_BR": "Acesso Direto ao Teclado", + "pt_BR": "Acesso direto ao teclado", "ru_RU": "Прямой ввод клавиатуры", - "sv_SE": "Direkt tangentbordsåtkomst", "th_TH": "เข้าถึงคีย์บอร์ดโดยตรง", "tr_TR": "Doğrudan Klavye Erişimi", "uk_UA": "Прямий доступ з клавіатури", @@ -6339,7 +5390,6 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", - "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -6364,7 +5414,6 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", - "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -6372,62 +5421,12 @@ "zh_TW": "關閉" } }, - { - "ID": "SettingsButtonReset", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Reset Settings", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Tilbakestill innstillinger", - "pl_PL": "", - "pt_BR": "Redefinir Configurações", - "ru_RU": "Сбросить настройки", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Скинути налаштування", - "zh_CN": "重置设置", - "zh_TW": "" - } - }, - { - "ID": "SettingsButtonResetConfirm", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "I want to reset my settings.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Jeg vil tilbakestille innstillingene mine.", - "pl_PL": "", - "pt_BR": "Quero redefinir minhas configurações.", - "ru_RU": "Я хочу сбросить свои настройки.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Я хочу скинути налаштування.", - "zh_CN": "我要重置我的设置。", - "zh_TW": "" - } - }, { "ID": "SettingsButtonOk", "Translations": { "ar_SA": "موافق", "de_DE": "", - "el_GR": "", + "el_GR": "ΟΚ", "en_US": "OK", "es_ES": "Aceptar", "fr_FR": "", @@ -6435,14 +5434,13 @@ "it_IT": "", "ja_JP": "", "ko_KR": "확인", - "no_NO": "", + "no_NO": "OK", "pl_PL": "", "pt_BR": "", - "ru_RU": "", - "sv_SE": "Ok", + "ru_RU": "Ок", "th_TH": "ตกลง", "tr_TR": "Tamam", - "uk_UA": "", + "uk_UA": "Гаразд", "zh_CN": "确定", "zh_TW": "確定" } @@ -6464,7 +5462,6 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", - "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -6489,7 +5486,6 @@ "pl_PL": "Zastosuj", "pt_BR": "Aplicar", "ru_RU": "Применить", - "sv_SE": "Verkställ", "th_TH": "นำไปใช้", "tr_TR": "Uygula", "uk_UA": "Застосувати", @@ -6514,7 +5510,6 @@ "pl_PL": "Gracz", "pt_BR": "Jogador", "ru_RU": "Игрок", - "sv_SE": "Spelare", "th_TH": "ผู้เล่น", "tr_TR": "Oyuncu", "uk_UA": "Гравець", @@ -6539,7 +5534,6 @@ "pl_PL": "Gracz 1", "pt_BR": "Jogador 1", "ru_RU": "Игрок 1", - "sv_SE": "Spelare 1", "th_TH": "ผู้เล่นคนที่ 1", "tr_TR": "Oyuncu 1", "uk_UA": "Гравець 1", @@ -6564,7 +5558,6 @@ "pl_PL": "Gracz 2", "pt_BR": "Jogador 2", "ru_RU": "Игрок 2", - "sv_SE": "Spelare 2", "th_TH": "ผู้เล่นคนที่ 2", "tr_TR": "Oyuncu 2", "uk_UA": "Гравець 2", @@ -6589,7 +5582,6 @@ "pl_PL": "Gracz 3", "pt_BR": "Jogador 3", "ru_RU": "Игрок 3", - "sv_SE": "Spelare 3", "th_TH": "ผู้เล่นคนที่ 3", "tr_TR": "Oyuncu 3", "uk_UA": "Гравець 3", @@ -6614,7 +5606,6 @@ "pl_PL": "Gracz 4", "pt_BR": "Jogador 4", "ru_RU": "Игрок 4", - "sv_SE": "Spelare 4", "th_TH": "ผู้เล่นคนที่ 4", "tr_TR": "Oyuncu 4", "uk_UA": "Гравець 4", @@ -6639,7 +5630,6 @@ "pl_PL": "Gracz 5", "pt_BR": "Jogador 5", "ru_RU": "Игрок 5", - "sv_SE": "Spelare 5", "th_TH": "ผู้เล่นคนที่ 5", "tr_TR": "Oyuncu 5", "uk_UA": "Гравець 5", @@ -6664,7 +5654,6 @@ "pl_PL": "Gracz 6", "pt_BR": "Jogador 6", "ru_RU": "Игрок 6", - "sv_SE": "Spelare 6", "th_TH": "ผู้เล่นคนที่ 6", "tr_TR": "Oyuncu 6", "uk_UA": "Гравець 6", @@ -6689,7 +5678,6 @@ "pl_PL": "Gracz 7", "pt_BR": "Jogador 7", "ru_RU": "Игрок 7", - "sv_SE": "Spelare 7", "th_TH": "ผู้เล่นคนที่ 7", "tr_TR": "Oyuncu 7", "uk_UA": "Гравець 7", @@ -6714,7 +5702,6 @@ "pl_PL": "Gracz 8", "pt_BR": "Jogador 8", "ru_RU": "Игрок 8", - "sv_SE": "Spelare 8", "th_TH": "ผู้เล่นคนที่ 8", "tr_TR": "Oyuncu 8", "uk_UA": "Гравець 8", @@ -6739,7 +5726,6 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный", - "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์โหมด", "tr_TR": "Portatif Mod", "uk_UA": "Портативний", @@ -6762,9 +5748,8 @@ "ko_KR": "입력 장치", "no_NO": "Inndataenhet", "pl_PL": "Urządzenie wejściowe", - "pt_BR": "Dispositivo de Entrada", + "pt_BR": "Dispositivo de entrada", "ru_RU": "Устройство ввода", - "sv_SE": "Inmatningsenhet", "th_TH": "อุปกรณ์ป้อนข้อมูล", "tr_TR": "Giriş Cihazı", "uk_UA": "Пристрій введення", @@ -6789,7 +5774,6 @@ "pl_PL": "Odśwież", "pt_BR": "Atualizar", "ru_RU": "Обновить", - "sv_SE": "Uppdatera", "th_TH": "รีเฟรช", "tr_TR": "Yenile", "uk_UA": "Оновити", @@ -6814,7 +5798,6 @@ "pl_PL": "Wyłączone", "pt_BR": "Desabilitado", "ru_RU": "Отключить", - "sv_SE": "Inaktiverad", "th_TH": "ปิดการใช้งาน", "tr_TR": "Devre Dışı", "uk_UA": "Вимкнено", @@ -6837,9 +5820,8 @@ "ko_KR": "컨트롤러 유형", "no_NO": "Kontrollertype", "pl_PL": "Typ kontrolera", - "pt_BR": "Tipo de Controle", + "pt_BR": "Tipo do controle", "ru_RU": "Тип контроллера", - "sv_SE": "Kontrollertyp", "th_TH": "ประเภทคอนโทรลเลอร์", "tr_TR": "Kumanda Tipi", "uk_UA": "Тип контролера", @@ -6864,7 +5846,6 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный", - "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์", "tr_TR": "Portatif Mod", "uk_UA": "Портативний", @@ -6889,10 +5870,9 @@ "pl_PL": "Pro Kontroler", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "โปรคอนโทรลเลอร์", "tr_TR": "Profesyonel Kumanda", - "uk_UA": "Геймпад Nintendo Switch Pro", + "uk_UA": "Контролер Pro", "zh_CN": "Pro 手柄", "zh_TW": "Pro 控制器" } @@ -6914,7 +5894,6 @@ "pl_PL": "Para JoyCon-ów", "pt_BR": "Par de JoyCon", "ru_RU": "JoyCon (пара)", - "sv_SE": "JoyCon (par)", "th_TH": "จับคู่ จอยคอน", "tr_TR": "JoyCon Çifti", "uk_UA": "Обидва JoyCon", @@ -6937,9 +5916,8 @@ "ko_KR": "좌측 조이콘", "no_NO": "JoyCon venstre", "pl_PL": "Lewy JoyCon", - "pt_BR": "JoyCon Esquerdo", + "pt_BR": "JoyCon esquerdo", "ru_RU": "JoyCon (левый)", - "sv_SE": "JoyCon vänster", "th_TH": "จอยคอน ด้านซ้าย", "tr_TR": "JoyCon Sol", "uk_UA": "Лівий JoyCon", @@ -6962,9 +5940,8 @@ "ko_KR": "우측 조이콘", "no_NO": "JoyCon høyre", "pl_PL": "Prawy JoyCon", - "pt_BR": "JoyCon Direito", + "pt_BR": "JoyCon direito", "ru_RU": "JoyCon (правый)", - "sv_SE": "JoyCon höger", "th_TH": "จอยคอน ด้านขวา", "tr_TR": "JoyCon Sağ", "uk_UA": "Правий JoyCon", @@ -6989,7 +5966,6 @@ "pl_PL": "Profil", "pt_BR": "Perfil", "ru_RU": "Профиль", - "sv_SE": "Profil", "th_TH": "โปรไฟล์", "tr_TR": "Profil", "uk_UA": "Профіль", @@ -7014,7 +5990,6 @@ "pl_PL": "Domyślny", "pt_BR": "Padrão", "ru_RU": "По умолчанию", - "sv_SE": "Standard", "th_TH": "ค่าเริ่มต้น", "tr_TR": "Varsayılan", "uk_UA": "Типовий", @@ -7039,7 +6014,6 @@ "pl_PL": "Wczytaj", "pt_BR": "Carregar", "ru_RU": "Загрузить", - "sv_SE": "Läs in", "th_TH": "โหลด", "tr_TR": "Yükle", "uk_UA": "Завантажити", @@ -7064,7 +6038,6 @@ "pl_PL": "Dodaj", "pt_BR": "Adicionar", "ru_RU": "Добавить", - "sv_SE": "Lägg till", "th_TH": "เพิ่ม", "tr_TR": "Ekle", "uk_UA": "Додати", @@ -7089,7 +6062,6 @@ "pl_PL": "Usuń", "pt_BR": "Remover", "ru_RU": "Удалить", - "sv_SE": "Ta bort", "th_TH": "เอาออก", "tr_TR": "Kaldır", "uk_UA": "Видалити", @@ -7114,7 +6086,6 @@ "pl_PL": "Przyciski", "pt_BR": "Botões", "ru_RU": "Кнопки", - "sv_SE": "Knappar", "th_TH": "ปุ่มกด", "tr_TR": "Tuşlar", "uk_UA": "Кнопки", @@ -7135,11 +6106,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "A", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7160,11 +6130,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "B", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7185,11 +6154,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "X", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7210,11 +6178,10 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Y", "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7239,7 +6206,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7264,7 +6230,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7287,9 +6252,8 @@ "ko_KR": "방향키", "no_NO": "Retningsfelt", "pl_PL": "Krzyżak (D-Pad)", - "pt_BR": "Direcional (D-Pad)", - "ru_RU": "Кнопки направления (D-pad)", - "sv_SE": "Riktningsknappar", + "pt_BR": "Direcional", + "ru_RU": "Кнопки направления", "th_TH": "ปุ่มลูกศร", "tr_TR": "Yön Tuşları", "uk_UA": "Панель направлення", @@ -7314,7 +6278,6 @@ "pl_PL": "Góra", "pt_BR": "Cima", "ru_RU": "Вверх", - "sv_SE": "Upp", "th_TH": "ขึ้น", "tr_TR": "Yukarı", "uk_UA": "Вгору", @@ -7339,7 +6302,6 @@ "pl_PL": "Dół", "pt_BR": "Baixo", "ru_RU": "Вниз", - "sv_SE": "Ner", "th_TH": "ลง", "tr_TR": "Aşağı", "uk_UA": "Вниз", @@ -7364,7 +6326,6 @@ "pl_PL": "Lewo", "pt_BR": "Esquerda", "ru_RU": "Влево", - "sv_SE": "Vänster", "th_TH": "ซ้าย", "tr_TR": "Sol", "uk_UA": "Вліво", @@ -7389,7 +6350,6 @@ "pl_PL": "Prawo", "pt_BR": "Direita", "ru_RU": "Вправо", - "sv_SE": "Höger", "th_TH": "ขวา", "tr_TR": "Sağ", "uk_UA": "Вправо", @@ -7414,12 +6374,11 @@ "pl_PL": "Przycisk", "pt_BR": "Botão", "ru_RU": "Нажатие на стик", - "sv_SE": "Knapp", "th_TH": "ปุ่ม", "tr_TR": "Tuş", "uk_UA": "Кнопка", "zh_CN": "按下摇杆", - "zh_TW": "搖桿按鍵" + "zh_TW": "按鍵" } }, { @@ -7439,7 +6398,6 @@ "pl_PL": "Góra ", "pt_BR": "Cima", "ru_RU": "Вверх", - "sv_SE": "Upp", "th_TH": "ขึ้น", "tr_TR": "Yukarı", "uk_UA": "Уверх", @@ -7464,7 +6422,6 @@ "pl_PL": "Dół ", "pt_BR": "Baixo", "ru_RU": "Вниз", - "sv_SE": "Ner", "th_TH": "ลง", "tr_TR": "Aşağı", "uk_UA": "Униз", @@ -7489,7 +6446,6 @@ "pl_PL": "Lewo", "pt_BR": "Esquerda", "ru_RU": "Влево", - "sv_SE": "Vänster", "th_TH": "ซ้าย", "tr_TR": "Sol", "uk_UA": "Ліворуч", @@ -7514,7 +6470,6 @@ "pl_PL": "Prawo", "pt_BR": "Direita", "ru_RU": "Вправо", - "sv_SE": "Höger", "th_TH": "ขวา", "tr_TR": "Sağ", "uk_UA": "Праворуч", @@ -7539,7 +6494,6 @@ "pl_PL": "Gałka", "pt_BR": "Analógico", "ru_RU": "Стик", - "sv_SE": "Spak", "th_TH": "จอยสติ๊ก", "tr_TR": "Analog", "uk_UA": "Стик", @@ -7562,9 +6516,8 @@ "ko_KR": "스틱 X축 반전", "no_NO": "Inverter Styrespak X", "pl_PL": "Odwróć gałkę X", - "pt_BR": "Inverter Eixo X", + "pt_BR": "Inverter eixo X", "ru_RU": "Инвертировать ось X", - "sv_SE": "Invertera Spak X", "th_TH": "กลับทิศทางของแกน X", "tr_TR": "X Eksenini Tersine Çevir", "uk_UA": "Обернути вісь стику X", @@ -7587,9 +6540,8 @@ "ko_KR": "스틱 Y축 반전", "no_NO": "Inverter Styrespak Y", "pl_PL": "Odwróć gałkę Y", - "pt_BR": "Inverter Eixo Y", + "pt_BR": "Inverter eixo Y", "ru_RU": "Инвертировать ось Y", - "sv_SE": "Invertera Spak Y", "th_TH": "กลับทิศทางของแกน Y", "tr_TR": "Y Eksenini Tersine Çevir", "uk_UA": "Обернути вісь стику Y", @@ -7612,9 +6564,8 @@ "ko_KR": "데드존 :", "no_NO": "Død sone:", "pl_PL": "Martwa strefa:", - "pt_BR": "Zona Morta:", + "pt_BR": "Zona morta:", "ru_RU": "Мёртвая зона:", - "sv_SE": "Dödläge:", "th_TH": "โซนที่ไม่ทำงานของ จอยสติ๊ก:", "tr_TR": "Ölü Bölge", "uk_UA": "Мертва зона:", @@ -7637,9 +6588,8 @@ "ko_KR": "좌측 스틱", "no_NO": "Venstre styrespak", "pl_PL": "Lewa Gałka", - "pt_BR": "Analógico Esquerdo", + "pt_BR": "Analógico esquerdo", "ru_RU": "Левый стик", - "sv_SE": "Vänster spak", "th_TH": "จอยสติ๊ก ด้านซ้าย", "tr_TR": "Sol Analog", "uk_UA": "Лівий джойстик", @@ -7662,9 +6612,8 @@ "ko_KR": "우측 스틱", "no_NO": "Høyre styrespak", "pl_PL": "Prawa Gałka", - "pt_BR": "Analógico Direito", + "pt_BR": "Analógico direito", "ru_RU": "Правый стик", - "sv_SE": "Höger spak", "th_TH": "จอยสติ๊ก ด้านขวา", "tr_TR": "Sağ Analog", "uk_UA": "Правий джойстик", @@ -7687,9 +6636,8 @@ "ko_KR": "좌측 트리거", "no_NO": "Utløsere venstre", "pl_PL": "Lewe Triggery", - "pt_BR": "Gatilho Esquerda", + "pt_BR": "Gatilhos esquerda", "ru_RU": "Триггеры слева", - "sv_SE": "Avtryckare vänster", "th_TH": "ทริกเกอร์ ด้านซ้าย", "tr_TR": "Tetikler Sol", "uk_UA": "Тригери ліворуч", @@ -7712,9 +6660,8 @@ "ko_KR": "우측 트리거", "no_NO": "Utløsere høyre", "pl_PL": "Prawe Triggery", - "pt_BR": "Gatilho Direita", + "pt_BR": "Gatilhos direita", "ru_RU": "Триггеры справа", - "sv_SE": "Avtryckare höger", "th_TH": "ทริกเกอร์ ด้านขวา", "tr_TR": "Tetikler Sağ", "uk_UA": "Тригери праворуч", @@ -7737,9 +6684,8 @@ "ko_KR": "좌측 트리거 버튼", "no_NO": "Utløserknapper Venstre", "pl_PL": "Lewe Przyciski Triggerów", - "pt_BR": "Botões de Gatilho da Esquerda", + "pt_BR": "Botões de gatilho esquerda", "ru_RU": "Триггерные кнопки слева", - "sv_SE": "Avtryckare knappar vänster", "th_TH": "ปุ่มทริกเกอร์ ด้านซ้าย", "tr_TR": "Tetik Tuşları Sol", "uk_UA": "Кнопки тригерів ліворуч", @@ -7762,9 +6708,8 @@ "ko_KR": "우측 트리거 버튼", "no_NO": "Utløserknapper høyre", "pl_PL": "Prawe Przyciski Triggerów", - "pt_BR": "Botões de Gatilho da Direita", + "pt_BR": "Botões de gatilho direita", "ru_RU": "Триггерные кнопки справа", - "sv_SE": "Avtryckare knappar höger", "th_TH": "ปุ่มทริกเกอร์ ด้านขวา", "tr_TR": "Tetik Tuşları Sağ", "uk_UA": "Кнопки тригерів праворуч", @@ -7789,7 +6734,6 @@ "pl_PL": "Triggery", "pt_BR": "Gatilhos", "ru_RU": "Триггеры", - "sv_SE": "Avtryckare", "th_TH": "ทริกเกอร์", "tr_TR": "Tetikler", "uk_UA": "Тригери", @@ -7814,7 +6758,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7839,7 +6782,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7864,7 +6806,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7889,7 +6830,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7914,7 +6854,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7939,7 +6878,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7964,7 +6902,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7989,7 +6926,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8012,9 +6948,8 @@ "ko_KR": "좌측 버튼", "no_NO": "Knapper til venstre", "pl_PL": "Lewe Przyciski", - "pt_BR": "Botões da Esquerda", + "pt_BR": "Botões esquerda", "ru_RU": "Левые кнопки", - "sv_SE": "Knappar vänster", "th_TH": "ปุ่มกดเสริม ด้านซ้าย", "tr_TR": "Tuşlar Sol", "uk_UA": "Кнопки ліворуч", @@ -8037,9 +6972,8 @@ "ko_KR": "우측 버튼", "no_NO": "Knapper til høyre", "pl_PL": "Prawe Przyciski", - "pt_BR": "Botões da Direita", + "pt_BR": "Botões direita", "ru_RU": "Правые кнопки", - "sv_SE": "Knappar höger", "th_TH": "ปุ่มกดเสริม ด้านขวา", "tr_TR": "Tuşlar Sağ", "uk_UA": "Кнопки праворуч", @@ -8064,7 +6998,6 @@ "pl_PL": "Różne", "pt_BR": "Miscelâneas", "ru_RU": "Разное", - "sv_SE": "Diverse", "th_TH": "การควบคุมเพิ่มเติม", "tr_TR": "Diğer", "uk_UA": "Різне", @@ -8087,9 +7020,8 @@ "ko_KR": "트리거 임계값 :", "no_NO": "Utløser terskel:", "pl_PL": "Próg Triggerów:", - "pt_BR": "Sensibilidade do Gatilho:", + "pt_BR": "Sensibilidade do gatilho:", "ru_RU": "Порог срабатывания:", - "sv_SE": "Tröskelvärde avtryckare:", "th_TH": "ตั้งค่าขีดจำกัดการกด:", "tr_TR": "Tetik Eşiği:", "uk_UA": "Поріг спрацьовування:", @@ -8112,9 +7044,8 @@ "ko_KR": "모션", "no_NO": "Bevegelse", "pl_PL": "Ruch", - "pt_BR": "Sensor de Movimento", + "pt_BR": "Sensor de movimento", "ru_RU": "Движение", - "sv_SE": "Rörelse", "th_TH": "การเคลื่อนไหว", "tr_TR": "Hareket", "uk_UA": "Рух", @@ -8137,9 +7068,8 @@ "ko_KR": "CemuHook 호환 모션 사용", "no_NO": "Bruk CemuHook kompatibel bevegelse", "pl_PL": "Użyj ruchu zgodnego z CemuHook", - "pt_BR": "Usar Sensor Compatível com CemuHook", + "pt_BR": "Usar sensor compatível com CemuHook", "ru_RU": "Включить совместимость с CemuHook", - "sv_SE": "Använd CemuHook-kompatibel rörelse", "th_TH": "ใช้การเคลื่อนไหวที่เข้ากันได้กับ CemuHook", "tr_TR": "CemuHook uyumlu hareket kullan", "uk_UA": "Використовувати рух, сумісний з CemuHook", @@ -8162,9 +7092,8 @@ "ko_KR": "컨트롤러 슬롯 :", "no_NO": "Kontrollertype:", "pl_PL": "Slot Kontrolera:", - "pt_BR": "Slot do Controle:", + "pt_BR": "Slot do controle:", "ru_RU": "Слот контроллера:", - "sv_SE": "Kontrollerplats:", "th_TH": "ช่องเสียบ คอนโทรลเลอร์:", "tr_TR": "Kumanda Yuvası:", "uk_UA": "Слот контролера:", @@ -8187,9 +7116,8 @@ "ko_KR": "미러 입력", "no_NO": "Speilvend", "pl_PL": "Odzwierciedlaj Sterowanie", - "pt_BR": "Espelhar Movimento", + "pt_BR": "Espelhar movimento", "ru_RU": "Зеркальный ввод", - "sv_SE": "Spegla inmatning", "th_TH": "นำเข้าการสะท้อน การควบคุม", "tr_TR": "Girişi Aynala", "uk_UA": "Дзеркальний вхід", @@ -8212,9 +7140,8 @@ "ko_KR": "우측 조이콘 슬롯:", "no_NO": "Høyre JoyCon set:", "pl_PL": "Prawy Slot JoyCon:", - "pt_BR": "Slot do JoyCon Direito:", + "pt_BR": "Slot do JoyCon direito:", "ru_RU": "Слот правого JoyCon:", - "sv_SE": "Höger JoyCon-plats:", "th_TH": "ช่องเสียบ จอยคอน ด้านขวา:", "tr_TR": "Sağ JoyCon Yuvası:", "uk_UA": "Правий слот JoyCon:", @@ -8237,9 +7164,8 @@ "ko_KR": "서버 호스트 :", "no_NO": "Server Vert:", "pl_PL": "Host Serwera:", - "pt_BR": "Endereço do Servidor:", + "pt_BR": "Endereço do servidor:", "ru_RU": "Хост сервера:", - "sv_SE": "Servervärd:", "th_TH": "เจ้าของเซิร์ฟเวอร์:", "tr_TR": "Sunucu Sahibi:", "uk_UA": "Хост сервера:", @@ -8262,9 +7188,8 @@ "ko_KR": "자이로 감도 :", "no_NO": "Gyro følsomhet:", "pl_PL": "Czułość Żyroskopu:", - "pt_BR": "Sensibilidade do Giroscópio:", + "pt_BR": "Sensibilidade do giroscópio:", "ru_RU": "Чувствительность гироскопа:", - "sv_SE": "Känslighet för gyro:", "th_TH": "ความไวของ Gyro:", "tr_TR": "Gyro Hassasiyeti:", "uk_UA": "Чутливість гіроскопа:", @@ -8287,9 +7212,8 @@ "ko_KR": "자이로 데드존 :", "no_NO": "Gyro Dødsone:", "pl_PL": "Deadzone Żyroskopu:", - "pt_BR": "Zona Morta do Giroscópio:", + "pt_BR": "Zona morta do giroscópio:", "ru_RU": "Мертвая зона гироскопа:", - "sv_SE": "Dödläge för gyro:", "th_TH": "ส่วนไม่ทำงานของ Gyro:", "tr_TR": "Gyro Ölü Bölgesi:", "uk_UA": "Мертва зона гіроскопа:", @@ -8297,131 +7221,6 @@ "zh_TW": "陀螺儀無感帶:" } }, - { - "ID": "ControllerSettingsLed", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "LED", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "", - "ru_RU": "LED-подсветка", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" - } - }, - { - "ID": "ControllerSettingsLedColorDisable", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Disable", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "비활성화", - "no_NO": "Deaktiver", - "pl_PL": "", - "pt_BR": "Desabilitar", - "ru_RU": "Отключить", - "sv_SE": "Inaktivera", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "关闭", - "zh_TW": "" - } - }, - { - "ID": "ControllerSettingsLedColorRainbow", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Rainbow", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "레인보우", - "no_NO": "Regnbue", - "pl_PL": "", - "pt_BR": "Arco-íris", - "ru_RU": "Радужная", - "sv_SE": "Regnbåge", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "彩虹", - "zh_TW": "" - } - }, - { - "ID": "ControllerSettingsLedColorRainbowSpeed", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Rainbow Speed", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "레인보우 속도", - "no_NO": "Regnbue Hastighet", - "pl_PL": "", - "pt_BR": "Velocidade do Arco-íris", - "ru_RU": "Скорость переливания", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "彩虹滚动速度", - "zh_TW": "" - } - }, - { - "ID": "ControllerSettingsLedColor", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Color", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "색상", - "no_NO": "Farge", - "pl_PL": "", - "pt_BR": "Cor", - "ru_RU": "Цвет", - "sv_SE": "Färg", - "th_TH": "", - "tr_TR": "", - "uk_UA": "", - "zh_CN": "颜色", - "zh_TW": "" - } - }, { "ID": "ControllerSettingsSave", "Translations": { @@ -8439,7 +7238,6 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", - "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -8464,7 +7262,6 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", - "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -8487,9 +7284,8 @@ "ko_KR": "알 수 없음", "no_NO": "Ukjent", "pl_PL": "", - "pt_BR": "Desconhecido", + "pt_BR": "", "ru_RU": "Неизвестно", - "sv_SE": "Okänd", "th_TH": "ไม่รู้จัก", "tr_TR": "", "uk_UA": "Невідома", @@ -8512,9 +7308,8 @@ "ko_KR": "좌측 Shift", "no_NO": "Skift venstre", "pl_PL": "", - "pt_BR": "Shift Esquerdo", + "pt_BR": "", "ru_RU": "Левый Shift", - "sv_SE": "Skift vänster", "th_TH": "", "tr_TR": "Sol Shift", "uk_UA": "Shift Лівий", @@ -8537,9 +7332,8 @@ "ko_KR": "우측 Shift", "no_NO": "Skift høyre", "pl_PL": "", - "pt_BR": "Shift Direito", + "pt_BR": "", "ru_RU": "Правый Shift", - "sv_SE": "Skift höger", "th_TH": "", "tr_TR": "Sağ Shift", "uk_UA": "Shift Правий", @@ -8562,9 +7356,8 @@ "ko_KR": "좌측 Ctrl", "no_NO": "Ctrl venstre", "pl_PL": "", - "pt_BR": "Ctrl Esquerdo", + "pt_BR": "", "ru_RU": "Левый Ctrl", - "sv_SE": "Ctrl vänster", "th_TH": "", "tr_TR": "Sol Ctrl", "uk_UA": "Ctrl Лівий", @@ -8587,9 +7380,8 @@ "ko_KR": "좌측 ⌃", "no_NO": "⌃ Venstre", "pl_PL": "", - "pt_BR": "⌃ Esquerda", + "pt_BR": "", "ru_RU": "Левый ⌃", - "sv_SE": "^ Vänster", "th_TH": "", "tr_TR": "⌃ Sol", "uk_UA": "⌃ Лівий", @@ -8612,9 +7404,8 @@ "ko_KR": "우측 Ctrl", "no_NO": "Ctrl høyre", "pl_PL": "", - "pt_BR": "Ctrl Direito", + "pt_BR": "", "ru_RU": "Правый Ctrl", - "sv_SE": "Ctrl höger", "th_TH": "", "tr_TR": "Sağ Control", "uk_UA": "Ctrl Правий", @@ -8637,9 +7428,8 @@ "ko_KR": "우측 ⌃", "no_NO": "⌃ Høyre", "pl_PL": "", - "pt_BR": "⌃ Direito", + "pt_BR": "", "ru_RU": "Правый ⌃", - "sv_SE": "^ Höger", "th_TH": "", "tr_TR": "⌃ Sağ", "uk_UA": "⌃ Правий", @@ -8662,9 +7452,8 @@ "ko_KR": "좌측 Alt", "no_NO": "Alt Venstre", "pl_PL": "", - "pt_BR": "Alt Esquerdo", + "pt_BR": "", "ru_RU": "Левый Alt", - "sv_SE": "Alt vänster", "th_TH": "", "tr_TR": "Sol Alt", "uk_UA": "Alt Лівий", @@ -8687,9 +7476,8 @@ "ko_KR": "좌측 ⌥", "no_NO": "⌥ Venstre", "pl_PL": "", - "pt_BR": "⌥ Esquerda", + "pt_BR": "", "ru_RU": "Левый ⌥", - "sv_SE": "⌥ vänster", "th_TH": "", "tr_TR": "⌥ Sol", "uk_UA": "⌥ Лівий", @@ -8712,9 +7500,8 @@ "ko_KR": "우측 Alt", "no_NO": "Alt høyre", "pl_PL": "", - "pt_BR": "Alt Direito", + "pt_BR": "", "ru_RU": "Правый Alt", - "sv_SE": "Alt höger", "th_TH": "", "tr_TR": "Sağ Alt", "uk_UA": "Alt Правий", @@ -8737,9 +7524,8 @@ "ko_KR": "우측 ⌥", "no_NO": "⌥ Høyre", "pl_PL": "", - "pt_BR": "⌥ Direito", + "pt_BR": "", "ru_RU": "Правый ⌥", - "sv_SE": "⌥ höger", "th_TH": "", "tr_TR": "⌥ Sağ", "uk_UA": "⌥ Правий", @@ -8762,9 +7548,8 @@ "ko_KR": "좌측 ⊞", "no_NO": "⊞ Venstre", "pl_PL": "", - "pt_BR": "⊞ Esquerdo", + "pt_BR": "", "ru_RU": "Левый ⊞", - "sv_SE": "⊞ vänster", "th_TH": "", "tr_TR": "⊞ Sol", "uk_UA": "⊞ Лівий", @@ -8787,9 +7572,8 @@ "ko_KR": "좌측 ⌘", "no_NO": "⌘ Venstre", "pl_PL": "", - "pt_BR": "⌘ Esquerdo", + "pt_BR": "", "ru_RU": "Левый ⌘", - "sv_SE": "⌘ vänster", "th_TH": "", "tr_TR": "⌘ Sol", "uk_UA": "⌘ Лівий", @@ -8812,9 +7596,8 @@ "ko_KR": "우측 ⊞", "no_NO": "⊞ Høyre", "pl_PL": "", - "pt_BR": "⊞ Direito", + "pt_BR": "", "ru_RU": "Правый ⊞", - "sv_SE": "⊞ höger", "th_TH": "", "tr_TR": "⊞ Sağ", "uk_UA": "⊞ Правий", @@ -8837,9 +7620,8 @@ "ko_KR": "우측 ⌘", "no_NO": "⌘ Høyre", "pl_PL": "", - "pt_BR": "⌘ Direito", + "pt_BR": "", "ru_RU": "Правый ⌘", - "sv_SE": "⌘ höger", "th_TH": "", "tr_TR": "⌘ Sağ", "uk_UA": "⌘ Правий", @@ -8864,12 +7646,11 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Меню", - "sv_SE": "Meny", "th_TH": "", "tr_TR": "Menü", - "uk_UA": "Меню", + "uk_UA": "", "zh_CN": "菜单键", - "zh_TW": "功能表鍵" + "zh_TW": "功能表" } }, { @@ -8887,12 +7668,11 @@ "ko_KR": "↑", "no_NO": "Opp", "pl_PL": "", - "pt_BR": "Cima", + "pt_BR": "", "ru_RU": "Вверх", - "sv_SE": "Upp", "th_TH": "", "tr_TR": "Yukarı", - "uk_UA": "Вгору ↑", + "uk_UA": "", "zh_CN": "上", "zh_TW": "上" } @@ -8912,12 +7692,11 @@ "ko_KR": "↓", "no_NO": "Ned", "pl_PL": "", - "pt_BR": "Baixo", + "pt_BR": "", "ru_RU": "Вниз", - "sv_SE": "Ner", "th_TH": "", "tr_TR": "Aşağı", - "uk_UA": "Вниз ↓", + "uk_UA": "", "zh_CN": "下", "zh_TW": "下" } @@ -8937,12 +7716,11 @@ "ko_KR": "←", "no_NO": "Venstre", "pl_PL": "", - "pt_BR": "Esquerda", + "pt_BR": "", "ru_RU": "Влево", - "sv_SE": "Vänster", "th_TH": "", "tr_TR": "Sol", - "uk_UA": "Вліво ←", + "uk_UA": "Вліво", "zh_CN": "左", "zh_TW": "左" } @@ -8962,12 +7740,11 @@ "ko_KR": "→", "no_NO": "Høyre", "pl_PL": "", - "pt_BR": "Direita", + "pt_BR": "", "ru_RU": "Вправо", - "sv_SE": "Höger", "th_TH": "", "tr_TR": "Sağ", - "uk_UA": "Вправо →", + "uk_UA": "Вправо", "zh_CN": "右", "zh_TW": "右" } @@ -8989,7 +7766,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9012,9 +7788,8 @@ "ko_KR": "Esc", "no_NO": "Esc-tast", "pl_PL": "", - "pt_BR": "Esc", - "ru_RU": "Esc", - "sv_SE": "", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "Esc", "uk_UA": "", @@ -9037,9 +7812,8 @@ "ko_KR": "스페이스", "no_NO": "Mellomrom", "pl_PL": "", - "pt_BR": "Espaço", + "pt_BR": "", "ru_RU": "Пробел", - "sv_SE": "Blanksteg", "th_TH": "", "tr_TR": "", "uk_UA": "Пробіл", @@ -9064,7 +7838,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9089,7 +7862,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "Geri tuşu", "uk_UA": "", @@ -9114,7 +7886,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9139,7 +7910,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9164,7 +7934,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9189,7 +7958,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9214,7 +7982,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9239,7 +8006,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9264,7 +8030,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9289,7 +8054,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9314,7 +8078,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9339,7 +8102,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9364,7 +8126,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9388,8 +8149,7 @@ "no_NO": "Tøm", "pl_PL": "", "pt_BR": "", - "ru_RU": "", - "sv_SE": "Töm", + "ru_RU": "Очистить", "th_TH": "", "tr_TR": "", "uk_UA": "Очистити", @@ -9413,11 +8173,10 @@ "no_NO": "Numerisk 0", "pl_PL": "", "pt_BR": "", - "ru_RU": "0 (цифровий блок)", - "sv_SE": "", + "ru_RU": "Блок цифр 0", "th_TH": "", "tr_TR": "", - "uk_UA": "Блок цифр 0", + "uk_UA": "", "zh_CN": "小键盘0", "zh_TW": "數字鍵 0" } @@ -9439,10 +8198,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 1", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Блок цифр 1", + "uk_UA": "", "zh_CN": "小键盘1", "zh_TW": "數字鍵 1" } @@ -9464,10 +8222,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 2", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "2 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘2", "zh_TW": "數字鍵 2" } @@ -9489,10 +8246,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 3", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "3 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘3", "zh_TW": "數字鍵 3" } @@ -9514,10 +8270,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 4", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "4 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘4", "zh_TW": "數字鍵 4" } @@ -9539,10 +8294,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 5", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "5 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘5", "zh_TW": "數字鍵 5" } @@ -9564,10 +8318,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 6", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "6 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘6", "zh_TW": "數字鍵 6" } @@ -9589,10 +8342,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 7", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "7 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘7", "zh_TW": "數字鍵 7" } @@ -9614,10 +8366,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 8", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "8 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘8", "zh_TW": "數字鍵 8" } @@ -9639,10 +8390,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 9", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "9 (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘9", "zh_TW": "數字鍵 9" } @@ -9664,10 +8414,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "/ (блок цифр)", - "sv_SE": "Keypad /", "th_TH": "", "tr_TR": "", - "uk_UA": "/ (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘/", "zh_TW": "數字鍵除號" } @@ -9689,10 +8438,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "* (блок цифр)", - "sv_SE": "Keypad *", "th_TH": "", "tr_TR": "", - "uk_UA": "* (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘*", "zh_TW": "數字鍵乘號" } @@ -9714,10 +8462,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "- (блок цифр)", - "sv_SE": "Keypad -", "th_TH": "", "tr_TR": "", - "uk_UA": "- (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘-", "zh_TW": "數字鍵減號" } @@ -9739,10 +8486,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "+ (блок цифр)", - "sv_SE": "Keypad +", "th_TH": "", "tr_TR": "", - "uk_UA": "+ (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘+", "zh_TW": "數字鍵加號" } @@ -9764,10 +8510,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": ". (блок цифр)", - "sv_SE": "Keypad ,", "th_TH": "", "tr_TR": "", - "uk_UA": ". (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘.", "zh_TW": "數字鍵小數點" } @@ -9789,10 +8534,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Enter (блок цифр)", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Enter (цифровий блок)", + "uk_UA": "", "zh_CN": "小键盘回车键", "zh_TW": "數字鍵 Enter" } @@ -9814,7 +8558,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9839,7 +8582,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9864,7 +8606,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9889,7 +8630,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9914,7 +8654,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9939,7 +8678,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9964,7 +8702,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9989,7 +8726,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10014,7 +8750,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10039,7 +8774,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10064,7 +8798,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10089,7 +8822,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10114,7 +8846,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10139,7 +8870,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10164,7 +8894,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10189,7 +8918,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10214,7 +8942,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10239,7 +8966,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10264,7 +8990,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10289,7 +9014,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10314,7 +9038,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10339,7 +9062,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10362,9 +9084,8 @@ "ko_KR": "연동 해제", "no_NO": "Ikke bundet", "pl_PL": "", - "pt_BR": "Não Atribuído", + "pt_BR": "", "ru_RU": "Не привязано", - "sv_SE": "Obunden", "th_TH": "", "tr_TR": "", "uk_UA": "Відв'язати", @@ -10389,7 +9110,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Кнопка лев. стика", - "sv_SE": "L-spakknapp", "th_TH": "", "tr_TR": "", "uk_UA": "L Кнопка Стіку", @@ -10414,7 +9134,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Кнопка пр. стика", - "sv_SE": "R-spakknapp", "th_TH": "", "tr_TR": "", "uk_UA": "R Кнопка Стіку", @@ -10439,7 +9158,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый бампер", - "sv_SE": "Vänster kantknapp", "th_TH": "", "tr_TR": "", "uk_UA": "Лівий Бампер", @@ -10464,7 +9182,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый бампер", - "sv_SE": "Höger kantknapp", "th_TH": "", "tr_TR": "", "uk_UA": "Правий Бампер", @@ -10489,7 +9206,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер", - "sv_SE": "Vänster avtryckare", "th_TH": "", "tr_TR": "", "uk_UA": "Лівий Тригер", @@ -10514,7 +9230,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер", - "sv_SE": "Höger avtryckare", "th_TH": "", "tr_TR": "", "uk_UA": "Правий Тригер", @@ -10539,7 +9254,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вверх", - "sv_SE": "Upp", "th_TH": "", "tr_TR": "", "uk_UA": "Вверх", @@ -10564,7 +9278,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вниз", - "sv_SE": "Ner", "th_TH": "", "tr_TR": "", "uk_UA": "Вниз", @@ -10589,7 +9302,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Влево", - "sv_SE": "Vänster", "th_TH": "", "tr_TR": "", "uk_UA": "Вліво", @@ -10614,7 +9326,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вправо", - "sv_SE": "Höger", "th_TH": "", "tr_TR": "Sağ", "uk_UA": "Вправо", @@ -10639,7 +9350,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -10664,7 +9374,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "4", "uk_UA": "", @@ -10682,17 +9391,16 @@ "es_ES": "", "fr_FR": "", "he_IL": "", - "it_IT": "Guida", + "it_IT": "", "ja_JP": "", "ko_KR": "가이드", "no_NO": "Veiledning", "pl_PL": "", "pt_BR": "", - "ru_RU": "Кнопка меню", - "sv_SE": "", + "ru_RU": "Кнопка Xbox", "th_TH": "", "tr_TR": "Rehber", - "uk_UA": "Меню", + "uk_UA": "", "zh_CN": "主页键", "zh_TW": "快顯功能表鍵" } @@ -10707,14 +9415,13 @@ "es_ES": "", "fr_FR": "Autre", "he_IL": "", - "it_IT": "Altro", + "it_IT": "", "ja_JP": "", "ko_KR": "기타", "no_NO": "Diverse", "pl_PL": "", "pt_BR": "", "ru_RU": "Прочее", - "sv_SE": "Diverse", "th_TH": "", "tr_TR": "Diğer", "uk_UA": "", @@ -10732,17 +9439,16 @@ "es_ES": "", "fr_FR": "Palette 1", "he_IL": "", - "it_IT": "Tasto extra 1", + "it_IT": "", "ja_JP": "", "ko_KR": "패들 1", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 1", - "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 1", - "uk_UA": "Додаткова кнопка 1", + "uk_UA": "", "zh_CN": "其他按键1", "zh_TW": "其他按鍵 1" } @@ -10757,17 +9463,16 @@ "es_ES": "", "fr_FR": "Palette 2", "he_IL": "", - "it_IT": "Tasto extra 2", + "it_IT": "", "ja_JP": "", "ko_KR": "패들 2", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 2", - "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 2", - "uk_UA": "Додаткова кнопка 2", + "uk_UA": "", "zh_CN": "其他按键2", "zh_TW": "其他按鍵 2" } @@ -10782,17 +9487,16 @@ "es_ES": "", "fr_FR": "Palette 3", "he_IL": "", - "it_IT": "Tasto extra 3", + "it_IT": "", "ja_JP": "", "ko_KR": "패들 3", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 3", - "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 3", - "uk_UA": "Додаткова кнопка 3", + "uk_UA": "", "zh_CN": "其他按键3", "zh_TW": "其他按鍵 3" } @@ -10807,17 +9511,16 @@ "es_ES": "", "fr_FR": "Palette 4", "he_IL": "", - "it_IT": "Tasto extra 4", + "it_IT": "", "ja_JP": "", "ko_KR": "패들 4", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 4", - "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 4", - "uk_UA": "Додаткова кнопка 4", + "uk_UA": "", "zh_CN": "其他按键4", "zh_TW": "其他按鍵 4" } @@ -10839,10 +9542,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Тачпад", - "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Сенсорна панель", + "uk_UA": "", "zh_CN": "触摸板", "zh_TW": "觸控板" } @@ -10864,7 +9566,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер 0", - "sv_SE": "Vänster avtryckare 0", "th_TH": "", "tr_TR": "Sol Tetik 0", "uk_UA": "Лівий Тригер 0", @@ -10889,7 +9590,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер 0", - "sv_SE": "Höger avtryckare 0", "th_TH": "", "tr_TR": "Sağ Tetik 0", "uk_UA": "Правий Тригер 0", @@ -10914,7 +9614,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер 1", - "sv_SE": "Vänster avtryckare 1", "th_TH": "", "tr_TR": "Sol Tetik 1", "uk_UA": "Лівий Тригер 1", @@ -10939,7 +9638,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер 1", - "sv_SE": "Höger avtryckare 1", "th_TH": "", "tr_TR": "Sağ Tetik 1", "uk_UA": "Правий Тригер 1", @@ -10964,7 +9662,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый стик", - "sv_SE": "Vänster spak", "th_TH": "", "tr_TR": "Sol Çubuk", "uk_UA": "Лівий Стік", @@ -10989,7 +9686,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый стик", - "sv_SE": "Höger spak", "th_TH": "", "tr_TR": "Sağ çubuk", "uk_UA": "Правий Стік", @@ -11012,9 +9708,8 @@ "ko_KR": "선택된 사용자 프로필 :", "no_NO": "Valgt brukerprofil:", "pl_PL": "Wybrany profil użytkownika:", - "pt_BR": "Perfil de Usuário Selecionado:", + "pt_BR": "Perfil de usuário selecionado:", "ru_RU": "Выбранный пользовательский профиль:", - "sv_SE": "Vald användarprofil:", "th_TH": "เลือกโปรไฟล์ผู้ใช้งาน:", "tr_TR": "Seçili Kullanıcı Profili:", "uk_UA": "Вибраний профіль користувача:", @@ -11037,9 +9732,8 @@ "ko_KR": "프로필 이름 저장", "no_NO": "Lagre profilnavnet", "pl_PL": "Zapisz nazwę profilu", - "pt_BR": "Salvar Nome de Perfil", + "pt_BR": "Salvar nome de perfil", "ru_RU": "Сохранить пользовательский профиль", - "sv_SE": "Spara profilnamn", "th_TH": "บันทึกชื่อโปรไฟล์", "tr_TR": "Profil İsmini Kaydet", "uk_UA": "Зберегти ім'я профілю", @@ -11062,9 +9756,8 @@ "ko_KR": "프로필 이미지 변경", "no_NO": "Endre profilbilde", "pl_PL": "Zmień obrazek profilu", - "pt_BR": "Mudar Imagem de Perfil", + "pt_BR": "Mudar imagem de perfil", "ru_RU": "Изменить аватар", - "sv_SE": "Byt profilbild", "th_TH": "เปลี่ยนรูปโปรไฟล์", "tr_TR": "Profil Resmini Değiştir", "uk_UA": "Змінити зображення профілю", @@ -11087,9 +9780,8 @@ "ko_KR": "사용 가능한 사용자 프로필 :", "no_NO": "Tilgjengelige brukerprofiler:", "pl_PL": "Dostępne profile użytkownika:", - "pt_BR": "Perfis de Usuário Disponíveis:", + "pt_BR": "Perfis de usuário disponíveis:", "ru_RU": "Доступные профили пользователей:", - "sv_SE": "Tillgängliga användarprofiler:", "th_TH": "โปรไฟล์ผู้ใช้ที่ใช้งานได้:", "tr_TR": "Mevcut Kullanıcı Profilleri:", "uk_UA": "Доступні профілі користувачів:", @@ -11112,9 +9804,8 @@ "ko_KR": "프로필 만들기", "no_NO": "Opprett Profil", "pl_PL": "Utwórz profil", - "pt_BR": "Criar Perfil", + "pt_BR": "Adicionar novo perfil", "ru_RU": "Добавить новый профиль", - "sv_SE": "Skapa profil", "th_TH": "สร้างโปรไฟล์ใหม่", "tr_TR": "Yeni Profil Ekle", "uk_UA": "Створити профіль", @@ -11139,7 +9830,6 @@ "pl_PL": "Usuń", "pt_BR": "Apagar", "ru_RU": "Удалить", - "sv_SE": "Ta bort", "th_TH": "ลบ", "tr_TR": "Sil", "uk_UA": "Видалити", @@ -11164,7 +9854,6 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", - "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -11187,9 +9876,8 @@ "ko_KR": "별명 선택", "no_NO": "Velg ett kallenavn", "pl_PL": "Wybierz pseudonim", - "pt_BR": "Escolha um Apelido", - "ru_RU": "Введите никнейм", - "sv_SE": "Välj ett smeknamn", + "pt_BR": "Escolha um apelido", + "ru_RU": "Укажите никнейм", "th_TH": "เลือก ชื่อเล่น", "tr_TR": "Kullanıcı Adı Seç", "uk_UA": "Оберіть псевдонім", @@ -11212,9 +9900,8 @@ "ko_KR": "프로필 이미지 선택", "no_NO": "Valg av profilbilde", "pl_PL": "Wybór Obrazu Profilu", - "pt_BR": "Seleção da Imagem de Perfil", + "pt_BR": "Seleção da imagem de perfil", "ru_RU": "Выбор изображения профиля", - "sv_SE": "Välj profilbild", "th_TH": "เลือก รูปโปรไฟล์ ของคุณ", "tr_TR": "Profil Resmi Seçimi", "uk_UA": "Вибір зображення профілю", @@ -11237,9 +9924,8 @@ "ko_KR": "프로필 이미지를 선택", "no_NO": "Velg et profilbilde", "pl_PL": "Wybierz zdjęcie profilowe", - "pt_BR": "Escolha uma Imagem de Perfil", + "pt_BR": "Escolha uma imagem de perfil", "ru_RU": "Выбор аватара", - "sv_SE": "Välj en profilbild", "th_TH": "เลือก รูปโปรไฟล์", "tr_TR": "Profil Resmi Seç", "uk_UA": "Виберіть зображення профілю", @@ -11264,7 +9950,6 @@ "pl_PL": "Możesz zaimportować niestandardowy obraz profilu lub wybrać awatar z firmware'u systemowego", "pt_BR": "Você pode importar uma imagem customizada, ou selecionar um avatar do firmware", "ru_RU": "Вы можете импортировать собственное изображение или выбрать аватар из системной прошивки.", - "sv_SE": "Du kan importera en anpassad profilbild eller välja en avatar från systemets firmware", "th_TH": "คุณสามารถนำเข้ารูปโปรไฟล์ที่กำหนดเองได้ หรือ เลือกรูปที่มีจากระบบ", "tr_TR": "Özel bir profil resmi içeri aktarabilir veya sistem avatarlarından birini seçebilirsiniz", "uk_UA": "Ви можете імпортувати власне зображення профілю або вибрати аватар із мікропрограми системи", @@ -11287,9 +9972,8 @@ "ko_KR": "이미지 파일 가져오기", "no_NO": "Importer bildefil", "pl_PL": "Importuj Plik Obrazu", - "pt_BR": "Importar Arquivo de Imagem", + "pt_BR": "Importar arquivo de imagem", "ru_RU": "Импорт изображения", - "sv_SE": "Importera bildfil", "th_TH": "นำเข้า ไฟล์รูปภาพ", "tr_TR": "Resim İçeri Aktar", "uk_UA": "Імпорт файлу зображення", @@ -11312,9 +9996,8 @@ "ko_KR": "펌웨어 아바타 선택", "no_NO": "Velg fastvare profilbilde", "pl_PL": "Wybierz domyślny awatar z oprogramowania konsoli", - "pt_BR": "Selecionar Avatar do Firmware", + "pt_BR": "Selecionar avatar do firmware", "ru_RU": "Встроенные аватары", - "sv_SE": "Välj avatar från firmware", "th_TH": "เลือก รูปอวาต้า จากระบบ", "tr_TR": "Yazılım Avatarı Seç", "uk_UA": "Виберіть аватар прошивки ", @@ -11335,11 +10018,10 @@ "it_IT": "Finestra di input", "ja_JP": "入力ダイアログ", "ko_KR": "대화 상자 입력", - "no_NO": "Dialogboksen Inndata", + "no_NO": "", "pl_PL": "Okno Dialogowe Wprowadzania", "pt_BR": "Diálogo de texto", "ru_RU": "Диалоговое окно ввода", - "sv_SE": "Inmatningsdialog", "th_TH": "กล่องโต้ตอบการป้อนข้อมูล", "tr_TR": "Giriş Yöntemi Diyaloğu", "uk_UA": "Діалог введення", @@ -11364,10 +10046,9 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "ОК", - "sv_SE": "Ok", "th_TH": "ตกลง", "tr_TR": "Tamam", - "uk_UA": "", + "uk_UA": "Гаразд", "zh_CN": "完成", "zh_TW": "確定" } @@ -11389,7 +10070,6 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", - "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -11407,19 +10087,18 @@ "es_ES": "", "fr_FR": "Annulation en cours", "he_IL": "", - "it_IT": "Annullamento in corso", + "it_IT": "Cancellando", "ja_JP": "", "ko_KR": "취소하기", "no_NO": "Kansellerer", "pl_PL": "", - "pt_BR": "Cancelando", - "ru_RU": "Отмена", - "sv_SE": "Avbryter", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Скасування", - "zh_CN": "正在取消", - "zh_TW": "正在取消" + "zh_CN": "", + "zh_TW": "" } }, { @@ -11437,14 +10116,13 @@ "ko_KR": "닫기", "no_NO": "Lukk", "pl_PL": "", - "pt_BR": "Fechar", - "ru_RU": "Закрыть", - "sv_SE": "Stäng", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Закрити", - "zh_CN": "关闭", - "zh_TW": "關閉" + "zh_CN": "", + "zh_TW": "" } }, { @@ -11462,9 +10140,8 @@ "ko_KR": "프로필 이름 선택", "no_NO": "Velg profilnavnet", "pl_PL": "Wybierz nazwę profilu", - "pt_BR": "Escolha o Nome de Perfil", + "pt_BR": "Escolha o nome de perfil", "ru_RU": "Выберите никнейм", - "sv_SE": "Välj ett profilnamn", "th_TH": "เลือก ชื่อโปรไฟล์", "tr_TR": "Profil İsmini Seç", "uk_UA": "Виберіть ім'я профілю", @@ -11487,9 +10164,8 @@ "ko_KR": "프로필 이름을 입력", "no_NO": "Vennligst skriv inn et profilnavn", "pl_PL": "Wprowadź nazwę profilu", - "pt_BR": "Escreva o Nome do Perfil", + "pt_BR": "Escreva o nome do perfil", "ru_RU": "Пожалуйста, введите никнейм", - "sv_SE": "Ange ett profilnamn", "th_TH": "กรุณาใส่ชื่อโปรไฟล์", "tr_TR": "Lütfen Bir Profil İsmi Girin", "uk_UA": "Будь ласка, введіть ім'я профілю", @@ -11512,9 +10188,8 @@ "ko_KR": "(최대 길이 : {0})", "no_NO": "(Maks lengde: {0})", "pl_PL": "(Maksymalna długość: {0})", - "pt_BR": "(Máximo de Caracteres: {0})", + "pt_BR": "(Máximo de caracteres: {0})", "ru_RU": "(Максимальная длина: {0})", - "sv_SE": "(Max längd: {0})", "th_TH": "(ความยาวสูงสุด: {0})", "tr_TR": "(Maksimum Uzunluk: {0})", "uk_UA": "(Макс. довжина: {0})", @@ -11537,9 +10212,8 @@ "ko_KR": "아바타 선택", "no_NO": "Velg profilbilde", "pl_PL": "Wybierz awatar", - "pt_BR": "Escolha o Avatar", + "pt_BR": "Escolher", "ru_RU": "Выбрать аватар", - "sv_SE": "Välj avatar", "th_TH": "เลือก รูปอวาต้า ของคุณ", "tr_TR": "Seç", "uk_UA": "Вибрати", @@ -11562,9 +10236,8 @@ "ko_KR": "배경색 설정", "no_NO": "Angi bakgrunnsfarge", "pl_PL": "Ustaw kolor tła", - "pt_BR": "Definir cor de Fundo", + "pt_BR": "Definir cor de fundo", "ru_RU": "Установить цвет фона", - "sv_SE": "Välj bakgrundsfärg", "th_TH": "ตั้งค่าสีพื้นหลัง", "tr_TR": "Arka Plan Rengi Ayarla", "uk_UA": "Встановити колір фону", @@ -11589,7 +10262,6 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", - "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -11612,9 +10284,8 @@ "ko_KR": "프로필 불러오기", "no_NO": "Last inn profil", "pl_PL": "Wczytaj profil", - "pt_BR": "Carregar Perfil", + "pt_BR": "Carregar perfil", "ru_RU": "Загрузить профиль", - "sv_SE": "Läs in profil", "th_TH": "โหลด โปรไฟล์", "tr_TR": "Profil Yükle", "uk_UA": "Завантажити профіль", @@ -11637,14 +10308,13 @@ "ko_KR": "프로필 보기", "no_NO": "Se Profil", "pl_PL": "", - "pt_BR": "Ver Perfil", - "ru_RU": "Показать профиль", - "sv_SE": "Visa profil", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Показати профіль", "zh_CN": "预览配置文件", - "zh_TW": "檢視設定檔" + "zh_TW": "" } }, { @@ -11662,9 +10332,8 @@ "ko_KR": "프로필 추가", "no_NO": "Legg til profil", "pl_PL": "Dodaj profil", - "pt_BR": "Adicionar Perfil", + "pt_BR": "Adicionar perfil", "ru_RU": "Добавить профиль", - "sv_SE": "Lägg till profil", "th_TH": "เพิ่ม โปรไฟล์", "tr_TR": "Profil Ekle", "uk_UA": "Додати профіль", @@ -11687,9 +10356,8 @@ "ko_KR": "프로필 삭제", "no_NO": "Fjern profil", "pl_PL": "Usuń profil", - "pt_BR": "Remover Perfil", + "pt_BR": "Remover perfil", "ru_RU": "Удалить профиль", - "sv_SE": "Ta bort profil", "th_TH": "ลบ โปรไฟล์", "tr_TR": "Profili Kaldır", "uk_UA": "Видалити профіль", @@ -11712,9 +10380,8 @@ "ko_KR": "프로필 추가", "no_NO": "Lagre Profil", "pl_PL": "Zapisz profil", - "pt_BR": "Salvar Perfil", + "pt_BR": "Salvar perfil", "ru_RU": "Сохранить профиль", - "sv_SE": "Spara profil", "th_TH": "บันทึก โปรไฟล์", "tr_TR": "Profili Kaydet", "uk_UA": "Зберегти профіль", @@ -11737,9 +10404,8 @@ "ko_KR": "스크린샷 찍기", "no_NO": "Ta skjermbilde", "pl_PL": "Zrób zrzut ekranu", - "pt_BR": "Tirar Captura de tela", + "pt_BR": "Salvar captura de tela", "ru_RU": "Сделать снимок экрана", - "sv_SE": "Ta skärmbild", "th_TH": "ถ่ายภาพหน้าจอ", "tr_TR": "Ekran Görüntüsü Al", "uk_UA": "Зробити знімок екрана", @@ -11764,7 +10430,6 @@ "pl_PL": "Ukryj interfejs użytkownika", "pt_BR": "Esconder Interface", "ru_RU": "Скрыть интерфейс", - "sv_SE": "Dölj gränssnittet", "th_TH": "ซ่อน UI", "tr_TR": "Arayüzü Gizle", "uk_UA": "Сховати інтерфейс", @@ -11789,10 +10454,9 @@ "pl_PL": "Uruchom aplikację ", "pt_BR": "Executar Aplicativo", "ru_RU": "Запуск приложения", - "sv_SE": "Kör applikation", "th_TH": "เปิดใช้งานแอปพลิเคชัน", "tr_TR": "Uygulamayı Çalıştır", - "uk_UA": "Запустити", + "uk_UA": "Запустити додаток", "zh_CN": "启动游戏", "zh_TW": "執行應用程式" } @@ -11812,12 +10476,11 @@ "ko_KR": "즐겨찾기 전환", "no_NO": "Vis/Skjul favoritter", "pl_PL": "Przełącz na ulubione", - "pt_BR": "Marcar como Favorito", + "pt_BR": "Alternar favorito", "ru_RU": "Добавить в избранное", - "sv_SE": "Växla som favorit", "th_TH": "สลับรายการโปรด", "tr_TR": "Favori Ayarla", - "uk_UA": "Додати в обрані", + "uk_UA": "Перемкнути вибране", "zh_CN": "收藏", "zh_TW": "加入/移除為我的最愛" } @@ -11837,12 +10500,11 @@ "ko_KR": "게임의 즐겨찾기 상태 전환", "no_NO": "Vis/Skjul favorittstatus for spillet", "pl_PL": "Przełącz status Ulubionej Gry", - "pt_BR": "Marca ou desmarca o jogo como favorito", - "ru_RU": "Добавляет игру в избранное и помечает звёздочкой", - "sv_SE": "Växla favoritstatus för spelet", + "pt_BR": "Marca ou desmarca jogo como favorito", + "ru_RU": "Добавляет игру в избранное и помечает звездочкой", "th_TH": "สลับสถานะเกมที่ชื่นชอบ", "tr_TR": "Oyunu Favorilere Ekle/Çıkar", - "uk_UA": "Додати або вилучити гру з обраних", + "uk_UA": "Перемкнути улюблений статус гри", "zh_CN": "切换游戏的收藏状态", "zh_TW": "切換遊戲的我的最愛狀態" } @@ -11864,7 +10526,6 @@ "pl_PL": "Motyw:", "pt_BR": "Tema:", "ru_RU": "Тема:", - "sv_SE": "Tema:", "th_TH": "ธีม:", "tr_TR": "Tema:", "uk_UA": "Тема:", @@ -11888,8 +10549,7 @@ "no_NO": "Automatisk", "pl_PL": "", "pt_BR": "Automático", - "ru_RU": "Авто", - "sv_SE": "Automatiskt", + "ru_RU": "", "th_TH": "อัตโนมัติ", "tr_TR": "", "uk_UA": "Авто.", @@ -11913,8 +10573,7 @@ "no_NO": "Mørk", "pl_PL": "Ciemny", "pt_BR": "Escuro", - "ru_RU": "Тёмная", - "sv_SE": "Mörkt", + "ru_RU": "Темная", "th_TH": "มืด", "tr_TR": "Karanlık", "uk_UA": "Темна", @@ -11939,7 +10598,6 @@ "pl_PL": "Jasny", "pt_BR": "Claro", "ru_RU": "Светлая", - "sv_SE": "Ljust", "th_TH": "สว่าง", "tr_TR": "Aydınlık", "uk_UA": "Світла", @@ -11964,7 +10622,6 @@ "pl_PL": "Konfiguruj", "pt_BR": "Configurar", "ru_RU": "Настройка", - "sv_SE": "Konfigurera", "th_TH": "กำหนดค่า", "tr_TR": "Ayarla", "uk_UA": "Налаштування", @@ -11989,7 +10646,6 @@ "pl_PL": "Wibracje", "pt_BR": "Vibração", "ru_RU": "Вибрация", - "sv_SE": "Vibration", "th_TH": "การสั่นไหว", "tr_TR": "Titreşim", "uk_UA": "Вібрація", @@ -12012,9 +10668,8 @@ "ko_KR": "강력한 진동 증폭기", "no_NO": "Sterk Vibrasjon multiplikator", "pl_PL": "Mnożnik mocnych wibracji", - "pt_BR": "Multiplicador de Vibração Forte", + "pt_BR": "Multiplicador de vibração forte", "ru_RU": "Множитель сильной вибрации", - "sv_SE": "Försvaga stark vibration", "th_TH": "เพิ่มความแรงการสั่น", "tr_TR": "Güçlü Titreşim Çoklayıcı", "uk_UA": "Множник сильної вібрації", @@ -12037,9 +10692,8 @@ "ko_KR": "약한 진동 증폭기", "no_NO": "Svak Vibrasjon multiplikator", "pl_PL": "Mnożnik słabych wibracji", - "pt_BR": "Multiplicador de Vibração Fraca", + "pt_BR": "Multiplicador de vibração fraca", "ru_RU": "Множитель слабой вибрации", - "sv_SE": "Förstärk svag vibration", "th_TH": "ลดความแรงการสั่น", "tr_TR": "Zayıf Titreşim Seviyesi", "uk_UA": "Множник слабкої вібрації", @@ -12064,11 +10718,10 @@ "pl_PL": "Nie ma zapisanych danych dla {0} [{1:x16}]", "pt_BR": "Não há jogos salvos para {0} [{1:x16}]", "ru_RU": "Нет сохранений для {0} [{1:x16}]", - "sv_SE": "Det finns inget sparat spel för {0} [{1:x16}]", "th_TH": "ไม่มีข้อมูลบันทึกไว้สำหรับ {0} [{1:x16}]", "tr_TR": "{0} [{1:x16}] için kayıt verisi bulunamadı", "uk_UA": "Немає збережених даних для {0} [{1:x16}]", - "zh_CN": "没有 {0} [{1:x16}] 的游戏存档", + "zh_CN": "没有{0} [{1:x16}]的游戏存档", "zh_TW": "沒有 {0} [{1:x16}] 的存檔" } }, @@ -12087,9 +10740,8 @@ "ko_KR": "이 게임의 저장 데이터를 만들겠습니까?", "no_NO": "Vil du lage lagrede data for dette spillet", "pl_PL": "Czy chcesz utworzyć zapis danych dla tej gry?", - "pt_BR": "Você gostaria de criar dados salvos para este jogo?", + "pt_BR": "Gostaria de criar o diretório de salvamento para esse jogo?", "ru_RU": "Создать сохранение для этой игры?", - "sv_SE": "Vill du skapa sparat spel för detta spel?", "th_TH": "คุณต้องการสร้างบันทึกข้อมูลสำหรับเกมนี้หรือไม่?", "tr_TR": "Bu oyun için kayıt verisi oluşturmak ister misiniz?", "uk_UA": "Хочете створити дані збереження для цієї гри?", @@ -12100,126 +10752,121 @@ { "ID": "DialogConfirmationTitle", "Translations": { - "ar_SA": "{0} - تأكيد", - "de_DE": "{0} - Bestätigung", - "el_GR": "{0} - Επιβεβαίωση", - "en_US": "{0} - Confirmation", - "es_ES": "{0} - Confirmación", + "ar_SA": "ريوجينكس - تأكيد", + "de_DE": "Ryujinx - Bestätigung", + "el_GR": "Ryujinx - Επιβεβαίωση", + "en_US": "Ryujinx - Confirmation", + "es_ES": "Ryujinx - Confirmación", "fr_FR": "", - "he_IL": "{0} - אישור", - "it_IT": "{0} - Conferma", - "ja_JP": "{0} - 確認", - "ko_KR": "{0} - 확인", - "no_NO": "{0} - Bekreftelse", - "pl_PL": "{0} - Potwierdzenie", - "pt_BR": "{0} - Confirmação", - "ru_RU": "{0} — Подтверждение", - "sv_SE": "{0} - Bekräftelse", - "th_TH": "{0} - ยืนยัน", - "tr_TR": "{0} - Onay", - "uk_UA": "{0} - Підтвердження", - "zh_CN": "{0} - 确认", - "zh_TW": "{0} - 確認" + "he_IL": "ריוג'ינקס - אישור", + "it_IT": "Ryujinx - Conferma", + "ja_JP": "Ryujinx - 確認", + "ko_KR": "Ryujinx - 확인", + "no_NO": "Ryujinx - Bekreftelse", + "pl_PL": "Ryujinx - Potwierdzenie", + "pt_BR": "Ryujinx - Confirmação", + "ru_RU": "Ryujinx - Подтверждение", + "th_TH": "Ryujinx - ยืนยัน", + "tr_TR": "Ryujinx - Onay", + "uk_UA": "Ryujinx - Підтвердження", + "zh_CN": "Ryujinx - 确认", + "zh_TW": "Ryujinx - 確認" } }, { "ID": "DialogUpdaterTitle", "Translations": { - "ar_SA": "{0} - المحدث", + "ar_SA": "ريوجينكس - المحدث", "de_DE": "", - "el_GR": "{0} - Ενημερωτής", - "en_US": "{0} - Updater", - "es_ES": "{0} - Actualizador", - "fr_FR": "{0} - Mise à Jour", - "he_IL": "{0} - מעדכן", - "it_IT": "{0} - Aggiornamento", - "ja_JP": "{0} - アップデータ", - "ko_KR": "{0} - 업데이터", - "no_NO": "{0} – Oppdaterer", - "pl_PL": "{0} - Asystent aktualizacji", - "pt_BR": "{0} - Atualizador", - "ru_RU": "{0} — Обновление", - "sv_SE": "{0} - Uppdatering", - "th_TH": "{0} - อัพเดต", - "tr_TR": "{0} - Güncelleyici", - "uk_UA": "{0} - Програма оновлення", - "zh_CN": "{0} - 更新", - "zh_TW": "{0} - 更新程式" + "el_GR": "Ryujinx - Ενημερωτής", + "en_US": "Ryujinx - Updater", + "es_ES": "Ryujinx - Actualizador", + "fr_FR": "Ryujinx - Mise à Jour", + "he_IL": "ריוג'ינקס - מעדכן", + "it_IT": "Ryujinx - Aggiornamento", + "ja_JP": "Ryujinx - アップデータ", + "ko_KR": "Ryujinx - 업데이터", + "no_NO": "Ryujinx – Oppdaterer", + "pl_PL": "Ryujinx - Asystent aktualizacji", + "pt_BR": "Ryujinx - Atualizador", + "ru_RU": "Ryujinx - Обновление", + "th_TH": "Ryujinx - อัพเดต", + "tr_TR": "Ryujinx - Güncelleyici", + "uk_UA": "Ryujinx - Програма оновлення", + "zh_CN": "Ryujinx - 更新", + "zh_TW": "Ryujinx - 更新程式" } }, { "ID": "DialogErrorTitle", "Translations": { - "ar_SA": "{0} - خطأ", - "de_DE": "{0} - Fehler", - "el_GR": "{0} - Σφάλμα", - "en_US": "{0} - Error", + "ar_SA": "ريوجينكس - خطأ", + "de_DE": "Ryujinx - Fehler", + "el_GR": "Ryujinx - Σφάλμα", + "en_US": "Ryujinx - Error", "es_ES": "", - "fr_FR": "{0} - Erreur", - "he_IL": "{0} - שגיאה", - "it_IT": "{0} - Errore", - "ja_JP": "{0} - エラー", - "ko_KR": "{0} - 오류", - "no_NO": "{0} - Feil", - "pl_PL": "{0} - Błąd", - "pt_BR": "{0} - Erro", - "ru_RU": "{0} — Ошибка", - "sv_SE": "{0} - Fel", - "th_TH": "{0} - ผิดพลาด", - "tr_TR": "{0} - Hata", - "uk_UA": "{0} - Помилка", - "zh_CN": "{0} - 错误", - "zh_TW": "{0} - 錯誤" + "fr_FR": "Ryujinx - Erreur", + "he_IL": "ריוג'ינקס - שגיאה", + "it_IT": "Ryujinx - Errore", + "ja_JP": "Ryujinx - エラー", + "ko_KR": "Ryujinx - 오류", + "no_NO": "Ryujinx - Feil", + "pl_PL": "Ryujinx - Błąd", + "pt_BR": "Ryujinx - Erro", + "ru_RU": "Ryujinx - Ошибка", + "th_TH": "Ryujinx - ผิดพลาด", + "tr_TR": "Ryujinx - Hata", + "uk_UA": "Ryujinx - Помилка", + "zh_CN": "Ryujinx - 错误", + "zh_TW": "Ryujinx - 錯誤" } }, { "ID": "DialogWarningTitle", "Translations": { - "ar_SA": "{0} - تحذير", - "de_DE": "{0} - Warnung", - "el_GR": "{0} - Προειδοποίηση", - "en_US": "{0} - Warning", - "es_ES": "{0} - Advertencia", - "fr_FR": "{0} - Avertissement", - "he_IL": "{0} - אזהרה", - "it_IT": "{0} - Avviso", - "ja_JP": "{0} - 警告", - "ko_KR": "{0} - 경고", - "no_NO": "{0} - Advarsel", - "pl_PL": "{0} - Ostrzeżenie", - "pt_BR": "{0} - Alerta", - "ru_RU": "{0} — Предупреждение", - "sv_SE": "{0} - Varning", - "th_TH": "{0} - คำเตือน", - "tr_TR": "{0} - Uyarı", - "uk_UA": "{0} - Попередження", - "zh_CN": "{0} - 警告", - "zh_TW": "{0} - 警告" + "ar_SA": "ريوجينكس - تحذير", + "de_DE": "Ryujinx - Warnung", + "el_GR": "Ryujinx - Προειδοποίηση", + "en_US": "Ryujinx - Warning", + "es_ES": "Ryujinx - Advertencia", + "fr_FR": "Ryujinx - Avertissement", + "he_IL": "ריוג'ינקס - אזהרה", + "it_IT": "Ryujinx - Avviso", + "ja_JP": "Ryujinx - 警告", + "ko_KR": "Ryujinx - 경고", + "no_NO": "Ryujinx - Advarsel", + "pl_PL": "Ryujinx - Ostrzeżenie", + "pt_BR": "Ryujinx - Alerta", + "ru_RU": "Ryujinx - Предупреждение", + "th_TH": "Ryujinx - คำเตือน", + "tr_TR": "Ryujinx - Uyarı", + "uk_UA": "Ryujinx - Попередження", + "zh_CN": "Ryujinx - 警告", + "zh_TW": "Ryujinx - 警告" } }, { "ID": "DialogExitTitle", "Translations": { - "ar_SA": "{0} - الخروج", - "de_DE": "{0} - Beenden", - "el_GR": "{0} - Έξοδος", - "en_US": "{0} - Exit", - "es_ES": "{0} - Salir", - "fr_FR": "{0} - Quitter", - "he_IL": "{0} - יציאה", - "it_IT": "{0} - Esci", - "ja_JP": "{0} - 終了", - "ko_KR": "{0} - 종료", - "no_NO": "{0} - Avslutt", - "pl_PL": "{0} - Wyjdź", - "pt_BR": "{0} - Sair", - "ru_RU": "{0} — Выход", - "sv_SE": "{0} - Avslut", - "th_TH": "{0} - ออก", - "tr_TR": "{0} - Çıkış", - "uk_UA": "{0} - Вихід", - "zh_CN": "{0} - 退出", - "zh_TW": "{0} - 結束" + "ar_SA": "ريوجينكس - الخروج", + "de_DE": "Ryujinx - Beenden", + "el_GR": "Ryujinx - Έξοδος", + "en_US": "Ryujinx - Exit", + "es_ES": "Ryujinx - Salir", + "fr_FR": "Ryujinx - Quitter", + "he_IL": "ריוג'ינקס - יציאה", + "it_IT": "Ryujinx - Esci", + "ja_JP": "Ryujinx - 終了", + "ko_KR": "Ryujinx - 종료", + "no_NO": "Ryujinx - Avslutt", + "pl_PL": "Ryujinx - Wyjdź", + "pt_BR": "Ryujinx - Sair", + "ru_RU": "Ryujinx - Выход", + "th_TH": "Ryujinx - ออก", + "tr_TR": "Ryujinx - Çıkış", + "uk_UA": "Ryujinx - Вихід", + "zh_CN": "Ryujinx - 退出", + "zh_TW": "Ryujinx - 結束" } }, { @@ -12239,7 +10886,6 @@ "pl_PL": "Ryujinx napotkał błąd", "pt_BR": "Ryujinx encontrou um erro", "ru_RU": "Ryujinx обнаружил ошибку", - "sv_SE": "Ryujinx har påträffat ett fel", "th_TH": "Ryujinx พบข้อผิดพลาด", "tr_TR": "Ryujinx bir hata ile karşılaştı", "uk_UA": "У Ryujinx сталася помилка", @@ -12264,7 +10910,6 @@ "pl_PL": "Czy na pewno chcesz zamknąć Ryujinx?", "pt_BR": "Tem certeza que deseja fechar o Ryujinx?", "ru_RU": "Вы уверены, что хотите выйти из Ryujinx?", - "sv_SE": "Är du säker på att du vill avsluta Ryujinx?", "th_TH": "คุณแน่ใจหรือไม่ว่าต้องการปิด Ryujinx หรือไม่?", "tr_TR": "Ryujinx'i kapatmak istediğinizden emin misiniz?", "uk_UA": "Ви впевнені, що бажаєте закрити Ryujinx?", @@ -12288,8 +10933,7 @@ "no_NO": "Alle ulagrede data vil gå tapt!", "pl_PL": "Wszystkie niezapisane dane zostaną utracone!", "pt_BR": "Todos os dados que não foram salvos serão perdidos!", - "ru_RU": "Все несохранённые данные будут потеряны", - "sv_SE": "Allt data som inte sparats kommer att förloras!", + "ru_RU": "Все несохраненные данные будут потеряны", "th_TH": "ข้อมูลทั้งหมดที่ไม่ได้บันทึกทั้งหมดจะสูญหาย!", "tr_TR": "Kaydedilmeyen bütün veriler kaybedilecek!", "uk_UA": "Усі незбережені дані буде втрачено!", @@ -12312,9 +10956,8 @@ "ko_KR": "지정된 저장 데이터를 생성하는 동안 오류가 발생 : {0}", "no_NO": "Det oppstod en feil under oppretting av den angitte lagredata: {0}", "pl_PL": "Wystąpił błąd podczas tworzenia określonych zapisanych danych: {0}", - "pt_BR": "Ocorreu um erro ao criar os dados salvos especificados: {0}", + "pt_BR": "Ocorreu um erro ao criar o diretório de salvamento: {0}", "ru_RU": "Произошла ошибка при создании указанных данных сохранения: {0}", - "sv_SE": "Det inträffade ett fel vid skapandet av angivet sparat spel: {0}", "th_TH": "มีข้อผิดพลาดในการสร้างข้อมูลบันทึกที่ระบุ: {0}", "tr_TR": "Belirtilen kayıt verisi oluşturulurken bir hata oluştu: {0}", "uk_UA": "Під час створення вказаних даних збереження сталася помилка: {0}", @@ -12337,9 +10980,8 @@ "ko_KR": "지정된 저장 데이터를 찾는 중 오류가 발생 : {0}", "no_NO": "Det oppstod en feil under oppretting av den angitte lagredata: {0}", "pl_PL": "Wystąpił błąd podczas próby znalezienia określonych zapisanych danych: {0}", - "pt_BR": "Ocorreu um erro ao encontrar os dados salvos especificados: {0}", + "pt_BR": "Ocorreu um erro ao tentar encontrar o diretório de salvamento: {0}", "ru_RU": "Произошла ошибка при поиске указанных данных сохранения: {0}", - "sv_SE": "Det inträffade ett fel vid sökandet av angivet sparat spel: {0}", "th_TH": "มีข้อผิดพลาดในการค้นหาข้อมูลบันทึกที่ระบุไว้: {0}", "tr_TR": "Belirtilen kayıt verisi bulunmaya çalışırken hata: {0}", "uk_UA": "Під час пошуку вказаних даних збереження сталася помилка: {0}", @@ -12362,9 +11004,8 @@ "ko_KR": "압축을 풀 폴더를 선택", "no_NO": "Velg mappen å pakke ut i", "pl_PL": "Wybierz folder, do którego chcesz rozpakować", - "pt_BR": "Escolha a pasta para extrair", + "pt_BR": "Escolha o diretório onde os arquivos serão extraídos", "ru_RU": "Выберите папку для извлечения", - "sv_SE": "Välj en mapp att extrahera till", "th_TH": "เลือกโฟลเดอร์ที่จะแตกไฟล์เข้าไป", "tr_TR": "İçine ayıklanacak klasörü seç", "uk_UA": "Виберіть теку для видобування", @@ -12389,7 +11030,6 @@ "pl_PL": "Wypakowywanie sekcji {0} z {1}...", "pt_BR": "Extraindo seção {0} de {1}...", "ru_RU": "Извлечение {0} раздела из {1}...", - "sv_SE": "Extraherar {0}-sektion från {1}...", "th_TH": "กำลังแตกไฟล์ {0} จากส่วน {1}...", "tr_TR": "{1} den {0} kısmı ayıklanıyor...", "uk_UA": "Видобування розділу {0} з {1}...", @@ -12412,9 +11052,8 @@ "ko_KR": "NCA 단면 추출기", "no_NO": "Ryujinx - NCA Seksjon Ekstraktor", "pl_PL": "Asystent wypakowania sekcji NCA", - "pt_BR": "Extrator de Seções NCA", + "pt_BR": "Extrator de seções NCA", "ru_RU": "Извлечение разделов NCA", - "sv_SE": "Ryujinx - Extrahera NCA-sektion", "th_TH": "เครื่องมือแตกไฟล์ของ NCA", "tr_TR": "NCA Kısmı Ayıklayıcısı", "uk_UA": "Екстрактор розділів NCA", @@ -12439,7 +11078,6 @@ "pl_PL": "Niepowodzenie podczas wypakowywania. W wybranym pliku nie było głównego NCA.", "pt_BR": "Falha na extração. O NCA principal não foi encontrado no arquivo selecionado.", "ru_RU": "Ошибка извлечения. Основной NCA не присутствовал в выбранном файле.", - "sv_SE": "Fel vid extrahering. Main NCA hittades inte i vald fil.", "th_TH": "เกิดความล้มเหลวในการแตกไฟล์เนื่องจากไม่พบ NCA หลักในไฟล์ที่เลือก", "tr_TR": "Ayıklama hatası. Ana NCA seçilen dosyada bulunamadı.", "uk_UA": "Помилка видобування. Основний NCA не був присутній у вибраному файлі.", @@ -12464,7 +11102,6 @@ "pl_PL": "Niepowodzenie podczas wypakowywania. Przeczytaj plik dziennika, aby uzyskać więcej informacji.", "pt_BR": "Falha na extração. Leia o arquivo de log para mais informações.", "ru_RU": "Ошибка извлечения. Прочтите файл журнала для получения дополнительной информации.", - "sv_SE": "Fel vid extrahering. Läs i loggfilen för mer information.", "th_TH": "เกิดความล้มเหลวในการแตกไฟล์ โปรดอ่านไฟล์บันทึกประวัติเพื่อดูข้อมูลเพิ่มเติม", "tr_TR": "Ayıklama hatası. Ek bilgi için kayıt dosyasını okuyun.", "uk_UA": "Помилка видобування. Прочитайте файл журналу для отримання додаткової інформації.", @@ -12489,7 +11126,6 @@ "pl_PL": "Wypakowywanie zakończone pomyślnie.", "pt_BR": "Extração concluída com êxito.", "ru_RU": "Извлечение завершено успешно.", - "sv_SE": "Extraheringen lyckades.", "th_TH": "การแตกไฟล์เสร็จสมบูรณ์แล้ว", "tr_TR": "Ayıklama başarıyla tamamlandı.", "uk_UA": "Видобування успішно завершено.", @@ -12514,7 +11150,6 @@ "pl_PL": "Nie udało się przekonwertować obecnej wersji Ryujinx.", "pt_BR": "Falha ao converter a versão atual do Ryujinx.", "ru_RU": "Не удалось преобразовать текущую версию Ryujinx.", - "sv_SE": "Misslyckades med att konvertera aktuell Ryujinx-version.", "th_TH": "ไม่สามารถแปลงเวอร์ชั่น Ryujinx ปัจจุบันได้", "tr_TR": "Güncel Ryujinx sürümü dönüştürülemedi.", "uk_UA": "Не вдалося конвертувати поточну версію Ryujinx.", @@ -12539,7 +11174,6 @@ "pl_PL": "Anulowanie aktualizacji!", "pt_BR": "Cancelando atualização!", "ru_RU": "Отмена обновления...", - "sv_SE": "Avbryter uppdatering!", "th_TH": "ยกเลิกการอัพเดต!", "tr_TR": "Güncelleme iptal ediliyor!", "uk_UA": "Скасування оновлення!", @@ -12564,7 +11198,6 @@ "pl_PL": "Używasz już najnowszej wersji Ryujinx!", "pt_BR": "Você já está usando a versão mais recente do Ryujinx!", "ru_RU": "Вы используете самую последнюю версию Ryujinx", - "sv_SE": "Du använder redan den senaste versionen av Ryujinx!", "th_TH": "คุณกำลังใช้ Ryujinx เวอร์ชั่นที่อัปเดตล่าสุด!", "tr_TR": "Zaten Ryujinx'in en güncel sürümünü kullanıyorsunuz!", "uk_UA": "Ви вже використовуєте останню версію Ryujinx!", @@ -12589,7 +11222,6 @@ "pl_PL": "Wystąpił błąd podczas próby uzyskania informacji o obecnej wersji z GitHub Release. Może to być spowodowane nową wersją kompilowaną przez GitHub Actions. Spróbuj ponownie za kilka minut.", "pt_BR": "Ocorreu um erro ao tentar obter as informações de atualização do GitHub Release. Isso pode ser causado se uma nova versão estiver sendo compilado pelas Ações do GitHub. Tente novamente em alguns minutos.", "ru_RU": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано тем, что в данный момент в GitHub Actions компилируется новый релиз. Повторите попытку позже.", - "sv_SE": "Ett fel inträffade vid försök att hämta information om utgåvan från GitHub. Detta kan hända om en ny utgåva har kompilerats av GitHub Actions. Försök igen om några minuter.", "th_TH": "เกิดข้อผิดพลาดขณะพยายามรับข้อมูลเวอร์ชั่นจาก GitHub Release ปัญหานี้อาจเกิดขึ้นได้หากมีการรวบรวมเวอร์ชั่นใหม่โดย GitHub โปรดลองอีกครั้งในอีกไม่กี่นาทีข้างหน้า", "tr_TR": "GitHub tarafından sürüm bilgileri alınırken bir hata oluştu. Eğer yeni sürüm için hazırlıklar yapılıyorsa bu hatayı almanız olasıdır. Lütfen birkaç dakika sonra tekrar deneyiniz.", "uk_UA": "Під час спроби отримати інформацію про випуск із GitHub Release сталася помилка. Це може бути спричинено, якщо новий випуск компілюється GitHub Actions. Повторіть спробу через кілька хвилин.", @@ -12612,9 +11244,8 @@ "ko_KR": "GitHub에서 받은 Ryujinx 버전을 변환하지 못했습니다.", "no_NO": "Kan ikke konvertere mottatt Ryujinx-versjon fra GitHub Utgivelse.", "pl_PL": "Nie udało się przekonwertować otrzymanej wersji Ryujinx z Github Release.", - "pt_BR": "Falha ao converter a versão Ryujinx recebida do GitHub.", + "pt_BR": "Falha ao converter a versão do Ryujinx recebida do AppVeyor.", "ru_RU": "Не удалось преобразовать полученную версию Ryujinx из GitHub Release.", - "sv_SE": "Misslyckades med att konvertera mottagen Ryujinx-version från GitHub.", "th_TH": "ไม่สามารถแปลงเวอร์ชั่น Ryujinx ที่ได้รับจาก GitHub Release", "tr_TR": "Github Release'den alınan Ryujinx sürümü dönüştürülemedi.", "uk_UA": "Не вдалося конвертувати отриману версію Ryujinx із випуску GitHub.", @@ -12637,9 +11268,8 @@ "ko_KR": "업데이트 내려받는 중...", "no_NO": "Laster ned oppdatering...", "pl_PL": "Pobieranie aktualizacji...", - "pt_BR": "Baixando Atualização...", + "pt_BR": "Baixando atualização...", "ru_RU": "Загрузка обновления...", - "sv_SE": "Hämtar uppdatering...", "th_TH": "กำลังดาวน์โหลดอัปเดต...", "tr_TR": "Güncelleme İndiriliyor...", "uk_UA": "Завантаження оновлення...", @@ -12662,9 +11292,8 @@ "ko_KR": "업데이트 추출 중...", "no_NO": "Pakker ut oppdatering...", "pl_PL": "Wypakowywanie Aktualizacji...", - "pt_BR": "Extraindo Atualização...", + "pt_BR": "Extraindo atualização...", "ru_RU": "Извлечение обновления...", - "sv_SE": "Extraherar uppdatering...", "th_TH": "กำลังแตกไฟล์อัปเดต...", "tr_TR": "Güncelleme Ayıklanıyor...", "uk_UA": "Видобування оновлення...", @@ -12682,14 +11311,13 @@ "es_ES": "Renombrando actualización...", "fr_FR": "Renommage de la mise à jour...", "he_IL": "משנה את שם העדכון...", - "it_IT": "Ridenominazione dell'aggiornamento...", + "it_IT": "Rinominazione dell'aggiornamento...", "ja_JP": "アップデートをリネーム中...", "ko_KR": "이름 변경 업데이트...", "no_NO": "Endrer navn på oppdatering...", "pl_PL": "Zmiana Nazwy Aktualizacji...", - "pt_BR": "Renomeando Atualização...", + "pt_BR": "Renomeando atualização...", "ru_RU": "Переименование обновления...", - "sv_SE": "Byter namn på uppdatering...", "th_TH": "กำลังลบไฟล์เก่า...", "tr_TR": "Güncelleme Yeniden Adlandırılıyor...", "uk_UA": "Перейменування оновлення...", @@ -12712,9 +11340,8 @@ "ko_KR": "새 업데이트 추가 중...", "no_NO": "Legger til ny oppdatering...", "pl_PL": "Dodawanie Nowej Aktualizacji...", - "pt_BR": "Adicionando Nova Atualização...", + "pt_BR": "Adicionando nova atualização...", "ru_RU": "Добавление нового обновления...", - "sv_SE": "Lägger till ny uppdatering...", "th_TH": "กำลังเพิ่มไฟล์อัปเดตใหม่...", "tr_TR": "Yeni Güncelleme Ekleniyor...", "uk_UA": "Додавання нового оновлення...", @@ -12732,19 +11359,18 @@ "es_ES": "", "fr_FR": "Afficher Changelog", "he_IL": "", - "it_IT": "Mostra il changelog", + "it_IT": "", "ja_JP": "", "ko_KR": "변경 로그 보기", "no_NO": "Vis endringslogg", "pl_PL": "", - "pt_BR": "Ver Registro de Alterações", - "ru_RU": "Показать список изменений", - "sv_SE": "Visa ändringslogg", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Показати список змін", - "zh_CN": "显示更新日志", - "zh_TW": "顯示更新日誌" + "zh_CN": "", + "zh_TW": "" } }, { @@ -12762,9 +11388,8 @@ "ko_KR": "업데이트가 완료되었습니다!", "no_NO": "Oppdateringen er fullført!", "pl_PL": "Aktualizacja Zakończona!", - "pt_BR": "Atualização Concluída!", + "pt_BR": "Atualização concluída!", "ru_RU": "Обновление завершено", - "sv_SE": "Uppdatering färdig!", "th_TH": "อัปเดตเสร็จสมบูรณ์แล้ว!", "tr_TR": "Güncelleme Tamamlandı!", "uk_UA": "Оновлення завершено!", @@ -12789,7 +11414,6 @@ "pl_PL": "Czy chcesz teraz zrestartować Ryujinx?", "pt_BR": "Deseja reiniciar o Ryujinx agora?", "ru_RU": "Перезапустить Ryujinx?", - "sv_SE": "Vill du starta om Ryujinx nu?", "th_TH": "คุณต้องการรีสตาร์ท Ryujinx ตอนนี้หรือไม่?", "tr_TR": "Ryujinx'i şimdi yeniden başlatmak istiyor musunuz?", "uk_UA": "Перезапустити Ryujinx зараз?", @@ -12814,7 +11438,6 @@ "pl_PL": "Nie masz połączenia z Internetem!", "pt_BR": "Você não está conectado à Internet!", "ru_RU": "Вы не подключены к интернету", - "sv_SE": "Du är inte ansluten till internet!", "th_TH": "คุณไม่ได้เชื่อมต่อกับอินเทอร์เน็ต!", "tr_TR": "İnternete bağlı değilsiniz!", "uk_UA": "Ви не підключені до Інтернету!", @@ -12839,7 +11462,6 @@ "pl_PL": "Sprawdź, czy masz działające połączenie internetowe!", "pt_BR": "Por favor, certifique-se de que você tem uma conexão funcional à Internet!", "ru_RU": "Убедитесь, что у вас работает подключение к интернету", - "sv_SE": "Försäkra dig om att du har en fungerande internetanslutning!", "th_TH": "โปรดตรวจสอบว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตว่ามีการใช้งานได้หรือไม่!", "tr_TR": "Lütfen aktif bir internet bağlantınız olduğunu kontrol edin!", "uk_UA": "Будь ласка, переконайтеся, що у вас є робоче підключення до Інтернету!", @@ -12864,7 +11486,6 @@ "pl_PL": "Nie możesz zaktualizować Dirty wersji Ryujinx!", "pt_BR": "Você não pode atualizar uma compilação Dirty do Ryujinx!", "ru_RU": "Вы не можете обновлять Dirty Build", - "sv_SE": "Du kan inte uppdatera en Dirty build av Ryujinx!", "th_TH": "คุณไม่สามารถอัปเดต Dirty build ของ Ryujinx ได้!", "tr_TR": "Ryujinx'in Dirty build'lerini güncelleyemezsiniz!", "uk_UA": "Ви не можете оновити брудну збірку Ryujinx!", @@ -12885,11 +11506,10 @@ "it_IT": "Scarica Ryujinx da https://ryujinx.app/download se stai cercando una versione supportata.", "ja_JP": "サポートされているバージョンをお探しなら, https://ryujinx.app/download で Ryujinx をダウンロードしてください.", "ko_KR": "지원되는 버전을 찾으신다면 https://ryujinx.app/download 에서 Ryujinx를 내려받으세요.", - "no_NO": "Vennligst last ned Ryujinx på https://ryujinx.app/download hvis du ser etter en støttet versjon.", + "no_NO": "Vennligst last ned Ryujinx på https://ryujinx.org/ hvis du ser etter en støttet versjon.", "pl_PL": "Pobierz Ryujinx ze strony https://ryujinx.app/download, jeśli szukasz obsługiwanej wersji.", "pt_BR": "Por favor, baixe o Ryujinx em https://ryujinx.app/download se está procurando por uma versão suportada.", "ru_RU": "Загрузите Ryujinx по адресу https://ryujinx.app/download если вам нужна поддерживаемая версия.", - "sv_SE": "Hämta Ryujinx från https://ryujinx.app/download om du letar efter en version som stöds.", "th_TH": "โปรดดาวน์โหลด Ryujinx ได้ที่ https://ryujinx.app/download หากคุณกำลังมองหาเวอร์ชั่นที่รองรับ", "tr_TR": "Desteklenen bir sürüm için lütfen Ryujinx'i https://ryujinx.app/download sitesinden indirin.", "uk_UA": "Будь ласка, завантажте Ryujinx на https://ryujinx.app/download, якщо ви шукаєте підтримувану версію.", @@ -12912,9 +11532,8 @@ "ko_KR": "다시 시작 필요", "no_NO": "Omstart Kreves", "pl_PL": "Wymagane Ponowne Uruchomienie", - "pt_BR": "Reinicialização Necessária", - "ru_RU": "Требуется перезапуск", - "sv_SE": "Omstart krävs", + "pt_BR": "Reinicialização necessária", + "ru_RU": "Требуется перезагрузка", "th_TH": "จำเป็นต้องรีสตาร์ทเพื่อให้การอัพเดตสามารถให้งานได้", "tr_TR": "Yeniden Başlatma Gerekli", "uk_UA": "Потрібен перезапуск", @@ -12938,8 +11557,7 @@ "no_NO": "Temaet har blitt lagret. En omstart kreves for å bruke temaet.", "pl_PL": "Motyw został zapisany. Aby zastosować motyw, konieczne jest ponowne uruchomienie.", "pt_BR": "O tema foi salvo. Uma reinicialização é necessária para aplicar o tema.", - "ru_RU": "Тема сохранена. Для применения темы требуется выполнить перезапуск.", - "sv_SE": "Temat har sparats. En omstart krävs för att verkställa ändringen.", + "ru_RU": "Тема сохранена. Для применения темы требуется перезапуск.", "th_TH": "บันทึกธีมแล้ว จำเป็นต้องรีสตาร์ทเพื่อใช้ธีม", "tr_TR": "Tema kaydedildi. Temayı uygulamak için yeniden başlatma gerekiyor.", "uk_UA": "Тему збережено. Щоб застосувати тему, потрібен перезапуск.", @@ -12963,8 +11581,7 @@ "no_NO": "Vil du starte på nytt", "pl_PL": "Czy chcesz uruchomić ponownie?", "pt_BR": "Deseja reiniciar?", - "ru_RU": "Выполнить перезапуск?", - "sv_SE": "Vill du starta om", + "ru_RU": "Хотите перезапустить", "th_TH": "คุณต้องการรีสตาร์ทหรือไม่?", "tr_TR": "Yeniden başlatmak ister misiniz", "uk_UA": "Ви хочете перезапустити", @@ -12982,14 +11599,13 @@ "es_ES": "¿Quieres instalar el firmware incluido en este juego? (Firmware versión {0})", "fr_FR": "Voulez-vous installer le firmware intégré dans ce jeu ? (Firmware {0})", "he_IL": "האם תרצו להתקין את הקושחה המוטמעת במשחק הזה? (קושחה {0})", - "it_IT": "Vuoi installare il firmware incluso in questo gioco? (Firmware {0})", + "it_IT": "Vuoi installare il firmware incorporato in questo gioco? (Firmware {0})", "ja_JP": "このゲームに含まれるファームウェアをインストールしてよろしいですか? (ファームウェア {0})", "ko_KR": "이 게임에 포함된 펌웨어를 설치하시겠습니까?(Firmware {0})", "no_NO": "Ønsker du å installere fastvaren innebygd i dette spillet? (Firmware {0})", "pl_PL": "Czy chcesz zainstalować firmware wbudowany w tę grę? (Firmware {0})", "pt_BR": "Gostaria de instalar o firmware incluso neste jogo? (Firmware {0})", "ru_RU": "Хотите установить прошивку, встроенную в эту игру? (Прошивка {0})", - "sv_SE": "Vill du installera det firmware som är inbäddat i detta spel? (Firmware {0})", "th_TH": "คุณต้องการติดตั้งเฟิร์มแวร์ที่ฝังอยู่ในเกมนี้หรือไม่? (เฟิร์มแวร์ {0})", "tr_TR": "Bu oyunun içine gömülü olan yazılımı yüklemek ister misiniz? (Firmware {0})", "uk_UA": "Бажаєте встановити прошивку, вбудовану в цю гру? (Прошивка {0})", @@ -13014,7 +11630,6 @@ "pl_PL": "Nie znaleziono zainstalowanego oprogramowania, ale Ryujinx był w stanie zainstalować oprogramowanie {0} z dostarczonej gry.\n\nEmulator uruchomi się teraz.", "pt_BR": "Nenhum firmware instalado foi encontrado, mas o Ryujinx conseguiu instalar o firmware {0} a partir do jogo fornecido.\nO emulador será iniciado agora.", "ru_RU": "Установленная прошивка не была найдена, но Ryujinx удалось установить прошивку {0} из предоставленной игры.\nТеперь эмулятор запустится.", - "sv_SE": "Inget installerat firmware hittades men Ryujinx kunde installera firmware {0} från angiven spel.\nEmulatorn kommer nu att startas.", "th_TH": "ไม่พบเฟิร์มแวร์ที่ติดตั้งไว้ แต่ Ryujinx จะติดตั้งเฟิร์มแวร์ได้ {0} จากเกมที่ให้มา\nขณะนี้โปรแกรมจำลองจะเริ่มทำงาน", "tr_TR": "", "uk_UA": "Встановлену прошивку не знайдено, але Ryujinx вдалося встановити прошивку {0} з наданої гри.\nТепер запуститься емулятор.", @@ -13037,9 +11652,8 @@ "ko_KR": "펌웨어가 설치되어 있지 않음", "no_NO": "Ingen fastvare installert", "pl_PL": "Brak Zainstalowanego Firmware'u", - "pt_BR": "Nenhum Firmware Instalado", + "pt_BR": "Firmware não foi instalado", "ru_RU": "Прошивка не установлена", - "sv_SE": "Inget firmware installerat", "th_TH": "ไม่มีการติดตั้งเฟิร์มแวร์", "tr_TR": "Yazılım Yüklü Değil", "uk_UA": "Прошивка не встановлена", @@ -13064,7 +11678,6 @@ "pl_PL": "Firmware {0} został zainstalowany", "pt_BR": "Firmware {0} foi instalado", "ru_RU": "Прошивка {0} была установлена", - "sv_SE": "Firmware {0} installerades", "th_TH": "เฟิร์มแวร์ {0} ติดตั้งแล้ว", "tr_TR": "Yazılım {0} yüklendi", "uk_UA": "Встановлено прошивку {0}", @@ -13089,7 +11702,6 @@ "pl_PL": "Pomyślnie zainstalowano typy plików!", "pt_BR": "Tipos de arquivo instalados com sucesso!", "ru_RU": "Типы файлов успешно установлены", - "sv_SE": "Filtyper har installerats!", "th_TH": "ติดตั้งตามประเภทของไฟล์สำเร็จแล้ว!", "tr_TR": "Dosya uzantıları başarıyla yüklendi!", "uk_UA": "Успішно встановлено типи файлів!", @@ -13114,7 +11726,6 @@ "pl_PL": "Nie udało się zainstalować typów plików.", "pt_BR": "Falha ao instalar tipos de arquivo.", "ru_RU": "Не удалось установить типы файлов.", - "sv_SE": "Misslyckades med att installera filtyper.", "th_TH": "ติดตั้งตามประเภทของไฟล์ไม่สำเร็จ", "tr_TR": "Dosya uzantıları yükleme işlemi başarısız oldu.", "uk_UA": "Не вдалося встановити типи файлів.", @@ -13139,7 +11750,6 @@ "pl_PL": "Pomyślnie odinstalowano typy plików!", "pt_BR": "Tipos de arquivo desinstalados com sucesso!", "ru_RU": "Типы файлов успешно удалены", - "sv_SE": "Filtyper avinstallerades!", "th_TH": "ถอนการติดตั้งตามประเภทของไฟล์สำเร็จแล้ว!", "tr_TR": "Dosya uzantıları başarıyla kaldırıldı!", "uk_UA": "Успішно видалено типи файлів!", @@ -13164,7 +11774,6 @@ "pl_PL": "Nie udało się odinstalować typów plików.", "pt_BR": "Falha ao desinstalar tipos de arquivo.", "ru_RU": "Не удалось удалить типы файлов.", - "sv_SE": "Misslyckades med att avinstallera filtyper.", "th_TH": "ไม่สามารถถอนการติดตั้งตามประเภทของไฟล์ได้", "tr_TR": "Dosya uzantıları kaldırma işlemi başarısız oldu.", "uk_UA": "Не вдалося видалити типи файлів.", @@ -13187,9 +11796,8 @@ "ko_KR": "설정 창 열기", "no_NO": "Åpne innstillinger-vinduet", "pl_PL": "Otwórz Okno Ustawień", - "pt_BR": "Abrir Janela de Configurações", + "pt_BR": "Abrir janela de configurações", "ru_RU": "Открывает окно параметров", - "sv_SE": "Öppna inställningar", "th_TH": "เปิดหน้าต่างการตั้งค่า", "tr_TR": "Seçenekler Penceresini Aç", "uk_UA": "Відкрити вікно налаштувань", @@ -13207,19 +11815,18 @@ "es_ES": "Ventana recortador XCI", "fr_FR": "Fenêtre de réduction de fichiers XCI", "he_IL": "", - "it_IT": "Riduci dimensioni dei file XCI", + "it_IT": "Finestra XCI Trimmer", "ja_JP": "", "ko_KR": "XCI 트리머 창", "no_NO": "XCI Trimmervindu", "pl_PL": "", - "pt_BR": "Janela de Redução XCI", - "ru_RU": "Окно триммера XCI", - "sv_SE": "XCI-optimerare", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Вікно XCI Тримера", - "zh_CN": "XCI 文件瘦身窗口", - "zh_TW": "XCI 修剪器視窗" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -13237,9 +11844,8 @@ "ko_KR": "컨트롤러 애플릿", "no_NO": "Kontroller Applet", "pl_PL": "Aplet Kontrolera", - "pt_BR": "Applet de Controle", + "pt_BR": "Applet de controle", "ru_RU": "Апплет контроллера", - "sv_SE": "Handkontroller-applet", "th_TH": "คอนโทรลเลอร์ Applet", "tr_TR": "Kumanda Applet'i", "uk_UA": "Аплет контролера", @@ -13257,14 +11863,13 @@ "es_ES": "Error al mostrar cuadro de diálogo: {0}", "fr_FR": "Erreur lors de l'affichage de la boîte de dialogue : {0}", "he_IL": "שגיאה בהצגת דיאלוג ההודעה: {0}", - "it_IT": "Errore nella visualizzazione della finestra di dialogo: {0}", + "it_IT": "Errore nella visualizzazione del Message Dialog: {0}", "ja_JP": "メッセージダイアログ表示エラー: {0}", "ko_KR": "메시지 대화 상자 표시 오류 : {0}", "no_NO": "Feil ved visning av meldings-dialog: {0}", "pl_PL": "Błąd wyświetlania okna Dialogowego Wiadomości: {0}", "pt_BR": "Erro ao exibir diálogo de mensagem: {0}", "ru_RU": "Ошибка отображения сообщения: {0}", - "sv_SE": "Fel vid visning av meddelandedialog: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงกล่องโต้ตอบข้อความ: {0}", "tr_TR": "Mesaj diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу діалогового вікна повідомлення: {0}", @@ -13289,7 +11894,6 @@ "pl_PL": "Błąd wyświetlania Klawiatury Oprogramowania: {0}", "pt_BR": "Erro ao exibir teclado virtual: {0}", "ru_RU": "Ошибка отображения программной клавиатуры: {0}", - "sv_SE": "Fel vid visning av programvarutangentbord: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงซอฟต์แวร์แป้นพิมพ์: {0}", "tr_TR": "Mesaj diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу програмної клавіатури: {0}", @@ -13307,14 +11911,13 @@ "es_ES": "Error al mostrar díalogo ErrorApplet: {0}", "fr_FR": "Erreur lors de l'affichage de la boîte de dialogue ErrorApplet: {0}", "he_IL": "שגיאה בהצגת דיאלוג ErrorApplet: {0}", - "it_IT": "Errore nella visualizzazione della finestra dell'ErrorApplet: {0}", + "it_IT": "Errore nella visualizzazione dell'ErrorApplet Dialog: {0}", "ja_JP": "エラーアプレットダイアログ表示エラー: {0}", "ko_KR": "애플릿 오류류 대화 상자 표시 오류 : {0}", "no_NO": "Feil ved visning av Feilmeldingsdialog: {0}", "pl_PL": "Błąd wyświetlania okna Dialogowego ErrorApplet: {0}", "pt_BR": "Erro ao exibir applet ErrorApplet: {0}", "ru_RU": "Ошибка отображения диалогового окна ErrorApplet: {0}", - "sv_SE": "Fel vid visning av ErrorApplet-dialog: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงกล่องโต้ตอบ ข้อผิดพลาดของ Applet: {0}", "tr_TR": "Applet diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу діалогового вікна ErrorApplet: {0}", @@ -13339,7 +11942,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -13364,7 +11966,6 @@ "pl_PL": "\nAby uzyskać więcej informacji o tym, jak naprawić ten błąd, zapoznaj się z naszym Przewodnikiem instalacji.", "pt_BR": "\nPara mais informações sobre como corrigir esse erro, siga nosso Guia de Configuração.", "ru_RU": "\nДля получения дополнительной информации о том, как исправить эту ошибку, следуйте нашему Руководству по установке.", - "sv_SE": "\nFölj vår konfigurationsguide för mer information om hur man rättar till detta fel.", "th_TH": "\nสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีแก้ไขข้อผิดพลาดนี้ โปรดทำตามคำแนะนำในการตั้งค่าของเรา", "tr_TR": "\nBu hatayı düzeltmek adına daha fazla bilgi için kurulum kılavuzumuzu takip edin.", "uk_UA": "\nДля отримання додаткової інформації про те, як виправити цю помилку, дотримуйтесь нашого посібника з налаштування.", @@ -13389,7 +11990,6 @@ "pl_PL": "Błąd Ryujinxa ({0})", "pt_BR": "Erro do Ryujinx ({0})", "ru_RU": "Ошибка Ryujinx ({0})", - "sv_SE": "Ryujinx-fel ({0}", "th_TH": "ข้อผิดพลาด Ryujinx ({0})", "tr_TR": "Ryujinx Hatası ({0})", "uk_UA": "Помилка Ryujinx ({0})", @@ -13407,17 +12007,16 @@ "es_ES": "", "fr_FR": "API Amiibo", "he_IL": "ממשק תכנות אמיבו", - "it_IT": "API Amiibo", + "it_IT": "", "ja_JP": "", "ko_KR": "", "no_NO": "", "pl_PL": "API Amiibo", "pt_BR": "API Amiibo", - "ru_RU": "API Amiibo", - "sv_SE": "Amiibo-API", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "API Amiibo", + "uk_UA": "", "zh_CN": "", "zh_TW": "" } @@ -13439,7 +12038,6 @@ "pl_PL": "Wystąpił błąd podczas pobierania informacji z API.", "pt_BR": "Um erro ocorreu ao tentar obter informações da API.", "ru_RU": "Произошла ошибка при получении информации из API.", - "sv_SE": "Ett fel inträffade vid hämtning av information från API.", "th_TH": "เกิดข้อผิดพลาดขณะเรียกข้อมูลจาก API", "tr_TR": "API'dan bilgi alırken bir hata oluştu.", "uk_UA": "Під час отримання інформації з API сталася помилка.", @@ -13457,14 +12055,13 @@ "es_ES": "No se pudo conectar al servidor de la API Amiibo. El servicio puede estar caído o tu conexión a internet puede haberse desconectado.", "fr_FR": "Impossible de se connecter au serveur API Amiibo. Le service est peut-être hors service ou vous devriez peut-être vérifier que votre connexion internet est connectée.", "he_IL": "לא ניתן להתחבר לממשק שרת האמיבו. ייתכן שהשירות מושבת או שתצטרך לוודא שהחיבור לאינטרנט שלך מקוון.", - "it_IT": "Impossibile connettersi al server dell'API Amiibo. Il servizio potrebbe non essere disponibile o potresti non essere connesso a Internet.", + "it_IT": "Impossibile connettersi al server Amiibo API. Il servizio potrebbe essere fuori uso o potresti dover verificare che la tua connessione internet sia online.", "ja_JP": "Amiibo API サーバに接続できませんでした. サーバがダウンしているか, インターネット接続に問題があるかもしれません.", "ko_KR": "Amiibo API 서버에 연결할 수 없습니다. 서비스가 다운되었거나 인터넷 연결이 온라인 상태인지 확인이 필요합니다.", "no_NO": "Kan ikke koble til Amiibo API server. Tjenesten kan være nede, eller du må kanskje verifisere at din internettforbindelse er tilkoblet.", "pl_PL": "Nie można połączyć się z serwerem API Amiibo. Usługa może nie działać lub może być konieczne sprawdzenie, czy połączenie internetowe jest online.", "pt_BR": "Não foi possível conectar ao servidor da API Amiibo. O serviço pode estar fora do ar ou você precisa verificar sua conexão com a Internet.", "ru_RU": "Не удалось подключиться к серверу Amiibo API. Служба может быть недоступна или вам может потребоваться проверить ваше интернет-соединение.", - "sv_SE": "Kunde inte ansluta till Amiibo API-server. Tjänsten kanske är nere eller så behöver du kontrollera att din internetanslutning fungerar.", "th_TH": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ Amiibo API บางบริการอาจหยุดทำงาน หรือไม่คุณต้องทำการตรวจสอบว่าอินเทอร์เน็ตของคุณอยู่ในสถานะเชื่อมต่ออยู่หรือไม่", "tr_TR": "Amiibo API sunucusuna bağlanılamadı. Sunucu çevrimdışı olabilir veya uygun bir internet bağlantınızın olduğunu kontrol etmeniz gerekebilir.", "uk_UA": "Неможливо підключитися до сервера Amiibo API. Можливо, служба не працює або вам потрібно перевірити, чи є підключення до Інтернету.", @@ -13482,14 +12079,13 @@ "es_ES": "El perfil {0} no es compatible con el sistema actual de configuración de entrada.", "fr_FR": "Le profil {0} est incompatible avec le système de configuration de manette actuel.", "he_IL": "הפרופיל {0} אינו תואם למערכת תצורת הקלט הנוכחית.", - "it_IT": "Il profilo {0} non è compatibile con l'attuale sistema di configurazione input.", + "it_IT": "Il profilo {0} è incompatibile con l'attuale sistema di configurazione input.", "ja_JP": "プロファイル {0} は現在の入力設定システムと互換性がありません.", "ko_KR": "프로필 {0}은(는) 현재 입력 구성 시스템과 호환되지 않습니다.", "no_NO": "Profil {0} er ikke kompatibel med den gjeldende inndata konfigurasjonen", "pl_PL": "Profil {0} jest niezgodny z bieżącym systemem konfiguracji sterowania.", "pt_BR": "Perfil {0} é incompatível com o sistema de configuração de controle atual.", "ru_RU": "Профиль {0} несовместим с текущей системой конфигурации ввода.", - "sv_SE": "Profilen {0} är inte kompatibel med aktuell konfiguration för inmatning.", "th_TH": "โปรไฟล์ {0} ไม่สามารถทำงานได้กับระบบกำหนดค่าอินพุตปัจจุบัน", "tr_TR": "Profil {0} güncel giriş konfigürasyon sistemi ile uyumlu değil.", "uk_UA": "Профіль {0} несумісний із поточною системою конфігурації вводу.", @@ -13514,7 +12110,6 @@ "pl_PL": "Profil Domyślny nie może zostać nadpisany", "pt_BR": "O perfil Padrão não pode ser substituído", "ru_RU": "Профиль по умолчанию не может быть перезаписан", - "sv_SE": "Standardprofilen kan inte skrivas över", "th_TH": "โปรไฟล์เริ่มต้นไม่สามารถเขียนทับได้", "tr_TR": "Varsayılan Profil'in üstüne yazılamaz", "uk_UA": "Стандартний профіль не можна перезаписати", @@ -13537,9 +12132,8 @@ "ko_KR": "프로필 삭제하기", "no_NO": "Sletter profil", "pl_PL": "Usuwanie Profilu", - "pt_BR": "Apagando Perfil", + "pt_BR": "Apagando perfil", "ru_RU": "Удаление профиля", - "sv_SE": "Tar bort profilen", "th_TH": "กำลังลบโปรไฟล์", "tr_TR": "Profil Siliniyor", "uk_UA": "Видалення профілю", @@ -13564,7 +12158,6 @@ "pl_PL": "Ta czynność jest nieodwracalna, czy na pewno chcesz kontynuować?", "pt_BR": "Essa ação é irreversível, tem certeza que deseja continuar?", "ru_RU": "Это действие необратимо. Вы уверены, что хотите продолжить?", - "sv_SE": "Denna åtgärd går inte att ångra. Är du säker på att du vill fortsätta?", "th_TH": "การดำเนินการนี้ไม่สามารถย้อนกลับได้ คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Bu eylem geri döndürülemez, devam etmek istediğinizden emin misiniz?", "uk_UA": "Цю дію неможливо скасувати. Ви впевнені, що бажаєте продовжити?", @@ -13589,7 +12182,6 @@ "pl_PL": "Uwaga", "pt_BR": "Alerta", "ru_RU": "Внимание", - "sv_SE": "Varning", "th_TH": "คำเตือน", "tr_TR": "Uyarı", "uk_UA": "Увага", @@ -13612,9 +12204,8 @@ "ko_KR": "다음에 부팅할 때, PPTC 재구축을 대기열에 추가하려고 합니다.\n\n{0}\n\n계속하시겠습니까?", "no_NO": "Du er i ferd med å bygge en PPTC i køen ved neste oppstart av:\n\n{0}\n\nEr du sikker på at du vil fortsette?", "pl_PL": "Masz zamiar umieścić w kolejce rekompilację PPTC przy następnym uruchomieniu:\n\n{0}\n\nCzy na pewno chcesz kontynuować?", - "pt_BR": "Você está prestes a enfileirar uma reconstrução PPTC na próxima inicialização de:\n\n{0}\n\nTem certeza de que deseja continuar?", + "pt_BR": "Você está prestes a apagar o cache PPTC para :\n\n{0}\n\nTem certeza que deseja continuar?", "ru_RU": "Вы собираетесь перестроить кэш PPTC при следующем запуске для:\n\n{0}\n\nВы уверены, что хотите продолжить?", - "sv_SE": "Du är på väg att kölägga en PPTC rebuild vid nästa uppstart av:\n\n{0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังตั้งค่าให้มีการสร้าง PPTC ใหม่ในการบูตครั้งถัดไป:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Belirtilen PPTC cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "uk_UA": "Ви збираєтеся видалити кеш PPTC для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", @@ -13637,9 +12228,8 @@ "ko_KR": "{0}에서 PPTC 캐시를 지우는 중 오류 발생 : {1}", "no_NO": "Feil under rensing av PPTC cache ved {0}: {1}", "pl_PL": "Błąd czyszczenia cache PPTC w {0}: {1}", - "pt_BR": "Erro ao limpar cache PPTC em {0}: {1}", + "pt_BR": "Erro apagando cache PPTC em {0}: {1}", "ru_RU": "Ошибка очистки кэша PPTC в {0}: {1}", - "sv_SE": "Fel vid tömning av PPTC-cache i {0}: {1}", "th_TH": "มีข้อผิดพลาดในการล้างแคช PPTC {0}: {1}", "tr_TR": "Belirtilen PPTC cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу PPTC на {0}: {1}", @@ -13647,31 +12237,6 @@ "zh_TW": "在 {0} 清除 PPTC 快取時出錯: {1}" } }, - { - "ID": "DialogPPTCNukeMessage", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?", - "no_NO": "Du er i ferd med å slette alle PPTC-data fra:\n\n{0}\n\n\nEr du sikker på at du vil fortsette?", - "pl_PL": "", - "pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?", - "ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?", - "zh_CN": "您正要清理 PPTC 数据:\n\n{0}\n\n您确实要继续吗?", - "zh_TW": "" - } - }, { "ID": "DialogShaderDeletionMessage", "Translations": { @@ -13689,7 +12254,6 @@ "pl_PL": "Zamierzasz usunąć cache Shaderów dla :\n\n{0}\n\nNa pewno chcesz kontynuować?", "pt_BR": "Você está prestes a apagar o cache de Shader para :\n\n{0}\n\nTem certeza que deseja continuar?", "ru_RU": "Вы собираетесь удалить кэш шейдеров для:\n\n{0}\n\nВы уверены, что хотите продолжить?", - "sv_SE": "Du är på väg att ta bort shader cache för :\n\n{0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบแคชแสงเงา:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Belirtilen Shader cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "uk_UA": "Ви збираєтеся видалити кеш шейдерів для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", @@ -13712,9 +12276,8 @@ "ko_KR": "{0}에서 셰이더 캐시를 삭제하는 중 오류 발생 : {1}", "no_NO": "Feil under tømming av Shader cache ved {0}: {1}", "pl_PL": "Błąd czyszczenia cache Shaderów w {0}: {1}", - "pt_BR": "Erro ao limpar o cache do Shader em {0}: {1}", + "pt_BR": "Erro apagando o cache de Shader em {0}: {1}", "ru_RU": "Ошибка очистки кэша шейдеров в {0}: {1}", - "sv_SE": "Fel vid tömning av shader cache i {0}: {1}", "th_TH": "เกิดข้อผิดพลาดในการล้าง แคชแสงเงา {0}: {1}", "tr_TR": "Belirtilen Shader cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу шейдерів на {0}: {1}", @@ -13739,7 +12302,6 @@ "pl_PL": "Ryujinx napotkał błąd", "pt_BR": "Ryujinx encontrou um erro", "ru_RU": "Ryujinx обнаружил ошибку", - "sv_SE": "Ryujinx har påträffat ett fel", "th_TH": "Ryujinx พบข้อผิดพลาด", "tr_TR": "Ryujinx bir hata ile karşılaştı", "uk_UA": "У Ryujinx сталася помилка", @@ -13764,7 +12326,6 @@ "pl_PL": "Błąd UI: Wybrana gra nie miała prawidłowego ID tytułu", "pt_BR": "Erro de interface: O jogo selecionado não tem um ID de título válido", "ru_RU": "Ошибка пользовательского интерфейса: выбранная игра не имеет действительного ID.", - "sv_SE": "Gränssnittsfel: Angivet spel saknar ett giltigt title ID", "th_TH": "ข้อผิดพลาดของ UI: เกมที่เลือกไม่มีชื่อ ID ที่ถูกต้อง", "tr_TR": "Arayüz hatası: Seçilen oyun geçerli bir title ID'ye sahip değil", "uk_UA": "Помилка інтерфейсу: вибрана гра не мала дійсного ідентифікатора назви", @@ -13789,7 +12350,6 @@ "pl_PL": "Nie znaleziono prawidłowego firmware'u systemowego w {0}.", "pt_BR": "Um firmware de sistema válido não foi encontrado em {0}.", "ru_RU": "Валидная системная прошивка не найдена в {0}.", - "sv_SE": "Ett giltigt systemfirmware hittades inte i {0}.", "th_TH": "ไม่พบเฟิร์มแวร์ของระบบที่ถูกต้อง {0}.", "tr_TR": "{0} da geçerli bir sistem firmware'i bulunamadı.", "uk_UA": "Дійсна прошивка системи не знайдена в {0}.", @@ -13812,9 +12372,8 @@ "ko_KR": "펌웨어 {0} 설치", "no_NO": "Installer fastvare {0}", "pl_PL": "Zainstaluj Firmware {0}", - "pt_BR": "Instalar Firmware {0}", + "pt_BR": "Instalar firmware {0}", "ru_RU": "Установить прошивку {0}", - "sv_SE": "Installera firmware {0}", "th_TH": "ติดตั้งเฟิร์มแวร์ {0}", "tr_TR": "Firmware {0} Yükle", "uk_UA": "Встановити прошивку {0}", @@ -13839,12 +12398,11 @@ "pl_PL": "Wersja systemu {0} zostanie zainstalowana.", "pt_BR": "A versão do sistema {0} será instalada.", "ru_RU": "Будет установлена версия прошивки {0}.", - "sv_SE": "Systemversion {0} kommer att installeras.", "th_TH": "ระบบเวอร์ชั่น {0} ได้รับการติดตั้งเร็วๆ นี้", "tr_TR": "Sistem sürümü {0} yüklenecek.", "uk_UA": "Буде встановлено версію системи {0}.", "zh_CN": "即将安装系统固件版本 {0} 。", - "zh_TW": "即將安裝系統韌體版本 {0}。" + "zh_TW": "將安裝系統版本 {0}。" } }, { @@ -13857,19 +12415,18 @@ "es_ES": "\n\nEsto reemplazará la versión de sistema actual, {0}.", "fr_FR": "\n\nCela remplacera la version actuelle du système {0}.", "he_IL": "\n\nזה יחליף את גרסת המערכת הנוכחית {0}.", - "it_IT": "\n\nQuesta sostituirà l'attuale versione del sistema ({0}).", + "it_IT": "\n\nQuesta sostituirà l'attuale versione di sistema {0}.", "ja_JP": "\n\n現在のシステムバージョン {0} を置き換えます.", "ko_KR": "\n\n현재 시스템 버전 {0}을(를) 대체합니다.", "no_NO": "\n\nDette erstatter den gjeldende systemversjonen {0}.", "pl_PL": "\n\nZastąpi to obecną wersję systemu {0}.", "pt_BR": "\n\nIsso substituirá a versão do sistema atual {0}.", "ru_RU": "\n\nЭто заменит текущую версию прошивки {0}.", - "sv_SE": "\n\nDetta kommer att ersätta aktuella systemversionen {0}.", "th_TH": "\n\nสิ่งนี้จะแทนที่เวอร์ชั่นของระบบเวอร์ชั่นปัจจุบัน {0}.", "tr_TR": "\n\nBu şimdiki sistem sürümünün yerini alacak {0}.", "uk_UA": "\n\nЦе замінить поточну версію системи {0}.", "zh_CN": "\n\n替换当前系统固件版本 {0} 。", - "zh_TW": "\n\n這將取代目前的系統韌體版本 {0}。" + "zh_TW": "\n\n這將取代目前的系統版本 {0}。" } }, { @@ -13889,7 +12446,6 @@ "pl_PL": "\n\nCzy chcesz kontynuować?", "pt_BR": "\n\nDeseja continuar?", "ru_RU": "\n\nПродолжить?", - "sv_SE": "\n\nVill du fortsätta?", "th_TH": "\n\nคุณต้องการดำเนินการต่อหรือไม่?", "tr_TR": "\n\nDevam etmek istiyor musunuz?", "uk_UA": "\n\nВи хочете продовжити?", @@ -13914,7 +12470,6 @@ "pl_PL": "Instalowanie firmware'u...", "pt_BR": "Instalando firmware...", "ru_RU": "Установка прошивки...", - "sv_SE": "Installerar firmware...", "th_TH": "กำลังติดตั้งเฟิร์มแวร์...", "tr_TR": "Firmware yükleniyor...", "uk_UA": "Встановлення прошивки...", @@ -13939,12 +12494,11 @@ "pl_PL": "Wersja systemu {0} została pomyślnie zainstalowana.", "pt_BR": "Versão do sistema {0} instalada com sucesso.", "ru_RU": "Прошивка версии {0} успешно установлена.", - "sv_SE": "Systemversion {0} har installerats.", "th_TH": "ระบบเวอร์ชั่น {0} ติดตั้งเรียบร้อยแล้ว", "tr_TR": "Sistem sürümü {0} başarıyla yüklendi.", "uk_UA": "Версію системи {0} успішно встановлено.", "zh_CN": "成功安装系统固件版本 {0} 。", - "zh_TW": "成功安裝系統韌體版本 {0}。" + "zh_TW": "成功安裝系統版本 {0}。" } }, { @@ -13957,19 +12511,18 @@ "es_ES": "Se halló un archivo Keys inválido en {0}", "fr_FR": "Un fichier de clés invalide a été trouvé dans {0}", "he_IL": "", - "it_IT": "È stato trovato un file di chiavi non valido in {0}", + "it_IT": "E' stato trovato un file di chiavi invalido ' {0}", "ja_JP": "", "ko_KR": "{0}에서 잘못된 키 파일이 발견", "no_NO": "En ugyldig Keys-fil ble funnet i {0}.", "pl_PL": "", - "pt_BR": "Um arquivo Chaves inválido foi encontrado em {0}", - "ru_RU": "В {0} были найдены некорректные ключи", - "sv_SE": "En ogiltig nyckelfil hittades i {0}", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Виявлено неправильний файл ключів у теці {0}", - "zh_CN": "在 {0} 发现了一个无效的密匙文件", - "zh_TW": "找到無效的金鑰檔案 {0}" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -13982,19 +12535,18 @@ "es_ES": "Instalar Keys", "fr_FR": "Installer des clés", "he_IL": "", - "it_IT": "Installa chiavi", + "it_IT": "Installa Chavi", "ja_JP": "", "ko_KR": "설치 키", "no_NO": "Installere nøkler", "pl_PL": "", - "pt_BR": "Instalar Chaves", - "ru_RU": "Установить ключи", - "sv_SE": "Installera nycklar", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Встановлення Ключів", - "zh_CN": "安装密匙", - "zh_TW": "安裝金鑰" + "zh_CN": "", + "zh_TW": "" } }, { @@ -14007,19 +12559,18 @@ "es_ES": "Un nuevo archivo Keys será instalado.", "fr_FR": "Nouveau fichier de clés sera installé.", "he_IL": "", - "it_IT": "Un nuovo file di chiavi sarà installato.", + "it_IT": "Un nuovo file di Chiavi sarà intallato.", "ja_JP": "", "ko_KR": "새로운 키 파일이 설치됩니다.", "no_NO": "Ny Keys-fil vil bli installert.", "pl_PL": "", - "pt_BR": "O novo arquivo Chaves será instalado", - "ru_RU": "Будут установлены новые ключи.", - "sv_SE": "Ny nyckelfil kommer att installeras.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Новий файл Ключів буде встановлено", - "zh_CN": "将会安装新密匙文件", - "zh_TW": "將會安裝新增的金鑰檔案。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -14032,19 +12583,18 @@ "es_ES": "\n\nEsto puede reemplazar algunas de las Keys actualmente instaladas.", "fr_FR": "\n\nCela pourrait remplacer les clés qui sont installés.", "he_IL": "", - "it_IT": "\n\nAlcune delle chiavi già installate potrebbero essere sovrascritte.", + "it_IT": "\n\nQuesto potrebbe sovrascrivere alcune delle Chiavi già installate.", "ja_JP": "", "ko_KR": "\n\n이로 인해 현재 설치된 키 중 일부가 대체될 수 있습니다.", "no_NO": "\n\nDette kan erstatte noen av de nåværende installerte nøklene.", "pl_PL": "", - "pt_BR": "\n\nIsso pode substituir algumas das chaves instaladas atualmente.", - "ru_RU": "\n\nЭто действие может перезаписать установленные ключи.", - "sv_SE": "\n\nDetta kan ersätta några av de redan installerade nycklarna.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "\n\nЦе замінить собою поточні файли Ключів.", - "zh_CN": "\n\n这也许会替换掉一些当前已安装的密匙", - "zh_TW": "\n\n這將取代部分已安裝的金鑰。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -14062,14 +12612,13 @@ "ko_KR": "\n\n계속하시겠습니까?", "no_NO": "\n\nVil du fortsette?", "pl_PL": "", - "pt_BR": "\n\nVocê quer continuar?", - "ru_RU": "\n\nХотите продолжить?", - "sv_SE": "\n\nVill du fortsätta?", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "\n\nВи хочете продовжити?", - "zh_CN": "\n\n你想要继续吗?", - "zh_TW": "\n\n是否繼續?" + "zh_CN": "", + "zh_TW": "" } }, { @@ -14082,19 +12631,18 @@ "es_ES": "Instalando Keys...", "fr_FR": "Installation des clés...", "he_IL": "", - "it_IT": "Installazione delle chiavi...", + "it_IT": "Installando le chiavi...", "ja_JP": "", "ko_KR": "키 설치 중...", "no_NO": "Installere nøkler...", "pl_PL": "", - "pt_BR": "Instalando Chaves...", - "ru_RU": "Установка ключей...", - "sv_SE": "Installerar nycklar...", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Встановлення Ключів...", - "zh_CN": "安装密匙中。。。", - "zh_TW": "正在安裝金鑰..." + "zh_CN": "", + "zh_TW": "" } }, { @@ -14112,14 +12660,13 @@ "ko_KR": "새로운 키 파일이 성공적으로 설치되었습니다.", "no_NO": "Ny Keys -fil installert.", "pl_PL": "", - "pt_BR": "Novo arquivo de chaves instalado com sucesso.", - "ru_RU": "Новые ключи были успешно установлены.", - "sv_SE": "Ny nyckelfil installerades.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Нові ключі встановлено.", - "zh_CN": "已成功安装新密匙文件", - "zh_TW": "成功安裝新增的金鑰檔案。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -14132,14 +12679,13 @@ "es_ES": "Si eliminas el perfil seleccionado no quedará ningún otro perfil", "fr_FR": "Il n'y aurait aucun autre profil à ouvrir si le profil sélectionné est supprimé", "he_IL": "לא יהיו פרופילים אחרים שייפתחו אם הפרופיל שנבחר יימחק", - "it_IT": "Non ci sarebbero altri profili da aprire se il profilo selezionato venisse cancellato", + "it_IT": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato", "ja_JP": "選択されたプロファイルを削除すると,プロファイルがひとつも存在しなくなります", "ko_KR": "선택한 프로필을 삭제하면 다른 프로필을 열 수 없음", "no_NO": "Det vil ikke være noen profiler å åpnes hvis valgt profil blir slettet", "pl_PL": "Nie będzie innych profili do otwarcia, jeśli wybrany profil zostanie usunięty", "pt_BR": "Não haveria nenhum perfil selecionado se o perfil atual fosse deletado", "ru_RU": "Если выбранный профиль будет удален, другие профили не будут открываться.", - "sv_SE": "Det skulle inte finnas några andra profiler att öppnas om angiven profil tas bort", "th_TH": "จะไม่มีโปรไฟล์อื่นให้เปิดหากโปรไฟล์ที่เลือกถูกลบ", "tr_TR": "Seçilen profil silinirse kullanılabilen başka profil kalmayacak", "uk_UA": "Якщо вибраний профіль буде видалено, інші профілі не відкриватимуться", @@ -14164,7 +12710,6 @@ "pl_PL": "Czy chcesz usunąć wybrany profil", "pt_BR": "Deseja deletar o perfil selecionado", "ru_RU": "Удалить выбранный профиль?", - "sv_SE": "Vill du ta bort den valda profilen", "th_TH": "คุณต้องการลบโปรไฟล์ที่เลือกหรือไม่?", "tr_TR": "Seçilen profili silmek istiyor musunuz", "uk_UA": "Ви хочете видалити вибраний профіль", @@ -14182,14 +12727,13 @@ "es_ES": "Advertencia - Cambios sin guardar", "fr_FR": "Avertissement - Modifications non enregistrées", "he_IL": "אזהרה - שינויים לא שמורים", - "it_IT": "Attenzione - Modifiche non salvate", + "it_IT": "Attenzione - Modifiche Non Salvate", "ja_JP": "警告 - 保存されていない変更", "ko_KR": "경고 - 저장되지 않은 변경 사항", "no_NO": "Advarsel - Ulagrede endringer", "pl_PL": "Uwaga - Niezapisane zmiany", "pt_BR": "Alerta - Alterações não salvas", "ru_RU": "Внимание - Несохраненные изменения", - "sv_SE": "Varning - Ej sparade ändringar", "th_TH": "คำเตือน - มีการเปลี่ยนแปลงที่ไม่ได้บันทึก", "tr_TR": "Uyarı - Kaydedilmemiş Değişiklikler", "uk_UA": "Увага — Незбережені зміни", @@ -14213,8 +12757,7 @@ "no_NO": "Du har gjort endringer i denne brukerprofilen som ikke er lagret.", "pl_PL": "Wprowadziłeś zmiany dla tego profilu użytkownika, które nie zostały zapisane.", "pt_BR": "Você fez alterações para este perfil de usuário que não foram salvas.", - "ru_RU": "В эту учётную запись внесены изменения, которые не были сохранены.", - "sv_SE": "Du har gjort ändringar i denna användarprofil som inte har sparats.", + "ru_RU": "В эту учетную запись внесены изменения, которые не были сохранены.", "th_TH": "คุณได้ทำการเปลี่ยนแปลงโปรไฟล์ผู้ใช้นี้โดยไม่ได้รับการบันทึก", "tr_TR": "Kullanıcı profilinizde kaydedilmemiş değişiklikler var.", "uk_UA": "Ви зробили зміни у цьому профілю користувача які не було збережено.", @@ -14239,7 +12782,6 @@ "pl_PL": "Czy chcesz odrzucić zmiany?", "pt_BR": "Deseja descartar as alterações?", "ru_RU": "Отменить изменения?", - "sv_SE": "Vill du förkasta dina ändringar?", "th_TH": "คุณต้องการทิ้งการเปลี่ยนแปลงของคุณหรือไม่?", "tr_TR": "Yaptığınız değişiklikleri iptal etmek istediğinize emin misiniz?", "uk_UA": "Бажаєте скасувати зміни?", @@ -14264,7 +12806,6 @@ "pl_PL": "Aktualne ustawienia kontrolera zostały zaktualizowane.", "pt_BR": "As configurações de controle atuais foram atualizadas.", "ru_RU": "Текущие настройки управления обновлены.", - "sv_SE": "Aktuella kontrollerinställningar har uppdaterats.", "th_TH": "การตั้งค่าคอนโทรลเลอร์ปัจจุบันได้รับการอัปเดตแล้ว", "tr_TR": "Geçerli kumanda seçenekleri güncellendi.", "uk_UA": "Поточні налаштування контролера оновлено.", @@ -14289,7 +12830,6 @@ "pl_PL": "Czy chcesz zapisać?", "pt_BR": "Deseja salvar?", "ru_RU": "Сохранить?", - "sv_SE": "Vill du spara?", "th_TH": "คุณต้องการบันทึกหรือไม่?", "tr_TR": "Kaydetmek istiyor musunuz?", "uk_UA": "Ви хочете зберегти?", @@ -14307,14 +12847,13 @@ "es_ES": "{0}. Archivo con error: {1}", "fr_FR": "{0}. Fichier erroné : {1}", "he_IL": "{0}. קובץ שגוי: {1}", - "it_IT": "{0}. Errore file: {1}", + "it_IT": "{0}. Errore File: {1}", "ja_JP": "{0}. エラー発生ファイル: {1}", "ko_KR": "{0}. 오류 파일 : {1}", "no_NO": "{0}. Feilet fil: {1}", "pl_PL": "{0}. Błędny plik: {1}", "pt_BR": "{0}. Arquivo com erro: {1}", "ru_RU": "{0}. Файл с ошибкой: {1}", - "sv_SE": "{0}. Fel i filen: {1}", "th_TH": "{0} ไฟล์เกิดข้อผิดพลาด: {1}", "tr_TR": "{0}. Hatalı Dosya: {1}", "uk_UA": "{0}. Файл з помилкою: {1}", @@ -14339,7 +12878,6 @@ "pl_PL": "Modyfikacja już istnieje", "pt_BR": "O mod já existe", "ru_RU": "Мод уже существует", - "sv_SE": "Modd finns redan", "th_TH": "มีม็อดนี้อยู่แล้ว", "tr_TR": "Mod zaten var", "uk_UA": "Модифікація вже існує", @@ -14364,10 +12902,9 @@ "pl_PL": "Podany katalog nie zawiera modyfikacji!", "pt_BR": "O diretório especificado não contém um mod!", "ru_RU": "Выбранная папка не содержит модов", - "sv_SE": "Den angivna katalogen innehåller inte en modd!", "th_TH": "ไดเร็กทอรีที่ระบุไม่มี ม็อดอยู่!", "tr_TR": "", - "uk_UA": "Вказана тека не містить модифікації!", + "uk_UA": "Вказаний каталог не містить модифікації!", "zh_CN": "指定的目录找不到 MOD 文件!", "zh_TW": "指定資料夾不包含模組!" } @@ -14389,10 +12926,9 @@ "pl_PL": "Nie udało się usunąć: Nie można odnaleźć katalogu nadrzędnego dla modyfikacji \"{0}\"!", "pt_BR": "Falha ao excluir: Não foi possível encontrar o diretório pai do mod \"{0}\"!", "ru_RU": "Невозможно удалить: не удалось найти папку мода \"{0}\"", - "sv_SE": "Misslyckades med att ta bort: Kunde inte hitta föräldrakatalogen för modden \"{0}\"!", "th_TH": "ไม่สามารถลบ: ไม่พบไดเร็กทอรีหลักสำหรับ ม็อด \"{0}\"!", "tr_TR": "Silme Başarısız: \"{0}\" Modu için üst dizin bulunamadı! ", - "uk_UA": "Не видалено: Не знайдено батьківський каталог (теку) для модифікації \"{0}\"!", + "uk_UA": "Не видалено: Не знайдено батьківський каталог для модифікації \"{0}\"!", "zh_CN": "删除失败:找不到 MOD 的父目录“{0}”!", "zh_TW": "刪除失敗: 無法找到模組「{0}」的父資料夾!" } @@ -14414,10 +12950,9 @@ "pl_PL": "Określony plik nie zawiera DLC dla wybranego tytułu!", "pt_BR": "O arquivo especificado não contém DLCs para o título selecionado!", "ru_RU": "Указанный файл не содержит DLC для выбранной игры", - "sv_SE": "Den angivna filen innehåller inte en DLC för angivet spel!", "th_TH": "ไฟล์ที่ระบุไม่มี DLC สำหรับชื่อที่เลือก!", "tr_TR": "Belirtilen dosya seçilen oyun için DLC içermiyor!", - "uk_UA": "Зазначений файл не містить DLC для обраної гри!", + "uk_UA": "Зазначений файл не містить DLC для вибраного заголовку!", "zh_CN": "选择的文件不是当前游戏的 DLC!", "zh_TW": "指定檔案不包含所選遊戲的 DLC!" } @@ -14439,7 +12974,6 @@ "pl_PL": "Masz włączone rejestrowanie śledzenia, które jest przeznaczone tylko dla programistów.", "pt_BR": "Os logs de depuração estão ativos, esse recurso é feito para ser usado apenas por desenvolvedores.", "ru_RU": "У вас включено ведение журнала отладки, предназначенное только для разработчиков.", - "sv_SE": "Du har spårloggning aktiverat som endast är designat att användas av utvecklare.", "th_TH": "คุณได้เปิดใช้งานการบันทึกการติดตาม ซึ่งออกแบบมาเพื่อให้นักพัฒนาใช้เท่านั้น", "tr_TR": "Sadece geliştiriler için dizayn edilen Trace Loglama seçeneği etkin.", "uk_UA": "Ви увімкнули журнал налагодження, призначений лише для розробників.", @@ -14463,8 +12997,7 @@ "no_NO": "For optimal ytelse er det anbefalt å deaktivere spor-logging. Ønsker du å deaktivere spor-logging nå?", "pl_PL": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie rejestrowania śledzenia. Czy chcesz teraz wyłączyć rejestrowanie śledzenia?", "pt_BR": "Para melhor performance, é recomendável desabilitar os logs de depuração. Gostaria de desabilitar os logs de depuração agora?", - "ru_RU": "Для оптимальной производительности рекомендуется отключить ведение журнала отладки. Хотите отключить?", - "sv_SE": "Det rekommenderas att inaktivera spårloggning för optimal prestanda. Vill du inaktivera spårloggning nu?", + "ru_RU": "Для оптимальной производительности рекомендуется отключить ведение журнала отладки. Хотите отключить ведение журнала отладки?", "th_TH": "เพื่อประสิทธิภาพสูงสุด ขอแนะนำให้ปิดใช้งานการบันทึกการติดตาม คุณต้องการปิดใช้การบันทึกการติดตามตอนนี้หรือไม่?", "tr_TR": "En iyi performans için trace loglama'nın devre dışı bırakılması tavsiye edilir. Trace loglama seçeneğini şimdi devre dışı bırakmak ister misiniz?", "uk_UA": "Для оптимальної продуктивності рекомендується вимкнути ведення журналу налагодження. Ви хочете вимкнути ведення журналу налагодження зараз?", @@ -14489,7 +13022,6 @@ "pl_PL": "Masz włączone zrzucanie shaderów, które jest przeznaczone tylko dla programistów.", "pt_BR": "O despejo de shaders está ativo, esse recurso é feito para ser usado apenas por desenvolvedores.", "ru_RU": "У вас включен дамп шейдеров, который предназначен только для разработчиков.", - "sv_SE": "Du har aktiverat shader dumping som endast är designat att användas av utvecklare.", "th_TH": "คุณได้เปิดใช้งาน การดัมพ์เชเดอร์ ซึ่งออกแบบมาเพื่อให้นักพัฒนาใช้งานเท่านั้น", "tr_TR": "Sadece geliştiriler için dizayn edilen Shader Dumping seçeneği etkin.", "uk_UA": "Ви увімкнули скидання шейдерів, призначений лише для розробників.", @@ -14514,7 +13046,6 @@ "pl_PL": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie zrzucania shaderów. Czy chcesz teraz wyłączyć zrzucanie shaderów?", "pt_BR": "Para melhor performance, é recomendável desabilitar o despejo de shaders. Gostaria de desabilitar o despejo de shaders agora?", "ru_RU": "Для оптимальной производительности рекомендуется отключить дамп шейдеров. Хотите отключить дамп шейдеров?", - "sv_SE": "Det rekommenderas att inaktivera shader dumping för optimal prestanda. Vill du inaktivera shader dumping nu?", "th_TH": "เพื่อประสิทธิภาพสูงสุด ขอแนะนำให้ปิดใช้การดัมพ์เชเดอร์ คุณต้องการปิดการใช้งานการ ดัมพ์เชเดอร์ ตอนนี้หรือไม่?", "tr_TR": "En iyi performans için Shader Dumping'in devre dışı bırakılması tavsiye edilir. Shader Dumping seçeneğini şimdi devre dışı bırakmak ister misiniz?", "uk_UA": "Для оптимальної продуктивності рекомендується вимкнути скидання шейдерів. Ви хочете вимкнути скидання шейдерів зараз?", @@ -14539,7 +13070,6 @@ "pl_PL": "Gra została już załadowana", "pt_BR": "Um jogo já foi carregado", "ru_RU": "Игра уже загружена", - "sv_SE": "Ett spel har redan lästs in", "th_TH": "ทำการโหลดเกมเรียบร้อยแล้ว", "tr_TR": "Bir oyun zaten yüklendi", "uk_UA": "Гру вже завантажено", @@ -14564,7 +13094,6 @@ "pl_PL": "Zatrzymaj emulację lub zamknij emulator przed uruchomieniem innej gry.", "pt_BR": "Por favor, pare a emulação ou feche o emulador antes de abrir outro jogo.", "ru_RU": "Пожалуйста, остановите эмуляцию или закройте эмулятор перед запуском другой игры.", - "sv_SE": "Stoppa emuleringen eller stäng emulatorn innan du startar ett annat spel.", "th_TH": "โปรดหยุดการจำลอง หรือปิดโปรแกรมจำลองก่อนที่จะเปิดเกมอื่น", "tr_TR": "Lütfen yeni bir oyun açmadan önce emülasyonu durdurun veya emülatörü kapatın.", "uk_UA": "Зупиніть емуляцію або закрийте емулятор перед запуском іншої гри.", @@ -14589,7 +13118,6 @@ "pl_PL": "Określony plik nie zawiera aktualizacji dla wybranego tytułu!", "pt_BR": "O arquivo especificado não contém atualizações para o título selecionado!", "ru_RU": "Указанный файл не содержит обновлений для выбранного приложения", - "sv_SE": "Angiven fil innehåller inte en uppdatering för angivet spel!", "th_TH": "ไฟล์ที่ระบุไม่มีการอัพเดตสำหรับชื่อเรื่องที่เลือก!", "tr_TR": "Belirtilen dosya seçilen oyun için güncelleme içermiyor!", "uk_UA": "Зазначений файл не містить оновлення для вибраного заголовка!", @@ -14612,9 +13140,8 @@ "ko_KR": "경고 - 후단부 스레딩", "no_NO": "Advarsel - Backend Tråd", "pl_PL": "Ostrzeżenie — Wątki Backend", - "pt_BR": "Alerta - Enfileiramento do Renderizador Gráfico", + "pt_BR": "Alerta - Threading da API gráfica", "ru_RU": "Предупреждение: многопоточность в бэкенде", - "sv_SE": "Varning - Backend Threading", "th_TH": "คำเตือน - การทำเธรดแบ็กเอนด์", "tr_TR": "Uyarı - Backend Threading", "uk_UA": "Попередження - потокове керування сервером", @@ -14638,8 +13165,7 @@ "no_NO": "Ryujinx må startes på nytt etter at dette alternativet er endret slik at det tas i bruk helt. Avhengig av plattformen din, må du kanskje manuelt skru av driveren's egen flertråder når du bruker Ryujinx's.", "pl_PL": "Ryujinx musi zostać ponownie uruchomiony po zmianie tej opcji, aby działał w pełni. W zależności od platformy może być konieczne ręczne wyłączenie sterownika wielowątkowości podczas korzystania z Ryujinx.", "pt_BR": "Ryujinx precisa ser reiniciado após mudar essa opção para que ela tenha efeito. Dependendo da sua plataforma, pode ser preciso desabilitar o multithreading do driver de vídeo quando usar o Ryujinx.", - "ru_RU": "Для применения этой настройки необходимо перезапустить Ryujinx. В зависимости от используемой вами операционной системы, вам может потребоваться вручную отключить многопоточность драйвера при использовании Ryujinx.", - "sv_SE": "Ryujinx måste startas om efter att denna inställning ändras för att verkställa den. Beroende på din plattform så kanske du måste manuellt inaktivera drivrutinens egna multithreading när Ryujinx används.", + "ru_RU": "Для применения этой настройки необходимо перезапустить Ryujinx. В зависимости от используемой вами операционной системы вам может потребоваться вручную отключить многопоточность драйвера при использовании Ryujinx.", "th_TH": "Ryujinx ต้องรีสตาร์ทหลังจากเปลี่ยนตัวเลือกนี้จึงจะใช้งานได้อย่างสมบูรณ์ คุณอาจต้องปิดการใช้งาน มัลติเธรด ของไดรเวอร์ของคุณด้วยตนเองเมื่อใช้ Ryujinx ทั้งนี้ขึ้นอยู่กับแพลตฟอร์มของคุณ", "tr_TR": "Bu seçeneğin tamamen uygulanması için Ryujinx'in kapatıp açılması gerekir. Kullandığınız işletim sistemine bağlı olarak, Ryujinx'in multithreading'ini kullanırken driver'ınızın multithreading seçeneğini kapatmanız gerekebilir.", "uk_UA": "Ryujinx потрібно перезапустити після зміни цього параметра, щоб він застосовувався повністю. Залежно від вашої платформи вам може знадобитися вручну вимкнути власну багатопотоковість драйвера під час використання Ryujinx.", @@ -14664,7 +13190,6 @@ "pl_PL": "Zamierzasz usunąć modyfikacje: {0}\n\nCzy na pewno chcesz kontynuować?", "pt_BR": "Você está prestes a excluir o mod: {0}\n\nTem certeza de que deseja continuar?", "ru_RU": "Вы сейчас удалите мод: {0}\n\nВы уверены, что хотите продолжить?", - "sv_SE": "Du är på väg att ta bort modden: {0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบ ม็อด: {0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "tr_TR": "", "uk_UA": "Ви збираєтесь видалити модифікацію: {0}\n\nВи дійсно бажаєте продовжити?", @@ -14689,7 +13214,6 @@ "pl_PL": "Zamierzasz usunąć wszystkie modyfikacje dla wybranego tytułu: {0}\n\nCzy na pewno chcesz kontynuować?", "pt_BR": "Você está prestes a excluir todos os mods para este jogo.\n\nTem certeza de que deseja continuar?", "ru_RU": "Вы сейчас удалите все выбранные моды для этой игры.\n\nВы уверены, что хотите продолжить?", - "sv_SE": "Du är på väg att ta bort alla moddar för detta spel.\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบม็อดทั้งหมดสำหรับชื่อนี้\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "tr_TR": "", "uk_UA": "Ви збираєтесь видалити всі модифікації для цього Додатка.\n\nВи дійсно бажаєте продовжити?", @@ -14713,8 +13237,7 @@ "no_NO": "Funksjoner", "pl_PL": "Funkcje", "pt_BR": "Recursos", - "ru_RU": "Функции", - "sv_SE": "Funktioner", + "ru_RU": "Функции & Улучшения", "th_TH": "คุณสมบัติ", "tr_TR": "Özellikler", "uk_UA": "Особливості", @@ -14737,9 +13260,8 @@ "ko_KR": "그래픽 후단부 다중 스레딩 :", "no_NO": "Grafikk Backend Fleroppgavekjøring", "pl_PL": "Wielowątkowość Backendu Graficznego:", - "pt_BR": "Multi Enfileiramento do Renderizador Gráfico:", + "pt_BR": "Multithreading da API gráfica:", "ru_RU": "Многопоточность графического бэкенда:", - "sv_SE": "Multithreading för grafikbakände:", "th_TH": "มัลติเธรด กราฟิกเบื้องหลัง:", "tr_TR": "Grafik Backend Multithreading:", "uk_UA": "Багатопотоковість графічного сервера:", @@ -14764,7 +13286,6 @@ "pl_PL": "", "pt_BR": "Automático", "ru_RU": "Автоматически", - "sv_SE": "Automatiskt", "th_TH": "อัตโนมัติ", "tr_TR": "Otomatik", "uk_UA": "Авто", @@ -14789,7 +13310,6 @@ "pl_PL": "Wyłączone", "pt_BR": "Desligado", "ru_RU": "Выключено", - "sv_SE": "Av", "th_TH": "ปิดการใช้งาน", "tr_TR": "Kapalı", "uk_UA": "Вимкнути", @@ -14814,7 +13334,6 @@ "pl_PL": "Włączone", "pt_BR": "Ligado", "ru_RU": "Включено", - "sv_SE": "På", "th_TH": "เปิดใช้งาน", "tr_TR": "Açık", "uk_UA": "Увімкнути", @@ -14839,7 +13358,6 @@ "pl_PL": "Tak", "pt_BR": "Sim", "ru_RU": "Да", - "sv_SE": "Ja", "th_TH": "ใช่", "tr_TR": "Evet", "uk_UA": "Так", @@ -14864,7 +13382,6 @@ "pl_PL": "Nie", "pt_BR": "Não", "ru_RU": "Нет", - "sv_SE": "Nej", "th_TH": "ไม่ใช่", "tr_TR": "Hayır", "uk_UA": "Ні", @@ -14889,7 +13406,6 @@ "pl_PL": "Nazwa pliku zawiera nieprawidłowe znaki. Proszę spróbuj ponownie.", "pt_BR": "O nome do arquivo contém caracteres inválidos. Por favor, tente novamente.", "ru_RU": "Имя файла содержит недопустимые символы. Пожалуйста, попробуйте еще раз.", - "sv_SE": "Filnamnet innehåller ogiltiga tecken. Försök igen.", "th_TH": "ชื่อไฟล์ประกอบด้วยอักขระที่ไม่ถูกต้อง กรุณาลองอีกครั้ง", "tr_TR": "Dosya adı geçersiz karakter içeriyor. Lütfen tekrar deneyin.", "uk_UA": "Ім'я файлу містить неприпустимі символи. Будь ласка, спробуйте ще раз.", @@ -14914,7 +13430,6 @@ "pl_PL": "Pauza", "pt_BR": "Pausar", "ru_RU": "Пауза эмуляции", - "sv_SE": "Paus", "th_TH": "หยุดชั่วคราว", "tr_TR": "Durdur", "uk_UA": "Пауза", @@ -14939,7 +13454,6 @@ "pl_PL": "Wznów", "pt_BR": "Resumir", "ru_RU": "Продолжить", - "sv_SE": "Återuppta", "th_TH": "ดำเนินการต่อ", "tr_TR": "Devam Et", "uk_UA": "Продовжити", @@ -14963,8 +13477,7 @@ "no_NO": "Klikk for å åpne Ryujinx nettsiden i din standardnettleser.", "pl_PL": "Kliknij, aby otworzyć stronę Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir o site do Ryujinx no seu navegador padrão.", - "ru_RU": "Нажмите, чтобы открыть веб-сайт Ryujinx в браузере", - "sv_SE": "Klicka för att öppna Ryujinx webbsida i din webbläsare.", + "ru_RU": "Нажмите, чтобы открыть веб-сайт Ryujinx", "th_TH": "คลิกเพื่อเปิดเว็บไซต์ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Ryujinx'in websitesini varsayılan tarayıcınızda açmak için tıklayın.", "uk_UA": "Натисніть, щоб відкрити сайт Ryujinx у браузері за замовчування.", @@ -14989,7 +13502,6 @@ "pl_PL": "Ryujinx nie jest w żaden sposób powiązany z Nintendo™,\nani z żadnym z jej partnerów.", "pt_BR": "Ryujinx não é afiliado com a Nintendo™,\nou qualquer um de seus parceiros, de nenhum modo.", "ru_RU": "Ryujinx никоим образом не связан ни с Nintendo™, ни с кем-либо из ее партнеров.", - "sv_SE": "Ryujinx har ingen koppling till Nintendo™,\neller någon av dess samarbetspartners.", "th_TH": "ทางผู้พัฒนาโปรแกรม Ryujinx ไม่มีส่วนเกี่ยวข้องกับทางบริษัท Nintendo™\nหรือพันธมิตรใดๆ ทั้งสิ้น!", "tr_TR": "Ryujinx, Nintendo™ veya ortaklarıyla herhangi bir şekilde bağlantılı değildir.", "uk_UA": "Ryujinx жодним чином не пов’язаний з Nintendo™,\nчи будь-яким із їхніх партнерів.", @@ -15014,7 +13526,6 @@ "pl_PL": "AmiiboAPI (www.amiiboapi.com) jest używane\nw naszej emulacji Amiibo.", "pt_BR": "AmiiboAPI (www.amiiboapi.com) é usado\nem nossa emulação de Amiibo.", "ru_RU": "Amiibo API (www.amiiboapi.com) используется для эмуляции Amiibo.", - "sv_SE": "AmiiboAPI (www.amiiboapi.com) används\ni vår Amiibo-emulation.", "th_TH": "AmiiboAPI (www.amiiboapi.com) ถูกใช้\nในการจำลอง อะมิโบ ของเรา", "tr_TR": "Amiibo emülasyonumuzda \nAmiiboAPI (www.amiiboapi.com) kullanılmaktadır.", "uk_UA": "AmiiboAPI (www.amiiboapi.com) використовується в нашій емуляції Amiibo.", @@ -15039,10 +13550,9 @@ "pl_PL": "Kliknij, aby otworzyć stronę GitHub Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir a página do GitHub do Ryujinx no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть страницу Ryujinx на GitHub", - "sv_SE": "Klicka för att öppna Ryujinx GitHub-sida i din webbläsare.", "th_TH": "คลิกเพื่อเปิดหน้า Github ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Ryujinx'in GitHub sayfasını varsayılan tarayıcınızda açmak için tıklayın.", - "uk_UA": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері.", + "uk_UA": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері за замовчуванням.", "zh_CN": "在浏览器中打开 Ryujinx 的 GitHub 代码库。", "zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 GitHub 網頁。" } @@ -15064,10 +13574,9 @@ "pl_PL": "Kliknij, aby otworzyć zaproszenie na serwer Discord Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir um convite ao servidor do Discord do Ryujinx no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть приглашение на сервер Ryujinx в Discord", - "sv_SE": "Klicka för att öppna en inbjudan till Ryujinx Discord-server i din webbläsare.", "th_TH": "คลิกเพื่อเปิดคำเชิญเข้าสู่เซิร์ฟเวอร์ Discord ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Varsayılan tarayıcınızda Ryujinx'in Discord'una bir davet açmak için tıklayın.", - "uk_UA": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері.", + "uk_UA": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері за замовчуванням.", "zh_CN": "在浏览器中打开 Ryujinx 的 Discord 邀请链接。", "zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 Discord 邀請連結。" } @@ -15089,7 +13598,6 @@ "pl_PL": "O Aplikacji:", "pt_BR": "Sobre:", "ru_RU": "О программе:", - "sv_SE": "Om:", "th_TH": "เกี่ยวกับ:", "tr_TR": "Hakkında:", "uk_UA": "Про програму:", @@ -15107,19 +13615,18 @@ "es_ES": "", "fr_FR": "Ryujinx est un émulateur pour la Nintendo Switch™.\nObtenez le dernières nouvelles sur le Discord.\nLes développeurs qui veulent contribuer peuvent en savoir plus sur notre GitHub ou Discord.", "he_IL": "", - "it_IT": "Ryujinx è un emulatore della console Nintendo Switch™.\nRimani aggiornato sulle ultime novità nel nostro server Discord.\nGli sviluppatori interessati a contribuire possono trovare maggiori informazioni su Discord o sulla nostra pagina GitHub.", + "it_IT": "", "ja_JP": "", "ko_KR": "Ryujinx는 Nintendo Switch™용 에뮬레이터입니다.\n모든 최신 소식을 Discord에서 확인하세요.\n기여에 관심이 있는 개발자는 GitHub 또는 Discord에서 자세한 내용을 확인할 수 있습니다.", "no_NO": "Ryujinx er en emulator for Nintendo SwitchTM.\nVennligst støtt oss på Patreon.\nFå alle de siste nyhetene på vår Twitter eller Discord.\nUtviklere som er interessert i å bidra kan finne ut mer på GitHub eller Discord.", "pl_PL": "", - "pt_BR": "Ryujinx é um emulador de Nintendo Switch™.\nReceba todas as últimas notícias em nosso Discord.\nDesenvolvedores interessados em contribuir podem descobrir mais em nosso GitHub ou Discord.", - "ru_RU": "Ryujinx - это эмулятор для Nintendo Switch™.\nПолучайте все последние новости разработки в нашем Discord.\nРазработчики, заинтересованные в участии, могут узнать больше на нашем GitHub или Discord.", - "sv_SE": "Ryujinx är en emulator för Nintendo Switch™.\nFå de senaste nyheterna via vår Discord.\nUtvecklare som är intresserade att bidra kan hitta mer info på vår GitHub eller Discord.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОстанні новини можна отримати в нашому Discord.\nРозробники, що бажають долучитись до розробки та зробити свій внесок, можуть отримати більше інформації на нашому GitHub або в Discord.", - "zh_CN": "Ryujinx 是一个 Nintendo Switch™ 模拟器。\n有兴趣做出贡献的开发者可以在我们的 GitHub 或 Discord 上了解更多信息。\n", - "zh_TW": "Ryujinx 是一款 Nintendo Switch™ 模擬器。\n關注我們的 Discord 取得所有最新消息。\n對於有興趣貢獻的開發者,可以在我們的 GitHub 或 Discord 上了解更多資訊。" + "uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОтримуйте всі останні новини в нашому Discord.\nРозробники, які хочуть зробити внесок, можуть дізнатися більше на нашому GitHub або в Discord.", + "zh_CN": "", + "zh_TW": "" } }, { @@ -15139,7 +13646,6 @@ "pl_PL": "Utrzymywany Przez:", "pt_BR": "Mantido por:", "ru_RU": "Разработка:", - "sv_SE": "Underhålls av:", "th_TH": "ได้รับการดูแลโดย:", "tr_TR": "Geliştiriciler:", "uk_UA": "Підтримується:", @@ -15157,19 +13663,18 @@ "es_ES": "", "fr_FR": "Anciennement Maintenu par :", "he_IL": "", - "it_IT": "Mantenuto in precedenza da:", + "it_IT": "", "ja_JP": "", "ko_KR": "이전 관리자 :", "no_NO": "Tidligere vedlikeholdt av:", "pl_PL": "", - "pt_BR": "Anteriormente mantido por:", - "ru_RU": "Поддержка:", - "sv_SE": "Underhölls tidigare av:", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Минулі розробники:", - "zh_CN": "曾经的维护者:", - "zh_TW": "過往的維護者:" + "zh_CN": "", + "zh_TW": "" } }, { @@ -15189,7 +13694,6 @@ "pl_PL": "Kliknij, aby otworzyć stronę Współtwórcy w domyślnej przeglądarce.", "pt_BR": "Clique para abrir a página de contribuidores no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть страницу с участниками", - "sv_SE": "Klicka för att öppna sidan över personer som bidragit till projektet i din webbläsare.", "th_TH": "คลิกเพื่อเปิดหน้าผู้มีส่วนร่วมบนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Katkıda bulunanlar sayfasını varsayılan tarayıcınızda açmak için tıklayın.", "uk_UA": "Натисніть, щоб відкрити сторінку співавторів у вашому браузері за замовчування.", @@ -15214,7 +13718,6 @@ "pl_PL": "Seria Amiibo", "pt_BR": "Franquia Amiibo", "ru_RU": "Серия Amiibo", - "sv_SE": "Amiibo-serie", "th_TH": "", "tr_TR": "Amiibo Serisi", "uk_UA": "Серія Amiibo", @@ -15239,7 +13742,6 @@ "pl_PL": "Postać", "pt_BR": "Personagem", "ru_RU": "Персонаж", - "sv_SE": "Karaktär", "th_TH": "ตัวละคร", "tr_TR": "Karakter", "uk_UA": "Персонаж", @@ -15264,7 +13766,6 @@ "pl_PL": "Zeskanuj", "pt_BR": "Escanear", "ru_RU": "Сканировать", - "sv_SE": "Skanna den", "th_TH": "สแกนเลย", "tr_TR": "Tarat", "uk_UA": "Сканувати", @@ -15287,9 +13788,8 @@ "ko_KR": "모든 Amiibo 표시", "no_NO": "Vis alle Amiibo", "pl_PL": "Pokaż Wszystkie Amiibo", - "pt_BR": "Exibir Todos os Amiibos", + "pt_BR": "Exibir todos os Amiibos", "ru_RU": "Показать все Amiibo", - "sv_SE": "Visa alla Amiibo", "th_TH": "แสดง Amiibo ทั้งหมด", "tr_TR": "Tüm Amiibo'ları Göster", "uk_UA": "Показати всі Amiibo", @@ -15312,13 +13812,12 @@ "ko_KR": "핵 : 무작위 태그 Uuid 사용", "no_NO": "Hack: Bruk tilfeldig tag-Uuid", "pl_PL": "Hack: Użyj losowego UUID tagu", - "pt_BR": "Hack: Usar Uuid de tag Aleatório", + "pt_BR": "Hack: Usar Uuid de tag aleatório", "ru_RU": "Хак: Использовать случайный тег Uuid", - "sv_SE": "Hack: Använd slumpmässig tagg för Uuid", "th_TH": "แฮ็ค: สุ่มแท็ก Uuid", "tr_TR": "Hack: Rastgele bir Uuid kullan", "uk_UA": "Хитрість: Використовувати випадковий тег Uuid", - "zh_CN": "修改:使用随机生成的 Amiibo ID", + "zh_CN": "修改:使用随机生成的Amiibo ID", "zh_TW": "補釘修正:使用隨機標記的 Uuid" } }, @@ -15339,7 +13838,6 @@ "pl_PL": "Włączone", "pt_BR": "Habilitado", "ru_RU": "Включено", - "sv_SE": "Aktiverad", "th_TH": "เปิดใช้งานแล้ว", "tr_TR": "Etkin", "uk_UA": "Увімкнено", @@ -15362,9 +13860,8 @@ "ko_KR": "타이틀 ID", "no_NO": "Tittel ID", "pl_PL": "ID Tytułu", - "pt_BR": "ID do Título", + "pt_BR": "ID do título", "ru_RU": "ID приложения", - "sv_SE": "Titel-ID", "th_TH": "ชื่อไอดี", "tr_TR": "Başlık ID", "uk_UA": "ID заголовка", @@ -15387,9 +13884,8 @@ "ko_KR": "컨테이너 경로", "no_NO": "Beholder bane", "pl_PL": "Ścieżka Kontenera", - "pt_BR": "Caminho do Contêiner", + "pt_BR": "Caminho do container", "ru_RU": "Путь к контейнеру", - "sv_SE": "Container-sökväg", "th_TH": "คอนเทนเนอร์เก็บไฟล์", "tr_TR": "Container Yol", "uk_UA": "Шлях до контейнеру", @@ -15412,9 +13908,8 @@ "ko_KR": "전체 경로", "no_NO": "Fullstendig bane", "pl_PL": "Pełna Ścieżka", - "pt_BR": "Caminho Completo", + "pt_BR": "Caminho completo", "ru_RU": "Полный путь", - "sv_SE": "Fullständig sökväg", "th_TH": "ที่เก็บไฟล์แบบเต็ม", "tr_TR": "Tam Yol", "uk_UA": "Повний шлях", @@ -15437,9 +13932,8 @@ "ko_KR": "모두 제거", "no_NO": "Fjern alle", "pl_PL": "Usuń Wszystkie", - "pt_BR": "Remover Todos", + "pt_BR": "Remover todos", "ru_RU": "Удалить все", - "sv_SE": "Ta bort allt", "th_TH": "ลบทั้งหมด", "tr_TR": "Tümünü kaldır", "uk_UA": "Видалити все", @@ -15462,9 +13956,8 @@ "ko_KR": "모두 활성화", "no_NO": "Aktiver alle", "pl_PL": "Włącz Wszystkie", - "pt_BR": "Habilitar Todos", + "pt_BR": "Habilitar todos", "ru_RU": "Включить все", - "sv_SE": "Aktivera allt", "th_TH": "เปิดใช้งานทั้งหมด", "tr_TR": "Tümünü Aktif Et", "uk_UA": "Увімкнути всі", @@ -15487,9 +13980,8 @@ "ko_KR": "모두 비활성화", "no_NO": "Deaktiver alle", "pl_PL": "Wyłącz Wszystkie", - "pt_BR": "Desabilitar Todos", + "pt_BR": "Desabilitar todos", "ru_RU": "Отключить все", - "sv_SE": "Inaktivera allt", "th_TH": "ปิดใช้งานทั้งหมด", "tr_TR": "Tümünü Devre Dışı Bırak", "uk_UA": "Вимкнути всі", @@ -15514,7 +14006,6 @@ "pl_PL": "Usuń wszystko", "pt_BR": "Apagar Tudo", "ru_RU": "Удалить все", - "sv_SE": "Ta bort allt", "th_TH": "ลบทั้งหมด", "tr_TR": "Hepsini Sil", "uk_UA": "Видалити все", @@ -15537,9 +14028,8 @@ "ko_KR": "언어 변경", "no_NO": "Endre språk", "pl_PL": "Zmień język", - "pt_BR": "Mudar Idioma", + "pt_BR": "Mudar idioma", "ru_RU": "Сменить язык", - "sv_SE": "Byt språk", "th_TH": "เปลี่ยนภาษา", "tr_TR": "Dili Değiştir", "uk_UA": "Змінити мову", @@ -15562,9 +14052,8 @@ "ko_KR": "파일 형식 표시", "no_NO": "Vis Filtyper", "pl_PL": "Pokaż typy plików", - "pt_BR": "Mostrar Tipos de Arquivo", + "pt_BR": "Mostrar tipos de arquivo", "ru_RU": "Показывать форматы файлов", - "sv_SE": "Visa filtyper", "th_TH": "แสดงประเภทของไฟล์", "tr_TR": "Dosya Uzantılarını Göster", "uk_UA": "Показати типи файлів", @@ -15589,7 +14078,6 @@ "pl_PL": "Sortuj", "pt_BR": "Ordenar", "ru_RU": "Сортировка", - "sv_SE": "Sortera", "th_TH": "เรียงลำดับ", "tr_TR": "Sırala", "uk_UA": "Сортувати", @@ -15612,9 +14100,8 @@ "ko_KR": "이름 표시", "no_NO": "Vis navn", "pl_PL": "Pokaż Nazwy", - "pt_BR": "Exibir Nomes", + "pt_BR": "Exibir nomes", "ru_RU": "Показывать названия", - "sv_SE": "Visa namn", "th_TH": "แสดงชื่อ", "tr_TR": "İsimleri Göster", "uk_UA": "Показати назви", @@ -15639,10 +14126,9 @@ "pl_PL": "Ulubione", "pt_BR": "Favorito", "ru_RU": "Избранное", - "sv_SE": "Favorit", "th_TH": "สิ่งที่ชื่นชอบ", "tr_TR": "Favori", - "uk_UA": "Обрані", + "uk_UA": "Вибрані", "zh_CN": "收藏", "zh_TW": "我的最愛" } @@ -15664,7 +14150,6 @@ "pl_PL": "Rosnąco", "pt_BR": "Ascendente", "ru_RU": "По возрастанию", - "sv_SE": "Stigande", "th_TH": "จากน้อยไปมาก", "tr_TR": "Artan", "uk_UA": "За зростанням", @@ -15689,7 +14174,6 @@ "pl_PL": "Malejąco", "pt_BR": "Descendente", "ru_RU": "По убыванию", - "sv_SE": "Fallande", "th_TH": "จากมากไปน้อย", "tr_TR": "Azalan", "uk_UA": "За спаданням", @@ -15713,8 +14197,7 @@ "no_NO": "Funksjoner & forbedringer", "pl_PL": "Funkcje i Ulepszenia", "pt_BR": "Recursos & Melhorias", - "ru_RU": "Функции и улучшения", - "sv_SE": "Funktioner och förbättringar", + "ru_RU": "Функции", "th_TH": "คุณสมบัติ และ การเพิ่มประสิทธิภาพ", "tr_TR": "Özellikler & İyileştirmeler", "uk_UA": "Функції та вдосконалення", @@ -15737,9 +14220,8 @@ "ko_KR": "오류 창", "no_NO": "Feilvindu", "pl_PL": "Okno Błędu", - "pt_BR": "Janela de Erro", + "pt_BR": "Janela de erro", "ru_RU": "Окно ошибки", - "sv_SE": "Felfönster", "th_TH": "หน้าต่างแสดงข้อผิดพลาด", "tr_TR": "Hata Penceresi", "uk_UA": "Вікно помилок", @@ -15762,9 +14244,8 @@ "ko_KR": "\"현재 진행 중인\" 디스코드 활동에 Ryujinx를 표시할지 여부를 선택", "no_NO": "Velg om Ryujinx skal vises på din \"spillende\" Discord aktivitet eller ikke", "pl_PL": "Wybierz, czy chcesz wyświetlać Ryujinx w swojej \"aktualnie grane\" aktywności Discord", - "pt_BR": "Escolha se deseja mostrar Ryujinx ou não na sua atividade do Discord quando estiver usando-o", - "ru_RU": "Включает или отключает отображение статуса «Играет в игру» в Discord", - "sv_SE": "Välj huruvida Ryujinx ska visas på din \"spelar för tillfället\" Discord-aktivitet", + "pt_BR": "Habilita ou desabilita Discord Rich Presence", + "ru_RU": "Включает или отключает отображение статуса \"Играет в игру\" в Discord", "th_TH": "เลือกว่าจะแสดง Ryujinx ในกิจกรรม Discord \"ที่กำลังเล่นอยู่\" ของคุณหรือไม่?", "tr_TR": "Ryujinx'i \"şimdi oynanıyor\" Discord aktivitesinde göstermeyi veya göstermemeyi seçin", "uk_UA": "Виберіть, чи відображати Ryujinx у вашій «поточній грі» в Discord", @@ -15789,10 +14270,9 @@ "pl_PL": "Wprowadź katalog gier aby dodać go do listy", "pt_BR": "Escreva um diretório de jogo para adicionar à lista", "ru_RU": "Введите путь к папке с играми для добавления ее в список выше", - "sv_SE": "Ange en spelkatalog att lägga till i listan", "th_TH": "ป้อนไดเรกทอรี่เกมที่จะทำการเพิ่มลงในรายการ", "tr_TR": "Listeye eklemek için oyun dizini seçin", - "uk_UA": "Додайте теку з іграми, щоб додати їх до списку", + "uk_UA": "Введіть каталог ігор, щоб додати до списку", "zh_CN": "输入要添加的游戏目录", "zh_TW": "輸入要新增到清單中的遊戲資料夾" } @@ -15814,10 +14294,9 @@ "pl_PL": "Dodaj katalog gier do listy", "pt_BR": "Adicionar um diretório de jogo à lista", "ru_RU": "Добавить папку с играми в список", - "sv_SE": "Lägg till en spelkatalog till listan", "th_TH": "เพิ่มไดเรกทอรี่เกมลงในรายการ", "tr_TR": "Listeye oyun dizini ekle", - "uk_UA": "Додати теку з іграми до списку", + "uk_UA": "Додати каталог гри до списку", "zh_CN": "添加游戏目录到列表中", "zh_TW": "新增遊戲資料夾到清單中" } @@ -15839,10 +14318,9 @@ "pl_PL": "Usuń wybrany katalog gier", "pt_BR": "Remover diretório de jogo selecionado", "ru_RU": "Удалить выбранную папку игры", - "sv_SE": "Ta bort vald spelkatalog", "th_TH": "ลบไดเรกทอรี่เกมที่เลือก", "tr_TR": "Seçili oyun dizinini kaldır", - "uk_UA": "Видалити вибрану теку гри", + "uk_UA": "Видалити вибраний каталог гри", "zh_CN": "移除选中的目录", "zh_TW": "移除選取的遊戲資料夾" } @@ -15857,14 +14335,13 @@ "es_ES": "Elige un directorio de carga automática para agregar a la lista", "fr_FR": "Entrez un répertoire de mises à jour/DLC à ajouter à la liste", "he_IL": "", - "it_IT": "Inserisci una cartella di caricamento automatico da aggiungere alla lista", + "it_IT": "Inserisci una directory di \"autoload\" da aggiungere alla lista", "ja_JP": "", "ko_KR": "목록에 추가할 자동 불러오기 디렉터리를 입력", "no_NO": "Angi en autoload-mappe som skal legges til i listen", "pl_PL": "", "pt_BR": "Insira um diretório de carregamento automático para adicionar à lista", - "ru_RU": "Введите папку автозагрузки для добавления в список", - "sv_SE": "Ange en katalog att automatiskt läsa in till listan", + "ru_RU": "", "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ", "tr_TR": "", "uk_UA": "Введіть шлях автозавантаження для додавання до списку", @@ -15882,14 +14359,13 @@ "es_ES": "Agregar un directorio de carga automática a la lista", "fr_FR": "Ajouter un répertoire de mises à jour/DLC à la liste", "he_IL": "", - "it_IT": "Aggiungi una cartella di caricamento automatico alla lista", + "it_IT": "Aggiungi una directory di \"autoload\" alla lista", "ja_JP": "", "ko_KR": "목록에 자동 불러오기 디렉터리 추가", "no_NO": "Legg til en autoload-mappe i listen", "pl_PL": "", "pt_BR": "Adicionar um diretório de carregamento automático à lista", - "ru_RU": "Добавить папку автозагрузки в список", - "sv_SE": "Lägg till en katalog att automatiskt läsa in till listan", + "ru_RU": "", "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ", "tr_TR": "", "uk_UA": "Додайте шлях автозавантаження для додавання до списку", @@ -15907,17 +14383,16 @@ "es_ES": "Eliminar el directorio de carga automática seleccionado", "fr_FR": "Supprimer le répertoire de mises à jour/DLC sélectionné", "he_IL": "", - "it_IT": "Rimuovi la cartella di caricamento automatico selezionata", + "it_IT": "Rimuovi la directory di autoload selezionata", "ja_JP": "", "ko_KR": "선택한 자동 불러오기 디렉터리 제거", "no_NO": "Fjern valgt autoload-mappe", "pl_PL": "", "pt_BR": "Remover o diretório de carregamento automático selecionado", - "ru_RU": "Убрать папку автозагрузки из списка", - "sv_SE": "Ta bort markerad katalog för automatisk inläsning", + "ru_RU": "", "th_TH": "ลบไดเรกทอรีสำหรับโหลดอัตโนมัติที่เลือก", "tr_TR": "", - "uk_UA": "Видалити вибрану теку автозавантаження", + "uk_UA": "Видалити вибраний каталог автозавантаження", "zh_CN": "移除被选中的自动加载目录", "zh_TW": "移除選取的「自動載入 DLC/遊戲更新資料夾」" } @@ -15932,14 +14407,13 @@ "es_ES": "Activa o desactiva los temas personalizados para la interfaz", "fr_FR": "Utilisez un thème personnalisé Avalonia pour modifier l'apparence des menus de l'émulateur", "he_IL": "השתמש בעיצוב מותאם אישית של אבלוניה עבור ה-ממשק הגראפי כדי לשנות את המראה של תפריטי האמולטור", - "it_IT": "Utilizza un tema di Avalonia personalizzato per cambiare l'aspetto dei menù dell'emulatore", + "it_IT": "Attiva o disattiva temi personalizzati nella GUI", "ja_JP": "エミュレータのメニュー外観を変更するためカスタム Avalonia テーマを使用します", "ko_KR": "GUI용 사용자 정의 Avalonia 테마를 사용하여 에뮬레이터 메뉴의 모양 변경", "no_NO": "Bruk et egendefinert Avalonia tema for GUI for å endre utseende til emulatormenyene", "pl_PL": "Użyj niestandardowego motywu Avalonia dla GUI, aby zmienić wygląd menu emulatora", - "pt_BR": "Use um tema Avalonia personalizado para a GUI para alterar a aparência dos menus do emulador", + "pt_BR": "Habilita ou desabilita temas customizados na interface gráfica", "ru_RU": "Включить или отключить пользовательские темы", - "sv_SE": "Använd ett anpassat Avalonia-tema för gränssnittet för att ändra utseendet i emulatormenyerna", "th_TH": "ใช้ธีม Avalonia แบบกำหนดเองสำหรับ GUI เพื่อเปลี่ยนรูปลักษณ์ของเมนูโปรแกรมจำลอง", "tr_TR": "Emülatör pencerelerinin görünümünü değiştirmek için özel bir Avalonia teması kullan", "uk_UA": "Використовуйте користувацьку тему Avalonia для графічного інтерфейсу, щоб змінити вигляд меню емулятора", @@ -15957,14 +14431,13 @@ "es_ES": "Carpeta que contiene los temas personalizados para la interfaz", "fr_FR": "Chemin vers le thème personnalisé de l'interface utilisateur", "he_IL": "נתיב לערכת נושא לממשק גראפי מותאם אישית", - "it_IT": "Percorso al tema dell'interfaccia personalizzato", + "it_IT": "Percorso al tema GUI personalizzato", "ja_JP": "カスタム GUI テーマのパスです", "ko_KR": "사용자 정의 GUI 테마 경로", "no_NO": "Bane til egendefinert GUI-tema", "pl_PL": "Ścieżka do niestandardowego motywu GUI", "pt_BR": "Diretório do tema customizado", - "ru_RU": "Путь к пользовательской теме интерфейса", - "sv_SE": "Sökväg till anpassat gränssnittstema", + "ru_RU": "Путь к пользовательской теме для интерфейса", "th_TH": "ไปยังที่เก็บไฟล์ธีม GUI แบบกำหนดเอง", "tr_TR": "Özel arayüz temasının yolu", "uk_UA": "Шлях до користувацької теми графічного інтерфейсу", @@ -15982,14 +14455,13 @@ "es_ES": "Busca un tema personalizado para la interfaz", "fr_FR": "Parcourir vers un thème personnalisé pour l'interface utilisateur", "he_IL": "חפש עיצוב ממשק גראפי מותאם אישית", - "it_IT": "Scegli un tema dell'interfaccia personalizzato", + "it_IT": "Sfoglia per cercare un tema GUI personalizzato", "ja_JP": "カスタム GUI テーマを参照します", "ko_KR": "사용자 정의 GUI 테마 찾아보기", "no_NO": "Søk etter et egendefinert GUI-tema", "pl_PL": "Wyszukaj niestandardowy motyw GUI", "pt_BR": "Navegar até um tema customizado", "ru_RU": "Просмотр пользовательской темы интерфейса", - "sv_SE": "Bläddra efter ett anpassat gränssnittstema", "th_TH": "เรียกดูธีม GUI ที่กำหนดเอง", "tr_TR": "Özel arayüz teması için göz at", "uk_UA": "Огляд користувацької теми графічного інтерфейсу", @@ -16013,8 +14485,7 @@ "no_NO": "Forankret modus gjør at systemet oppføre seg som en forankret Nintendo Switch. Dette forbedrer grafikkkvaliteten i de fleste spill. Motsatt vil deaktivering av dette gjøre at systemet oppføre seg som en håndholdt Nintendo Switch, noe som reduserer grafikkkvaliteten.\n\nKonfigurer spiller 1 kontroller hvis du planlegger å bruke forankret modus; konfigurer håndholdte kontroller hvis du planlegger å bruke håndholdte modus.\n\nLa PÅ hvis du er usikker.", "pl_PL": "Tryb Zadokowany sprawia, że emulowany system zachowuje się jak zadokowany Nintendo Switch. Poprawia to jakość grafiki w większości gier. I odwrotnie, wyłączenie tej opcji sprawi, że emulowany system będzie zachowywał się jak przenośny Nintendo Switch, zmniejszając jakość grafiki.\n\nSkonfiguruj sterowanie gracza 1, jeśli planujesz używać trybu Zadokowanego; Skonfiguruj sterowanie przenośne, jeśli planujesz używać trybu przenośnego.\n\nPozostaw WŁĄCZONY, jeśli nie masz pewności.", "pt_BR": "O modo TV faz o sistema emulado se comportar como um Nintendo Switch na TV, o que melhora a fidelidade gráfica na maioria dos jogos. Por outro lado, desativar essa opção fará o sistema emulado se comportar como um Nintendo Switch portátil, reduzindo a qualidade gráfica.\n\nConfigure os controles do jogador 1 se planeja usar o modo TV; configure os controles de portátil se planeja usar o modo Portátil.\n\nMantenha ativado se estiver em dúvida.", - "ru_RU": "\"Стационарный\" режим запускает эмулятор, как если бы Nintendo Switch находилась в доке, что улучшает графику и разрешение в большинстве игр. И наоборот, при отключении этого режима эмулятор будет запускать игры в \"Портативном\" режиме, снижая качество графики.\n\nНастройте управление для Игрока 1 если планируете использовать эмулятор в \"Стационарном\" режиме; настройте портативное управление если планируете использовать эмулятор в \"Портативном\" режиме.\n\nРекомендуется оставить включенным.", - "sv_SE": "Dockat läge gör att det emulerade systemet beter sig som en dockad Nintendo Switch. Detta förbättrar grafiken i de flesta spel. Inaktiveras detta så kommer det emulerade systemet att bete sig som en handhållen Nintendo Switch, vilket reducerar grafikkvaliteten.\n\nKonfigurera kontrollen för Spelare 1 om du planerar att använda dockat läge; konfigurera handhållna kontroller om du planerar att använda handhållet läge.\n\nLämna PÅ om du är osäker.", + "ru_RU": "\"Стационарный\" режим запускает эмулятор, как если бы Nintendo Switch находилась в доке, что улучшает графику и разрешение в большинстве игр. И наоборот, при отключении этого режима эмулятор будет запускать игры в \"Портативном\" режиме, снижая качество графики.\n\nНастройте управление для Игрока 1 если планируете использовать в \"Стационарном\" режиме; настройте портативное управление если планируете использовать эмулятор в \"Портативном\" режиме.\n\nРекомендуется оставить включенным.", "th_TH": "ด็อกโหมด ทำให้ระบบจำลองการทำงานเสมือน Nintendo ที่กำลังเชื่อมต่ออยู่ด็อก สิ่งนี้จะปรับปรุงความเสถียรภาพของกราฟิกในเกมส่วนใหญ่ ในทางกลับกัน การปิดใช้จะทำให้ระบบจำลองทำงานเหมือนกับ Nintendo Switch แบบพกพา ส่งผลให้คุณภาพกราฟิกลดลง\n\nแนะนำกำหนดค่าควบคุมของผู้เล่น 1 หากวางแผนที่จะใช้ด็อกโหมด กำหนดค่าการควบคุมแบบ แฮนด์เฮลด์ หากวางแผนที่จะใช้โหมดแฮนด์เฮลด์\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Docked modu emüle edilen sistemin yerleşik Nintendo Switch gibi davranmasını sağlar. Bu çoğu oyunda grafik kalitesini arttırır. Diğer yandan, bu seçeneği devre dışı bırakmak emüle edilen sistemin portatif Ninendo Switch gibi davranmasını sağlayıp grafik kalitesini düşürür.\n\nDocked modu kullanmayı düşünüyorsanız 1. Oyuncu kontrollerini; Handheld modunu kullanmak istiyorsanız portatif kontrollerini konfigüre edin.\n\nEmin değilseniz aktif halde bırakın.", "uk_UA": "У режимі док-станції емульована система веде себе як приєднаний Nintendo Switch. Це покращує точність графіки в більшості ігор. І навпаки, вимкнення цього призведе до того, що емульована система поводитиметься як портативний комутатор Nintendo, погіршуючи якість графіки.\n\nНалаштуйте елементи керування для гравця 1, якщо плануєте використовувати режим док-станції; налаштуйте ручні елементи керування, якщо плануєте використовувати портативний режим.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -16039,7 +14510,6 @@ "pl_PL": "Obsługa bezpośredniego dostępu do klawiatury (HID). Zapewnia dostęp gier do klawiatury jako urządzenia do wprowadzania tekstu.\n\nDziała tylko z grami, które natywnie wspierają użycie klawiatury w urządzeniu Switch hardware.\n\nPozostaw wyłączone w razie braku pewności.", "pt_BR": "Suporte para acesso direto ao teclado (HID). Permite que os jogos acessem seu teclado como um dispositivo de entrada de texto.\n\nFunciona apenas com jogos que suportam o uso de teclado nativamente no hardware do Switch.\n\nDeixe desativado se estiver em dúvida.", "ru_RU": "Поддержка прямого ввода с клавиатуры (HID). Предоставляет игре прямой доступ к клавиатуре в качестве устройства ввода текста.\nРаботает только с играми, которые изначально поддерживают использование клавиатуры с Switch.\nРекомендуется оставить выключенным.", - "sv_SE": "Stöd för direkt tangentbordsåtkomst (HID). Ger spel åtkomst till ditt tangentbord som en textinmatningsenhet.\n\nFungerar endast med spel som har inbyggt stöd för tangentbordsanvändning på Switch-hårdvara.\n\nLämna AV om du är osäker.", "th_TH": "รองรับการเข้าถึงแป้นพิมพ์โดยตรง (HID) ให้เกมเข้าถึงคีย์บอร์ดของคุณเป็นอุปกรณ์ป้อนข้อความ\n\nใช้งานได้กับเกมที่รองรับการใช้งานคีย์บอร์ดบนฮาร์ดแวร์ของ Switch เท่านั้น\n\nหากคุณไม่แน่ใจให้ปิดใช้งานไว้", "tr_TR": "", "uk_UA": "Підтримка прямого доступу до клавіатури (HID). Надає іграм доступ до клавіатури для вводу тексту.\n\nПрацює тільки з іграми, які підтримують клавіатуру на обладнанні Switch.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -16064,10 +14534,9 @@ "pl_PL": "Obsługa bezpośredniego dostępu do myszy (HID). Zapewnia dostęp gier do myszy jako urządzenia wskazującego.\n\nDziała tylko z grami, które natywnie obsługują przyciski myszy w urządzeniu Switch, które są nieliczne i daleko między nimi.\n\nPo włączeniu funkcja ekranu dotykowego może nie działać.\n\nPozostaw wyłączone w razie wątpliwości.", "pt_BR": "Suporte para acesso direto ao mouse (HID). Permite que os jogos acessem seu mouse como um dispositivo de apontamento.\n\nFunciona apenas com jogos que suportam controles de mouse nativamente no hardware do Switch, o que é raro.\n\nQuando ativado, a funcionalidade de tela sensível ao toque pode não funcionar.\n\nDeixe desativado se estiver em dúvida.", "ru_RU": "Поддержка прямого ввода мыши (HID). Предоставляет игре прямой доступ к мыши в качестве указывающего устройства.\nРаботает только с играми, которые изначально поддерживают использование мыши совместно с железом Switch.\nРекомендуется оставить выключенным.", - "sv_SE": "Stöd för direkt musåtkomst (HID). Ger spel åtkomst till din mus som pekdon.\n\nFungerar endast med spel som har inbyggt stöd för muskontroller på Switch-hårdvara, som är endast ett fåtal.\n\nViss pekskärmsfunktionalitet kanske inte fungerar när aktiverat.\n\nLämna AV om du är osäker.", "th_TH": "รองรับการเข้าถึงเมาส์โดยตรง (HID) ให้เกมเข้าถึงเมาส์ของคุณเป็นอุปกรณ์ชี้ตำแหน่ง\n\nใช้งานได้เฉพาะกับเกมที่รองรับการควบคุมเมาส์บนฮาร์ดแวร์ของ Switch เท่านั้น ซึ่งมีอยู่ไม่มากนัก\n\nเมื่อเปิดใช้งาน ฟังก์ชั่นหน้าจอสัมผัสอาจไม่ทำงาน\n\nหากคุณไม่แน่ใจให้ปิดใช้งานไว้", "tr_TR": "", - "uk_UA": "Підтримка прямого доступу до миші (HID). Надає іграм доступ до миші, як пристрій вказування.\n\nПрацює тільки з тими іграми, що підтримують мишу на обладнанні Switch (таких небагато).\n\nФункціонал сенсорного екрану може не працювати, якщо увімкнути цю функцію.\n\nЗалиште вимкненим, якщо не впевнені.", + "uk_UA": "Підтримка прямого доступу до миші (HID). Надає іграм доступ до миші, як пристрій вказування.\n\nПрацює тільки з іграми, які підтримують мишу на обладнанні Switch, їх небагато.\n\nФункціонал сенсорного екрана може не працювати, якщо функція ввімкнена.\n\nЗалиште вимкненим, якщо не впевнені.", "zh_CN": "直接鼠标访问(HID)支持,游戏可以直接访问鼠标作为指针输入设备。\n\n只适用于在 Switch 硬件上原生支持鼠标控制的游戏,这种游戏很少。\n\n启用后,触屏功能可能无法正常工作。\n\n如果不确定,请保持关闭状态。", "zh_TW": "支援滑鼠直接存取 (HID)。遊戲可將滑鼠作為指向裝置使用。\n\n僅適用於在 Switch 硬體上原生支援滑鼠控制的遊戲,這類遊戲很少。\n\n啟用後,觸控螢幕功能可能無法使用。\n\n如果不確定,請保持關閉狀態。" } @@ -16087,9 +14556,8 @@ "ko_KR": "시스템 지역 변경", "no_NO": "Endre systemregion", "pl_PL": "Zmień Region Systemu", - "pt_BR": "Mudar a Região do Sistema", - "ru_RU": "Сменяет регион системы", - "sv_SE": "Ändra systemets region", + "pt_BR": "Mudar a região do sistema", + "ru_RU": "Сменяет регион прошивки", "th_TH": "เปลี่ยนภูมิภาคของระบบ", "tr_TR": "Sistem Bölgesini Değiştir", "uk_UA": "Змінити регіон системи", @@ -16112,9 +14580,8 @@ "ko_KR": "시스템 언어 변경", "no_NO": "Endre systemspråk", "pl_PL": "Zmień język systemu", - "pt_BR": "Mudar o Idioma do Sistema", - "ru_RU": "Меняет язык системы", - "sv_SE": "Ändra systemets språk", + "pt_BR": "Mudar o idioma do sistema", + "ru_RU": "Меняет язык прошивки", "th_TH": "เปลี่ยนภาษาของระบบ", "tr_TR": "Sistem Dilini Değiştir", "uk_UA": "Змінити мову системи", @@ -16137,9 +14604,8 @@ "ko_KR": "시스템 시간대 변경", "no_NO": "Endre systemtidssone", "pl_PL": "Zmień Strefę Czasową Systemu", - "pt_BR": "Mudar o Fuso-Horário do Sistema", - "ru_RU": "Меняет часовой пояс системы", - "sv_SE": "Ändra systemets tidszon", + "pt_BR": "Mudar o fuso-horário do sistema", + "ru_RU": "Меняет часовой пояс прошивки", "th_TH": "เปลี่ยนโซนเวลาของระบบ", "tr_TR": "Sistem Saat Dilimini Değiştir", "uk_UA": "Змінити часовий пояс системи", @@ -16162,12 +14628,11 @@ "ko_KR": "시스템 시간 변경", "no_NO": "Endre systemtid", "pl_PL": "Zmień czas systemowy", - "pt_BR": "Mudar a Data e Hora do Sistema", - "ru_RU": "Меняет системное время системы", - "sv_SE": "Ändra systemtid", + "pt_BR": "Mudar a hora do sistema", + "ru_RU": "Меняет системное время прошивки", "th_TH": "เปลี่ยนเวลาของระบบ", "tr_TR": "Sistem Saatini Değiştir", - "uk_UA": "Змінити системний час", + "uk_UA": "Змінити час системи", "zh_CN": "更改系统时间", "zh_TW": "變更系統時鐘" } @@ -16178,23 +14643,22 @@ "ar_SA": "", "de_DE": "", "el_GR": "", - "en_US": "Sync System Time to match your PC's current date & time.", + "en_US": "Resync System Time to match your PC's current date & time.\n\nThis is not an active setting, it can still fall out of sync; in which case just click this button again.", "es_ES": "", - "fr_FR": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.", + "fr_FR": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.\n\nCeci n'est pas un paramètrage automatique, la date peut se désynchroniser; dans ce cas là, rappuyer sur le boutton.", "he_IL": "", - "it_IT": "Sincronizza data e ora del sistema con quelle del PC.", + "it_IT": "", "ja_JP": "", - "ko_KR": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.", - "no_NO": "Resynkroniser systemtiden slik at den samsvarer med PC-ens gjeldende dato og klokkeslett.", + "ko_KR": "", + "no_NO": "", "pl_PL": "", - "pt_BR": "Sincroniza a data e hora do emulador com seu sistema PC", - "ru_RU": "Повторно синхронизирует системное время, чтобы оно соответствовало текущей дате и времени вашего компьютера.", - "sv_SE": "Återsynkronisera systemtiden för att matcha din dators aktuella datum och tid.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Синхронізувати системний час, щоб він відповідав поточній даті та часу вашого ПК.", - "zh_CN": "重新同步系统时间以匹配您电脑的当前日期和时间。", - "zh_TW": "重新同步系統韌體時間至 PC 目前的日期和時間。" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -16207,17 +14671,16 @@ "es_ES": "Sincronización vertical de la consola emulada. En práctica un limitador del framerate para la mayoría de los juegos; desactivando puede causar que juegos corran a mayor velocidad o que las pantallas de carga tarden más o queden atascados.\n\nSe puede alternar en juego utilizando una tecla de acceso rápido configurable (F1 by default). Recomendamos hacer esto en caso de querer desactivar sincroniziación vertical.\n\nDesactívalo si no sabes qué hacer.", "fr_FR": "La synchronisation verticale de la console émulée. Essentiellement un limiteur de trame pour la majorité des jeux ; le désactiver peut entraîner un fonctionnement plus rapide des jeux ou prolonger ou bloquer les écrans de chargement.\n\nPeut être activé ou désactivé en jeu avec un raccourci clavier de votre choix (F1 par défaut). Nous recommandons de le faire si vous envisagez de le désactiver.\n\nLaissez activé si vous n'êtes pas sûr.", "he_IL": "", - "it_IT": "Sincronizzazione verticale della console emulata. Funziona essenzialmente come un limitatore del framerate per la maggior parte dei giochi; disabilitarla può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata mentre giochi con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarla.\n\nNel dubbio, lascia l'opzione attiva.", + "it_IT": "Sincronizzazione verticale della console Emulata. Essenzialmente un limitatore di frame per la maggior parte dei giochi; disabilitarlo può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata in gioco con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarlo.\n\nLascia ON se non sei sicuro.", "ja_JP": "エミュレートされたゲーム機の垂直同期です. 多くのゲームにおいて, フレームリミッタとして機能します. 無効にすると, ゲームが高速で実行されたり, ロード中に時間がかかったり, 止まったりすることがあります.\n\n設定したホットキー(デフォルトではF1)で, ゲーム内で切り替え可能です. 無効にする場合は, この操作を行うことをおすすめします.\n\nよくわからない場合はオンのままにしてください.", "ko_KR": "에뮬레이트된 콘솔의 수직 동기화입니다. 기본적으로 대부분의 게임에서 프레임 제한 기능으로, 비활성화하면 게임이 더 빠른 속도로 실행되거나 로딩 화면이 더 오래 걸리거나 멈출 수 있습니다.\n\n게임 내에서 원하는 단축키(기본값은 F1)로 전환할 수 있습니다. 비활성화하려면 이 작업을 수행하는 것이 좋습니다.\n\n모르면 켬으로 두세요.", "no_NO": "Emuler konsollens loddrett synkronisering. på ett vis en bildefrekvens begrensning for de fleste spill; deaktivering kan få spill til å kjøre med høyere hastighet, eller til å laste skjermene tar lengre tid eller sitter fast.\n\nkan byttes inn i spillet med en hurtigtast for preferansen (F1 som standard). Vi anbefaler å gjøre dette hvis du planlegger å deaktivere dette.\n\nLa være PÅ hvis du er usikker.", "pl_PL": "Synchronizacja pionowa emulowanej konsoli. Zasadniczo ogranicznik klatek dla większości gier; wyłączenie jej może spowodować, że gry będą działać z większą szybkością, ekrany wczytywania wydłużą się lub nawet utkną.\n\nMoże być przełączana w grze za pomocą preferowanego skrótu klawiszowego. Zalecamy to zrobić, jeśli planujesz ją wyłączyć.\n\nW razie wątpliwości pozostaw WŁĄCZONĄ.", "pt_BR": "V-Sync do console emulado. Funciona essencialmente como um limitador de quadros para a maioria dos jogos; desativá-lo pode fazer com que os jogos rodem em uma velocidade mais alta ou que telas de carregamento demorem mais ou travem.\n\nPode ser alternado durante o jogo com uma tecla de atalho de sua preferência (F1 por padrão). Recomendamos isso caso planeje desativá-lo.\n\nMantenha ligado se estiver em dúvida.", "ru_RU": "Эмуляция вертикальной синхронизации консоли, которая ограничивает количество кадров в секунду в большинстве игр; отключение может привести к тому, что игры будут запущены с более высокой частотой кадров, но загрузка игры может занять больше времени, либо игра не запустится вообще.\n\nМожно включать и выключать эту настройку непосредственно в игре с помощью горячих клавиш (F1 по умолчанию). Если планируете отключить вертикальную синхронизацию, рекомендуем настроить горячие клавиши.\n\nРекомендуется оставить включенным.", - "sv_SE": "Emulerade konsollens vertikala synk. I grund och botten en begränsare för bitrutor för de flesta spel; inaktivera den kan orsaka att spel kör på en högre hastighet eller gör att skärmar tar längre tid att läsa eller fastnar i dem.\n\nKan växlas inne i spelet med en snabbtangent som du väljer (F1 som standard). Vi rekommenderar att göra detta om du planerar att inaktivera den.\n\nLämna PÅ om du är osäker.", "th_TH": "Vertical Sync ของคอนโซลจำลอง โดยพื้นฐานแล้วเป็นตัวจำกัดเฟรมสำหรับเกมส่วนใหญ่ การปิดใช้งานอาจทำให้เกมทำงานด้วยความเร็วสูงขึ้น หรือทำให้หน้าจอการโหลดใช้เวลานานขึ้นหรือค้าง\n\nสามารถสลับได้ในเกมด้วยปุ่มลัดตามที่คุณต้องการ (F1 เป็นค่าเริ่มต้น) เราขอแนะนำให้ทำเช่นนี้หากคุณวางแผนที่จะปิดการใช้งาน\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "", - "uk_UA": "Емуляція Вертикальної Синхронізації консолі. По суті, це обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.", + "uk_UA": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.", "zh_CN": "模拟控制台的垂直同步,开启后会降低大部分游戏的帧率。关闭后,可以获得更高的帧率,但也可能导致游戏画面加载耗时更长或卡住。\n\n在游戏中可以使用热键进行切换(默认为 F1 键)。\n\n如果不确定,请保持开启状态。", "zh_TW": "模擬遊戲機的垂直同步。對大多數遊戲來說,它本質上是一個幀率限制器;停用它可能會導致遊戲以更高的速度執行,或使載入畫面耗時更長或卡住。\n\n可以在遊戲中使用快速鍵進行切換 (預設為 F1)。如果您打算停用,我們建議您這樣做。\n\n如果不確定,請保持開啟狀態。" } @@ -16237,12 +14700,11 @@ "ko_KR": "번역된 JIT 함수를 저장하여 게임을 불러올 때마다 번역할 필요가 없도록 합니다.\n\n게임을 처음 부팅한 후 끊김 현상을 줄이고 부팅 시간을 크게 단축합니다.\n\n모르면 켬으로 두세요.", "no_NO": "Lagrer oversatte JIT funksjoner så de ikke trenger og bli oversatt hver gang spillet laster.\n\nKan redusere hakkete spilling og gjør at spillet starter opp raskere ved første oppstart.\n\nLa være PÅ om usikker.", "pl_PL": "Zapisuje przetłumaczone funkcje JIT, dzięki czemu nie muszą być tłumaczone za każdym razem, gdy gra się ładuje.\n\nZmniejsza zacinanie się i znacznie przyspiesza uruchamianie po pierwszym uruchomieniu gry.\n\nJeśli nie masz pewności, pozostaw WŁĄCZONE", - "pt_BR": "Salva funções JIT traduzidas para que elas não precisem ser traduzidas toda vez que o jogo for carregado.\n\nReduz a trepidação e acelera significativamente os tempos de inicialização após a primeira inicialização de um jogo.\n\nDeixe LIGADO se não tiver certeza.", + "pt_BR": "Habilita ou desabilita PPTC", "ru_RU": "Сохраняет скомпилированные JIT-функции для того, чтобы не преобразовывать их по новой каждый раз при запуске игры.\n\nУменьшает статтеры и значительно ускоряет последующую загрузку игр.\n\nРекомендуется оставить включенным.", - "sv_SE": "Sparar översatta JIT-funktioner så att de inte behöver översättas varje gång som spelet läses in.\n\nMinskar stuttering och snabbare på uppstartstiden väsentligt efter första uppstarten av ett spel.\n\nLämna PÅ om du är osäker.", "th_TH": "บันทึกฟังก์ชั่น JIT ที่แปลแล้ว ดังนั้นจึงไม่จำเป็นต้องแปลทุกครั้งที่โหลดเกม\n\nลดอาการกระตุกและเร่งความเร็วการบูตได้อย่างมากหลังจากการบูตครั้งแรกของเกม\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Çevrilen JIT fonksiyonlarını oyun her açıldığında çevrilmek zorunda kalmaması için kaydeder.\n\nTeklemeyi azaltır ve ilk açılıştan sonra oyunların ilk açılış süresini ciddi biçimde hızlandırır.\n\nEmin değilseniz aktif halde bırakın.", - "uk_UA": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання (stuttering) та значно прискорює наступні завантаження гри (після першого завантаження).\n\nЗалиште увімкненим, якщо не впевнені.", + "uk_UA": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.", "zh_CN": "缓存已编译的游戏指令,这样每次游戏加载时就无需重新编译。\n\n可以减少卡顿和启动时间,提高游戏响应速度。\n\n如果不确定,请保持开启状态。", "zh_TW": "儲存已轉譯的 JIT 函數,這樣每次載入遊戲時就無需再轉譯這些函數。\n\n減少遊戲首次啟動後的卡頓現象,並大大加快啟動時間。\n\n如果不確定,請保持開啟狀態。" } @@ -16257,18 +14719,17 @@ "es_ES": "Cargue el PPTC utilizando un tercio de la cantidad de núcleos.", "fr_FR": "Charger le PPTC en utilisant un tiers des coeurs.", "he_IL": "", - "it_IT": "Carica la cache PPTC usando un terzo dei core del processore.", + "it_IT": "Carica il PPTC usando un terzo dei core.", "ja_JP": "", "ko_KR": "코어의 3분의 1을 사용하여 PPTC를 불러옵니다.", "no_NO": "Last inn PPTC med en tredjedel av antall kjerner.", "pl_PL": "", - "pt_BR": "Carrega o PPTC usando um terço da quantidade de núcleos.", - "ru_RU": "Загрузить PPTC, используя треть от количества ядер.", - "sv_SE": "Läs in PPTC med en tredjedel av mängden kärnor.", + "pt_BR": "Carregar o PPTC usando um terço da quantidade de núcleos.", + "ru_RU": "", "th_TH": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์", "tr_TR": "", "uk_UA": "Завантажувати PPTC використовуючи третину від кількості ядер.", - "zh_CN": "使用三分之一的核心数加载 PPTC.", + "zh_CN": "使用三分之一的核心数加载PPTC.", "zh_TW": "使用 CPU 核心數量的三分之一載入 PPTC。" } }, @@ -16287,9 +14748,8 @@ "ko_KR": "게임을 부팅할 때 손상된 파일을 확인하고, 손상된 파일이 감지되면 로그에 해시 오류를 표시합니다.\n\n성능에 영향을 미치지 않으며 문제 해결에 도움이 됩니다.\n\n모르면 켬으로 두세요.", "no_NO": "Sjekker for korrupte filer ved oppstart av et spill, og dersom korrupte filer oppdages, viser en hashfeil i loggen.\n\nhar ingen innvirkning på ytelsen og er ment å hjelpe med feilsøking.\n\nLa være PÅ hvis usikker.", "pl_PL": "Sprawdza pliki podczas uruchamiania gry i jeśli zostaną wykryte uszkodzone pliki, wyświetla w dzienniku błąd hash.\n\nNie ma wpływu na wydajność i ma pomóc w rozwiązywaniu problemów.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Verifica se há arquivos corrompidos ao inicializar um jogo e, se forem detectados, exibe um erro de hash no log.\n\nNão tem impacto no desempenho e tem como objetivo ajudar na solução de problemas.\n\nDeixe LIGADO se não tiver certeza.", + "pt_BR": "Habilita ou desabilita verificação de integridade dos arquivos do jogo", "ru_RU": "Проверяет файлы при загрузке игры и если обнаружены поврежденные файлы, выводит сообщение о поврежденном хэше в журнале.\n\nНе влияет на производительность и необходим для помощи в устранении неполадок.\n\nРекомендуется оставить включенным.", - "sv_SE": "Letar efter skadade filer när ett spel startas upp, och om skadade filer hittas, visas ett kontrollsummefel i loggen.\n\nHar ingen påverkan på prestandan och är tänkt att hjälpa felsökningen.\n\nLämna PÅ om du är osäker.", "th_TH": "ตรวจสอบไฟล์ที่เสียหายเมื่อบูตเกม และหากตรวจพบไฟล์ที่เสียหาย จะแสดงข้อผิดพลาดของแฮชในบันทึก\n\nไม่มีผลกระทบต่อประสิทธิภาพการทำงานและมีไว้เพื่อช่วยในการแก้ไขปัญหา\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Oyun açarken hatalı dosyaların olup olmadığını kontrol eder, ve hatalı dosya bulursa log dosyasında hash hatası görüntüler.\n\nPerformansa herhangi bir etkisi yoktur ve sorun gidermeye yardımcı olur.\n\nEmin değilseniz aktif halde bırakın.", "uk_UA": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -16312,9 +14772,8 @@ "ko_KR": "오디오 렌더링에 사용되는 백엔드를 변경합니다.\n\nSDL2가 선호되는 반면 OpenAL 및 SoundIO는 대체 수단으로 사용됩니다. 더미에는 소리가 나지 않습니다.\n\n모르면 SDL2로 설정하세요.", "no_NO": "Endrer backend brukt til å gjengi lyd.\n\nSDL2 er foretrukket, mens OpenAL og SoundIO brukes som reserveløsning. Dummy kommer ikke til å ha lyd.\n\nSett til SDL2 hvis usikker.", "pl_PL": "Zmienia backend używany do renderowania dźwięku.\n\nSDL2 jest preferowany, podczas gdy OpenAL i SoundIO są używane jako rezerwy. Dummy nie będzie odtwarzać dźwięku.\n\nW razie wątpliwości ustaw SDL2.", - "pt_BR": "Altera o módulo usado para renderizar áudio.\n\nSDL2 é o preferido, enquanto OpenAL e SoundIO são usados como fallbacks. Dummy não terá som.\n\nDefina como SDL2 se não tiver certeza.", + "pt_BR": "Mudar biblioteca de áudio", "ru_RU": "Изменяет используемый аудио бэкенд для рендера звука.\n\nSDL2 является предпочтительным вариантом, в то время как OpenAL и SoundIO используются в качестве резервных.\n\nРекомендуется использование SDL2.", - "sv_SE": "Ändrar bakänden som används för att rendera ljud.\n\nSDL2 är den föredragna, men OpenAL och SoundIO används för att falla tillbaka på. Dummy har inget ljud.\n\nStäll in till SDL2 om du är osäker.", "th_TH": "เปลี่ยนแบ็กเอนด์ที่ใช้ในการเรนเดอร์เสียง\n\nแนะนำเป็น SDL2 ในขณะที่ OpenAL และ SoundIO ถูกใช้เป็นทางเลือกสำรอง ดัมมี่จะไม่มีเสียง\n\nตั้งค่าเป็น SDL2 หากคุณไม่แน่ใจ", "tr_TR": "Ses çıkış motorunu değiştirir.\n\nSDL2 tercih edilen seçenektir, OpenAL ve SoundIO ise alternatif olarak kullanılabilir. Dummy seçeneğinde ses çıkışı olmayacaktır.\n\nEmin değilseniz SDL2 seçeneğine ayarlayın.", "uk_UA": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.", @@ -16337,9 +14796,8 @@ "ko_KR": "게스트 메모리 매핑 및 접속 방법을 변경합니다. 에뮬레이트된 CPU 성능에 큰 영향을 미칩니다.\n\n모르면 호스트 확인 안 함으로 설정합니다.", "no_NO": "Endre hvordan gjesteminne tilordnes og åpnes. Påvirker emulator CPU-ytelsen veldig mye.\n\nSett til HOST UNCHECKED hvis usikker.", "pl_PL": "Zmień sposób mapowania i uzyskiwania dostępu do pamięci gości. Znacznie wpływa na wydajność emulowanego procesora.\n\nUstaw na HOST UNCHECKED, jeśli nie masz pewności.", - "pt_BR": "Altera como a memória do convidado é mapeada e acessada. Afeta muito o desempenho da CPU emulada.\n\nDefina como HÓSPEDE SEM VERIFICAÇÃO se não tiver certeza.", - "ru_RU": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить «Хост не установлен»", - "sv_SE": "Ändra hur gästminne mappas och ges åtkomst till. Påverkar emulerad CPU-prestanda mycket.\n\nStäll in till \"Värd inte kontrollerad\" om du är osäker.", + "pt_BR": "Muda como a memória do sistema convidado é acessada. Tem um grande impacto na performance da CPU emulada.", + "ru_RU": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить \"Хост не установлен\"", "th_TH": "เปลี่ยนวิธีการเข้าถึงหน่วยความจำของผู้เยี่ยมชม ส่งผลอย่างมากต่อประสิทธิภาพการทำงานของ CPU ที่จำลอง\n\nตั้งค่าเป็น ไม่ได้ตรวจสอบโฮสต์ หากคุณไม่แน่ใจ", "tr_TR": "Guest hafızasının nasıl tahsis edilip erişildiğini değiştirir. Emüle edilen CPU performansını ciddi biçimde etkiler.\n\nEmin değilseniz HOST UNCHECKED seçeneğine ayarlayın.", "uk_UA": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.", @@ -16364,7 +14822,6 @@ "pl_PL": "Użyj tabeli stron oprogramowania do translacji adresów. Najwyższa celność, ale najwolniejsza wydajność.", "pt_BR": "Usar uma tabela de página via software para tradução de endereços. Maior precisão, porém performance mais baixa.", "ru_RU": "Использует таблицу страниц для преобразования адресов. \nСамая высокая точность, но самая низкая производительность.", - "sv_SE": "Använd en programvarubaserad page table för adressöversättning. Högsta noggrannhet men lägsta prestanda.", "th_TH": "ใช้ตารางหน้าซอฟต์แวร์สำหรับการแปลที่อยู่ ความแม่นยำสูงสุดแต่ประสิทธิภาพช้าที่สุด", "tr_TR": "Adres çevirisi için bir işlemci sayfası kullanır. En yüksek doğruluğu ve en yavaş performansı sunar.", "uk_UA": "Використовує програмну таблицю сторінок для перекладу адрес. Найвища точність, але найповільніша продуктивність.", @@ -16389,7 +14846,6 @@ "pl_PL": "Bezpośrednio mapuj pamięć w przestrzeni adresowej hosta. Znacznie szybsza kompilacja i wykonanie JIT.", "pt_BR": "Mapeia memória no espaço de endereço hóspede diretamente. Compilação e execução do JIT muito mais rápida.", "ru_RU": "Прямая разметка памяти в адресном пространстве хоста. \nЗначительно более быстрые запуск и компиляция JIT.", - "sv_SE": "Direkt mappning av minne i host address space. Mycket snabbare JIT-kompilering och körning.", "th_TH": "แมปหน่วยความจำในพื้นที่ที่อยู่โฮสต์โดยตรง การคอมไพล์และดำเนินการของ JIT เร็วขึ้นมาก", "tr_TR": "Hafızayı doğrudan host adres aralığında tahsis eder. Çok daha hızlı JIT derleme ve işletimi sunar.", "uk_UA": "Пряме відображення пам'яті в адресному просторі хосту. Набагато швидша компіляція та виконання JIT.", @@ -16414,7 +14870,6 @@ "pl_PL": "Bezpośrednio mapuj pamięć, ale nie maskuj adresu w przestrzeni adresowej gościa przed uzyskaniem dostępu. Szybciej, ale kosztem bezpieczeństwa. Aplikacja gościa może uzyskać dostęp do pamięci z dowolnego miejsca w Ryujinx, więc w tym trybie uruchamiaj tylko programy, którym ufasz.", "pt_BR": "Mapeia memória diretamente, mas sem limitar o acesso ao espaço de endereçamento do sistema convidado. Mais rápido, porém menos seguro. O aplicativo convidado pode acessar memória de qualquer parte do Ryujinx, então apenas rode programas em que você confia nesse modo.", "ru_RU": "Производит прямую разметку памяти, но не маскирует адрес в гостевом адресном пространстве перед получением доступа. \nБыстро, но небезопасно. Гостевое приложение может получить доступ к памяти из Ryujinx, поэтому в этом режиме рекомендуется запускать только те программы, которым вы доверяете.", - "sv_SE": "Direkt mappning av minne, men maskera inte adressen inom guest address space innan åtkomst. Snabbare men kostar säkerhet. Gästapplikationen kan komma åt minne från överallt i Ryujinx, så kör endast program som du litar på i detta läge.", "th_TH": "แมปหน่วยความจำโดยตรง แต่อย่าตั้งค่าที่อยู่ของผู้เยี่ยมชมก่อนที่จะเข้าถึง เร็วกว่า แต่ต้องแลกกับความปลอดภัย แอปพลิเคชั่นของผู้เยี่ยมชมสามารถเข้าถึงหน่วยความจำได้จากทุกที่ใน Ryujinx แนะนำให้รันเฉพาะโปรแกรมที่คุณเชื่อถือในโหมดนี้", "tr_TR": "Hafızayı doğrudan tahsis eder, ancak host aralığına erişimden önce adresi maskelemez. Daha iyi performansa karşılık emniyetten ödün verir. Misafir uygulama Ryujinx içerisinden istediği hafızaya erişebilir, bu sebeple bu seçenek ile sadece güvendiğiniz uygulamaları çalıştırın.", "uk_UA": "Пряме відображення пам’яті, але не маскує адресу в гостьовому адресному просторі перед доступом. Швидше, але ціною безпеки. Гостьова програма може отримати доступ до пам’яті з будь-якого місця в Ryujinx, тому запускайте в цьому режимі лише програми, яким ви довіряєте.", @@ -16439,7 +14894,6 @@ "pl_PL": "Użyj Hiperwizora zamiast JIT. Znacznie poprawia wydajność, gdy jest dostępny, ale może być niestabilny w swoim obecnym stanie ", "pt_BR": "Usa o Hypervisor em vez de JIT (recompilador dinâmico). Melhora significativamente o desempenho quando disponível, mas pode ser instável no seu estado atual.", "ru_RU": "Использует Hypervisor вместо JIT. Значительно увеличивает производительность, но может работать нестабильно.", - "sv_SE": "Använd hypervisor istället för JIT. Förbättrar prestandan avsevärt när den finns tillgänglig men kan ge ostabilitet i dess aktuella tillstånd.", "th_TH": "ใช้ Hypervisor แทน JIT ปรับปรุงประสิทธิภาพอย่างมากเมื่อพร้อมใช้งาน แต่อาจไม่เสถียรในสถานะปัจจุบัน", "tr_TR": "JIT yerine Hypervisor kullan. Uygun durumlarda performansı büyük oranda arttırır. Ancak şu anki halinde stabil durumda çalışmayabilir.", "uk_UA": "Використання гіпервізор замість JIT. Значно покращує продуктивність, коли доступний, але може бути нестабільним у поточному стані.", @@ -16462,9 +14916,8 @@ "ko_KR": "Switch 개발 모델을 모방하기 위해 8GB DRAM이 포함된 대체 메모리 모드를 활용합니다.\n\n이는 고해상도 텍스처 팩 또는 4K 해상도 모드에만 유용합니다. 성능을 개선하지 않습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Bruker en alternativ minnemodus med 8GiB i DRAM for og etterligne Switch utvikler modeller.\n\nDette er bare nyttig for teksturpakker eller 4k oppløsningsmoduler. Forbedrer IKKE ytelsen.\n\nLa AV hvis usikker.", "pl_PL": "Wykorzystuje alternatywny układ MemoryMode, aby naśladować model rozwojowy Switcha.\n\nJest to przydatne tylko w przypadku pakietów tekstur o wyższej rozdzielczości lub modów w rozdzielczości 4k. NIE poprawia wydajności.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.", - "pt_BR": "Utiliza um modo de memória alternativo com 6, 8 ou 12 GB de DRAM para imitar um modelo de desenvolvimento do Switch.\n\nIsso só é útil para pacotes de textura de alta resolução ou mods de resolução 4k. NÃO melhora o desempenho.\n\nDeixe em 4 GB se não tiver certeza.", + "pt_BR": "Expande a memória do sistema emulado de 4GiB para 6GiB", "ru_RU": "Использует альтернативный макет MemoryMode для имитации использования Nintendo Switch в режиме разработчика.\n\nПолезно только для пакетов текстур с высоким разрешением или модов добавляющих разрешение 4К. Не улучшает производительность.\n\nРекомендуется оставить выключенным.", - "sv_SE": "Använder ett alternativt minnesläge med 8GiB av DRAM för att efterlikna en utvecklingsmodell av Switch.\n\nDetta är endast användbart för texturpaket med högre upplösning eller moddar för 4k-upplösning. Det förbättrar INTE prestandan.\n\nLämna AV om du är osäker.", "th_TH": "ใช้รูปแบบ MemoryMode ทางเลือกเพื่อเลียนแบบโมเดลการพัฒนาสวิตช์\n\nสิ่งนี้มีประโยชน์สำหรับแพ็กพื้นผิวที่มีความละเอียดสูงกว่าหรือม็อดที่มีความละเอียด 4k เท่านั้น\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Emüle edilen sistem hafızasını 4GiB'dan 6GiB'a yükseltir.\n\nBu seçenek yalnızca yüksek çözünürlük doku paketleri veya 4k çözünürlük modları için kullanılır. Performansı artırMAZ!\n\nEmin değilseniz devre dışı bırakın.", "uk_UA": "Використовує альтернативний макет MemoryMode для імітації моделі розробки Switch.\n\nЦе корисно лише для пакетів текстур з вищою роздільною здатністю або модифікацій із роздільною здатністю 4K. НЕ покращує продуктивність.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -16487,39 +14940,37 @@ "ko_KR": "구현되지 않은 Horizon OS 서비스는 무시됩니다. 특정 게임을 부팅할 때, 발생하는 충돌을 우회하는 데 도움이 될 수 있습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Ignorerer ikke implementerte Horisont OS-tjenester. Dette kan hjelpe med å omgå krasj ved oppstart av enkelte spill.\n\nLa AV hvis du er usikker.", "pl_PL": "Ignoruje niezaimplementowane usługi Horizon OS. Może to pomóc w ominięciu awarii podczas uruchamiania niektórych gier.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.", - "pt_BR": "Ignora serviços não implementados do Horizon OS. Isso pode ajudar a contornar travamentos ao inicializar certos jogos.\n\nDeixe OFF se não tiver certeza.", + "pt_BR": "Habilita ou desabilita a opção de ignorar serviços não implementados", "ru_RU": "Игнорирует нереализованные сервисы Horizon в новых прошивках. Эта настройка поможет избежать вылеты при запуске определенных игр.\n\nРекомендуется оставить выключенным.", - "sv_SE": "Ignorerar Horizon OS-tjänster som inte har implementerats. Detta kan avhjälpa krascher när vissa spel startar upp.\n\nLämna AV om du är osäker.", "th_TH": "ละเว้นบริการ Horizon OS ที่ยังไม่ได้ใช้งาน วิธีนี้อาจช่วยในการหลีกเลี่ยงข้อผิดพลาดเมื่อบูตเกมบางเกม\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Henüz programlanmamış Horizon işletim sistemi servislerini görmezden gelir. Bu seçenek belirli oyunların açılırken çökmesinin önüne geçmeye yardımcı olabilir.\n\nEmin değilseniz devre dışı bırakın.", - "uk_UA": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим якщо не впевнені.", + "uk_UA": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим, якщо не впевнені.", "zh_CN": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用了新的未知系统服务,可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后,则无需开启此选项。\n\n如果不确定,请保持关闭状态。", "zh_TW": "忽略未實現的 Horizon OS 服務。這可能有助於在啟動某些遊戲時避免崩潰。\n\n如果不確定,請保持關閉狀態。" } }, { - "ID": "IgnoreControllerAppletTooltip", + "ID": "IgnoreAppletTooltip", "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "The Controller Applet dialog will not appear if the gamepad is disconnected while an application is running.\n\nLeave OFF if unsure.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.", - "ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.", - "zh_CN": "", - "zh_TW": "" + "ar_SA": "لن يظهر مربع الحوار الخارجي \"تطبيق وحدة التحكم\" إذا تم فصل لوحة الألعاب أثناء اللعب. ولن تظهر مطالبة بإغلاق مربع الحوار أو إعداد وحدة تحكم جديدة. وبمجرد إعادة توصيل وحدة التحكم التي تم فصلها سابقًا، ستستأنف اللعبة تلقائيًا.", + "de_DE": "Der externe Dialog \"Controller-Applet\" wird nicht angezeigt, wenn das Gamepad während des Spiels getrennt wird. Es erfolgt keine Aufforderung, den Dialog zu schließen oder einen neuen Controller einzurichten. Sobald der zuvor getrennte Controller wieder angeschlossen wird, wird das Spiel automatisch fortgesetzt.", + "el_GR": "Το εξωτερικό παράθυρο διαλόγου \"Ελεγκτής μικροεφαρμογής\" δεν θα εμφανιστεί εάν το gamepad αποσυνδεθεί κατά τη διάρκεια του παιχνιδιού. Δεν θα σας ζητηθεί να κλείσετε το παράθυρο διαλόγου ή να ρυθμίσετε έναν νέο ελεγκτή. Μόλις επανασυνδεθεί το χειριστήριο που είχε αποσυνδεθεί προηγουμένως, το παιχνίδι θα συνεχιστεί αυτόματα.", + "en_US": "The external dialog \"Controller Applet\" will not appear if the gamepad is disconnected during gameplay. There will be no prompt to close the dialog or set up a new controller. Once the previously disconnected controller is reconnected, the game will automatically resume.", + "es_ES": "El cuadro de diálogo externo \"Applet del controlador\" no aparecerá si el gamepad se desconecta durante el juego. No aparecerá ningún mensaje para cerrar el cuadro de diálogo o configurar un nuevo controlador. Una vez que se vuelva a conectar el controlador que se había desconectado anteriormente, el juego se reanudará automáticamente.", + "fr_FR": "La boîte de dialogue externe \"Programme Manette\" n'apparaîtra pas si la manette est déconnectée en jeu. Il n'y aura aucune boîte de dialogue ouverte pour configurer une nouvelle manette. Une fois que la manette précédemment déconnectée est reconnectée, le jeu reprendra automatiquement. \n\nLaissez désactivé en cas d'incertitude.", + "he_IL": "תיבת הדו-שיח החיצונית \"Controller Applet\" לא תופיע אם ה-Gamepad מנותק במהלך המשחק. לא תהיה הנחיה לסגור את תיבת הדו-שיח או להגדיר בקר חדש. ברגע שהבקר שנותק בעבר יתחבר מחדש, המשחק יתחדש אוטומטית.", + "it_IT": "La finestra di dialogo esterna \"Controller Applet\" non apparirà se il gamepad viene disconnesso durante il gioco. Non ci sarà alcun prompt per chiudere la finestra di dialogo o impostare un nuovo controller. Una volta che il controller disconnesso in precedenza viene ricollegato, il gioco riprenderà automaticamente.", + "ja_JP": "ゲームプレイ中にゲームパッドが切断された場合、外部ダイアログ「コントローラーアプレット」は表示されません。このダイアログを閉じるか、新しいコントローラーを設定するように求めるプロンプトは表示されません。以前に切断されたコントローラーが再接続されると、ゲームは自動的に再開されます。", + "ko_KR": "게임 플레이 중에 게임패드 연결이 끊어지면 외부 대화 상자 \"컨트롤러 애플릿\"이 나타나지 않습니다. 대화 상자를 닫거나 새 컨트롤러를 설정하라는 메시지가 표시되지 않습니다. 이전에 연결이 끊어진 컨트롤러가 다시 연결되면 게임이 자동으로 다시 시작됩니다.", + "no_NO": "Den eksterne dialogboksen «Controller Applet» vises ikke hvis gamepaden kobles fra under spilling. Du blir ikke bedt om å lukke dialogboksen eller konfigurere en ny kontroller. Når den tidligere frakoblede kontrolleren er koblet til igjen, fortsetter spillet automatisk.", + "pl_PL": "Zewnętrzny dialog \"Controller Applet\" nie pojawi się, jeśli gamepad zostanie odłączony podczas rozgrywki. Nie pojawi się monit o zamknięcie dialogu lub skonfigurowanie nowego kontrolera. Po ponownym podłączeniu poprzednio odłączonego kontrolera gra zostanie automatycznie wznowiona.", + "pt_BR": "O diálogo externo \"Controller Applet\" não aparecerá se o gamepad for desconectado durante o jogo. Não haverá prompt para fechar o diálogo ou configurar um novo controle. Assim que o controle desconectado anteriormente for reconectado, o jogo será retomado automaticamente.", + "ru_RU": "Внешний диалог \"Апплет контроллера\" не появится, если геймпад будет отключен во время игры. Не будет предложено закрыть диалог или настроить новый контроллер. После повторного подключения ранее отключенного контроллера игра автоматически возобновится.", + "th_TH": "กล่องโต้ตอบภายนอก \"แอปเพล็ตตัวควบคุม\" จะไม่ปรากฏขึ้นหากแป้นเกมถูกตัดการเชื่อมต่อระหว่างการเล่นเกม จะไม่มีข้อความแจ้งให้ปิดกล่องโต้ตอบหรือตั้งค่าตัวควบคุมใหม่ เมื่อเชื่อมต่อคอนโทรลเลอร์ที่ตัดการเชื่อมต่อก่อนหน้านี้อีกครั้ง เกมจะดำเนินการต่อโดยอัตโนมัติ", + "tr_TR": "Oyun sırasında oyun kumandasının bağlantısı kesilirse, harici \"Controller Applet\" iletişim kutusu görünmez. İletişim kutusunu kapatma veya yeni bir kumanda ayarlama isteği olmaz. Daha önce bağlantısı kesilen kumanda tekrar bağlandığında oyun otomatik olarak devam eder.", + "uk_UA": "Зовнішнє діалогове вікно \"Аплет контролера\" не з’являтиметься, якщо геймпад буде від’єднано під час гри. Не буде запиту закрити діалогове вікно чи налаштувати новий контролер. Після повторного підключення раніше від’єднаного контролера гра автоматично відновиться.", + "zh_CN": "如果游戏手柄在游戏过程中断开连接,则不会出现外部对话框“控制器小程序”。不会提示关闭对话框或设置新控制器。一旦先前断开连接的控制器重新连接,游戏将自动恢复。", + "zh_TW": "如果遊戲手把在遊戲過程中斷開連接,則外部對話方塊「控制器小程式」將不會出現。不會提示關閉對話方塊或設定新控制器。一旦先前斷開的控制器重新連接,遊戲將自動恢復。" } }, { @@ -16532,17 +14983,16 @@ "es_ES": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.", "fr_FR": "Exécute des commandes du backend graphiques sur un second thread.\n\nAccélère la compilation des shaders, réduit les crashs et les lags, améliore les performances sur les pilotes GPU sans support de multithreading. Légère augementation des performances sur les pilotes avec multithreading intégrer.\n\nRéglez sur Auto en cas d'incertitude.", "he_IL": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", - "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Automatico.", + "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Auto.", "ja_JP": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", "ko_KR": "2번째 스레드에서 그래픽 후단부 명령을 실행합니다.\n\n셰이더 컴파일 속도를 높이고, 끊김 현상을 줄이며, 자체 다중 스레딩 지원 없이 GPU 드라이버의 성능을 향상시킵니다. 다중 스레딩이 있는 드라이버에서 성능이 좀 더 좋습니다.\n\n모르면 자동으로 설정합니다.", "no_NO": "Utfører grafikkbackend kommandoer på en annen tråd.\n\nØker hastigheten for shaderkomprimering, reduserer hakking og forbedrer ytelsen til GPU-drivere uten å spre støtten fra sine egne. Litt bedre ytelse på drivere med flertråd.\n\nSett for å AUTO hvis usikker.", "pl_PL": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.", - "pt_BR": "Executa comandos do renderizador gráfico em um segundo thread.\n\nAcelera a compilação de shader, reduz a gagueira e melhora o desempenho em drivers de GPU sem suporte multithreading próprio. Desempenho ligeiramente melhor em drivers com multithreading.\n\nDefina como AUTO se não tiver certeza.", + "pt_BR": "Habilita multithreading do backend gráfico", "ru_RU": "Выполняет команды графического бэкенда на втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах видеоадаптера без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить Автоматически.", - "sv_SE": "Kör kommandon för grafikbakände i en andra tråd.\n\nSnabbar upp shader compilation, minskar stuttering och förbättrar prestandan på GPU-drivrutiner utan stöd för egen multithreading. Något bättre prestanda på drivrutiner med multithreading.\n\nStäll in till AUTO om du är osäker.", "th_TH": "ดำเนินการคำสั่งแบ็กเอนด์กราฟิกบนเธรดที่สอง\n\nเร่งความเร็วการคอมไพล์ ลดการกระตุก และปรับปรุงประสิทธิภาพการทำงานของไดรเวอร์ GPU โดยไม่ต้องรองรับมัลติเธรดในตัว ประสิทธิภาพที่ดีขึ้นเล็กน้อยสำหรับไดรเวอร์ที่มีมัลติเธรด\n\nตั้งเป็น อัตโนมัติ หากคุณไม่แน่ใจ", "tr_TR": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.", - "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто» якщо не впевнені", + "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто», якщо не впевнені", "zh_CN": "在第二个线程上执行图形引擎指令。\n\n可以加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为“自动”。", "zh_TW": "在第二個執行緒上執行圖形後端指令。\n\n在本身不支援多執行緒的 GPU 驅動程式上,可加快著色器編譯、減少卡頓並提高效能。在支援多執行緒的驅動程式上效能略有提升。\n\n如果不確定,請設定為自動。" } @@ -16557,17 +15007,16 @@ "es_ES": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.", "fr_FR": "Exécute des commandes du backend graphiques sur un second thread.\n\nAccélère la compilation des shaders, réduit les crashs et les lags, améliore les performances sur les pilotes GPU sans support de multithreading. Légère augementation des performances sur les pilotes avec multithreading intégrer.\n\nRéglez sur Auto en cas d'incertitude.", "he_IL": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", - "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Automatico.", + "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Auto.", "ja_JP": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", "ko_KR": "2번째 스레드에서 그래픽 후단부 명령을 실행합니다.\n\n셰이더 컴파일 속도를 높이고 끊김 현상을 줄이며 자체 다중 스레딩 지원 없이 GPU 드라이버의 성능을 향상시킵니다. 다중 스레딩이 있는 드라이버에서 성능이 좀 더 좋습니다.\n\n모르면 자동으로 설정합니다.", "no_NO": "Utfører grafikkbackend kommandoer på en annen tråd.\n\nØker hastigheten for shaderkomprimering, reduserer hakking og forbedrer ytelsen til GPU-drivere uten flertråd støtte. Litt bedre ytelse på drivere med flertråd.\n\nSett for å AUTO hvis usikker.", "pl_PL": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.", - "pt_BR": "Executa comandos do renderizador gráfico em um segundo thread.\n\nAcelera a compilação de shader, reduz a gagueira e melhora o desempenho em drivers de GPU sem suporte multithreading próprio. Desempenho ligeiramente melhor em drivers com multithreading.\n\nDefina como AUTO se não tiver certeza.", + "pt_BR": "Executa comandos do backend gráfico em uma segunda thread. Permite multithreading em tempo de execução da compilação de shader, diminui os travamentos, e melhora performance em drivers sem suporte embutido a multithreading. Pequena variação na performance máxima em drivers com suporte a multithreading. Ryujinx pode precisar ser reiniciado para desabilitar adequadamente o multithreading embutido do driver, ou você pode precisar fazer isso manualmente para ter a melhor performance.", "ru_RU": "Выполняет команды графического бэкенда на втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах видеоадаптера без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить Автоматически.", - "sv_SE": "Kör kommandon för grafikbakände i en andra tråd.\n\nSnabbar upp shader compilation, minskar stuttering och förbättrar prestandan på GPU-drivrutiner utan stöd för egen multithreading. Något bättre prestanda på drivrutiner med multithreading.\n\nStäll in till AUTO om du är osäker.", "th_TH": "ดำเนินการคำสั่งแบ็กเอนด์กราฟิกบนเธรดที่สอง\n\nเร่งความเร็วการคอมไพล์เชเดอร์ ลดการกระตุก และปรับปรุงประสิทธิภาพการทำงานของไดรเวอร์ GPU โดยไม่ต้องรองรับมัลติเธรดในตัว ประสิทธิภาพที่ดีขึ้นเล็กน้อยสำหรับไดรเวอร์ที่มีมัลติเธรด\n\nตั้งเป็น อัตโนมัติ หากคุณไม่แน่ใจ", "tr_TR": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.", - "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\n\nВстановіть значення «Авто» якщо не впевнені.", + "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\n\nВстановіть значення «Авто», якщо не впевнені.", "zh_CN": "在第二个线程上执行图形引擎指令。\n\n可以加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为“自动”。", "zh_TW": "在第二個執行緒上執行圖形後端指令。\n\n在本身不支援多執行緒的 GPU 驅動程式上,可加快著色器編譯、減少卡頓並提高效能。在支援多執行緒的驅動程式上效能略有提升。\n\n如果不確定,請設定為自動。" } @@ -16587,12 +15036,11 @@ "ko_KR": "후속 실행 시 끊김 현상을 줄이는 디스크 셰이더 캐시를 저장합니다.\n\n모르면 켬으로 두세요.", "no_NO": "Lagrer en disk shader cache som reduserer hakking jo flere ganger du spiller.\n\nLa være PÅ om usikker.", "pl_PL": "Zapisuje pamięć podręczną shaderów na dysku, co zmniejsza zacinanie się w kolejnych uruchomieniach.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Salva um cache de shader no disco que reduz a trepidação em execuções subsequentes.\n\nDeixe LIGADO se não tiver certeza.", + "pt_BR": "Habilita ou desabilita o cache de shader", "ru_RU": "Сохраняет кэш шейдеров на диске, для уменьшения статтеров при последующих запусках.\n\nРекомендуется оставить включенным.", - "sv_SE": "Sparar en disk shader cache som minskar stuttering i efterföljande körningar.\n\nLämna PÅ om du är osäker.", "th_TH": "บันทึกแคชแสงเงาของดิสก์ซึ่งช่วยลดการกระตุกในการรันครั้งต่อๆ ไป\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Sonraki çalışmalarda takılmaları engelleyen bir gölgelendirici disk önbelleğine kaydeder.", - "uk_UA": "Зберігає кеш дискового шейдера, що зменшує затримки під час наступних запусків.\n\nЗалиште увімкненим якщо не впевнені.", + "uk_UA": "Зберігає кеш дискового шейдера, що зменшує затримки під час наступних запусків.\n\nЗалиште увімкненим, якщо не впевнені.", "zh_CN": "模拟器将已编译的着色器保存到硬盘,可以减少游戏再次渲染相同图形导致的卡顿。\n\n如果不确定,请保持开启状态。", "zh_TW": "儲存磁碟著色器快取,減少後續執行時的卡頓。\n\n如果不確定,請保持開啟狀態。" } @@ -16607,14 +15055,13 @@ "es_ES": "Multiplica la resolución de rendereo del juego.\n\nAlgunos juegos podrían no funcionar con esto y verse pixelado al aumentar la resolución; en esos casos, quizás sería necesario buscar mods que de anti-aliasing o que aumenten la resolución interna. Para usar este último, probablemente necesitarás seleccionar Nativa.\n\nEsta opción puede ser modificada mientras que un juego este corriendo haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nTener en cuenta que 4x es excesivo para prácticamente cualquier configuración.", "fr_FR": "Multiplie la résolution de rendu du jeu.\n\nQuelques jeux peuvent ne pas fonctionner avec cette fonctionnalité et sembler pixelisés même lorsque la résolution est augmentée ; pour ces jeux, vous devrez peut-être trouver des mods qui suppriment l'anti-aliasing ou qui augmentent leur résolution de rendu interne. Pour utiliser cette dernière option, vous voudrez probablement sélectionner \"Natif\".\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres sur le côté et expérimenter jusqu'à ce que vous trouviez l'apparence souhaitée pour un jeu.\n\nGardez à l'esprit que 4x est excessif pour pratiquement n'importe quelle configuration.", "he_IL": "", - "it_IT": "Moltiplica la risoluzione di rendering del gioco.\n\nAlcuni giochi potrebbero non funzionare con questa opzione e sembrare pixelati anche quando la risoluzione è aumentata; per quei giochi, potrebbe essere necessario trovare mod che rimuovono l'anti-aliasing o che aumentano la risoluzione di rendering interna. Per quest'ultimo caso, probabilmente dovrai selezionare Nativo (1x).\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito.\n\nTieni presente che \"4x\" è eccessivo per praticamente qualsiasi configurazione.", + "it_IT": "Moltiplica la risoluzione di rendering del gioco.\n\nAlcuni giochi potrebbero non funzionare con questa opzione e sembrare pixelati anche quando la risoluzione è aumentata; per quei giochi, potrebbe essere necessario trovare mod che rimuovono l'anti-aliasing o che aumentano la risoluzione di rendering interna. Per quest'ultimo caso, probabilmente dovrai selezionare Nativo (1x).\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nTenete a mente che 4x è troppo per praticamente qualsiasi configurazione.", "ja_JP": "ゲームのレンダリング解像度倍率を設定します.\n\n解像度を上げてもピクセルのように見えるゲームもあります. そのようなゲームでは, アンチエイリアスを削除するか, 内部レンダリング解像度を上げる mod を見つける必要があるかもしれません. その場合, ようなゲームでは、ネイティブを選択してください.\n\nこのオプションはゲーム実行中に下の「適用」をクリックすることで変更できます. 設定ウィンドウを脇に移動して, ゲームが好みの表示になるよう試してみてください.\n\nどのような設定でも, \"4x\" はやり過ぎであることを覚えておいてください.", "ko_KR": "게임의 렌더링 해상도를 배가시킵니다.\n\n일부 게임에서는 이 기능이 작동하지 않고 해상도가 높아져도 픽셀화되어 보일 수 있습니다. 해당 게임의 경우 앤티 앨리어싱을 제거하거나 내부 렌더링 해상도를 높이는 모드를 찾아야 할 수 있습니다. 후자를 사용하려면 기본을 선택하는 것이 좋습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임이 실행되는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮기고 원하는 게임 모양을 찾을 때까지 실험해 보세요.\n\n4배는 거의 모든 설정에서 과하다는 점을 명심하세요.", "no_NO": "Dobler spillets gjengivelse.\n\nNoen få spill fungerer kanskje ikke med dette aktivert og kan se veldig pikselert ut selv når gjengivelsen er økt; for de spillene, så kan det hende du må bruke modifikasjoner som fjerner anti-aliasing eller som øker den interne gjengivelsen. For og bruke sistnenvte, så vil du helst bruke \"Native\".\n\nHa til tanke at 4x er unødig for virituelt alle maskiner.", "pl_PL": "", "pt_BR": "Multiplica a resolução de renderização do jogo.\n\nAlguns jogos podem não funcionar bem com essa opção e apresentar uma aparência pixelada, mesmo com o aumento da resolução; para esses jogos, talvez seja necessário encontrar mods que removam o anti-aliasing ou aumentem a resolução de renderização interna. Ao usar a segunda opção, provavelmente desejará selecionar Nativa.\n\nEssa opção pode ser alterada enquanto um jogo está em execução, clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nLembre-se de que 4x é exagerado para praticamente qualquer configuração.", - "ru_RU": "Увеличивает разрешение рендера игры.\n\nНекоторые игры могут не работать с этой настройкой и выглядеть смазано даже когда разрешение увеличено. Для таких игр может потребоваться установка модов, которые убирают сглаживание или увеличивают разрешение рендеринга. \nДля использования последнего, вам нужно будет выбрать опцию «Нативное».\n\nЭта опция может быть изменена во время игры по нажатию кнопки «Применить» ниже. Вы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nИмейте в виду, что «4x» является излишеством.", - "sv_SE": "Multiplicerar spelets renderingsupplösning.\n\nNågra spel kanske inte fungerar med detta och ser pixelerade ut även när upplösningen ökas; för dessa spel så kan du behöva hitta moddar som tar bort anti-aliasing eller som ökar deras interna renderingsupplösning. För att använda det senare, kommer du sannolikt vilja välja Inbyggd.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nTänk på att 4x är overkill för praktiskt taget alla maskiner.", + "ru_RU": "Увеличивает разрешение рендера игры.\n\nНекоторые игры могут не работать с этой настройкой и выглядеть смазано даже когда разрешение увеличено. Для таких игр может потребоваться установка модов, которые убирают сглаживание или увеличивают разрешение рендеринга. \nДля использования последнего, вам нужно будет выбрать опцию \"Нативное\".\n\nЭта опция может быть изменена во время игры по нажатию кнопки \"Применить\" ниже. Вы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nИмейте в виду, что \"4x\" является излишеством.", "th_TH": "คูณความละเอียดการเรนเดอร์ของเกม\n\nเกมบางเกมอาจไม่สามารถใช้งานได้และดูเป็นพิกเซลแม้ว่าความละเอียดจะเพิ่มขึ้นก็ตาม สำหรับเกมเหล่านั้น คุณอาจต้องค้นหาม็อดที่ลบรอยหยักของภาพหรือเพิ่มความละเอียดในการเรนเดอร์ภายใน หากต้องการใช้อย่างหลัง คุณอาจต้องเลือก Native\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำมาใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nโปรดทราบว่า 4x นั้นเกินความจำเป็นสำหรับการตั้งค่าแทบทุกประเภท", "tr_TR": "", "uk_UA": "Множить роздільну здатність гри.\n\nДеякі ігри можуть не працювати з цією функцією, і виглядатимуть піксельними; для цих ігор треба знайти модифікації, що зупиняють згладжування або підвищують роздільну здатність. Для останніх модифікацій, вибирайте \"Native\".\n\nЦей параметр можна міняти коли гра запущена кліком на \"Застосувати\"; ви можете перемістити вікно налаштувань і поекспериментувати з видом гри.\n\nМайте на увазі, що 4x це занадто для будь-якого комп'ютера.", @@ -16632,14 +15079,13 @@ "es_ES": "Escalado de resolución de coma flotante, como por ejemplo 1,5. Los valores no íntegros pueden causar errores gráficos o crashes.", "fr_FR": "Échelle de résolution à virgule, telle que : 1.5. Les échelles non intégrales sont plus susceptibles de causer des problèmes ou des crashs.", "he_IL": "שיפור רזולוציית נקודה צפה, כגון 1.5. הוא שיפור לא אינטגרלי הנוטה לגרום יותר בעיות או להקריס.", - "it_IT": "Scala della risoluzione in virgola mobile, come 1,5. I valori non interi hanno maggiori probabilità di causare problemi o arresti anomali.", + "it_IT": "Scala della risoluzione in virgola mobile, come 1,5. Le scale non integrali hanno maggiori probabilità di causare problemi o crash.", "ja_JP": "1.5 のような整数でない倍率を指定すると,問題が発生したりクラッシュしたりする場合があります.", "ko_KR": "부동 소수점 해상도 스케일(예: 1.5)입니다. 적분이 아닌 스케일은 문제나 충돌을 일으킬 가능성이 높습니다.", "no_NO": "Det er mer sannsynlig at flytende punktoppløsning skalaer som 1.5. Ikke-integrerte skalaer forårsaker problemer eller krasj.", "pl_PL": "Skala rozdzielczości zmiennoprzecinkowej, np. 1,5. Skale niecałkowite częściej powodują problemy lub awarie.", "pt_BR": "Escala de resolução de ponto flutuante, como 1.5. Valores não inteiros tem probabilidade maior de causar problemas ou quebras.", "ru_RU": "Масштабирование разрешения с плавающей запятой, например 1,5. Неинтегральное масштабирование с большой вероятностью вызовет сбои в работе.", - "sv_SE": "Skala för floating point resolution, såsom 1.5. Icke-heltalsskalor är mer benägna att orsaka problem eller krasch.", "th_TH": "สเกลความละเอียดจุดทศนิยม เช่น 1.5 ไม่ใช่จำนวนเต็มของสเกล มีแนวโน้มที่จะก่อให้เกิดปัญหาหรือความผิดพลาดได้", "tr_TR": "Küsüratlı çözünürlük ölçeği, 1.5 gibi. Küsüratlı ölçekler hata oluşturmaya ve çökmeye daha yatkındır.", "uk_UA": "Масштаб роздільної здатності з плаваючою комою, наприклад 1,5. Не інтегральні масштаби, швидше за все, спричинять проблеми або збій.", @@ -16657,17 +15103,16 @@ "es_ES": "Nivel de filtrado anisotrópico. Setear en Auto para utilizar el valor solicitado por el juego.", "fr_FR": "Niveau de filtrage anisotrope. Réglez sur Auto pour utiliser la valeur demandée par le jeu.", "he_IL": "", - "it_IT": "Livello del filtro anisotropico. Imposta su Automatico per usare il valore richiesto dal gioco.", + "it_IT": "Livello del filtro anisotropico. Imposta su Auto per usare il valore richiesto dal gioco.", "ja_JP": "異方性フィルタリングのレベルです. ゲームが要求する値を使用する場合は「自動」を設定してください.", "ko_KR": "이방성 필터링 수준입니다. 게임에서 요청한 값을 사용하려면 자동으로 설정하세요.", "no_NO": "Nivå av Anisotropisk filtrering. Sett til Auto for å bruke verdien som kreves av spillet.", "pl_PL": "", "pt_BR": "Nível de Filtragem Anisotrópica. Defina como Automático para usar o valor solicitado pelo jogo.", "ru_RU": "Уровень анизотропной фильтрации. \n\nУстановите значение Автоматически, чтобы использовать значение по умолчанию игры.", - "sv_SE": "Nivå av anisotropisk filtrering. Ställ in till Automatiskt för att använda det värde som begärts av spelet.", "th_TH": "ระดับของ Anisotropic ตั้งค่าเป็นอัตโนมัติเพื่อใช้ค่าพื้นฐานของเกม", "tr_TR": "", - "uk_UA": "Рівень анізотропної фільтрації. Встановіть «Авто», щоб використовувати значення яке вимагає гра.", + "uk_UA": "Рівень анізотропної фільтрації. Встановіть на «Авто», щоб використовувати значення, яке вимагає гра.", "zh_CN": "各向异性过滤等级,可以提高倾斜视角纹理的清晰度。\n当设置为“自动”时,使用游戏自身设定的等级。", "zh_TW": "各向異性過濾等級。設定為自動可使用遊戲要求的值。" } @@ -16680,7 +15125,7 @@ "el_GR": "", "en_US": "Aspect Ratio applied to the renderer window.\n\nOnly change this if you're using an aspect ratio mod for your game, otherwise the graphics will be stretched.\n\nLeave on 16:9 if unsure.", "es_ES": "Relación de aspecto aplicada a la ventana del renderizador.\n\nSolamente modificar esto si estás utilizando un mod de relación de aspecto para su juego, en cualquier otro caso los gráficos se estirarán.\n\nDejar en 16:9 si no sabe que hacer.", - "fr_FR": "Format\u00A0d'affichage appliqué à la fenêtre du moteur de rendu.\n\nChangez cela uniquement si vous utilisez un mod changeant le format\u00A0d'affichage pour votre jeu, sinon les graphismes seront étirés.\n\nLaissez sur 16:9 si vous n'êtes pas sûr.", + "fr_FR": "Format d'affichage appliqué à la fenêtre du moteur de rendu.\n\nChangez cela uniquement si vous utilisez un mod changeant le format d'affichage pour votre jeu, sinon les graphismes seront étirés.\n\nLaissez sur 16:9 si vous n'êtes pas sûr.", "he_IL": "", "it_IT": "Proporzioni dello schermo applicate alla finestra di renderizzazione.\n\nCambialo solo se stai usando una mod di proporzioni per il tuo gioco, altrimenti la grafica verrà allungata.\n\nLasciare il 16:9 se incerto.", "ja_JP": "レンダリングウインドウに適用するアスペクト比です.\n\nゲームにアスペクト比を変更する mod を使用している場合のみ変更してください.\n\nわからない場合は16:9のままにしておいてください.\n", @@ -16689,10 +15134,9 @@ "pl_PL": "", "pt_BR": "Proporção de Tela aplicada à janela do renderizador.\n\nAltere isso apenas se estiver usando um mod de proporção para o seu jogo; caso contrário, os gráficos ficarão esticados.\n\nMantenha em 16:9 se estiver em dúvida.", "ru_RU": "Соотношение сторон окна рендерера.\n\nИзмените эту настройку только если вы используете мод для соотношения сторон, иначе изображение будет растянуто.\n\nРекомендуется настройка 16:9.", - "sv_SE": "Bildförhållande att appliceras på renderarfönstret.\n\nÄndra endast detta om du använder en modd för bildförhållande till ditt spel, annars kommer grafiken att sträckas ut.\n\nLämna den till 16:9 om du är osäker.", "th_TH": "อัตราส่วนภาพที่ใช้กับหน้าต่างตัวแสดงภาพ\n\nเปลี่ยนสิ่งนี้หากคุณใช้ตัวดัดแปลงอัตราส่วนกว้างยาวสำหรับเกมของคุณ ไม่เช่นนั้นกราฟิกจะถูกยืดออก\n\nทิ้งไว้ที่ 16:9 หากไม่แน่ใจ", "tr_TR": "", - "uk_UA": "Співвідношення сторін застосовано до вікна рендера.\n\nМіняйте тільки, якщо використовуєте модифікацію співвідношення сторін для гри, інакше зображення буде розтягнутим.\n\nЗалиште на \"16:9\", якщо не впевнені.", + "uk_UA": "Співвідношення сторін застосовано до вікна рендера.\n\nМіняйте тільки, якщо використовуєте модифікацію співвідношення сторін для гри, інакше графіка буде розтягнута.\n\nЗалиште на \"16:9\", якщо не впевнені.", "zh_CN": "游戏渲染窗口的宽高比。\n\n只有当游戏使用了修改宽高比的 MOD 时才需要修改这个设置,否则图像会被拉伸。\n\n如果不确定,请保持为“16:9”。", "zh_TW": "套用於繪製器視窗的長寬比。\n\n只有在遊戲中使用長寬比模組時才可變更,否則圖形會被拉伸。\n\n如果不確定,請保持 16:9 狀態。" } @@ -16712,12 +15156,11 @@ "ko_KR": "그래픽 셰이더 덤프 경로", "no_NO": "Grafikk Shader Dump bane", "pl_PL": "Ścieżka Zrzutu Shaderów Grafiki", - "pt_BR": "Diretório de Despejo de Shaders", + "pt_BR": "Diretòrio de despejo de shaders", "ru_RU": "Путь с дампами графических шейдеров", - "sv_SE": "Sökväg för Graphics Shaders Dump", "th_TH": "ที่เก็บ ดัมพ์ไฟล์เชเดอร์", "tr_TR": "Grafik Shader Döküm Yolu", - "uk_UA": "Шлях до дампу графічних шейдерів", + "uk_UA": "Шлях скидання графічних шейдерів", "zh_CN": "转储图形着色器的路径", "zh_TW": "圖形著色器傾印路徑" } @@ -16737,12 +15180,11 @@ "ko_KR": "디스크의 로그 파일에 콘솔 기록을 저장합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Lagrer konsoll-logging til en loggfil på harddisken. Påvirker ikke ytelsen.", "pl_PL": "Zapisuje logowanie konsoli w pliku dziennika na dysku. Nie wpływa na wydajność.", - "pt_BR": "Salva o log do console em um arquivo de log no disco. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita log para um arquivo no disco", "ru_RU": "Включает ведение журнала в файл на диске. Не влияет на производительность.", - "sv_SE": "Sparar konsolloggning till en loggfil på disk. Påverkar inte prestandan.", "th_TH": "บันทึกประวัติคอนโซลลงในไฟล์บันทึก จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Konsol loglarını diskte bir log dosyasına kaydeder. Performansı etkilemez.", - "uk_UA": "Зберігає консольне ведення журналу у файл на диску. Не впливає на продуктивність.", + "uk_UA": "Зберігає журнал консолі у файл журналу на диску. Не впливає на продуктивність.", "zh_CN": "将控制台日志保存到硬盘文件,不影响性能。", "zh_TW": "將控制台日誌儲存到磁碟上的日誌檔案中。不會影響效能。" } @@ -16762,12 +15204,11 @@ "ko_KR": "콘솔에 조각 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut log meldinger i konsollen. Påvirker ikke ytelsen.", "pl_PL": "Wyświetla w konsoli skrótowe komunikaty dziennika. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log stub no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens de stub", "ru_RU": "Включает ведение журнала-заглушки. Не влияет на производительность.", - "sv_SE": "Skriver ut stubbloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Stub log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Відображає повідомлення журналу-заглушки (tub log) в консолі. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення журналу-заглушки на консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示存根日志,不影响性能。", "zh_TW": "在控制台中輸出日誌訊息。不會影響效能。" } @@ -16787,12 +15228,11 @@ "ko_KR": "콘솔에 정보 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut info loggmeldinger i konsollen. Påvirker ikke ytelse.", "pl_PL": "Wyświetla komunikaty dziennika informacyjnego w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log de informações no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens informativas", "ru_RU": "Включает вывод сообщений информационного журнала в консоль. Не влияет на производительность.", - "sv_SE": "Skriver ut informationsloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความบันทึกข้อมูลในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Bilgi log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Виводить повідомлення журналу інформації (info log) в консоль. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення інформаційного журналу на консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示信息日志,不影响性能。", "zh_TW": "在控制台中輸出資訊日誌訊息。不會影響效能。" } @@ -16812,12 +15252,11 @@ "ko_KR": "콘솔에 경고 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut varselloggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika ostrzeżeń w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log de aviso no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens de alerta", "ru_RU": "Включает вывод сообщений журнала предупреждений в консоль. Не влияет на производительность.", - "sv_SE": "Skriver ut varningsloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติการเตือนในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Uyarı log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Додає повідомлення журналу попереджень (warning log) до консолі. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення журналу попереджень у консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示警告日志,不影响性能。", "zh_TW": "在控制台中輸出警告日誌訊息。不會影響效能。" } @@ -16837,12 +15276,11 @@ "ko_KR": "콘솔에 오류 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut feilloggmeldinger i konsollen. Påvirker ikke ytelse.", "pl_PL": "Wyświetla w konsoli komunikaty dziennika błędów. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log de erro no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens de erro", "ru_RU": "Включает вывод сообщений журнала ошибок. Не влияет на производительность.", - "sv_SE": "Skriver ut felloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความบันทึกข้อผิดพลาดในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Hata log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Додає повідомлення журналу помилок (error log) до консолі. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення журналу помилок у консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示错误日志,不影响性能。", "zh_TW": "在控制台中輸出錯誤日誌訊息。不會影響效能。" } @@ -16862,12 +15300,11 @@ "ko_KR": "콘솔에 추적 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut sporbare loggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika śledzenia w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log de rastreamento no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens de rastreamento", "ru_RU": "Выводит сообщения журнала трассировки в консоли. Не влияет на производительность.", - "sv_SE": "Skriver ut spårloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติการติดตามในคอนโซล ไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Trace log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Додає повідомлення журналу трасування (trace log) до консолі. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення журналу трасування на консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示跟踪日志。", "zh_TW": "在控制台中輸出追蹤日誌訊息。不會影響效能。" } @@ -16887,12 +15324,11 @@ "ko_KR": "콘솔에 게스트 로그 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut gjesteloggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika gości w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Imprime mensagens de log do convidado no console. Não afeta o desempenho.", + "pt_BR": "Habilita ou desabilita exibição de mensagens do programa convidado", "ru_RU": "Включает вывод сообщений гостевого журнала. Не влияет на производительность.", - "sv_SE": "Skriver ut gästloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติของผู้เยี่ยมชมในคอนโซล ไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Guest log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Додає повідомлення журналу гостей (guest log) до консолі. Не впливає на продуктивність.", + "uk_UA": "Друкує повідомлення журналу гостей у консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示访客日志,不影响性能。", "zh_TW": "在控制台中輸出客體日誌訊息。不會影響效能。" } @@ -16912,12 +15348,11 @@ "ko_KR": "콘솔에 파일 접속 기록 메시지를 출력합니다.", "no_NO": "Skriver ut filtilgang til loggmeldinger i konsollen.", "pl_PL": "Wyświetla w konsoli komunikaty dziennika dostępu do plików.", - "pt_BR": "Imprime mensagens de log de acesso a arquivos no console.", + "pt_BR": "Habilita ou desabilita exibição de mensagens do acesso de arquivos", "ru_RU": "Включает вывод сообщений журнала доступа к файлам.", - "sv_SE": "Skriver ut loggmeddelanden för filåtkomst i konsollen.", "th_TH": "พิมพ์ข้อความบันทึกการเข้าถึงไฟล์ในคอนโซล", "tr_TR": "Dosya sistemi erişim log mesajlarını konsola yazdırır.", - "uk_UA": "Виводить повідомлення журналу доступу (access log) до файлів в консоль.", + "uk_UA": "Друкує повідомлення журналу доступу до файлів у консолі.", "zh_CN": "在控制台中显示文件访问日志。", "zh_TW": "在控制台中輸出檔案存取日誌訊息。" } @@ -16937,12 +15372,11 @@ "ko_KR": "콘솔에 파일 시스템 접속 기록 출력을 활성화합니다. 가능한 모드는 0-3", "no_NO": "Aktiverer FS tilgang loggutgang til konsollen. Mulige moduser er 0-3", "pl_PL": "Włącza wyjście dziennika dostępu FS do konsoli. Możliwe tryby to 0-3", - "pt_BR": "Habilita a saída do log de acesso FS para o console. Os modos possíveis são 0-3", + "pt_BR": "Habilita exibição de mensagens de acesso ao sistema de arquivos no console. Modos permitidos são 0-3", "ru_RU": "Включает вывод журнала доступа к файловой системе. Возможные режимы: 0-3", - "sv_SE": "Aktiverar loggutdata för filsystemsåtkomst i konsollen. Möjliga lägen är 0-3", "th_TH": "เปิดใช้งาน เอาต์พุตประวัติการเข้าถึง FS ไปยังคอนโซล โหมดที่เป็นไปได้คือ 0-3", "tr_TR": "Konsola FS erişim loglarının yazılmasını etkinleştirir. Kullanılabilir modlar 0-3'tür", - "uk_UA": "Увімкнути виведення журналу доступу (access log) до файлової системи в консоль. Можливі режими: 0-3", + "uk_UA": "Вмикає виведення журналу доступу до FS на консоль. Можливі режими 0-3", "zh_CN": "在控制台中显示文件系统访问日志,可选模式为 0-3。", "zh_TW": "啟用檔案系統存取日誌輸出到控制台中。可能的模式為 0 到 3" } @@ -16957,46 +15391,20 @@ "es_ES": "Usar con cuidado", "fr_FR": "À utiliser avec précaution", "he_IL": "השתמש בזהירות", - "it_IT": "Usa con cautela", + "it_IT": "Usa con attenzione", "ja_JP": "使用上の注意", "ko_KR": "주의해서 사용", "no_NO": "Bruk med forsiktighet", "pl_PL": "Używaj ostrożnie", "pt_BR": "Use com cuidado", "ru_RU": "Используйте с осторожностью", - "sv_SE": "Använd med försiktighet", "th_TH": "โปรดใช้ด้วยความระมัดระวัง", "tr_TR": "Dikkatli kullanın", - "uk_UA": "Використовувати обережно", + "uk_UA": "Використовуйте з обережністю", "zh_CN": "请谨慎使用", "zh_TW": "謹慎使用" } }, - { - "ID": "AvaloniaLogTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Prints Avalonia (UI) log messages in the console.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Skriver ut Avalonia (UI)-loggmeldinger i konsollen.", - "pl_PL": "", - "pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.", - "ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль", - "zh_CN": "在控制台显示 Avalonia (UI) 的日志信息", - "zh_TW": "" - } - }, { "ID": "OpenGlLogLevel", "Translations": { @@ -17012,12 +15420,11 @@ "ko_KR": "적절한 기록 수준이 활성화되어 있어야 함", "no_NO": "Krever riktige loggnivåer aktivert", "pl_PL": "Wymaga włączonych odpowiednich poziomów logów", - "pt_BR": "Requer níveis de log apropriados habilitados", + "pt_BR": "Requer que os níveis de log apropriados estejaam habilitados", "ru_RU": "Требует включения соответствующих уровней ведения журнала", - "sv_SE": "Kräver att lämpliga loggnivåer aktiveras", "th_TH": "จำเป็นต้องเปิดใช้งานระดับบันทึกที่เหมาะสม", "tr_TR": "Uygun log seviyesinin aktif olmasını gerektirir", - "uk_UA": "Потрібно увімкнути відповідні рівні журналу (log)", + "uk_UA": "Потрібно увімкнути відповідні рівні журналу", "zh_CN": "需要启用适当的日志级别", "zh_TW": "需要啟用適當的日誌等級" } @@ -17037,12 +15444,11 @@ "ko_KR": "콘솔에 디버그 기록 메시지를 출력합니다.\n\n담당자가 특별히 요청한 경우에만 이 기능을 사용하십시오. 로그를 읽기 어렵게 만들고 에뮬레이터 성능을 저하시킬 수 있기 때문입니다.", "no_NO": "Skriver ut loggmeldinger i konsollen.\n\nBruk bare dette hvis et medlem har gitt spesifikke instruksjoner, siden det vil gjøre loggene vanskelig å lese og forverre emulatorytelse.", "pl_PL": "Wyświetla komunikaty dziennika debugowania w konsoli.\n\nUżywaj tego tylko na wyraźne polecenie członka załogi, ponieważ utrudni to odczytanie dzienników i pogorszy wydajność emulatora.", - "pt_BR": "Imprime mensagens de log de depuração no console.\n\nUse isso somente se for especificamente instruído por um membro da equipe, pois isso tornará os logs difíceis de ler e piorará o desempenho do emulador.", + "pt_BR": "Habilita exibição de mensagens de depuração", "ru_RU": "Выводит журнал сообщений отладки в консоли.\n\nИспользуйте только в случае просьбы разработчика, так как включение этой функции затруднит чтение журналов и ухудшит работу эмулятора.", - "sv_SE": "Skriver ut felsökningsloggmeddelanden i konsolen.\n\nAnvänd endast detta om det är specifikt instruerat av en medarbetare, eftersom det kommer att göra loggar svåra att läsa och försämra emulatorprestanda.", "th_TH": "พิมพ์ข้อความประวัติการแก้ไขข้อบกพร่องในคอนโซล\n\nใช้สิ่งนี้เฉพาะเมื่อได้รับคำแนะนำจากผู้ดูแลเท่านั้น เนื่องจากจะทำให้บันทึกอ่านยากและทำให้ประสิทธิภาพของโปรแกรมจำลองแย่ลง", "tr_TR": "Debug log mesajlarını konsola yazdırır.\n\nBu seçeneği yalnızca geliştirici üyemiz belirtirse aktifleştirin, çünkü bu seçenek log dosyasını okumayı zorlaştırır ve emülatörün performansını düşürür.", - "uk_UA": "Виводить повідомлення журналу налагодження в консолі.\n\nВикористовуйте лише за спеціальною вказівкою розробника, оскільки увімкнення цього параметру ускладнить читання журналів (logs) і погіршить роботу емулятора.", + "uk_UA": "Друкує повідомлення журналу налагодження на консолі.\n\nВикористовуйте це лише за спеціальною вказівкою співробітника, оскільки це ускладнить читання журналів і погіршить роботу емулятора.", "zh_CN": "在控制台中显示调试日志。\n\n仅在特别需要时使用此功能,因为它会导致日志信息难以阅读,并降低模拟器性能。", "zh_TW": "在控制台中輸出偵錯日誌訊息。\n\n只有在人員特別指示的情況下才能使用,因為這會導致日誌難以閱讀,並降低模擬器效能。" } @@ -17057,17 +15463,16 @@ "es_ES": "Abre el explorador de archivos para elegir un archivo compatible con Switch para cargar", "fr_FR": "Ouvre l'explorateur de fichiers pour choisir un fichier compatible Switch à charger", "he_IL": "פתח סייר קבצים כדי לבחור קובץ תואם סוויץ' לטעינה", - "it_IT": "Apri un selettore file per scegliere un file compatibile con Switch da caricare", + "it_IT": "Apri un file explorer per scegliere un file compatibile Switch da caricare", "ja_JP": "ロードする Switch 互換のファイルを選択するためファイルエクスプローラを開きます", "ko_KR": "파일 탐색기를 열어 불러올 Switch 호환 파일을 선택", "no_NO": "Åpne filutforsker for å velge en Switch kompatibel fil å laste", "pl_PL": "Otwórz eksplorator plików, aby wybrać plik kompatybilny z Switch do wczytania", - "pt_BR": "Abre um explorador de arquivos para escolher um arquivo compatível com o Switch para carregar", + "pt_BR": "Abre o navegador de arquivos para seleção de um arquivo do Switch compatível a ser carregado", "ru_RU": "Открывает файловый менеджер для выбора файла, совместимого с Nintendo Switch.", - "sv_SE": "Öppna en filutforskare för att välja en Switch-kompatibel fil att läsa in", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกไฟล์ที่เข้ากันได้กับ Switch ที่จะโหลด", "tr_TR": "Switch ile uyumlu bir dosya yüklemek için dosya tarayıcısını açar", - "uk_UA": "Відкриває Файловий провідник, щоб обрати для завантаження сумісний зі Switch файл", + "uk_UA": "Відкриває файловий провідник, щоб вибрати для завантаження сумісний файл Switch", "zh_CN": "选择 Switch 游戏文件并加载", "zh_TW": "開啟檔案總管,選擇與 Switch 相容的檔案來載入" } @@ -17082,17 +15487,16 @@ "es_ES": "Abre el explorador de archivos para elegir un archivo desempaquetado y compatible con Switch para cargar", "fr_FR": "Ouvre l'explorateur de fichiers pour choisir une application Switch compatible et décompressée à charger", "he_IL": "פתח סייר קבצים כדי לבחור יישום תואם סוויץ', לא ארוז לטעינה.", - "it_IT": "Apri un selettore file per scegliere un'applicazione estratta compatibile con Switch da caricare", + "it_IT": "Apri un file explorer per scegliere un file compatibile Switch, applicazione sfusa da caricare", "ja_JP": "ロードする Switch 互換の展開済みアプリケーションを選択するためファイルエクスプローラを開きます", "ko_KR": "Switch와 호환되는 압축 해제된 앱을 선택하여 불러오려면 파일 탐색기를 엽니다.", "no_NO": "Åpne en filutforsker for å velge en Switch kompatibel, upakket applikasjon for å laste", "pl_PL": "Otwórz eksplorator plików, aby wybrać zgodną z Switch, rozpakowaną aplikację do załadowania", - "pt_BR": "Abre um explorador de arquivos para escolher um aplicativo descompactado compatível com o Switch para carregar", + "pt_BR": "Abre o navegador de pastas para seleção de pasta extraída do Switch compatível a ser carregada", "ru_RU": "Открывает файловый менеджер для выбора распакованного приложения, совместимого с Nintendo Switch.", - "sv_SE": "Öppna en filutforskare för att välja en Switch-kompatibel, uppackad applikation att läsa in", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกไฟล์ที่เข้ากันได้กับ Switch ที่จะโหลด", "tr_TR": "Switch ile uyumlu ayrıştırılmamış bir uygulama yüklemek için dosya tarayıcısını açar", - "uk_UA": "Відкриває Файловий провідник, щоб обрати сумісну зі Switch розпаковану програму для завантаження", + "uk_UA": "Відкриває файловий провідник, щоб вибрати сумісну з комутатором розпаковану програму для завантаження", "zh_CN": "选择解包后的 Switch 游戏目录并加载", "zh_TW": "開啟檔案總管,選擇與 Switch 相容且未封裝的應用程式來載入" } @@ -17107,18 +15511,17 @@ "es_ES": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar DLC de forma masiva", "fr_FR": "Ouvre l'explorateur de fichier pour choisir un ou plusieurs dossiers duquel charger les DLC", "he_IL": "", - "it_IT": "Apri un selettore file per scegliere una o più cartelle dalle quali caricare DLC in blocco", + "it_IT": "Apri un esploratore file per scegliere una o più cartelle dalle quali caricare DLC in massa", "ja_JP": "", "ko_KR": "파일 탐색기를 열어 DLC를 일괄 불러오기할 폴더를 하나 이상 선택", "no_NO": "Åpne en filutforsker for å velge en eller flere mapper å laste inn DLC fra", "pl_PL": "", - "pt_BR": "Abre um explorador de arquivos para escolher uma ou mais pastas para carregar DLC em massa", - "ru_RU": "Открывает проводник, для выбора одной или нескольких папок для массовой загрузки DLC", - "sv_SE": "Öppna en filutforskare för att välja en eller flera mappar att läsa in alla DLC från", + "pt_BR": "", + "ru_RU": "", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลด DLC จำนวนมาก", "tr_TR": "", - "uk_UA": "Відкриває Файловий провідник для обрання однієї або декількох тек для масового завантаження DLC", - "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载 DLC。", + "uk_UA": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження DLC", + "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载DLC。", "zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入 DLC" } }, @@ -17132,17 +15535,16 @@ "es_ES": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar actualizaciones de título de forma masiva", "fr_FR": "Ouvre l'explorateur de fichier pour choisir un ou plusieurs dossiers duquel charger les mises à jour", "he_IL": "", - "it_IT": "Apri un selettore file per scegliere una o più cartelle dalle quali caricare aggiornamenti in blocco", + "it_IT": "Apri un esploratore file per scegliere una o più cartelle dalle quali caricare aggiornamenti in massa", "ja_JP": "", "ko_KR": "파일 탐색기를 열어 하나 이상의 폴더를 선택하여 대량으로 타이틀 업데이트 불러오기", "no_NO": "Åpne en filutforsker for å velge en eller flere mapper som du vil laste inn titteloppdateringer fra", "pl_PL": "", - "pt_BR": "Abre um explorador de arquivos para escolher uma ou mais pastas para carregar em massa as atualizações de títulos", - "ru_RU": "Открывает проводник, чтобы выбрать одну или несколько папок для массовой загрузки обновлений приложений", - "sv_SE": "Öppna en filutforskare för att välja en eller flera mappar att läsa in alla titeluppdateringar från", + "pt_BR": "Abra o explorador de arquivos para selecionar uma ou mais pastas e carregar atualizações de jogo em massa.", + "ru_RU": "", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลดไฟล์อัปเดตจำนวนมาก", "tr_TR": "", - "uk_UA": "Відкриває Файловий Провідник для обрання однієї або декількох тек для масового завантаження оновлень", + "uk_UA": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження оновлень заголовків", "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载游戏更新。", "zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入遊戲更新" } @@ -17162,41 +15564,15 @@ "ko_KR": "Ryujinx 파일 시스템 폴더 열기", "no_NO": "Åpne Ryujinx filsystem-mappen", "pl_PL": "Otwórz folder systemu plików Ryujinx", - "pt_BR": "Abre a pasta do sistema de arquivos Ryujinx", - "ru_RU": "Открывает папку с файлами Ryujinx", - "sv_SE": "Öppna Ryujinx-filsystemsmappen", + "pt_BR": "Abre o diretório do sistema de arquivos do Ryujinx", + "ru_RU": "Открывает папку с файлами Ryujinx. ", "th_TH": "เปิดโฟลเดอร์ระบบไฟล์ Ryujinx", "tr_TR": "Ryujinx dosya sistem klasörünü açar", - "uk_UA": "Відкриває теку з файлами Ryujinx", + "uk_UA": "Відкриває теку файлової системи Ryujinx", "zh_CN": "打开 Ryujinx 模拟器系统目录", "zh_TW": "開啟 Ryujinx 檔案系統資料夾" } }, - { - "ID": "OpenScreenshotFolderTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Open Ryujinx screenshots folder", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "", - "pl_PL": "", - "pt_BR": "Abre a pasta de capturas de tela do Ryujinx", - "ru_RU": "Открывает папку скриншотов Ryujinx", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx", - "zh_CN": "", - "zh_TW": "" - } - }, { "ID": "OpenRyujinxLogsTooltip", "Translations": { @@ -17212,12 +15588,11 @@ "ko_KR": "로그가 기록되는 폴더 열기", "no_NO": "Åpner mappen hvor logger er lagret", "pl_PL": "Otwiera folder, w którym zapisywane są logi", - "pt_BR": "Abre a pasta onde os logs são gravados", - "ru_RU": "Открывает папку, в которую записываются логи", - "sv_SE": "Öppnar mappen där loggarna har skrivits till", + "pt_BR": "Abre o diretório onde os logs são salvos", + "ru_RU": "Открывает папку в которую записываются логи", "th_TH": "เปิดโฟลเดอร์ ที่เก็บไฟล์ประวัติ", "tr_TR": "Log dosyalarının bulunduğu klasörü açar", - "uk_UA": "Відкриває теку, куди зберігаються журнали (logs)", + "uk_UA": "Відкриває теку, куди записуються журнали", "zh_CN": "打开日志存放的目录", "zh_TW": "開啟日誌被寫入的資料夾" } @@ -17239,10 +15614,9 @@ "pl_PL": "Wyjdź z Ryujinx", "pt_BR": "Sair do Ryujinx", "ru_RU": "Выйти из Ryujinx", - "sv_SE": "Avsluta Ryujinx", "th_TH": "ออกจากโปรแกรม Ryujinx", "tr_TR": "Ryujinx'ten çıkış yapmayı sağlar", - "uk_UA": "Закриває Ryujinx", + "uk_UA": "Виходить з Ryujinx", "zh_CN": "退出 Ryujinx 模拟器", "zh_TW": "結束 Ryujinx" } @@ -17264,7 +15638,6 @@ "pl_PL": "Otwórz okno ustawień", "pt_BR": "Abrir janela de configurações", "ru_RU": "Открывает окно параметров", - "sv_SE": "Öppna inställningar", "th_TH": "เปิดหน้าต่างการตั้งค่า", "tr_TR": "Seçenekler penceresini açar", "uk_UA": "Відкриває вікно налаштувань", @@ -17287,9 +15660,8 @@ "ko_KR": "사용자 프로필 관리자 창 열기", "no_NO": "Åpne vindu for brukerprofiler", "pl_PL": "Otwórz okno Menedżera Profili Użytkownika", - "pt_BR": "Abrir Janela de Gerenciamento de Perfis", - "ru_RU": "Открыть менеджер учётных записей", - "sv_SE": "Öppna hanterare för användarprofiler", + "pt_BR": "Abrir janela de gerenciamento de perfis", + "ru_RU": "Открыть менеджер учетных записей", "th_TH": "เปิดหน้าต่างตัวจัดการโปรไฟล์ผู้ใช้", "tr_TR": "Kullanıcı profil yöneticisi penceresini açar", "uk_UA": "Відкриває вікно диспетчера профілів користувачів", @@ -17313,8 +15685,7 @@ "no_NO": "Stopp emuleringen av dette spillet og gå tilbake til spill valg", "pl_PL": "Zatrzymaj emulację bieżącej gry i wróć do wyboru gier", "pt_BR": "Parar emulação do jogo atual e voltar a seleção de jogos", - "ru_RU": "Остановка эмуляции текущей игры с последующим возвратом к списку игр", - "sv_SE": "Stoppa emulering av aktuellt spel och återgå till spelväljaren", + "ru_RU": "Остановка эмуляции текущей игры и возврат к списку игр", "th_TH": "หยุดการจำลองของเกมที่เปิดอยู่ในปัจจุบันและกลับไปยังการเลือกเกม", "tr_TR": "Oynanmakta olan oyunun emülasyonunu durdurup oyun seçimine geri döndürür", "uk_UA": "Зупиняє емуляцію поточної гри та повертається до вибору гри", @@ -17338,8 +15709,7 @@ "no_NO": "Se etter oppdateringer til Ryujinx", "pl_PL": "Sprawdź aktualizacje Ryujinx", "pt_BR": "Verificar por atualizações para o Ryujinx", - "ru_RU": "Проверяет наличие обновлений Ryujinx", - "sv_SE": "Leta efter uppdateringar för Ryujinx", + "ru_RU": "Проверяет наличие обновлений для Ryujinx", "th_TH": "ตรวจสอบอัปเดตของ Ryujinx", "tr_TR": "Ryujinx güncellemelerini denetlemeyi sağlar", "uk_UA": "Перевіряє наявність оновлень для Ryujinx", @@ -17362,9 +15732,8 @@ "ko_KR": "정보 창 열기", "no_NO": "Åpne Om Vindu", "pl_PL": "Otwórz Okno Informacje", - "pt_BR": "Abrir Janela Sobre", + "pt_BR": "Abrir janela sobre", "ru_RU": "Открывает окно «О программе»", - "sv_SE": "Öppna Om-fönstret", "th_TH": "เปิดหน้าต่าง เกี่ยวกับ", "tr_TR": "Hakkında penceresini açar", "uk_UA": "Відкриває вікно «Про програму».", @@ -17387,9 +15756,8 @@ "ko_KR": "그리드 크기", "no_NO": "Rutenett størrelse", "pl_PL": "Wielkość siatki", - "pt_BR": "Tamanho da Grade", + "pt_BR": "Tamanho da grade", "ru_RU": "Размер сетки", - "sv_SE": "Rutnätsstorlek", "th_TH": "ขนาดตาราง", "tr_TR": "Öge Boyutu", "uk_UA": "Розмір сітки", @@ -17414,7 +15782,6 @@ "pl_PL": "Zmień rozmiar elementów siatki", "pt_BR": "Mudar tamanho dos items da grade", "ru_RU": "Меняет размер сетки элементов", - "sv_SE": "Ändra objektstorleken för rutnätet", "th_TH": "เปลี่ยนขนาด ของตาราง", "tr_TR": "Grid ögelerinin boyutunu değiştirmeyi sağlar", "uk_UA": "Змінити розмір елементів сітки", @@ -17439,7 +15806,6 @@ "pl_PL": "Brazylijski Portugalski", "pt_BR": "Português do Brasil", "ru_RU": "Португальский язык (Бразилия)", - "sv_SE": "Portugisiska (braziliansk)", "th_TH": "บราซิล โปรตุเกส", "tr_TR": "Brezilya Portekizcesi", "uk_UA": "Португальська (Бразилія)", @@ -17462,9 +15828,8 @@ "ko_KR": "모든 기여자 보기", "no_NO": "Se alle bidragsytere", "pl_PL": "Zobacz Wszystkich Współtwórców", - "pt_BR": "Ver Todos os Contribuidores", + "pt_BR": "Ver todos os contribuidores", "ru_RU": "Посмотреть всех участников", - "sv_SE": "Visa alla som bidragit", "th_TH": "ดูผู้มีส่วนร่วมทั้งหมด", "tr_TR": "Tüm katkıda bulunanları gör", "uk_UA": "Переглянути всіх співавторів", @@ -17489,7 +15854,6 @@ "pl_PL": "Głośność: ", "pt_BR": "Volume:", "ru_RU": "Громкость: ", - "sv_SE": "Volym: ", "th_TH": "ระดับเสียง: ", "tr_TR": "Ses Seviyesi: ", "uk_UA": "Гучність: ", @@ -17512,9 +15876,8 @@ "ko_KR": "음량 변경", "no_NO": "Endre lydenivå", "pl_PL": "Zmień Głośność Dźwięku", - "pt_BR": "Mudar Volume do Áudio", + "pt_BR": "Mudar volume do áudio", "ru_RU": "Изменяет громкость звука", - "sv_SE": "Ändra ljudvolym", "th_TH": "ปรับระดับเสียง", "tr_TR": "Ses seviyesini değiştirir", "uk_UA": "Змінити гучність звуку", @@ -17537,9 +15900,8 @@ "ko_KR": "게스트 인터넷 접속/LAN 모드", "no_NO": "Internett-tilgang for gjeste/LAN-modus", "pl_PL": "Dostęp do Internetu Gościa/Tryb LAN", - "pt_BR": "Acesso à Internet para Convidados/Modo LAN", + "pt_BR": "Habilitar acesso à internet do programa convidado", "ru_RU": "Гостевой доступ в интернет/сетевой режим", - "sv_SE": "Gäståtkomst för Internet/LAN-läge", "th_TH": "การเข้าถึงอินเทอร์เน็ตของผู้เยี่ยมชม/โหมด LAN", "tr_TR": "Guest Internet Erişimi/LAN Modu", "uk_UA": "Гостьовий доступ до Інтернету/режим LAN", @@ -17562,9 +15924,8 @@ "ko_KR": "에뮬레이트된 앱을 인터넷에 연결할 수 있습니다.\n\nLAN 모드가 있는 게임은 이 기능이 활성화되고 시스템이 동일한 접속 포인트에 연결되어 있을 때 서로 연결할 수 있습니다. 이는 실제 콘솔도 포함됩니다.\n\nNintendo 서버 연결을 허용하지 않습니다. 인터넷에 연결을 시도하는 특정 게임에서 충돌이 발생할 수 있습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Tillater emulert applikasjon å koble til Internett.\n\nSpill med en LAN-modus kan koble til hverandre når dette er aktivert og systemene er koblet til det samme tilgangspunktet. Dette inkluderer ekte konsoller også.\n\ntillater IKKE tilkobling til Nintendo servere. Kan forårsake krasjing i enkelte spill som prøver å koble til Internett.\n\nLa stå AV hvis du er usikker.", "pl_PL": "Pozwala emulowanej aplikacji na łączenie się z Internetem.\n\nGry w trybie LAN mogą łączyć się ze sobą, gdy ta opcja jest włączona, a systemy są połączone z tym samym punktem dostępu. Dotyczy to również prawdziwych konsol.\n\nNie pozwala na łączenie się z serwerami Nintendo. Może powodować awarie niektórych gier, które próbują połączyć się z Internetem.\n\nPozostaw WYŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Permite que o aplicativo emulado se conecte à Internet.\n\nJogos com modo LAN podem se conectar uns aos outros quando isso está habilitado e os sistemas estão conectados ao mesmo ponto de acesso. Isso inclui consoles reais também.\n\nNÃO permite a conexão com servidores Nintendo. Pode causar travamentos em certos jogos que tentam se conectar à Internet.\n\nDeixe DESLIGADO se não tiver certeza.", + "pt_BR": "Habilita acesso à internet do programa convidado. Se habilitado, o aplicativo vai se comportar como se o sistema Switch emulado estivesse conectado a Internet. Note que em alguns casos, aplicativos podem acessar a Internet mesmo com essa opção desabilitada", "ru_RU": "Позволяет эмулированному приложению подключаться к Интернету.\n\nПри включении этой функции игры с возможностью сетевой игры могут подключаться друг к другу, если все эмуляторы (или реальные консоли) подключены к одной и той же точке доступа.\n\nНЕ разрешает подключение к серверам Nintendo. Может вызвать сбой в некоторых играх, которые пытаются подключиться к Интернету.\n\nРекомендутеся оставить выключенным.", - "sv_SE": "Tillåter det emulerade programmet att ansluta till internet.\n\nSpel med ett LAN-läge kan ansluta till varandra när detta är aktiverat och systemen är anslutna till samma åtkomstpunkt. Detta inkluderar riktiga konsoler också.\n\nTillåter INTE anslutning till Nintendo-servrar. Kan orsaka kraschar i vissa spel som försöker ansluta till internet.\n\nLämna AV om du är osäker.", "th_TH": "อนุญาตให้แอปพลิเคชันจำลองเชื่อมต่ออินเทอร์เน็ต\n\nเกมที่มีโหมด LAN สามารถเชื่อมต่อระหว่างกันได้เมื่อเปิดใช้งานและระบบเชื่อมต่อกับจุดเชื่อมต่อเดียวกัน รวมถึงคอนโซลจริงด้วย\n\nไม่อนุญาตให้มีการเชื่อมต่อกับเซิร์ฟเวอร์ Nintendo อาจทำให้เกิดการหยุดทำงานในบางเกมที่พยายามเชื่อมต่ออินเทอร์เน็ต\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Emüle edilen uygulamanın internete bağlanmasını sağlar.\n\nLAN modu bulunan oyunlar bu seçenek ile birbirine bağlanabilir ve sistemler aynı access point'e bağlanır. Bu gerçek konsolları da kapsar.\n\nNintendo sunucularına bağlanmayı sağlaMAZ. Internete bağlanmaya çalışan baz oyunların çökmesine sebep olabilr.\n\nEmin değilseniz devre dışı bırakın.", "uk_UA": "Дозволяє емульованій програмі підключатися до Інтернету.\n\nІгри з режимом локальної мережі можуть підключатися одна до одної, якщо це увімкнено, і системи підключені до однієї точки доступу. Сюди входять і справжні консолі.\n\nНЕ дозволяє підключатися до серверів Nintendo. Може призвести до збою в деяких іграх, які намагаються підключитися до Інтернету.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -17587,12 +15948,11 @@ "ko_KR": "치트 관리", "no_NO": "Administrer juksemoduser", "pl_PL": "Zarządzaj Kodami", - "pt_BR": "Gerenciar Trapaças", + "pt_BR": "Gerenciar Cheats", "ru_RU": "Открывает окно управления читами", - "sv_SE": "Hantera fusk", "th_TH": "ฟังก์ชั่นจัดการสูตรโกง", "tr_TR": "Hileleri yönetmeyi sağlar", - "uk_UA": "Відкриває меню керування чит-кодами (cheats)", + "uk_UA": "Керування читами", "zh_CN": "管理当前游戏的金手指", "zh_TW": "管理密技" } @@ -17612,9 +15972,8 @@ "ko_KR": "치트 관리", "no_NO": "Administrer juksemoduser", "pl_PL": "Zarządzaj Kodami", - "pt_BR": "Gerenciar Trapaças", + "pt_BR": "Gerenciar Cheats", "ru_RU": "Управление читами", - "sv_SE": "Hantera fusk", "th_TH": "ฟังก์ชั่นจัดการสูตรโกง", "tr_TR": "Hileleri Yönet", "uk_UA": "Керування читами", @@ -17639,10 +15998,9 @@ "pl_PL": "Zarządzaj modyfikacjami", "pt_BR": "Gerenciar Mods", "ru_RU": "Открывает окно управления модами", - "sv_SE": "Hantera moddar", "th_TH": "ฟังก์ชั่นจัดการม็อด", "tr_TR": "Modları Yönet", - "uk_UA": "Відкриває меню керування модифікаціями (mods)", + "uk_UA": "Керування модами", "zh_CN": "管理当前游戏的 MOD", "zh_TW": "管理模組" } @@ -17664,7 +16022,6 @@ "pl_PL": "Zarządzaj modyfikacjami", "pt_BR": "Gerenciar Mods", "ru_RU": "Управление модами", - "sv_SE": "Hantera moddar", "th_TH": "ฟังก์ชั่นจัดการม็อด", "tr_TR": "Modları Yönet", "uk_UA": "Керування модами", @@ -17689,7 +16046,6 @@ "pl_PL": "Zasięg:", "pt_BR": "Intervalo:", "ru_RU": "Диапазон:", - "sv_SE": "Omfång:", "th_TH": "ขอบเขต:", "tr_TR": "Menzil:", "uk_UA": "Діапазон:", @@ -17700,26 +16056,25 @@ { "ID": "DialogStopEmulationTitle", "Translations": { - "ar_SA": "{0} - إيقاف المحاكاة", - "de_DE": "{0} - Beende Emulation", - "el_GR": "{0} - Διακοπή εξομοίωσης", - "en_US": "{0} - Stop Emulation", - "es_ES": "{0} - Detener emulación", - "fr_FR": "{0} - Arrêt de l'émulation", - "he_IL": "{0} - עצור אמולציה", - "it_IT": "{0} - Ferma emulazione", - "ja_JP": "{0} - エミュレーションを中止", - "ko_KR": "{0} - 에뮬레이션 중지", - "no_NO": "{0} - Stopp emulasjon", - "pl_PL": "{0} - Zatrzymaj Emulację", - "pt_BR": "{0} - Parar emulação", - "ru_RU": "{0} - Остановка эмуляции", - "sv_SE": "{0} - Stoppa emulering", - "th_TH": "{0} - หยุดการจำลอง", - "tr_TR": "{0} - Emülasyonu Durdur", - "uk_UA": "{0} - Зупинити емуляцію", - "zh_CN": "{0} - 停止模拟", - "zh_TW": "{0} - 停止模擬" + "ar_SA": "ريوجينكس - إيقاف المحاكاة", + "de_DE": "Ryujinx - Beende Emulation", + "el_GR": "Ryujinx - Διακοπή εξομοίωσης", + "en_US": "Ryujinx - Stop Emulation", + "es_ES": "Ryujinx - Detener emulación", + "fr_FR": "Ryujinx - Arrêt de l'émulation", + "he_IL": "ריוג'ינקס - עצור אמולציה", + "it_IT": "Ryujinx - Ferma emulazione", + "ja_JP": "Ryujinx - エミュレーションを中止", + "ko_KR": "Ryujinx - 에뮬레이션 중지", + "no_NO": "Ryujinx - Stopp emulasjon", + "pl_PL": "Ryujinx - Zatrzymaj Emulację", + "pt_BR": "Ryujinx - Parar emulação", + "ru_RU": "Ryujinx - Остановка эмуляции", + "th_TH": "Ryujinx - หยุดการจำลอง", + "tr_TR": "Ryujinx - Emülasyonu Durdur", + "uk_UA": "Ryujinx - Зупинити емуляцію", + "zh_CN": "Ryujinx - 停止模拟", + "zh_TW": "Ryujinx - 停止模擬" } }, { @@ -17739,7 +16094,6 @@ "pl_PL": "Czy na pewno chcesz zatrzymać emulację?", "pt_BR": "Tem certeza que deseja parar a emulação?", "ru_RU": "Вы уверены, что хотите остановить эмуляцию?", - "sv_SE": "Är du säker på att du vill stoppa emuleringen?", "th_TH": "คุณแน่ใจหรือไม่ว่าต้องการหยุดการจำลองหรือไม่?", "tr_TR": "Emülasyonu durdurmak istediğinizden emin misiniz?", "uk_UA": "Ви впевнені, що хочете зупинити емуляцію?", @@ -17764,7 +16118,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Процессор", - "sv_SE": "Processor", "th_TH": "ซีพียู", "tr_TR": "İşlemci", "uk_UA": "ЦП", @@ -17789,7 +16142,6 @@ "pl_PL": "Dżwięk", "pt_BR": "Áudio", "ru_RU": "Аудио", - "sv_SE": "Ljud", "th_TH": "เสียง", "tr_TR": "Ses", "uk_UA": "Аудіо", @@ -17814,7 +16166,6 @@ "pl_PL": "Sieć", "pt_BR": "Rede", "ru_RU": "Сеть", - "sv_SE": "Nätverk", "th_TH": "เครือข่าย", "tr_TR": "Ağ", "uk_UA": "Мережа", @@ -17837,9 +16188,8 @@ "ko_KR": "네트워크 연결", "no_NO": "Nettverk tilkobling", "pl_PL": "Połączenie Sieciowe", - "pt_BR": "Conexão de Rede", + "pt_BR": "Conexão de rede", "ru_RU": "Подключение к сети", - "sv_SE": "Nätverksanslutning", "th_TH": "การเชื่อมต่อเครือข่าย", "tr_TR": "Ağ Bağlantısı", "uk_UA": "Підключення до мережі", @@ -17864,10 +16214,9 @@ "pl_PL": "Cache CPU", "pt_BR": "Cache da CPU", "ru_RU": "Кэш процессора", - "sv_SE": "CPU-cache", "th_TH": "แคชซีพียู", "tr_TR": "İşlemci Belleği", - "uk_UA": "Кеш CPU", + "uk_UA": "Кеш ЦП", "zh_CN": "CPU 缓存", "zh_TW": "CPU 快取" } @@ -17887,12 +16236,11 @@ "ko_KR": "CPU 모드", "no_NO": "Prosessor modus", "pl_PL": "Pamięć CPU", - "pt_BR": "Modo da CPU", - "ru_RU": "Режим работы процессора", - "sv_SE": "CPU-läge", + "pt_BR": "Memória da CPU", + "ru_RU": "Режим процессора", "th_TH": "โหมดซีพียู", "tr_TR": "CPU Hafızası", - "uk_UA": "Режим CPU", + "uk_UA": "Пам'ять ЦП", "zh_CN": "CPU 模式", "zh_TW": "CPU 模式" } @@ -17912,9 +16260,8 @@ "ko_KR": "업데이터가 비활성화되었습니다!", "no_NO": "Oppdatering Deaktivert!", "pl_PL": "Aktualizator Wyłączony!", - "pt_BR": "Atualizador Desabilitado!", + "pt_BR": "Atualizador desabilitado!", "ru_RU": "Средство обновления отключено", - "sv_SE": "Uppdateringar inaktiverade!", "th_TH": "ปิดใช้งานการอัปเดตแล้ว!", "tr_TR": "Güncelleyici Devre Dışı!", "uk_UA": "Програму оновлення вимкнено!", @@ -17922,31 +16269,6 @@ "zh_TW": "更新已停用!" } }, - { - "ID": "UpdaterBackgroundStatusBarButtonText", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Update Available!", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Oppdatering tilgjengelig!", - "pl_PL": "", - "pt_BR": "Atualização Disponível!", - "ru_RU": "Доступно обновление!", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Доступне оновлення!", - "zh_CN": "有可用的更新!", - "zh_TW": "" - } - }, { "ID": "ControllerSettingsRotate90", "Translations": { @@ -17962,9 +16284,8 @@ "ko_KR": "시계 방향으로 90° 회전", "no_NO": "Roter 90° med klokken", "pl_PL": "Obróć o 90° w Prawo", - "pt_BR": "Rodar 90° Sentido Horário", + "pt_BR": "Rodar 90° sentido horário", "ru_RU": "Повернуть на 90° по часовой стрелке", - "sv_SE": "Rotera 90° medurs", "th_TH": "หมุน 90 องศา ตามเข็มนาฬิกา", "tr_TR": "Saat yönünde 90° Döndür", "uk_UA": "Повернути на 90° за годинниковою стрілкою", @@ -17987,12 +16308,11 @@ "ko_KR": "아이콘 크기", "no_NO": "Ikon størrelse", "pl_PL": "Rozmiar ikon", - "pt_BR": "Tamanho do Ícone", + "pt_BR": "Tamanho do ícone", "ru_RU": "Размер обложек", - "sv_SE": "Ikonstorlek", "th_TH": "ขนาดไอคอน", "tr_TR": "Ikon Boyutu", - "uk_UA": "Розмір обкладинки", + "uk_UA": "Розмір значка", "zh_CN": "图标尺寸", "zh_TW": "圖示大小" } @@ -18014,10 +16334,9 @@ "pl_PL": "Zmień rozmiar ikon gry", "pt_BR": "Muda o tamanho do ícone do jogo", "ru_RU": "Меняет размер обложек", - "sv_SE": "Ändra storleken för spelikonerna", "th_TH": "เปลี่ยนขนาดของไอคอนเกม", "tr_TR": "Oyun ikonlarının boyutunu değiştirmeyi sağlar", - "uk_UA": "Змінити розмір обкладинок (значків) ігор", + "uk_UA": "Змінити розмір значків гри", "zh_CN": "更改游戏图标的显示尺寸", "zh_TW": "變更遊戲圖示的大小" } @@ -18037,9 +16356,8 @@ "ko_KR": "콘솔 표시", "no_NO": "Vis konsoll", "pl_PL": "Pokaż Konsolę", - "pt_BR": "Exibir Console", + "pt_BR": "Exibir console", "ru_RU": "Показать консоль", - "sv_SE": "Visa konsoll", "th_TH": "แสดง คอนโซล", "tr_TR": "Konsol'u Göster", "uk_UA": "Показати консоль", @@ -18062,9 +16380,8 @@ "ko_KR": "{0}에서 셰이더 캐시를 삭제하는 중 오류 발생 : {1}", "no_NO": "Feil under tømming av shader cache ved {0}: {1}", "pl_PL": "Błąd podczas czyszczenia cache shaderów w {0}: {1}", - "pt_BR": "Erro ao limpar o cache do shader em {0}: {1}", + "pt_BR": "Erro ao deletar o shader em {0}: {1}", "ru_RU": "Ошибка очистки кэша шейдеров в {0}: {1}", - "sv_SE": "Fel vid tömning av shader cache i {0}: {1}", "th_TH": "เกิดข้อผิดพลาดในการล้างแคชแสงเงา {0}: {1}", "tr_TR": "Belirtilen shader cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу шейдера {0}: {1}", @@ -18089,7 +16406,6 @@ "pl_PL": "Nie znaleziono kluczy", "pt_BR": "Chaves não encontradas", "ru_RU": "Ключи не найдены", - "sv_SE": "Nycklarna hittades inte", "th_TH": "ไม่พบ คีย์", "tr_TR": "Keys bulunamadı", "uk_UA": "Ключі не знайдено", @@ -18114,7 +16430,6 @@ "pl_PL": "Nie znaleziono firmware'u", "pt_BR": "Firmware não encontrado", "ru_RU": "Прошивка не найдена", - "sv_SE": "Firmware hittades inte", "th_TH": "ไม่พบ เฟิร์มแวร์", "tr_TR": "Firmware bulunamadı", "uk_UA": "Прошивка не знайдена", @@ -18132,14 +16447,13 @@ "es_ES": "Error al analizar el firmware", "fr_FR": "Erreur d'analyse du firmware", "he_IL": "שגיאת ניתוח קושחה", - "it_IT": "Errore di analisi del firmware", + "it_IT": "Errori di analisi del firmware", "ja_JP": "ファームウェアのパーズエラー", "ko_KR": "펌웨어 구문 분석 오류", "no_NO": "Fastvare analysefeil", "pl_PL": "Błąd parsowania firmware'u", - "pt_BR": "Erro de análise de firmware", + "pt_BR": "Erro na leitura do Firmware", "ru_RU": "Ошибка извлечения прошивки", - "sv_SE": "Tolkningsfel i firmware", "th_TH": "เกิดข้อผิดพลาดในการวิเคราะห์เฟิร์มแวร์", "tr_TR": "Firmware çözümleme hatası", "uk_UA": "Помилка аналізу прошивки", @@ -18164,10 +16478,9 @@ "pl_PL": "Aplikacja nie znaleziona", "pt_BR": "Aplicativo não encontrado", "ru_RU": "Приложение не найдено", - "sv_SE": "Applikationen hittades inte", "th_TH": "ไม่พบ แอปพลิเคชัน", "tr_TR": "Uygulama bulunamadı", - "uk_UA": "Застосунок не знайдено", + "uk_UA": "Додаток не знайдено", "zh_CN": "找不到游戏程序", "zh_TW": "找不到應用程式" } @@ -18189,7 +16502,6 @@ "pl_PL": "Nieznany błąd", "pt_BR": "Erro desconhecido", "ru_RU": "Неизвестная ошибка", - "sv_SE": "Okänt fel", "th_TH": "ข้อผิดพลาดที่ไม่รู้จัก", "tr_TR": "Bilinmeyen hata", "uk_UA": "Невідома помилка", @@ -18214,7 +16526,6 @@ "pl_PL": "Niezdefiniowany błąd", "pt_BR": "Erro indefinido", "ru_RU": "Неопределенная ошибка", - "sv_SE": "Odefinierat fel", "th_TH": "ข้อผิดพลาดที่ไม่ได้ระบุ", "tr_TR": "Tanımlanmayan hata", "uk_UA": "Невизначена помилка", @@ -18239,7 +16550,6 @@ "pl_PL": "Ryujinx nie mógł znaleźć twojego pliku 'prod.keys'", "pt_BR": "Ryujinx não conseguiu encontrar o seu arquivo 'prod.keys'", "ru_RU": "Ryujinx не удалось найти ваш 'prod.keys' файл", - "sv_SE": "Ryujinx kunde inte hitta din 'prod.keys'-fil", "th_TH": "Ryujinx ไม่พบไฟล์ 'prod.keys' ในเครื่องของคุณ", "tr_TR": "Ryujinx 'prod.keys' dosyasını bulamadı", "uk_UA": "Ryujinx не вдалося знайти ваш файл «prod.keys».", @@ -18264,7 +16574,6 @@ "pl_PL": "Ryujinx nie mógł znaleźć żadnego zainstalowanego firmware'u", "pt_BR": "Ryujinx não conseguiu encontrar nenhum Firmware instalado", "ru_RU": "Ryujinx не удалось найти ни одной установленной прошивки", - "sv_SE": "Ryujinx kunde inte hitta några installerade firmwares", "th_TH": "Ryujinx ไม่พบ เฟิร์มแวร์ที่ติดตั้งไว้ในเครื่องของคุณ", "tr_TR": "Ryujinx yüklü herhangi firmware bulamadı", "uk_UA": "Ryujinx не вдалося знайти встановлену прошивку", @@ -18289,7 +16598,6 @@ "pl_PL": "Ryujinx nie był w stanie zparsować dostarczonego firmware'u. Jest to zwykle spowodowane nieaktualnymi kluczami.", "pt_BR": "Ryujinx não conseguiu ler o Firmware fornecido. Geralmente isso é causado por chaves desatualizadas.", "ru_RU": "Ryujinx не удалось распаковать выбранную прошивку. Обычно это вызвано устаревшими ключами.", - "sv_SE": "Ryujinx kunde inte tolka angiven firmware. Detta sker oftast med utdaterade nycklar.", "th_TH": "Ryujinx ไม่สามารถวิเคราะห์เฟิร์มแวร์ที่ให้มาได้ ซึ่งมักมีสาเหตุมาจากคีย์ที่เก่าจนเกินไป", "tr_TR": "Ryujinx temin edilen firmware'i çözümleyemedi. Bu durum genellikle güncel olmayan keys'den kaynaklanır.", "uk_UA": "Ryujinx не вдалося проаналізувати прошивку. Зазвичай це спричинено застарілими ключами.", @@ -18314,10 +16622,9 @@ "pl_PL": "Ryujinx nie mógł znaleźć prawidłowej aplikacji na podanej ścieżce.", "pt_BR": "Ryujinx não conseguiu encontrar um aplicativo válido no caminho fornecido.", "ru_RU": "Ryujinx не удалось найти валидное приложение по указанному пути.", - "sv_SE": "Ryujinx kunde inte hitta en giltig applikation i angiven sökväg.", "th_TH": "Ryujinx ไม่พบแอปพลิเคชันที่ถูกต้องในที่เก็บไฟล์ที่กำหนด", "tr_TR": "Ryujinx belirtilen yolda geçerli bir uygulama bulamadı.", - "uk_UA": "Ryujinx не вдалося знайти дійсний застосунок (гру) за вказаним шляхом", + "uk_UA": "Ryujinx не вдалося знайти дійсний додаток за вказаним шляхом", "zh_CN": "Ryujinx 模拟器在所选路径中找不到有效的游戏程序。", "zh_TW": "Ryujinx 無法在指定路徑下找到有效的應用程式。" } @@ -18337,9 +16644,8 @@ "ko_KR": "알 수 없는 오류가 발생했습니다!", "no_NO": "En ukjent feil oppstod!", "pl_PL": "Wystąpił nieznany błąd!", - "pt_BR": "Ocorreu um erro desconhecido!", + "pt_BR": "Um erro desconhecido foi encontrado!", "ru_RU": "Произошла неизвестная ошибка", - "sv_SE": "Ett okänt fel inträffade!", "th_TH": "เกิดข้อผิดพลาดที่ไม่รู้จัก!", "tr_TR": "Bilinmeyen bir hata oluştu!", "uk_UA": "Сталася невідома помилка!", @@ -18364,10 +16670,9 @@ "pl_PL": "Wystąpił niezdefiniowany błąd! To nie powinno się zdarzyć, skontaktuj się z deweloperem!", "pt_BR": "Um erro indefinido occoreu! Isso não deveria acontecer, por favor contate um desenvolvedor!", "ru_RU": "Произошла неизвестная ошибка. Этого не должно происходить, пожалуйста, свяжитесь с разработчиками.", - "sv_SE": "Ett odefinierat fel inträffade! Detta ska inte hända. Kontakta en utvecklare!", "th_TH": "เกิดข้อผิดพลาดที่ไม่สามารถระบุได้! สิ่งนี้ไม่ควรเกิดขึ้น โปรดติดต่อผู้พัฒนา!", "tr_TR": "Tanımlanmayan bir hata oluştu! Bu durum ile karşılaşılmamalıydı, lütfen bir geliştirici ile iletişime geçin!", - "uk_UA": "Виникла невизначена помилка! Це не повинно було статися. Будь ласка, зверніться до розробника!", + "uk_UA": "Сталася невизначена помилка! Цього не повинно статися, зверніться до розробника!", "zh_CN": "出现未定义错误!此类错误不应出现,请联系开发者!", "zh_TW": "發生未定義錯誤! 這種情況不應該發生,請聯絡開發人員!" } @@ -18387,9 +16692,8 @@ "ko_KR": "설정 가이드 열기", "no_NO": "Åpne oppsettsveiledningen", "pl_PL": "Otwórz Podręcznik Konfiguracji", - "pt_BR": "Abrir o Guia de Configuração", + "pt_BR": "Abrir o guia de configuração", "ru_RU": "Открыть руководство по установке", - "sv_SE": "Öppna konfigurationsguiden", "th_TH": "เปิดคู่มือการตั้งค่า", "tr_TR": "Kurulum Kılavuzunu Aç", "uk_UA": "Відкрити посібник із налаштування", @@ -18412,12 +16716,11 @@ "ko_KR": "업데이트 없음", "no_NO": "Ingen oppdatering", "pl_PL": "Brak Aktualizacji", - "pt_BR": "Sem Atualizações", + "pt_BR": "Sem atualizações", "ru_RU": "Без обновлений", - "sv_SE": "Ingen uppdatering", "th_TH": "ไม่มีการอัปเดต", "tr_TR": "Güncelleme Yok", - "uk_UA": "НБез оновлень", + "uk_UA": "Немає оновлень", "zh_CN": "无更新(默认版本)", "zh_TW": "沒有更新" } @@ -18426,23 +16729,22 @@ "ID": "TitleUpdateVersionLabel", "Translations": { "ar_SA": "الإصدار: {0}", - "de_DE": "", - "el_GR": "", + "de_DE": "Version {0} - {1}", + "el_GR": "Version {0} - {1}", "en_US": "Version {0}", - "es_ES": "Versión {0}", + "es_ES": "Versión {0} - {1}", "fr_FR": "", - "he_IL": "גרסה: {0}", + "he_IL": "גרסה {0}", "it_IT": "Versione {0}", - "ja_JP": "バージョン {0}", + "ja_JP": "バージョン {0} - {1}", "ko_KR": "버전 {0}", "no_NO": "Versjon {0}", - "pl_PL": "Wersja {0}", + "pl_PL": "Wersja {0} - {1}", "pt_BR": "Versão {0}", - "ru_RU": "Версия {0}", - "sv_SE": "", + "ru_RU": "Version {0} - {1}", "th_TH": "เวอร์ชั่น {0}", - "tr_TR": "Sürüm {0}", - "uk_UA": "Версія {0}", + "tr_TR": "Sürüm {0} - {1}", + "uk_UA": "Версія {0} - {1}", "zh_CN": "游戏更新的版本 {0}", "zh_TW": "版本 {0}" } @@ -18457,14 +16759,13 @@ "es_ES": "Incorporado: Versión {0}", "fr_FR": "Inclus avec le jeu: Version {0}", "he_IL": "", - "it_IT": "Incluso: Versione {0}", + "it_IT": "In bundle: Versione {0}", "ja_JP": "", "ko_KR": "번들 : 버전 {0}", "no_NO": "Pakket: Versjon {0}", "pl_PL": "", "pt_BR": "Empacotado: Versão {0}", - "ru_RU": "Баднл: Версия {0}", - "sv_SE": "Bundlad: Version {0}", + "ru_RU": "", "th_TH": "Bundled: เวอร์ชั่น {0}", "tr_TR": "", "uk_UA": "Комплектні: Версія {0}", @@ -18482,14 +16783,13 @@ "es_ES": "Incorporado:", "fr_FR": "Inclus avec le jeu :", "he_IL": "", - "it_IT": "Incluso:", + "it_IT": "In bundle:", "ja_JP": "", "ko_KR": "번들 :", "no_NO": "Pakket:", "pl_PL": "", "pt_BR": "Empacotado:", - "ru_RU": "Бандл:", - "sv_SE": "Bundlad:", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Комплектні:", @@ -18512,14 +16812,13 @@ "ko_KR": "일부", "no_NO": "Delvis", "pl_PL": "", - "pt_BR": "Parcial", - "ru_RU": "Частично", - "sv_SE": "Delvis", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Часткові", - "zh_CN": "分区", - "zh_TW": "部分" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18532,19 +16831,18 @@ "es_ES": "Sin recortar", "fr_FR": "Non réduit", "he_IL": "", - "it_IT": "Dim. originale", + "it_IT": "Non Trimmato", "ja_JP": "", "ko_KR": "트리밍되지 않음", "no_NO": "Ikke trimmet", "pl_PL": "", - "pt_BR": "Não Reduzido", - "ru_RU": "Не обрезан", - "sv_SE": "Inte optimerad", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Необрізані", - "zh_CN": "没有瘦身的", - "zh_TW": "未修剪" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18557,19 +16855,18 @@ "es_ES": "Recortado", "fr_FR": "Réduit", "he_IL": "", - "it_IT": "Dim. ridotta", + "it_IT": "Trimmato", "ja_JP": "", "ko_KR": "트리밍됨", "no_NO": "Trimmet", "pl_PL": "", - "pt_BR": "Reduzido", - "ru_RU": "Обрезан", - "sv_SE": "Optimerad", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізані", - "zh_CN": "经过瘦身的", - "zh_TW": "已修剪" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18587,14 +16884,13 @@ "ko_KR": "(실패)", "no_NO": "(Mislyktes)", "pl_PL": "", - "pt_BR": "Falhou", - "ru_RU": "(Ошибка)", - "sv_SE": "(misslyckades)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "(Невдача)", - "zh_CN": "(失败)", - "zh_TW": "(失敗)" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18607,19 +16903,18 @@ "es_ES": "Ahorra {0:n0} Mb", "fr_FR": "Sauvegarde de {0:n0} Mo", "he_IL": "", - "it_IT": "Risparmia {0:n0} MB", + "it_IT": "Salva {0:n0} Mb", "ja_JP": "", "ko_KR": "{0:n0} Mb 저장", "no_NO": "Spare {0:n0} Mb", "pl_PL": "", - "pt_BR": "Salvar {0:n0} Mb", - "ru_RU": "Сохранить {0:n0} Мб", - "sv_SE": "Spara {0:n0} Mb", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Зберегти {0:n0} Мб", - "zh_CN": "能节约 {0:n0} Mb", - "zh_TW": "可節省 {0:n0} Mb" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18632,69 +16927,66 @@ "es_ES": "{0:n0} Mb ahorrado(s)", "fr_FR": "Sauvegardé {0:n0} Mo", "he_IL": "", - "it_IT": "Risparmiati {0:n0} MB", + "it_IT": "Salva {0:n0} Mb", "ja_JP": "", "ko_KR": "{0:n0}Mb 저장됨", "no_NO": "Spart {0:n0} Mb", "pl_PL": "", - "pt_BR": "Salvo {0:n0} Mb", - "ru_RU": "Сохранено {0:n0} Мб", - "sv_SE": "Sparade {0:n0} Mb", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Збережено {0:n0} Мб", - "zh_CN": "节约了 {0:n0} Mb", - "zh_TW": "已節省 {0:n0} Mb" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "RyujinxInfo", "Translations": { - "ar_SA": "{0} - معلومات", + "ar_SA": "ريوجينكس - معلومات", "de_DE": "", - "el_GR": "{0} - Πληροφορίες", - "en_US": "{0} - Info", + "el_GR": "Ryujinx - Πληροφορίες", + "en_US": "Ryujinx - Info", "es_ES": "", "fr_FR": "", - "he_IL": "{0} - מידע", - "it_IT": "{0} - Informazioni", - "ja_JP": "{0} - 情報", - "ko_KR": "{0} - 정보", - "no_NO": "{0} - Informasjon", + "he_IL": "ריוג'ינקס - מידע", + "it_IT": "Ryujinx - Informazioni", + "ja_JP": "Ryujinx - 情報", + "ko_KR": "Ryujinx - 정보", + "no_NO": "Ryujinx - Informasjon", "pl_PL": "", - "pt_BR": "{0} - Informação", - "ru_RU": "{0} - Информация", - "sv_SE": "{0} - Information", - "th_TH": "{0} – ข้อมูล", - "tr_TR": "{0} - Bilgi", - "uk_UA": "{0} - Інформація", - "zh_CN": "{0} - 信息", - "zh_TW": "{0} - 資訊" + "pt_BR": "Ryujinx - Informação", + "ru_RU": "Ryujinx - Информация", + "th_TH": "Ryujinx – ข้อมูล", + "tr_TR": "Ryujinx - Bilgi", + "uk_UA": "Ryujin x - Інформація", + "zh_CN": "Ryujinx - 信息", + "zh_TW": "Ryujinx - 資訊" } }, { "ID": "RyujinxConfirm", "Translations": { - "ar_SA": "{0} - تأكيد", - "de_DE": "{0} - Bestätigung", - "el_GR": "{0} - Επιβεβαίωση", - "en_US": "{0} - Confirmation", - "es_ES": "{0} - Confirmación", + "ar_SA": "ريوجينكس - تأكيد", + "de_DE": "Ryujinx - Bestätigung", + "el_GR": "Ryujinx - Επιβεβαίωση", + "en_US": "Ryujinx - Confirmation", + "es_ES": "Ryujinx - Confirmación", "fr_FR": "", - "he_IL": "{0} - אישור", - "it_IT": "{0} - Conferma", - "ja_JP": "{0} - 確認", - "ko_KR": "{0} - 확인", - "no_NO": "{0} - Bekreftelse", - "pl_PL": "{0} - Potwierdzenie", - "pt_BR": "{0} - Confirmação", - "ru_RU": "{0} - Подтверждение", - "sv_SE": "{0} - Bekräfta", - "th_TH": "{0} - ยืนยัน", - "tr_TR": "{0} - Doğrulama", - "uk_UA": "{0} - Підтвердження", - "zh_CN": "{0} - 确认", - "zh_TW": "{0} - 確認" + "he_IL": "ריוג'ינקס - אישור", + "it_IT": "Ryujinx - Conferma", + "ja_JP": "Ryujinx - 確認", + "ko_KR": "Ryujinx - 확인", + "no_NO": "Ryujinx - Bekreftelse", + "pl_PL": "Ryujinx - Potwierdzenie", + "pt_BR": "Ryujinx - Confirmação", + "ru_RU": "Ryujinx - Подтверждение", + "th_TH": "Ryujinx - ยืนยัน", + "tr_TR": "Ryujinx - Doğrulama", + "uk_UA": "Ryujinx - Підтвердження", + "zh_CN": "Ryujinx - 确认", + "zh_TW": "Ryujinx - 確認" } }, { @@ -18714,7 +17006,6 @@ "pl_PL": "Wszystkie typy", "pt_BR": "Todos os tipos", "ru_RU": "Все типы", - "sv_SE": "Alla typer", "th_TH": "ทุกประเภท", "tr_TR": "Tüm türler", "uk_UA": "Всі типи", @@ -18739,7 +17030,6 @@ "pl_PL": "Nigdy", "pt_BR": "Nunca", "ru_RU": "Никогда", - "sv_SE": "Aldrig", "th_TH": "ไม่ต้อง", "tr_TR": "Hiçbir Zaman", "uk_UA": "Ніколи", @@ -18764,7 +17054,6 @@ "pl_PL": "Musi mieć co najmniej {0} znaków", "pt_BR": "Deve ter pelo menos {0} caracteres", "ru_RU": "Должно быть не менее {0} символов.", - "sv_SE": "Får endast vara minst {0} tecken långt", "th_TH": "ต้องมีความยาวของตัวอักษรอย่างน้อย {0} ตัว", "tr_TR": "En az {0} karakter uzunluğunda olmalı", "uk_UA": "Мінімальна кількість символів: {0}", @@ -18789,7 +17078,6 @@ "pl_PL": "Musi mieć długość od {0}-{1} znaków", "pt_BR": "Deve ter entre {0}-{1} caracteres", "ru_RU": "Должно быть {0}-{1} символов", - "sv_SE": "Får endast vara {0}-{1} tecken långt", "th_TH": "ต้องมีความยาวของตัวอักษร {0}-{1} ตัว", "tr_TR": "{0}-{1} karakter uzunluğunda olmalı", "uk_UA": "Має бути {0}-{1} символів", @@ -18812,14 +17100,13 @@ "ko_KR": "캐비닛 대화 상자", "no_NO": "Dialogboks for kabinett", "pl_PL": "", - "pt_BR": "Diálogo do Gabinete", - "ru_RU": "Сообщение кабинета", - "sv_SE": "Cabinet-dialog", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Сповіщення Cabinet", - "zh_CN": "档案对话框", - "zh_TW": "Cabinet 對話方塊" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -18832,19 +17119,18 @@ "es_ES": "Ingresa el nuevo nombre de tu Amiibo", "fr_FR": "Entrer le nouveau nom de votre Amiibo", "he_IL": "", - "it_IT": "Inserisci il nuovo nome del tuo Amiibo", + "it_IT": "", "ja_JP": "", "ko_KR": "Amiibo의 새 이름 입력하기", "no_NO": "Skriv inn Amiiboens nye navn", "pl_PL": "", - "pt_BR": "Digite o novo nome do seu Amiibo", - "ru_RU": "Введите новое имя вашего Amiibo", - "sv_SE": "Ange nya namnet för din Amiibo", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Вкажіть Ваше нове ім'я Amiibo", - "zh_CN": "输入你的 Amiibo 的新名字", - "zh_TW": "輸入 Amiibo 的新名稱" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18857,19 +17143,18 @@ "es_ES": "Escanea tu Amiibo ahora.", "fr_FR": "Veuillez scannez votre Amiibo.", "he_IL": "", - "it_IT": "Scansiona ora il tuo Amiibo.", + "it_IT": "", "ja_JP": "", "ko_KR": "지금 Amiibo를 스캔하세요.", "no_NO": "Vennligst skann Amiiboene dine nå.", "pl_PL": "", - "pt_BR": "Por favor, escaneie seu Amiibo agora.", - "ru_RU": "Пожалуйста, отсканируйте свой Amiibo.", - "sv_SE": "Skanna din Amiibo nu.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Будь ласка, проскануйте Ваш Amiibo.", - "zh_CN": "请现在扫描你的 Amiibo", - "zh_TW": "請掃描你的 Amiibo。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -18889,7 +17174,6 @@ "pl_PL": "Klawiatura Oprogramowania", "pt_BR": "Teclado por Software", "ru_RU": "Программная клавиатура", - "sv_SE": "Programvarutangentbord", "th_TH": "ซอฟต์แวร์คีย์บอร์ด", "tr_TR": "Yazılım Klavyesi", "uk_UA": "Програмна клавіатура", @@ -18907,14 +17191,13 @@ "es_ES": "Debe ser sólo 0-9 o '.'", "fr_FR": "Doit être 0-9 ou '.' uniquement", "he_IL": "חייב להיות בין 0-9 או '.' בלבד", - "it_IT": "Può contenere solo numeri o '.'", + "it_IT": "Deve essere solo 0-9 o '.'", "ja_JP": "0-9 または '.' のみでなければなりません", "ko_KR": "0-9 또는 '.'만 가능", "no_NO": "Må kun være 0-9 eller '.'", "pl_PL": "Może składać się jedynie z 0-9 lub '.'", "pt_BR": "Deve ser somente 0-9 ou '.'", "ru_RU": "Должно быть в диапазоне 0-9 или '.'", - "sv_SE": "Får endast vara 0-9 eller '.'", "th_TH": "ต้องเป็น 0-9 หรือ '.' เท่านั้น", "tr_TR": "Sadece 0-9 veya '.' olabilir", "uk_UA": "Повинно бути лише 0-9 або “.”", @@ -18932,14 +17215,13 @@ "es_ES": "Solo deben ser caracteres no CJK", "fr_FR": "Doit être uniquement des caractères non CJK", "he_IL": "מחויב להיות ללא אותיות CJK", - "it_IT": "Può contenere solo caratteri non CJK", + "it_IT": "Deve essere solo caratteri non CJK", "ja_JP": "CJK文字以外のみ", "ko_KR": "CJK 문자가 아닌 문자만 가능", "no_NO": "Må kun være uten CJK-tegn", "pl_PL": "Nie może zawierać znaków CJK", "pt_BR": "Apenas devem ser caracteres não CJK.", "ru_RU": "Не должно быть CJK-символов", - "sv_SE": "Får endast vara icke-CJK-tecken", "th_TH": "ต้องเป็นตัวอักษรที่ไม่ใช่ประเภท CJK เท่านั้น", "tr_TR": "Sadece CJK-characters olmayan karakterler olabilir", "uk_UA": "Повинно бути лише не CJK-символи", @@ -18957,14 +17239,13 @@ "es_ES": "Solo deben ser texto ASCII", "fr_FR": "Doit être uniquement du texte ASCII", "he_IL": "מחויב להיות טקסט אסקיי", - "it_IT": "Può contenere solo testo ASCII", + "it_IT": "Deve essere solo testo ASCII", "ja_JP": "ASCII文字列のみ", "ko_KR": "ASCII 텍스트만 가능", "no_NO": "Må være kun ASCII-tekst", "pl_PL": "Musi zawierać tylko tekst ASCII", "pt_BR": "Deve ser apenas texto ASCII", "ru_RU": "Текст должен быть только в ASCII кодировке", - "sv_SE": "Får endast vara ASCII-text", "th_TH": "ต้องเป็นตัวอักษร ASCII เท่านั้น", "tr_TR": "Sadece ASCII karakterler olabilir", "uk_UA": "Повинно бути лише ASCII текст", @@ -18987,9 +17268,8 @@ "ko_KR": "지원되는 컨트롤러 :", "no_NO": "Støttede kontrollere:", "pl_PL": "Obsługiwane Kontrolery:", - "pt_BR": "Controladores Suportados:", + "pt_BR": "", "ru_RU": "Поддерживаемые геймпады:", - "sv_SE": "Handkontroller som stöds:", "th_TH": "คอนโทรลเลอร์ที่รองรับ:", "tr_TR": "Desteklenen Kumandalar:", "uk_UA": "Підтримувані контролери:", @@ -19014,7 +17294,6 @@ "pl_PL": "Gracze:", "pt_BR": "Jogadores:", "ru_RU": "Игроки:", - "sv_SE": "Spelare:", "th_TH": "ผู้เล่น:", "tr_TR": "Oyuncular:", "uk_UA": "Гравці:", @@ -19037,9 +17316,8 @@ "ko_KR": "현재 구성이 유효하지 않습니다. 설정을 열고 입력을 다시 구성하십시오.", "no_NO": "Din nåværende konfigurasjon er ugyldig. Åpne innstillinger og konfigurer inndata.", "pl_PL": "Twoja aktualna konfiguracja jest nieprawidłowa. Otwórz ustawienia i skonfiguruj swoje wejścia.", - "pt_BR": "Sua configuração atual é inválida. Abra as configurações e reconfigure suas entradas.", + "pt_BR": "", "ru_RU": "Текущая конфигурация некорректна. Откройте параметры и перенастройте управление.", - "sv_SE": "Din aktuella konfiguration är ogiltig. Öppna inställningarna och konfigurera om din inmatning.", "th_TH": "การกำหนดค่าปัจจุบันของคุณไม่ถูกต้อง กรุณาเปิดการตั้งค่าและกำหนดค่าอินพุตของคุณใหม่", "tr_TR": "Halihazırdaki konfigürasyonunuz geçersiz. Ayarları açın ve girişlerinizi yeniden konfigüre edin.", "uk_UA": "Поточна конфігурація невірна. Відкрийте налаштування та переналаштуйте Ваші дані.", @@ -19062,9 +17340,8 @@ "ko_KR": "도킹 모드가 설정되었습니다. 휴대용 제어 기능을 비활성화해야 합니다.", "no_NO": "Docked modus. Håndholdt kontroll skal være deaktivert.", "pl_PL": "Ustawiony tryb zadokowany. Sterowanie przenośne powinno być wyłączone.", - "pt_BR": "Modo TV definido. O controle portátil deve ser desabilitado.", + "pt_BR": "", "ru_RU": "Используется стационарный режим. Управление в портативном режиме должно быть отключено.", - "sv_SE": "Dockat läge angivet. Handhållna kontroller bör inaktiveras.", "th_TH": "ตั้งค่าด็อกโหมด ควรปิดใช้งานการควบคุมแบบแฮนด์เฮลด์", "tr_TR": "Docked mod ayarlandı. Portatif denetim devre dışı bırakılmalı.", "uk_UA": "Встановлений режим в док-станції. Вимкніть портативні контролери.", @@ -19082,14 +17359,13 @@ "es_ES": "Renombrando archivos viejos...", "fr_FR": "Renommage des anciens fichiers...", "he_IL": "משנה שמות של קבצים ישנים...", - "it_IT": "Ridenominazione dei vecchi file...", + "it_IT": "Rinominazione dei vecchi files...", "ja_JP": "古いファイルをリネーム中...", "ko_KR": "오래된 파일 이름 바꾸기...", "no_NO": "Omdøper gamle filer...", "pl_PL": "Zmienianie Nazw Starych Plików...", "pt_BR": "Renomeando arquivos antigos...", "ru_RU": "Переименование старых файлов...", - "sv_SE": "Byter namn på gamla filer...", "th_TH": "กำลังเปลี่ยนชื่อไฟล์เก่า...", "tr_TR": "Eski dosyalar yeniden adlandırılıyor...", "uk_UA": "Перейменування старих файлів...", @@ -19114,7 +17390,6 @@ "pl_PL": "Aktualizator nie mógł zmienić nazwy pliku: {0}", "pt_BR": "O atualizador não conseguiu renomear o arquivo: {0}", "ru_RU": "Программе обновления не удалось переименовать файл: {0}", - "sv_SE": "Uppdateraren kunde inte byta namn på filen: {0}", "th_TH": "โปรแกรมอัปเดตไม่สามารถเปลี่ยนชื่อไฟล์ได้: {0}", "tr_TR": "Güncelleyici belirtilen dosyayı yeniden adlandıramadı: {0}", "uk_UA": "Програмі оновлення не вдалося перейменувати файл: {0}", @@ -19137,9 +17412,8 @@ "ko_KR": "새 파일 추가...", "no_NO": "Legger til nye filer...", "pl_PL": "Dodawanie Nowych Plików...", - "pt_BR": "Adicionando Novos Arquivos...", + "pt_BR": "Adicionando novos arquivos...", "ru_RU": "Добавление новых файлов...", - "sv_SE": "Lägger till nya filer...", "th_TH": "กำลังเพิ่มไฟล์ใหม่...", "tr_TR": "Yeni Dosyalar Ekleniyor...", "uk_UA": "Додавання нових файлів...", @@ -19162,9 +17436,8 @@ "ko_KR": "업데이트 추출...", "no_NO": "Pakker ut oppdatering...", "pl_PL": "Wypakowywanie Aktualizacji...", - "pt_BR": "Extraíndo Atualização...", + "pt_BR": "Extraíndo atualização...", "ru_RU": "Извлечение обновления...", - "sv_SE": "Extraherar uppdatering...", "th_TH": "กำลังแยกการอัปเดต...", "tr_TR": "Güncelleme Ayrıştırılıyor...", "uk_UA": "Видобування оновлення...", @@ -19187,9 +17460,8 @@ "ko_KR": "업데이트 내려받기 중...", "no_NO": "Laster ned oppdatering...", "pl_PL": "Pobieranie Aktualizacji...", - "pt_BR": "Baixando Atualização...", + "pt_BR": "Baixando atualização...", "ru_RU": "Загрузка обновления...", - "sv_SE": "Hämtar uppdatering...", "th_TH": "กำลังดาวน์โหลดอัปเดต...", "tr_TR": "Güncelleme İndiriliyor...", "uk_UA": "Завантаження оновлення...", @@ -19212,9 +17484,8 @@ "ko_KR": "도킹", "no_NO": "Forankret", "pl_PL": "Zadokowany", - "pt_BR": "Dock/TV", + "pt_BR": "TV", "ru_RU": "Стационарный режим", - "sv_SE": "Dockad", "th_TH": "ด็อก", "tr_TR": "", "uk_UA": "Док-станція", @@ -19239,7 +17510,6 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный режим", - "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์", "tr_TR": "El tipi", "uk_UA": "Портативний", @@ -19262,9 +17532,8 @@ "ko_KR": "연결 오류가 발생했습니다.", "no_NO": "Tilkoblingsfeil", "pl_PL": "Błąd Połączenia.", - "pt_BR": "Erro de Conexão.", + "pt_BR": "Erro de conexão.", "ru_RU": "Ошибка соединения", - "sv_SE": "Anslutningsfel.", "th_TH": "การเชื่อมต่อล้มเหลว", "tr_TR": "Bağlantı Hatası.", "uk_UA": "Помилка з'єднання.", @@ -19289,7 +17558,6 @@ "pl_PL": "{0} i więcej...", "pt_BR": "{0} e mais...", "ru_RU": "{0} и другие...", - "sv_SE": "{0} och fler...", "th_TH": "{0} และอื่นๆ ...", "tr_TR": "{0} ve daha fazla...", "uk_UA": "{0} та інші...", @@ -19314,7 +17582,6 @@ "pl_PL": "Błąd API.", "pt_BR": "Erro de API.", "ru_RU": "Ошибка API.", - "sv_SE": "API-fel.", "th_TH": "ข้อผิดพลาดของ API", "tr_TR": "API Hatası.", "uk_UA": "Помилка API.", @@ -19339,7 +17606,6 @@ "pl_PL": "Wczytywanie {0}", "pt_BR": "Carregando {0}", "ru_RU": "Загрузка {0}", - "sv_SE": "Läser in {0}", "th_TH": "กำลังโหลด {0}", "tr_TR": "{0} Yükleniyor", "uk_UA": "Завантаження {0}", @@ -19351,25 +17617,24 @@ "ID": "CompilingPPTC", "Translations": { "ar_SA": "تجميع الـ‫(PPTC)", - "de_DE": "PPTC wird kompiliert", - "el_GR": "Μεταγλώττιση του PPTC", - "en_US": "Compiling PPTC", - "es_ES": "Compilando PPTC", - "fr_FR": "Compilation PPTC", - "he_IL": "קימפול PPTC", + "de_DE": "PTC wird kompiliert", + "el_GR": "Μεταγλώττιση του PTC", + "en_US": "Compiling PTC", + "es_ES": "Compilando PTC", + "fr_FR": "Compilation PTC", + "he_IL": "קימפול PTC", "it_IT": "Compilazione PPTC", - "ja_JP": "PPTC をコンパイル中", - "ko_KR": "PPTC 컴파일", - "no_NO": "Sammensetter PPTC", - "pl_PL": "Kompilowanie PPTC", - "pt_BR": "Compilando PPTC", - "ru_RU": "Компиляция PPTC", - "sv_SE": "Kompilerar PPTC", - "th_TH": "กำลังคอมไพล์ PPTC", - "tr_TR": "PPTC Derleniyor", - "uk_UA": "Компіляція PPTC", + "ja_JP": "PTC をコンパイル中", + "ko_KR": "PTC 컴파일", + "no_NO": "Sammensetter PTC", + "pl_PL": "Kompilowanie PTC", + "pt_BR": "Compilando PTC", + "ru_RU": "Компиляция PTC", + "th_TH": "กำลังคอมไพล์ PTC", + "tr_TR": "PTC Derleniyor", + "uk_UA": "Компіляція PTC", "zh_CN": "编译 PPTC 缓存中", - "zh_TW": "正在編譯 PPTC" + "zh_TW": "正在編譯 PTC" } }, { @@ -19389,7 +17654,6 @@ "pl_PL": "Kompilowanie Shaderów", "pt_BR": "Compilando Shaders", "ru_RU": "Компиляция шейдеров", - "sv_SE": "Kompilerar shaders", "th_TH": "กำลังคอมไพล์ พื้นผิวและแสงเงา", "tr_TR": "Shaderlar Derleniyor", "uk_UA": "Компіляція шейдерів", @@ -19412,9 +17676,8 @@ "ko_KR": "모든 키보드", "no_NO": "Alle tastaturer", "pl_PL": "Wszystkie klawiatury", - "pt_BR": "Todos os Teclados", + "pt_BR": "Todos os teclados", "ru_RU": "Все клавиатуры", - "sv_SE": "Alla tangentbord", "th_TH": "คีย์บอร์ดทั้งหมด", "tr_TR": "Tüm Klavyeler", "uk_UA": "Всі клавіатури", @@ -19439,7 +17702,6 @@ "pl_PL": "Wybierz obsługiwany plik do otwarcia", "pt_BR": "Selecione um arquivo suportado para abrir", "ru_RU": "Выберите совместимый файл для открытия", - "sv_SE": "Välj en fil som stöds att öppna", "th_TH": "เลือกไฟล์ที่สนับสนุนเพื่อเปิด", "tr_TR": "Açmak için desteklenen bir dosya seçin", "uk_UA": "Виберіть підтримуваний файл для відкриття", @@ -19462,9 +17724,8 @@ "ko_KR": "압축 해제된 게임이 있는 폴더를 선택", "no_NO": "Velg en mappe med et pakket ut spill", "pl_PL": "Wybierz folder z rozpakowaną grą", - "pt_BR": "Selecione uma pasta com um jogo descompactado", + "pt_BR": "Selecione um diretório com um jogo extraído", "ru_RU": "Выберите папку с распакованной игрой", - "sv_SE": "Välj en mapp med ett uppackat spel", "th_TH": "เลือกโฟลเดอร์ที่มีเกมที่แตกไฟล์แล้ว", "tr_TR": "Ayrıştırılmamış oyun içeren bir klasör seçin", "uk_UA": "Виберіть теку з розпакованою грою", @@ -19487,9 +17748,8 @@ "ko_KR": "지원되는 모든 형식", "no_NO": "Alle støttede formater", "pl_PL": "Wszystkie Obsługiwane Formaty", - "pt_BR": "Todos os Formatos Suportados", + "pt_BR": "Todos os formatos suportados", "ru_RU": "Все поддерживаемые форматы", - "sv_SE": "Alla format som stöds", "th_TH": "รูปแบบที่รองรับทั้งหมด", "tr_TR": "Tüm Desteklenen Formatlar", "uk_UA": "Усі підтримувані формати", @@ -19500,26 +17760,25 @@ { "ID": "RyujinxUpdater", "Translations": { - "ar_SA": "محدث {0}", - "de_DE": "", - "el_GR": "{0} Ενημερωτής", - "en_US": "{0} Updater", - "es_ES": "Actualizador de {0}", - "fr_FR": "Mise à jour de {0}", - "he_IL": "מעדכן {0}", - "it_IT": "Aggiornamento di {0}", - "ja_JP": "{0} アップデータ", - "ko_KR": "{0} 업데이터", - "no_NO": "{0} Oppgradering", - "pl_PL": "Aktualizator {0}", - "pt_BR": "Atualizador do {0}", - "ru_RU": "{0} Обновление", - "sv_SE": "Uppdaterare för {0}", - "th_TH": "ตัวอัปเดต {0}", - "tr_TR": "{0} Güncelleyicisi", - "uk_UA": "Програма оновлення {0}", - "zh_CN": "{0} 更新", - "zh_TW": "{0} 更新程式" + "ar_SA": "محدث ريوجينكس", + "de_DE": "Ryujinx - Updater", + "el_GR": "Ryujinx Ενημερωτής", + "en_US": "Ryujinx Updater", + "es_ES": "Actualizador de Ryujinx", + "fr_FR": "Mise à jour de Ryujinx", + "he_IL": "מעדכן ריוג'ינקס", + "it_IT": "Aggiornamento di Ryujinx", + "ja_JP": "Ryujinx アップデータ", + "ko_KR": "Ryujinx 업데이터", + "no_NO": "Ryujinx Oppgradering", + "pl_PL": "Aktualizator Ryujinx", + "pt_BR": "Atualizador do Ryujinx", + "ru_RU": "Ryujinx - Обновление", + "th_TH": "ตัวอัปเดต Ryujinx", + "tr_TR": "Ryujinx Güncelleyicisi", + "uk_UA": "Програма оновлення Ryujinx", + "zh_CN": "Ryujinx 更新", + "zh_TW": "Ryujinx 更新程式" } }, { @@ -19537,9 +17796,8 @@ "ko_KR": "키보드 단축키", "no_NO": "Hurtigtaster for tastatur", "pl_PL": "Skróty Klawiszowe Klawiatury", - "pt_BR": "Atalhos do Teclado", + "pt_BR": "Atalhos do teclado", "ru_RU": "Горячие клавиши", - "sv_SE": "Snabbtangenter för tangentbord", "th_TH": "ปุ่มลัดของคีย์บอร์ด", "tr_TR": "Klavye Kısayolları", "uk_UA": "Гарячі клавіші клавіатури", @@ -19562,9 +17820,8 @@ "ko_KR": "키보드 단축키", "no_NO": "Hurtigtaster for tastatur", "pl_PL": "Skróty Klawiszowe Klawiatury", - "pt_BR": "Atalhos do Teclado", + "pt_BR": "Atalhos do teclado", "ru_RU": "Горячие клавиши", - "sv_SE": "Snabbtangenter för tangentbord", "th_TH": "ปุ่มลัดของคีย์บอร์ด", "tr_TR": "Klavye Kısayolları", "uk_UA": "Гарячі клавіші клавіатури", @@ -19587,9 +17844,8 @@ "ko_KR": "스크린샷 :", "no_NO": "Skjermbilde", "pl_PL": "Zrzut Ekranu:", - "pt_BR": "Captura de Tela:", - "ru_RU": "Скриншот:", - "sv_SE": "Skärmbild:", + "pt_BR": "Captura de tela:", + "ru_RU": "Сделать скриншот:", "th_TH": "ภาพหน้าจอ:", "tr_TR": "Ekran Görüntüsü Al:", "uk_UA": "Знімок екрана:", @@ -19614,7 +17870,6 @@ "pl_PL": "Pokaż UI:", "pt_BR": "Exibir UI:", "ru_RU": "Показать интерфейс:", - "sv_SE": "Visa gränssnitt:", "th_TH": "แสดง UI:", "tr_TR": "Arayüzü Göster:", "uk_UA": "Показати інтерфейс:", @@ -19639,7 +17894,6 @@ "pl_PL": "Pauza:", "pt_BR": "Pausar:", "ru_RU": "Пауза эмуляции:", - "sv_SE": "Paus:", "th_TH": "หยุดชั่วคราว:", "tr_TR": "Durdur:", "uk_UA": "Пауза:", @@ -19664,7 +17918,6 @@ "pl_PL": "Wycisz:", "pt_BR": "Mudo:", "ru_RU": "Выключить звук:", - "sv_SE": "Tyst:", "th_TH": "ปิดเสียง:", "tr_TR": "Sustur:", "uk_UA": "Вимкнути звук:", @@ -19687,9 +17940,8 @@ "ko_KR": "모션 컨트롤 설정", "no_NO": "Innstillinger for bevegelses kontroll", "pl_PL": "Ustawienia Sterowania Ruchowego", - "pt_BR": "Configurações do Controle de Movimento", + "pt_BR": "Configurações do controle de movimento", "ru_RU": "Настройки управления движением", - "sv_SE": "Inställningar för rörelsekontroller", "th_TH": "ตั้งค่าควบคุมการเคลื่อนไหว", "tr_TR": "Hareket Kontrol Seçenekleri", "uk_UA": "Налаштування керування рухом", @@ -19712,9 +17964,8 @@ "ko_KR": "진동 설정", "no_NO": "Innstillinger for Vibrasjon", "pl_PL": "Ustawienia Wibracji", - "pt_BR": "Configurações de Vibração", + "pt_BR": "Configurações de vibração", "ru_RU": "Настройки вибрации", - "sv_SE": "Inställningar för vibration", "th_TH": "ตั้งค่าการสั่นไหว", "tr_TR": "Titreşim Seçenekleri", "uk_UA": "Налаштування вібрації", @@ -19722,31 +17973,6 @@ "zh_TW": "震動設定" } }, - { - "ID": "ControllerLedTitle", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "LED Settings", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "LED 설정", - "no_NO": "LED-innstillinger", - "pl_PL": "", - "pt_BR": "Configurações de LED", - "ru_RU": "Настройки LED-подсветки", - "sv_SE": "LED-inställningar", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Налаштування LED", - "zh_CN": "LED 设置", - "zh_TW": "" - } - }, { "ID": "SettingsSelectThemeFileDialogTitle", "Translations": { @@ -19762,9 +17988,8 @@ "ko_KR": "테마 파일 선택", "no_NO": "Velg tema fil", "pl_PL": "Wybierz Plik Motywu", - "pt_BR": "Selecionar Arquivo de Tema", + "pt_BR": "Selecionar arquivo do tema", "ru_RU": "Выбрать файл темы", - "sv_SE": "Välj temafil", "th_TH": "เลือกธีมไฟล์", "tr_TR": "Tema Dosyası Seç", "uk_UA": "Виберіть файл теми", @@ -19782,14 +18007,13 @@ "es_ES": "Archivo de tema Xaml", "fr_FR": "Fichier thème Xaml", "he_IL": "קובץ ערכת נושא Xaml", - "it_IT": "File del tema XAML", + "it_IT": "File del tema xaml", "ja_JP": "Xaml テーマファイル", "ko_KR": "Xaml 테마 파일", "no_NO": "Xaml tema-fil", "pl_PL": "Plik Motywu Xaml", - "pt_BR": "Arquivo de Tema Xaml", + "pt_BR": "Arquivo de tema Xaml", "ru_RU": "Файл темы Xaml", - "sv_SE": "Xaml-temafil", "th_TH": "ไฟล์ธีมรูปแบบ XAML", "tr_TR": "Xaml Tema Dosyası", "uk_UA": "Файл теми Xaml", @@ -19812,9 +18036,8 @@ "ko_KR": "계정 관리 - 아바타", "no_NO": "Administrer kontoer - Profilbilde", "pl_PL": "Zarządzaj Kontami — Avatar", - "pt_BR": "Gerenciar Contas - Avatar", + "pt_BR": "Gerenciar contas - Avatar", "ru_RU": "Управление аккаунтами - Аватар", - "sv_SE": "Hantera konton - Avatar", "th_TH": "จัดการบัญชี - อวาต้า", "tr_TR": "Hesapları Yönet - Avatar", "uk_UA": "Керування обліковими записами - Аватар", @@ -19839,7 +18062,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -19864,7 +18086,6 @@ "pl_PL": "Nieznane", "pt_BR": "Desconhecido", "ru_RU": "Неизвестно", - "sv_SE": "Okänt", "th_TH": "ไม่รู้จัก", "tr_TR": "Bilinmeyen", "uk_UA": "Невідомо", @@ -19889,7 +18110,6 @@ "pl_PL": "Użycie", "pt_BR": "Uso", "ru_RU": "Применение", - "sv_SE": "Användning", "th_TH": "การใช้งาน", "tr_TR": "Kullanım", "uk_UA": "Використання", @@ -19914,7 +18134,6 @@ "pl_PL": "Zapisywalne", "pt_BR": "Gravável", "ru_RU": "Доступно для записи", - "sv_SE": "Skrivbar", "th_TH": "สามารถเขียนทับได้", "tr_TR": "Yazılabilir", "uk_UA": "Можливість запису", @@ -19937,9 +18156,8 @@ "ko_KR": "DLC 파일 선택", "no_NO": "Velg DLC-filer", "pl_PL": "Wybierz pliki DLC", - "pt_BR": "Selecionar Arquivos de DLC", + "pt_BR": "Selecionar arquivos de DLC", "ru_RU": "Выберите файлы DLC", - "sv_SE": "Välj DLC-filer", "th_TH": "เลือกไฟล์ DLC", "tr_TR": "DLC dosyalarını seç", "uk_UA": "Виберіть файли DLC", @@ -19964,7 +18182,6 @@ "pl_PL": "Wybierz pliki aktualizacji", "pt_BR": "Selecionar arquivos de atualização", "ru_RU": "Выберите файлы обновлений", - "sv_SE": "Välj uppdateringsfiler", "th_TH": "เลือกไฟล์อัพเดต", "tr_TR": "Güncelleme dosyalarını seç", "uk_UA": "Виберіть файли оновлення", @@ -19987,9 +18204,8 @@ "ko_KR": "모드 디렉터리 선택", "no_NO": "Velg modifikasjons mappe", "pl_PL": "Wybierz katalog modów", - "pt_BR": "Selecione o diretório do mod", + "pt_BR": "", "ru_RU": "Выбрать папку с модами", - "sv_SE": "Välj moddkatalog", "th_TH": "เลือกไดเรกทอรี Mods", "tr_TR": "Mod Dizinini Seç", "uk_UA": "Виберіть теку з модами", @@ -20007,19 +18223,18 @@ "es_ES": "Verificar y recortar archivo XCI", "fr_FR": "Vérifier et Réduire le fichier XCI", "he_IL": "", - "it_IT": "Controlla e riduci la dimensione del file XCI", + "it_IT": "Controlla e Trimma i file XCI ", "ja_JP": "", "ko_KR": "XCI 파일 확인 및 정리", "no_NO": "Kontroller og trim XCI-filen", "pl_PL": "", - "pt_BR": "Verifique e Reduza o Arquivo XCI", - "ru_RU": "Проверить и обрезать XCI файл", - "sv_SE": "Kontrollera och optimera XCI-filer", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Перевірити та Обрізати XCI файл", - "zh_CN": "检查并瘦身 XCI 文件", - "zh_TW": "檢查及修剪 XCI 檔案" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20032,19 +18247,18 @@ "es_ES": "Esta función verificará el espacio vacío y después recortará el archivo XCI para ahorrar espacio en disco", "fr_FR": "Cette fonction va vérifier l'espace vide, puis réduire le fichier XCI pour économiser de l'espace de disque dur.", "he_IL": "", - "it_IT": "Questa funzionalità controllerà prima lo spazio libero e poi ridurrà la dimensione del file XCI per risparmiare spazio su disco.", + "it_IT": "Questa funzionalita controllerà prima lo spazio libero e poi trimmerà il file XCI per liberare dello spazio.", "ja_JP": "", "ko_KR": "이 기능은 먼저 충분한 공간을 확보한 다음 XCI 파일을 트리밍하여 디스크 공간을 절약합니다.", "no_NO": "Denne funksjonen kontrollerer først hvor mye plass som er ledig, og trimmer deretter XCI-filen for å spare diskplass.", "pl_PL": "", - "pt_BR": "Esta função primeiro verificará o espaço vazio e depois reduzirá o arquivo XCI para economizar espaço em disco.", - "ru_RU": "Эта функция сначала проверит наличие пустого пространства, а затем обрежет файл XCI, чтобы сэкономить место на диске.", - "sv_SE": "Denna funktion kommer först att kontrollera ledigt utrymme och sedan optimera XCI-filen för att spara diskutrymme.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Ця функція спочатку перевірить наявність порожнього місця, після чого обріже файл XCI для економії місця на диску.", - "zh_CN": "这个功能将会先检查 XCI 文件,再对其执行瘦身操作以节约磁盘空间。", - "zh_TW": "此功能首先檢查 XCI 檔案是否有可修剪的字元,然後修剪檔案以節省儲存空間。" + "uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20057,19 +18271,18 @@ "es_ES": "Tamaño de archivo actual: {0:n} MB\nTamaño de datos de juego: {1:n} MB\nAhorro de espacio en disco: {2:n} MB", "fr_FR": "Taille actuelle du fichier: {0:n} MB\nTaille des données de jeux: {1:n} MB\nÉconomie d'espaces sur le disque: {2:n} MB", "he_IL": "", - "it_IT": "Dimensione attuale del file: {0:n} MB\nDimensione dei dati del gioco: {1:n} MB\nRisparmio spazio su disco: {2:n} MB", + "it_IT": "Dimensioni Attuali File: {0:n} MB\nDimensioni Dati Gioco: {1:n} MB\nRisparimio Spazio Disco: {2:n} MB", "ja_JP": "", "ko_KR": "현재 파일 크기 : {0:n}MB\n게임 데이터 크기 : {1:n}MB\n디스크 공간 절약 : {2:n}MB", "no_NO": "Nåværende filstørrelse: 0:n MB\nSpilldatastørrelse: {1:n} MB\nDiskplassbesparelse: {2:n} MB", "pl_PL": "", - "pt_BR": "Tamanho atual do arquivo: {0:n} MB\nTamanho dos dados do jogo: {1:n} MB\nEconomia de espaço em disco: {2:n} MB", - "ru_RU": "Размер текущего файла: {0:n} Мб\nРазмер игровых данных: {1:n} MB\nЭкономия дискового пространства: {2:n} Мб", - "sv_SE": "Aktuell filstorlek: {0:n} MB\nStorlek för speldata: {1:n} MB\nSparat diskutrymme: {2:n} MB", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB", - "zh_CN": "当前文件大小: {0:n} MB\n游戏数据大小: {1:n} MB\n节约的磁盘空间: {2:n} MB", - "zh_TW": "現在的檔案大小: {0:n} MB\n遊戲資料大小: {1:n} MB\n節省的儲存空間: {2:n} MB" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20082,19 +18295,18 @@ "es_ES": "El archivo XCI no necesita ser recortado. Verifica los logs para más detalles.", "fr_FR": "Fichier XCI n'a pas besoin d'être réduit. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Non è necessario ridurre la dimensione del file XCI. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI non deve essere trimmato. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 트리밍할 필요가 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen trenger ikke å trimmes. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "O arquivo XCI não precisa ser reduzido. Verifique os logs para mais detalhes", - "ru_RU": "Файл XCI не нуждается в обрезке. Проверьте логи для получения более подробной информации", - "sv_SE": "XCI-filen behöver inte optimeras. Kontrollera loggen för mer information", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл не потребує обрізання. Перевірте журнали (logs) для отримання додаткової інформації", - "zh_CN": "XCI 文件不需要被瘦身。查看日志以获得更多细节。", - "zh_TW": "XCI 檔案不需要修剪。檢查日誌以取得更多資訊" + "uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20107,19 +18319,18 @@ "es_ES": "El recorte del archivo XCI no puede ser deshecho. Verifica los registros para más detalles.", "fr_FR": "Fichier XCI ne peut pas être dé-réduit. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI non può essere riportato alla sua dimensione originale. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI non può essere untrimmato. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 트리밍을 해제할 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen kan ikke trimmes. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "O arquivo XCI reduzido não pode ser desfeito. Verifique os logs para mais detalhes", - "ru_RU": "XCI файл не может быть обрезан. Проверьте логи для получения более подробной информации", - "sv_SE": "XCI-filen kan inte avoptimeras. Kontrollera loggen för mer information", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали (logs) для отримання додаткової інформації", - "zh_CN": "XCI 文件不能被瘦身。查看日志以获得更多细节。", - "zh_TW": "XCI 檔案不能被修剪。檢查日誌以取得更多資訊" + "uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20132,19 +18343,18 @@ "es_ES": "El archivo XCI es de solo Lectura y no se le puede escribir. Lee el registro para más información.", "fr_FR": "Fichier XCI est en Lecture Seule et n'a pas pu être rendu accessible en écriture. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI è in sola lettura e non può essere reso accessibile in scrittura. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI è in sola lettura e non può essere reso Scrivibile. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 읽기 전용이므로 쓰기 가능하게 만들 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen er skrivebeskyttet og kunne ikke gjøres skrivbar. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "O arquivo XCI é somente leitura e não pôde ser tornado gravável. Verifique os logs para mais detalhes", - "ru_RU": "Файл XCI доступен только для чтения и его невозможно сделать доступным для записи. Проверьте логи для получения более подробной информации", - "sv_SE": "XCI-filen är skrivskyddad och kunde inte göras skrivbar. Kontrollera loggen för mer information", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали (logs) для отримання додаткової інформації", - "zh_CN": "XCI 文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。", - "zh_TW": "XCI 檔案是唯讀,並且無法改成可寫入。檢查日誌以取得更多資訊" + "uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20157,19 +18367,18 @@ "es_ES": "El archivo XCI ha cambiado de tamaño desde que fue escaneado. Verifica que no se esté escribiendo al archivo y vuelve a intentarlo.", "fr_FR": "Fichier XCI a changé en taille depuis qu'il a été scanné. Vérifier que le fichier n'est pas en cours d'écriture et réessayer.", "he_IL": "", - "it_IT": "La dimensione del file XCI è cambiata da quando è stato scansionato. Controlla che il file non stia venendo scritto da qualche altro programma e poi riprova.", + "it_IT": "Il file XCI ha cambiato dimensioni da quando è stato scansionato. Controlla che il file non stia venendo scritto da qualche altro programma e poi riprova.", "ja_JP": "", "ko_KR": "XCI 파일이 스캔된 후 크기가 변경되었습니다. 파일이 쓰여지고 있지 않은지 확인하고 다시 시도하세요.", "no_NO": "XCI File har endret størrelse siden den ble skannet. Kontroller at det ikke skrives til filen, og prøv på nytt.", "pl_PL": "", - "pt_BR": "O arquivo XCI mudou de tamanho desde que foi escaneado. Verifique se o arquivo não está sendo gravado e tente novamente.", - "ru_RU": "Файл XCI изменился в размере после сканирования. Проверьте, не производится ли запись в этот файл, и повторите попытку.", - "sv_SE": "XCI-filen har ändrats i storlek sedan den lästes av. Kontrollera att filen inte skrivs till och försök igen.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову", - "zh_CN": "XCI 文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。", - "zh_TW": "XCI 檔案大小比較上次的掃瞄已經改變。請檢查檔案是否未被寫入,然後再嘗試。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20182,19 +18391,18 @@ "es_ES": "El archivo XCI tiene datos en el área de espacio libre, no es seguro recortar.", "fr_FR": "Fichier XCI a des données dans la zone d'espace libre, ce n'est pas sûr de réduire", "he_IL": "", - "it_IT": "Il file XCI contiene dei dati nello spazio libero, non è sicuro ridurne la dimensione", + "it_IT": "Il file XCI ha dati nello spazio libero, non è sicuro effettuare il trimming", "ja_JP": "", "ko_KR": "XCI 파일에 여유 공간 영역에 데이터가 있으므로 트리밍하는 것이 안전하지 않음", "no_NO": "XCI-filen har data i ledig plass, og det er ikke trygt å trimme den", "pl_PL": "", - "pt_BR": "O arquivo XCI tem dados na área de espaço livre, não é seguro reduzi-lo", - "ru_RU": "XCI файл содержит данные в пустой зоне, обрезать его небезопасно", - "sv_SE": "XCI-filen har data i det lediga utrymmet. Den är inte säker att optimera", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна", - "zh_CN": "XCI 文件的空闲区域内有数据,不能安全瘦身。", - "zh_TW": "XCI 檔案有數據儲存於可節省儲存空間的區域,所以試圖修剪並不安全" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20207,19 +18415,18 @@ "es_ES": "El archivo XCI contiene datos inválidos. Lee el registro para más información.", "fr_FR": "Fichier XCI contient des données invalides. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI contiene dei dati non validi. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI contiene dati invlidi. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일에 유효하지 않은 데이터가 포함되어 있습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen inneholder ugyldige data. Sjekk loggene for ytterligere detaljer", "pl_PL": "", - "pt_BR": "O arquivo XCI contém dados inválidos. Verifique os logs para obter mais detalhes", - "ru_RU": "Файл XCI содержит недопустимые данные. Проверьте логи для получения дополнительной информации", - "sv_SE": "XCI-filen innehåller ogiltig data. Kontrollera loggen för mer information", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали (logs) для отримання додаткової інформації", - "zh_CN": "XCI 文件含有无效数据。查看日志以获得更多细节。", - "zh_TW": "XCI 檔案帶有無效的數據。檢查日誌以取得更多資訊" + "uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20232,19 +18439,18 @@ "es_ES": "El archivo XCI no se puede abrir para escribirlo. Lee el registro para más información.", "fr_FR": "Fichier XCI n'a pas pu été ouvert pour écriture. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI non può essere aperto in scrittura. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI non può essere aperto per essere scritto. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일을 쓰기 위해 열 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen kunne ikke åpnes for skriving. Sjekk loggene for ytterligere detaljer", "pl_PL": "", - "pt_BR": "O arquivo XCI não pôde ser aberto para gravação. Verifique os logs para mais detalhes", - "ru_RU": "XCI файл не удалось открыть для записи. Проверьте логи для получения дополнительной информации", - "sv_SE": "XCI-filen kunde inte öppnas för skrivning. Kontrollera loggen för mer information", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації", - "zh_CN": "XCI 文件不能被读写。查看日志以获得更多细节。", - "zh_TW": "XCI 檔案不能被寫入。檢查日誌以取得更多資訊" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20257,19 +18463,18 @@ "es_ES": "El recorte del archivo XCI falló", "fr_FR": "Réduction du fichier XCI a échoué", "he_IL": "", - "it_IT": "Riduzione della dimensione del file XCI fallita", + "it_IT": "Trimming del file XCI fallito", "ja_JP": "", "ko_KR": "XCI 파일 트리밍에 실패", "no_NO": "Trimming av XCI-filen mislyktes", "pl_PL": "", - "pt_BR": "A redução do arquivo XCI falhou", - "ru_RU": "Обрезка файла XCI не удалась", - "sv_SE": "Optimering av XCI-filen misslyckades", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Не вдалося обрізати файл XCI", - "zh_CN": "XCI 文件瘦身失败", - "zh_TW": "修剪 XCI 檔案失敗" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20282,19 +18487,18 @@ "es_ES": "La operación fue cancelada", "fr_FR": "L'opération a été annulée", "he_IL": "", - "it_IT": "L'operazione è stata annullata", + "it_IT": "Operazione Cancellata", "ja_JP": "", "ko_KR": "작업이 취소됨", "no_NO": "Operasjonen ble avlyst", "pl_PL": "", - "pt_BR": "A operação foi cancelada", - "ru_RU": "Операция была отменена", - "sv_SE": "Åtgärden avbröts", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Операція перервана", - "zh_CN": "操作已取消", - "zh_TW": "修剪已取消" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20307,19 +18511,18 @@ "es_ES": "No se realizó ninguna operación", "fr_FR": "Aucune opération a été faite", "he_IL": "", - "it_IT": "Non è stata effettuata alcuna operazione", + "it_IT": "Nessuna operazione è stata effettuata", "ja_JP": "", "ko_KR": "작업이 수행되지 않음", "no_NO": "Ingen operasjon ble utført", "pl_PL": "", - "pt_BR": "Nenhuma operação foi realizada", - "ru_RU": "Операция не была проведена", - "sv_SE": "Ingen åtgärd genomfördes", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Операція не проводилася", - "zh_CN": "未执行操作", - "zh_TW": "沒有修剪" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20337,9 +18540,8 @@ "ko_KR": "사용자 프로필 관리자", "no_NO": "Bruker Profiler Behandler", "pl_PL": "Menedżer Profili Użytkowników", - "pt_BR": "Gerenciador de Perfis de Usuário", - "ru_RU": "Менеджер учётных записей", - "sv_SE": "Hanterare för användarprofiler", + "pt_BR": "Gerenciador de perfis de usuário", + "ru_RU": "Менеджер учетных записей", "th_TH": "จัดการโปรไฟล์ผู้ใช้", "tr_TR": "Kullanıcı Profillerini Yönet", "uk_UA": "Менеджер профілів користувачів", @@ -20362,9 +18564,8 @@ "ko_KR": "치트 관리자", "no_NO": "Juksing behandler", "pl_PL": "Menedżer Kodów", - "pt_BR": "Gerenciador de Trapaças", + "pt_BR": "Gerenciador de Cheats", "ru_RU": "Менеджер читов", - "sv_SE": "Fuskhanterare", "th_TH": "จัดการสูตรโกง", "tr_TR": "Oyun Hilelerini Yönet", "uk_UA": "Менеджер читів", @@ -20387,9 +18588,8 @@ "ko_KR": "{0} ({1})의 내려받기 가능한 콘텐츠 관리", "no_NO": "Behandle nedlastbart innhold for {0} ({1})", "pl_PL": "Menedżer Zawartości do Pobrania", - "pt_BR": "Gerenciar conteúdo para download para {0} ({1})", + "pt_BR": "Gerenciador de DLC", "ru_RU": "Управление DLC для {0} ({1})", - "sv_SE": "Hantera hämtningsbart innehåll för {0} ({1})", "th_TH": "จัดการ DLC ที่ดาวน์โหลดได้สำหรับ {0} ({1})", "tr_TR": "Oyun DLC'lerini Yönet", "uk_UA": "Менеджер вмісту для завантаження", @@ -20414,7 +18614,6 @@ "pl_PL": "Zarządzaj modami dla {0} ({1})", "pt_BR": "Gerenciar Mods para {0} ({1})", "ru_RU": "Управление модами для {0} ({1})", - "sv_SE": "Hantera moddar för {0} ({1})", "th_TH": "จัดการม็อดที่ดาวน์โหลดได้สำหรับ {0} ({1})", "tr_TR": "", "uk_UA": "Керувати модами для {0} ({1})", @@ -20437,9 +18636,8 @@ "ko_KR": "타이틀 업데이트 관리자", "no_NO": "Tittel oppdatering behandler", "pl_PL": "Menedżer Aktualizacji Tytułu", - "pt_BR": "Gerenciador de Atualização de Título", + "pt_BR": "Gerenciador de atualizações", "ru_RU": "Менеджер обновлений игр", - "sv_SE": "Hanterare för speluppdateringar", "th_TH": "จัดการอัปเดตหัวข้อ", "tr_TR": "Oyun Güncellemelerini Yönet", "uk_UA": "Менеджер оновлення назв", @@ -20457,19 +18655,18 @@ "es_ES": "Recortador de archivos XCI", "fr_FR": "Rogneur de fichier XCI", "he_IL": "", - "it_IT": "Riduci dimensioni dei file XCI", + "it_IT": "", "ja_JP": "", "ko_KR": "XCI 파일 트리머", - "no_NO": "", + "no_NO": "XCI File Trimmer", "pl_PL": "", - "pt_BR": "Redutor de Arquivo XCI", - "ru_RU": "Уменьшение размера XCI файлов", - "sv_SE": "Optimera XCI-filer", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка XCI Файлів", - "zh_CN": "XCI 文件瘦身器", - "zh_TW": "XCI 檔案修剪器" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20482,19 +18679,18 @@ "es_ES": "{0} de {1} Título(s) seleccionado(s)", "fr_FR": "{0} sur {1} Fichier(s) Sélectionnés", "he_IL": "", - "it_IT": "{0} di {1} titoli selezionati", + "it_IT": "{0} di {1} Titolo(i) Selezionati", "ja_JP": "", "ko_KR": "{1}개 타이틀 중 {0}개 선택됨", "no_NO": "{0} av {1} Valgte tittel(er)", "pl_PL": "", - "pt_BR": "{0} de {1} Título(s) Selecionado(s)", - "ru_RU": "{0} из {1} файла(ов) выбрано", - "sv_SE": "{0} av {1} spel markerade", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0} з {1} тайтл(ів) обрано", - "zh_CN": "在 {1} 中选中了 {0} 个游戏 ", - "zh_TW": "已選擇 {1} 之 {0} 的遊戲" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20507,19 +18703,18 @@ "es_ES": "{0} de {1} Título(s) seleccionado(s) ({2} mostrado(s))", "fr_FR": "{0} sur {1} Fichier(s) Sélectionnés ({2} affiché(s)", "he_IL": "", - "it_IT": "{0} di {1} titoli selezionati ({2} visualizzati)", + "it_IT": "{0} of {1} Titolo(i) Selezionati ({2} visualizzato)", "ja_JP": "", "ko_KR": "{1}개 타이틀 중 {0}개 선택됨({2}개 표시됨)", "no_NO": "{0} av {1} Tittel(er) valgt ({2} vises)", "pl_PL": "", - "pt_BR": "{0} de {1} Título(s) Selecionado(s) ({2} exibidos)", - "ru_RU": "{0} из {1} файла(ов) выбрано ({2} показано)", - "sv_SE": "{0} av {1} spel markerade ({2} visade)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)", - "zh_CN": "在 {1} 中选中了 {0} 个游戏 (显示了 {2} 个)", - "zh_TW": "已選擇 {1} 之 {0} 的遊戲 (已顯示 {2} 個)" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20532,19 +18727,18 @@ "es_ES": "Recortando {0} Título(s)...", "fr_FR": "Réduction de {0} Fichier(s)...", "he_IL": "", - "it_IT": "Riduzione delle dimensioni di {0} titolo/i...", + "it_IT": "Trimming {0} Titolo(i)...", "ja_JP": "", "ko_KR": "{0}개의 타이틀을 트리밍 중...", "no_NO": "Trimming av {0} tittel(er)...", "pl_PL": "", - "pt_BR": "Reduzindo {0} Título(s)...", - "ru_RU": "Обрезка {0} файла(ов)...", - "sv_SE": "Optimerar {0} spel...", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка {0} тайтл(ів)...", - "zh_CN": "{0} 个游戏瘦身中。。。", - "zh_TW": "正在修剪 {0} 個遊戲..." + "zh_CN": "", + "zh_TW": "" } }, { @@ -20557,19 +18751,18 @@ "es_ES": "Deshaciendo recorte de {0} Título(s)...", "fr_FR": "Dé-Réduction de {0} Fichier(s)...", "he_IL": "", - "it_IT": "Ripristino alle dimensioni originali di {0} titolo/i...", + "it_IT": "Untrimming {0} Titolo(i)...", "ja_JP": "", "ko_KR": "{0}개의 타이틀을 트리밍 해제 중...", "no_NO": "Untrimming {0} Tittel(er)...", "pl_PL": "", - "pt_BR": "Desfazendo redução {0} Título(s)...", - "ru_RU": "Отмена обрезки {0} файла(ов)...", - "sv_SE": "Avoptimerar {0} spel...", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Необрізаних {0} тайтл(ів)...", - "zh_CN": "正在精简 {0} 个游戏", - "zh_TW": "正在反修剪 {0} 個遊戲..." + "zh_CN": "", + "zh_TW": "" } }, { @@ -20587,14 +18780,13 @@ "ko_KR": "실패", "no_NO": "Mislyktes", "pl_PL": "", - "pt_BR": "Falhou", - "ru_RU": "Ошибка", - "sv_SE": "Misslyckades", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Невдача", - "zh_CN": "失败", - "zh_TW": "失敗" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20607,19 +18799,18 @@ "es_ES": "Ahorro potencial", "fr_FR": "Économies potentielles d'espace de disque dur", "he_IL": "", - "it_IT": "Risparmio potenziale", + "it_IT": "Potenziali Salvataggi", "ja_JP": "", "ko_KR": "잠재적 비용 절감", "no_NO": "Potensielle besparelser", "pl_PL": "", - "pt_BR": "Economia Potencial", - "ru_RU": "Потенциально освобождено места", - "sv_SE": "Möjlig besparning", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Потенційна економія", - "zh_CN": "潜在的储存空间节省", - "zh_TW": "潛在節省的儲存空間" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20632,19 +18823,18 @@ "es_ES": "Ahorro real", "fr_FR": "Économies actualles d'espace de disque dur", "he_IL": "", - "it_IT": "Risparmio effettivo", + "it_IT": "Effettivi Salvataggi", "ja_JP": "", "ko_KR": "실제 비용 절감", "no_NO": "Faktiske besparelser", "pl_PL": "", - "pt_BR": "Economia Real", - "ru_RU": "Реально освобождено места", - "sv_SE": "Faktisk besparning", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Зекономлено", - "zh_CN": "实际的储存空间节省", - "zh_TW": "實際節省的儲存空間" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20657,14 +18847,13 @@ "es_ES": "", "fr_FR": "{0:n0} Mo", "he_IL": "", - "it_IT": "{0:n0} MB", + "it_IT": "", "ja_JP": "", "ko_KR": "{0:n0}MB", "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "{0:n0} Мб", - "sv_SE": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0:n0} Мб", @@ -20682,19 +18871,18 @@ "es_ES": "Seleccionar mostrado(s)", "fr_FR": "Sélectionner Affiché", "he_IL": "", - "it_IT": "Seleziona visualizzati", + "it_IT": "Seleziona Visualizzati", "ja_JP": "", "ko_KR": "표시됨 선택", "no_NO": "Velg vist", "pl_PL": "", - "pt_BR": "Marcar Todos", - "ru_RU": "Выбрать то что показано", - "sv_SE": "Markera visade", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Вибрати показані", - "zh_CN": "选定显示的", - "zh_TW": "選擇已顯示" + "uk_UA": "Вибрати показане", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20707,19 +18895,18 @@ "es_ES": "Deseleccionar mostrado(s)", "fr_FR": "Désélectionner Affiché", "he_IL": "", - "it_IT": "Deseleziona visualizzati", + "it_IT": "Deselziona Visualizzati", "ja_JP": "", "ko_KR": "표시됨 선택 취소", "no_NO": "Opphev valg av Vist", "pl_PL": "", - "pt_BR": "Desmarcar Todos", - "ru_RU": "Отменить выбор показанного", - "sv_SE": "Avmarkera visade", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Скасувати вибір показаного", - "zh_CN": "反选显示的", - "zh_TW": "取消選擇已顯示" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20737,14 +18924,13 @@ "ko_KR": "타이틀", "no_NO": "Tittel", "pl_PL": "", - "pt_BR": "Título", - "ru_RU": "Приложение", - "sv_SE": "Titel", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Назва", - "zh_CN": "标题", - "zh_TW": "名稱" + "uk_UA": "Заголовок", + "zh_CN": "", + "zh_TW": "" } }, { @@ -20757,19 +18943,18 @@ "es_ES": "Ahorro de espacio", "fr_FR": "Économies de disque dur", "he_IL": "", - "it_IT": "Spazio risparmiato", + "it_IT": "Salvataggio Spazio", "ja_JP": "", "ko_KR": "공간 절약s", "no_NO": "Plassbesparelser", "pl_PL": "", - "pt_BR": "Economia de Espaço", - "ru_RU": "Сохранение места на диске", - "sv_SE": "Utrymmesbesparning", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Економія місця", - "zh_CN": "节省空间", - "zh_TW": "節省的儲存空間" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20782,19 +18967,18 @@ "es_ES": "Recortar", "fr_FR": "Réduire", "he_IL": "", - "it_IT": "Riduci dimensioni", + "it_IT": "", "ja_JP": "", "ko_KR": "트림", "no_NO": "", "pl_PL": "", - "pt_BR": "Reduzir XCI", - "ru_RU": "Обрезать", - "sv_SE": "Optimera", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка", - "zh_CN": "瘦身", - "zh_TW": "修剪" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20807,19 +18991,18 @@ "es_ES": "Deshacer recorte", "fr_FR": "Dé-Réduire", "he_IL": "", - "it_IT": "Riporta alle dimensioni originali", + "it_IT": "", "ja_JP": "", "ko_KR": "언트림", "no_NO": "Utrim", "pl_PL": "", - "pt_BR": "Desfazer Redução", - "ru_RU": "Отмена обрезки", - "sv_SE": "Avoptimera", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Зшивання", - "zh_CN": "取消精简", - "zh_TW": "反修剪" + "zh_CN": "", + "zh_TW": "" } }, { @@ -20832,17 +19015,16 @@ "es_ES": "{0} nueva(s) actualización(es) agregada(s)", "fr_FR": "{0} nouvelle(s) mise(s) à jour ajoutée(s)", "he_IL": "", - "it_IT": "{0} nuovo/i aggiornamento/i aggiunto/i", + "it_IT": "{0} aggiornamento/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새 업데이트가 추가됨", "no_NO": "{0} ny(e) oppdatering(er) lagt til", "pl_PL": "", "pt_BR": "{0} nova(s) atualização(ões) adicionada(s)", - "ru_RU": "Добавлено {0} новых обновлений", - "sv_SE": "{0} nya uppdatering(ar) lades till", + "ru_RU": "", "th_TH": "{0} อัพเดตที่เพิ่มมาใหม่", "tr_TR": "", - "uk_UA": "{0} нових оновлень додано", + "uk_UA": "{0} нове оновлення додано", "zh_CN": "{0} 个更新被添加", "zh_TW": "已加入 {0} 個遊戲更新" } @@ -20857,14 +19039,13 @@ "es_ES": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.", "fr_FR": "Les mises à jour incluses avec le jeu ne peuvent pas être supprimées mais peuvent être désactivées.", "he_IL": "", - "it_IT": "Gli aggiornamenti inclusi non possono essere rimossi, ma solo disabilitati.", + "it_IT": "Gli aggiornamenti inclusi non possono essere eliminati, ma solo disattivati", "ja_JP": "", "ko_KR": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.", "no_NO": "Medfølgende oppdateringer kan ikke fjernes, bare deaktiveres.", "pl_PL": "", "pt_BR": "Atualizações incorporadas não podem ser removidas, apenas desativadas.", - "ru_RU": "Обновления бандлов не могут быть удалены, только отключены.", - "sv_SE": "Bundlade uppdateringar kan inte tas bort, endast inaktiveras.", + "ru_RU": "", "th_TH": "แพ็คที่อัพเดตมาไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น", "tr_TR": "", "uk_UA": "Вбудовані оновлення не можуть бути видалені, лише вимкнені.", @@ -20887,12 +19068,11 @@ "ko_KR": "{0} [{1}]에 사용 가능한 치트", "no_NO": "Juks tilgjengelig for {0} [{1}]", "pl_PL": "Kody Dostępne dla {0} [{1}]", - "pt_BR": "Trapaças disponíveis para {0} [{1}]", + "pt_BR": "Cheats disponíveis para {0} [{1}]", "ru_RU": "Доступные читы для {0} [{1}]", - "sv_SE": "Fusk tillgängliga för {0} [{1}]", "th_TH": "สูตรโกงมีให้สำหรับ {0} [{1}]", "tr_TR": "{0} için Hile mevcut [{1}]", - "uk_UA": "Чит-коди доступні для {0} [{1}]", + "uk_UA": "Коди доступні для {0} [{1}]", "zh_CN": "适用于 {0} [{1}] 的金手指", "zh_TW": "可用於 {0} [{1}] 的密技" } @@ -20914,7 +19094,6 @@ "pl_PL": "Identyfikator wersji:", "pt_BR": "ID da Build:", "ru_RU": "ID версии:", - "sv_SE": "Bygg-id:", "th_TH": "รหัสการสร้าง:", "tr_TR": "", "uk_UA": "ID збірки:", @@ -20932,18 +19111,17 @@ "es_ES": "", "fr_FR": "Les DLC inclus avec le jeu ne peuvent pas être supprimés mais peuvent être désactivés.", "he_IL": "", - "it_IT": "I DLC inclusi non possono essere rimossi, ma solo disabilitati.", + "it_IT": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.", "ja_JP": "", "ko_KR": "번들 DLC는 제거할 수 없으며 비활성화만 가능합니다.", "no_NO": "Medfølgende DLC kan ikke fjernes, bare deaktiveres.", "pl_PL": "", "pt_BR": "DLCs incorporadas não podem ser removidas, apenas desativadas.", - "ru_RU": "DLC бандлов не могут быть удалены, только отключены.", - "sv_SE": "Bundlade DLC kan inte tas bort, endast inaktiveras.", + "ru_RU": "", "th_TH": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น", "tr_TR": "", - "uk_UA": "Комплектні DLC (бандли) не можуть бути видаленими, лише вимкненими.", - "zh_CN": "游戏整合的 DLC 无法移除,可尝试禁用。", + "uk_UA": "Вбудований DLC не може бути видаленим, лише вимкненим.", + "zh_CN": "游戏整合的DLC无法移除,可尝试禁用。", "zh_TW": "附帶的 DLC 只能被停用而無法被刪除。" } }, @@ -20957,19 +19135,18 @@ "es_ES": "", "fr_FR": "{0} DLC(s) disponibles", "he_IL": "{0} הרחבות משחק", - "it_IT": "{0} DLC disponibile/i", + "it_IT": "", "ja_JP": "", "ko_KR": "{0} DLC 사용 가능", "no_NO": "{0} Nedlastbare innhold(er)", "pl_PL": "", - "pt_BR": "{0} DLC(s) disponíveis", - "ru_RU": "{0} доступных DLC", - "sv_SE": "{0} DLC(er) tillgängliga", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0} DLC доступно", "zh_CN": "{0} 个 DLC", - "zh_TW": "{0} 個可下載內容" + "zh_TW": "" } }, { @@ -20982,18 +19159,17 @@ "es_ES": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "he_IL": "", - "it_IT": "{0} nuovo/i DLC aggiunto/i", + "it_IT": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "no_NO": "{0} nytt nedlastbart innhold lagt til", "pl_PL": "", "pt_BR": "{0} novo(s) conteúdo(s) para download adicionado(s)", - "ru_RU": "Добавлено {0} новых DLC", - "sv_SE": "{0} nya hämtningsbara innehåll lades till", + "ru_RU": "", "th_TH": "{0} DLC ใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нового завантажувального вмісту додано", - "zh_CN": "{0} 个 DLC 被添加", + "zh_CN": "{0} 个DLC被添加", "zh_TW": "已加入 {0} 個 DLC" } }, @@ -21007,18 +19183,17 @@ "es_ES": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "he_IL": "", - "it_IT": "{0} nuovo/i DLC aggiunto/i", + "it_IT": "{0} contenuto/i scaricabile/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "no_NO": "{0} nytt nedlastbart innhold lagt til", "pl_PL": "", "pt_BR": "{0} novo(s) conteúdo(s) para download adicionado(s)", - "ru_RU": "Добавлено {0} новых DLC", - "sv_SE": "{0} nya hämtningsbara innehåll lades till", + "ru_RU": "", "th_TH": "{0} ใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нового завантажувального вмісту додано", - "zh_CN": "{0} 个 DLC 被添加", + "zh_CN": "{0} 个DLC被添加", "zh_TW": "已加入 {0} 個 DLC" } }, @@ -21032,18 +19207,17 @@ "es_ES": "Se eliminaron {0} contenido(s) descargable(s) faltantes", "fr_FR": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)", "he_IL": "", - "it_IT": "{0} DLC mancante/i rimosso/i", + "it_IT": "{0} contenuto/i scaricabile/i mancante/i rimosso/i", "ja_JP": "", "ko_KR": "{0}개의 내려받기 가능한 콘텐츠가 제거됨", "no_NO": "{0} manglende nedlastbart innhold fjernet", "pl_PL": "", "pt_BR": "{0} conteúdo(s) para download ausente(s) removido(s)", - "ru_RU": "{0} отсутствующих DLC удалено", - "sv_SE": "{0} saknade hämtningsbara innehåll togs bort", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0} відсутнього завантажувального вмісту видалено", - "zh_CN": "{0} 个失效的 DLC 已移除", + "zh_CN": "{0} 个失效的DLC已移除", "zh_TW": "已刪除 {0} 個遺失的 DLC" } }, @@ -21057,14 +19231,13 @@ "es_ES": "Se agregaron {0} nueva(s) actualización(es)", "fr_FR": "{0} nouvelle(s) mise(s) à jour ajoutée(s)", "he_IL": "", - "it_IT": "{0} nuovo/i aggiornamento/i aggiunto/i", + "it_IT": "{0} aggiornamento/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새 업데이트가 추가됨", "no_NO": "{0} ny(e) oppdatering(er) lagt til", "pl_PL": "", "pt_BR": "{0} nova(s) atualização(ões) adicionada(s)", - "ru_RU": "{0} новых обновлений добавлено", - "sv_SE": "{0} nya uppdatering(ar) lades till", + "ru_RU": "", "th_TH": "{0} อัพเดตใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нових оновлень додано", @@ -21088,8 +19261,7 @@ "no_NO": "{0} manglende oppdatering(er) fjernet", "pl_PL": "", "pt_BR": "{0} atualização(ões) ausente(s) removida(s)", - "ru_RU": "{0} отсутствующих обновлений удалено", - "sv_SE": "{0} saknade uppdatering(ar) togs bort", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0} відсутніх оновлень видалено", @@ -21114,7 +19286,6 @@ "pl_PL": "{0} Mod(y/ów)", "pt_BR": "", "ru_RU": "Моды для {0} ", - "sv_SE": "{0} modd(ar)", "th_TH": "{0} ม็อด", "tr_TR": "{0} Mod(lar)", "uk_UA": "{0} мод(ів)", @@ -21139,7 +19310,6 @@ "pl_PL": "Edytuj Zaznaczone", "pt_BR": "Editar selecionado", "ru_RU": "Изменить выбранные", - "sv_SE": "Redigera markerade", "th_TH": "แก้ไขที่เลือกแล้ว", "tr_TR": "Seçiliyi Düzenle", "uk_UA": "Редагувати вибране", @@ -21162,14 +19332,13 @@ "ko_KR": "계속", "no_NO": "Fortsett", "pl_PL": "", - "pt_BR": "Continuar", - "ru_RU": "Продолжить", - "sv_SE": "Fortsätt", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Продовжити", - "zh_CN": "继续", - "zh_TW": "繼續" + "zh_CN": "", + "zh_TW": "" } }, { @@ -21189,7 +19358,6 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", - "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -21214,7 +19382,6 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", - "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -21239,7 +19406,6 @@ "pl_PL": "Odrzuć", "pt_BR": "Descartar", "ru_RU": "Отменить", - "sv_SE": "Förkasta", "th_TH": "ละทิ้ง", "tr_TR": "Iskarta", "uk_UA": "Скасувати", @@ -21262,9 +19428,8 @@ "ko_KR": "일시 중지됨", "no_NO": "Satt på pause", "pl_PL": "Wstrzymano", - "pt_BR": "Pausado", + "pt_BR": "", "ru_RU": "Приостановлено", - "sv_SE": "Pausad", "th_TH": "หยุดชั่วคราว", "tr_TR": "Durduruldu", "uk_UA": "Призупинено", @@ -21287,9 +19452,8 @@ "ko_KR": "프로필 이미지 설정", "no_NO": "Angi profilbilde", "pl_PL": "Ustaw Obraz Profilu", - "pt_BR": "Definir Imagem de Perfil", + "pt_BR": "Definir imagem de perfil", "ru_RU": "Установить аватар", - "sv_SE": "Välj profilbild", "th_TH": "ตั้งค่ารูปโปรไฟล์", "tr_TR": "Profil Resmi Ayarla", "uk_UA": "Встановити зображення профілю", @@ -21312,9 +19476,8 @@ "ko_KR": "이름 필수 입력", "no_NO": "Navn er påkrevd", "pl_PL": "Nazwa jest wymagana", - "pt_BR": "Nome é obrigatório", + "pt_BR": "É necessário um nome", "ru_RU": "Необходимо ввести никнейм", - "sv_SE": "Namn krävs", "th_TH": "จำเป็นต้องระบุชื่อ", "tr_TR": "İsim gerekli", "uk_UA": "Імʼя обовʼязкове", @@ -21337,9 +19500,8 @@ "ko_KR": "프로필 이미지를 설정해야 함", "no_NO": "Profilbilde må være angitt", "pl_PL": "Należy ustawić obraz profilowy", - "pt_BR": "A Imagem de Perfil Deve ser Definida", + "pt_BR": "A imagem de perfil deve ser definida", "ru_RU": "Необходимо установить аватар", - "sv_SE": "Profilbild måste anges", "th_TH": "จำเป็นต้องตั้งค่ารูปโปรไฟล์", "tr_TR": "Profil resmi ayarlanmalıdır", "uk_UA": "Зображення профілю обовʼязкове", @@ -21364,10 +19526,9 @@ "pl_PL": "{0} Aktualizacje dostępne dla {1} ({2})", "pt_BR": "{0} atualizações disponíveis para {1} ({2})", "ru_RU": "Доступные обновления для {0} ({1})", - "sv_SE": "Hantera uppdateringar för {0} ({1})", "th_TH": "จัดการอัพเดตสำหรับ {0} ({1})", "tr_TR": "{0} için güncellemeler mevcut [{1}]", - "uk_UA": "Доступні оновлення для {0} ({1})", + "uk_UA": "{0} Доступні оновлення для {1} ({2})", "zh_CN": "管理 {0} ({1}) 的更新", "zh_TW": "管理 {0} 的更新 ({1})" } @@ -21387,9 +19548,8 @@ "ko_KR": "해상도 증가 :", "no_NO": "Øke oppløsning:", "pl_PL": "Zwiększ Rozdzielczość:", - "pt_BR": "Aumentar a Resolução:", + "pt_BR": "Aumentar a resolução:", "ru_RU": "Увеличить разрешение:", - "sv_SE": "Öka upplösning:", "th_TH": "เพิ่มความละเอียด:", "tr_TR": "Çözünürlüğü artır:", "uk_UA": "Збільшити роздільність:", @@ -21412,9 +19572,8 @@ "ko_KR": "해상도 감소 :", "no_NO": "Reduser oppløsning:", "pl_PL": "Zmniejsz Rozdzielczość:", - "pt_BR": "Reduzir a Resolução:", + "pt_BR": "Diminuir a resolução:", "ru_RU": "Уменьшить разрешение:", - "sv_SE": "Sänk upplösning:", "th_TH": "ลดความละเอียด:", "tr_TR": "Çözünürlüğü azalt:", "uk_UA": "Зменшити роздільність:", @@ -21439,7 +19598,6 @@ "pl_PL": "Nazwa:", "pt_BR": "Nome:", "ru_RU": "Никнейм:", - "sv_SE": "Namn:", "th_TH": "ชื่อ:", "tr_TR": "İsim:", "uk_UA": "Імʼя", @@ -21462,9 +19620,8 @@ "ko_KR": "사용자 ID :", "no_NO": "Bruker ID:", "pl_PL": "ID Użytkownika:", - "pt_BR": "ID de Usuário:", + "pt_BR": "ID de usuário:", "ru_RU": "ID пользователя:", - "sv_SE": "Användar-id:", "th_TH": "รหัสผู้ใช้:", "tr_TR": "Kullanıcı Adı:", "uk_UA": "ID користувача:", @@ -21487,9 +19644,8 @@ "ko_KR": "그래픽 후단부", "no_NO": "Grafikk Backend", "pl_PL": "Backend Graficzny", - "pt_BR": "Renderizador Gráfico", + "pt_BR": "Backend gráfico", "ru_RU": "Графический бэкенд", - "sv_SE": "Grafikbakände", "th_TH": "กราฟิกเบื้องหลัง", "tr_TR": "Grafik Arka Ucu", "uk_UA": "Графічний сервер", @@ -21512,9 +19668,8 @@ "ko_KR": "에뮬레이터에서 사용할 그래픽 후단부를 선택합니다.\n\nVulkan은 드라이버가 최신 상태인 한 모든 최신 그래픽 카드에 전반적으로 더 좋습니다. Vulkan은 또한 모든 GPU 공급업체에서 더 빠른 셰이더 컴파일(덜 끊김)을 제공합니다.\n\nOpenGL은 오래된 Nvidia GPU, Linux의 오래된 AMD GPU 또는 VRAM이 낮은 GPU에서 더 나은 결과를 얻을 수 있지만 셰이더 컴파일 끊김이 더 큽니다.\n\n모르면 Vulkan으로 설정합니다. 최신 그래픽 드라이버를 사용해도 GPU가 Vulkan을 지원하지 않는 경우 OpenGL로 설정하세요..", "no_NO": "Velg grafikkbackend som skal brukes i emulatoren.\n\nVulkan er generelt bedre for alle moderne grafikkort, så lenge driverne er oppdatert. Vulkan har også en raskere sammenstilling av Shader (mindre hakkete) på alle GPU-leverandører.\n\nOpenGL kan oppnå bedre resultater for eldre Nvidia GPU-er, på eldre AMD GPU-er på Linux, eller på GPU-er med lavere VRAM, selv om skyggekompileringsutløser vil være større.\n\nSett til Vulkan hvis du er usikker. Sett til OpenGL hvis ikke GPU-en støtter Vulkan selv med de nyeste grafikkdriverne.", "pl_PL": "", - "pt_BR": "Selecione o renderizador gráfico que será usado no emulador.\n\nO Vulkan é melhor no geral para todas as placas de vídeo modernas, desde que seus drivers estejam atualizados. O Vulkan também apresenta compilação de shader mais rápida (menos travamentos) em todos os fornecedores de GPU.\n\nO OpenGL pode obter melhores resultados em GPUs Nvidia antigas, em GPUs AMD antigas no Linux ou em GPUs com VRAM menor, embora os travamentos de compilação de shader sejam maiores.\n\nDefina como Vulkan se não tiver certeza. Defina como OpenGL se sua GPU não suportar Vulkan, mesmo com os drivers gráficos mais recentes.", - "ru_RU": "Выбирает бэкенд, который будет использован в эмуляторе.\n\nVulkan является лучшим выбором для всех современных графических карт с актуальными драйверами. В Vulkan также включена более быстрая компиляция шейдеров (меньше статтеров) для всех видеоадаптеров.\n\nПри использовании OpenGL можно достичь лучших результатов на старых видеоадаптерах Nvidia и AMD в Linux или на видеоадаптерах с небольшим количеством видеопамяти, хотя статтеров при компиляции шейдеров будет больше.\n\nРекомендуется использовать Vulkan. Используйте OpenGL, если ваш видеоадаптер не поддерживает Vulkan даже с актуальными драйверами.", - "sv_SE": "Väljer den grafikbakände som ska användas i emulatorn.\n\nVulkan är oftast bättre för alla moderna grafikkort, så länge som deras drivrutiner är uppdaterade. Vulkan har också funktioner för snabbare shader compilation (mindre stuttering) för alla GPU-tillverkare.\n\nOpenGL kan nå bättre resultat på gamla Nvidia GPU:er, på äldre AMD GPU:er på Linux, eller på GPU:er med lägre VRAM, även om shader compilation stuttering kommer att vara större.\n\nStäll in till Vulkan om du är osäker. Ställ in till OpenGL om du GPU inte har stöd för Vulkan även med de senaste grafikdrivrutinerna.", + "pt_BR": "", + "ru_RU": "Выберает бэкенд, который будет использован в эмуляторе.\n\nVulkan является лучшим выбором для всех современных графических карт с актуальными драйверами. В Vulkan также включена более быстрая компиляция шейдеров (меньше статтеров) для всех видеоадаптеров.\n\nПри использовании OpenGL можно достичь лучших результатов на старых видеоадаптерах Nvidia и AMD в Linux или на видеоадаптерах с небольшим количеством видеопамяти, хотя статтеров при компиляции шейдеров будет больше.\n\nРекомендуется использовать Vulkan. Используйте OpenGL, если ваш видеоадаптер не поддерживает Vulkan даже с актуальными драйверами.", "th_TH": "เลือกกราฟิกเบื้องหลังที่จะใช้ในโปรแกรมจำลอง\n\nโดยรวมแล้ว Vulkan นั้นดีกว่าสำหรับการ์ดจอรุ่นใหม่ทั้งหมด ตราบใดที่ไดรเวอร์ยังอัพเดทอยู่เสมอ Vulkan ยังมีคุณสมบัติการคอมไพล์เชเดอร์ที่เร็วขึ้น(และลดอาการกระตุก) สำหรับ GPU อื่นๆทุกอัน\n\nOpenGL อาจได้รับผลลัพธ์ที่ดีกว่าบน Nvidia GPU รุ่นเก่า, AMD GPU รุ่นเก่าบน Linux หรือบน GPU ที่มี VRAM น้อย แม้ว่าการคอมไพล์เชเดอร์ จะทำให้อาการกระตุกมากขึ้นก็ตาม\n\nตั้งค่าเป็น Vulkan หากไม่แน่ใจ ตั้งค่าเป็น OpenGL หาก GPU ของคุณไม่รองรับ Vulkan แม้จะมีไดรเวอร์กราฟิกล่าสุดก็ตาม", "tr_TR": "", "uk_UA": "Виберіть backend графіки, що буде використовуватись в емуляторі.\n\n\"Vulkan\" краще для всіх сучасних відеокарт, якщо драйвери вчасно оновлюються. У Vulkan також швидше компілюються шейдери (менше \"заїкання\" зображення) на відеокартах всіх компаній.\n\n\"OpenGL\" може дати кращі результати на старих відеокартах Nvidia, старих відеокартах AMD на Linux, або на відеокартах з маленькою кількістю VRAM, але \"заїкання\" через компіляцію шейдерів будуть частіші.\n\nЯкщо не впевнені, встановіть на \"Vulkan\". Встановіть на \"OpenGL\", якщо Ваша відеокарта не підтримує Vulkan навіть на останніх драйверах.", @@ -21522,56 +19677,6 @@ "zh_TW": "選擇模擬器將使用的圖形後端。\n\n只要驅動程式是最新的,Vulkan 對所有現代顯示卡來說都更好用。Vulkan 還能在所有 GPU 廠商上實現更快的著色器編譯 (減少卡頓)。\n\nOpenGL 在舊式 Nvidia GPU、Linux 上的舊式 AMD GPU 或 VRAM 較低的 GPU 上可能會取得更好的效果,不過著色器編譯的卡頓會更嚴重。\n\n如果不確定,請設定為 Vulkan。如果您的 GPU 使用最新的圖形驅動程式也不支援 Vulkan,請設定為 OpenGL。" } }, - { - "ID": "SettingsTabGraphicsBackendAuto", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Auto", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "Automatico", - "ja_JP": "", - "ko_KR": "자동", - "no_NO": "", - "pl_PL": "", - "pt_BR": "Automático", - "ru_RU": "Авто", - "sv_SE": "Automatiskt", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Автоматично", - "zh_CN": "自动", - "zh_TW": "自動" - } - }, - { - "ID": "SettingsTabGraphicsBackendAutoTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Uses Vulkan.\nOn an ARM Mac, and when playing a game that runs well under it, uses the Metal backend.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "Utilizza Vulkan.\nSu un Mac con processore ARM, utilizza il backend Metal nei giochi che funzionano bene con quest'ultimo.", - "ja_JP": "", - "ko_KR": "Vulkan을 사용합니다.\nARM 맥에서 해당 플랫폼에서 잘 실행되는 게임을 플레이하는 경우 Metal 후단부를 사용합니다.", - "no_NO": "Bruker Vulkan \nPå en ARM Mac, og når du spiller et spill som kjører bra under den, bruker du Metal-backend.", - "pl_PL": "", - "pt_BR": "Usa Vulkan.\nEm um Mac ARM, e ao jogar um jogo que roda bem nele, usa o renderizador Metal.", - "ru_RU": "Использует Vulkan.\nНа Mac с ARM процессорами используется Metal, если игра с ним совместима и хорошо работает.", - "sv_SE": "Använder Vulkan.\nPå en ARM Mac och vid spel som körs bra på den så används Metal-bakänden.", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Використовує Vulkan.\nНа Mac з ARM-архітектурою, якщо гра добре працює з Vulkan, використовується графічний рушій Metal.", - "zh_CN": "使用 Vulkan。\n在 ARM Mac 上,当玩在其下运行良好的游戏时,使用 Metal 后端。", - "zh_TW": "使用Vulkan。\n在 ARM Mac 上,如果遊戲執行性能良好時,則將使用 Metal 後端。" - } - }, { "ID": "SettingsEnableTextureRecompression", "Translations": { @@ -21587,9 +19692,8 @@ "ko_KR": "텍스처 재압축 활성화", "no_NO": "Aktiver teksturkomprimering", "pl_PL": "Włącz Rekompresję Tekstur", - "pt_BR": "Habilitar Recompressão de Texturas", + "pt_BR": "Habilitar recompressão de texturas", "ru_RU": "Пережимать текстуры", - "sv_SE": "Aktivera Texture Recompression", "th_TH": "เปิดใช้งาน การบีบอัดพื้นผิวอีกครั้ง", "tr_TR": "Yeniden Doku Sıkıştırılmasını Aktif Et", "uk_UA": "Увімкнути рекомпресію текстури", @@ -21612,9 +19716,8 @@ "ko_KR": "VRAM 사용량을 줄이기 위해 ASTC 텍스처를 압축합니다.\n\n이 텍스처 형식을 사용하는 게임에는 Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder, The Legend of Zelda: Tears of the Kingdom이 있습니다.\n\n4GiB VRAM 이하의 그래픽 카드는 이러한 게임을 실행하는 동안 어느 시점에서 충돌할 가능성이 있습니다.\n\n위에서 언급한 게임에서 VRAM이 부족한 경우에만 활성화합니다. 모르면 끔으로 두세요.", "no_NO": "Kompresser ASTC-teksturer for å redusere VRAM-bruk.\n\nSpill som bruker dette teksturformatet, inkluderer Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder and The Legend of Zelda: Tears of the Kingdom.\n\nGrafikkkort med 4GiB VRAM eller mindre, vil sannsynligvis krasje på et tidspunkt når spillene kjører.\n\nAktiver bare hvis du går tom for VRAM på nevnte spill. La AV om du er usikker.", "pl_PL": "", - "pt_BR": "Compacta texturas ASTC para reduzir o uso de VRAM.\n\nJogos que usam esse formato de textura incluem Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder e The Legend of Zelda: Tears of the Kingdom.\n\nPlacas gráficas com 4GB VRAM ou menos provavelmente travarão em algum momento durante a execução desses jogos.\n\nHabilite somente se estiver ficando sem VRAM nos jogos mencionados acima. Deixe DESLIGADO se não tiver certeza.", + "pt_BR": "", "ru_RU": "Сжатие ASTC текстур для уменьшения использования VRAM. \n\nИгры, использующие этот формат текстур: Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder и The Legend of Zelda: Tears of the Kingdom. \nНа видеоадаптерах с 4GiB видеопамяти или менее возможны вылеты при запуске этих игр. \n\nВключите, только если у вас заканчивается видеопамять в вышеупомянутых играх. \n\nРекомендуется оставить выключенным.", - "sv_SE": "Komprimerar ASTC-texturer för att minska VRAM-användning.\n\nSpel som använder detta texturformat inkluderar Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder och The Legend of Zelda: Tears of the Kingdom.\n\nGrafikkort med 4GiB VRAM eller mindre kommer sannolikt krascha någon gång när du kör dessa spel.\n\nAktivera endast om du har slut på VRAM på ovan nämnda spel. Lämna AV om du är osäker.", "th_TH": "บีบอัดพื้นผิว ASTC เพื่อลดการใช้งาน VRAM\n\nเกมที่ใช้รูปแบบพื้นผิวนี้ ได้แก่ Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder และ The Legend of Zelda: Tears of the Kingdom\n\nการ์ดจอที่มี 4GiB VRAM หรือน้อยกว่ามีแนวโน้มที่จะพังในบางจุดขณะเล่นเกมเหล่านี้\n\nเปิดใช้งานเฉพาะในกรณีที่ VRAM ของคุณใกล้หมดในเกมที่กล่าวมาข้างต้น ปล่อยให้ปิดหากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Стискає текстури ASTC, щоб зменшити використання VRAM.\n\nЦим форматом текстур користуються такі ігри, як Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder і The Legend of Zelda: Tears of the Kingdom.\n\nЦі ігри, скоріше всього крашнуться на відеокартах з розміром VRAM в 4 Гб і менше.\n\nВмикайте тільки якщо у Вас закінчується VRAM на цих іграх. Залиште на \"Вимкнути\", якщо не впевнені.", @@ -21637,9 +19740,8 @@ "ko_KR": "기본 GPU", "no_NO": "Foretrukket GPU", "pl_PL": "Preferowane GPU", - "pt_BR": "GPU Preferida", + "pt_BR": "GPU preferencial", "ru_RU": "Предпочтительный видеоадаптер", - "sv_SE": "Föredragen GPU", "th_TH": "GPU ที่ต้องการ", "tr_TR": "Kullanılan GPU", "uk_UA": "Бажаний GPU", @@ -21657,14 +19759,13 @@ "es_ES": "Selecciona la tarjeta gráfica que se utilizará con los back-end de gráficos Vulkan.\n\nNo afecta la GPU que utilizará OpenGL.\n\nFije a la GPU marcada como \"dGUP\" ante dudas. Si no hay una, no haga modificaciones.", "fr_FR": "Sélectionnez la carte graphique qui sera utilisée avec l'interface graphique Vulkan.\n\nCela ne change pas le GPU qu'OpenGL utilisera.\n\nChoisissez le GPU noté \"dGPU\" si vous n'êtes pas sûr. S'il n'y en a pas, ne pas modifier.", "he_IL": "בחר את הכרטיס הגראפי שישומש עם הגראפיקה של וולקאן.\n\nדבר זה לא משפיע על הכרטיס הגראפי שישומש עם OpenGL.\n\nמוטב לבחור את ה-GPU המסומן כ-\"dGPU\" אם אינכם בטוחים, אם זו לא אופצייה, אל תשנו דבר.", - "it_IT": "Seleziona la scheda grafica che verrà usata con il backend grafico Vulkan.\n\nL'opzione non modifica la GPU usata da OpenGL.\n\nNel dubbio, seleziona la GPU contrassegnata come \"dGPU\". Se non ce n'è una, lascia intatta questa opzione.", + "it_IT": "Seleziona la scheda grafica che verrà usata con la backend grafica Vulkan.\n\nNon influenza la GPU che userà OpenGL.\n\nImposta la GPU contrassegnata come \"dGPU\" se non sei sicuro. Se non ce n'è una, lascia intatta quest'impostazione.", "ja_JP": "Vulkanグラフィックスバックエンドで使用されるグラフィックスカードを選択します.\n\nOpenGLが使用するGPUには影響しません.\n\n不明な場合は, \"dGPU\" としてフラグが立っているGPUに設定します. ない場合はそのままにします.", "ko_KR": "Vulkan 그래픽 후단부와 함께 사용할 그래픽 카드를 선택하세요.\n\nOpenGL에서 사용할 GPU에는 영향을 미치지 않습니다.\n\n모르면 \"dGPU\"로 플래그가 지정된 GPU로 설정하세요. 없으면 그대로 두세요.", "no_NO": "Velg grafikkkortet som skal brukes sammen med Vulkan grafikkbackenden\n\nPåvirker ikke GPU-er som OpenGL skal bruke.\n\nSett til GPU-merket som \"dGPU\" hvis usikker. Hvis det ikke det er en, la være uberørt.", "pl_PL": "Wybierz kartę graficzną, która będzie używana z backendem graficznym Vulkan.\n\nNie wpływa na GPU używane przez OpenGL.\n\nW razie wątpliwości ustaw flagę GPU jako \"dGPU\". Jeśli żadnej nie ma, pozostaw nietknięte.", - "pt_BR": "Selecione a placa de vídeo que será usada com o renderizador gráfico Vulkan.\n\nNão afeta a GPU que OpenGL usará.\n\nSelecione \"dGPU\" em caso de dúvida. Se não houver nenhuma, não mexa.", - "ru_RU": "Выберает видеоадаптер, который будет использоваться графическим бэкендом Vulkan.\n\nЭта настройка не влияет на видеоадаптер, который будет использоваться с OpenGL.\n\nЕсли вы не уверены что нужно выбрать, используйте графический процессор, помеченный как «dGPU». Если его нет, оставьте выбор по умолчанию.", - "sv_SE": "Välj grafikkortet som ska användas med Vulkan-grafikbakänden.\n\nPåverkar inte GPU:n som OpenGL använder.\n\nStäll in till den GPU som flaggats som \"dGPU\" om osäker. Om det inte finns någon, lämna orörd.", + "pt_BR": "Selecione a placa de vídeo que será usada com o backend gráfico Vulkan.\n\nNão afeta a GPU que OpenGL usará.\n\nSelecione \"dGPU\" em caso de dúvida. Se não houver nenhuma, não mexa.", + "ru_RU": "Выберает видеоадаптер, который будет использоваться графическим бэкендом Vulkan.\n\nЭта настройка не влияет на видеоадаптер, который будет использоваться с OpenGL.\n\nЕсли вы не уверены что нужно выбрать, используйте графический процессор, помеченный как \"dGPU\". Если его нет, оставьте выбор по умолчанию.", "th_TH": "เลือกการ์ดจอที่จะใช้กับแบ็กเอนด์กราฟิก Vulkan\n\nไม่ส่งผลต่อ GPU ที่ OpenGL จะใช้\n\nตั้งค่าเป็น GPU ที่ถูกตั้งค่าสถานะเป็น \"dGPU\" ถ้าหากคุณไม่แน่ใจ ,หากไม่มีก็ปล่อยทิ้งไว้โดยไม่ต้องแตะต้องมัน", "tr_TR": "Vulkan Grafik Arka Ucu ile kullanılacak Ekran Kartını Seçin.\n\nOpenGL'nin kullanacağı GPU'yu etkilemez.\n\n Emin değilseniz \"dGPU\" olarak işaretlenmiş GPU'ya ayarlayın. Eğer yoksa, dokunmadan bırakın.\n", "uk_UA": "Виберіть відеокарту, яка використовуватиметься з графічним сервером Vulkan.\n\nНе впливає на графічний процесор, який використовуватиме OpenGL.\n\nВстановіть графічний процесор, позначений як «dGPU», якщо не впевнені. Якщо такого немає, не чіпайте.", @@ -21687,9 +19788,8 @@ "ko_KR": "Ryujinx 다시 시작 필요", "no_NO": "Ryujinx Omstart nødvendig", "pl_PL": "Wymagane Zrestartowanie Ryujinx", - "pt_BR": "Reinicialização do Ryujinx Necessária", + "pt_BR": "Reinicialização do Ryujinx necessária", "ru_RU": "Требуется перезапуск Ryujinx", - "sv_SE": "Omstart av Ryujinx krävs", "th_TH": "จำเป็นต้องรีสตาร์ท Ryujinx", "tr_TR": "Ryujinx'i Yeniden Başlatma Gerekli", "uk_UA": "Необхідно перезапустити Ryujinx", @@ -21707,14 +19807,13 @@ "es_ES": "La configuración de la GPU o del back-end de los gráficos fue modificada. Es necesario reiniciar para que se aplique.", "fr_FR": "Les paramètres de l'interface graphique ou du GPU ont été modifiés. Cela nécessitera un redémarrage pour être appliqué", "he_IL": "הגדרות אחראי גרפיקה או כרטיס גראפי שונו. זה ידרוש הפעלה מחדש כדי להחיל שינויים", - "it_IT": "Le impostazioni del backend grafico o della GPU sono state modificate. È necessario un riavvio per applicare le modifiche", + "it_IT": "Le impostazioni della backend grafica o della GPU sono state modificate. Questo richiederà un riavvio perché le modifiche siano applicate", "ja_JP": "グラフィックスバックエンドまたはGPUの設定が変更されました. 変更を適用するには再起動する必要があります", "ko_KR": "그래픽 후단부 또는 GPU 설정이 수정되었습니다. 이를 적용하려면 다시 시작이 필요", "no_NO": "Grafikk Backend eller GPU-innstillinger er endret. Dette krever en omstart for å aktiveres", "pl_PL": "Zmieniono ustawienia Backendu Graficznego lub GPU. Będzie to wymagało ponownego uruchomienia", - "pt_BR": "Configurações do renderizador gráfico ou da GPU foram alteradas. Uma reinicialização é necessária para que as mudanças tenham efeito.", + "pt_BR": "Configurações do backend gráfico ou da GPU foram alteradas. Uma reinicialização é necessária para que as mudanças tenham efeito.", "ru_RU": "Графический бэкенд или настройки графического процессора были изменены. Требуется перезапуск для вступления в силу изменений.", - "sv_SE": "Grafikbakänden eller GPU-inställningar har ändrats. Detta kräver en omstart", "th_TH": "การตั้งค่ากราฟิกเบื้องหลังหรือ GPU ได้รับการแก้ไขแล้ว สิ่งนี้จะต้องมีการรีสตาร์ทจึงจะสามารถใช้งานได้", "tr_TR": "Grafik Motoru ya da GPU ayarları değiştirildi. Bu işlemin uygulanması için yeniden başlatma gerekli.", "uk_UA": "Налаштування графічного сервера або GPU було змінено. Для цього знадобиться перезапуск", @@ -21739,7 +19838,6 @@ "pl_PL": "Czy chcesz zrestartować teraz?", "pt_BR": "Deseja reiniciar agora?", "ru_RU": "Перезапустить сейчас?", - "sv_SE": "Vill du starta om nu?", "th_TH": "คุณต้องการรีสตาร์ทตอนนี้หรือไม่?", "tr_TR": "Şimdi yeniden başlatmak istiyor musunuz?", "uk_UA": "Бажаєте перезапустити зараз?", @@ -21764,7 +19862,6 @@ "pl_PL": "Czy chcesz zaktualizować Ryujinx do najnowszej wersji?", "pt_BR": "Você quer atualizar o Ryujinx para a última versão?", "ru_RU": "Обновить Ryujinx до последней версии?", - "sv_SE": "Vill du uppdatera Ryujinx till senaste versionen?", "th_TH": "คุณต้องการอัพเดต Ryujinx เป็นเวอร์ชั่นล่าสุดหรือไม่?", "tr_TR": "Ryujinx'i en son sürüme güncellemek ister misiniz?", "uk_UA": "Бажаєте оновити Ryujinx до останньої версії?", @@ -21787,9 +19884,8 @@ "ko_KR": "음량 증가 :", "no_NO": "Øk Volum:", "pl_PL": "Zwiększ Głośność:", - "pt_BR": "Aumentar Volume:", + "pt_BR": "Aumentar volume:", "ru_RU": "Увеличить громкость:", - "sv_SE": "Öka volym:", "th_TH": "เพิ่มระดับเสียง:", "tr_TR": "Sesi Arttır:", "uk_UA": "Збільшити гучність:", @@ -21812,9 +19908,8 @@ "ko_KR": "음량 감소 :", "no_NO": "Reduser Volum:", "pl_PL": "Zmniejsz Głośność:", - "pt_BR": "Diminuir Volume:", + "pt_BR": "Diminuir volume:", "ru_RU": "Уменьшить громкость:", - "sv_SE": "Sänk volym:", "th_TH": "ลดระดับเสียง:", "tr_TR": "Sesi Azalt:", "uk_UA": "Зменшити гучність:", @@ -21837,9 +19932,8 @@ "ko_KR": "매크로 HLE 활성화", "no_NO": "Aktiver Makro HLE", "pl_PL": "Włącz Macro HLE", - "pt_BR": "Habilitar Macro HLE", + "pt_BR": "Habilitar emulação de alto nível para Macros", "ru_RU": "Использовать макрос высокоуровневой эмуляции видеоадаптера", - "sv_SE": "Aktivera Macro HLE", "th_TH": "เปิดใช้งาน มาโคร HLE", "tr_TR": "Macro HLE'yi Aktifleştir", "uk_UA": "Увімкнути макрос HLE", @@ -21863,8 +19957,7 @@ "no_NO": "High-level emulering av GPU makrokode.\n\nForbedrer ytelse, men kan forårsake grafiske glitches i noen spill.\n\nForlat PÅ hvis usikker.", "pl_PL": "Wysokopoziomowa emulacja kodu GPU Macro.\n\nPoprawia wydajność, ale może powodować błędy graficzne w niektórych grach.\n\nW razie wątpliwości pozostaw WŁĄCZONE.", "pt_BR": "Habilita emulação de alto nível de códigos Macro da GPU.\n\nMelhora a performance, mas pode causar problemas gráficos em alguns jogos.\n\nEm caso de dúvida, deixe ATIVADO.", - "ru_RU": "Высокоуровневая эмуляция макрокода видеоадаптера.\n\nПовышает производительность, но может вызывать графические артефакты в некоторых играх.\n\nРекомендуется оставить включенным.", - "sv_SE": "Högnivåemulering av GPU Macro-kod.\n\nFörbättrar prestandan men kan orsaka grafiska glitches i vissa spel.\n\nLämna PÅ om du är osäker.", + "ru_RU": "Высокоуровневая эмуляции макрокода видеоадаптера.\n\nПовышает производительность, но может вызывать графические артефакты в некоторых играх.\n\nРекомендуется оставить включенным.", "th_TH": "การจำลองระดับสูงของโค้ดมาโคร GPU\n\nปรับปรุงประสิทธิภาพ แต่อาจทำให้เกิดข้อผิดพลาดด้านกราฟิกในบางเกม\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "GPU Macro kodunun yüksek seviye emülasyonu.\n\nPerformansı arttırır, ama bazı oyunlarda grafik hatalarına yol açabilir.\n\nEmin değilseniz AÇIK bırakın.", "uk_UA": "Високорівнева емуляція коду макросу GPU.\n\nПокращує продуктивність, але може викликати графічні збої в деяких іграх.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -21887,9 +19980,8 @@ "ko_KR": "색 공간 통과", "no_NO": "Fargeromsgjennomgang", "pl_PL": "Przekazywanie przestrzeni kolorów", - "pt_BR": "Passagem do Espaço de Cores", + "pt_BR": "Passagem de Espaço Cor", "ru_RU": "Пропускать цветовое пространство", - "sv_SE": "Genomströmning av färgrymd", "th_TH": "ทะลุผ่านพื้นที่สี", "tr_TR": "Renk Alanı Geçişi", "uk_UA": "Наскрізний колірний простір", @@ -21912,9 +20004,8 @@ "ko_KR": "Vulkan 후단부가 색 공간을 지정하지 않고 색상 정보를 전달하도록 지시합니다. 넓은 색역 화면 표시 장치를 사용하는 사용자의 경우 색상 정확성을 희생하고 더 생생한 색상이 나올 수 있습니다.", "no_NO": "Dirigerer Vulkan backenden til å gå gjennom farge informasjonen uten og spesifisere en fargeromsgjennomgang. For brukere med en bred spillvisning kan dette resultere i mer vibrerende farger og få riktig farge.", "pl_PL": "Nakazuje API Vulkan przekazywać informacje o kolorze bez określania przestrzeni kolorów. Dla użytkowników z wyświetlaczami o szerokim zakresie kolorów może to skutkować bardziej żywymi kolorami, kosztem ich poprawności.", - "pt_BR": "Direciona o renderizador Vulkan para passar informações de cores sem especificar um espaço de cores. Para usuários com telas de ampla gama, isso pode resultar em cores mais vibrantes, ao custo da correção de cores.", + "pt_BR": "Direciona o backend Vulkan para passar informações de cores sem especificar um espaço de cores. Para usuários com telas de ampla gama, isso pode resultar em cores mais vibrantes, ao custo da correção de cores.", "ru_RU": "Направляет бэкенд Vulkan на передачу информации о цвете без указания цветового пространства. Для пользователей с экранами с расширенной гаммой данная настройка приводит к получению более ярких цветов за счет снижения корректности цветопередачи.", - "sv_SE": "Dirigerar Vulkan-bakänden att skicka genom färginformation utan att ange en färgrymd. För användare med breda gamut-skärmar kan detta resultera i mer levande färger på bekostnad av färgkorrekthet.", "th_TH": "สั่งให้แบ็กเอนด์ Vulkan ส่งผ่านข้อมูลสีโดยไม่ต้องระบุค่าของสี สำหรับผู้ใช้ที่มีการแสดงกระจายตัวของสี อาจส่งผลให้สีสดใสมากขึ้น โดยต้องแลกกับความถูกต้องของสี", "tr_TR": "Vulkan Backend'ini renk alanı belirtmeden renk bilgisinden geçmeye yönlendirir. Geniş gam ekranlı kullanıcılar için bu, renk doğruluğu pahasına daha canlı renklerle sonuçlanabilir.", "uk_UA": "Дозволяє серверу Vulkan передавати інформацію про колір без вказівки колірного простору. Для користувачів з екранами з широкою гамою це може призвести до більш яскравих кольорів, але шляхом втрати коректності передачі кольору.", @@ -21937,9 +20028,8 @@ "ko_KR": "음량", "no_NO": "", "pl_PL": "Głoś", - "pt_BR": "Volume", + "pt_BR": "", "ru_RU": "Громкость", - "sv_SE": "Volym", "th_TH": "ระดับเสียง", "tr_TR": "Ses", "uk_UA": "Гуч.", @@ -21962,9 +20052,8 @@ "ko_KR": "저장 관리", "no_NO": "Administrer lagring", "pl_PL": "Zarządzaj Zapisami", - "pt_BR": "Gerenciar Jogos Salvos", + "pt_BR": "Gerenciar jogos salvos", "ru_RU": "Управление сохранениями", - "sv_SE": "Hantera sparade spel", "th_TH": "จัดการบันทึก", "tr_TR": "Kayıtları Yönet", "uk_UA": "Керувати збереженнями", @@ -21989,7 +20078,6 @@ "pl_PL": "Czy chcesz usunąć zapis użytkownika dla tej gry?", "pt_BR": "Deseja apagar o jogo salvo do usuário para este jogo?", "ru_RU": "Удалить сохранения для этой игры?", - "sv_SE": "Vill du ta bort användarsparade spel för detta spel?", "th_TH": "คุณต้องการลบบันทึกผู้ใช้สำหรับเกมนี้หรือไม่?", "tr_TR": "Bu oyun için kullanıcı kaydını silmek istiyor musunuz?", "uk_UA": "Ви хочете видалити збереження користувача для цієї гри?", @@ -22014,7 +20102,6 @@ "pl_PL": "Ta czynność nie jest odwracalna.", "pt_BR": "Esta ação não é reversível.", "ru_RU": "Данное действие является необратимым.", - "sv_SE": "Denna åtgärd går inte att ångra.", "th_TH": "การดำเนินการนี้ไม่สามารถย้อนกลับได้", "tr_TR": "Bu eylem geri alınamaz.", "uk_UA": "Цю дію не можна скасувати.", @@ -22037,9 +20124,8 @@ "ko_KR": "{0} ({1})에 대한 저장 관리", "no_NO": "Administrer lagring for {0} ({1})", "pl_PL": "Zarządzaj Zapisami dla {0}", - "pt_BR": "Gerenciar Jogos Salvos para {0}", + "pt_BR": "Gerenciar jogos salvos para {0}", "ru_RU": "Редактирование сохранений для {0} ({1})", - "sv_SE": "Hantera sparade spel för {0} ({1})", "th_TH": "จัดการบันทึกสำหรับ {0} ({1})", "tr_TR": "{0} için Kayıt Dosyalarını Yönet", "uk_UA": "Керувати збереженнями для {0}", @@ -22062,9 +20148,8 @@ "ko_KR": "관리자 저장", "no_NO": "Lagre behandler", "pl_PL": "Menedżer Zapisów", - "pt_BR": "Gerenciador de Jogos Salvos", + "pt_BR": "Gerenciador de jogos salvos", "ru_RU": "Менеджер сохранений", - "sv_SE": "Sparhanterare", "th_TH": "จัดการบันทึก", "tr_TR": "Kayıt Yöneticisi", "uk_UA": "Менеджер збереження", @@ -22080,7 +20165,7 @@ "el_GR": "Όνομα", "en_US": "Name", "es_ES": "Nombre", - "fr_FR": "Nom\u00A0", + "fr_FR": "Nom ", "he_IL": "שם", "it_IT": "Nome", "ja_JP": "名称", @@ -22089,7 +20174,6 @@ "pl_PL": "Nazwa", "pt_BR": "Nome", "ru_RU": "Название", - "sv_SE": "Namn", "th_TH": "ชื่อ", "tr_TR": "İsim", "uk_UA": "Назва", @@ -22114,7 +20198,6 @@ "pl_PL": "Rozmiar", "pt_BR": "Tamanho", "ru_RU": "Размер", - "sv_SE": "Storlek", "th_TH": "ขนาด", "tr_TR": "Boyut", "uk_UA": "Розмір", @@ -22139,7 +20222,6 @@ "pl_PL": "Wyszukaj", "pt_BR": "Buscar", "ru_RU": "Поиск", - "sv_SE": "Sök", "th_TH": "ค้นหา", "tr_TR": "Ara", "uk_UA": "Пошук", @@ -22162,9 +20244,8 @@ "ko_KR": "잃어버린 계정 복구", "no_NO": "Gjenopprett tapte kontoer", "pl_PL": "Odzyskaj Utracone Konta", - "pt_BR": "Recuperar Contas Perdidas", - "ru_RU": "Восстановить учётные записи", - "sv_SE": "Återskapa förlorade konton", + "pt_BR": "Recuperar contas perdidas", + "ru_RU": "Восстановить учетные записи", "th_TH": "กู้คืนบัญชีที่สูญหาย", "tr_TR": "Kayıp Hesapları Kurtar", "uk_UA": "Відновлення профілів", @@ -22189,7 +20270,6 @@ "pl_PL": "Odzyskaj", "pt_BR": "Recuperar", "ru_RU": "Восстановление", - "sv_SE": "Återskapa", "th_TH": "กู้คืน", "tr_TR": "Kurtar", "uk_UA": "Відновити", @@ -22214,7 +20294,6 @@ "pl_PL": "Znaleziono zapisy dla następujących kont", "pt_BR": "Jogos salvos foram encontrados para as seguintes contas", "ru_RU": "Были найдены сохранения для следующих аккаунтов", - "sv_SE": "Sparade spel hittades för följande konton", "th_TH": "พบบันทึกสำหรับบัญชีดังต่อไปนี้", "tr_TR": "Aşağıdaki hesaplar için kayıtlar bulundu", "uk_UA": "Знайдено збереження для наступних облікових записів", @@ -22238,8 +20317,7 @@ "no_NO": "Ingen profiler å gjenopprette", "pl_PL": "Brak profili do odzyskania", "pt_BR": "Nenhum perfil para recuperar", - "ru_RU": "Нет учётных записей для восстановления", - "sv_SE": "Inga profiler att återskapa", + "ru_RU": "Нет учетных записей для восстановления", "th_TH": "ไม่มีโปรไฟล์ที่สามารถกู้คืนได้", "tr_TR": "Kurtarılacak profil bulunamadı", "uk_UA": "Немає профілів для відновлення", @@ -22257,14 +20335,13 @@ "es_ES": "Aplica antia-aliasing al rendereo del juego.\n\nFXAA desenfocará la mayor parte del la iamgen, mientras que SMAA intentará encontrar bordes irregulares y suavizarlos.\n\nNo se recomienda usar en conjunto con filtro de escala FSR.\n\nEsta opción puede ser modificada mientras que esté corriendo el juego haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDejar en NADA si no está seguro.", "fr_FR": "FXAA floute la plupart de l'image, tandis que SMAA tente de détecter les contours dentelés et de les lisser.\n\nIl n'est pas recommandé de l'utiliser en conjonction avec le filtre de mise à l'échelle FSR.\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres sur le côté et expérimenter jusqu'à ce que vous trouviez l'apparence souhaitée pour un jeu.\n\nLaissez sur AUCUN si vous n'êtes pas sûr.", "he_IL": "", - "it_IT": "Applica l'anti-aliasing al rendering del gioco.\n\nFXAA rende la maggior parte dell'immagine sfocata, mentre SMAA tenta di rilevare e smussare i bordi frastagliati.\n\nSi consiglia di non usarlo in combinazione con il filtro di scaling FSR.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nNel dubbio, lascia su Nessuno.", + "it_IT": "Applica anti-aliasing al rendering del gioco.\n\nFXAA sfocerà la maggior parte dell'immagine, mentre SMAA tenterà di trovare bordi frastagliati e lisciarli.\n\nNon si consiglia di usarlo in combinazione con il filtro di scala FSR.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nLasciare su Nessuno se incerto.", "ja_JP": "ゲームレンダリングにアンチエイリアスを適用します.\n\nFXAAは画像の大部分をぼかし, SMAAはギザギザのエッジを見つけて滑らかにします.\n\nFSRスケーリングフィルタとの併用は推奨しません.\n\nこのオプションは, ゲーム実行中に下の「適用」をクリックして変更できます. 設定ウィンドウを脇に移動し, ゲームが好みの表示になるように試してみてください.\n\n不明な場合は「なし」のままにしておいてください.", "ko_KR": "게임 렌더에 앤티 앨리어싱을 적용합니다.\n\nFXAA는 이미지 대부분을 흐리게 처리하지만 SMAA는 들쭉날쭉한 가장자리를 찾아 부드럽게 처리합니다.\n\nFSR 스케일링 필터와 함께 사용하지 않는 것이 좋습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임을 실행하는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮겨 원하는 게임의 모습을 찾을 때까지 실험해 볼 수 있습니다.\n\n모르면 없음으로 두세요.", "no_NO": "Aktiverer anti-aliasing til spill render.\n\nFXAA vil gjøre det meste av bildet, mens SMAA vil forsøke å finne berørte kanter og glatte dem ut.\n\nAnbefales ikke til bruk i forbindelse med FSR-skaleringsfilteret.\n\nDette valget kan endres mens et spill kjører ved å klikke \"Apply\" nedenfor; du kan bare flytte innstillingsvinduet til du finner det foretrukne utseendet til et spill.\n\nForlat på NONE hvis usikker.", "pl_PL": "", "pt_BR": "Aplica anti-aliasing à renderização do jogo.\n\nFXAA borrará a maior parte da imagem, enquanto SMAA tentará identificar e suavizar bordas serrilhadas.\n\nNão é recomendado usar em conjunto com o filtro de escala FSR.\n\nEssa opção pode ser alterada enquanto o jogo está em execução clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nDeixe em NENHUM se estiver em dúvida.", - "ru_RU": "Применимое сглаживание для рендера.\n\nFXAA размывает большую часть изображения, SMAA попытается найти «зазубренные» края и сгладить их.\n\nНе рекомендуется использовать вместе с масштабирующим фильтром FSR.\n\nЭта опция может быть изменена во время игры по нажатию «Применить» ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не найдёте подходящую настройку игры.\n\nРекомендуется использовать «Нет».", - "sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.", + "ru_RU": "Применимое сглаживание для рендера.\n\nFXAA размывает большую часть изображения, SMAA попытается найти \"зазубренные\" края и сгладить их.\n\nНе рекомендуется использовать вместе с масштабирующим фильтром FSR.\n\nЭта опция может быть изменена во время игры по нажатию \"Применить\" ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не найдёте подходящую настройку игры.\n\nРекомендуется использовать \"Нет\".", "th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Немає\", якщо не впевнені.", @@ -22282,14 +20359,13 @@ "es_ES": "Suavizado de bordes:", "fr_FR": "Anticrénelage :", "he_IL": "החלקת-עקומות:", - "it_IT": "Anti-aliasing:", + "it_IT": "", "ja_JP": "アンチエイリアス:", "ko_KR": "앤티 앨리어싱 :", "no_NO": "Kantutjevning:", "pl_PL": "Antyaliasing:", - "pt_BR": "Anti-Serrilhado:", + "pt_BR": "Anti-serrilhado:", "ru_RU": "Сглаживание:", - "sv_SE": "Antialiasing:", "th_TH": "ลดการฉีกขาดของภาพ:", "tr_TR": "Kenar Yumuşatma:", "uk_UA": "Згладжування:", @@ -22307,14 +20383,13 @@ "es_ES": "Filtro de escalado:", "fr_FR": "Filtre de mise à l'échelle :", "he_IL": "מסנן מידת איכות:", - "it_IT": "Filtro di scaling:", + "it_IT": "Filtro di scala:", "ja_JP": "スケーリングフィルタ:", "ko_KR": "크기 조정 필터 :", "no_NO": "Skaleringsfilter:", "pl_PL": "Filtr skalowania:", - "pt_BR": "Filtro de Escala:", + "pt_BR": "Filtro de escala:", "ru_RU": "Интерполяция:", - "sv_SE": "Skalningsfilter:", "th_TH": "ปรับขนาดตัวกรอง:", "tr_TR": "Ölçekleme Filtresi:", "uk_UA": "Фільтр масштабування:", @@ -22332,17 +20407,16 @@ "es_ES": "Elija el filtro de escala que se aplicará al utilizar la escala de resolución.\n\nBilinear funciona bien para juegos 3D y es una opción predeterminada segura.\n\nSe recomienda el bilinear para juegos de pixel art.\n\nFSR 1.0 es simplemente un filtro de afilado, no se recomienda su uso con FXAA o SMAA.\n\nEsta opción se puede cambiar mientras se ejecuta un juego haciendo clic en \"Aplicar\" a continuación; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDéjelo en BILINEAR si no está seguro.", "fr_FR": "Choisissez le filtre de mise à l'échelle qui sera appliqué lors de l'utilisation de la mise à l'échelle de la résolution.\n\nLe filtre bilinéaire fonctionne bien pour les jeux en 3D et constitue une option par défaut sûre.\n\nLe filtre le plus proche est recommandé pour les jeux de pixel art.\n\nFSR 1.0 est simplement un filtre de netteté, non recommandé pour une utilisation avec FXAA ou SMAA.\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres de côté et expérimenter jusqu'à ce que vous trouviez l'aspect souhaité pour un jeu.\n\nLaissez sur BILINÉAIRE si vous n'êtes pas sûr.", "he_IL": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", - "it_IT": "Scegli il filtro di scaling che verrà applicato quando si utilizza lo scaling della risoluzione.\n\nBilineare funziona bene per i giochi 3D ed è un'opzione predefinita affidabile.\n\nNearest è consigliato per i giochi in pixel art.\n\nFSR 1.0 è solo un filtro di nitidezza, sconsigliato per l'uso con FXAA o SMAA.\n\nLo scaling ad area è consigliato quando si riducono delle risoluzioni che sono più grandi della finestra di output. Può essere usato per ottenere un effetto di anti-aliasing supercampionato quando si riduce di più di 2x.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nNel dubbio, lascia su Bilineare.", + "it_IT": "Scegli il filtro di scaling che verrà applicato quando si utilizza o scaling di risoluzione.\n\nBilineare funziona bene per i giochi 3D ed è un'opzione predefinita affidabile.\n\nNearest è consigliato per i giochi in pixel art.\n\nFSR 1.0 è solo un filtro di nitidezza, non raccomandato per l'uso con FXAA o SMAA.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nLasciare su Bilineare se incerto.", "ja_JP": "解像度変更時に適用されるスケーリングフィルタを選択します.\n\nBilinearは3Dゲームに適しており, 安全なデフォルトオプションです.\n\nピクセルアートゲームにはNearestを推奨します.\n\nFSR 1.0は単なるシャープニングフィルタであり, FXAAやSMAAとの併用は推奨されません.\n\nこのオプションは, ゲーム実行中に下の「適用」をクリックすることで変更できます. 設定ウィンドウを脇に移動し, ゲームが好みの表示になるように試してみてください.\n\n不明な場合はBilinearのままにしておいてください.", "ko_KR": "해상도 스케일을 사용할 때 적용될 스케일링 필터를 선택합니다.\n\n쌍선형은 3D 게임에 적합하며 안전한 기본 옵션입니다.\n\nNearest는 픽셀 아트 게임에 권장됩니다.\n\nFSR 1.0은 단순히 선명도 필터일 뿐이며 FXAA 또는 SMAA와 함께 사용하는 것은 권장되지 않습니다.\n\nArea 스케일링은 출력 창보다 큰 해상도를 다운스케일링할 때 권장됩니다. 2배 이상 다운스케일링할 때 슈퍼샘플링된 앤티앨리어싱 효과를 얻는 데 사용할 수 있습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임을 실행하는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮겨 원하는 게임 모양을 찾을 때까지 실험하면 됩니다.\n\n모르면 쌍선형을 그대로 두세요.", "no_NO": "Velg det skaleringsfilteret som skal brukes når du bruker oppløsningsskalaen.\n\nBilinear fungerer godt for 3D-spill og er et trygt standardalternativ.\n\nNærmeste anbefales for pixel kunst-spill.\n\nFSR 1.0 er bare et skarpere filter, ikke anbefalt for bruk med FXAA eller SMAA.\n\nOmrådeskalering anbefales når nedskalering er større enn utgangsvinduet. Den kan brukes til å oppnå en superprøvetaket anti-aliasingseffekt når en nedskalerer med mer enn 2x.\n\nDette valget kan endres mens et spill kjører ved å klikke \"Apply\" nedenfor; du kan bare flytte innstillingsvinduet til du finner det foretrukne utseendet til et spill.\n\nLa være på BILINEAR hvis usikker.", "pl_PL": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", "pt_BR": "Escolha o filtro de escala que será aplicado ao usar a escala de resolução.\n\nBilinear funciona bem para jogos 3D e é uma opção padrão segura.\n\nNearest é recomendado para jogos em pixel art.\n\nFSR 1.0 é apenas um filtro de nitidez, não recomendado para uso com FXAA ou SMAA.\n\nEssa opção pode ser alterada enquanto o jogo está em execução, clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nMantenha em BILINEAR se estiver em dúvida.", - "ru_RU": "Фильтрация текстур, которая будет применяться при масштабировании.\n\nБилинейная хорошо работает для 3D-игр и является настройкой по умолчанию.\n\nСтупенчатая рекомендуется для пиксельных игр.\n\nFSR это фильтр резкости, который не рекомендуется использовать с FXAA или SMAA.\n\nЗональная рекомендуется в случае использования разрешения больше разрешения окна. Можно использовать для достижения эффекта суперсемплига (SSAA) при даунскейле более чем в 2 раза.\n\nЭта опция может быть изменена во время игры по нажатию кнопки «Применить» ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nРекомендуется использовать «Билинейная».", - "sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.", + "ru_RU": "Фильтрация текстур, которая будет применяться при масштабировании.\n\nБилинейная хорошо работает для 3D-игр и является настройкой по умолчанию.\n\nСтупенчатая рекомендуется для пиксельных игр.\n\nFSR это фильтр резкости, который не рекомендуется использовать с FXAA или SMAA.\n\nЭта опция может быть изменена во время игры по нажатию кнопки \"Применить\" ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nРекомендуется использовать \"Билинейная\".", "th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม", "tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", - "uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна змінювати під час гри кліком на \"Застосувати\" нижче; ви можете відсунути вікно налаштувань і поекспериментувати з тим, як відображатиметься гра.\n\nЗалиште на \"Білінійний\", якщо не впевнені.", + "uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - це просто фільтр різкості, не рекомендується використовувати разом з FXAA або SMAA.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Білінійний\", якщо не впевнені.", "zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear(双线性过滤)对于3D游戏效果较好,是一个安全的默认选项。\n\nNearest(最近邻过滤)推荐用于像素艺术游戏。\n\nFSR(超级分辨率锐画)只是一个锐化过滤器,不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea(局部过滤),当渲染分辨率大于窗口实际分辨率,推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时,通过点击下面的“应用”按钮可以使设置生效;你可以将设置窗口移开,并试验找到您喜欢的游戏画面效果。\n\n如果不确定,请保持为“Bilinear(双线性过滤)”。", "zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更;您只需將設定視窗移到一旁,然後進行試驗,直到找到您喜歡的遊戲效果。\n\n如果不確定,請保持雙線性 (Bilinear) 狀態。" } @@ -22364,7 +20438,6 @@ "pl_PL": "Dwuliniowe", "pt_BR": "", "ru_RU": "Билинейная", - "sv_SE": "Bilinjär", "th_TH": "", "tr_TR": "", "uk_UA": "Білінійний", @@ -22389,7 +20462,6 @@ "pl_PL": "Najbliższe", "pt_BR": "", "ru_RU": "Ступенчатая", - "sv_SE": "Närmaste", "th_TH": "ใกล้สุด", "tr_TR": "", "uk_UA": "Найближчий", @@ -22414,7 +20486,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -22437,14 +20508,13 @@ "ko_KR": "영역", "no_NO": "Område", "pl_PL": "", - "pt_BR": "Área", - "ru_RU": "Зональная", - "sv_SE": "Yta", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "", "zh_CN": "Area(区域过滤)", - "zh_TW": "區域" + "zh_TW": "" } }, { @@ -22464,7 +20534,6 @@ "pl_PL": "Poziom", "pt_BR": "Nível", "ru_RU": "Уровень", - "sv_SE": "Nivå", "th_TH": "ระดับ", "tr_TR": "Seviye", "uk_UA": "Рівень", @@ -22488,11 +20557,10 @@ "no_NO": "Definer FSR 1,0 skarpere nivå. Høyere er skarpere.", "pl_PL": "Ustaw poziom ostrzeżenia FSR 1.0. Wyższy jest ostrzejszy.", "pt_BR": "Defina o nível de nitidez do FSR 1.0. Quanto maior, mais nítido.", - "ru_RU": "Выбор режима работы FSR 1.0. Выше — четче.", - "sv_SE": "Ställ in nivå för FSR 1.0 sharpening. Högre är skarpare.", + "ru_RU": "Выбор режима работы FSR 1.0. Выше - четче.", "th_TH": "ตั้งค่าระดับความคมชัด FSR 1.0 ยิ่งสูงกว่าจะยิ่งคมชัดกว่า", "tr_TR": "", - "uk_UA": "Встановити рівень різкості FSR 1.0. Чим вище - тим різкіше.", + "uk_UA": "Встановити рівень різкості в FSR 1.0. Чим вище - тим різкіше.", "zh_CN": "设置 FSR 1.0 的锐化等级,数值越高,图像越锐利。", "zh_TW": "設定 FSR 1.0 銳化等級。越高越清晰。" } @@ -22514,7 +20582,6 @@ "pl_PL": "SMAA Niskie", "pt_BR": "SMAA Baixo", "ru_RU": "SMAA Низкое", - "sv_SE": "SMAA låg", "th_TH": "SMAA ต่ำ", "tr_TR": "Düşük SMAA", "uk_UA": "SMAA Низький", @@ -22539,7 +20606,6 @@ "pl_PL": "SMAA Średnie", "pt_BR": "SMAA Médio", "ru_RU": "SMAA Среднее", - "sv_SE": "SMAA medium", "th_TH": "SMAA ปานกลาง", "tr_TR": "Orta SMAA", "uk_UA": "SMAA Середній", @@ -22564,7 +20630,6 @@ "pl_PL": "SMAA Wysokie", "pt_BR": "SMAA Alto", "ru_RU": "SMAA Высокое", - "sv_SE": "SMAA hög", "th_TH": "SMAA สูง", "tr_TR": "Yüksek SMAA", "uk_UA": "SMAA Високий", @@ -22589,7 +20654,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "SMAA Ультра", - "sv_SE": "SMAA ultra", "th_TH": "SMAA สูงมาก", "tr_TR": "En Yüksek SMAA", "uk_UA": "SMAA Ультра", @@ -22607,14 +20671,13 @@ "es_ES": "Editar usuario", "fr_FR": "Modifier Utilisateur", "he_IL": "ערוך משתמש", - "it_IT": "Modifica utente", + "it_IT": "Modificare L'Utente", "ja_JP": "ユーザを編集", "ko_KR": "사용자 편집", "no_NO": "Rediger bruker", "pl_PL": "Edytuj użytkownika", - "pt_BR": "Editar Usuário", + "pt_BR": "Editar usuário", "ru_RU": "Редактирование пользователя", - "sv_SE": "Redigera användare", "th_TH": "แก้ไขผู้ใช้", "tr_TR": "Kullanıcıyı Düzenle", "uk_UA": "Редагувати користувача", @@ -22632,14 +20695,13 @@ "es_ES": "Crear Usuario", "fr_FR": "Créer Utilisateur", "he_IL": "צור משתמש", - "it_IT": "Crea utente", + "it_IT": "Crea Un Utente", "ja_JP": "ユーザを作成", "ko_KR": "사용자 만들기", "no_NO": "Opprett bruker", "pl_PL": "Utwórz użytkownika", "pt_BR": "Criar usuário", "ru_RU": "Создание пользователя", - "sv_SE": "Skapa användare", "th_TH": "สร้างผู้ใช้", "tr_TR": "Kullanıcı Oluştur", "uk_UA": "Створити користувача", @@ -22659,12 +20721,11 @@ "he_IL": "ממשק רשת", "it_IT": "Interfaccia di rete:", "ja_JP": "ネットワークインタフェース:", - "ko_KR": "네트워크 인터페이스 :", + "ko_KR": "네트워크 인터페이스:", "no_NO": "Nettverksgrensesnitt", "pl_PL": "Interfejs sieci:", - "pt_BR": "Interface de Rede:", + "pt_BR": "Interface de rede:", "ru_RU": "Сетевой интерфейс:", - "sv_SE": "Nätverksgränssnitt:", "th_TH": "เชื่อมต่อเครือข่าย:", "tr_TR": "Ağ Bağlantısı:", "uk_UA": "Мережевий інтерфейс:", @@ -22688,8 +20749,7 @@ "no_NO": "Nettverksgrensesnittets grensesnitt brukt for LAN/LDN funksjoner.\n\ni konjuksjon med en VPN eller XLink Kai og ett spill med LAN støtte, kan bli brukt til og spoofe ett \"samme-nettverk\" tilkobling over nettet.\n\nLa være på DEFAULT om usikker.", "pl_PL": "Interfejs sieciowy używany dla funkcji LAN/LDN.\n\nw połączeniu z VPN lub XLink Kai i grą z obsługą sieci LAN, może być użyty do spoofowania połączenia z tą samą siecią przez Internet.\n\nZostaw DOMYŚLNE, jeśli nie ma pewności.", "pt_BR": "A interface de rede usada para recursos de LAN/LDN.\n\nEm conjunto com uma VPN ou XLink Kai e um jogo com suporte a LAN, pode ser usada para simular uma conexão na mesma rede pela Internet.\n\nMantenha em PADRÃO se estiver em dúvida.", - "ru_RU": "Сетевой интерфейс, используемый для функций LAN/LDN.\n\nМожет использоваться для игры через интернет в сочетании с VPN или XLink Kai и игрой с поддержкой LAN.\n\nРекомендуется использовать «По умолчанию».", - "sv_SE": "Nätverksgränssnittet som används för LAN/LDN-funktioner.\n\nTillsammans med en VPN eller XLink Kai och ett spel med LAN-stöd så kan detta användas för att spoofa en same-network-anslutning över internet.\n\nLämna som STANDARD om du är osäker.", + "ru_RU": "Сетевой интерфейс, используемый для функций LAN/LDN.\n\nМожет использоваться для игры через интернет в сочетании с VPN или XLink Kai и игрой с поддержкой LAN.\n\nРекомендуется использовать \"По умолчанию\".", "th_TH": "อินเทอร์เฟซเครือข่ายที่ใช้สำหรับคุณสมบัติ LAN/LDN\n\nเมื่อใช้ร่วมกับ VPN หรือ XLink Kai และเกมที่รองรับ LAN สามารถใช้เพื่อปลอมการเชื่อมต่อเครือข่ายเดียวกันผ่านทางอินเทอร์เน็ต\n\nปล่อยให้เป็น ค่าเริ่มต้น หากคุณไม่แน่ใจ", "tr_TR": "", "uk_UA": "Мережевий інтерфейс, що використовується для LAN/LDN.\n\nРазом з VPN або XLink Kai, і грою що підтримує LAN, може імітувати з'єднання в однаковій мережі через Інтернет.", @@ -22714,7 +20774,6 @@ "pl_PL": "Domyślny", "pt_BR": "Padrão", "ru_RU": "По умолчанию", - "sv_SE": "Standard", "th_TH": "ค่าเริ่มต้น", "tr_TR": "Varsayılan", "uk_UA": "Стандартний", @@ -22739,7 +20798,6 @@ "pl_PL": "Pakuje Shadery ", "pt_BR": "Empacotamento de Shaders", "ru_RU": "Упаковка шейдеров", - "sv_SE": "Paketering av Shaders", "th_TH": "รวม Shaders เข้าด้วยกัน", "tr_TR": "Gölgeler Paketleniyor", "uk_UA": "Пакування шейдерів", @@ -22762,9 +20820,8 @@ "ko_KR": "GitHub에서 변경 내역 보기", "no_NO": "Vis endringslogg på GitHub", "pl_PL": "Zobacz listę zmian na GitHubie", - "pt_BR": "Ver Mudanças no GitHub", - "ru_RU": "Показать список изменений на GitHub", - "sv_SE": "Visa ändringslogg på GitHub", + "pt_BR": "Ver mudanças no GitHub", + "ru_RU": "Список изменений на GitHub", "th_TH": "ดูประวัติการเปลี่ยนแปลงบน GitHub", "tr_TR": "GitHub'da Değişiklikleri Görüntüle", "uk_UA": "Переглянути журнал змін на GitHub", @@ -22782,14 +20839,13 @@ "es_ES": "Haga clic para abrir el registro de cambios para esta versión en su navegador predeterminado.", "fr_FR": "Cliquez pour ouvrir le changelog de cette version dans votre navigateur par défaut.", "he_IL": "לחץ כדי לפתוח את יומן השינויים עבור גרסה זו בדפדפן ברירת המחדל שלך.", - "it_IT": "Clicca per aprire il changelog di questa versione nel tuo browser predefinito.", + "it_IT": "Clicca per aprire il changelog per questa versione nel tuo browser predefinito.", "ja_JP": "クリックして, このバージョンの更新履歴をデフォルトのブラウザで開きます.", "ko_KR": "기본 브라우저에서 이 버전의 변경 내역을 열람하려면 클릭하세요.", "no_NO": "Klikk for å åpne endringsloggen for denne versjonen i din nettleser.", "pl_PL": "Kliknij, aby otworzyć listę zmian dla tej wersji w domyślnej przeglądarce.", "pt_BR": "Clique para abrir o relatório de alterações para esta versão no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть список изменений для этой версии", - "sv_SE": "Klicka för att öppna ändringsloggen för denna version i din standardwebbläsare.", "th_TH": "คลิกเพื่อเปิดประวัติการเปลี่ยนแปลงสำหรับเวอร์ชั่นนี้ บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Kullandığınız versiyon için olan değişiklikleri varsayılan tarayıcınızda görmek için tıklayın", "uk_UA": "Клацніть, щоб відкрити журнал змін для цієї версії у стандартному браузері.", @@ -22812,9 +20868,8 @@ "ko_KR": "멀티플레이어", "no_NO": "Flerspiller", "pl_PL": "Gra Wieloosobowa", - "pt_BR": "Multijogador", + "pt_BR": "", "ru_RU": "Мультиплеер", - "sv_SE": "Flerspelare", "th_TH": "ผู้เล่นหลายคน", "tr_TR": "Çok Oyunculu", "uk_UA": "Мережева гра", @@ -22839,7 +20894,6 @@ "pl_PL": "Tryb:", "pt_BR": "Modo:", "ru_RU": "Режим:", - "sv_SE": "Läge:", "th_TH": "โหมด:", "tr_TR": "Mod:", "uk_UA": "Режим:", @@ -22863,8 +20917,7 @@ "no_NO": "Endre LDN flerspillermodus.\n\nLdnMitm vil endre lokal trådløst/lokal spillfunksjonalitet i spill som skal fungere som om den var LAN, noe som tillater lokal, samme nettverk forbindelser med andre Ryujinx instanser og hacket Nintendo Switch konsoller som har installert ldn_mitm-modulen.\n\nFlerspiller krever at alle spillerne er på samme versjon (dvs. Super Smash Bros. Ultimat v13.0.1 kan ikke koble til v13.0.0).\n\nForlat DEAKTIVERT hvis usikker.", "pl_PL": "", "pt_BR": "Alterar o modo multiplayer LDN.\n\nLdnMitm modificará a funcionalidade de jogo sem fio/local nos jogos para funcionar como se fosse LAN, permitindo conexões locais, na mesma rede, com outras instâncias do Ryujinx e consoles Nintendo Switch hackeados que possuem o módulo ldn_mitm instalado.\n\nO multiplayer exige que todos os jogadores estejam na mesma versão do jogo (ex.: Super Smash Bros. Ultimate v13.0.1 não consegue se conectar à v13.0.0).\n\nDeixe DESATIVADO se estiver em dúvida.", - "ru_RU": "Меняет многопользовательский режим LDN.\n\nLdnMitm модифицирует функциональность локальной беспроводной/игры на одном устройстве в играх, позволяя играть с другими пользователями Ryujinx или взломанными консолями Nintendo Switch с установленным модулем ldn_mitm, находящимися в одной локальной сети друг с другом.\n\nМногопользовательская игра требует наличия у всех игроков одной и той же версии игры (т.е. Super Smash Bros. Ultimate v13.0.1 не может подключиться к v13.0.0).\n\nРекомендуется оставить выключенным.", - "sv_SE": "Ändra LDN-flerspelarläge\n\nLdnMitm kommer att ändra lokal funktionalitet för trådlös/lokalt spel att fungera som om det vore ett LAN, vilket ger stöd för anslutningar med local och same-network med andra Ryujinx-instanser och hackade Nintendo Switch-konsoller som har modulen ldn_mitm installerad.\n\nFlerspelare kräver att alla spelare har samma spelversion (t.ex. Super Smash Bros. Ultimate v13.0.1 kan inte ansluta till v13.0.0).\n\nLämna INAKTIVERAD om du är osäker.", + "ru_RU": "Меняет многопользовательский режим LDN.\n\nLdnMitm модифицирует функциональность локальной беспроводной/игры на одном устройстве в играх, позволяя играть с другими пользователями Ryujinx или взломанными консолями Nintendo Switch с установленным модулем ldn_mitm, находящимися в одной локальной сети друг с другом.\n\nМногопользовательская игра требует наличия у всех игроков одной и той же версии игры (т.е. Super Smash Bros. Ultimate v13.0.1 не может подключиться к v13.0.0).\n\nРекомендуется оставить отключенным.", "th_TH": "เปลี่ยนโหมดผู้เล่นหลายคนของ LDN\n\nLdnMitm จะปรับเปลี่ยนฟังก์ชันการเล่นแบบไร้สาย/ภายใน จะให้เกมทำงานเหมือนกับว่าเป็น LAN ช่วยให้สามารถเชื่อมต่อภายในเครือข่ายเดียวกันกับอินสแตนซ์ Ryujinx อื่น ๆ และคอนโซล Nintendo Switch ที่ถูกแฮ็กซึ่งมีโมดูล ldn_mitm ติดตั้งอยู่\n\nผู้เล่นหลายคนต้องการให้ผู้เล่นทุกคนอยู่ในเกมเวอร์ชันเดียวกัน (เช่น Super Smash Bros. Ultimate v13.0.1 ไม่สามารถเชื่อมต่อกับ v13.0.0)\n\nปล่อยให้ปิดการใช้งานหากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Змінити LDN мультиплеєру.\n\nLdnMitm змінить функціонал бездротової/локальної гри в іграх, щоб вони працювали так, ніби це LAN, що дозволяє локальні підключення в тій самій мережі з іншими екземплярами Ryujinx та хакнутими консолями Nintendo Switch, які мають встановлений модуль ldn_mitm.\n\nМультиплеєр вимагає, щоб усі гравці були на одній і тій же версії гри (наприклад Super Smash Bros. Ultimate v13.0.1 не зможе під'єднатися до v13.0.0).\n\nЗалиште на \"Вимкнено\", якщо не впевнені, ", @@ -22889,7 +20942,6 @@ "pl_PL": "Wyłączone", "pt_BR": "Desativado", "ru_RU": "Отключено", - "sv_SE": "Inaktiverad", "th_TH": "ปิดใช้งาน", "tr_TR": "Devre Dışı", "uk_UA": "Вимкнено", @@ -22914,7 +20966,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -22939,7 +20990,6 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -22962,14 +21012,13 @@ "ko_KR": "P2P 네트워크 호스팅 비활성화(대기 시간이 늘어날 수 있음)", "no_NO": "Deaktiver P2P-nettverkshosting (kan øke ventetiden)", "pl_PL": "", - "pt_BR": "Desabilitar hospedagem de rede P2P (pode aumentar a latência)", - "ru_RU": "Отключить хостинг P2P-сетей (может увеличить задержку)", - "sv_SE": "Inaktivera P2P-nätverkshosting (kan öka latens)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)", - "zh_CN": "禁用 P2P 网络连接 (也许会增加延迟)", - "zh_TW": "停用對等網路代管 (P2P Network Hosting) (可能增加網路延遲)" + "zh_CN": "", + "zh_TW": "" } }, { @@ -22987,14 +21036,13 @@ "ko_KR": "P2P 네트워크 호스팅을 비활성화하면 피어가 직접 연결하지 않고 마스터 서버를 통해 프록시합니다.", "no_NO": "Deaktiver P2P-nettverkshosting, så vil andre brukere gå via hovedserveren i stedet for å koble seg direkte til deg.", "pl_PL": "", - "pt_BR": "Desabilite a hospedagem de rede P2P, os pares farão proxy através do servidor mestre em vez de se conectarem a você diretamente.", - "ru_RU": "Отключая хостинг P2P-сетей, пользователи будут проксироваться через главный сервер, а не подключаться к вам напрямую.", - "sv_SE": "Inaktivera P2P-nätverkshosting, motparter kommer skickas genom masterservern isället för att ansluta direkt till dig.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.", - "zh_CN": "禁用 P2P 网络连接,对方将通过主服务器进行连接,而不是直接连接到您。", - "zh_TW": "停用對等網路代管 (P2P Network Hosting), 用戶群會經過代理何服器而非直接連線至你的主機。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23012,14 +21060,13 @@ "ko_KR": "네트워크 암호 문구 :", "no_NO": "Nettverkspassord:", "pl_PL": "", - "pt_BR": "Senha de Rede:", - "ru_RU": "Cетевой пароль:", - "sv_SE": "Lösenfras för nätverk:", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Мережевий пароль:", - "zh_CN": "网络密码:", - "zh_TW": "網路密碼片語 (passphrase):" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23037,14 +21084,13 @@ "ko_KR": "귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.", "no_NO": "Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.", "pl_PL": "", - "pt_BR": "Você só poderá ver jogos hospedados com a mesma senha que você.", - "ru_RU": "Вы сможете видеть только те игры, в которых используется тот же пароль, что и у вас.", - "sv_SE": "Du kommer endast kunna se hostade spel med samma lösenfras som du.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.", - "zh_CN": "您只能看到与您使用相同密码的游戏房间。", - "zh_TW": "你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23062,14 +21108,13 @@ "ko_KR": "Ryujinx-<8 hex chars> 형식으로 암호를 입력하세요. 귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.", "no_NO": "Skriv inn en passordfrase i formatet Ryujinx-<8 heks tegn>. Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.", "pl_PL": "", - "pt_BR": "Insira uma frase-senha no formato Ryujinx-<8 hex chars>. Você só poderá ver jogos hospedados com a mesma frase-senha que você.", - "ru_RU": "Введите пароль в формате Ryujinx-<8 шестнадцатеричных символов>. Вы сможете видеть только те игры, в которых используется тот же пароль, что и у вас.", - "sv_SE": "Ange en lösenfras i formatet Ryujinx-<8 hextecken>. Du kommer endast kunna se hostade spel med samma lösenfras som du.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.", - "zh_CN": "以 Ryujinx-<8个十六进制字符> 的格式输入密码。您只能看到与您使用相同密码的游戏房间。", - "zh_TW": "以「Ryujinx-<8 個十六進制數字>」的格式輸入密碼片語 (passphrase)。你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23087,14 +21132,13 @@ "ko_KR": "(일반)", "no_NO": "(offentlig)", "pl_PL": "", - "pt_BR": "(público)", - "ru_RU": "(публичный)", - "sv_SE": "(publik)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "(публічний)", - "zh_CN": "(公开的)", - "zh_TW": "(公開模式)" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23112,14 +21156,13 @@ "ko_KR": "무작위 생성", "no_NO": "Generer tilfeldig", "pl_PL": "", - "pt_BR": "Gerar Aleatório", - "ru_RU": "Сгенерировать рандомно", - "sv_SE": "Generera slumpmässigt", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Згенерувати випадкову", - "zh_CN": "随机生成", - "zh_TW": "隨機產生" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23137,14 +21180,13 @@ "ko_KR": "다른 플레이어와 공유할 수 있는 새로운 암호 문구를 생성합니다.", "no_NO": "Genererer en ny passordfrase, som kan deles med andre spillere.", "pl_PL": "", - "pt_BR": "Gera uma nova senha, que pode ser compartilhada com outros jogadores.", - "ru_RU": "Генерирует новый пароль, который можно передать другим игрокам.", - "sv_SE": "Genererar en ny lösenfras som kan delas med andra spelare.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.", - "zh_CN": "生成一个新的密码,可以与其他玩家共享。", - "zh_TW": "產生一組新的密碼片語 (passphrase), 以供分享給其他玩家。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23162,14 +21204,13 @@ "ko_KR": "지우기", "no_NO": "Slett", "pl_PL": "", - "pt_BR": "Limpar", - "ru_RU": "Очистить", - "sv_SE": "Töm", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Очистити", - "zh_CN": "清除", - "zh_TW": "清除" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23187,14 +21228,13 @@ "ko_KR": "현재 암호를 지우고 공용 네트워크로 돌아갑니다.", "no_NO": "Sletter den gjeldende passordfrasen og går tilbake til det offentlige nettverket.", "pl_PL": "", - "pt_BR": "Limpa a senha atual, retornando à rede pública.", - "ru_RU": "Очищает текущий пароль, возвращаясь в публичную сеть.", - "sv_SE": "Tömmer aktuell lösenfras och återgår till det publika nätverket.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.", - "zh_CN": "清除当前密码,返回公共网络。", - "zh_TW": "清除現有的密碼片語 (passphrase), 藉此公開網路連線。" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23212,14 +21252,13 @@ "ko_KR": "유효하지 않은 암호입니다! \"Ryujinx-<8 hex chars>\" 형식이어야 합니다.", "no_NO": "Ugyldig passordfrase! Må være i formatet \"Ryujinx-<8 hex tegn>\"", "pl_PL": "", - "pt_BR": "Frase-senha inválida! Deve estar no formato \"Ryujinx-<8 hex chars>\"", - "ru_RU": "Неверный пароль! Пароль должен быть в формате «Ryujinx-<8 шестнадцатеричных символов>»", - "sv_SE": "Ogiltig lösenfras! Måste vara i formatet \"Ryujinx-<8 hextecken>\"", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"", - "zh_CN": "无效密码!密码的格式必须是\"Ryujinx-<8个十六进制字符>\"", - "zh_TW": "無效的密碼片語 (passphrase)! 密碼片語必須是以「Ryujinx-<8 個十六進制數字>」的格式輸入" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23238,13 +21277,12 @@ "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "Вертикальная синхронизация:", - "sv_SE": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Вертикальна синхронізація (VSync):", - "zh_CN": "垂直同步(VSync)", - "zh_TW": "垂直同步:" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23257,19 +21295,18 @@ "es_ES": "", "fr_FR": "Activer le taux de rafraîchissement customisé (Expérimental)", "he_IL": "", - "it_IT": "Attiva la frequenza di aggiornamento personalizzata (sperimentale)", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 활성화(실험적)", "no_NO": "Aktiver egendefinert oppdateringsfrekvens (eksperimentell)", "pl_PL": "", - "pt_BR": "Habilitar taxa de atualização personalizada (Experimental)", - "ru_RU": "Включить пользовательскую частоту кадров (Экспериментально)", - "sv_SE": "Aktivera anpassad uppdateringsfrekvens (experimentell)", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)", - "zh_CN": "启动自定义刷新率(实验性功能)", - "zh_TW": "啟用自訂的重新整理頻率 (實驗性功能)" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23280,7 +21317,7 @@ "el_GR": "", "en_US": "Switch", "es_ES": "", - "fr_FR": "", + "fr_FR": "Switch", "he_IL": "", "it_IT": "", "ja_JP": "", @@ -23288,8 +21325,7 @@ "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "Консоль", - "sv_SE": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -23307,19 +21343,18 @@ "es_ES": "", "fr_FR": "Sans Limite", "he_IL": "", - "it_IT": "Nessun limite", + "it_IT": "", "ja_JP": "", "ko_KR": "무제한", "no_NO": "Ubegrenset", "pl_PL": "", - "pt_BR": "Ilimitado", - "ru_RU": "Без ограничений", - "sv_SE": "Obunden", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Безмежна", - "zh_CN": "无限制", - "zh_TW": "沒有限制" + "zh_CN": "", + "zh_TW": "" } }, { @@ -23332,194 +21367,186 @@ "es_ES": "", "fr_FR": "Taux de Rafraîchissement Customisé", "he_IL": "", - "it_IT": "Frequenza di aggiornamento personalizzata", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율", "no_NO": "Egendefinert oppdateringsfrekvens", "pl_PL": "", - "pt_BR": "Taxa de Atualização Personalizada", - "ru_RU": "Пользовательская частота кадров", - "sv_SE": "Anpassad uppdateringsfrekvens", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька", - "zh_CN": "自定义刷新率", - "zh_TW": "自訂的重新整理頻率" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemVSyncModeTooltip", "Translations": { "ar_SA": "", - "de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. \"Unbounded\" ist eine unbegrenzte Bildwiederholfrequenz.", + "de_DE": "", "el_GR": "", "en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate.", "es_ES": "", "fr_FR": "VSync émulé. 'Switch' émule le taux de rafraîchissement de la Switch (60Hz). 'Sans Limite' est un taux de rafraîchissement qui n'est pas limité.", "he_IL": "", - "it_IT": "Sincronizzazione verticale emulata. \"Switch\" emula la frequenza di aggiornamento di Nintendo Switch (60Hz). \"Nessun limite\" non impone alcun limite alla frequenza di aggiornamento.", + "it_IT": "", "ja_JP": "", "ko_KR": "에뮬레이트된 수직 동기화. '스위치'는 스위치의 60Hz 주사율을 에뮬레이트합니다. '무한'은 무제한 주사율입니다.", "no_NO": "Emulert vertikal synkronisering. «Switch» emulerer Switchs oppdateringsfrekvens på 60 Hz. «Ubegrenset» er en ubegrenset oppdateringsfrekvens.", "pl_PL": "", - "pt_BR": "Sincronização vertical emulada. 'Switch' emula a taxa de atualização de 60 Hz do Switch. 'Ilimitada' é uma taxa de atualização sem limite.", - "ru_RU": "Эмулированная вертикальная синхронизация. «Консоль» эмулирует частоту обновления консоли, равную 60 Гц. «Без ограничений» — неограниченная частота кадров.", - "sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень.", - "zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。", - "zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。" + "uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemVSyncModeTooltipCustom", "Translations": { "ar_SA": "", - "de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. „Unbounded“ ist eine unbegrenzte Bildwiederholfrequenz. „Benutzerdefinierte Bildwiederholfrequenz“ emuliert die angegebene benutzerdefinierte Bildwiederholfrequenz.", + "de_DE": "", "el_GR": "", "en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate. 'Custom Refresh Rate' emulates the specified custom refresh rate.", "es_ES": "", "fr_FR": "VSync émulé. 'Switch' émule le taux de rafraîchissement de la Switch (60Hz). 'Sans Limite' est un taux de rafraîchissement qui n'est pas limité. 'Taux de Rafraîchissement Customisé' émule le taux de rafraîchissement spécifié.", "he_IL": "", - "it_IT": "Sincronizzazione verticale emulata. \"Switch\" emula la frequenza di aggiornamento di Nintendo Switch (60Hz). \"Nessun limite\" non impone alcun limite alla frequenza di aggiornamento. \"Frequenza di aggiornamento personalizzata\" emula la frequenza di aggiornamento specificata.", + "it_IT": "", "ja_JP": "", "ko_KR": "에뮬레이트된 수직 동기화. '스위치'는 스위치의 60Hz 주사율을 에뮬레이트합니다. '무한'은 무제한 주사율입니다. '사용자 지정'은 지정된 사용자 지정 주사율을 에뮬레이트합니다.", "no_NO": "Emulert vertikal synkronisering. «Switch» emulerer Switchs oppdateringsfrekvens på 60 Hz. «Ubegrenset» er en ubegrenset oppdateringsfrekvens. «Egendefinert» emulerer den angitte egendefinerte oppdateringsfrekvensen.", "pl_PL": "", - "pt_BR": "Sincronização Vertical Emulada. 'Switch' emula a taxa de atualização de 60 Hz do Switch. 'Ilimitada' é uma taxa de atualização sem limite. 'Taxa de atualização personalizada' emula a taxa de atualização personalizada especificada.", - "ru_RU": "Эмулированная вертикальная синхронизация. «Консоль» эмулирует частоту обновления консоли, равную 60 Гц. «Без ограничений» — неограниченная частота кадров. «Пользовательска частота кадров» эмулирует выбранную пользователем частоту кадров.", - "sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens. 'Anpassad uppdateringsfrekvens' emulerar den angivna anpassade uppdateringsfrekvensen.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.", - "zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。", - "zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。" + "uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemEnableCustomVSyncIntervalTooltip", "Translations": { "ar_SA": "", - "de_DE": "Ermöglicht es dem Benutzer, eine emulierte Bildwiederholfrequenz festzulegen. In einigen Titeln kann dies die Geschwindigkeit der Spiel-Logik erhöhen oder verringern. In anderen Titeln kann dies dazu führen, dass die FPS auf ein Vielfaches der Bildwiederholfrequenz begrenzt werden oder zu unvorhersehbarem Verhalten führen. Dies ist eine experimentelle Funktion, ohne Garantien dafür, wie sich das Gameplay auswirkt. \n\nLassen Sie diese Option deaktiviert, wenn Sie sich nicht sicher sind.", + "de_DE": "", "el_GR": "", "en_US": "Allows the user to specify an emulated refresh rate. In some titles, this may speed up or slow down the rate of gameplay logic. In other titles, it may allow for capping FPS at some multiple of the refresh rate, or lead to unpredictable behavior. This is an experimental feature, with no guarantees for how gameplay will be affected. \n\nLeave OFF if unsure.", "es_ES": "", "fr_FR": "Permet à l'utilisateur de spécifier un taux de rafraîchissement émulé. Dans certains jeux, ceci pourrait accélérer ou ralentir le taux de logique du gameplay. Dans d'autre titres, cela permettrait limiter le FPS à un multiple du taux de rafraîchissement, ou conduire à un comportement imprévisible. Ceci est une fonctionnalité expérimentale, avec aucune garanties pour comment le gameplay sera affecté. \n\nLaisser désactiver en cas de doute.", "he_IL": "", - "it_IT": "Consente all'utente di specificare una frequenza di aggiornamento emulata. In alcuni titoli potrebbe aumentare o diminuire la velocità del gameplay, mentre in altri potrebbe consentire di limitare il framerate a un multiplo della frequenza di aggiornamento, o causare comportamenti imprevedibili. Questa funzionalità è sperimentale, e non ci sono certezze sul modo in cui influenzerà il gameplay.\n\nNel dubbio, lascia l'opzione disattivata.", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자가 에뮬레이트된 화면 주사율을 지정할 수 있습니다. 일부 타이틀에서는 게임플레이 로직 속도가 빨라지거나 느려질 수 있습니다. 다른 타이틀에서는 주사율의 배수로 FPS를 제한하거나 예측할 수 없는 동작으로 이어질 수 있습니다. 이는 실험적 기능으로 게임 플레이에 어떤 영향을 미칠지 보장할 수 없습니다. \n\n모르면 끔으로 두세요.", "no_NO": "Gjør det mulig for brukeren å angi en emulert oppdateringsfrekvens. I noen titler kan dette øke eller senke hastigheten på spillogikken. I andre titler kan det gjøre det mulig å begrense FPS til et multiplum av oppdateringsfrekvensen, eller føre til uforutsigbar oppførsel. Dette er en eksperimentell funksjon, og det gis ingen garantier for hvordan spillingen påvirkes. \n\nLa AV stå hvis du er usikker.", "pl_PL": "", - "pt_BR": "Permite que o usuário especifique uma taxa de atualização emulada. Em alguns títulos, isso pode acelerar ou desacelerar a taxa de lógica do jogo. Em outros títulos, pode permitir limitar o FPS em algum múltiplo da taxa de atualização ou levar a um comportamento imprevisível. Este é um recurso experimental, sem garantias de como o jogo será afetado. \n\nDeixe OFF se não tiver certeza.", - "ru_RU": "Позволяет пользователю указать эмулируемую частоту кадров. В некоторых играх это может ускорить или замедлить скорость логики игрового процесса. В других играх это может позволить ограничить FPS на уровне, кратном частоте обновления, или привести к непредсказуемому поведению. Это экспериментальная функция, и нет никаких гарантий того, как она повлияет на игровой процесс. \n\nОставьте выключенным, если не уверены.", - "sv_SE": "Låter användaren ange en emulerad uppdateringsfrekvens. För vissa spel så kan detta snabba upp eller ner frekvensen för spellogiken. I andra spel så kan detta tillåta att bildfrekvensen kapas för delar av uppdateringsfrekvensen eller leda till oväntat beteende. Detta är en experimentell funktion utan några garantier för hur spelet påverkas. \n\nLämna AV om du är osäker.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. Натомість в інших іграх ця функція може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як вона вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.", - "zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将 FPS 限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。", - "zh_TW": "容許使用者自訂模擬的重新整理頻率。你可能會在某些遊戲裡感受到加快或減慢的遊戲速度;其他遊戲裡則可能會容許限制最高的 FPS 至重新整理頻率的倍數,或引起未知遊戲行為。這是實驗性功能,且沒有保證遊戲會穩定執行。\n\n如果不確定,請保持關閉狀態。" + "uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalValueTooltip", "Translations": { "ar_SA": "", - "de_DE": "Der Zielwert für die benutzerdefinierte Bildwiederholfrequenz.", + "de_DE": "", "el_GR": "", "en_US": "The custom refresh rate target value.", "es_ES": "", "fr_FR": "La valeur cible du taux de rafraîchissement customisé.", "he_IL": "", - "it_IT": "Il valore desiderato della frequenza di aggiornamento personalizzata.", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 목표 값입니다.", "no_NO": "Den egendefinerte målverdien for oppdateringsfrekvens.", "pl_PL": "", - "pt_BR": "O valor de meta da taxa de atualização personalizada.", - "ru_RU": "Заданное значение частоты кадров", - "sv_SE": "Målvärde för anpassad uppdateringsfrekvens.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Цільове значення користувацької частоти оновлення.", - "zh_CN": "目标自定义刷新率值。", - "zh_TW": "自訂的重新整理頻率數值。" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalSliderTooltip", "Translations": { "ar_SA": "", - "de_DE": "Die benutzerdefinierte Bildwiederholfrequenz als Prozentsatz der normalen Switch-Bildwiederholfrequenz.", + "de_DE": "", "el_GR": "", "en_US": "The custom refresh rate, as a percentage of the normal Switch refresh rate.", "es_ES": "", "fr_FR": "Le taux de rafraîchissement customisé, comme un pourcentage du taux de rafraîchissement normal de la Switch.", "he_IL": "", - "it_IT": "La frequenza di aggiornamento personalizzata, espressa in percentuale della normale frequenza di aggiornamento di Switch.", + "it_IT": "", "ja_JP": "", "ko_KR": "일반 스위치 주사율의 백분율로 나타낸 사용자 지정 주사율입니다.", "no_NO": "Den egendefinerte oppdateringsfrekvensen, i prosent av den normale oppdateringsfrekvensen for Switch-konsollen.", "pl_PL": "", - "pt_BR": "A taxa de atualização personalizada, como uma porcentagem da taxa de atualização normal do Switch.", - "ru_RU": "Пользовательская частота кадров в процентах от обычной частоты обновления на консоли.", - "sv_SE": "Anpassad uppdateringsfrekvens, som en procentdel av den normala uppdateringsfrekvensen för Switch.", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.", - "zh_CN": "自定义刷新率,占正常SWitch刷新率的百分比值。", - "zh_TW": "以 Nintendo Switch 重新整理頻率的百分比自訂重新整理頻率。" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalPercentage", "Translations": { "ar_SA": "", - "de_DE": "Benutzerdefinierte Bildwiederholfrequenz %:", + "de_DE": "", "el_GR": "", "en_US": "Custom Refresh Rate %:", "es_ES": "", "fr_FR": "Pourcentage du Taux de Rafraîchissement Customisé :", "he_IL": "", - "it_IT": "Frequenza di aggiornamento personalizzata (%):", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 % :", "no_NO": "Egendefinert oppdateringsfrekvens %:", "pl_PL": "", - "pt_BR": "Taxa de Atualização Personalizada %:", - "ru_RU": "Пользовательская частота кадров %:", - "sv_SE": "Anpassad uppdateringsfrekvens %:", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька частота оновлення %:", - "zh_CN": "自定义刷新率值 %:", - "zh_TW": "自訂重新整理頻率 %:" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalValue", "Translations": { "ar_SA": "", - "de_DE": "Wert für benutzerdefinierte Bildwiederholfrequenz:", + "de_DE": "", "el_GR": "", "en_US": "Custom Refresh Rate Value:", "es_ES": "", "fr_FR": "Valeur du Taux de Rafraîchissement Customisé :", "he_IL": "", - "it_IT": "Valore della frequenza di aggiornamento personalizzata:", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 값 :", "no_NO": "Egendefinert verdi for oppdateringsfrekvens:", "pl_PL": "", - "pt_BR": "Valor da Taxa de Atualização Personalizada:", - "ru_RU": "Значение пользовательской частоты кадров:", - "sv_SE": "Värde för anpassad uppdateringsfrekvens:", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Значення користувацької частоти оновлення:", - "zh_CN": "自定义刷新率值:", - "zh_TW": "自訂重新整理頻率數值:" + "uk_UA": "Значення користувацька частота оновлення:", + "zh_CN": "", + "zh_TW": "" } }, { @@ -23532,545 +21559,91 @@ "es_ES": "", "fr_FR": "Intervalle", "he_IL": "", - "it_IT": "Intervallo", + "it_IT": "", "ja_JP": "", "ko_KR": "간격", "no_NO": "Intervall", "pl_PL": "", - "pt_BR": "Intervalo", - "ru_RU": "Интервал", - "sv_SE": "Intervall", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", - "uk_UA": "Інтервал", - "zh_CN": "间隔", - "zh_TW": "間隔" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabHotkeysToggleVSyncModeHotkey", "Translations": { "ar_SA": "", - "de_DE": "VSync-Modus umschalten:", + "de_DE": "", "el_GR": "", "en_US": "Toggle VSync mode:", "es_ES": "", "fr_FR": "Activer/Désactiver mode VSync :", "he_IL": "", - "it_IT": "Cambia modalità VSync:", + "it_IT": "", "ja_JP": "", "ko_KR": "수직 동기화 모드 전환 :", "no_NO": "Veksle mellom VSync-modus:", "pl_PL": "", - "pt_BR": "Alternar Modo VSync:", - "ru_RU": "Выбрать режим вертикальной синхронизации:", - "sv_SE": "Växla VSync-läge:", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Перемкнути VSync режим:", - "zh_CN": "设置 VSync 模式:", - "zh_TW": "切換 VSync 模式:" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey", "Translations": { "ar_SA": "", - "de_DE": "Benutzerdefinierte Bildwiederholfrequenz erhöhen:", + "de_DE": "", "el_GR": "", "en_US": "Raise custom refresh rate", "es_ES": "", "fr_FR": "Augmenter le taux de rafraîchissement customisé :", "he_IL": "", - "it_IT": "Aumenta la frequenza di aggiornamento personalizzata:", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 증가", "no_NO": "Øk den egendefinerte oppdateringsfrekvensen", "pl_PL": "", - "pt_BR": "Aumentar Taxa de Atualização:", - "ru_RU": "Повышение пользовательской частоты кадров", - "sv_SE": "Höj anpassad uppdateringsfrekvens", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Підвищити користувацьку частоту оновлення", - "zh_CN": "提高自定义刷新率:", - "zh_TW": "提高自訂的重新整理頻率" + "zh_CN": "", + "zh_TW": "" } }, { "ID": "SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey", "Translations": { "ar_SA": "", - "de_DE": "Benutzerdefinierte Bildwiederholfrequenz senken:", + "de_DE": "", "el_GR": "", "en_US": "Lower custom refresh rate:", "es_ES": "", "fr_FR": "Baisser le taux de rafraîchissement customisé :", "he_IL": "", - "it_IT": "Riduci la frequenza di aggiornamento personalizzata:", + "it_IT": "", "ja_JP": "", "ko_KR": "사용자 정의 주사율 감소", "no_NO": "Lavere tilpasset oppdateringsfrekvens", "pl_PL": "", - "pt_BR": "Reduzir Taxa de Atualização:", - "ru_RU": "Понижение пользовательской частоты кадров", - "sv_SE": "Sänk anpassad uppdateringsfrekvens", + "pt_BR": "", + "ru_RU": "", "th_TH": "", "tr_TR": "", "uk_UA": "Понизити користувацьку частоту оновлення", - "zh_CN": "降低自定义刷新率:", - "zh_TW": "降低自訂的重新整理頻率" - } - }, - { - "ID": "CompatibilityListLastUpdated", - "Translations": { - "ar_SA": "", - "de_DE": "Zuletzt aktualisiert: {0}", - "el_GR": "", - "en_US": "Last updated: {0}", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "최종 업데이트 : {0}", - "no_NO": "Sist oppdatert: {0}", - "pl_PL": "", - "pt_BR": "Última atualização: {0}", - "ru_RU": "Последнее обновление: {0}", - "sv_SE": "Senast uppdaterad: {0}", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Останнє оновлення: {0}", - "zh_CN": "最后更新于: {0}", - "zh_TW": "上次更新時間: {0}" - } - }, - { - "ID": "CompatibilityListWarning", - "Translations": { - "ar_SA": "", - "de_DE": "Diese Kompatibilitätsliste könnte veraltete Einträge enthalten. Teste dennoch Spiele im \"Ingame\"-Status.", - "el_GR": "", - "en_US": "This compatibility list might contain out of date entries.\nDo not be opposed to testing games in the \"Ingame\" status.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "이 호환성 목록에는 오래된 항목이 포함되어 있을 수 있습니다.\n\"게임 내\" 상태에서 게임을 테스트하는 것을 반대하지 마십시오.", - "no_NO": "Denne kompatibilitetslisten kan inneholde oppføringer som er tomme for data.\nVær ikke imot å teste spill i statusen «Ingame».", - "pl_PL": "", - "pt_BR": "Esta lista de compatibilidade pode estar desatualizada.\nNão se oponha a testar os jogos", - "ru_RU": "В списке совместимости могут содержаться устаревшие записи.\nНе стестняйтесь тестировать игр в статусе «Запускается»", - "sv_SE": "Denna kompatibilitetslista kan innehålla utdaterade poster.\nTesta gärna spelen som listas med \"Spelproblem\"-status.", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Цей список сумісності може містити застарілі дані.\nНе відмовляйтеся від тестування ігор що мають статус \"Запускаються\".", - "zh_CN": "此兼容性列表可能包含过时的条目。\n不要只测试 \"进入游戏\" 状态的游戏。", - "zh_TW": "這個相容性列表可能含有已過時的紀錄。\n敬請繼續測試「大致可遊玩 (Ingame)」狀態的遊戲並回報以更新紀錄。" - } - }, - { - "ID": "CompatibilityListSearchBoxWatermark", - "Translations": { - "ar_SA": "", - "de_DE": "Kompatibilitätseinträge durchsuchen...", - "el_GR": "", - "en_US": "Search compatibility entries...", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "호환성 항목 검색...", - "no_NO": "Søk i kompatibilitetsoppføringer...", - "pl_PL": "", - "pt_BR": "Pesquisa de compatibilidade", - "ru_RU": "Поиск записей о совместимости...", - "sv_SE": "Sök i kompatibilitetsposter...", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Перевірити сумісність гри...", - "zh_CN": "正在搜索兼容性条目...", - "zh_TW": "搜尋相容性列表紀錄..." - } - }, - { - "ID": "CompatibilityListOpen", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Open Compatibility List", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "호환성 목록 열기", - "no_NO": "Åpne kompatibilitetslisten", - "pl_PL": "", - "pt_BR": "Lista de Compatibilidade", - "ru_RU": "Открыть список совместимости", - "sv_SE": "Öppna kompatibilitetslistan", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Відкрити Список Сумісності", - "zh_CN": "打开兼容性列表", - "zh_TW": "開啟相容性列表" - } - }, - { - "ID": "CompatibilityListOnlyShowOwnedGames", - "Translations": { - "ar_SA": "", - "de_DE": "Nur eigene Spiele anzeigen", - "el_GR": "", - "en_US": "Only show owned games", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "보유 게임만 표시", - "no_NO": "Vis bare eide spill", - "pl_PL": "", - "pt_BR": "Mostrar apenas jogos disponíveis", - "ru_RU": "Показывать только свои игры", - "sv_SE": "Visa endast ägda spel", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Показувати лише ігри в наявності", - "zh_CN": "仅显示拥有的游戏", - "zh_TW": "只顯示已擁有的遊戲" - } - }, - { - "ID": "CompatibilityListPlayable", - "Translations": { - "ar_SA": "", - "de_DE": "Spielbar", - "el_GR": "", - "en_US": "Playable", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "플레이 가능", - "no_NO": "Spillbar", - "pl_PL": "", - "pt_BR": "Jogável", - "ru_RU": "Играбельно", - "sv_SE": "Spelbart", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Оптимально", - "zh_CN": "可游玩", - "zh_TW": "可暢順遊玩" - } - }, - { - "ID": "CompatibilityListIngame", - "Translations": { - "ar_SA": "", - "de_DE": "Im Spiel", - "el_GR": "", - "en_US": "Ingame", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "게임 내", - "no_NO": "", - "pl_PL": "", - "pt_BR": "No jogo", - "ru_RU": "Запускается", - "sv_SE": "Spelproblem", - "th_TH": "", - "tr_TR": "", - "uk_UA": "З недоліками", - "zh_CN": "进入游戏", - "zh_TW": "大致可遊玩" - } - }, - { - "ID": "CompatibilityListMenus", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Menus", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "메뉴", - "no_NO": "Menyer", - "pl_PL": "", - "pt_BR": "Menu", - "ru_RU": "Меню", - "sv_SE": "Menyer", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Меню", - "zh_CN": "菜单", - "zh_TW": "只開啟至遊戲開始功能表" - } - }, - { - "ID": "CompatibilityListBoots", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Boots", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "부츠", - "no_NO": "Starter", - "pl_PL": "", - "pt_BR": "Inicializa", - "ru_RU": "Стартует", - "sv_SE": "Startar", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускається", - "zh_CN": "启动", - "zh_TW": "只能啟動" - } - }, - { - "ID": "CompatibilityListNothing", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Nothing", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "없음", - "no_NO": "Ingenting", - "pl_PL": "", - "pt_BR": "Nada", - "ru_RU": "Ничего", - "sv_SE": "Ingenting", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Не працює", - "zh_CN": "什么都没有", - "zh_TW": "無法啟動" - } - }, - { - "ID": "CompatibilityListPlayableTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Boots and plays without any crashes or GPU bugs of any kind, and at a speed fast enough to reasonably enjoy on an average PC.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.", - "pl_PL": "", - "pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.", - "ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.", - "zh_CN": "启动和游戏时不会出现任何崩溃或任何类型的 GPU bug 且速度足够快可以在一般 PC 上尽情游玩。", - "zh_TW": "" - } - }, - { - "ID": "CompatibilityListIngameTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Boots and goes in-game but suffers from one or more of the following: crashes, deadlocks, GPU bugs, distractingly bad audio, or is simply too slow. Game still might able to be played all the way through, but not as the game is intended to play.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.", - "pl_PL": "", - "pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.", - "ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.", - "zh_CN": "可以成功启动并进入游戏但可能会遇到以下一种或多种问题: 崩溃、卡死、GPU bug、令人无法接受的音频,或者只是太慢。仍然可以继续进行游戏,但是可能无法达到预期。", - "zh_TW": "" - } - }, - { - "ID": "CompatibilityListMenusTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Boots and goes past the title screen but does not make it into main gameplay.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Starter opp og går forbi tittelskjermen, men kommer ikke inn i hovedspillet.", - "pl_PL": "", - "pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.", - "ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.", - "zh_CN": "可以启动并通过标题画面但是无法进入到主要的游戏流程。", - "zh_TW": "" - } - }, - { - "ID": "CompatibilityListBootsTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "Startet, kommt aber nicht über den Titelbildschirm hinaus.", - "el_GR": "", - "en_US": "Boots but does not make it past the title screen.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Starter, men kommer ikke lenger enn til tittelskjermen.", - "pl_PL": "", - "pt_BR": "Inizializa, mas não passa da tela de título.", - "ru_RU": "Загружается, но не проходит дальше титульного экрана.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Запускається, але не відображає навіть початкового екрану.", - "zh_CN": "可以启动但是无法通过标题画面。", - "zh_TW": "" - } - }, - { - "ID": "CompatibilityListNothingTooltip", - "Translations": { - "ar_SA": "", - "de_DE": "Startet nicht oder zeigt keine Anzeichen von Aktivität.", - "el_GR": "", - "en_US": "Does not boot or shows no signs of activity.", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.", - "pl_PL": "", - "pt_BR": "Não inicializa ou não mostra sinais de atividade.", - "ru_RU": "Не запускается или не подаёт признаков жизни.", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Взагалі не запускається.", - "zh_CN": "无法启动或显示无任何动静。", - "zh_TW": "" - } - }, - { - "ID": "ExtractAocListHeader", - "Translations": { - "ar_SA": "", - "de_DE": "Wähle ein DLC zum Extrahieren aus", - "el_GR": "", - "en_US": "Select a DLC to Extract", - "es_ES": "", - "fr_FR": "Choisissez un DLC à extraire", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "추출할 DLC 선택", - "no_NO": "Velg en DLC og hente ut", - "pl_PL": "", - "pt_BR": "Selecione um DLC para Extrair", - "ru_RU": "Выберите DLC для извлечения", - "sv_SE": "Välj en DLC att extrahera", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Оберіть DLC які бажаєте вилучити", - "zh_CN": "选择一个要解压的 DLC", - "zh_TW": "" - } - }, - { - "ID": "GameInfoRpcImage", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Rich Presence Image", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Rikt nærværsbilde", - "pl_PL": "", - "pt_BR": "Imagem da Presença do Discord", - "ru_RU": "Изображение для статуса активности", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Зображення картки активності Discord", - "zh_CN": "Rich Presence 图像", - "zh_TW": "" - } - }, - { - "ID": "GameInfoRpcDynamic", - "Translations": { - "ar_SA": "", - "de_DE": "", - "el_GR": "", - "en_US": "Dynamic Rich Presence", - "es_ES": "", - "fr_FR": "", - "he_IL": "", - "it_IT": "", - "ja_JP": "", - "ko_KR": "", - "no_NO": "Dynamisk og rik tilstedeværelse", - "pl_PL": "", - "pt_BR": "Presença Dinâmica do Discord", - "ru_RU": "Динамический статус активности", - "sv_SE": "", - "th_TH": "", - "tr_TR": "", - "uk_UA": "Динамічна картка активності Discord", - "zh_CN": "动态 Rich Presence", + "zh_CN": "", "zh_TW": "" } } ] -} \ No newline at end of file +} diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.cs b/src/Ryujinx/Headless/HeadlessRyujinx.cs index 003b8a31e..12158176a 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.cs @@ -1,11 +1,13 @@ using CommandLine; using Gommon; -using Ryujinx.Ava; -using Ryujinx.Ava.Utilities.Configuration; +using LibHac.Tools.FsSystem; +using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Controller.Motion; +using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; using Ryujinx.Common.Logging.Targets; @@ -13,9 +15,14 @@ using Ryujinx.Common.SystemInterop; using Ryujinx.Common.Utilities; using Ryujinx.Cpu; using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu.Shader; +using Ryujinx.Graphics.OpenGL; +using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan.MoltenVK; +using Ryujinx.Headless.SDL2.OpenGL; +using Ryujinx.Headless.SDL2.Vulkan; using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; @@ -24,16 +31,22 @@ using Ryujinx.Input; using Ryujinx.Input.HLE; using Ryujinx.Input.SDL2; using Ryujinx.SDL2.Common; +using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.IO; -using System.Linq; +using System.Text.Json; using System.Threading; +using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId; +using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; +using Key = Ryujinx.Common.Configuration.Hid.Key; -namespace Ryujinx.Headless +namespace Ryujinx.Headless.SDL2 { - public partial class HeadlessRyujinx + class Program { + public static string Version { get; private set; } + private static VirtualFileSystem _virtualFileSystem; private static ContentManager _contentManager; private static AccountManager _accountManager; @@ -43,18 +56,20 @@ namespace Ryujinx.Headless private static Switch _emulationContext; private static WindowBase _window; private static WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution; - private static List _inputConfiguration = []; + private static List _inputConfiguration; private static bool _enableKeyboard; private static bool _enableMouse; private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - public static void Entrypoint(string[] args) + static void Main(string[] args) { + Version = ReleaseInformation.Version; + // Make process DPI aware for proper window sizing on high-res screens. ForceDpiAware.Windows(); - Console.Title = $"HeadlessRyujinx Console {Program.Version}"; + Console.Title = $"Ryujinx Console {Version} (Headless SDL2)"; if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) { @@ -82,7 +97,7 @@ namespace Ryujinx.Headless } Parser.Default.ParseArguments(args) - .WithParsed(options => Load(args, options)) + .WithParsed(Load) .WithNotParsed(errors => { Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:"); @@ -90,86 +105,239 @@ namespace Ryujinx.Headless errors.ForEach(err => Logger.Error?.PrintMsg(LogClass.Application, $" - {err.Tag}")); }); } - - public static void ReloadConfig(string customConfigPath = null) + + private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) { - string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); - string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); - - string configurationPath = null; - - // Now load the configuration as the other subsystems are now registered - if (customConfigPath != null && File.Exists(customConfigPath)) + if (inputId == null) { - configurationPath = customConfigPath; - } - else if (File.Exists(localConfigurationPath)) - { - configurationPath = localConfigurationPath; - } - else if (File.Exists(appDataConfigurationPath)) - { - configurationPath = appDataConfigurationPath; - } - - if (configurationPath == null) - { - // No configuration, we load the default values and save it to disk - configurationPath = appDataConfigurationPath; - Logger.Notice.Print(LogClass.Application, $"No configuration file found. Saving default configuration to: {configurationPath}"); - - ConfigurationState.Instance.LoadDefault(); - ConfigurationState.Instance.ToFileFormat().SaveConfig(configurationPath); - } - else - { - Logger.Notice.Print(LogClass.Application, $"Loading configuration from: {configurationPath}"); - - if (ConfigurationFileFormat.TryLoad(configurationPath, out ConfigurationFileFormat configurationFileFormat)) + if (index == PlayerIndex.Player1) { - ConfigurationState.Instance.Load(configurationFileFormat, configurationPath); + Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard."); + + // Default to keyboard + inputId = "0"; } else { - Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location: {configurationPath}"); + Logger.Info?.Print(LogClass.Application, $"{index} not configured"); - ConfigurationState.Instance.LoadDefault(); + return null; } } + + IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId); + + bool isKeyboard = true; + + if (gamepad == null) + { + gamepad = _inputManager.GamepadDriver.GetGamepad(inputId); + isKeyboard = false; + + if (gamepad == null) + { + Logger.Error?.Print(LogClass.Application, $"{index} gamepad not found (\"{inputId}\")"); + + return null; + } + } + + string gamepadName = gamepad.Name; + + gamepad.Dispose(); + + InputConfig config; + + if (inputProfileName == null || inputProfileName.Equals("default")) + { + if (isKeyboard) + { + config = new StandardKeyboardInputConfig + { + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.WindowKeyboard, + Id = null, + ControllerType = ControllerType.JoyconPair, + LeftJoycon = new LeftJoyconCommonConfig + { + DpadUp = Key.Up, + DpadDown = Key.Down, + DpadLeft = Key.Left, + DpadRight = Key.Right, + ButtonMinus = Key.Minus, + ButtonL = Key.E, + ButtonZl = Key.Q, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound, + }, + + LeftJoyconStick = new JoyconConfigKeyboardStick + { + StickUp = Key.W, + StickDown = Key.S, + StickLeft = Key.A, + StickRight = Key.D, + StickButton = Key.F, + }, + + RightJoycon = new RightJoyconCommonConfig + { + ButtonA = Key.Z, + ButtonB = Key.X, + ButtonX = Key.C, + ButtonY = Key.V, + ButtonPlus = Key.Plus, + ButtonR = Key.U, + ButtonZr = Key.O, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound, + }, + + RightJoyconStick = new JoyconConfigKeyboardStick + { + StickUp = Key.I, + StickDown = Key.K, + StickLeft = Key.J, + StickRight = Key.L, + StickButton = Key.H, + }, + }; + } + else + { + bool isNintendoStyle = gamepadName.Contains("Nintendo"); + + config = new StandardControllerInputConfig + { + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.GamepadSDL2, + Id = null, + ControllerType = ControllerType.JoyconPair, + DeadzoneLeft = 0.1f, + DeadzoneRight = 0.1f, + RangeLeft = 1.0f, + RangeRight = 1.0f, + TriggerThreshold = 0.5f, + LeftJoycon = new LeftJoyconCommonConfig + { + DpadUp = ConfigGamepadInputId.DpadUp, + DpadDown = ConfigGamepadInputId.DpadDown, + DpadLeft = ConfigGamepadInputId.DpadLeft, + DpadRight = ConfigGamepadInputId.DpadRight, + ButtonMinus = ConfigGamepadInputId.Minus, + ButtonL = ConfigGamepadInputId.LeftShoulder, + ButtonZl = ConfigGamepadInputId.LeftTrigger, + ButtonSl = ConfigGamepadInputId.Unbound, + ButtonSr = ConfigGamepadInputId.Unbound, + }, + + LeftJoyconStick = new JoyconConfigControllerStick + { + Joystick = ConfigStickInputId.Left, + StickButton = ConfigGamepadInputId.LeftStick, + InvertStickX = false, + InvertStickY = false, + Rotate90CW = false, + }, + + RightJoycon = new RightJoyconCommonConfig + { + ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, + ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, + ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, + ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, + ButtonPlus = ConfigGamepadInputId.Plus, + ButtonR = ConfigGamepadInputId.RightShoulder, + ButtonZr = ConfigGamepadInputId.RightTrigger, + ButtonSl = ConfigGamepadInputId.Unbound, + ButtonSr = ConfigGamepadInputId.Unbound, + }, + + RightJoyconStick = new JoyconConfigControllerStick + { + Joystick = ConfigStickInputId.Right, + StickButton = ConfigGamepadInputId.RightStick, + InvertStickX = false, + InvertStickY = false, + Rotate90CW = false, + }, + + Motion = new StandardMotionConfigController + { + MotionBackend = MotionInputBackendType.GamepadDriver, + EnableMotion = true, + Sensitivity = 100, + GyroDeadzone = 1, + }, + Rumble = new RumbleConfigController + { + StrongRumble = 1f, + WeakRumble = 1f, + EnableRumble = false, + }, + }; + } + } + else + { + string profileBasePath; + + if (isKeyboard) + { + profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "keyboard"); + } + else + { + profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "controller"); + } + + string path = Path.Combine(profileBasePath, inputProfileName + ".json"); + + if (!File.Exists(path)) + { + Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" not found for \"{inputId}\""); + + return null; + } + + try + { + config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig); + } + catch (JsonException) + { + Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" parsing failed for \"{inputId}\""); + + return null; + } + } + + config.Id = inputId; + config.PlayerIndex = index; + + string inputTypeName = isKeyboard ? "Keyboard" : "Gamepad"; + + Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\""); + + // If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0. + if (config is StandardControllerInputConfig controllerConfig) + { + if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f) + { + controllerConfig.RangeLeft = 1.0f; + controllerConfig.RangeRight = 1.0f; + + Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration"); + } + } + + return config; } - static void Load(string[] originalArgs, Options option) + static void Load(Options option) { - Initialize(); - - bool useLastUsedProfile = false; - - if (option.InheritConfig) - { - option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile); - } - AppDataManager.Initialize(option.BaseDataDir); - - if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out UserProfile profile)) - option.UserProfile = profile.Name; - - // Check if keys exists. - if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"))) - { - if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys")))) - { - Logger.Error?.Print(LogClass.Application, "Keys not found"); - } - } - - ReloadConfig(); - if (option.InheritConfig) - { - option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance); - } - _virtualFileSystem = VirtualFileSystem.CreateInstance(); _libHacHorizonManager = new LibHacHorizonManager(); @@ -184,7 +352,7 @@ namespace Ryujinx.Headless _inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver()); - GraphicsConfig.EnableShaderCache = !option.DisableShaderCache; + GraphicsConfig.EnableShaderCache = true; if (OperatingSystem.IsMacOS()) { @@ -195,13 +363,15 @@ namespace Ryujinx.Headless } } + IGamepad gamepad; + if (option.ListInputIds) { Logger.Info?.Print(LogClass.Application, "Input Ids:"); foreach (string id in _inputManager.KeyboardDriver.GamepadsIds) { - IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(id); + gamepad = _inputManager.KeyboardDriver.GetGamepad(id); Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); @@ -210,7 +380,7 @@ namespace Ryujinx.Headless foreach (string id in _inputManager.GamepadDriver.GamepadsIds) { - IGamepad gamepad = _inputManager.GamepadDriver.GetGamepad(id); + gamepad = _inputManager.GamepadDriver.GetGamepad(id); Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); @@ -227,12 +397,22 @@ namespace Ryujinx.Headless return; } - _inputConfiguration ??= []; + _inputConfiguration = new List(); _enableKeyboard = option.EnableKeyboard; _enableMouse = option.EnableMouse; - + + static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) + { + InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index); + + if (inputConfig != null) + { + _inputConfiguration.Add(inputConfig); + } + } + LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1); - LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); + LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); LoadPlayerConfiguration(option.InputProfile3Name, option.InputId3, PlayerIndex.Player3); LoadPlayerConfiguration(option.InputProfile4Name, option.InputId4, PlayerIndex.Player4); LoadPlayerConfiguration(option.InputProfile5Name, option.InputId5, PlayerIndex.Player5); @@ -240,7 +420,7 @@ namespace Ryujinx.Headless LoadPlayerConfiguration(option.InputProfile7Name, option.InputId7, PlayerIndex.Player7); LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8); LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld); - + if (_inputConfiguration.Count == 0) { return; @@ -251,7 +431,7 @@ namespace Ryujinx.Headless Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub); Logger.SetEnable(LogLevel.Info, !option.LoggingDisableInfo); Logger.SetEnable(LogLevel.Warning, !option.LoggingDisableWarning); - Logger.SetEnable(LogLevel.Error, !option.LoggingDisableError); + Logger.SetEnable(LogLevel.Error, option.LoggingEnableError); Logger.SetEnable(LogLevel.Trace, option.LoggingEnableTrace); Logger.SetEnable(LogLevel.Guest, !option.LoggingDisableGuest); Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog); @@ -288,10 +468,6 @@ namespace Ryujinx.Headless GraphicsConfig.EnableMacroHLE = !option.DisableMacroHLE; DriverUtilities.InitDriverConfig(option.BackendThreading == BackendThreading.Off); - - if (_inputConfiguration.OfType() - .Any(ic => ic?.Led?.UseRainbow ?? false)) - Rainbow.Enable(); while (true) { @@ -305,28 +481,7 @@ namespace Ryujinx.Headless _userChannelPersistence.ShouldRestart = false; } - try - { - _inputManager.Dispose(); - } catch {} - - return; - - void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) - { - if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0) - { - Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured."); - return; - } - - InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index); - - if (inputConfig != null) - { - _inputConfiguration.Add(inputConfig); - } - } + _inputManager.Dispose(); } private static void SetupProgressHandler() @@ -345,24 +500,96 @@ namespace Ryujinx.Headless { string label = state switch { - LoadState => "PTC", - ShaderCacheState => "Shaders", - _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}") + LoadState => $"PTC : {current}/{total}", + ShaderCacheState => $"Shaders : {current}/{total}", + _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"), }; - Logger.Info?.Print(LogClass.Application, $"{label} : {current}/{total}"); + Logger.Info?.Print(LogClass.Application, label); } private static WindowBase CreateWindow(Options options) { - return options.GraphicsBackend switch + return options.GraphicsBackend == GraphicsBackend.Vulkan + ? new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet) + : new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet); + } + + private static IRenderer CreateRenderer(Options options, WindowBase window) + { + if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow) { - GraphicsBackend.Vulkan => new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet), - GraphicsBackend.Metal => OperatingSystem.IsMacOS() ? - new MetalWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableKeyboard, options.HideCursorMode, options.IgnoreControllerApplet) : - throw new Exception("Attempted to use Metal renderer on non-macOS platform!"), - _ => new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet) - }; + string preferredGpuId = string.Empty; + Vk api = Vk.GetApi(); + + if (!string.IsNullOrEmpty(options.PreferredGPUVendor)) + { + string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant(); + var devices = VulkanRenderer.GetPhysicalDevices(api); + + foreach (var device in devices) + { + if (device.Vendor.ToLowerInvariant() == preferredGpuVendor) + { + preferredGpuId = device.Id; + break; + } + } + } + + return new VulkanRenderer( + api, + (instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))), + vulkanWindow.GetRequiredInstanceExtensions, + preferredGpuId); + } + + return new OpenGLRenderer(); + } + + private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) + { + BackendThreading threadingMode = options.BackendThreading; + + bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); + + if (threadedGAL) + { + renderer = new ThreadedRenderer(renderer); + } + + HLEConfiguration configuration = new(_virtualFileSystem, + _libHacHorizonManager, + _contentManager, + _accountManager, + _userChannelPersistence, + renderer, + new SDL2HardwareDeviceDriver(), + options.DramSize, + window, + options.SystemLanguage, + options.SystemRegion, + options.VSyncMode, + !options.DisableDockedMode, + !options.DisablePTC, + options.EnableInternetAccess, + !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, + options.FsGlobalAccessLogMode, + options.SystemTimeOffset, + options.SystemTimeZone, + options.MemoryManagerMode, + options.IgnoreMissingServices, + options.AspectRatio, + options.AudioVolume, + options.UseHypervisor ?? true, + options.MultiplayerLanInterfaceId, + Common.Configuration.Multiplayer.MultiplayerMode.Disabled, + false, + string.Empty, + string.Empty, + options.CustomVSyncInterval); + + return new Switch(configuration); } private static void ExecutionEntrypoint() diff --git a/src/Ryujinx/Headless/Windows/MetalWindow.cs b/src/Ryujinx/Headless/Windows/MetalWindow.cs deleted file mode 100644 index d79bd7938..000000000 --- a/src/Ryujinx/Headless/Windows/MetalWindow.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Ryujinx.Common.Configuration; -using Ryujinx.Input.HLE; -using Ryujinx.SDL2.Common; -using SharpMetal.QuartzCore; -using System.Runtime.Versioning; -using static SDL2.SDL; - -namespace Ryujinx.Headless -{ - [SupportedOSPlatform("macos")] - class MetalWindow : WindowBase - { - private CAMetalLayer _caMetalLayer; - - public CAMetalLayer GetLayer() - { - return _caMetalLayer; - } - - public MetalWindow( - InputManager inputManager, - GraphicsDebugLevel glLogLevel, - AspectRatio aspectRatio, - bool enableMouse, - HideCursorMode hideCursorMode, - bool ignoreControllerApplet) - : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { } - - public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_METAL; - - protected override void InitializeWindowRenderer() - { - void CreateLayer() - { - _caMetalLayer = new CAMetalLayer(SDL_Metal_GetLayer(SDL_Metal_CreateView(WindowHandle))); - } - - SDL2Driver.MainThreadDispatcher?.Invoke(CreateLayer); - } - - protected override void InitializeRenderer() { } - - protected override void FinalizeWindowRenderer() { } - - protected override void SwapBuffers() { } - } -} diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index d7987534f..9b8ded44b 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -204,7 +204,6 @@ namespace Ryujinx.Ava { "opengl" => GraphicsBackend.OpenGl, "vulkan" => GraphicsBackend.Vulkan, - "metal" => GraphicsBackend.Metal, _ => ConfigurationState.Instance.Graphics.GraphicsBackend }; diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 174aadeb0..ce75b1d87 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -13,10 +13,9 @@ $(DefaultItemExcludes);._* - - - - + + + @@ -48,9 +47,6 @@ - - - @@ -60,8 +56,6 @@ - - @@ -72,8 +66,6 @@ - - @@ -81,7 +73,9 @@ + + @@ -114,10 +108,6 @@ Designer - - - - MSBuild:Compile @@ -127,6 +117,7 @@ + @@ -135,42 +126,14 @@ - - Assets\ShortcutFiles\shortcut-template.desktop - - - Assets\ShortcutFiles\shortcut-launch-script.sh - - - Assets\ShortcutFiles\shortcut-template.plist - - - Assets\RyujinxGameCompatibility.csv - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs deleted file mode 100644 index 9e92d9289..000000000 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Ryujinx.Common.Helper; -using SharpMetal.QuartzCore; -using System; - -namespace Ryujinx.Ava.UI.Renderer -{ - public class EmbeddedWindowMetal : EmbeddedWindow - { - public CAMetalLayer CreateSurface() - { - if (OperatingSystem.IsMacOS() && RunningPlatform.IsArm) - { - return new CAMetalLayer(MetalLayer); - } - - throw new NotSupportedException($"Cannot create a {nameof(CAMetalLayer)} without being on ARM Mac."); - } - } -} diff --git a/src/Ryujinx/UI/Renderer/RendererHost.cs b/src/Ryujinx/UI/Renderer/RendererHost.cs index f755b6d70..4bf10d0d7 100644 --- a/src/Ryujinx/UI/Renderer/RendererHost.cs +++ b/src/Ryujinx/UI/Renderer/RendererHost.cs @@ -1,15 +1,12 @@ -using Avalonia; +using Avalonia; using Avalonia.Controls; -using Avalonia.Media; -using Ryujinx.Ava.Utilities.Configuration; -using Ryujinx.Common; using Ryujinx.Common.Configuration; -using Ryujinx.Common.Logging; +using Ryujinx.UI.Common.Configuration; using System; namespace Ryujinx.Ava.UI.Renderer { - public class RendererHost : UserControl, IDisposable + public partial class RendererHost : UserControl, IDisposable { public readonly EmbeddedWindow EmbeddedWindow; @@ -18,58 +15,20 @@ namespace Ryujinx.Ava.UI.Renderer public RendererHost() { - Focusable = true; - FlowDirection = FlowDirection.LeftToRight; + InitializeComponent(); - EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch + if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl) { - GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), - GraphicsBackend.Metal => new EmbeddedWindowMetal(), - GraphicsBackend.Vulkan or GraphicsBackend.Auto => new EmbeddedWindowVulkan(), - _ => throw new NotSupportedException() - }; + EmbeddedWindow = new EmbeddedWindowOpenGL(); + } + else + { + EmbeddedWindow = new EmbeddedWindowVulkan(); + } Initialize(); } - public GraphicsBackend Backend => - EmbeddedWindow switch - { - EmbeddedWindowVulkan => GraphicsBackend.Vulkan, - EmbeddedWindowOpenGL => GraphicsBackend.OpenGl, - EmbeddedWindowMetal => GraphicsBackend.Metal, - _ => throw new NotImplementedException() - }; - - public RendererHost(string titleId) - { - Focusable = true; - FlowDirection = FlowDirection.LeftToRight; - - EmbeddedWindow = -#pragma warning disable CS8509 - TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend) switch -#pragma warning restore CS8509 - { - GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), - GraphicsBackend.Metal => new EmbeddedWindowMetal(), - GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), - }; - - string backendText = EmbeddedWindow switch - { - EmbeddedWindowVulkan => "Vulkan", - EmbeddedWindowOpenGL => "OpenGL", - EmbeddedWindowMetal => "Metal", - _ => throw new NotImplementedException() - }; - - Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend ({ConfigurationState.Instance.Graphics.GraphicsBackend.Value}): {backendText}"); - - Initialize(); - } - - private void Initialize() { EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated; @@ -107,4 +66,3 @@ namespace Ryujinx.Ava.UI.Renderer } } } - diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 1dd4a6b6d..21db4c310 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1574,7 +1574,7 @@ namespace Ryujinx.Ava.UI.ViewModels PrepareLoadScreen(); - RendererHostControl = new RendererHost(application.Id.ToString("X16")); + RendererHostControl = new RendererHost(); AppHost = new AppHost( RendererHostControl, diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index fe71a7420..0824e3f86 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -1,8 +1,6 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Threading; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL2; @@ -11,24 +9,23 @@ using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Windows; -using Ryujinx.Ava.Utilities.Configuration; -using Ryujinx.Ava.Utilities.Configuration.System; -using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; -using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Time.TimeZone; +using Ryujinx.UI.Common.Configuration; +using Ryujinx.UI.Common.Configuration.System; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.NetworkInformation; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using System.Threading.Tasks; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; @@ -48,9 +45,10 @@ namespace Ryujinx.Ava.UI.ViewModels private int _resolutionScale; private int _graphicsBackendMultithreadingIndex; private float _volume; - [ObservableProperty] private bool _isVulkanAvailable = true; - [ObservableProperty] private bool _gameListNeedsRefresh; - private readonly List _gpuIds = []; + private bool _isVulkanAvailable = true; + private bool _gameDirectoryChanged; + private bool _autoloadDirectoryChanged; + private readonly List _gpuIds = new(); private int _graphicsBackendIndex; private int _scalingFilter; private int _scalingFilterLevel; @@ -64,9 +62,7 @@ namespace Ryujinx.Ava.UI.ViewModels private int _networkInterfaceIndex; private int _multiplayerModeIndex; private string _ldnPassphrase; - [ObservableProperty] private string _ldnServer; - - public SettingsHacksViewModel DirtyHacks { get; } + private string _LdnServer; public int ResolutionScale { @@ -75,7 +71,8 @@ namespace Ryujinx.Ava.UI.ViewModels { _resolutionScale = value; - OnPropertiesChanged(nameof(CustomResolutionScale), nameof(IsCustomResolutionScaleActive)); + OnPropertyChanged(nameof(CustomResolutionScale)); + OnPropertyChanged(nameof(IsCustomResolutionScaleActive)); } } @@ -112,8 +109,45 @@ namespace Ryujinx.Ava.UI.ViewModels } } + public bool IsVulkanAvailable + { + get => _isVulkanAvailable; + set + { + _isVulkanAvailable = value; + + OnPropertyChanged(); + } + } + public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS(); + public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64; + + public bool GameDirectoryChanged + { + get => _gameDirectoryChanged; + set + { + _gameDirectoryChanged = value; + + OnPropertyChanged(); + } + } + + public bool AutoloadDirectoryChanged + { + get => _autoloadDirectoryChanged; + set + { + _autoloadDirectoryChanged = value; + + OnPropertyChanged(); + } + } + + public bool IsMacOS => OperatingSystem.IsMacOS(); + public bool EnableDiscordIntegration { get; set; } public bool CheckUpdatesOnStart { get; set; } public bool ShowConfirmExit { get; set; } @@ -121,20 +155,17 @@ namespace Ryujinx.Ava.UI.ViewModels public bool RememberWindowState { get; set; } public bool ShowTitleBar { get; set; } public int HideCursor { get; set; } - public int UpdateCheckerType { get; set; } public bool EnableDockedMode { get; set; } public bool EnableKeyboard { get; set; } public bool EnableMouse { get; set; } - public bool DisableInputWhenOutOfFocus { get; set; } - - public int FocusLostActionType { get; set; } - public VSyncMode VSyncMode { get => _vSyncMode; set { - if (value is VSyncMode.Custom or VSyncMode.Switch or VSyncMode.Unbounded) + if (value == VSyncMode.Custom || + value == VSyncMode.Switch || + value == VSyncMode.Unbounded) { _vSyncMode = value; OnPropertyChanged(); @@ -150,13 +181,19 @@ namespace Ryujinx.Ava.UI.ViewModels int newInterval = (int)((value / 100f) * 60); _customVSyncInterval = newInterval; _customVSyncIntervalPercentageProxy = value; - OnPropertiesChanged( - nameof(CustomVSyncInterval), - nameof(CustomVSyncIntervalPercentageText)); + OnPropertyChanged((nameof(CustomVSyncInterval))); + OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText))); } } - public string CustomVSyncIntervalPercentageText => CustomVSyncIntervalPercentageProxy + "%"; + public string CustomVSyncIntervalPercentageText + { + get + { + string text = CustomVSyncIntervalPercentageProxy.ToString() + "%"; + return text; + } + } public bool EnableCustomVSyncInterval { @@ -184,9 +221,8 @@ namespace Ryujinx.Ava.UI.ViewModels _customVSyncInterval = value; int newPercent = (int)((value / 60f) * 100); _customVSyncIntervalPercentageProxy = newPercent; - OnPropertiesChanged( - nameof(CustomVSyncIntervalPercentageProxy), - nameof(CustomVSyncIntervalPercentageText)); + OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy)); + OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText)); OnPropertyChanged(); } } @@ -200,7 +236,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTextureRecompression { get; set; } public bool EnableMacroHLE { get; set; } public bool EnableColorSpacePassthrough { get; set; } - public bool ColorSpacePassthroughAvailable => RunningPlatform.IsMacOS; + public bool ColorSpacePassthroughAvailable => IsMacOS; public bool EnableFileLog { get; set; } public bool EnableStub { get; set; } public bool EnableInfo { get; set; } @@ -209,7 +245,6 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTrace { get; set; } public bool EnableGuest { get; set; } public bool EnableFsAccessLog { get; set; } - public bool EnableAvaloniaLog { get; set; } public bool EnableDebug { get; set; } public bool IsOpenAlEnabled { get; set; } public bool IsSoundIoEnabled { get; set; } @@ -217,13 +252,10 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsCustomResolutionScaleActive => _resolutionScale == 4; public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr; - public bool IsVulkanSelected => - GraphicsBackendIndex == 1 || (GraphicsBackendIndex == 0 && !OperatingSystem.IsMacOS()); + public bool IsVulkanSelected => GraphicsBackendIndex == 0; public bool UseHypervisor { get; set; } public bool DisableP2P { get; set; } - public bool ShowDirtyHacks => ConfigurationState.Instance.Hacks.ShowDirtyHacks; - public string TimeZone { get; set; } public string ShaderDumpPath { get; set; } @@ -297,8 +329,6 @@ namespace Ryujinx.Ava.UI.ViewModels } } - [ObservableProperty] private bool _matchSystemTime; - public DateTimeOffset CurrentDate { get; set; } public TimeSpan CurrentTime { get; set; } @@ -321,6 +351,7 @@ namespace Ryujinx.Ava.UI.ViewModels set { _networkInterfaceIndex = value != -1 ? value : 0; + ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]]; } } @@ -330,21 +361,32 @@ namespace Ryujinx.Ava.UI.ViewModels set { _multiplayerModeIndex = value; + ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex; } } + [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] + private static partial Regex LdnPassphraseRegex(); + public bool IsInvalidLdnPassphraseVisible { get; set; } + public string LdnServer + { + get => _LdnServer; + set + { + _LdnServer = value; + OnPropertyChanged(); + } + } + public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this() { _virtualFileSystem = virtualFileSystem; _contentManager = contentManager; - if (Program.PreviewerDetached) { Task.Run(LoadTimeZones); - - DirtyHacks = new SettingsHacksViewModel(this); } } @@ -364,8 +406,6 @@ namespace Ryujinx.Ava.UI.ViewModels { Task.Run(LoadAvailableGpus); LoadCurrentConfiguration(); - - DirtyHacks = new SettingsHacksViewModel(this); } } @@ -387,16 +427,16 @@ namespace Ryujinx.Ava.UI.ViewModels { AvailableGpus.Clear(); - DeviceInfo[] devices = VulkanRenderer.GetPhysicalDevices(); + var devices = VulkanRenderer.GetPhysicalDevices(); if (devices.Length == 0) { IsVulkanAvailable = false; - GraphicsBackendIndex = 2; + GraphicsBackendIndex = 1; } else { - foreach (DeviceInfo device in devices) + foreach (var device in devices) { await Dispatcher.UIThread.InvokeAsync(() => { @@ -414,6 +454,18 @@ namespace Ryujinx.Ava.UI.ViewModels Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(PreferredGpuIndex))); } + public void MatchSystemTime() + { + var dto = DateTimeOffset.Now; + + CurrentDate = new DateTimeOffset(dto.Year, dto.Month, dto.Day, 0, 0, 0, dto.Offset); + + CurrentTime = dto.TimeOfDay; + + OnPropertyChanged(nameof(CurrentDate)); + OnPropertyChanged(nameof(CurrentTime)); + } + public async Task LoadTimeZones() { _timeZoneContentManager = new TimeZoneContentManager(); @@ -459,7 +511,7 @@ namespace Ryujinx.Ava.UI.ViewModels private bool ValidateLdnPassphrase(string passphrase) { - return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && Patterns.LdnPassphrase.IsMatch(passphrase)); + return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && LdnPassphraseRegex().IsMatch(passphrase)); } public void ValidateAndSetTimeZone(string location) @@ -478,11 +530,10 @@ namespace Ryujinx.Ava.UI.ViewModels EnableDiscordIntegration = config.EnableDiscordIntegration; CheckUpdatesOnStart = config.CheckUpdatesOnStart; ShowConfirmExit = config.ShowConfirmExit; + IgnoreApplet = config.IgnoreApplet; RememberWindowState = config.RememberWindowState; ShowTitleBar = config.ShowTitleBar; HideCursor = (int)config.HideCursor.Value; - UpdateCheckerType = (int)config.UpdateCheckerType.Value; - FocusLostActionType = (int)config.FocusLostActionType.Value; GameDirectories.Clear(); GameDirectories.AddRange(config.UI.GameDirs.Value); @@ -502,7 +553,6 @@ namespace Ryujinx.Ava.UI.ViewModels EnableDockedMode = config.System.EnableDockedMode; EnableKeyboard = config.Hid.EnableKeyboard; EnableMouse = config.Hid.EnableMouse; - DisableInputWhenOutOfFocus = config.Hid.DisableInputWhenOutOfFocus; // Keyboard Hotkeys KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value); @@ -518,15 +568,12 @@ namespace Ryujinx.Ava.UI.ViewModels CurrentDate = currentDateTime.Date; CurrentTime = currentDateTime.TimeOfDay; - MatchSystemTime = config.System.MatchSystemTime; - - EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval; + EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value; CustomVSyncInterval = config.Graphics.CustomVSyncInterval; VSyncMode = config.Graphics.VSyncMode; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; DramSize = config.System.DramSize; IgnoreMissingServices = config.System.IgnoreMissingServices; - IgnoreApplet = config.System.IgnoreControllerApplet; // CPU EnablePptc = config.System.EnablePtc; @@ -569,14 +616,13 @@ namespace Ryujinx.Ava.UI.ViewModels EnableGuest = config.Logger.EnableGuest; EnableDebug = config.Logger.EnableDebug; EnableFsAccessLog = config.Logger.EnableFsAccessLog; - EnableAvaloniaLog = config.Logger.EnableAvaloniaLog; FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode; OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value; MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value; - DisableP2P = config.Multiplayer.DisableP2p; - LdnPassphrase = config.Multiplayer.LdnPassphrase; - LdnServer = config.Multiplayer.LdnServer; + DisableP2P = config.Multiplayer.DisableP2p.Value; + LdnPassphrase = config.Multiplayer.LdnPassphrase.Value; + LdnServer = config.Multiplayer.LdnServer.Value; } public void SaveSettings() @@ -587,13 +633,22 @@ namespace Ryujinx.Ava.UI.ViewModels config.EnableDiscordIntegration.Value = EnableDiscordIntegration; config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart; config.ShowConfirmExit.Value = ShowConfirmExit; + config.IgnoreApplet.Value = IgnoreApplet; config.RememberWindowState.Value = RememberWindowState; config.ShowTitleBar.Value = ShowTitleBar; config.HideCursor.Value = (HideCursorMode)HideCursor; - config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType; - config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType; - config.UI.GameDirs.Value = [..GameDirectories]; - config.UI.AutoloadDirs.Value = [..AutoloadDirectories]; + + if (_gameDirectoryChanged) + { + List gameDirs = new(GameDirectories); + config.UI.GameDirs.Value = gameDirs; + } + + if (_autoloadDirectoryChanged) + { + List autoloadDirs = new(AutoloadDirectories); + config.UI.AutoloadDirs.Value = autoloadDirs; + } config.UI.BaseStyle.Value = BaseStyleIndex switch { @@ -607,29 +662,26 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.EnableDockedMode.Value = EnableDockedMode; config.Hid.EnableKeyboard.Value = EnableKeyboard; config.Hid.EnableMouse.Value = EnableMouse; - config.Hid.DisableInputWhenOutOfFocus.Value = DisableInputWhenOutOfFocus; // Keyboard Hotkeys config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig(); // System config.System.Region.Value = (Region)Region; - - if (config.System.Language.Value != (Language)Language) - GameListNeedsRefresh = true; - config.System.Language.Value = (Language)Language; + if (_validTzRegions.Contains(TimeZone)) { config.System.TimeZone.Value = TimeZone; } - config.System.MatchSystemTime.Value = MatchSystemTime; config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds()); + config.Graphics.VSyncMode.Value = VSyncMode; + config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval; + config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval; config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.DramSize.Value = DramSize; config.System.IgnoreMissingServices.Value = IgnoreMissingServices; - config.System.IgnoreControllerApplet.Value = IgnoreApplet; // CPU config.System.EnablePtc.Value = EnablePptc; @@ -638,9 +690,6 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.UseHypervisor.Value = UseHypervisor; // Graphics - config.Graphics.VSyncMode.Value = VSyncMode; - config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval; - config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval; config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex; config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex); config.Graphics.EnableShaderCache.Value = EnableShaderCache; @@ -687,7 +736,6 @@ namespace Ryujinx.Ava.UI.ViewModels config.Logger.EnableGuest.Value = EnableGuest; config.Logger.EnableDebug.Value = EnableDebug; config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog; - config.Logger.EnableAvaloniaLog.Value = EnableAvaloniaLog; config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode; config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel; @@ -696,20 +744,16 @@ namespace Ryujinx.Ava.UI.ViewModels config.Multiplayer.DisableP2p.Value = DisableP2P; config.Multiplayer.LdnPassphrase.Value = LdnPassphrase; config.Multiplayer.LdnServer.Value = LdnServer; - - // Dirty Hacks - config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; - config.Hacks.EnableShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelayEnabled; - config.Hacks.ShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelay; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); MainWindow.UpdateGraphicsConfig(); - RyujinxApp.MainWindow.ViewModel.VSyncModeSettingChanged(); + MainWindow.MainWindowViewModel.VSyncModeSettingChanged(); SaveSettingsEvent?.Invoke(); - GameListNeedsRefresh = false; + _gameDirectoryChanged = false; + _autoloadDirectoryChanged = false; } private static void RevertIfNotSaved() @@ -728,25 +772,6 @@ namespace Ryujinx.Ava.UI.ViewModels CloseWindow?.Invoke(); } - [ObservableProperty] private bool _wantsToReset; - - public AsyncRelayCommand ResetButton => Commands.Create(async () => - { - if (!WantsToReset) return; - - CloseWindow?.Invoke(); - ConfigurationState.Instance.LoadDefault(); - ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); - RyujinxApp.MainWindow.LoadApplications(); - - await ContentDialogHelper.CreateInfoDialog( - $"Your {RyujinxApp.FullAppName} configuration has been reset.", - "", - string.Empty, - LocaleManager.Instance[LocaleKeys.SettingsButtonClose], - "Configuration Reset"); - }); - public void CancelButton() { RevertIfNotSaved(); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml index 62f087510..c7f03a45d 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml @@ -6,7 +6,6 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" - xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -70,7 +69,7 @@ diff --git a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml index 42515a4e9..219efcef8 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml @@ -8,7 +8,6 @@ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" - xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" Design.Width="1000" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -34,24 +33,16 @@ ToolTip.Tip="{ext:Locale SettingsTabGraphicsBackendTooltip}" Text="{ext:Locale SettingsTabGraphicsBackend}" Width="250" /> - - - - + - - - diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index 701c3ddaf..4d1fa899a 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -64,34 +64,34 @@ namespace Ryujinx.Ava.UI.Windows { switch (navItem.Tag.ToString()) { - case nameof(UiPage): + case "UiPage": UiPage.ViewModel = ViewModel; NavPanel.Content = UiPage; break; - case nameof(InputPage): + case "InputPage": NavPanel.Content = InputPage; break; - case nameof(HotkeysPage): + case "HotkeysPage": NavPanel.Content = HotkeysPage; break; - case nameof(SystemPage): + case "SystemPage": SystemPage.ViewModel = ViewModel; NavPanel.Content = SystemPage; break; - case nameof(CpuPage): + case "CpuPage": NavPanel.Content = CpuPage; break; - case nameof(GraphicsPage): + case "GraphicsPage": NavPanel.Content = GraphicsPage; break; - case nameof(AudioPage): + case "AudioPage": NavPanel.Content = AudioPage; break; - case nameof(NetworkPage): + case "NetworkPage": NetworkPage.ViewModel = ViewModel; NavPanel.Content = NetworkPage; break; - case nameof(LoggingPage): + case "LoggingPage": NavPanel.Content = LoggingPage; break; case nameof(HacksPage): diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index 02a91e51d..4fdf7c4f0 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -318,15 +318,14 @@ namespace Ryujinx.Ava.Utilities.Configuration private static GraphicsBackend DefaultGraphicsBackend() { - // Any system running macOS should default to auto, so it uses Vulkan everywhere and Metal in games where it works well. - if (OperatingSystem.IsMacOS()) - return GraphicsBackend.Auto; - - // Any system returning any amount of valid Vulkan devices should default to Vulkan. + // Any system running macOS or returning any amount of valid Vulkan devices should default to Vulkan. // Checks for if the Vulkan version and featureset is compatible should be performed within VulkanRenderer. - return VulkanRenderer.GetPhysicalDevices().Length > 0 - ? GraphicsBackend.Vulkan - : GraphicsBackend.OpenGl; + if (OperatingSystem.IsMacOS() || VulkanRenderer.GetPhysicalDevices().Length > 0) + { + return GraphicsBackend.Vulkan; + } + + return GraphicsBackend.OpenGl; + } + } } - } -} -- 2.47.1 From 8bc96313669b9ad6ec9cc3051e2174bf1158d683 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 21 Feb 2025 20:42:34 -0600 Subject: [PATCH 2/3] fix revert conflicts --- Directory.Packages.props | 32 +- Ryujinx.sln | 8 - src/Ryujinx/AppHost.cs | 170 +- src/Ryujinx/Assets/locales.json | 5447 +++++++++++++----- src/Ryujinx/Headless/HeadlessRyujinx.Init.cs | 6 - src/Ryujinx/Headless/HeadlessRyujinx.cs | 450 +- src/Ryujinx/Ryujinx.csproj | 8 +- src/Ryujinx/UI/Renderer/RendererHost.cs | 59 +- 8 files changed, 4206 insertions(+), 1974 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 34655164e..62a642374 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,13 +3,13 @@ true - - - - - - - + + + + + + + @@ -17,7 +17,8 @@ - + + @@ -25,7 +26,7 @@ - + @@ -41,15 +42,16 @@ - + + - - - - - + + + + + diff --git a/Ryujinx.sln b/Ryujinx.sln index c3cb5a2b0..9ed282d09 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -57,14 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}" @@ -206,10 +202,6 @@ Global {D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU {D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU {D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU - {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 5872b278f..ed1cd7486 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -3,6 +3,7 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Threading; +using DiscordRPC; using LibHac.Common; using LibHac.Ns; using LibHac.Tools.FsSystem; @@ -19,11 +20,15 @@ using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Renderer; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; +using Ryujinx.Ava.Utilities; +using Ryujinx.Ava.Utilities.AppLibrary; +using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; using Ryujinx.Common.SystemInterop; +using Ryujinx.Common.UI; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; @@ -37,11 +42,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.SystemState; using Ryujinx.Input; using Ryujinx.Input.HLE; -using Ryujinx.UI.App.Common; -using Ryujinx.UI.Common; -using Ryujinx.UI.Common.Configuration; -using Ryujinx.UI.Common.Helper; -using Silk.NET.Vulkan; using SkiaSharp; using SPB.Graphics.Vulkan; using System; @@ -238,10 +238,10 @@ namespace Ryujinx.Ava _lastCursorMoveTime = Stopwatch.GetTimestamp(); } - var point = e.GetCurrentPoint(window).Position; - var bounds = RendererHost.EmbeddedWindow.Bounds; - var windowYOffset = bounds.Y + window.MenuBarHeight; - var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; + Point point = e.GetCurrentPoint(window).Position; + Rect bounds = RendererHost.EmbeddedWindow.Bounds; + double windowYOffset = bounds.Y + window.MenuBarHeight; + double windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; if (!_viewModel.ShowMenuAndStatusBar) { @@ -265,10 +265,10 @@ namespace Ryujinx.Ava if (sender is MainWindow window) { - var point = e.GetCurrentPoint(window).Position; - var bounds = RendererHost.EmbeddedWindow.Bounds; - var windowYOffset = bounds.Y + window.MenuBarHeight; - var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; + Point point = e.GetCurrentPoint(window).Position; + Rect bounds = RendererHost.EmbeddedWindow.Bounds; + double windowYOffset = bounds.Y + window.MenuBarHeight; + double windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1; if (!_viewModel.ShowMenuAndStatusBar) { @@ -287,19 +287,19 @@ namespace Ryujinx.Ava private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); - _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); + _renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); + _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); } private void UpdateScalingFilter(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); - _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); + _renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); + _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); } private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs e) { - _renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value); + _renderer.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough); } public void UpdateVSyncMode(object sender, ReactiveEventArgs e) @@ -309,39 +309,21 @@ 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); + _viewModel.UpdateVSyncIntervalPicker(); } public void VSyncModeToggle() { VSyncMode oldVSyncMode = Device.VSyncMode; - VSyncMode newVSyncMode = VSyncMode.Switch; bool customVSyncIntervalEnabled = ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Value; - switch (oldVSyncMode) - { - case VSyncMode.Switch: - newVSyncMode = VSyncMode.Unbounded; - break; - case VSyncMode.Unbounded: - if (customVSyncIntervalEnabled) - { - newVSyncMode = VSyncMode.Custom; - } - else - { - newVSyncMode = VSyncMode.Switch; - } - - break; - case VSyncMode.Custom: - newVSyncMode = VSyncMode.Switch; - break; - } - - UpdateVSyncMode(this, new ReactiveEventArgs(oldVSyncMode, newVSyncMode)); + UpdateVSyncMode(this, new ReactiveEventArgs( + oldVSyncMode, + oldVSyncMode.Next(customVSyncIntervalEnabled)) + ); } private void UpdateCustomVSyncIntervalValue(object sender, ReactiveEventArgs e) @@ -434,7 +416,7 @@ namespace Ryujinx.Ava return; } - var colorType = e.IsBgra ? SKColorType.Bgra8888 : SKColorType.Rgba8888; + SKColorType colorType = e.IsBgra ? SKColorType.Bgra8888 : SKColorType.Rgba8888; using SKBitmap bitmap = new(new SKImageInfo(e.Width, e.Height, colorType, SKAlphaType.Premul)); Marshal.Copy(e.Data, 0, bitmap.GetPixels(), e.Data.Length); @@ -447,7 +429,7 @@ namespace Ryujinx.Ava float scaleX = e.FlipX ? -1 : 1; float scaleY = e.FlipY ? -1 : 1; - var matrix = SKMatrix.CreateScale(scaleX, scaleY, bitmap.Width / 2f, bitmap.Height / 2f); + SKMatrix matrix = SKMatrix.CreateScale(scaleX, scaleY, bitmap.Width / 2f, bitmap.Height / 2f); canvas.SetMatrix(matrix); canvas.DrawBitmap(bitmap, SKPoint.Empty); @@ -466,8 +448,8 @@ namespace Ryujinx.Ava private static void SaveBitmapAsPng(SKBitmap bitmap, string path) { - using var data = bitmap.Encode(SKEncodedImageFormat.Png, 100); - using var stream = File.OpenWrite(path); + using SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100); + using FileStream stream = File.OpenWrite(path); data.SaveTo(stream); } @@ -488,7 +470,7 @@ namespace Ryujinx.Ava Dispatcher.UIThread.InvokeAsync(() => { - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar); }); _viewModel.SetUiProgressHandlers(Device); @@ -500,6 +482,8 @@ namespace Ryujinx.Ava _renderingThread.Start(); _viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value; + + Rainbow.Enable(); MainLoop(); @@ -524,7 +508,7 @@ namespace Ryujinx.Ava private void UpdateAntiAliasing(object sender, ReactiveEventArgs e) { - _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)e.NewValue); + _renderer?.Window?.SetAntiAliasing(e.NewValue); } private void UpdateDockedModeState(object sender, ReactiveEventArgs e) @@ -532,7 +516,7 @@ namespace Ryujinx.Ava Device?.System.ChangeDockedModeState(e.NewValue); } - private void UpdateAudioVolumeState(object sender, ReactiveEventArgs e) + public void UpdateAudioVolumeState(object sender, ReactiveEventArgs e) { Device?.SetVolume(e.NewValue); @@ -575,7 +559,6 @@ namespace Ryujinx.Ava public void Stop() { _isActive = false; - DiscordIntegrationModule.SwitchToMainState(); } private void Exit() @@ -587,6 +570,17 @@ namespace Ryujinx.Ava return; } + foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) + { + gamepad?.ClearLed(); + gamepad?.Dispose(); + } + + DiscordIntegrationModule.GuestAppStartedAt = null; + + Rainbow.Disable(); + Rainbow.Reset(); + _isStopped = true; Stop(); } @@ -674,7 +668,9 @@ namespace Ryujinx.Ava public async Task LoadGuestApplication(BlitStruct? customNacpData = null) { - InitializeSwitchInstance(); + DiscordIntegrationModule.GuestAppStartedAt = Timestamps.Now; + + InitEmulatedSwitch(); MainWindow.UpdateGraphicsConfig(); SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); @@ -757,6 +753,8 @@ namespace Ryujinx.Ava { romFsFiles = Directory.GetFiles(ApplicationPath, "*.romfs"); } + + Logger.Notice.Print(LogClass.Application, $"Loading unpacked content archive from '{ApplicationPath}'."); if (romFsFiles.Length > 0) { @@ -783,6 +781,8 @@ namespace Ryujinx.Ava } else if (File.Exists(ApplicationPath)) { + Logger.Notice.Print(LogClass.Application, $"Loading content archive from '{ApplicationPath}'."); + switch (Path.GetExtension(ApplicationPath).ToLowerInvariant()) { case ".xci": @@ -859,13 +859,11 @@ namespace Ryujinx.Ava return false; } - - ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, + + ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => appMetadata.UpdatePreGame() ); - DiscordIntegrationModule.SwitchToPlayingState(appMeta, Device.Processes.ActiveApplication); - return true; } @@ -874,7 +872,7 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(false); _viewModel.IsPaused = false; - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar); Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } @@ -883,26 +881,30 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(true); _viewModel.IsPaused = true; - _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, LocaleManager.Instance[LocaleKeys.Paused]); + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar, LocaleManager.Instance[LocaleKeys.Paused]); Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } - private void InitializeSwitchInstance() + private void InitEmulatedSwitch() { // Initialize KeySet. VirtualFileSystem.ReloadKeySet(); // Initialize Renderer. - IRenderer renderer = ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl - ? new OpenGLRenderer() - : VulkanRenderer.Create( + GraphicsBackend backend = TitleIDs.SelectGraphicsBackend(ApplicationId.ToString("X16"), ConfigurationState.Instance.Graphics.GraphicsBackend); + + IRenderer renderer = backend switch + { + GraphicsBackend.Vulkan => VulkanRenderer.Create( ConfigurationState.Instance.Graphics.PreferredGpu, (RendererHost.EmbeddedWindow as EmbeddedWindowVulkan)!.CreateSurface, - VulkanHelper.GetRequiredInstanceExtensions); + VulkanHelper.GetRequiredInstanceExtensions), + _ => new OpenGLRenderer() + }; BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading; - var isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); + bool isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); if (isGALThreaded) { renderer = new ThreadedRenderer(renderer); @@ -911,9 +913,9 @@ namespace Ryujinx.Ava Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}"); // Initialize Configuration. - var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; + MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; - Device = new HLE.Switch(new HLEConfiguration( + Device = new Switch(new HLEConfiguration( VirtualFileSystem, _viewModel.LibHacHorizonManager, ContentManager, @@ -931,7 +933,9 @@ namespace Ryujinx.Ava ConfigurationState.Instance.System.EnableInternetAccess, ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, ConfigurationState.Instance.System.FsGlobalAccessLogMode, - ConfigurationState.Instance.System.SystemTimeOffset, + ConfigurationState.Instance.System.MatchSystemTime + ? 0 + : ConfigurationState.Instance.System.SystemTimeOffset, ConfigurationState.Instance.System.TimeZone, ConfigurationState.Instance.System.MemoryManagerMode, ConfigurationState.Instance.System.IgnoreMissingServices, @@ -942,19 +946,20 @@ namespace Ryujinx.Ava ConfigurationState.Instance.Multiplayer.Mode, ConfigurationState.Instance.Multiplayer.DisableP2p, ConfigurationState.Instance.Multiplayer.LdnPassphrase, - ConfigurationState.Instance.Multiplayer.LdnServer, - ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value)); + ConfigurationState.Instance.Multiplayer.GetLdnServer(), + ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value, + ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null)); } private static IHardwareDeviceDriver InitializeAudio() { - var availableBackends = new List - { + List availableBackends = + [ AudioBackend.SDL2, AudioBackend.SoundIo, AudioBackend.OpenAl, - AudioBackend.Dummy, - }; + AudioBackend.Dummy + ]; AudioBackend preferredBackend = ConfigurationState.Instance.System.AudioBackend.Value; @@ -1031,9 +1036,10 @@ namespace Ryujinx.Ava if (_viewModel.StartGamesInFullscreen) { _viewModel.WindowState = WindowState.FullScreen; + _viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true; } - if (_viewModel.WindowState is WindowState.FullScreen) + if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI) { _viewModel.ShowMenuAndStatusBar = false; } @@ -1047,10 +1053,10 @@ namespace Ryujinx.Ava Device.Gpu.Renderer.Initialize(_glLogLevel); - _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)ConfigurationState.Instance.Graphics.AntiAliasing.Value); - _renderer?.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value); - _renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); - _renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value); + _renderer?.Window?.SetAntiAliasing(ConfigurationState.Instance.Graphics.AntiAliasing); + _renderer?.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter); + _renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel); + _renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough); Width = (int)RendererHost.Bounds.Width; Height = (int)RendererHost.Bounds.Height; @@ -1064,7 +1070,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) { @@ -1111,7 +1117,7 @@ namespace Ryujinx.Ava public void InitStatus() { - _viewModel.BackendText = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch + _viewModel.BackendText = RendererHost.Backend switch { GraphicsBackend.Vulkan => "Vulkan", GraphicsBackend.OpenGl => "OpenGL", @@ -1139,8 +1145,8 @@ namespace Ryujinx.Ava LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%", dockedMode, ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), - $"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", - $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %", + Device.Statistics.FormatGameFrameRate(), + Device.Statistics.FormatFifoPercent(), _displayCount)); } diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 2e86df0aa..6e2577182 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -14,6 +14,7 @@ "pl_PL", "pt_BR", "ru_RU", + "sv_SE", "th_TH", "tr_TR", "uk_UA", @@ -38,6 +39,7 @@ "pl_PL": "Polski", "pt_BR": "Português (BR)", "ru_RU": "Русский (RU)", + "sv_SE": "Svenska", "th_TH": "ภาษาไทย", "tr_TR": "Türkçe", "uk_UA": "Українська", @@ -62,6 +64,7 @@ "pl_PL": "Otwórz Aplet", "pt_BR": "Abrir Applet", "ru_RU": "Открыть апплет", + "sv_SE": "Öppna applet", "th_TH": "เปิด Applet", "tr_TR": "Applet'i Aç", "uk_UA": "Відкрити аплет", @@ -73,24 +76,25 @@ "ID": "MenuBarFileOpenAppletOpenMiiApplet", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Mii-Bearbeitungsapplet", "el_GR": "", "en_US": "Mii Edit Applet", "es_ES": "Applet Editor Mii", "fr_FR": "Éditeur de Mii", "he_IL": "", - "it_IT": "", + "it_IT": "Applet Editor Mii", "ja_JP": "", "ko_KR": "Mii 편집 애플릿", "no_NO": "Mii-redigeringsapplet", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Editor de Mii", + "ru_RU": "Апплет Mii Editor", + "sv_SE": "Redigera Mii-applet", "th_TH": "", "tr_TR": "", - "uk_UA": "Аплет для редагування Mii", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Аплет редагування Mii", + "zh_CN": "Mii 小程序", + "zh_TW": "Mii 編輯器小程式" } }, { @@ -103,13 +107,14 @@ "es_ES": "Abre el editor de Mii en modo autónomo", "fr_FR": "Ouvrir l'éditeur Mii en mode Standalone", "he_IL": "פתח את יישומון עורך ה- Mii במצב עצמאי", - "it_IT": "Apri l'applet Mii Editor in modalità Standalone", + "it_IT": "Apri l'applet Editor Mii in modalità Standalone", "ja_JP": "スタンドアロンモードで Mii エディタアプレットを開きます", "ko_KR": "독립 실행형 모드로 Mii 편집기 애플릿 열기", "no_NO": "Åpne Mii Redigerings program i eget vindu", "pl_PL": "Otwórz aplet Mii Editor w trybie indywidualnym", - "pt_BR": "Abrir editor Mii em modo avulso", + "pt_BR": "Abrir Editor de Mii em Modo Independente", "ru_RU": "Открывает апплет Mii Editor в автономном режиме", + "sv_SE": "Öppna Mii Editor Applet i fristående läge", "th_TH": "เปิดโปรแกรม Mii Editor Applet", "tr_TR": "Mii Editör Applet'ini Bağımsız Mod'da Aç", "uk_UA": "Відкрити аплет Mii Editor в автономному режимі", @@ -132,11 +137,12 @@ "ko_KR": "마우스 직접 접근", "no_NO": "Direkte tilgang med Mus", "pl_PL": "Bezpośredni dostęp do myszy", - "pt_BR": "Acesso direto ao mouse", + "pt_BR": "Acesso Direto ao Mouse", "ru_RU": "Прямой ввод мыши", + "sv_SE": "Direkt musåtkomst", "th_TH": "เข้าถึงเมาส์ได้โดยตรง", "tr_TR": "Doğrudan Mouse Erişimi", - "uk_UA": "Прямий доступ мишею", + "uk_UA": "Пряме керування мишею", "zh_CN": "直通鼠标操作", "zh_TW": "滑鼠直接存取" } @@ -156,8 +162,9 @@ "ko_KR": "메모리 관리자 모드 :", "no_NO": "Memory Manager-modus", "pl_PL": "Tryb menedżera pamięci:", - "pt_BR": "Modo de gerenciamento de memória:", + "pt_BR": "Modo de Gerenciamento da Memória:", "ru_RU": "Режим менеджера памяти:", + "sv_SE": "Läge för minnehanterare:", "th_TH": "โหมดจัดการหน่วยความจำ:", "tr_TR": "Hafıza Yönetim Modu:", "uk_UA": "Режим диспетчера пам’яті:", @@ -169,7 +176,7 @@ "ID": "SettingsTabSystemMemoryManagerModeSoftware", "Translations": { "ar_SA": "البرنامج", - "de_DE": "", + "de_DE": "Programme", "el_GR": "Λογισμικό", "en_US": "Software", "es_ES": "", @@ -182,6 +189,7 @@ "pl_PL": "Oprogramowanie", "pt_BR": "", "ru_RU": "Программное обеспечение", + "sv_SE": "Programvara", "th_TH": "ซอฟต์แวร์", "tr_TR": "Yazılım", "uk_UA": "Програмне забезпечення", @@ -206,6 +214,7 @@ "pl_PL": "Gospodarz (szybki)", "pt_BR": "Hóspede (rápido)", "ru_RU": "Хост (быстро)", + "sv_SE": "Värd (snabb)", "th_TH": "โฮสต์ (เร็ว)", "tr_TR": "Host (hızlı)", "uk_UA": "Хост (швидко)", @@ -228,8 +237,9 @@ "ko_KR": "호스트 확인 안함(가장 빠르나 위험)", "no_NO": "Vert Ukontrollert (raskets, utrygt)", "pl_PL": "Gospodarza (NIESPRAWDZONY, najszybszy, niebezpieczne)", - "pt_BR": "Hóspede sem verificação (mais rápido, inseguro)", + "pt_BR": "Hóspede sem Verificação (mais rápido, inseguro)", "ru_RU": "Хост не установлен (самый быстрый, небезопасный)", + "sv_SE": "Värd inte kontrollerad (snabbaste, osäkert)", "th_TH": "ไม่ได้ตรวจสอบโฮสต์ (เร็วที่สุด, แต่ไม่ปลอดภัย)", "tr_TR": "Host Unchecked (en hızlısı, tehlikeli)", "uk_UA": "Неперевірений хост (найшвидший, небезпечний)", @@ -254,6 +264,7 @@ "pl_PL": "Użyj Hipernadzorcy", "pt_BR": "Usar Hipervisor", "ru_RU": "Использовать Hypervisor", + "sv_SE": "Använd Hypervisor", "th_TH": "ใช้งาน Hypervisor", "tr_TR": "Hypervisor Kullan", "uk_UA": "Використовувати гіпервізор", @@ -278,6 +289,7 @@ "pl_PL": "_Plik", "pt_BR": "_Arquivo", "ru_RU": "_Файл", + "sv_SE": "_Arkiv", "th_TH": "ไฟล์", "tr_TR": "_Dosya", "uk_UA": "_Файл", @@ -300,8 +312,9 @@ "ko_KR": "파일에서 앱 불러오기(_L)", "no_NO": "_Last inn program fra fil", "pl_PL": "_Załaduj aplikację z pliku", - "pt_BR": "_Abrir ROM do jogo...", + "pt_BR": "_Abrir ROM do Jogo", "ru_RU": "_Добавить приложение из файла", + "sv_SE": "_Läs in applikation från fil", "th_TH": "โหลดแอปพลิเคชั่นจากไฟล์", "tr_TR": "_Dosyadan Uygulama Aç", "uk_UA": "_Завантажити програму з файлу", @@ -313,19 +326,20 @@ "ID": "MenuBarFileOpenFromFileError", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Keine Anwendungen im ausgewählten Datei gefunden.", "el_GR": "", "en_US": "No applications found in selected file.", "es_ES": "No se encontraron aplicaciones en el archivo seleccionado.", "fr_FR": "Aucun jeu trouvé dans le fichier sélectionné", "he_IL": "", - "it_IT": "Nessuna applicazione trovata nel file selezionato", + "it_IT": "Nessuna applicazione trovata nel file selezionato.", "ja_JP": "", "ko_KR": "선택한 파일에서 앱을 찾을 수 없습니다.", "no_NO": "Ingen apper ble funnet i valgt fil.", "pl_PL": "", "pt_BR": "Nenhum aplicativo encontrado no arquivo selecionado.", - "ru_RU": "", + "ru_RU": "Приложения в выбранном файле не найдены", + "sv_SE": "Inga applikationer hittades i vald fil.", "th_TH": "ไม่พบแอปพลิเคชั่นจากไฟล์ที่เลือก", "tr_TR": "", "uk_UA": "У вибраному файлі не знайдено жодних додатків.", @@ -348,8 +362,9 @@ "ko_KR": "압축 푼 게임 불러오기(_U)", "no_NO": "Last inn _Upakket spill", "pl_PL": "Załaduj _rozpakowaną grę", - "pt_BR": "Abrir jogo _extraído...", + "pt_BR": "Abrir Jogo _Extraído", "ru_RU": "Добавить _распакованную игру", + "sv_SE": "Läs in _uppackat spel", "th_TH": "โหลดเกมที่แตกไฟล์แล้ว", "tr_TR": "_Sıkıştırılmamış Oyun Aç", "uk_UA": "Завантажити _розпаковану гру", @@ -361,23 +376,24 @@ "ID": "MenuBarFileLoadDlcFromFolder", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "DLC aus Ordner laden", "el_GR": "", "en_US": "Load DLC From Folder", "es_ES": "Cargar DLC Desde Carpeta", "fr_FR": "Charger les DLC depuis le dossier des DLC", "he_IL": "", - "it_IT": "Carica DLC Da una Cartella", + "it_IT": "Carica DLC da una cartella", "ja_JP": "", "ko_KR": "폴더에서 DLC 불러오기", "no_NO": "Last inn DLC fra mappe", "pl_PL": "", "pt_BR": "Carregar DLC da Pasta", - "ru_RU": "", + "ru_RU": "Загрузить DLC из папки", + "sv_SE": "Läs in DLC från mapp", "th_TH": "โหลด DLC จากโฟลเดอร์", "tr_TR": "", "uk_UA": "Завантажити DLC з теки", - "zh_CN": "从文件夹加载DLC", + "zh_CN": "从文件夹加载 DLC", "zh_TW": "從資料夾中載入 DLC" } }, @@ -385,22 +401,23 @@ "ID": "MenuBarFileLoadTitleUpdatesFromFolder", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Titel-Updates aus Ordner laden", "el_GR": "", "en_US": "Load Title Updates From Folder", "es_ES": "Cargar Actualizaciones de Títulos Desde Carpeta", "fr_FR": "Charger les mises à jour depuis le dossier des mises à jour", "he_IL": "", - "it_IT": "Carica Aggiornamenti Da una Cartella", + "it_IT": "Carica aggiornamenti da una cartella", "ja_JP": "", "ko_KR": "폴더에서 타이틀 업데이트 불러오기", "no_NO": "Last inn titteloppdateringer fra mappe", "pl_PL": "", "pt_BR": "Carregar Atualizações de Jogo da Pasta", - "ru_RU": "", + "ru_RU": "Загрузить обновления из папки", + "sv_SE": "Läs in titeluppdateringar från mapp", "th_TH": "โหลดไฟล์อัพเดตจากโฟลเดอร์", "tr_TR": "", - "uk_UA": "Завантажити оновлення заголовків з теки", + "uk_UA": "Завантажити оновлення ігор з теки", "zh_CN": "从文件夹加载游戏更新", "zh_TW": "從資料夾中載入遊戲更新" } @@ -420,8 +437,9 @@ "ko_KR": "Ryujinx 폴더 열기", "no_NO": "Åpne Ryujinx mappe", "pl_PL": "Otwórz folder Ryujinx", - "pt_BR": "Abrir diretório do e_mulador...", + "pt_BR": "Abrir Pasta do Ryujinx", "ru_RU": "Открыть папку Ryujinx", + "sv_SE": "Öppna Ryujinx-mapp", "th_TH": "เปิดโฟลเดอร์ Ryujinx", "tr_TR": "Ryujinx Klasörünü aç", "uk_UA": "Відкрити теку Ryujinx", @@ -429,6 +447,31 @@ "zh_TW": "開啟 Ryujinx 資料夾" } }, + { + "ID": "MenuBarFileOpenScreenshotsFolder", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Open Screenshots Folder", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "Abrir Pasta de Capturas de Tela", + "ru_RU": "Открыть папку со скриншотами", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Відкрити теку скріншотів", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "MenuBarFileOpenLogsFolder", "Translations": { @@ -444,8 +487,9 @@ "ko_KR": "로그 폴더 열기", "no_NO": "Åpne Logg mappen", "pl_PL": "Otwórz folder plików dziennika zdarzeń", - "pt_BR": "Abrir diretório de _logs...", + "pt_BR": "Abrir Pasta de _Logs", "ru_RU": "Открыть папку с логами", + "sv_SE": "Öppna loggmapp", "th_TH": "เปิดโฟลเดอร์ Logs", "tr_TR": "Logs Klasörünü aç", "uk_UA": "Відкрити теку журналів змін", @@ -470,6 +514,7 @@ "pl_PL": "_Wyjdź", "pt_BR": "_Sair", "ru_RU": "_Выход", + "sv_SE": "A_vsluta", "th_TH": "_ออก", "tr_TR": "_Çıkış", "uk_UA": "_Вихід", @@ -494,6 +539,7 @@ "pl_PL": "_Opcje", "pt_BR": "_Opções", "ru_RU": "_Настройки", + "sv_SE": "I_nställningar", "th_TH": "_ตัวเลือก", "tr_TR": "_Seçenekler", "uk_UA": "_Параметри", @@ -516,8 +562,9 @@ "ko_KR": "전체 화면 전환", "no_NO": "Fullskjermsvisning av/på", "pl_PL": "Przełącz na tryb pełnoekranowy", - "pt_BR": "_Mudar para tela cheia", + "pt_BR": "_Mudar para Tela Cheia", "ru_RU": "Включить полноэкранный режим", + "sv_SE": "Växla helskärm", "th_TH": "สลับเป็นโหมดเต็มหน้าจอ", "tr_TR": "Tam Ekran Modunu Aç", "uk_UA": "На весь екран", @@ -540,8 +587,9 @@ "ko_KR": "전체 화면 모드로 게임 시작", "no_NO": "Start spill i Fullskjermmodus", "pl_PL": "Uruchamiaj gry w trybie pełnoekranowym", - "pt_BR": "Iniciar jogos em tela cheia", + "pt_BR": "Iniciar Jogos em Tela Cheia", "ru_RU": "Запускать игры в полноэкранном режиме", + "sv_SE": "Starta spel i helskärmsläge", "th_TH": "เริ่มเกมในโหมดเต็มหน้าจอ", "tr_TR": "Oyunları Tam Ekran Modunda Başlat", "uk_UA": "Запускати ігри на весь екран", @@ -549,6 +597,31 @@ "zh_TW": "使用全螢幕模式啟動遊戲" } }, + { + "ID": "MenuBarOptionsStartGamesWithoutUI", + "Translations": { + "ar_SA": "", + "de_DE": "Spiele ohne Benutzeroberfläche starten", + "el_GR": "", + "en_US": "Start Games with UI Hidden", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "UI를 숨긴 상태에서 게임 시작", + "no_NO": "Start Spillet med UI Gjemt", + "pl_PL": "", + "pt_BR": "Iniciar Jogos Ocultando a Interface", + "ru_RU": "Запускать игры скрывая интерфейс", + "sv_SE": "Starta spel med dolt användargränssnitt", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускати ігри з прихованим інтерфейсом", + "zh_CN": "启动游戏时隐藏 UI", + "zh_TW": "" + } + }, { "ID": "MenuBarOptionsStopEmulation", "Translations": { @@ -564,8 +637,9 @@ "ko_KR": "에뮬레이션 중지", "no_NO": "Stopp Emulering", "pl_PL": "Zatrzymaj emulację", - "pt_BR": "_Encerrar emulação", + "pt_BR": "_Parar a Emulação", "ru_RU": "Остановить эмуляцию", + "sv_SE": "Stoppa emulering", "th_TH": "หยุดการจำลอง", "tr_TR": "Emülasyonu Durdur", "uk_UA": "Зупинити емуляцію", @@ -590,6 +664,7 @@ "pl_PL": "_Ustawienia", "pt_BR": "_Configurações", "ru_RU": "_Параметры", + "sv_SE": "_Inställningar", "th_TH": "_ตั้งค่า", "tr_TR": "_Seçenekler", "uk_UA": "_Налаштування", @@ -612,8 +687,9 @@ "ko_KR": "사용자 프로필 관리(_M)", "no_NO": "_Administrere Brukerprofiler", "pl_PL": "_Zarządzaj profilami użytkowników", - "pt_BR": "_Gerenciar perfis de usuário", - "ru_RU": "_Менеджер учетных записей", + "pt_BR": "_Gerenciar Perfis de Usuário", + "ru_RU": "_Менеджер учётных записей", + "sv_SE": "_Hantera användarprofiler", "th_TH": "_จัดการโปรไฟล์ผู้ใช้งาน", "tr_TR": "_Kullanıcı Profillerini Yönet", "uk_UA": "_Керувати профілями користувачів", @@ -638,6 +714,7 @@ "pl_PL": "_Akcje", "pt_BR": "_Ações", "ru_RU": "_Действия", + "sv_SE": "Åt_gärder", "th_TH": "การดำเนินการ", "tr_TR": "_Eylemler", "uk_UA": "_Дії", @@ -660,8 +737,9 @@ "ko_KR": "웨이크업 메시지 시뮬레이션", "no_NO": "Simuler oppvåknings-melding", "pl_PL": "Symuluj wiadomość wybudzania", - "pt_BR": "_Simular mensagem de acordar console", + "pt_BR": "_Simular Mensagem de Acordar o Console", "ru_RU": "Имитировать сообщение пробуждения", + "sv_SE": "Simulera uppvakningsmeddelande", "th_TH": "จำลองข้อความปลุก", "tr_TR": "Uyandırma Mesajı Simüle Et", "uk_UA": "Симулювати повідомлення про пробудження", @@ -686,6 +764,7 @@ "pl_PL": "Skanuj Amiibo", "pt_BR": "Escanear um Amiibo", "ru_RU": "Сканировать Amiibo", + "sv_SE": "Skanna en Amiibo", "th_TH": "สแกนหา Amiibo", "tr_TR": "Bir Amiibo Tara", "uk_UA": "Сканувати Amiibo", @@ -697,52 +776,29 @@ "ID": "MenuBarActionsScanAmiiboBin", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Amiibo scannen (aus Bin-Datei)", "el_GR": "", "en_US": "Scan An Amiibo (From Bin)", "es_ES": "", "fr_FR": "Scanner un Amiibo (à partir d'un .bin)", "he_IL": "", - "it_IT": "", + "it_IT": "Scansiona un Amiibo (da file .bin)", "ja_JP": "", "ko_KR": "Amiibo 스캔(빈에서)", "no_NO": "Skann en Amiibo (fra bin fil)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Escaneie um Amiibo (de um .bin)", + "ru_RU": "Сканировать Amiibo (из папки Bin)", + "sv_SE": "Skanna en Amiibo (från bin-fil)", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Сканувати Amiibo (з теки Bin)", + "zh_CN": "扫描 Amiibo (从 bin 文件)", + "zh_TW": "掃瞄 Amiibo (從 Bin 檔案)" } }, { - "ID": "MenuBarTools", - "Translations": { - "ar_SA": "_الأدوات", - "de_DE": "", - "el_GR": "_Εργαλεία", - "en_US": "_Tools", - "es_ES": "_Herramientas", - "fr_FR": "_Outils", - "he_IL": "_כלים", - "it_IT": "_Strumenti", - "ja_JP": "ツール(_T)", - "ko_KR": "도구(_T)", - "no_NO": "_Verktøy", - "pl_PL": "_Narzędzia", - "pt_BR": "_Ferramentas", - "ru_RU": "_Инструменты", - "th_TH": "_เครื่องมือ", - "tr_TR": "_Araçlar", - "uk_UA": "_Інструменти", - "zh_CN": "工具(_T)", - "zh_TW": "工具(_T)" - } - }, - { - "ID": "MenuBarToolsInstallFirmware", + "ID": "MenuBarActionsInstallFirmware", "Translations": { "ar_SA": "تثبيت البرنامج الثابت", "de_DE": "Firmware installieren", @@ -756,17 +812,18 @@ "ko_KR": "펌웨어 설치", "no_NO": "Installer fastvare", "pl_PL": "Zainstaluj oprogramowanie", - "pt_BR": "_Instalar firmware", + "pt_BR": "_Instalar Firmware", "ru_RU": "Установка прошивки", + "sv_SE": "Installera firmware", "th_TH": "ติดตั้งเฟิร์มแวร์", "tr_TR": "Yazılım Yükle", - "uk_UA": "Установити прошивку", + "uk_UA": "Встановити прошивку (Firmware)", "zh_CN": "安装系统固件", "zh_TW": "安裝韌體" } }, { - "ID": "MenuBarFileToolsInstallFirmwareFromFile", + "ID": "MenuBarActionsInstallFirmwareFromFile", "Translations": { "ar_SA": "تثبيت برنامج ثابت من XCI أو ZIP", "de_DE": "Firmware von einer XCI- oder einer ZIP-Datei installieren", @@ -782,15 +839,16 @@ "pl_PL": "Zainstaluj oprogramowanie z XCI lub ZIP", "pt_BR": "Instalar firmware a partir de um arquivo ZIP/XCI", "ru_RU": "Установить прошивку из XCI или ZIP", + "sv_SE": "Installera en firmware från XCI eller ZIP", "th_TH": "ติดตั้งเฟิร์มแวร์จาก ไฟล์ XCI หรือ ไฟล์ ZIP", "tr_TR": "XCI veya ZIP'ten Yazılım Yükle", - "uk_UA": "Установити прошивку з XCI або ZIP", - "zh_CN": "从 XCI 或 ZIP 文件中安装系统固件", + "uk_UA": "Встановити прошивку з XCI або ZIP", + "zh_CN": "从 XCI 或 ZIP 文件安装系统固件", "zh_TW": "從 XCI 或 ZIP 安裝韌體" } }, { - "ID": "MenuBarFileToolsInstallFirmwareFromDirectory", + "ID": "MenuBarActionsInstallFirmwareFromDirectory", "Translations": { "ar_SA": "تثبيت برنامج ثابت من مجلد", "de_DE": "Firmware aus einem Verzeichnis installieren", @@ -799,94 +857,98 @@ "es_ES": "Instalar firmware desde una carpeta", "fr_FR": "Installer un firmware depuis un dossier", "he_IL": "התקן קושחה מתוך תקייה", - "it_IT": "Installa un firmare da una cartella", + "it_IT": "Installa un firmware da una cartella", "ja_JP": "ディレクトリからファームウェアをインストール", "ko_KR": "디렉터리에서 펌웨어 설치", "no_NO": "Installer en fastvare fra en mappe", "pl_PL": "Zainstaluj oprogramowanie z katalogu", "pt_BR": "Instalar firmware a partir de um diretório", "ru_RU": "Установить прошивку из папки", + "sv_SE": "Installera en firmware från en katalog", "th_TH": "ติดตั้งเฟิร์มแวร์จากไดเร็กทอรี", "tr_TR": "Bir Dizin Üzerinden Yazılım Yükle", - "uk_UA": "Установити прошивку з теки", - "zh_CN": "从文件夹中安装系统固件", + "uk_UA": "Встановити прошивку з теки", + "zh_CN": "从文件夹安装系统固件", "zh_TW": "從資料夾安裝韌體" } }, { - "ID": "MenuBarToolsInstallKeys", + "ID": "MenuBarActionsInstallKeys", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Schlüssel installieren", "el_GR": "", "en_US": "Install Keys", "es_ES": "", "fr_FR": "Installer des clés", "he_IL": "", - "it_IT": "Installa Chiavi", + "it_IT": "Installa chiavi", "ja_JP": "", "ko_KR": "설치 키", "no_NO": "Installere nøkler", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Instalar Chaves", + "ru_RU": "Установить ключи", + "sv_SE": "Installera nycklar", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Встановити ключі", + "zh_CN": "安装密匙", + "zh_TW": "安裝金鑰" } }, { - "ID": "MenuBarFileToolsInstallKeysFromFile", + "ID": "MenuBarFileActionsInstallKeysFromFile", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Schlüssel aus KEYS oder ZIP installieren", "el_GR": "", "en_US": "Install keys from KEYS or ZIP", "es_ES": "Instalar keys de KEYS o ZIP", "fr_FR": "Installer des clés à partir de .KEYS or .ZIP", "he_IL": "", - "it_IT": "Installa Chiavi da file KEYS o ZIP", + "it_IT": "Installa chiavi da file KEYS o ZIP", "ja_JP": "", "ko_KR": "키나 ZIP에서 키 설치", "no_NO": "Installer nøkler fra KEYS eller ZIP", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Instalar chaves de CHAVES ou ZIP", + "ru_RU": "Установить ключи из файла KEYS или ZIP", + "sv_SE": "Installera nycklar från KEYS eller ZIP", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Встановити ключі з файлу .KEYS або .ZIP", + "zh_CN": "从 .KEYS 文件或 .ZIP 压缩包安装密匙", + "zh_TW": "從 .KEYS 或 .ZIP 安裝金鑰" } }, { - "ID": "MenuBarFileToolsInstallKeysFromFolder", + "ID": "MenuBarFileActionsInstallKeysFromFolder", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Schlüssel aus einem Verzeichnis installieren", "el_GR": "", "en_US": "Install keys from a directory", "es_ES": "Instalar keys de un directorio", "fr_FR": "Installer des clés à partir d'un dossier", "he_IL": "", - "it_IT": "Installa Chiavi da una Cartella", + "it_IT": "Installa chiavi da una cartella", "ja_JP": "", "ko_KR": "디렉터리에서 키 설치", "no_NO": "Installer nøkler fra en mappe", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Instalar chaves de um diretório", + "ru_RU": "Установить ключи из папки", + "sv_SE": "Installera nycklar från en katalog", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Встановити ключі з теки", + "zh_CN": "从一个文件夹安装密匙", + "zh_TW": "從資料夾安裝金鑰" } }, { - "ID": "MenuBarToolsManageFileTypes", + "ID": "MenuBarActionsManageFileTypes", "Translations": { "ar_SA": "إدارة أنواع الملفات", "de_DE": "Dateitypen verwalten", @@ -900,8 +962,9 @@ "ko_KR": "파일 형식 관리", "no_NO": "Behandle filtyper", "pl_PL": "Zarządzaj rodzajami plików", - "pt_BR": "Gerenciar tipos de arquivo", + "pt_BR": "Gerenciar Tipos de Arquivos", "ru_RU": "Управление типами файлов", + "sv_SE": "Hantera filtyper", "th_TH": "จัดการประเภทไฟล์", "tr_TR": "Dosya uzantılarını yönet", "uk_UA": "Керувати типами файлів", @@ -910,7 +973,7 @@ } }, { - "ID": "MenuBarToolsInstallFileTypes", + "ID": "MenuBarActionsInstallFileTypes", "Translations": { "ar_SA": "تثبيت أنواع الملفات", "de_DE": "Dateitypen installieren", @@ -924,17 +987,18 @@ "ko_KR": "파일 형식 설치", "no_NO": "Installer filtyper", "pl_PL": "Typy plików instalacyjnych", - "pt_BR": "Instalar tipos de arquivo", + "pt_BR": "Instalar tipos de arquivos", "ru_RU": "Установить типы файлов", + "sv_SE": "Installera filtyper", "th_TH": "ติดตั้งประเภทไฟล์", "tr_TR": "Dosya uzantılarını yükle", - "uk_UA": "Установити типи файлів", + "uk_UA": "Встановити типи файлів", "zh_CN": "关联文件扩展名", "zh_TW": "安裝檔案類型" } }, { - "ID": "MenuBarToolsUninstallFileTypes", + "ID": "MenuBarActionsUninstallFileTypes", "Translations": { "ar_SA": "إزالة أنواع الملفات", "de_DE": "Dateitypen deinstallieren", @@ -950,6 +1014,7 @@ "pl_PL": "Typy plików dezinstalacyjnych", "pt_BR": "Desinstalar tipos de arquivos", "ru_RU": "Удалить типы файлов", + "sv_SE": "Avinstallera filtyper", "th_TH": "ถอนการติดตั้งประเภทไฟล์", "tr_TR": "Dosya uzantılarını kaldır", "uk_UA": "Видалити типи файлів", @@ -958,27 +1023,28 @@ } }, { - "ID": "MenuBarToolsXCITrimmer", + "ID": "MenuBarActionsXCITrimmer", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "XCI-Dateien trimmen", "el_GR": "", "en_US": "Trim XCI Files", "es_ES": "Recortar archivos XCI", "fr_FR": "Réduire les fichiers XCI", "he_IL": "", - "it_IT": "", + "it_IT": "Riduci dimensioni dei file XCI", "ja_JP": "", "ko_KR": "XCI 파일 트리머", "no_NO": "Trim XCI-filer", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzir Arquivos XCI", + "ru_RU": "Уменьшить размер XCI файлов", + "sv_SE": "Optimera XCI-filer", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізати XCI файли", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "瘦身 XCI 文件", + "zh_TW": "修剪 XCI 檔案" } }, { @@ -996,8 +1062,9 @@ "ko_KR": "보기(_V)", "no_NO": "_Vis", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Ver", "ru_RU": "_Вид", + "sv_SE": "_Visa", "th_TH": "_มุมมอง", "tr_TR": "_Görüntüle", "uk_UA": "_Вид", @@ -1015,13 +1082,14 @@ "es_ES": "Tamaño Ventana", "fr_FR": "Taille de la fenêtre", "he_IL": "", - "it_IT": "Dimensione Finestra", + "it_IT": "Dimensione finestra", "ja_JP": "", "ko_KR": "윈도 창", "no_NO": "Vindu størrelse", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Tamanho da Janela", "ru_RU": "Размер окна", + "sv_SE": "Fönsterstorlek", "th_TH": "ขนาดหน้าต่าง", "tr_TR": "Pencere Boyutu", "uk_UA": "Розмір вікна", @@ -1042,10 +1110,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "720p", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1066,10 +1135,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "1080p", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1094,6 +1164,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1118,6 +1189,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -1142,9 +1214,10 @@ "pl_PL": "_Pomoc", "pt_BR": "_Ajuda", "ru_RU": "_Помощь", + "sv_SE": "_Hjälp", "th_TH": "_ช่วยเหลือ", "tr_TR": "_Yardım", - "uk_UA": "_Допомога", + "uk_UA": "_Довідка", "zh_CN": "帮助(_H)", "zh_TW": "說明(_H)" } @@ -1164,8 +1237,9 @@ "ko_KR": "업데이트 확인", "no_NO": "Se etter oppdateringer", "pl_PL": "Sprawdź aktualizacje", - "pt_BR": "_Verificar se há atualizações", + "pt_BR": "_Verificar Atualizações", "ru_RU": "Проверить наличие обновлений", + "sv_SE": "Leta efter uppdateringar", "th_TH": "ตรวจสอบอัปเดต", "tr_TR": "Güncellemeleri Denetle", "uk_UA": "Перевірити оновлення", @@ -1177,168 +1251,175 @@ "ID": "MenuBarHelpFaqAndGuides", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "FAQ & Anleitungen", "el_GR": "", "en_US": "FAQ & Guides", "es_ES": "", "fr_FR": "", "he_IL": "", - "it_IT": "", + "it_IT": "Guide e domande frequenti", "ja_JP": "", - "ko_KR": "", - "no_NO": "", + "ko_KR": "자주 묻는 질문(FAQ) 및 안내", + "no_NO": "Vanlige spørsmål og veiledninger", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "FAQ & Guias", + "ru_RU": "FAQ и Руководства", + "sv_SE": "Frågor, svar och guider", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "FAQ та посібники", + "zh_CN": "问答与指南", + "zh_TW": "常見問題 (FAQ) 和指南" } }, { "ID": "MenuBarHelpFaq", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "FAQ & Fehlerbehebung Seite", "el_GR": "", "en_US": "FAQ & Troubleshooting Page", "es_ES": "", "fr_FR": "Page de FAQ et de dépannage", "he_IL": "", - "it_IT": "", + "it_IT": "Domande frequenti e risoluzione dei problemi", "ja_JP": "", "ko_KR": "자주 묻는 질문(FAQ) 및 문제해결 페이지", "no_NO": "FAQ- og feilsøkingsside", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "FAQ e Solução de Problemas", + "ru_RU": "FAQ & Устранение неполадок", + "sv_SE": "Frågor, svar och felsökningssida", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "FAQ та усунення несправностей (eng)", + "zh_CN": "常见问题和问题排除页面", + "zh_TW": "常見問題 (FAQ) 和疑難排解頁面" } }, { "ID": "MenuBarHelpFaqTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Öffnet die FAQ- und Fehlerbehebungsseite im offiziellen Ryujinx-Wiki", "el_GR": "", "en_US": "Opens the FAQ and Troubleshooting page on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre la page de FAQ et de dépannage sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "", + "it_IT": "Apre la pagina della wiki ufficiale di Ryujinx relativa alle domande frequenti e alla risoluzione dei problemi", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 자주 묻는 질문(FAQ) 및 문제 해결 페이지 열기", "no_NO": "Åpner FAQ- og feilsøkingssiden på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Abre a página de FAQ e solução de problemas no wiki oficial do Ryujinx", + "ru_RU": "Открывает страницы с FAQ и Устранением неполадок на официальной странице вики Ryujinx", + "sv_SE": "Öppnar Frågor, svar och felsökningssidan på den officiella Ryujinx-wikin", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Відкриває сторінку з Посібником по усуненню помилок та несправностей на офіційній вікі-сторінці Ryujinx (англійською)", + "zh_CN": "打开 Ryujinx 官方 Wiki 的常见问题和问题排除页面", + "zh_TW": "開啟官方 Ryujinx Wiki 常見問題 (FAQ) 和疑難排解頁面" } }, { "ID": "MenuBarHelpSetup", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Setup- und Konfigurationsanleitung", "el_GR": "", "en_US": "Setup & Configuration Guide", "es_ES": "", "fr_FR": "Guide d'Installation et de Configuration", "he_IL": "", - "it_IT": "", + "it_IT": "Guida all'installazione e alla configurazione", "ja_JP": "", "ko_KR": "설치 및 구성 안내", "no_NO": "Oppsett- og konfigurasjonsveiledning", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Guia de Instalação e Configuração", + "ru_RU": "Руководство по установке и настройке", + "sv_SE": "Konfigurationsguide", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Посібник зі встановлення та налаштування (eng)", + "zh_CN": "安装与配置指南", + "zh_TW": "設定和配置指南" } }, { "ID": "MenuBarHelpSetupTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Öffnet die Setup- und Konfigurationsanleitung im offiziellen Ryujinx-Wiki", "el_GR": "", "en_US": "Opens the Setup & Configuration guide on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre le guide d'installation et de configuration sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "", + "it_IT": "Apre la guida all'installazione e alla configurazione presente nella wiki ufficiale di Ryujinx", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 설정 및 구성 안내 열기", "no_NO": "Åpner oppsett- og konfigurasjonsveiledningen på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Abre o guia de instalação e configuração no wiki oficial do Ryujinx", + "ru_RU": "Открывает страницу Руководство по установке и настройке на официальной странице вики Ryujinx", + "sv_SE": "Öppnar konfigurationsguiden på den officiella Ryujinx-wikin", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Відкриває посібник з Налаштування та конфігурації на офіційній вікі-сторінці Ryujinx (англійською)", + "zh_CN": "打开 Ryujinx 官方 Wiki 的安装与配置指南", + "zh_TW": "開啟官方 Ryujinx Wiki 設定和配置指南" } }, { "ID": "MenuBarHelpMultiplayer", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Multiplayer (LDN/LAN) Anleitung", "el_GR": "", "en_US": "Multiplayer (LDN/LAN) Guide", "es_ES": "", "fr_FR": "Guide Multijoueur (LDN/LAN)", "he_IL": "", - "it_IT": "", + "it_IT": "Guida alla modalità multigiocatore (LDN/LAN)", "ja_JP": "", "ko_KR": "멀티플레이어(LDN/LAN) 안내", "no_NO": "Flerspillerveiledning (LDN/LAN)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Guia Multijogador (LDN/LAN)", + "ru_RU": "Гайд по мультиплееру (LDN/LAN)", + "sv_SE": "Flerspelarguide (LDN/LAN)", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Посібник з мультиплеєру (LDN/LAN) (eng)", + "zh_CN": "多人游戏(LDN/LAN)指南", + "zh_TW": "多人遊戲 (LDN/LAN) 指南" } }, { "ID": "MenuBarHelpMultiplayerTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Öffnet die Multiplayer-Anleitung im offiziellen Ryujinx-Wiki", "el_GR": "", "en_US": "Opens the Multiplayer guide on the official Ryujinx wiki", "es_ES": "", "fr_FR": "Ouvre le guide de Multijoueur sur le wiki officiel de Ryujinx", "he_IL": "", - "it_IT": "", + "it_IT": "Apre la guida alla modalità multigiocatore presente nella wiki ufficiale di Ryujinx", "ja_JP": "", "ko_KR": "공식 Ryujinx 위키에서 멀티플레이어 안내 열기", "no_NO": "Åpner flerspillerveiledningen på den offisielle Ryujinx-wikien", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Abre o guia multijogador no wiki oficial do Ryujinx", + "ru_RU": "Открывает гайд по мультиплееру на официальной странице вики Ryujinx", + "sv_SE": "Öppnar flerspelarguiden på den officiella Ryujinx-wikin", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Відкриває посібник з налаштування Мультиплеєру на офіційній вікі-сторінці Ryujinx (англійською)", + "zh_CN": "打开 Ryujinx 官方 Wiki 的多人游戏指南", + "zh_TW": "開啟官方 Ryujinx Wiki 多人遊戲 (LDN/LAN) 指南" } }, { @@ -1358,6 +1439,7 @@ "pl_PL": "O programie", "pt_BR": "_Sobre", "ru_RU": "О программе", + "sv_SE": "Om", "th_TH": "เกี่ยวกับ", "tr_TR": "Hakkında", "uk_UA": "Про застосунок", @@ -1382,10 +1464,11 @@ "pl_PL": "Wyszukaj...", "pt_BR": "Buscar...", "ru_RU": "Поиск...", + "sv_SE": "Sök...", "th_TH": "กำลังค้นหา...", "tr_TR": "Ara...", "uk_UA": "Пошук...", - "zh_CN": "搜索…", + "zh_CN": "搜索...", "zh_TW": "搜尋..." } }, @@ -1402,10 +1485,11 @@ "it_IT": "Preferito", "ja_JP": "お気に入り", "ko_KR": "즐겨찾기", - "no_NO": "", + "no_NO": "Favoritter", "pl_PL": "Ulubione", "pt_BR": "Favorito", "ru_RU": "Избранное", + "sv_SE": "Favorit", "th_TH": "ชื่นชอบ", "tr_TR": "Favori", "uk_UA": "Обране", @@ -1430,6 +1514,7 @@ "pl_PL": "Ikona", "pt_BR": "Ícone", "ru_RU": "Значок", + "sv_SE": "Ikon", "th_TH": "ไอคอน", "tr_TR": "Simge", "uk_UA": "Значок", @@ -1454,6 +1539,7 @@ "pl_PL": "Nazwa", "pt_BR": "Nome", "ru_RU": "Название", + "sv_SE": "Namn", "th_TH": "ชื่อ", "tr_TR": "Oyun Adı", "uk_UA": "Назва", @@ -1463,6 +1549,156 @@ }, { "ID": "GameListHeaderDeveloper", + "Translations": { + "ar_SA": "", + "de_DE": "Entwickelt von {0}", + "el_GR": "", + "en_US": "Developed by {0}", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Utviklet av {0}", + "pl_PL": "", + "pt_BR": "Desenvolvido por {0}", + "ru_RU": "Разработана {0}", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Розроблено: {0}", + "zh_CN": "由 {0} 开发", + "zh_TW": "" + } + }, + { + "ID": "GameListHeaderVersion", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "Έκδοση: {0}", + "en_US": "Version: {0}", + "es_ES": "Versión: {0}", + "fr_FR": "", + "he_IL": "", + "it_IT": "Versione: {0}", + "ja_JP": "バージョン: {0}", + "ko_KR": "버전: {0}", + "no_NO": "Versjon: {0}", + "pl_PL": "Wersja: {0}", + "pt_BR": "Versão: {0}", + "ru_RU": "Версия: {0}", + "sv_SE": "", + "th_TH": "เวอร์ชั่น: {0}", + "tr_TR": "Sürüm: {0}", + "uk_UA": "Версія: {0}", + "zh_CN": "版本: {0}", + "zh_TW": "版本: {0}" + } + }, + { + "ID": "GameListHeaderTimePlayed", + "Translations": { + "ar_SA": "", + "de_DE": "Spielzeit:", + "el_GR": "Χρόνος:", + "en_US": "Play Time:", + "es_ES": "Tiempo jugado:", + "fr_FR": "Temps de jeu:", + "he_IL": "", + "it_IT": "Tempo di gioco:", + "ja_JP": "プレイ時間:", + "ko_KR": "플레이 타임:", + "no_NO": "Spilletid:", + "pl_PL": "Czas w grze:", + "pt_BR": "Tempo de Jogo:", + "ru_RU": "Время в игре:", + "sv_SE": "Speltid:", + "th_TH": "เล่นไปแล้ว:", + "tr_TR": "Oynama Süresi:", + "uk_UA": "Зіграно часу:", + "zh_CN": "游玩时长:", + "zh_TW": "遊玩時數:" + } + }, + { + "ID": "GameListHeaderLastPlayed", + "Translations": { + "ar_SA": "", + "de_DE": "Zuletzt gespielt: ", + "el_GR": "Παίχτηκε: ", + "en_US": "Last Played:", + "es_ES": "Jugado por última vez:", + "fr_FR": "Dernière partie jouée:", + "he_IL": "", + "it_IT": "Ultima partita:", + "ja_JP": "最終プレイ日時:", + "ko_KR": "마지막 플레이:", + "no_NO": "Sist Spilt:", + "pl_PL": "Ostatnio grane:", + "pt_BR": "Última vez Jogado:", + "ru_RU": "Последний запуск:", + "sv_SE": "Senast spelad:", + "th_TH": "เล่นล่าสุด:", + "tr_TR": "Son Oynama Tarihi:", + "uk_UA": "Востаннє зіграно:", + "zh_CN": "最近游玩:", + "zh_TW": "最近遊玩:" + } + }, + { + "ID": "GameListHeaderFileExtension", + "Translations": { + "ar_SA": "", + "de_DE": "Dateiformat: {0}", + "el_GR": "Κατάληξη: {0}", + "en_US": "Extension: {0}", + "es_ES": "Extensión: {0}", + "fr_FR": "Extension du Fichier: {0}", + "he_IL": "", + "it_IT": "Estensione: {0}", + "ja_JP": "ファイル拡張子: {0}", + "ko_KR": "파일 확장자: {0}", + "no_NO": "Fil Eks.: {0}", + "pl_PL": "Rozszerzenie pliku: {0}", + "pt_BR": "Extensão: {0}", + "ru_RU": "Расширение файла: {0}", + "sv_SE": "Filänd: {0}", + "th_TH": "นามสกุลไฟล์: {0}", + "tr_TR": "Dosya Uzantısı: {0}", + "uk_UA": "Розширення файлу: {0}", + "zh_CN": "扩展名: {0}", + "zh_TW": "副檔名: {0}" + } + }, + { + "ID": "GameListHeaderFileSize", + "Translations": { + "ar_SA": "", + "de_DE": "Dateigröße: {0}", + "el_GR": "Μέγεθος Αρχείου: {0}", + "en_US": "File Size: {0}", + "es_ES": "Tamaño del archivo: {0}", + "fr_FR": "Taille du Fichier: {0}", + "he_IL": "", + "it_IT": "Dimensione file: {0}", + "ja_JP": "ファイルサイズ: {0}", + "ko_KR": "파일 크기: {0}", + "no_NO": "Fil Størrelse: {0}", + "pl_PL": "Rozmiar pliku: {0}", + "pt_BR": "Tamanho: {0}", + "ru_RU": "Размер файла: {0}", + "sv_SE": "Filstorlek: {0}", + "th_TH": "ขนาดไฟล์: {0}", + "tr_TR": "Dosya Boyutu: {0}", + "uk_UA": "Розмір файлу: {0}", + "zh_CN": "大小: {0}", + "zh_TW": "檔案大小: {0}" + } + }, + { + "ID": "GameListSortDeveloper", "Translations": { "ar_SA": "المطور", "de_DE": "Entwickler", @@ -1478,6 +1714,7 @@ "pl_PL": "Twórca", "pt_BR": "Desenvolvedor", "ru_RU": "Разработчик", + "sv_SE": "Utvecklare", "th_TH": "ผู้พัฒนา", "tr_TR": "Geliştirici", "uk_UA": "Розробник", @@ -1486,31 +1723,7 @@ } }, { - "ID": "GameListHeaderVersion", - "Translations": { - "ar_SA": "الإصدار", - "de_DE": "", - "el_GR": "Έκδοση", - "en_US": "Version", - "es_ES": "Versión", - "fr_FR": "", - "he_IL": "גרסה", - "it_IT": "Versione", - "ja_JP": "バージョン", - "ko_KR": "버전", - "no_NO": "Versjon", - "pl_PL": "Wersja", - "pt_BR": "Versão", - "ru_RU": "Версия", - "th_TH": "เวอร์ชั่น", - "tr_TR": "Sürüm", - "uk_UA": "Версія", - "zh_CN": "版本", - "zh_TW": "版本" - } - }, - { - "ID": "GameListHeaderTimePlayed", + "ID": "GameListSortTimePlayed", "Translations": { "ar_SA": "وقت اللعب", "de_DE": "Spielzeit", @@ -1524,8 +1737,9 @@ "ko_KR": "플레이 타임", "no_NO": "Spilletid", "pl_PL": "Czas w grze:", - "pt_BR": "Tempo de jogo", + "pt_BR": "Tempo de Jogo", "ru_RU": "Время в игре", + "sv_SE": "Speltid", "th_TH": "เล่นไปแล้ว", "tr_TR": "Oynama Süresi", "uk_UA": "Зіграно часу", @@ -1534,7 +1748,7 @@ } }, { - "ID": "GameListHeaderLastPlayed", + "ID": "GameListSortLastPlayed", "Translations": { "ar_SA": "آخر مرة لُعبت", "de_DE": "Zuletzt gespielt", @@ -1548,8 +1762,9 @@ "ko_KR": "마지막 플레이", "no_NO": "Sist Spilt", "pl_PL": "Ostatnio grane", - "pt_BR": "Último jogo", + "pt_BR": "Última vez Jogado", "ru_RU": "Последний запуск", + "sv_SE": "Senast spelad", "th_TH": "เล่นล่าสุด", "tr_TR": "Son Oynama Tarihi", "uk_UA": "Востаннє зіграно", @@ -1558,7 +1773,7 @@ } }, { - "ID": "GameListHeaderFileExtension", + "ID": "GameListSortFileExtension", "Translations": { "ar_SA": "صيغة الملف", "de_DE": "Dateiformat", @@ -1574,6 +1789,7 @@ "pl_PL": "Rozszerzenie pliku", "pt_BR": "Extensão", "ru_RU": "Расширение файла", + "sv_SE": "Filänd", "th_TH": "นามสกุลไฟล์", "tr_TR": "Dosya Uzantısı", "uk_UA": "Розширення файлу", @@ -1582,7 +1798,7 @@ } }, { - "ID": "GameListHeaderFileSize", + "ID": "GameListSortFileSize", "Translations": { "ar_SA": "حجم الملف", "de_DE": "Dateigröße", @@ -1598,6 +1814,7 @@ "pl_PL": "Rozmiar pliku", "pt_BR": "Tamanho", "ru_RU": "Размер файла", + "sv_SE": "Filstorlek", "th_TH": "ขนาดไฟล์", "tr_TR": "Dosya Boyutu", "uk_UA": "Розмір файлу", @@ -1606,7 +1823,7 @@ } }, { - "ID": "GameListHeaderPath", + "ID": "GameListSortPath", "Translations": { "ar_SA": "المسار", "de_DE": "Pfad", @@ -1622,6 +1839,7 @@ "pl_PL": "Ścieżka", "pt_BR": "Caminho", "ru_RU": "Путь", + "sv_SE": "Sökväg", "th_TH": "ที่อยู่ไฟล์", "tr_TR": "Yol", "uk_UA": "Шлях", @@ -1629,6 +1847,106 @@ "zh_TW": "路徑" } }, + { + "ID": "GameListHeaderCompatibilityStatus", + "Translations": { + "ar_SA": "", + "de_DE": "Kompatibilität:", + "el_GR": "", + "en_US": "Compatibility:", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Kompatibilitet", + "pl_PL": "", + "pt_BR": "Compatibilidade:", + "ru_RU": "Совместимость:", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Сумісність:", + "zh_CN": "兼容性:", + "zh_TW": "" + } + }, + { + "ID": "GameListHeaderTitleId", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Title ID:", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Tittel ID:", + "pl_PL": "", + "pt_BR": "ID do Título:", + "ru_RU": "ID приложения", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "ID гри:", + "zh_CN": "标题 ID:", + "zh_TW": "" + } + }, + { + "ID": "GameListHeaderHostedGames", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Hosted Games: {0}", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Spill som Arrangeres: {0}", + "pl_PL": "", + "pt_BR": "Jogos Hospedados: {0}", + "ru_RU": "Запущенно игр: {0}", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Розміщені ігри: {0}", + "zh_CN": "服务的游戏: {0}", + "zh_TW": "" + } + }, + { + "ID": "GameListHeaderPlayerCount", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Online Players: {0}", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Online-spillere: {0}", + "pl_PL": "", + "pt_BR": "Jogadores Online: {0}", + "ru_RU": "Игроков онлайн: {0}", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Гравців онлайн: {0}", + "zh_CN": "在线玩家: {0}", + "zh_TW": "" + } + }, { "ID": "GameListContextMenuOpenUserSaveDirectory", "Translations": { @@ -1644,11 +1962,12 @@ "ko_KR": "사용자 저장 디렉터리 열기", "no_NO": "Åpne bruker lagrings mappe", "pl_PL": "Otwórz katalog zapisów użytkownika", - "pt_BR": "Abrir diretório de saves do usuário", + "pt_BR": "Abrir Diretório de Saves do Usuário", "ru_RU": "Открыть папку с сохранениями", + "sv_SE": "Öppna användarkatalog för sparningar", "th_TH": "เปิดไดเร็กทอรี่บันทึกของผู้ใช้", "tr_TR": "Kullanıcı Kayıt Dosyası Dizinini Aç", - "uk_UA": "Відкрити теку збереження користувача", + "uk_UA": "Відкрити теку збережень користувача", "zh_CN": "打开用户存档目录", "zh_TW": "開啟使用者存檔資料夾" } @@ -1670,9 +1989,10 @@ "pl_PL": "Otwiera katalog, który zawiera zapis użytkownika dla tej aplikacji", "pt_BR": "Abre o diretório que contém jogos salvos para o usuário atual", "ru_RU": "Открывает папку с пользовательскими сохранениями", + "sv_SE": "Öppnar katalogen som innehåller applikationens användarsparade spel", "th_TH": "เปิดไดเร็กทอรี่ซึ่งมีการบันทึกข้อมูลของผู้ใช้แอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває каталог, який містить збереження користувача програми", + "uk_UA": "Відкриває теку, яка містить збереження користувача", "zh_CN": "打开储存游戏用户存档的目录", "zh_TW": "開啟此應用程式的使用者存檔資料夾" } @@ -1692,11 +2012,12 @@ "ko_KR": "기기 저장 디렉터리 열기", "no_NO": "Åpne lagringsmappe for enheten", "pl_PL": "Otwórz katalog zapisów urządzenia", - "pt_BR": "Abrir diretório de saves de dispositivo do usuário", + "pt_BR": "Abrir Diretório de Saves de Dispositivo do Usuário", "ru_RU": "Открыть папку сохраненных устройств", + "sv_SE": "Öppna enhetens katalog för sparade spel", "th_TH": "เปิดไดเร็กทอรี่บันทึกของอุปกรณ์", "tr_TR": "Kullanıcı Cihaz Dizinini Aç", - "uk_UA": "Відкрити каталог пристроїв користувача", + "uk_UA": "Відкрити теку пристроїв користувача", "zh_CN": "打开系统数据目录", "zh_TW": "開啟裝置存檔資料夾" } @@ -1718,9 +2039,10 @@ "pl_PL": "Otwiera katalog, który zawiera zapis urządzenia dla tej aplikacji", "pt_BR": "Abre o diretório que contém saves do dispositivo para o usuário atual", "ru_RU": "Открывает папку, содержащую сохраненные устройства", + "sv_SE": "Öppnar katalogen som innehåller applikationens sparade spel på enheten", "th_TH": "เปิดไดเรกทอรี่ซึ่งมีบันทึกข้อมูลของอุปกรณ์ในแอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı Cihaz Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває каталог, який містить збереження пристрою програми", + "uk_UA": "Відкриває теку, яка містить збережені пристрої", "zh_CN": "打开储存游戏系统数据的目录", "zh_TW": "開啟此應用程式的裝置存檔資料夾" } @@ -1740,11 +2062,12 @@ "ko_KR": "BCAT 저장 디렉터리 열기", "no_NO": "Åpne BCAT lagringsmappe", "pl_PL": "Otwórz katalog zapisu BCAT obecnego użytkownika", - "pt_BR": "Abrir diretório de saves BCAT do usuário", + "pt_BR": "Abrir Diretório de Saves BCAT do Usuário", "ru_RU": "Открыть папку сохраненных BCAT", + "sv_SE": "Öppna katalog för BCAT-sparningar", "th_TH": "เปิดไดเรกทอรี่บันทึกของ BCAT", "tr_TR": "Kullanıcı BCAT Dizinini Aç", - "uk_UA": "Відкрити каталог користувача BCAT", + "uk_UA": "Відкрити теку збережень BCAT", "zh_CN": "打开 BCAT 数据目录", "zh_TW": "開啟 BCAT 存檔資料夾" } @@ -1766,9 +2089,10 @@ "pl_PL": "Otwiera katalog, który zawiera zapis BCAT dla tej aplikacji", "pt_BR": "Abre o diretório que contém saves BCAT para o usuário atual", "ru_RU": "Открывает папку, содержащую сохраненные BCAT", + "sv_SE": "Öppnar katalogen som innehåller applikationens BCAT-sparningar", "th_TH": "เปิดไดเรกทอรี่ซึ่งมีการบันทึกข้อมูลของ BCAT ในแอปพลิเคชัน", "tr_TR": "Uygulamanın Kullanıcı BCAT Kaydı'nın bulunduğu dizini açar", - "uk_UA": "Відкриває каталог, який містить BCAT-збереження програми", + "uk_UA": "Відкриває теку, яка містить BCAT-збереження програми", "zh_CN": "打开储存游戏 BCAT 数据的目录", "zh_TW": "開啟此應用程式的 BCAT 存檔資料夾" } @@ -1788,11 +2112,12 @@ "ko_KR": "타이틀 업데이트 관리", "no_NO": "Administrer titteloppdateringer", "pl_PL": "Zarządzaj aktualizacjami", - "pt_BR": "Gerenciar atualizações do jogo", + "pt_BR": "Gerenciar Atualizações do Jogo", "ru_RU": "Управление обновлениями", + "sv_SE": "Hantera speluppdateringar", "th_TH": "จัดการเวอร์ชั่นอัปเดต", "tr_TR": "Oyun Güncellemelerini Yönet", - "uk_UA": "Керування оновленнями заголовків", + "uk_UA": "Керування оновленнями", "zh_CN": "管理游戏更新", "zh_TW": "管理遊戲更新" } @@ -1814,9 +2139,10 @@ "pl_PL": "Otwiera okno zarządzania aktualizacjami danej aplikacji", "pt_BR": "Abre a janela de gerenciamento de atualizações", "ru_RU": "Открывает окно управления обновлениями приложения", + "sv_SE": "Öppnar spelets hanteringsfönster för uppdateringar", "th_TH": "เปิดหน้าต่างการจัดการเวอร์ชั่นการอัพเดต", "tr_TR": "Oyun Güncelleme Yönetim Penceresini Açar", - "uk_UA": "Відкриває вікно керування оновленням заголовка", + "uk_UA": "Відкриває меню керування оновленнями до гри (застосунку)", "zh_CN": "打开游戏更新管理窗口", "zh_TW": "開啟遊戲更新管理視窗" } @@ -1838,6 +2164,7 @@ "pl_PL": "Zarządzaj dodatkową zawartością (DLC)", "pt_BR": "Gerenciar DLCs", "ru_RU": "Управление DLC", + "sv_SE": "Hantera DLC", "th_TH": "จัดการ DLC", "tr_TR": "DLC'leri Yönet", "uk_UA": "Керування DLC", @@ -1862,9 +2189,10 @@ "pl_PL": "Otwiera okno zarządzania dodatkową zawartością", "pt_BR": "Abre a janela de gerenciamento de DLCs", "ru_RU": "Открывает окно управления DLC", + "sv_SE": "Öppnar DLC-hanteringsfönstret", "th_TH": "เปิดหน้าต่างจัดการ DLC", "tr_TR": "DLC yönetim penceresini açar", - "uk_UA": "Відкриває вікно керування DLC", + "uk_UA": "Відкриває меню керування DLC", "zh_CN": "打开 DLC 管理窗口", "zh_TW": "開啟 DLC 管理視窗" } @@ -1884,8 +2212,9 @@ "ko_KR": "캐시 관리", "no_NO": "Cache administrasjon", "pl_PL": "Zarządzanie Cache", - "pt_BR": "Gerenciamento de cache", + "pt_BR": "Gerenciamento de Cache", "ru_RU": "Управление кэшем", + "sv_SE": "Cachehantering", "th_TH": "จัดการแคช", "tr_TR": "Önbellek Yönetimi", "uk_UA": "Керування кешем", @@ -1908,11 +2237,12 @@ "ko_KR": "대기열 PPTC 재구성", "no_NO": "Start PPTC gjenoppbygging", "pl_PL": "Zakolejkuj rekompilację PPTC", - "pt_BR": "Limpar cache PPTC", + "pt_BR": "Reconstruir Cache PPTC", "ru_RU": "Перестроить очередь PPTC", + "sv_SE": "Kölägg PPTC Rebuild", "th_TH": "เพิ่มคิวการสร้าง PPTC ใหม่", "tr_TR": "PPTC Yeniden Yapılandırmasını Başlat", - "uk_UA": "Очистити кеш PPTC", + "uk_UA": "Додати до черги перекомпіляцію PPTC", "zh_CN": "清除 PPTC 缓存文件", "zh_TW": "佇列 PPTC 重建" } @@ -1932,15 +2262,66 @@ "ko_KR": "다음 게임 실행 부팅 시, PPTC를 트리거하여 다시 구성", "no_NO": "Utløs PPTC for å gjenoppbygge ved oppstart av neste spill-start", "pl_PL": "Zainicjuj Rekompilację PPTC przy następnym uruchomieniu gry", - "pt_BR": "Deleta o cache PPTC armazenado em disco do jogo", + "pt_BR": "Aciona o PPTC para reconstruir o cache no momento da próxima inicialização do jogo", "ru_RU": "Запускает перестройку PPTC во время следующего запуска игры.", + "sv_SE": "Gör så att PPTC bygger om vid uppstart när nästa spel startas", "th_TH": "ให้ PPTC สร้างใหม่ในเวลาบูตเมื่อเปิดเกมครั้งถัดไป", "tr_TR": "Oyunun bir sonraki açılışında PPTC'yi yeniden yapılandır", - "uk_UA": "Видаляє кеш PPTC програми", + "uk_UA": "Видаляє кеш PPTC застосунку (гри)", "zh_CN": "删除游戏的 PPTC 缓存文件,下次启动游戏时重新编译生成 PPTC 缓存文件", "zh_TW": "下一次啟動遊戲時,觸發 PPTC 進行重建" } }, + { + "ID": "GameListContextMenuCacheManagementNukePptc", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Purge PPTC cache", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "PPTC 캐시 제거", + "no_NO": "Tøm PPTC-bufferen", + "pl_PL": "", + "pt_BR": "Limpar Cache PPTC", + "ru_RU": "Очистить кэш PPTC", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Очистити кеш PPTC", + "zh_CN": "清理 PPTC 缓存", + "zh_TW": "" + } + }, + { + "ID": "GameListContextMenuCacheManagementNukePptcToolTip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Deletes all PPTC cache files for the Application", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "앱의 모든 PPTC 캐시 파일 삭제", + "no_NO": "Sletter alle PPTC-cache-filer for applikasjonen", + "pl_PL": "", + "pt_BR": "Apaga os arquivos de cache PPTC do aplicativo", + "ru_RU": "Удаляет все файлы кэша PPTC для приложения", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Видаляє всі файли кешу PPTC для застосунку", + "zh_CN": "删除应用程序的所有 PPTC 缓存", + "zh_TW": "" + } + }, { "ID": "GameListContextMenuCacheManagementPurgeShaderCache", "Translations": { @@ -1956,8 +2337,9 @@ "ko_KR": "퍼지 셰이더 캐시", "no_NO": "Tøm shader cache", "pl_PL": "Wyczyść pamięć podręczną cieni", - "pt_BR": "Limpar cache de Shader", + "pt_BR": "Limpar Cache de Shader", "ru_RU": "Очистить кэш шейдеров", + "sv_SE": "Töm shader cache", "th_TH": "ล้างแคช แสงเงา", "tr_TR": "Shader Önbelleğini Temizle", "uk_UA": "Очистити кеш шейдерів", @@ -1980,11 +2362,12 @@ "ko_KR": "앱의 셰이더 캐시 삭제", "no_NO": "Sletter applikasjonens shader cache", "pl_PL": "Usuwa pamięć podręczną cieni danej aplikacji", - "pt_BR": "Deleta o cache de Shader armazenado em disco do jogo", + "pt_BR": "Deleta o cache de Shader do jogo armazenado em disco", "ru_RU": "Удаляет кеш шейдеров приложения", + "sv_SE": "Tar bort applikationens shader cache", "th_TH": "ลบแคช แสงเงา ของแอปพลิเคชัน", "tr_TR": "Uygulamanın shader önbelleğini temizler", - "uk_UA": "Видаляє кеш шейдерів програми", + "uk_UA": "Видаляє кеш шейдерів застосунку (гри)", "zh_CN": "删除游戏的着色器缓存文件,下次启动游戏时重新生成着色器缓存文件", "zh_TW": "刪除應用程式的著色器快取" } @@ -2004,11 +2387,12 @@ "ko_KR": "PPTC 디렉터리 열기", "no_NO": "Åpne PPTC mappe", "pl_PL": "Otwórz katalog PPTC", - "pt_BR": "Abrir diretório do cache PPTC", + "pt_BR": "Abrir Diretório de PPTC Cache", "ru_RU": "Открыть папку PPTC", + "sv_SE": "Öppna PPTC-katalog", "th_TH": "เปิดไดเรกทอรี่ PPTC", "tr_TR": "PPTC Dizinini Aç", - "uk_UA": "Відкрити каталог PPTC", + "uk_UA": "Відкрити теку PPTC", "zh_CN": "打开 PPTC 缓存目录", "zh_TW": "開啟 PPTC 資料夾" } @@ -2030,9 +2414,10 @@ "pl_PL": "Otwiera katalog, który zawiera pamięć podręczną PPTC aplikacji", "pt_BR": "Abre o diretório contendo os arquivos do cache PPTC", "ru_RU": "Открывает папку, содержащую PPTC кэш приложений и игр", + "sv_SE": "Öppnar katalogen som innehåller applikationens PPTC-cache", "th_TH": "เปิดไดเร็กทอรี่ของ แคช PPTC ในแอปพลิเคชัน", "tr_TR": "Uygulamanın PPTC Önbelleğinin bulunduğu dizini açar", - "uk_UA": "Відкриває каталог, який містить кеш PPTC програми", + "uk_UA": "Відкриває теку, яка містить PPTC кеш застосунку (гри)", "zh_CN": "打开储存游戏 PPTC 缓存文件的目录", "zh_TW": "開啟此應用程式的 PPTC 快取資料夾" } @@ -2052,11 +2437,12 @@ "ko_KR": "셰이더 캐시 디렉터리 열기", "no_NO": "Åpne Shader Cache-mappen", "pl_PL": "Otwórz katalog pamięci podręcznej cieni", - "pt_BR": "Abrir diretório do cache de Shader", + "pt_BR": "Abrir Diretório de Shader Cache", "ru_RU": "Открыть папку с кэшем шейдеров", + "sv_SE": "Öppna katalog för shader cache", "th_TH": "เปิดไดเรกทอรี่ แคช แสงเงา", "tr_TR": "Shader Önbelleği Dizinini Aç", - "uk_UA": "Відкрити каталог кешу шейдерів", + "uk_UA": "Відкрити теку з кешем шейдерів", "zh_CN": "打开着色器缓存目录", "zh_TW": "開啟著色器快取資料夾" } @@ -2078,9 +2464,10 @@ "pl_PL": "Otwiera katalog, który zawiera pamięć podręczną cieni aplikacji", "pt_BR": "Abre o diretório contendo os arquivos do cache de Shader", "ru_RU": "Открывает папку, содержащую кэш шейдеров приложений и игр", + "sv_SE": "Öppnar katalogen som innehåller applikationens shader cache", "th_TH": "เปิดไดเรกทอรี่ของ แคช แสงเงา ในแอปพลิเคชัน", "tr_TR": "Uygulamanın shader önbelleğinin bulunduğu dizini açar", - "uk_UA": "Відкриває каталог, який містить кеш шейдерів програми", + "uk_UA": "Відкриває теку, яка містить кеш шейдерів застосунку (гри)", "zh_CN": "打开储存游戏着色器缓存文件的目录", "zh_TW": "開啟此應用程式的著色器快取資料夾" } @@ -2100,8 +2487,9 @@ "ko_KR": "데이터 추출", "no_NO": "Hent ut data", "pl_PL": "Wypakuj dane", - "pt_BR": "Extrair dados", + "pt_BR": "Extrair Dados", "ru_RU": "Извлечь данные", + "sv_SE": "Extrahera data", "th_TH": "แยกส่วนข้อมูล", "tr_TR": "Veriyi Ayıkla", "uk_UA": "Видобути дані", @@ -2122,10 +2510,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "ExeFS", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -2143,13 +2532,14 @@ "es_ES": "Extraer la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section ExeFS du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", + "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します", "ko_KR": "앱의 현재 구성에서 ExeFS 추출(업데이트 포함)", "no_NO": "Pakk ut ExeFS seksjonen fra Programmets gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção ExeFS do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела ExeFS из текущих настроек приложения (включая обновления)", + "sv_SE": "Extrahera ExeFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน ExeFS ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัปเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)", "uk_UA": "Видобуває розділ ExeFS із поточної конфігурації програми (включаючи оновлення)", @@ -2170,10 +2560,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "RomFS", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -2191,20 +2582,71 @@ "es_ES": "Extraer la sección RomFS de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section RomFS du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-RomFS מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", + "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)から RomFS セクションを展開します", "ko_KR": "앱의 현재 구성에서 RomFS 추출(업데이트 포함)", "no_NO": "Pakk ut RomFS seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję RomFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção RomFS do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела RomFS из текущих настроек приложения (включая обновления)", + "sv_SE": "Extrahera RomFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน RomFS ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัพเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil)", - "uk_UA": "Видобуває розділ RomFS із поточної конфігурації програми (включаючи оновлення)", + "uk_UA": "Видобуває розділ RomFS із поточної конфігурації застосунку (включно з оновленнями)", "zh_CN": "从游戏的当前状态中提取 RomFS 分区 (包括更新)", "zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)" } }, + { + "ID": "GameListContextMenuExtractDataAocRomFS", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "DLC RomFS", + "es_ES": "", + "fr_FR": "RomFS de DLC", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "GameListContextMenuExtractDataAocRomFSToolTip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Extract the RomFS from a selected DLC file", + "es_ES": "", + "fr_FR": "Extraire les RomFS d'un fichier DLC choisi", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "선택한 DLC 파일에서 RomFS 추출", + "no_NO": "Pakk ut RomFS filene fra valgt DLC fil", + "pl_PL": "", + "pt_BR": "Extraia o RomFS de um arquivo DLC selecionado", + "ru_RU": "Извлекает файлы RomFS из выбранного файла DLC", + "sv_SE": "Extrahera RomFS från en vald DLC-fil", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Витягти RomFS з обраного файлу DLC", + "zh_CN": "从选定的 DLC 文件中解压 RomFS", + "zh_TW": "" + } + }, { "ID": "GameListContextMenuExtractDataLogo", "Translations": { @@ -2218,15 +2660,16 @@ "it_IT": "", "ja_JP": "ロゴ", "ko_KR": "로고", - "no_NO": "Logo", + "no_NO": "", "pl_PL": "", - "pt_BR": "", - "ru_RU": "Логотип", + "pt_BR": "Logotipo", + "ru_RU": "Лого", + "sv_SE": "Logotyp", "th_TH": "โลโก้", "tr_TR": "Simge", "uk_UA": "Логотип", "zh_CN": "图标", - "zh_TW": "" + "zh_TW": "圖示" } }, { @@ -2239,13 +2682,14 @@ "es_ES": "Extraer la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones)", "fr_FR": "Extrait la section Logo du jeu (mise à jour incluse)", "he_IL": "חלץ את קטע ה-Logo מתצורת היישום הנוכחית (כולל עדכונים)", - "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", + "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)", "ja_JP": "現在のアプリケーション設定(アップデート含む)からロゴセクションを展開します", "ko_KR": "앱의 현재 구성에서 로고 섹션 추출 (업데이트 포함)", "no_NO": "Pakk ut Logo-seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)", "pl_PL": "Wyodrębnij sekcję z logiem z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "pt_BR": "Extrai a seção Logo do jogo (incluindo atualizações)", "ru_RU": "Извлечение раздела с логотипом из текущих настроек приложения (включая обновления)", + "sv_SE": "Extrahera Logo-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)", "th_TH": "แยกส่วน โลโก้ ออกจากการตั้งค่าปัจจุบันของแอปพลิเคชัน (รวมถึงอัปเดต)", "tr_TR": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil)", "uk_UA": "Видобуває розділ логотипу з поточної конфігурації програми (включаючи оновлення)", @@ -2268,8 +2712,9 @@ "ko_KR": "바로 가기 만들기", "no_NO": "Lag programsnarvei", "pl_PL": "Utwórz skrót aplikacji", - "pt_BR": "Criar atalho da aplicação", + "pt_BR": "Criar Atalho da Aplicação", "ru_RU": "Создать ярлык приложения", + "sv_SE": "Skapa genväg till applikation", "th_TH": "สร้างทางลัดของแอปพลิเคชัน", "tr_TR": "Uygulama Kısayolu Oluştur", "uk_UA": "Створити ярлик застосунку", @@ -2292,11 +2737,12 @@ "ko_KR": "선택한 앱을 실행하는 바탕 화면에 바로 가기를 생성", "no_NO": "Lag en snarvei på skrivebordet som starter den valgte Applikasjonen", "pl_PL": "Utwórz skrót na pulpicie, który uruchamia wybraną aplikację", - "pt_BR": "Criar um atalho de área de trabalho que inicia o aplicativo selecionado", + "pt_BR": "Criar um atalho na área de trabalho que inicia o aplicativo selecionado", "ru_RU": "Создает ярлык на рабочем столе, с помощью которого можно запустить игру или приложение", + "sv_SE": "Skapa en skrivbordsgenväg som startar vald applikation", "th_TH": "สร้างทางลัดบนเดสก์ท็อปสำหรับใช้แอปพลิเคชันที่เลือก", "tr_TR": "Seçilmiş uygulamayı çalıştıracak bir masaüstü kısayolu oluştur", - "uk_UA": "Створити ярлик на робочому столі, який запускає вибраний застосунок", + "uk_UA": "Створити ярлик на робочому столі, який запускатиме вибраний застосунок (гру)", "zh_CN": "创建一个直接启动此游戏的桌面快捷方式", "zh_TW": "建立桌面捷徑,啟動選取的應用程式" } @@ -2318,13 +2764,114 @@ "pl_PL": "Utwórz skrót w folderze 'Aplikacje' w systemie macOS, który uruchamia wybraną aplikację", "pt_BR": "Crie um atalho na pasta Aplicativos do macOS que abre o Aplicativo selecionado", "ru_RU": "Создает ярлык игры или приложения в папке Программы macOS", + "sv_SE": "Skapa en genväg i macOS-programmapp som startar vald applikation", "th_TH": "สร้างทางลัดในโฟลเดอร์ Applications ของ macOS สำหรับใช้แอปพลิเคชันที่เลือก", "tr_TR": "", - "uk_UA": "Створити ярлик у каталозі macOS програм, що запускає обраний Додаток", + "uk_UA": "Створити ярлик у каталозі програм macOS, що запускатиме обраний застосунок (гру)", "zh_CN": "在 macOS 的应用程序目录中创建一个直接启动此游戏的快捷方式", "zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式" } }, + { + "ID": "GameListContextMenuShowCompatEntry", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Show Compatibility Entry", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "호환성 항목 표시", + "no_NO": "Vis kompatibilitetsoppføring", + "pl_PL": "", + "pt_BR": "Mostrar Dados de Compatibilidade", + "ru_RU": "Показать записи о совместимости", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Iнформація про сумісність", + "zh_CN": "显示兼容性项目", + "zh_TW": "" + } + }, + { + "ID": "GameListContextMenuShowCompatEntryToolTip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Show the selected game in the Compatibility List you can normally access via the Help menu.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.", + "no_NO": "Vis det valgte spillet i kompatibilitetslisten, som du vanligvis får tilgang til via Hjelp-menyen.", + "pl_PL": "", + "pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.", + "ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.", + "zh_CN": "在兼容性列表中显示选定的游戏,您通常可以通过帮助菜单访问。", + "zh_TW": "" + } + }, + { + "ID": "GameListContextMenuShowGameData", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Show Game Info", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "게임 통계 표시", + "no_NO": "Vis Spill Info", + "pl_PL": "", + "pt_BR": "Mostrar Informações do Jogo", + "ru_RU": "Показать информацию об игре", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Інформація про гру", + "zh_CN": "显示游戏信息", + "zh_TW": "" + } + }, + { + "ID": "GameListContextMenuShowGameDataToolTip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Show stats & details about the currently selected game.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "그리드 보기 레이아웃에서 누락된 현재 선택된 게임에 대한 다양한 정보를 표시합니다.", + "no_NO": "Vis statistikk og detaljer om det valgte spillet.", + "pl_PL": "", + "pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.", + "ru_RU": "Показывать статистику и подробную информацию о выбранной игре.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Показати статистику та деталі обраної гри.", + "zh_CN": "显示当前选定游戏的状态与详细信息。", + "zh_TW": "" + } + }, { "ID": "GameListContextMenuOpenModsDirectory", "Translations": { @@ -2340,8 +2887,9 @@ "ko_KR": "모드 디렉터리 열기", "no_NO": "Åpne Modifikasjonsmappen", "pl_PL": "Otwórz katalog modów", - "pt_BR": "Abrir pasta de Mods", + "pt_BR": "Abrir Pasta de Mods", "ru_RU": "Открыть папку с модами", + "sv_SE": "Öppna Mods-katalog", "th_TH": "เปิดไดเร็กทอรี่ Mods", "tr_TR": "Mod Dizinini Aç", "uk_UA": "Відкрити теку з модами", @@ -2366,9 +2914,10 @@ "pl_PL": "Otwiera katalog zawierający mody dla danej aplikacji", "pt_BR": "Abre a pasta que contém os mods da aplicação ", "ru_RU": "Открывает папку, содержащую моды для приложений и игр", + "sv_SE": "Öppnar katalogen som innehåller applikationens Mods", "th_TH": "เปิดไดเร็กทอรี่ Mods ของแอปพลิเคชัน", "tr_TR": "", - "uk_UA": "Відкриває каталог, який містить модифікації Додатків", + "uk_UA": "Відкриває теку, яка містить модифікації застосунків (ігор)", "zh_CN": "打开存放游戏 MOD 的目录", "zh_TW": "開啟此應用程式模組的資料夾" } @@ -2388,11 +2937,12 @@ "ko_KR": "Atmosphere 모드 디렉터리 열기", "no_NO": "Åpne Atmosfære modifikasjons mappen", "pl_PL": "Otwórz katalog modów Atmosphere", - "pt_BR": "Abrir diretório de mods Atmosphere", + "pt_BR": "Abrir Diretório de Mods Atmosphere", "ru_RU": "Открыть папку с модами Atmosphere", + "sv_SE": "Öppna Atmosphere Mods-katalogen", "th_TH": "เปิดไดเร็กทอรี่ Mods Atmosphere", "tr_TR": "", - "uk_UA": "Відкрити каталог модифікацій Atmosphere", + "uk_UA": "Відкрити теку модифікацій Atmosphere", "zh_CN": "打开大气层系统 MOD 目录", "zh_TW": "開啟 Atmosphere 模組資料夾" } @@ -2412,11 +2962,12 @@ "ko_KR": "해당 게임의 모드가 포함된 대체 SD 카드 Atmosphere 디렉터리를 엽니다. 실제 하드웨어용으로 패키징된 모드에 유용합니다.", "no_NO": "Åpner den alternative SD-kortets Atmosfære-mappe som inneholder programmoduser. Nyttig for modifikasjoner som er pakket for ekte maskinvare.", "pl_PL": "Otwiera alternatywny katalog Atmosphere na karcie SD, który zawiera mody danej aplikacji. Przydatne dla modów przygotowanych pod prawdziwy sprzęt.", - "pt_BR": "", + "pt_BR": "Abre o diretório Atmosphere do cartão SD alternativo que contém os Mods do aplicativo. Útil para mods que são empacotados para hardware real.", "ru_RU": "Открывает папку Atmosphere на альтернативной SD-карте, которая содержит моды для приложений и игр. Полезно для модов, сделанных для реальной консоли.", + "sv_SE": "Öppnar den alternativa Atmosphere-katalogen på SD-kort som innehåller applikationens Mods. Användbart för Mods som är paketerade för riktig hårdvara.", "th_TH": "เปิดไดเร็กทอรี่ Atmosphere ของการ์ด SD สำรองซึ่งมี Mods ของแอปพลิเคชัน ซึ่งมีประโยชน์สำหรับ Mods ที่บรรจุมากับฮาร์ดแวร์จริง", "tr_TR": "", - "uk_UA": "Відкриває альтернативний каталог SD-карти Atmosphere, що містить модифікації Додатків. Корисно для модифікацій, зроблених для реального обладнання.", + "uk_UA": "Відкриває альтернативну теку SD-карти Atmosphere, що містить модифікації до застосунків або ігор. Корисно для модифікацій, зроблених для реального обладнання.", "zh_CN": "打开存放适用于大气层系统的游戏 MOD 的目录,对于为真实硬件打包的 MOD 非常有用", "zh_TW": "開啟此應用程式模組的另一個 SD 卡 Atmosphere 資料夾。適用於為真實硬體封裝的模組。" } @@ -2431,18 +2982,19 @@ "es_ES": "Verificar y recortar archivo XCI", "fr_FR": "Vérifier et réduire les fichiers XCI", "he_IL": "", - "it_IT": "Controlla e Trimma i file XCI", + "it_IT": "Controlla e riduci la dimensione del file XCI", "ja_JP": "", "ko_KR": "XCI 파일 확인 및 트림", "no_NO": "Kontroller og trim XCI-filen", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Verificar e Reduzir o Arquivo XCI", + "ru_RU": "Проверить и обрезать XCI файл", + "sv_SE": "Kontrollera och optimera XCI-fil", "th_TH": "", "tr_TR": "", - "uk_UA": "Перевірка та Нарізка XCI Файлів", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Перевірка та нарізка XCI Файлу", + "zh_CN": "检查并瘦身 XCI 文件", + "zh_TW": "檢查及修剪 XCI 檔案" } }, { @@ -2455,18 +3007,19 @@ "es_ES": "Verificar y recortar archivo XCI para ahorrar espacio en disco", "fr_FR": "Vérifier et réduire les fichiers XCI pour économiser de l'espace", "he_IL": "", - "it_IT": "Controlla e Trimma i file XCI da Salvare Sullo Spazio del Disco", + "it_IT": "Controlla e riduci la dimensione del file XCI per risparmiare spazio su disco", "ja_JP": "", "ko_KR": "디스크 공간을 절약하기 위해 XCI 파일 확인 및 트림", "no_NO": "Kontroller og trimm XCI-filen for å spare diskplass", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Verifique e reduza o arquivo XCI para economizar espaço em disco", + "ru_RU": "Проверить и обрезать XCI файл для уменьшения его размера", + "sv_SE": "Kontrollera och optimera XCI-fil för att spara diskutrymme", "th_TH": "", "tr_TR": "", - "uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Перевірити та обрізати XCI Файл задля збереження місця на диску", + "zh_CN": "检查并瘦身 XCI 文件以节约磁盘空间", + "zh_TW": "檢查及修剪 XCI 檔案以節省儲存空間" } }, { @@ -2479,13 +3032,14 @@ "es_ES": "{0}/{1} juegos cargados", "fr_FR": "{0}/{1} Jeux chargés", "he_IL": "{1}/{0} משחקים נטענו", - "it_IT": "{0}/{1} Giochi Caricati", + "it_IT": "{0}/{1} giochi caricati", "ja_JP": "{0}/{1} ゲーム", "ko_KR": "{0}/{1}개의 게임 불러옴", "no_NO": "{0}/{1} Spill Lastet", "pl_PL": "{0}/{1} Załadowane gry", - "pt_BR": "{0}/{1} jogos carregados", + "pt_BR": "{0}/{1} Jogos Carregados", "ru_RU": "{0}/{1} игр загружено", + "sv_SE": "{0}/{1} spel inlästa", "th_TH": "เกมส์โหลดแล้ว {0}/{1}", "tr_TR": "{0}/{1} Oyun Yüklendi", "uk_UA": "{0}/{1} ігор завантажено", @@ -2503,18 +3057,19 @@ "es_ES": "", "fr_FR": "Version du Firmware: {0}", "he_IL": "", - "it_IT": "", + "it_IT": "Versione firmware: {0}", "ja_JP": "", - "ko_KR": "", - "no_NO": "", + "ko_KR": "펌웨어 버전 : {0}", + "no_NO": "Fastvareversjon: {0}", "pl_PL": "", - "pt_BR": "Versão do firmware: {0}", + "pt_BR": "Versão do Firmware: {0}", "ru_RU": "Версия прошивки: {0}", + "sv_SE": "Firmware-version: {0}", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "Версія прошивки: {0}", "zh_CN": "系统固件版本:{0}", - "zh_TW": "" + "zh_TW": "系統韌體版本: {0}" } }, { @@ -2527,18 +3082,19 @@ "es_ES": "Recortando el siguiente archivo XCI: '{0}'", "fr_FR": "Réduction du fichier XCI '{0}'", "he_IL": "", - "it_IT": "Trimmando i file XCI '{0}'", + "it_IT": "Riduzione della dimensione del file XCI '{0}'", "ja_JP": "", "ko_KR": "XCI 파일 '{0}' 트리밍", "no_NO": "Trimming av XCI-filen '{0}'", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzindo o Arquivo XCI '{0}'", + "ru_RU": "Обрезается XCI файл '{0}'", + "sv_SE": "Optimerar XCI-filen '{0}'", "th_TH": "", "tr_TR": "", - "uk_UA": "Обрізано XCI Файлів '{0}'", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Обрізається XCI Файлів '{0}'", + "zh_CN": "正在瘦身 XCI 文件 '{0}'", + "zh_TW": "正在修剪 XCI 檔案 '{0}'" } }, { @@ -2556,8 +3112,9 @@ "ko_KR": "메모리 매핑 한계 감지", "no_NO": "Lav grense for minnetildelinger oppdaget", "pl_PL": "Wykryto niski limit dla przypisań pamięci", - "pt_BR": "Limite baixo para mapeamentos de memória detectado", + "pt_BR": "Detectado limite baixo para mapeamentos de memória", "ru_RU": "Обнаружен низкий лимит разметки памяти", + "sv_SE": "Låg gräns för minnesmappningar upptäcktes", "th_TH": "การตั้งค่าหน่วยความถึงขีดจำกัดต่ำสุดแล้ว", "tr_TR": "Bellek Haritaları İçin Düşük Limit Tespit Edildi ", "uk_UA": "Виявлено низьку межу для відображення памʼяті", @@ -2582,9 +3139,10 @@ "pl_PL": "Czy chcesz zwiększyć wartość vm.max_map_count do {0}", "pt_BR": "Você gostaria de aumentar o valor de vm.max_map_count para {0}", "ru_RU": "Хотите увеличить значение vm.max_map_count до {0}", + "sv_SE": "Vill du öka värdet för vm.max_map_count till {0}", "th_TH": "คุณต้องเพิ่มค่า vm.max_map_count ไปยัง {0}", "tr_TR": "vm.max_map_count değerini {0} sayısına yükseltmek ister misiniz", - "uk_UA": "Бажаєте збільшити значення vm.max_map_count на {0}", + "uk_UA": "Бажаєте збільшити значення vm.max_map_count до {0}", "zh_CN": "你想要将操作系统 vm.max_map_count 的值增加到 {0} 吗", "zh_TW": "您是否要將 vm.max_map_count 的數值增至 {0}?" } @@ -2606,9 +3164,10 @@ "pl_PL": "Niektóre gry mogą próbować przypisać sobie więcej pamięci niż obecnie, jest to dozwolone. Ryujinx ulegnie awarii, gdy limit zostanie przekroczony.", "pt_BR": "Alguns jogos podem tentar criar mais mapeamentos de memória do que o atualmente permitido. Ryujinx irá falhar assim que este limite for excedido.", "ru_RU": "Некоторые игры могут создавать большую разметку памяти, чем разрешено на данный момент по умолчанию. Ryujinx вылетит при превышении этого лимита.", + "sv_SE": "Vissa spel kan försöka att skapa fler minnesmappningar än vad som tillåts. Ryujinx kommer att krascha så snart som denna gräns överstigs.", "th_TH": "บางเกมอาจพยายามใช้งานหน่วยความจำมากกว่าที่ได้รับอนุญาตในปัจจุบัน Ryujinx จะปิดตัวลงเมื่อเกินขีดจำกัดนี้", "tr_TR": "Bazı oyunlar şu an izin verilen bellek haritası limitinden daha fazlasını yaratmaya çalışabilir. Ryujinx bu limitin geçildiği takdirde kendini kapatıcaktır.", - "uk_UA": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.", + "uk_UA": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж це дозволено зараз. Ryujinx закриється (крашнеться), щойно цей ліміт буде перевищено.", "zh_CN": "有些游戏可能会尝试创建超过当前系统允许的内存映射最大数量,若超过当前最大数量,Ryujinx 模拟器将会闪退。", "zh_TW": "某些遊戲可能會嘗試建立超過目前允許的記憶體映射。一旦超過此限制,Ryujinx 就會崩潰。" } @@ -2630,6 +3189,7 @@ "pl_PL": "Tak, do następnego ponownego uruchomienia", "pt_BR": "Sim, até a próxima reinicialização", "ru_RU": "Да, до следующего перезапуска", + "sv_SE": "Ja, tills nästa omstart", "th_TH": "ใช่, จนกว่าจะรีสตาร์ทครั้งถัดไป", "tr_TR": "Evet, bir sonraki yeniden başlatmaya kadar", "uk_UA": "Так, до наст. перезапуску", @@ -2654,9 +3214,10 @@ "pl_PL": "Tak, permanentnie ", "pt_BR": "Sim, permanentemente", "ru_RU": "Да, постоянно", + "sv_SE": "Ja, permanent", "th_TH": "ใช่, อย่างถาวร", "tr_TR": "Evet, kalıcı olarak", - "uk_UA": "Так, назавжди", + "uk_UA": "Так, постійно", "zh_CN": "确定,永久保存", "zh_TW": "是的,永久設定" } @@ -2678,9 +3239,10 @@ "pl_PL": "Maksymalna ilość przypisanej pamięci jest mniejsza niż zalecana.", "pt_BR": "A quantidade máxima de mapeamentos de memória é menor que a recomendada.", "ru_RU": "Максимальная разметка памяти меньше, чем рекомендуется.", + "sv_SE": "Maximal mängd minnesmappningar är lägre än rekommenderat.", "th_TH": "จำนวนสูงสุดของการจัดการหน่วยความจำ ต่ำกว่าที่แนะนำ", "tr_TR": "İzin verilen maksimum bellek haritası değeri tavsiye edildiğinden daha düşük. ", - "uk_UA": "Максимальна кількість відображення памʼяті менша, ніж рекомендовано.", + "uk_UA": "Максимальний обсяг виділеної пам'яті менший за рекомендований.", "zh_CN": "内存映射的最大数量低于推荐值。", "zh_TW": "記憶體映射的最大值低於建議值。" } @@ -2702,9 +3264,10 @@ "pl_PL": "Obecna wartość vm.max_map_count ({0}) jest mniejsza niż {1}. Niektóre gry mogą próbować stworzyć więcej mapowań pamięci niż obecnie jest to dozwolone. Ryujinx napotka crash, gdy dojdzie do takiej sytuacji.\n\nMożesz chcieć ręcznie zwiększyć limit lub zainstalować pkexec, co pozwala Ryujinx na pomoc w tym zakresie.", "pt_BR": "O valor atual de vm.max_map_count ({0}) é menor que {1}. Alguns jogos podem tentar criar mais mapeamentos de memória do que o permitido no momento. Ryujinx vai falhar assim que este limite for excedido.\n\nTalvez você queira aumentar o limite manualmente ou instalar pkexec, o que permite que Ryujinx ajude com isso.", "ru_RU": "Текущее значение vm.max_map_count ({0}) меньше, чем {1}. Некоторые игры могут попытаться создать большую разметку памяти, чем разрешено в данный момент. Ryujinx вылетит как только этот лимит будет превышен.\n\nВозможно, вам потребуется вручную увеличить лимит или установить pkexec, что позволит Ryujinx помочь справиться с превышением лимита.", + "sv_SE": "Det aktuella värdet för vm.max_map_count ({0}) är lägre än {1}. Vissa spel kan försöka att skapa fler minnesmappningar än vad som tillåts. Ryujinx kommer att krascha så snart som denna gräns överstigs.\n\nDu kanske vill manuellt öka gränsen eller installera pkexec, vilket tillåter att Ryujinx hjälper till med det.", "th_TH": "ค่าปัจจุบันของ vm.max_map_count ({0}) มีค่าต่ำกว่า {1} บางเกมอาจพยายามใช้หน่วยความจำมากกว่าที่ได้รับอนุญาตในปัจจุบัน Ryujinx จะปิดตัวลงเมื่อเกินขีดจำกัดนี้\n\nคุณอาจต้องการตั้งค่าเพิ่มขีดจำกัดด้วยตนเองหรือติดตั้ง pkexec ซึ่งอนุญาตให้ Ryujinx ช่วยเหลือคุณได้", "tr_TR": "Şu anki vm.max_map_count değeri {0}, bu {1} değerinden daha az. Bazı oyunlar şu an izin verilen bellek haritası limitinden daha fazlasını yaratmaya çalışabilir. Ryujinx bu limitin geçildiği takdirde kendini kapatıcaktır.\n\nManuel olarak bu limiti arttırmayı deneyebilir ya da pkexec'i yükleyebilirsiniz, bu da Ryujinx'in yardımcı olmasına izin verir.", - "uk_UA": "Поточне значення vm.max_map_count ({0}) менше за {1}. Деякі ігри можуть спробувати створити більше відображень пам’яті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.\n\nВи можете збільшити ліміт вручну або встановити pkexec, який дозволяє Ryujinx допомогти з цим.", + "uk_UA": "Поточне значення vm.max_map_count ({0}) менше за {1}. Деякі ігри можуть спробувати створити більше відображень пам’яті, ніж дозволено наразі. Ryujinx закриється (крашнеться), щойно цей ліміт буде перевищено.\n\nВи можете збільшити ліміт власноруч або встановити pkexec, який допоможе Ryujinx впоратися з перевищенням ліміту.", "zh_CN": "vm.max_map_count ({0}) 的当前值小于 {1}。 有些游戏可能会尝试创建超过当前系统允许的内存映射最大数量,若超过当前最大数量,Ryujinx 模拟器将会闪退。\n\n你可以手动增加内存映射最大数量,或者安装 pkexec,它可以辅助 Ryujinx 完成内存映射最大数量的修改操作。", "zh_TW": "目前 vm.max_map_count ({0}) 的數值小於 {1}。某些遊戲可能會嘗試建立比目前允許值更多的記憶體映射。一旦超過此限制,Ryujinx 就會崩潰。\n\n您可能需要手動提高上限,或者安裝 pkexec,讓 Ryujinx 協助提高上限。" } @@ -2726,6 +3289,7 @@ "pl_PL": "Ustawienia", "pt_BR": "Configurações", "ru_RU": "Параметры", + "sv_SE": "Inställningar", "th_TH": "ตั้งค่า", "tr_TR": "Ayarlar", "uk_UA": "Налаштування", @@ -2748,8 +3312,9 @@ "ko_KR": "사용자 인터페이스", "no_NO": "Brukergrensesnitt", "pl_PL": "Interfejs użytkownika", - "pt_BR": "Geral", + "pt_BR": "Interface do Usuário", "ru_RU": "Интерфейс", + "sv_SE": "Användargränssnitt", "th_TH": "หน้าจอผู้ใช้", "tr_TR": "Kullancı Arayüzü", "uk_UA": "Інтерфейс користувача", @@ -2774,6 +3339,7 @@ "pl_PL": "Ogólne", "pt_BR": "Geral", "ru_RU": "Общее", + "sv_SE": "Allmänt", "th_TH": "ทั่วไป", "tr_TR": "Genel", "uk_UA": "Загальні", @@ -2796,8 +3362,9 @@ "ko_KR": "디스코드 활동 상태 활성화", "no_NO": "Aktiver Discord Rik Tilstedeværelse", "pl_PL": "Włącz Bogatą Obecność Discord", - "pt_BR": "Habilitar Rich Presence do Discord", + "pt_BR": "Habilitar Presença no Discord", "ru_RU": "Статус активности в Discord", + "sv_SE": "Aktivera Discord Rich Presence", "th_TH": "เปิดใช้งาน Discord Rich Presence", "tr_TR": "Discord Zengin İçerik'i Etkinleştir", "uk_UA": "Увімкнути розширену присутність Discord", @@ -2808,25 +3375,251 @@ { "ID": "SettingsTabGeneralCheckUpdatesOnLaunch", "Translations": { - "ar_SA": "التحقق من وجود تحديثات عند التشغيل", - "de_DE": "Beim Start nach Updates suchen", - "el_GR": "Έλεγχος για Ενημερώσεις στην Εκκίνηση", - "en_US": "Check for Updates on Launch", - "es_ES": "Buscar actualizaciones al iniciar", - "fr_FR": "Vérifier les mises à jour au démarrage", - "he_IL": "בדוק אם קיימים עדכונים בהפעלה", - "it_IT": "Controlla aggiornamenti all'avvio", - "ja_JP": "起動時にアップデートを確認する", - "ko_KR": "시작 시, 업데이트 확인", - "no_NO": "Se etter oppdateringer ved oppstart", - "pl_PL": "Sprawdzaj aktualizacje przy uruchomieniu", - "pt_BR": "Verificar se há atualizações ao iniciar", - "ru_RU": "Проверять наличие обновлений при запуске", - "th_TH": "ตรวจหาการอัปเดตเมื่อเปิดโปรแกรม", - "tr_TR": "Her Açılışta Güncellemeleri Denetle", - "uk_UA": "Перевіряти наявність оновлень під час запуску", - "zh_CN": "启动时检查更新", - "zh_TW": "啟動時檢查更新" + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Check for Updates:", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Se etter Oppdateringer:", + "pl_PL": "", + "pt_BR": "Verificar Atualizações:", + "ru_RU": "Проверка наличия обновлений", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Перевірка оновлень:", + "zh_CN": "检查更新", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchOff", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Off", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Av", + "pl_PL": "", + "pt_BR": "Desligado", + "ru_RU": "Отключить", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Вимкнути", + "zh_CN": "关闭", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Prompt", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Spør", + "pl_PL": "", + "pt_BR": "Ao Abrir", + "ru_RU": "При запуске", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запитувати щоразу", + "zh_CN": "提示", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchBackground", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Background", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Bakgrunn", + "pl_PL": "", + "pt_BR": "2° Plano", + "ru_RU": "В фоне", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Оновлювати в фоні", + "zh_CN": "背景", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossType", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "On Emulator Focus Lost:", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "På Emulator Fokus Tapt:", + "pl_PL": "", + "pt_BR": "Ao Perder o Foco:", + "ru_RU": "При выходе эмулятора из фокуса", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "При втраті фокуса емулятором:", + "zh_CN": "当模拟器在后台时:", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossTypeDoNothing", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Do Nothing", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Gjør Ingenting", + "pl_PL": "", + "pt_BR": "Não Fazer Nada", + "ru_RU": "Ничего не делать", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Нічого не робити", + "zh_CN": "什么事情也不做", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossTypeBlockInput", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Block Input", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Blokkinngang", + "pl_PL": "", + "pt_BR": "Bloquear Controles", + "ru_RU": "Блокировать управление", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Блокувати введення", + "zh_CN": "禁用输入", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossTypeMuteAudio", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Mute Volume", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Demp Lyd", + "pl_PL": "", + "pt_BR": "Ficar Mudo", + "ru_RU": "Отключить звук", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Вимкнути звук", + "zh_CN": "静音", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Block Input & Mute Volume", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Blokker Inputs og demp Volumet", + "pl_PL": "", + "pt_BR": "Bloquear Controles & Ficar Mudo", + "ru_RU": "Блокировать управление и отключить звук", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Блокувати введення та Вимкнути звук", + "zh_CN": "阻止输入且静音", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralFocusLossTypePauseEmulation", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Pause Emulation", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Pause Emulatoren", + "pl_PL": "", + "pt_BR": "Pausar a Emulação", + "ru_RU": "Поставить паузу", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Поставити на паузу", + "zh_CN": "暂停模拟", + "zh_TW": "" } }, { @@ -2844,8 +3637,9 @@ "ko_KR": "\"종료 확인\" 대화 상자 표시", "no_NO": "Vis \"Bekreft Avslutt\" vinduet", "pl_PL": "Pokazuj okno dialogowe \"Potwierdź wyjście\"", - "pt_BR": "Exibir diálogo de confirmação ao sair", + "pt_BR": "Exibir \"Diálogo de confirmação\" ao Sair", "ru_RU": "Подтверждать выход из приложения", + "sv_SE": "Visa \"Bekräfta avslut\"-dialog", "th_TH": "แสดง \"ปุ่มยืนยันการออก\" เมื่อออกเกม", "tr_TR": "\"Çıkışı Onayla\" Diyaloğunu Göster", "uk_UA": "Показати діалогове вікно «Підтвердити вихід».", @@ -2863,13 +3657,14 @@ "es_ES": "Recordar Tamaño/Posición de la Ventana", "fr_FR": "Mémoriser la taille/position de la fenêtre", "he_IL": "", - "it_IT": "Ricorda Dimensione/Posizione Finestra", + "it_IT": "Ricorda la dimensione e la posizione della finestra", "ja_JP": "", "ko_KR": "창 크기/위치 기억", "no_NO": "Husk vinduets størrelse/posisjon", "pl_PL": "", - "pt_BR": "Lembrar tamanho/posição da Janela", + "pt_BR": "Lembrar Tamanho e Posição da Janela", "ru_RU": "Запомнить размер/положение окна", + "sv_SE": "Kom ihåg fönstrets storlek/position", "th_TH": "จดจำ ขนาดหน้าต่างแอพพลิเคชั่น/คำแหน่ง", "tr_TR": "", "uk_UA": "Запам'ятати Розмір/Позицію вікна", @@ -2877,6 +3672,31 @@ "zh_TW": "記住視窗大小/位置" } }, + { + "ID": "SettingsTabGeneralDisableInputWhenOutOfFocus", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Disable Input when Out of Focus", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Deaktiver inndata når vinduet er ute av fokus", + "pl_PL": "", + "pt_BR": "Desativar Controles Quando Estiver Fora de Foco", + "ru_RU": "Отключает управление при выходе из фокуса", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "在后台时禁用输入", + "zh_TW": "" + } + }, { "ID": "SettingsTabGeneralShowTitleBar", "Translations": { @@ -2892,8 +3712,9 @@ "ko_KR": "제목 표시줄 표시(다시 시작해야 함)", "no_NO": "Vis tittellinje (krever omstart)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Mostrar Barra de Título (Requer reinicialização)", + "ru_RU": "Показать строку заголовка (требуется перезапуск)", + "sv_SE": "Visa titelrad (kräver omstart)", "th_TH": "", "tr_TR": "", "uk_UA": "Показувати рядок заголовка (Потрібен перезапуск)", @@ -2916,11 +3737,12 @@ "ko_KR": "커서 숨기기 :", "no_NO": "Skjul musepeker:", "pl_PL": "Ukryj kursor:", - "pt_BR": "Esconder o cursor do mouse:", + "pt_BR": "Esconder Cursor do Mouse:", "ru_RU": "Скрывать курсор", + "sv_SE": "Dölj markör:", "th_TH": "ซ่อน เคอร์เซอร์:", "tr_TR": "İşaretçiyi Gizle:", - "uk_UA": "Сховати вказівник:", + "uk_UA": "Сховати курсор:", "zh_CN": "隐藏鼠标指针:", "zh_TW": "隱藏滑鼠游標:" } @@ -2942,6 +3764,7 @@ "pl_PL": "Nigdy", "pt_BR": "Nunca", "ru_RU": "Никогда", + "sv_SE": "Aldrig", "th_TH": "ไม่ต้อง", "tr_TR": "Hiçbir Zaman", "uk_UA": "Ніколи", @@ -2964,8 +3787,9 @@ "ko_KR": "유휴 상태", "no_NO": "Når inaktiv", "pl_PL": "Gdy bezczynny", - "pt_BR": "Esconder o cursor quando ocioso", + "pt_BR": "Quando Ocioso", "ru_RU": "В простое", + "sv_SE": "Vid overksam", "th_TH": "เมื่อไม่ได้ใช้งาน", "tr_TR": "Hareketsiz Durumda", "uk_UA": "Сховати у режимі очікування", @@ -2990,6 +3814,7 @@ "pl_PL": "Zawsze", "pt_BR": "Sempre", "ru_RU": "Всегда", + "sv_SE": "Alltid", "th_TH": "ตลอดเวลา", "tr_TR": "Her Zaman", "uk_UA": "Завжди", @@ -3012,8 +3837,9 @@ "ko_KR": "게임 데릭터리", "no_NO": "Spillmapper", "pl_PL": "Katalogi gier", - "pt_BR": "Diretórios de jogo", + "pt_BR": "Pasta de Jogos", "ru_RU": "Папки с играми", + "sv_SE": "Spelkataloger", "th_TH": "ไดเรกทอรี่ของเกม", "tr_TR": "Oyun Dizinleri", "uk_UA": "Тека ігор", @@ -3031,17 +3857,18 @@ "es_ES": "Carpetas de DLC/Actualizaciones para Carga Automática", "fr_FR": "Dossiers des mises à jour/DLC", "he_IL": "", - "it_IT": "Directory di Caricamento Automatico per DLC/Aggiornamenti", + "it_IT": "Cartelle di caricamento automatico di DLC/aggiornamenti", "ja_JP": "", "ko_KR": "DLC/업데이트 디렉터리 자동 불러오기", "no_NO": "Autoload DLC/Updates-mapper", "pl_PL": "", - "pt_BR": "Carregar Automaticamente Diretórios de DLC/Atualizações", - "ru_RU": "", + "pt_BR": "Carregar Automaticamente Pasta de DLC e Atualizações", + "ru_RU": "Автозагрузка папки с DLC/Обновлениями", + "sv_SE": "Läs automatisk in DLC/speluppdateringar", "th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ", "tr_TR": "", - "uk_UA": "Автозавантаження каталогів DLC/Оновлень", - "zh_CN": "自动加载DLC/游戏更新目录", + "uk_UA": "Автозавантаження теки DLC/Оновлень", + "zh_CN": "自动加载 DLC 及 游戏更新 的目录", "zh_TW": "自動載入 DLC/遊戲更新資料夾" } }, @@ -3055,17 +3882,18 @@ "es_ES": "DLC y Actualizaciones que hacen referencia a archivos ausentes serán desactivado automáticamente", "fr_FR": "Les DLC et les mises à jour faisant référence aux fichiers manquants seront automatiquement déchargés.", "he_IL": "", - "it_IT": "Aggiornamenti e DLC che collegano a file mancanti verranno disabilitati automaticamente", + "it_IT": "Aggiornamenti e DLC che fanno riferimento a file mancanti verranno disabilitati automaticamente", "ja_JP": "", - "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 언로드", + "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 불러오기 취소", "no_NO": "DLC og oppdateringer som henviser til manglende filer, vil bli lastet ned automatisk", "pl_PL": "", - "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão descarregadas automaticamente", - "ru_RU": "", + "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão desabilitados automaticamente", + "ru_RU": "DLC и обновления, которые ссылаются на отсутствующие файлы, будут выгружаться автоматически", + "sv_SE": "DLC och speluppdateringar som refererar till saknade filer kommer inte att läsas in automatiskt", "th_TH": "", "tr_TR": "", "uk_UA": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.", - "zh_CN": "DLC/游戏更新可自动加载和卸载", + "zh_CN": "DLC 及 游戏更新 可自动加载和卸载", "zh_TW": "遺失的 DLC 及遊戲更新檔案將會在自動載入中移除" } }, @@ -3086,6 +3914,7 @@ "pl_PL": "Dodaj", "pt_BR": "Adicionar", "ru_RU": "Добавить", + "sv_SE": "Lägg till", "th_TH": "เพิ่ม", "tr_TR": "Ekle", "uk_UA": "Додати", @@ -3110,6 +3939,7 @@ "pl_PL": "Usuń", "pt_BR": "Remover", "ru_RU": "Удалить", + "sv_SE": "Ta bort", "th_TH": "เอาออก", "tr_TR": "Kaldır", "uk_UA": "Видалити", @@ -3130,10 +3960,11 @@ "it_IT": "Sistema", "ja_JP": "システム", "ko_KR": "시스템", - "no_NO": "System", + "no_NO": "", "pl_PL": "", "pt_BR": "Sistema", "ru_RU": "Система", + "sv_SE": "", "th_TH": "ระบบ", "tr_TR": "Sistem", "uk_UA": "Система", @@ -3158,6 +3989,7 @@ "pl_PL": "Główne", "pt_BR": "Principal", "ru_RU": "Основные настройки", + "sv_SE": "Kärna", "th_TH": "แกนกลาง", "tr_TR": "Çekirdek", "uk_UA": "Ядро", @@ -3180,8 +4012,9 @@ "ko_KR": "시스템 지역 :", "no_NO": "System region:", "pl_PL": "Region systemu:", - "pt_BR": "Região do sistema:", + "pt_BR": "Região do Sistema:", "ru_RU": "Регион прошивки:", + "sv_SE": "Systemregion:", "th_TH": "ภูมิภาคของระบบ:", "tr_TR": "Sistem Bölgesi:", "uk_UA": "Регіон системи:", @@ -3202,10 +4035,11 @@ "it_IT": "Giappone", "ja_JP": "日本", "ko_KR": "일본", - "no_NO": "Japan", + "no_NO": "", "pl_PL": "Japonia", "pt_BR": "Japão", "ru_RU": "Япония", + "sv_SE": "", "th_TH": "ญี่ปุ่น", "tr_TR": "Japonya", "uk_UA": "Японія", @@ -3226,10 +4060,11 @@ "it_IT": "Stati Uniti d'America", "ja_JP": "アメリカ", "ko_KR": "미국", - "no_NO": "USA", + "no_NO": "", "pl_PL": "Stany Zjednoczone", "pt_BR": "EUA", "ru_RU": "США", + "sv_SE": "", "th_TH": "สหรัฐอเมริกา", "tr_TR": "ABD", "uk_UA": "США", @@ -3254,6 +4089,7 @@ "pl_PL": "Europa", "pt_BR": "Europa", "ru_RU": "Европа", + "sv_SE": "Europa", "th_TH": "ยุโรป", "tr_TR": "Avrupa", "uk_UA": "Європа", @@ -3274,10 +4110,11 @@ "it_IT": "", "ja_JP": "オーストラリア", "ko_KR": "호주", - "no_NO": "Australia", + "no_NO": "", "pl_PL": "", "pt_BR": "Austrália", "ru_RU": "Австралия", + "sv_SE": "Australien", "th_TH": "ออสเตรเลีย", "tr_TR": "Avustralya", "uk_UA": "Австралія", @@ -3302,6 +4139,7 @@ "pl_PL": "Chiny", "pt_BR": "", "ru_RU": "Китай", + "sv_SE": "Kina", "th_TH": "จีน", "tr_TR": "Çin", "uk_UA": "Китай", @@ -3322,10 +4160,11 @@ "it_IT": "Corea", "ja_JP": "韓国", "ko_KR": "한국", - "no_NO": "Korea", + "no_NO": "Koreansk", "pl_PL": "", "pt_BR": "Coreia", "ru_RU": "Корея", + "sv_SE": "", "th_TH": "เกาหลี", "tr_TR": "Kore", "uk_UA": "Корея", @@ -3346,10 +4185,11 @@ "it_IT": "", "ja_JP": "台湾", "ko_KR": "대만", - "no_NO": "Taiwan", + "no_NO": "", "pl_PL": "Tajwan", "pt_BR": "", "ru_RU": "Тайвань", + "sv_SE": "", "th_TH": "ไต้หวัน", "tr_TR": "Tayvan", "uk_UA": "Тайвань", @@ -3372,8 +4212,9 @@ "ko_KR": "시스템 언어 :", "no_NO": "Systemspråk", "pl_PL": "Język systemu:", - "pt_BR": "Idioma do sistema:", - "ru_RU": "Язык прошивки:", + "pt_BR": "Idioma do Sistema:", + "ru_RU": "Язык системы:", + "sv_SE": "Systemspråk:", "th_TH": "ภาษาของระบบ:", "tr_TR": "Sistem Dili:", "uk_UA": "Мова системи:", @@ -3398,6 +4239,7 @@ "pl_PL": "Japoński", "pt_BR": "Japonês", "ru_RU": "Японский", + "sv_SE": "Japanska", "th_TH": "ญี่ปุ่น", "tr_TR": "Japonca", "uk_UA": "Японська", @@ -3420,8 +4262,9 @@ "ko_KR": "미국 영어", "no_NO": "Amerikansk engelsk", "pl_PL": "Angielski (Stany Zjednoczone)", - "pt_BR": "Inglês americano", + "pt_BR": "Inglês Americano", "ru_RU": "Английский (США)", + "sv_SE": "Amerikansk engelska", "th_TH": "อังกฤษ (อเมริกัน)", "tr_TR": "Amerikan İngilizcesi", "uk_UA": "Англійська (США)", @@ -3446,6 +4289,7 @@ "pl_PL": "Francuski", "pt_BR": "Francês", "ru_RU": "Французский", + "sv_SE": "Franska", "th_TH": "ฝรั่งเศส", "tr_TR": "Fransızca", "uk_UA": "Французька", @@ -3469,7 +4313,8 @@ "no_NO": "Tysk", "pl_PL": "Niemiecki", "pt_BR": "Alemão", - "ru_RU": "Германский", + "ru_RU": "Немецкий", + "sv_SE": "Tyska", "th_TH": "เยอรมัน", "tr_TR": "Almanca", "uk_UA": "Німецька", @@ -3494,6 +4339,7 @@ "pl_PL": "Włoski", "pt_BR": "Italiano", "ru_RU": "Итальянский", + "sv_SE": "Italienska", "th_TH": "อิตาลี", "tr_TR": "İtalyanca", "uk_UA": "Італійська", @@ -3518,6 +4364,7 @@ "pl_PL": "Hiszpański", "pt_BR": "Espanhol", "ru_RU": "Испанский", + "sv_SE": "Spanska", "th_TH": "สเปน", "tr_TR": "İspanyolca", "uk_UA": "Іспанська", @@ -3542,6 +4389,7 @@ "pl_PL": "Chiński", "pt_BR": "Chinês", "ru_RU": "Китайский", + "sv_SE": "Kinesiska", "th_TH": "จีน", "tr_TR": "Çince", "uk_UA": "Китайська", @@ -3566,6 +4414,7 @@ "pl_PL": "Koreański", "pt_BR": "Coreano", "ru_RU": "Корейский", + "sv_SE": "Koreanska", "th_TH": "เกาหลี", "tr_TR": "Korece", "uk_UA": "Корейська", @@ -3590,6 +4439,7 @@ "pl_PL": "Holenderski", "pt_BR": "Holandês", "ru_RU": "Нидерландский", + "sv_SE": "Nederländska", "th_TH": "ดัตช์", "tr_TR": "Flemenkçe", "uk_UA": "Нідерландська", @@ -3614,6 +4464,7 @@ "pl_PL": "Portugalski", "pt_BR": "Português", "ru_RU": "Португальский", + "sv_SE": "Portugisiska", "th_TH": "โปรตุเกส", "tr_TR": "Portekizce", "uk_UA": "Португальська", @@ -3638,6 +4489,7 @@ "pl_PL": "Rosyjski", "pt_BR": "Russo", "ru_RU": "Русский", + "sv_SE": "Ryska", "th_TH": "รัสเซีย", "tr_TR": "Rusça", "uk_UA": "Російська", @@ -3661,7 +4513,8 @@ "no_NO": "Taiwansk", "pl_PL": "Tajwański", "pt_BR": "Taiwanês", - "ru_RU": "Тайванский", + "ru_RU": "Тайваньский", + "sv_SE": "Taiwanesiska", "th_TH": "จีนตัวเต็ม (ไต้หวัน)", "tr_TR": "Tayvanca", "uk_UA": "Тайванська", @@ -3684,8 +4537,9 @@ "ko_KR": "영국 영어", "no_NO": "Britisk engelsk", "pl_PL": "Angielski (Wielka Brytania)", - "pt_BR": "Inglês britânico", - "ru_RU": "Английский (Британия)", + "pt_BR": "Inglês Britânico", + "ru_RU": "Английский (Великобритания)", + "sv_SE": "Brittisk engelska", "th_TH": "อังกฤษ (บริติช)", "tr_TR": "İngiliz İngilizcesi", "uk_UA": "Англійська (Великобританія)", @@ -3708,8 +4562,9 @@ "ko_KR": "캐나다 프랑스어", "no_NO": "Canadisk Fransk", "pl_PL": "Kanadyjski Francuski", - "pt_BR": "Francês canadense", + "pt_BR": "Francês Canadense", "ru_RU": "Французский (Канада)", + "sv_SE": "Kanadensisk franska", "th_TH": "ฝรั่งเศส (แคนาดา)", "tr_TR": "Kanada Fransızcası", "uk_UA": "Французька (Канада)", @@ -3732,8 +4587,9 @@ "ko_KR": "남미 스페인어", "no_NO": "Latinamerikansk spansk", "pl_PL": "Hiszpański (Ameryka Łacińska)", - "pt_BR": "Espanhol latino", + "pt_BR": "Espanhol Latino", "ru_RU": "Испанский (Латинская Америка)", + "sv_SE": "Latinamerikansk spanska", "th_TH": "สเปน (ลาตินอเมริกา)", "tr_TR": "Latin Amerika İspanyolcası", "uk_UA": "Іспанська (Латиноамериканська)", @@ -3756,8 +4612,9 @@ "ko_KR": "중국어 간체", "no_NO": "Forenklet kinesisk", "pl_PL": "Chiński (Uproszczony)", - "pt_BR": "Chinês simplificado", + "pt_BR": "Chinês Simplificado", "ru_RU": "Китайский (упрощённый)", + "sv_SE": "Förenklad kinesiska", "th_TH": "จีน (ตัวย่อ)", "tr_TR": "Basitleştirilmiş Çince", "uk_UA": "Спрощена китайська", @@ -3780,8 +4637,9 @@ "ko_KR": "중국어 번체", "no_NO": "Tradisjonell Kinesisk", "pl_PL": "Chiński (Tradycyjny)", - "pt_BR": "Chinês tradicional", + "pt_BR": "Chinês Tradicional", "ru_RU": "Китайский (традиционный)", + "sv_SE": "Traditionell kinesiska", "th_TH": "จีน (ดั้งเดิม)", "tr_TR": "Geleneksel Çince", "uk_UA": "Традиційна китайська", @@ -3797,15 +4655,16 @@ "el_GR": "Ζώνη Ώρας Συστήματος:", "en_US": "System Time Zone:", "es_ES": "Zona horaria del sistema:", - "fr_FR": "Fuseau horaire du système :", + "fr_FR": "Fuseau horaire du système\u00A0:", "he_IL": "אזור זמן מערכת:", "it_IT": "Fuso orario del sistema:", "ja_JP": "タイムゾーン:", "ko_KR": "시스템 시간대 :", "no_NO": "System Tidssone:", "pl_PL": "Strefa czasowa systemu:", - "pt_BR": "Fuso horário do sistema:", - "ru_RU": "Часовой пояс прошивки:", + "pt_BR": "Fuso Horário do Sistema:", + "ru_RU": "Часовой пояс системы:", + "sv_SE": "Systemets tidszon:", "th_TH": "เขตเวลาของระบบ:", "tr_TR": "Sistem Saat Dilimi:", "uk_UA": "Часовий пояс системи:", @@ -3828,8 +4687,9 @@ "ko_KR": "시스템 시간 :", "no_NO": "System tid:", "pl_PL": "Czas systemu:", - "pt_BR": "Hora do sistema:", - "ru_RU": "Системное время в прошивке:", + "pt_BR": "Data e Hora do Sistema:", + "ru_RU": "Системное время:", + "sv_SE": "Systemtid:", "th_TH": "เวลาของระบบ:", "tr_TR": "Sistem Saati:", "uk_UA": "Час системи:", @@ -3843,21 +4703,22 @@ "ar_SA": "", "de_DE": "", "el_GR": "", - "en_US": "Resync to PC Date & Time", + "en_US": "Match System Time", "es_ES": "", - "fr_FR": "Resynchronier la Date à celle du PC", + "fr_FR": "", "he_IL": "", "it_IT": "", "ja_JP": "", - "ko_KR": "", - "no_NO": "", + "ko_KR": "매치 시스템 시간", + "no_NO": "Match systemtid", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Sincronizar com o Sistema PC", + "ru_RU": "Соответствовать времени в системе", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", - "zh_CN": "", + "zh_CN": "与系统时间同步", "zh_TW": "" } }, @@ -3876,8 +4737,9 @@ "ko_KR": "PPTC(프로파일된 영구 번역 캐시)", "no_NO": "PPTC (Profilert Vedvarende Oversettelseshurtigbuffer)", "pl_PL": "PPTC (Profilowana pamięć podręczna trwałych łłumaczeń)", - "pt_BR": "Habilitar PPTC (Profiled Persistent Translation Cache)", + "pt_BR": "PPTC (Cache de Tradução Persistente de Perfil)", "ru_RU": "Использовать PPTC (Profiled Persistent Translation Cache)", + "sv_SE": "PPTC (Profilerad bestående översättningscache)", "th_TH": "PPTC (แคชโปรไฟล์การแปลแบบถาวร)", "tr_TR": "PPTC (Profilli Sürekli Çeviri Önbelleği)", "uk_UA": "PPTC (профільований постійний кеш перекладу)", @@ -3895,13 +4757,14 @@ "es_ES": "Cache PPTC de bajo consumo", "fr_FR": "PPTC à faible puissance", "he_IL": "Low-power PPTC", - "it_IT": "Low-power PPTC", + "it_IT": "Caricamento PPTC a basso consumo energetico", "ja_JP": "Low-power PPTC", "ko_KR": "저전력 PPTC 캐시", "no_NO": "PPTC med lavt strømforbruk", "pl_PL": "Low-power PPTC", - "pt_BR": "Low-power PPTC", - "ru_RU": "Low-power PPTC", + "pt_BR": "Cache PPTC com Baixo Consumo de Energia", + "ru_RU": "PPTC с низким электропотреблением", + "sv_SE": "PPTC med låg strömförbrukning", "th_TH": "PPTC แบบพลังงานตํ่า", "tr_TR": "Low-power PPTC", "uk_UA": "Low-power PPTC", @@ -3924,13 +4787,14 @@ "ko_KR": "파일 시스템 무결성 검사", "no_NO": "FS Integritetssjekk", "pl_PL": "Sprawdzanie integralności systemu plików", - "pt_BR": "Habilitar verificação de integridade do sistema de arquivos", + "pt_BR": "Verificações de Integridade do FS", "ru_RU": "Проверка целостности файловой системы", + "sv_SE": "Integritetskontroller av filsystem", "th_TH": "ตรวจสอบความถูกต้องของ FS", "tr_TR": "FS Bütünlük Kontrolleri", "uk_UA": "Перевірка цілісності FS", "zh_CN": "启用文件系统完整性检查", - "zh_TW": "檔案系統完整性檢查" + "zh_TW": "啟用檔案系統完整性檢查" } }, { @@ -3948,8 +4812,9 @@ "ko_KR": "음향 후단부 :", "no_NO": "Lyd Backend:", "pl_PL": "Backend Dżwięku:", - "pt_BR": "Biblioteca de saída de áudio:", + "pt_BR": "Módulo de Áudio:", "ru_RU": "Аудио бэкенд:", + "sv_SE": "Ljudbakände:", "th_TH": "ระบบเสียงเบื้องหลัง:", "tr_TR": "Ses Motoru:", "uk_UA": "Аудіосистема:", @@ -3970,13 +4835,14 @@ "it_IT": "", "ja_JP": "ダミー", "ko_KR": "더미", - "no_NO": "Dummy", + "no_NO": "", "pl_PL": "Atrapa", - "pt_BR": "Nenhuma", + "pt_BR": "Nenhum", "ru_RU": "Без звука", + "sv_SE": "", "th_TH": "", "tr_TR": "Yapay", - "uk_UA": "", + "uk_UA": "Вимкнено", "zh_CN": "无", "zh_TW": "虛設 (Dummy)" } @@ -3994,10 +4860,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "OpenAL", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4022,6 +4889,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4042,10 +4910,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "SDL2", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4061,15 +4930,16 @@ "el_GR": "Μικροδιορθώσεις", "en_US": "Hacks", "es_ES": "", - "fr_FR": "Hacks", + "fr_FR": "", "he_IL": "האצות", "it_IT": "Espedienti", "ja_JP": "ハック", "ko_KR": "핵", - "no_NO": "Hacks", + "no_NO": "", "pl_PL": "Hacki", "pt_BR": "", "ru_RU": "Хаки", + "sv_SE": "Hack", "th_TH": "แฮ็ก", "tr_TR": "Hack'ler", "uk_UA": "Хитрощі", @@ -4092,8 +4962,9 @@ "ko_KR": "불안정성을 유발할 수 있음", "no_NO": "Kan forårsake ustabilitet", "pl_PL": " (mogą powodować niestabilność)", - "pt_BR": " (Pode causar instabilidade)", + "pt_BR": "Pode causar instabilidade", "ru_RU": "Возможна нестабильная работа", + "sv_SE": "Kan orsaka instabilitet", "th_TH": "อาจทำให้เกิดข้อผิดพลาดได้", "tr_TR": " (dengesizlik oluşturabilir)", "uk_UA": " (може викликати нестабільність)", @@ -4111,13 +4982,14 @@ "es_ES": "Tamaño DRAM:", "fr_FR": "Taille de la DRAM :", "he_IL": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)", - "it_IT": "Usa layout di memoria alternativo (per sviluppatori)", + "it_IT": "Dimensione memoria DRAM:", "ja_JP": "DRAMサイズ:", "ko_KR": "DRAM 크기 :", "no_NO": "DRAM Mengde", "pl_PL": "Użyj alternatywnego układu pamięci (Deweloperzy)", "pt_BR": "Tamanho da DRAM:", "ru_RU": "Использовать альтернативный макет памяти (для разработчиков)", + "sv_SE": "DRAM-storlek:", "th_TH": "ใช้หน่วยความจำสำรอง (โหมดนักพัฒนา)", "tr_TR": "Alternatif bellek düzeni kullan (Geliştirici)", "uk_UA": "Використовувати альтернативне розташування пам'яті (для розробників)", @@ -4140,8 +5012,9 @@ "ko_KR": "4GB", "no_NO": "4GB", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "4GB", + "ru_RU": "4ГиБ", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "4Гб", @@ -4164,8 +5037,9 @@ "ko_KR": "6GB", "no_NO": "6GB", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "6GB", + "ru_RU": "6ГиБ", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "6Гб", @@ -4188,8 +5062,9 @@ "ko_KR": "8GB", "no_NO": "8GB", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "8GB", + "ru_RU": "8ГиБ", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "8Гб", @@ -4212,8 +5087,9 @@ "ko_KR": "12GB", "no_NO": "12GB", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "12GB", + "ru_RU": "12ГиБ", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "12Гб", @@ -4236,8 +5112,9 @@ "ko_KR": "누락된 서비스 무시", "no_NO": "Ignorer manglende tjenester", "pl_PL": "Ignoruj Brakujące Usługi", - "pt_BR": "Ignorar serviços não implementados", + "pt_BR": "Ignorar Serviços Ausentes", "ru_RU": "Игнорировать отсутствующие службы", + "sv_SE": "Ignorera saknade tjänster", "th_TH": "เมินเฉยบริการที่หายไป", "tr_TR": "Eksik Servisleri Görmezden Gel", "uk_UA": "Ігнорувати відсутні служби", @@ -4246,27 +5123,28 @@ } }, { - "ID": "SettingsTabSystemIgnoreApplet", + "ID": "SettingsTabSystemIgnoreControllerApplet", "Translations": { "ar_SA": "", - "de_DE": "Applet ignorieren", - "el_GR": "Αγνοήστε το Applet", - "en_US": "Ignore Applet", - "es_ES": "Ignorar el Applet", - "fr_FR": "Ignorer la déconnexion de la manette", + "de_DE": "", + "el_GR": "", + "en_US": "Ignore Controller Applet", + "es_ES": "", + "fr_FR": "", "he_IL": "", - "it_IT": "Ignora l'applet", - "ja_JP": "アプレットを無視する", - "ko_KR": "애플릿 무시", - "no_NO": "Ignorer appleten", - "pl_PL": "Ignoruj ​​aplet", - "pt_BR": "Ignorar applet", - "ru_RU": "Игнорировать Апплет", - "th_TH": "เมินเฉย Applet", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "Ignorar Applet do Controlador", + "ru_RU": "Игнорировать апплет контроллера", + "sv_SE": "", + "th_TH": "", "tr_TR": "", - "uk_UA": "Ігнорувати Аплет", - "zh_CN": "忽略小程序", - "zh_TW": "忽略小程式" + "uk_UA": "Ігнорувати Аплет Контролера", + "zh_CN": "", + "zh_TW": "" } }, { @@ -4286,6 +5164,7 @@ "pl_PL": "Grafika", "pt_BR": "Gráficos", "ru_RU": "Графика", + "sv_SE": "Grafik", "th_TH": "กราฟฟิก", "tr_TR": "Grafikler", "uk_UA": "Графіка", @@ -4310,6 +5189,7 @@ "pl_PL": "Graficzne API", "pt_BR": "API gráfica", "ru_RU": "Графические API", + "sv_SE": "Grafik-API", "th_TH": "API กราฟฟิก", "tr_TR": "Grafikler API", "uk_UA": "Графічний API", @@ -4332,8 +5212,9 @@ "ko_KR": "셰이더 캐시 활성화", "no_NO": "Aktiver Shader Cachen", "pl_PL": "Włącz pamięć podręczną cieni", - "pt_BR": "Habilitar cache de shader", + "pt_BR": "Habilitar Cache de Shader", "ru_RU": "Кэшировать шейдеры", + "sv_SE": "Aktivera Shader Cache", "th_TH": "เปิดใช้งาน แคชแสงเงา", "tr_TR": "Shader Önbelleğini Etkinleştir", "uk_UA": "Увімкнути кеш шейдерів", @@ -4356,8 +5237,9 @@ "ko_KR": "이방성 필터링 :", "no_NO": "Anisotropisk filtrering:", "pl_PL": "Filtrowanie anizotropowe:", - "pt_BR": "Filtragem anisotrópica:", + "pt_BR": "Filtro Anisotrópico:", "ru_RU": "Анизотропная фильтрация:", + "sv_SE": "Anisotropisk filtrering:", "th_TH": "ตัวกรองแบบ Anisotropic:", "tr_TR": "Eşyönsüz Doku Süzmesi:", "uk_UA": "Анізотропна фільтрація:", @@ -4375,13 +5257,14 @@ "es_ES": "Automático", "fr_FR": "", "he_IL": "אוטומטי", - "it_IT": "", + "it_IT": "Automatico", "ja_JP": "自動", "ko_KR": "자동", "no_NO": "Automatisk", "pl_PL": "Automatyczne", "pt_BR": "Automático", "ru_RU": "Автоматически", + "sv_SE": "Automatiskt", "th_TH": "อัตโนมัติ", "tr_TR": "Otomatik", "uk_UA": "Авто", @@ -4402,10 +5285,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "2배", - "no_NO": "2x", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4426,10 +5310,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "4배", - "no_NO": "4x", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4450,10 +5335,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "8배", - "no_NO": "8x", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4474,10 +5360,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "16배", - "no_NO": "16x", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4500,8 +5387,9 @@ "ko_KR": "해상도 배율 :", "no_NO": "Oppløsnings skala:", "pl_PL": "Skalowanie rozdzielczości:", - "pt_BR": "Escala de resolução:", + "pt_BR": "Escala de Resolução:", "ru_RU": "Масштабирование:", + "sv_SE": "Upplösningsskalning:", "th_TH": "อัตราส่วนความละเอียด:", "tr_TR": "Çözünürlük Ölçeği:", "uk_UA": "Роздільна здатність:", @@ -4524,8 +5412,9 @@ "ko_KR": "사용자 정의(권장하지 않음)", "no_NO": "Egendefinert (anbefales ikke)", "pl_PL": "Niestandardowa (Niezalecane)", - "pt_BR": "Customizada (não recomendado)", + "pt_BR": "Customizada (Não recomendado)", "ru_RU": "Пользовательское (не рекомендуется)", + "sv_SE": "Anpassad (rekommenderas inte)", "th_TH": "กำหนดเอง (ไม่แนะนำ)", "tr_TR": "Özel (Tavsiye Edilmez)", "uk_UA": "Користувацька (не рекомендовано)", @@ -4550,6 +5439,7 @@ "pl_PL": "Natywna (720p/1080p)", "pt_BR": "Nativa (720p/1080p)", "ru_RU": "Нативное (720p/1080p)", + "sv_SE": "Inbyggd (720p/1080p)", "th_TH": "พื้นฐานระบบ (720p/1080p)", "tr_TR": "Yerel (720p/1080p)", "uk_UA": "Стандартний (720p/1080p)", @@ -4570,10 +5460,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "2배(1440p/2160p)", - "no_NO": "2x (1440p/2160p)", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4594,10 +5485,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "3배(2160p/3240p)", - "no_NO": "3x (2160p/3240p)", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4620,8 +5512,9 @@ "ko_KR": "4배(2880p/4320p) (권장하지 않음)", "no_NO": "4x (2880p/4320p) (anbefales ikke)", "pl_PL": "4x (2880p/4320p) (niezalecane)", - "pt_BR": "4x (2880p/4320p) (não recomendado)", + "pt_BR": "4x (2880p/4320p) (Não recomendado)", "ru_RU": "4x (2880p/4320p) (не рекомендуется)", + "sv_SE": "4x (2880p/4320p) (rekommenderas inte)", "th_TH": "4x (2880p/4320p) (ไม่แนะนำ)", "tr_TR": "4x (2880p/4320p) (Tavsiye Edilmez)", "uk_UA": "4x (2880p/4320p) (Не рекомендується)", @@ -4644,8 +5537,9 @@ "ko_KR": "종횡비 :", "no_NO": "Bildeformat", "pl_PL": "Format obrazu:", - "pt_BR": "Proporção:", + "pt_BR": "Proporção da Tela:", "ru_RU": "Соотношение сторон:", + "sv_SE": "Bildförhållande:", "th_TH": "อัตราส่วนภาพ:", "tr_TR": "En-Boy Oranı:", "uk_UA": "Співвідношення сторін:", @@ -4666,10 +5560,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "4:3", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4690,10 +5585,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "16:9", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4714,10 +5610,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "16:10", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4738,10 +5635,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "21:9", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4762,10 +5660,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "32:9", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4788,8 +5687,9 @@ "ko_KR": "창에 맞춰 늘리기", "no_NO": "Strekk for og Tilpasse vindu", "pl_PL": "Rozciągnij do Okna", - "pt_BR": "Esticar até caber", + "pt_BR": "Esticar até Caber", "ru_RU": "Растянуть до размеров окна", + "sv_SE": "Sträck ut för att passa fönster", "th_TH": "ยืดภาพเพื่อให้พอดีกับหน้าต่าง", "tr_TR": "Pencereye Sığdırmak İçin Genişlet", "uk_UA": "Розтягнути до розміру вікна", @@ -4814,6 +5714,7 @@ "pl_PL": "Opcje programisty", "pt_BR": "Opções do desenvolvedor", "ru_RU": "Параметры разработчика", + "sv_SE": "Utvecklarinställningar", "th_TH": "ตัวเลือกนักพัฒนา", "tr_TR": "Geliştirici Seçenekleri", "uk_UA": "Параметри розробника", @@ -4836,8 +5737,9 @@ "ko_KR": "그래픽 셰이더 덤프 경로 :", "no_NO": "Grafikk Shader Dump bane:", "pl_PL": "Ścieżka do zgranych cieni graficznych:", - "pt_BR": "Diretório para despejo de shaders:", + "pt_BR": "Diretório para Despejo de Shaders:", "ru_RU": "Путь дампа графических шейдеров", + "sv_SE": "Sökväg för Graphics Shader Dump:", "th_TH": "ที่เก็บ ดัมพ์ไฟล์ แสงเงา:", "tr_TR": "Grafik Shader Döküm Yolu:", "uk_UA": "Шлях скидання графічного шейдера:", @@ -4858,10 +5760,11 @@ "it_IT": "Log", "ja_JP": "ロギング", "ko_KR": "로그 기록", - "no_NO": "Logging", + "no_NO": "", "pl_PL": "Dziennik zdarzeń", "pt_BR": "Log", "ru_RU": "Журналирование", + "sv_SE": "Loggning", "th_TH": "ประวัติ", "tr_TR": "Loglama", "uk_UA": "Налагодження", @@ -4882,10 +5785,11 @@ "it_IT": "Log", "ja_JP": "ロギング", "ko_KR": "로그 기록", - "no_NO": "Logging", + "no_NO": "", "pl_PL": "Dziennik zdarzeń", "pt_BR": "Log", "ru_RU": "Журналирование", + "sv_SE": "Loggning", "th_TH": "ประวัติ", "tr_TR": "Loglama", "uk_UA": "Налагодження", @@ -4908,13 +5812,14 @@ "ko_KR": "파일에 로그 기록 활성화", "no_NO": "Aktiver logging til fil", "pl_PL": "Włącz rejestrowanie zdarzeń do pliku", - "pt_BR": "Salvar logs em arquivo", + "pt_BR": "Salvar Logs em Arquivo", "ru_RU": "Включить запись в файл", + "sv_SE": "Aktivera loggning till fil", "th_TH": "เปิดใช้งานการบันทึกประวัติ ไปยังไฟล์", "tr_TR": "Logları Dosyaya Kaydetmeyi Etkinleştir", "uk_UA": "Увімкнути налагодження у файл", "zh_CN": "将日志写入文件", - "zh_TW": "啟用日誌到檔案" + "zh_TW": "啟用日誌寫入到檔案" } }, { @@ -4932,8 +5837,9 @@ "ko_KR": "조각 기록 활성화", "no_NO": "Aktiver Stub-logger", "pl_PL": "Wlącz Skróty Logów", - "pt_BR": "Habilitar logs de stub", + "pt_BR": "Habilitar logs de Stub", "ru_RU": "Включить журнал-заглушку", + "sv_SE": "Aktivera stubbloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติ", "tr_TR": "Stub Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали заглушки", @@ -4956,8 +5862,9 @@ "ko_KR": "정보 기록 활성화", "no_NO": "Aktiver informasjonslogger", "pl_PL": "Włącz Logi Informacyjne", - "pt_BR": "Habilitar logs de informação", + "pt_BR": "Habilitar logs de Informação", "ru_RU": "Включить информационный журнал", + "sv_SE": "Aktivera informationsloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติการใช้งาน", "tr_TR": "Bilgi Loglarını Etkinleştir", "uk_UA": "Увімкнути інформаційні журнали", @@ -4980,8 +5887,9 @@ "ko_KR": "경고 기록 활성화", "no_NO": "Aktiver varsellogger", "pl_PL": "Włącz Logi Ostrzeżeń", - "pt_BR": "Habilitar logs de alerta", + "pt_BR": "Habilitar Logs de Alerta", "ru_RU": "Включить журнал предупреждений", + "sv_SE": "Aktivera varningsloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติคำเตือน", "tr_TR": "Uyarı Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали попереджень", @@ -5004,8 +5912,9 @@ "ko_KR": "오류 기록 활성화", "no_NO": "Aktiver feillogger", "pl_PL": "Włącz Logi Błędów", - "pt_BR": "Habilitar logs de erro", + "pt_BR": "Habilitar Logs de Erro", "ru_RU": "Включить журнал ошибок", + "sv_SE": "Aktivera felloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติข้อผิดพลาด", "tr_TR": "Hata Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали помилок", @@ -5028,8 +5937,9 @@ "ko_KR": "추적 기록 활성화", "no_NO": "Aktiver spor logger", "pl_PL": "Włącz Logi Śledzenia", - "pt_BR": "Habilitar logs de rastreamento", + "pt_BR": "Habilitar Logs de Rastreamento", "ru_RU": "Включить журнал трассировки", + "sv_SE": "Aktivera spårloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติการติดตาม", "tr_TR": "Trace Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали трасування", @@ -5052,8 +5962,9 @@ "ko_KR": "방문 기록 활성화", "no_NO": "Aktiver gjestelogger", "pl_PL": "Włącz Logi Gości", - "pt_BR": "Habilitar logs do programa convidado", + "pt_BR": "Habilitar Logs de Convidados", "ru_RU": "Включить гостевые журналы", + "sv_SE": "Aktivera gästloggar", "th_TH": "เปิดใช้งานการบันทึกประวัติผู้เยี่ยมชม", "tr_TR": "Guest Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали гостей", @@ -5061,6 +5972,31 @@ "zh_TW": "啟用客體日誌" } }, + { + "ID": "SettingsTabLoggingEnableAvaloniaLogs", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Enable UI Logs", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Aktivere UI-logger", + "pl_PL": "", + "pt_BR": "Habilitar Logs da IU", + "ru_RU": "Включить журнал интерфейса", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Увімкнути журнали інтерфейсу", + "zh_CN": "启用 UI 日志", + "zh_TW": "" + } + }, { "ID": "SettingsTabLoggingEnableFsAccessLogs", "Translations": { @@ -5076,11 +6012,12 @@ "ko_KR": "파일 시스템 접속 기록 활성화", "no_NO": "Aktiver Fs tilgangslogger", "pl_PL": "Włącz Logi Dostępu do Systemu Plików", - "pt_BR": "Habilitar logs de acesso ao sistema de arquivos", + "pt_BR": "Habilitar Logs de Acesso Fs", "ru_RU": "Включить журналы доступа файловой системы", + "sv_SE": "Aktivera loggar för filsystemsåtkomst", "th_TH": "เปิดใช้งานการบันทึกประวัติการเข้าถึง Fs", "tr_TR": "Fs Erişim Loglarını Etkinleştir", - "uk_UA": "Увімкнути журнали доступу Fs", + "uk_UA": "Увімкнути журнали доступу до файлової системи", "zh_CN": "启用文件访问日志", "zh_TW": "啟用檔案系統存取日誌" } @@ -5100,11 +6037,12 @@ "ko_KR": "파일 시스템 전역 접속 로그 모드 :", "no_NO": "Fs Global Access-logg-modus:", "pl_PL": "Tryb globalnego dziennika zdarzeń systemu plików:", - "pt_BR": "Modo global de logs do sistema de arquivos:", + "pt_BR": "Modo de Log de Acesso Global Fs:", "ru_RU": "Режим журнала глобального доступа файловой системы:", + "sv_SE": "Loggläge för global filsystemsåtkomst:", "th_TH": "โหมด การเข้าถึงประวัติส่วนกลาง:", "tr_TR": "Fs Evrensel Erişim Log Modu:", - "uk_UA": "Режим журналу глобального доступу Fs:", + "uk_UA": "Режим журналу глобального доступу файлової системи:", "zh_CN": "文件系统全局访问日志模式:", "zh_TW": "檔案系統全域存取日誌模式:" } @@ -5124,8 +6062,9 @@ "ko_KR": "개발자 옵션", "no_NO": "Utvikleralternativer", "pl_PL": "Opcje programisty (UWAGA: wpływa na wydajność)", - "pt_BR": "Opções do desenvolvedor (AVISO: Vai reduzir a performance)", + "pt_BR": "Opções do desenvolvedor", "ru_RU": "Параметры разработчика", + "sv_SE": "Utvecklarinställningar", "th_TH": "ตัวเลือกนักพัฒนา", "tr_TR": "Geliştirici Seçenekleri (UYARI: Performansı düşürecektir)", "uk_UA": "Параметри розробника (УВАГА: шкодить продуктивності!)", @@ -5143,16 +6082,17 @@ "es_ES": "ADVERTENCIA: Reducirá el rendimiento", "fr_FR": "ATTENTION : Réduira les performances", "he_IL": "אזהרה: יפחית ביצועים", - "it_IT": "ATTENZIONE: ridurrà le prestazioni", + "it_IT": "ATTENZIONE: ridurranno le prestazioni", "ja_JP": "警告: パフォーマンスを低下させます", "ko_KR": "경고 : 성능이 감소합니다.", "no_NO": "Advarsel: Vil redusere ytelsen", "pl_PL": "UWAGA: Pogrorszy wydajność", "pt_BR": "AVISO: Reduzirá o desempenho", "ru_RU": "ВНИМАНИЕ: эти настройки снижают производительность", + "sv_SE": "VARNING: Kommer att reducera prestandan", "th_TH": "คำเตือน: จะทำให้ประสิทธิภาพลดลง", "tr_TR": "UYARI: Oyun performansı azalacak", - "uk_UA": "УВАГА: Зміна параметрів нижче негативно впливає на продуктивність", + "uk_UA": "УВАГА: Зміна параметрів нижче має негативний вплив на продуктивність", "zh_CN": "警告:会降低模拟器性能", "zh_TW": "警告: 會降低效能" } @@ -5172,11 +6112,12 @@ "ko_KR": "그래픽 후단부 기록 레벨 :", "no_NO": "Grafikk Backend-loggnivå:", "pl_PL": "Poziom rejestrowania do dziennika zdarzeń Backendu Graficznego:", - "pt_BR": "Nível de log do backend gráfico:", + "pt_BR": "Nível de Log do Renderizador Gráfico:", "ru_RU": "Уровень журнала бэкенда графики:", + "sv_SE": "Loggnivå för grafikbakände:", "th_TH": "ระดับการบันทึกประวัติ กราฟิกเบื้องหลัง:", "tr_TR": "Grafik Arka Uç Günlük Düzeyi", - "uk_UA": "Рівень журналу графічного сервера:", + "uk_UA": "Рівень журналу графічного бекенда:", "zh_CN": "图形引擎日志级别:", "zh_TW": "圖形後端日誌等級:" } @@ -5198,6 +6139,7 @@ "pl_PL": "Nic", "pt_BR": "Nenhum", "ru_RU": "Нет", + "sv_SE": "Ingen", "th_TH": "ไม่มี", "tr_TR": "Hiçbiri", "uk_UA": "Немає", @@ -5222,6 +6164,7 @@ "pl_PL": "Błędy", "pt_BR": "Erro", "ru_RU": "Ошибка", + "sv_SE": "Fel", "th_TH": "ผิดพลาด", "tr_TR": "Hata", "uk_UA": "Помилка", @@ -5246,6 +6189,7 @@ "pl_PL": "Spowolnienia", "pt_BR": "Lentidão", "ru_RU": "Замедления", + "sv_SE": "Långsamheter", "th_TH": "ช้าลง", "tr_TR": "Yavaşlamalar", "uk_UA": "Уповільнення", @@ -5270,6 +6214,7 @@ "pl_PL": "Wszystko", "pt_BR": "Todos", "ru_RU": "Всё", + "sv_SE": "Alla", "th_TH": "ทั้งหมด", "tr_TR": "Hepsi", "uk_UA": "Все", @@ -5292,8 +6237,9 @@ "ko_KR": "디버그 기록 활성화", "no_NO": "Aktiver feilsøkingslogger", "pl_PL": "Włącz dzienniki zdarzeń do debugowania", - "pt_BR": "Habilitar logs de depuração", + "pt_BR": "Habilitar Logs de Depuração", "ru_RU": "Включить журнал отладки", + "sv_SE": "Aktivera felsökningsloggar", "th_TH": "เปิดใช้งาน ประวัติข้อบกพร่อง", "tr_TR": "Hata Ayıklama Loglarını Etkinleştir", "uk_UA": "Увімкнути журнали налагодження", @@ -5311,16 +6257,17 @@ "es_ES": "Entrada", "fr_FR": "Contrôles", "he_IL": "קלט", - "it_IT": "", + "it_IT": "Comandi", "ja_JP": "入力", "ko_KR": "입력", "no_NO": "Inndata", "pl_PL": "Sterowanie", "pt_BR": "Controle", "ru_RU": "Управление", + "sv_SE": "Inmatning", "th_TH": "ป้อนข้อมูล", "tr_TR": "Giriş Yöntemi", - "uk_UA": "Введення", + "uk_UA": "Керування", "zh_CN": "输入", "zh_TW": "輸入" } @@ -5340,8 +6287,9 @@ "ko_KR": "도킹 모드", "no_NO": "Forankret modus", "pl_PL": "Tryb zadokowany", - "pt_BR": "Habilitar modo TV", + "pt_BR": "Modo TV", "ru_RU": "Стационарный режим", + "sv_SE": "Dockat läge", "th_TH": "ด็อกโหมด", "tr_TR": "Docked Modu Etkinleştir", "uk_UA": "Режим док-станції", @@ -5364,8 +6312,9 @@ "ko_KR": "키보드 직접 접속", "no_NO": "Direkte tastaturtilgang", "pl_PL": "Bezpośredni dostęp do klawiatury", - "pt_BR": "Acesso direto ao teclado", + "pt_BR": "Acesso Direto ao Teclado", "ru_RU": "Прямой ввод клавиатуры", + "sv_SE": "Direkt tangentbordsåtkomst", "th_TH": "เข้าถึงคีย์บอร์ดโดยตรง", "tr_TR": "Doğrudan Klavye Erişimi", "uk_UA": "Прямий доступ з клавіатури", @@ -5390,6 +6339,7 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", + "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -5414,6 +6364,7 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", + "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -5421,12 +6372,62 @@ "zh_TW": "關閉" } }, + { + "ID": "SettingsButtonReset", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Reset Settings", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Tilbakestill innstillinger", + "pl_PL": "", + "pt_BR": "Redefinir Configurações", + "ru_RU": "Сбросить настройки", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Скинути налаштування", + "zh_CN": "重置设置", + "zh_TW": "" + } + }, + { + "ID": "SettingsButtonResetConfirm", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "I want to reset my settings.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Jeg vil tilbakestille innstillingene mine.", + "pl_PL": "", + "pt_BR": "Quero redefinir minhas configurações.", + "ru_RU": "Я хочу сбросить свои настройки.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Я хочу скинути налаштування.", + "zh_CN": "我要重置我的设置。", + "zh_TW": "" + } + }, { "ID": "SettingsButtonOk", "Translations": { "ar_SA": "موافق", "de_DE": "", - "el_GR": "ΟΚ", + "el_GR": "", "en_US": "OK", "es_ES": "Aceptar", "fr_FR": "", @@ -5434,13 +6435,14 @@ "it_IT": "", "ja_JP": "", "ko_KR": "확인", - "no_NO": "OK", + "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "Ок", + "ru_RU": "", + "sv_SE": "Ok", "th_TH": "ตกลง", "tr_TR": "Tamam", - "uk_UA": "Гаразд", + "uk_UA": "", "zh_CN": "确定", "zh_TW": "確定" } @@ -5462,6 +6464,7 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", + "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -5486,6 +6489,7 @@ "pl_PL": "Zastosuj", "pt_BR": "Aplicar", "ru_RU": "Применить", + "sv_SE": "Verkställ", "th_TH": "นำไปใช้", "tr_TR": "Uygula", "uk_UA": "Застосувати", @@ -5510,6 +6514,7 @@ "pl_PL": "Gracz", "pt_BR": "Jogador", "ru_RU": "Игрок", + "sv_SE": "Spelare", "th_TH": "ผู้เล่น", "tr_TR": "Oyuncu", "uk_UA": "Гравець", @@ -5534,6 +6539,7 @@ "pl_PL": "Gracz 1", "pt_BR": "Jogador 1", "ru_RU": "Игрок 1", + "sv_SE": "Spelare 1", "th_TH": "ผู้เล่นคนที่ 1", "tr_TR": "Oyuncu 1", "uk_UA": "Гравець 1", @@ -5558,6 +6564,7 @@ "pl_PL": "Gracz 2", "pt_BR": "Jogador 2", "ru_RU": "Игрок 2", + "sv_SE": "Spelare 2", "th_TH": "ผู้เล่นคนที่ 2", "tr_TR": "Oyuncu 2", "uk_UA": "Гравець 2", @@ -5582,6 +6589,7 @@ "pl_PL": "Gracz 3", "pt_BR": "Jogador 3", "ru_RU": "Игрок 3", + "sv_SE": "Spelare 3", "th_TH": "ผู้เล่นคนที่ 3", "tr_TR": "Oyuncu 3", "uk_UA": "Гравець 3", @@ -5606,6 +6614,7 @@ "pl_PL": "Gracz 4", "pt_BR": "Jogador 4", "ru_RU": "Игрок 4", + "sv_SE": "Spelare 4", "th_TH": "ผู้เล่นคนที่ 4", "tr_TR": "Oyuncu 4", "uk_UA": "Гравець 4", @@ -5630,6 +6639,7 @@ "pl_PL": "Gracz 5", "pt_BR": "Jogador 5", "ru_RU": "Игрок 5", + "sv_SE": "Spelare 5", "th_TH": "ผู้เล่นคนที่ 5", "tr_TR": "Oyuncu 5", "uk_UA": "Гравець 5", @@ -5654,6 +6664,7 @@ "pl_PL": "Gracz 6", "pt_BR": "Jogador 6", "ru_RU": "Игрок 6", + "sv_SE": "Spelare 6", "th_TH": "ผู้เล่นคนที่ 6", "tr_TR": "Oyuncu 6", "uk_UA": "Гравець 6", @@ -5678,6 +6689,7 @@ "pl_PL": "Gracz 7", "pt_BR": "Jogador 7", "ru_RU": "Игрок 7", + "sv_SE": "Spelare 7", "th_TH": "ผู้เล่นคนที่ 7", "tr_TR": "Oyuncu 7", "uk_UA": "Гравець 7", @@ -5702,6 +6714,7 @@ "pl_PL": "Gracz 8", "pt_BR": "Jogador 8", "ru_RU": "Игрок 8", + "sv_SE": "Spelare 8", "th_TH": "ผู้เล่นคนที่ 8", "tr_TR": "Oyuncu 8", "uk_UA": "Гравець 8", @@ -5726,6 +6739,7 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный", + "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์โหมด", "tr_TR": "Portatif Mod", "uk_UA": "Портативний", @@ -5748,8 +6762,9 @@ "ko_KR": "입력 장치", "no_NO": "Inndataenhet", "pl_PL": "Urządzenie wejściowe", - "pt_BR": "Dispositivo de entrada", + "pt_BR": "Dispositivo de Entrada", "ru_RU": "Устройство ввода", + "sv_SE": "Inmatningsenhet", "th_TH": "อุปกรณ์ป้อนข้อมูล", "tr_TR": "Giriş Cihazı", "uk_UA": "Пристрій введення", @@ -5774,6 +6789,7 @@ "pl_PL": "Odśwież", "pt_BR": "Atualizar", "ru_RU": "Обновить", + "sv_SE": "Uppdatera", "th_TH": "รีเฟรช", "tr_TR": "Yenile", "uk_UA": "Оновити", @@ -5798,6 +6814,7 @@ "pl_PL": "Wyłączone", "pt_BR": "Desabilitado", "ru_RU": "Отключить", + "sv_SE": "Inaktiverad", "th_TH": "ปิดการใช้งาน", "tr_TR": "Devre Dışı", "uk_UA": "Вимкнено", @@ -5820,8 +6837,9 @@ "ko_KR": "컨트롤러 유형", "no_NO": "Kontrollertype", "pl_PL": "Typ kontrolera", - "pt_BR": "Tipo do controle", + "pt_BR": "Tipo de Controle", "ru_RU": "Тип контроллера", + "sv_SE": "Kontrollertyp", "th_TH": "ประเภทคอนโทรลเลอร์", "tr_TR": "Kumanda Tipi", "uk_UA": "Тип контролера", @@ -5846,6 +6864,7 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный", + "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์", "tr_TR": "Portatif Mod", "uk_UA": "Портативний", @@ -5870,9 +6889,10 @@ "pl_PL": "Pro Kontroler", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "โปรคอนโทรลเลอร์", "tr_TR": "Profesyonel Kumanda", - "uk_UA": "Контролер Pro", + "uk_UA": "Геймпад Nintendo Switch Pro", "zh_CN": "Pro 手柄", "zh_TW": "Pro 控制器" } @@ -5894,6 +6914,7 @@ "pl_PL": "Para JoyCon-ów", "pt_BR": "Par de JoyCon", "ru_RU": "JoyCon (пара)", + "sv_SE": "JoyCon (par)", "th_TH": "จับคู่ จอยคอน", "tr_TR": "JoyCon Çifti", "uk_UA": "Обидва JoyCon", @@ -5916,8 +6937,9 @@ "ko_KR": "좌측 조이콘", "no_NO": "JoyCon venstre", "pl_PL": "Lewy JoyCon", - "pt_BR": "JoyCon esquerdo", + "pt_BR": "JoyCon Esquerdo", "ru_RU": "JoyCon (левый)", + "sv_SE": "JoyCon vänster", "th_TH": "จอยคอน ด้านซ้าย", "tr_TR": "JoyCon Sol", "uk_UA": "Лівий JoyCon", @@ -5940,8 +6962,9 @@ "ko_KR": "우측 조이콘", "no_NO": "JoyCon høyre", "pl_PL": "Prawy JoyCon", - "pt_BR": "JoyCon direito", + "pt_BR": "JoyCon Direito", "ru_RU": "JoyCon (правый)", + "sv_SE": "JoyCon höger", "th_TH": "จอยคอน ด้านขวา", "tr_TR": "JoyCon Sağ", "uk_UA": "Правий JoyCon", @@ -5966,6 +6989,7 @@ "pl_PL": "Profil", "pt_BR": "Perfil", "ru_RU": "Профиль", + "sv_SE": "Profil", "th_TH": "โปรไฟล์", "tr_TR": "Profil", "uk_UA": "Профіль", @@ -5990,6 +7014,7 @@ "pl_PL": "Domyślny", "pt_BR": "Padrão", "ru_RU": "По умолчанию", + "sv_SE": "Standard", "th_TH": "ค่าเริ่มต้น", "tr_TR": "Varsayılan", "uk_UA": "Типовий", @@ -6014,6 +7039,7 @@ "pl_PL": "Wczytaj", "pt_BR": "Carregar", "ru_RU": "Загрузить", + "sv_SE": "Läs in", "th_TH": "โหลด", "tr_TR": "Yükle", "uk_UA": "Завантажити", @@ -6038,6 +7064,7 @@ "pl_PL": "Dodaj", "pt_BR": "Adicionar", "ru_RU": "Добавить", + "sv_SE": "Lägg till", "th_TH": "เพิ่ม", "tr_TR": "Ekle", "uk_UA": "Додати", @@ -6062,6 +7089,7 @@ "pl_PL": "Usuń", "pt_BR": "Remover", "ru_RU": "Удалить", + "sv_SE": "Ta bort", "th_TH": "เอาออก", "tr_TR": "Kaldır", "uk_UA": "Видалити", @@ -6086,6 +7114,7 @@ "pl_PL": "Przyciski", "pt_BR": "Botões", "ru_RU": "Кнопки", + "sv_SE": "Knappar", "th_TH": "ปุ่มกด", "tr_TR": "Tuşlar", "uk_UA": "Кнопки", @@ -6106,10 +7135,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "A", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6130,10 +7160,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "B", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6154,10 +7185,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "X", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6178,10 +7210,11 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "Y", + "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6206,6 +7239,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6230,6 +7264,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6252,8 +7287,9 @@ "ko_KR": "방향키", "no_NO": "Retningsfelt", "pl_PL": "Krzyżak (D-Pad)", - "pt_BR": "Direcional", - "ru_RU": "Кнопки направления", + "pt_BR": "Direcional (D-Pad)", + "ru_RU": "Кнопки направления (D-pad)", + "sv_SE": "Riktningsknappar", "th_TH": "ปุ่มลูกศร", "tr_TR": "Yön Tuşları", "uk_UA": "Панель направлення", @@ -6278,6 +7314,7 @@ "pl_PL": "Góra", "pt_BR": "Cima", "ru_RU": "Вверх", + "sv_SE": "Upp", "th_TH": "ขึ้น", "tr_TR": "Yukarı", "uk_UA": "Вгору", @@ -6302,6 +7339,7 @@ "pl_PL": "Dół", "pt_BR": "Baixo", "ru_RU": "Вниз", + "sv_SE": "Ner", "th_TH": "ลง", "tr_TR": "Aşağı", "uk_UA": "Вниз", @@ -6326,6 +7364,7 @@ "pl_PL": "Lewo", "pt_BR": "Esquerda", "ru_RU": "Влево", + "sv_SE": "Vänster", "th_TH": "ซ้าย", "tr_TR": "Sol", "uk_UA": "Вліво", @@ -6350,6 +7389,7 @@ "pl_PL": "Prawo", "pt_BR": "Direita", "ru_RU": "Вправо", + "sv_SE": "Höger", "th_TH": "ขวา", "tr_TR": "Sağ", "uk_UA": "Вправо", @@ -6374,11 +7414,12 @@ "pl_PL": "Przycisk", "pt_BR": "Botão", "ru_RU": "Нажатие на стик", + "sv_SE": "Knapp", "th_TH": "ปุ่ม", "tr_TR": "Tuş", "uk_UA": "Кнопка", "zh_CN": "按下摇杆", - "zh_TW": "按鍵" + "zh_TW": "搖桿按鍵" } }, { @@ -6398,6 +7439,7 @@ "pl_PL": "Góra ", "pt_BR": "Cima", "ru_RU": "Вверх", + "sv_SE": "Upp", "th_TH": "ขึ้น", "tr_TR": "Yukarı", "uk_UA": "Уверх", @@ -6422,6 +7464,7 @@ "pl_PL": "Dół ", "pt_BR": "Baixo", "ru_RU": "Вниз", + "sv_SE": "Ner", "th_TH": "ลง", "tr_TR": "Aşağı", "uk_UA": "Униз", @@ -6446,6 +7489,7 @@ "pl_PL": "Lewo", "pt_BR": "Esquerda", "ru_RU": "Влево", + "sv_SE": "Vänster", "th_TH": "ซ้าย", "tr_TR": "Sol", "uk_UA": "Ліворуч", @@ -6470,6 +7514,7 @@ "pl_PL": "Prawo", "pt_BR": "Direita", "ru_RU": "Вправо", + "sv_SE": "Höger", "th_TH": "ขวา", "tr_TR": "Sağ", "uk_UA": "Праворуч", @@ -6494,6 +7539,7 @@ "pl_PL": "Gałka", "pt_BR": "Analógico", "ru_RU": "Стик", + "sv_SE": "Spak", "th_TH": "จอยสติ๊ก", "tr_TR": "Analog", "uk_UA": "Стик", @@ -6516,8 +7562,9 @@ "ko_KR": "스틱 X축 반전", "no_NO": "Inverter Styrespak X", "pl_PL": "Odwróć gałkę X", - "pt_BR": "Inverter eixo X", + "pt_BR": "Inverter Eixo X", "ru_RU": "Инвертировать ось X", + "sv_SE": "Invertera Spak X", "th_TH": "กลับทิศทางของแกน X", "tr_TR": "X Eksenini Tersine Çevir", "uk_UA": "Обернути вісь стику X", @@ -6540,8 +7587,9 @@ "ko_KR": "스틱 Y축 반전", "no_NO": "Inverter Styrespak Y", "pl_PL": "Odwróć gałkę Y", - "pt_BR": "Inverter eixo Y", + "pt_BR": "Inverter Eixo Y", "ru_RU": "Инвертировать ось Y", + "sv_SE": "Invertera Spak Y", "th_TH": "กลับทิศทางของแกน Y", "tr_TR": "Y Eksenini Tersine Çevir", "uk_UA": "Обернути вісь стику Y", @@ -6564,8 +7612,9 @@ "ko_KR": "데드존 :", "no_NO": "Død sone:", "pl_PL": "Martwa strefa:", - "pt_BR": "Zona morta:", + "pt_BR": "Zona Morta:", "ru_RU": "Мёртвая зона:", + "sv_SE": "Dödläge:", "th_TH": "โซนที่ไม่ทำงานของ จอยสติ๊ก:", "tr_TR": "Ölü Bölge", "uk_UA": "Мертва зона:", @@ -6588,8 +7637,9 @@ "ko_KR": "좌측 스틱", "no_NO": "Venstre styrespak", "pl_PL": "Lewa Gałka", - "pt_BR": "Analógico esquerdo", + "pt_BR": "Analógico Esquerdo", "ru_RU": "Левый стик", + "sv_SE": "Vänster spak", "th_TH": "จอยสติ๊ก ด้านซ้าย", "tr_TR": "Sol Analog", "uk_UA": "Лівий джойстик", @@ -6612,8 +7662,9 @@ "ko_KR": "우측 스틱", "no_NO": "Høyre styrespak", "pl_PL": "Prawa Gałka", - "pt_BR": "Analógico direito", + "pt_BR": "Analógico Direito", "ru_RU": "Правый стик", + "sv_SE": "Höger spak", "th_TH": "จอยสติ๊ก ด้านขวา", "tr_TR": "Sağ Analog", "uk_UA": "Правий джойстик", @@ -6636,8 +7687,9 @@ "ko_KR": "좌측 트리거", "no_NO": "Utløsere venstre", "pl_PL": "Lewe Triggery", - "pt_BR": "Gatilhos esquerda", + "pt_BR": "Gatilho Esquerda", "ru_RU": "Триггеры слева", + "sv_SE": "Avtryckare vänster", "th_TH": "ทริกเกอร์ ด้านซ้าย", "tr_TR": "Tetikler Sol", "uk_UA": "Тригери ліворуч", @@ -6660,8 +7712,9 @@ "ko_KR": "우측 트리거", "no_NO": "Utløsere høyre", "pl_PL": "Prawe Triggery", - "pt_BR": "Gatilhos direita", + "pt_BR": "Gatilho Direita", "ru_RU": "Триггеры справа", + "sv_SE": "Avtryckare höger", "th_TH": "ทริกเกอร์ ด้านขวา", "tr_TR": "Tetikler Sağ", "uk_UA": "Тригери праворуч", @@ -6684,8 +7737,9 @@ "ko_KR": "좌측 트리거 버튼", "no_NO": "Utløserknapper Venstre", "pl_PL": "Lewe Przyciski Triggerów", - "pt_BR": "Botões de gatilho esquerda", + "pt_BR": "Botões de Gatilho da Esquerda", "ru_RU": "Триггерные кнопки слева", + "sv_SE": "Avtryckare knappar vänster", "th_TH": "ปุ่มทริกเกอร์ ด้านซ้าย", "tr_TR": "Tetik Tuşları Sol", "uk_UA": "Кнопки тригерів ліворуч", @@ -6708,8 +7762,9 @@ "ko_KR": "우측 트리거 버튼", "no_NO": "Utløserknapper høyre", "pl_PL": "Prawe Przyciski Triggerów", - "pt_BR": "Botões de gatilho direita", + "pt_BR": "Botões de Gatilho da Direita", "ru_RU": "Триггерные кнопки справа", + "sv_SE": "Avtryckare knappar höger", "th_TH": "ปุ่มทริกเกอร์ ด้านขวา", "tr_TR": "Tetik Tuşları Sağ", "uk_UA": "Кнопки тригерів праворуч", @@ -6734,6 +7789,7 @@ "pl_PL": "Triggery", "pt_BR": "Gatilhos", "ru_RU": "Триггеры", + "sv_SE": "Avtryckare", "th_TH": "ทริกเกอร์", "tr_TR": "Tetikler", "uk_UA": "Тригери", @@ -6758,6 +7814,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6782,6 +7839,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6806,6 +7864,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6830,6 +7889,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6854,6 +7914,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6878,6 +7939,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6902,6 +7964,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6926,6 +7989,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -6948,8 +8012,9 @@ "ko_KR": "좌측 버튼", "no_NO": "Knapper til venstre", "pl_PL": "Lewe Przyciski", - "pt_BR": "Botões esquerda", + "pt_BR": "Botões da Esquerda", "ru_RU": "Левые кнопки", + "sv_SE": "Knappar vänster", "th_TH": "ปุ่มกดเสริม ด้านซ้าย", "tr_TR": "Tuşlar Sol", "uk_UA": "Кнопки ліворуч", @@ -6972,8 +8037,9 @@ "ko_KR": "우측 버튼", "no_NO": "Knapper til høyre", "pl_PL": "Prawe Przyciski", - "pt_BR": "Botões direita", + "pt_BR": "Botões da Direita", "ru_RU": "Правые кнопки", + "sv_SE": "Knappar höger", "th_TH": "ปุ่มกดเสริม ด้านขวา", "tr_TR": "Tuşlar Sağ", "uk_UA": "Кнопки праворуч", @@ -6998,6 +8064,7 @@ "pl_PL": "Różne", "pt_BR": "Miscelâneas", "ru_RU": "Разное", + "sv_SE": "Diverse", "th_TH": "การควบคุมเพิ่มเติม", "tr_TR": "Diğer", "uk_UA": "Різне", @@ -7020,8 +8087,9 @@ "ko_KR": "트리거 임계값 :", "no_NO": "Utløser terskel:", "pl_PL": "Próg Triggerów:", - "pt_BR": "Sensibilidade do gatilho:", + "pt_BR": "Sensibilidade do Gatilho:", "ru_RU": "Порог срабатывания:", + "sv_SE": "Tröskelvärde avtryckare:", "th_TH": "ตั้งค่าขีดจำกัดการกด:", "tr_TR": "Tetik Eşiği:", "uk_UA": "Поріг спрацьовування:", @@ -7044,8 +8112,9 @@ "ko_KR": "모션", "no_NO": "Bevegelse", "pl_PL": "Ruch", - "pt_BR": "Sensor de movimento", + "pt_BR": "Sensor de Movimento", "ru_RU": "Движение", + "sv_SE": "Rörelse", "th_TH": "การเคลื่อนไหว", "tr_TR": "Hareket", "uk_UA": "Рух", @@ -7068,8 +8137,9 @@ "ko_KR": "CemuHook 호환 모션 사용", "no_NO": "Bruk CemuHook kompatibel bevegelse", "pl_PL": "Użyj ruchu zgodnego z CemuHook", - "pt_BR": "Usar sensor compatível com CemuHook", + "pt_BR": "Usar Sensor Compatível com CemuHook", "ru_RU": "Включить совместимость с CemuHook", + "sv_SE": "Använd CemuHook-kompatibel rörelse", "th_TH": "ใช้การเคลื่อนไหวที่เข้ากันได้กับ CemuHook", "tr_TR": "CemuHook uyumlu hareket kullan", "uk_UA": "Використовувати рух, сумісний з CemuHook", @@ -7092,8 +8162,9 @@ "ko_KR": "컨트롤러 슬롯 :", "no_NO": "Kontrollertype:", "pl_PL": "Slot Kontrolera:", - "pt_BR": "Slot do controle:", + "pt_BR": "Slot do Controle:", "ru_RU": "Слот контроллера:", + "sv_SE": "Kontrollerplats:", "th_TH": "ช่องเสียบ คอนโทรลเลอร์:", "tr_TR": "Kumanda Yuvası:", "uk_UA": "Слот контролера:", @@ -7116,8 +8187,9 @@ "ko_KR": "미러 입력", "no_NO": "Speilvend", "pl_PL": "Odzwierciedlaj Sterowanie", - "pt_BR": "Espelhar movimento", + "pt_BR": "Espelhar Movimento", "ru_RU": "Зеркальный ввод", + "sv_SE": "Spegla inmatning", "th_TH": "นำเข้าการสะท้อน การควบคุม", "tr_TR": "Girişi Aynala", "uk_UA": "Дзеркальний вхід", @@ -7140,8 +8212,9 @@ "ko_KR": "우측 조이콘 슬롯:", "no_NO": "Høyre JoyCon set:", "pl_PL": "Prawy Slot JoyCon:", - "pt_BR": "Slot do JoyCon direito:", + "pt_BR": "Slot do JoyCon Direito:", "ru_RU": "Слот правого JoyCon:", + "sv_SE": "Höger JoyCon-plats:", "th_TH": "ช่องเสียบ จอยคอน ด้านขวา:", "tr_TR": "Sağ JoyCon Yuvası:", "uk_UA": "Правий слот JoyCon:", @@ -7164,8 +8237,9 @@ "ko_KR": "서버 호스트 :", "no_NO": "Server Vert:", "pl_PL": "Host Serwera:", - "pt_BR": "Endereço do servidor:", + "pt_BR": "Endereço do Servidor:", "ru_RU": "Хост сервера:", + "sv_SE": "Servervärd:", "th_TH": "เจ้าของเซิร์ฟเวอร์:", "tr_TR": "Sunucu Sahibi:", "uk_UA": "Хост сервера:", @@ -7188,8 +8262,9 @@ "ko_KR": "자이로 감도 :", "no_NO": "Gyro følsomhet:", "pl_PL": "Czułość Żyroskopu:", - "pt_BR": "Sensibilidade do giroscópio:", + "pt_BR": "Sensibilidade do Giroscópio:", "ru_RU": "Чувствительность гироскопа:", + "sv_SE": "Känslighet för gyro:", "th_TH": "ความไวของ Gyro:", "tr_TR": "Gyro Hassasiyeti:", "uk_UA": "Чутливість гіроскопа:", @@ -7212,8 +8287,9 @@ "ko_KR": "자이로 데드존 :", "no_NO": "Gyro Dødsone:", "pl_PL": "Deadzone Żyroskopu:", - "pt_BR": "Zona morta do giroscópio:", + "pt_BR": "Zona Morta do Giroscópio:", "ru_RU": "Мертвая зона гироскопа:", + "sv_SE": "Dödläge för gyro:", "th_TH": "ส่วนไม่ทำงานของ Gyro:", "tr_TR": "Gyro Ölü Bölgesi:", "uk_UA": "Мертва зона гіроскопа:", @@ -7221,6 +8297,131 @@ "zh_TW": "陀螺儀無感帶:" } }, + { + "ID": "ControllerSettingsLed", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "LED", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "LED-подсветка", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "ControllerSettingsLedColorDisable", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Disable", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "비활성화", + "no_NO": "Deaktiver", + "pl_PL": "", + "pt_BR": "Desabilitar", + "ru_RU": "Отключить", + "sv_SE": "Inaktivera", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "关闭", + "zh_TW": "" + } + }, + { + "ID": "ControllerSettingsLedColorRainbow", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Rainbow", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "레인보우", + "no_NO": "Regnbue", + "pl_PL": "", + "pt_BR": "Arco-íris", + "ru_RU": "Радужная", + "sv_SE": "Regnbåge", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "彩虹", + "zh_TW": "" + } + }, + { + "ID": "ControllerSettingsLedColorRainbowSpeed", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Rainbow Speed", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "레인보우 속도", + "no_NO": "Regnbue Hastighet", + "pl_PL": "", + "pt_BR": "Velocidade do Arco-íris", + "ru_RU": "Скорость переливания", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "彩虹滚动速度", + "zh_TW": "" + } + }, + { + "ID": "ControllerSettingsLedColor", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Color", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "색상", + "no_NO": "Farge", + "pl_PL": "", + "pt_BR": "Cor", + "ru_RU": "Цвет", + "sv_SE": "Färg", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "颜色", + "zh_TW": "" + } + }, { "ID": "ControllerSettingsSave", "Translations": { @@ -7238,6 +8439,7 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", + "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -7262,6 +8464,7 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", + "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -7284,8 +8487,9 @@ "ko_KR": "알 수 없음", "no_NO": "Ukjent", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Desconhecido", "ru_RU": "Неизвестно", + "sv_SE": "Okänd", "th_TH": "ไม่รู้จัก", "tr_TR": "", "uk_UA": "Невідома", @@ -7308,8 +8512,9 @@ "ko_KR": "좌측 Shift", "no_NO": "Skift venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Shift Esquerdo", "ru_RU": "Левый Shift", + "sv_SE": "Skift vänster", "th_TH": "", "tr_TR": "Sol Shift", "uk_UA": "Shift Лівий", @@ -7332,8 +8537,9 @@ "ko_KR": "우측 Shift", "no_NO": "Skift høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Shift Direito", "ru_RU": "Правый Shift", + "sv_SE": "Skift höger", "th_TH": "", "tr_TR": "Sağ Shift", "uk_UA": "Shift Правий", @@ -7356,8 +8562,9 @@ "ko_KR": "좌측 Ctrl", "no_NO": "Ctrl venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Ctrl Esquerdo", "ru_RU": "Левый Ctrl", + "sv_SE": "Ctrl vänster", "th_TH": "", "tr_TR": "Sol Ctrl", "uk_UA": "Ctrl Лівий", @@ -7380,8 +8587,9 @@ "ko_KR": "좌측 ⌃", "no_NO": "⌃ Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌃ Esquerda", "ru_RU": "Левый ⌃", + "sv_SE": "^ Vänster", "th_TH": "", "tr_TR": "⌃ Sol", "uk_UA": "⌃ Лівий", @@ -7404,8 +8612,9 @@ "ko_KR": "우측 Ctrl", "no_NO": "Ctrl høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Ctrl Direito", "ru_RU": "Правый Ctrl", + "sv_SE": "Ctrl höger", "th_TH": "", "tr_TR": "Sağ Control", "uk_UA": "Ctrl Правий", @@ -7428,8 +8637,9 @@ "ko_KR": "우측 ⌃", "no_NO": "⌃ Høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌃ Direito", "ru_RU": "Правый ⌃", + "sv_SE": "^ Höger", "th_TH": "", "tr_TR": "⌃ Sağ", "uk_UA": "⌃ Правий", @@ -7452,8 +8662,9 @@ "ko_KR": "좌측 Alt", "no_NO": "Alt Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Alt Esquerdo", "ru_RU": "Левый Alt", + "sv_SE": "Alt vänster", "th_TH": "", "tr_TR": "Sol Alt", "uk_UA": "Alt Лівий", @@ -7476,8 +8687,9 @@ "ko_KR": "좌측 ⌥", "no_NO": "⌥ Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌥ Esquerda", "ru_RU": "Левый ⌥", + "sv_SE": "⌥ vänster", "th_TH": "", "tr_TR": "⌥ Sol", "uk_UA": "⌥ Лівий", @@ -7500,8 +8712,9 @@ "ko_KR": "우측 Alt", "no_NO": "Alt høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Alt Direito", "ru_RU": "Правый Alt", + "sv_SE": "Alt höger", "th_TH": "", "tr_TR": "Sağ Alt", "uk_UA": "Alt Правий", @@ -7524,8 +8737,9 @@ "ko_KR": "우측 ⌥", "no_NO": "⌥ Høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌥ Direito", "ru_RU": "Правый ⌥", + "sv_SE": "⌥ höger", "th_TH": "", "tr_TR": "⌥ Sağ", "uk_UA": "⌥ Правий", @@ -7548,8 +8762,9 @@ "ko_KR": "좌측 ⊞", "no_NO": "⊞ Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⊞ Esquerdo", "ru_RU": "Левый ⊞", + "sv_SE": "⊞ vänster", "th_TH": "", "tr_TR": "⊞ Sol", "uk_UA": "⊞ Лівий", @@ -7572,8 +8787,9 @@ "ko_KR": "좌측 ⌘", "no_NO": "⌘ Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌘ Esquerdo", "ru_RU": "Левый ⌘", + "sv_SE": "⌘ vänster", "th_TH": "", "tr_TR": "⌘ Sol", "uk_UA": "⌘ Лівий", @@ -7596,8 +8812,9 @@ "ko_KR": "우측 ⊞", "no_NO": "⊞ Høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⊞ Direito", "ru_RU": "Правый ⊞", + "sv_SE": "⊞ höger", "th_TH": "", "tr_TR": "⊞ Sağ", "uk_UA": "⊞ Правий", @@ -7620,8 +8837,9 @@ "ko_KR": "우측 ⌘", "no_NO": "⌘ Høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "⌘ Direito", "ru_RU": "Правый ⌘", + "sv_SE": "⌘ höger", "th_TH": "", "tr_TR": "⌘ Sağ", "uk_UA": "⌘ Правий", @@ -7646,11 +8864,12 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Меню", + "sv_SE": "Meny", "th_TH": "", "tr_TR": "Menü", - "uk_UA": "", + "uk_UA": "Меню", "zh_CN": "菜单键", - "zh_TW": "功能表" + "zh_TW": "功能表鍵" } }, { @@ -7668,11 +8887,12 @@ "ko_KR": "↑", "no_NO": "Opp", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Cima", "ru_RU": "Вверх", + "sv_SE": "Upp", "th_TH": "", "tr_TR": "Yukarı", - "uk_UA": "", + "uk_UA": "Вгору ↑", "zh_CN": "上", "zh_TW": "上" } @@ -7692,11 +8912,12 @@ "ko_KR": "↓", "no_NO": "Ned", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Baixo", "ru_RU": "Вниз", + "sv_SE": "Ner", "th_TH": "", "tr_TR": "Aşağı", - "uk_UA": "", + "uk_UA": "Вниз ↓", "zh_CN": "下", "zh_TW": "下" } @@ -7716,11 +8937,12 @@ "ko_KR": "←", "no_NO": "Venstre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Esquerda", "ru_RU": "Влево", + "sv_SE": "Vänster", "th_TH": "", "tr_TR": "Sol", - "uk_UA": "Вліво", + "uk_UA": "Вліво ←", "zh_CN": "左", "zh_TW": "左" } @@ -7740,11 +8962,12 @@ "ko_KR": "→", "no_NO": "Høyre", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Direita", "ru_RU": "Вправо", + "sv_SE": "Höger", "th_TH": "", "tr_TR": "Sağ", - "uk_UA": "Вправо", + "uk_UA": "Вправо →", "zh_CN": "右", "zh_TW": "右" } @@ -7766,6 +8989,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7788,8 +9012,9 @@ "ko_KR": "Esc", "no_NO": "Esc-tast", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Esc", + "ru_RU": "Esc", + "sv_SE": "", "th_TH": "", "tr_TR": "Esc", "uk_UA": "", @@ -7812,8 +9037,9 @@ "ko_KR": "스페이스", "no_NO": "Mellomrom", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Espaço", "ru_RU": "Пробел", + "sv_SE": "Blanksteg", "th_TH": "", "tr_TR": "", "uk_UA": "Пробіл", @@ -7838,6 +9064,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7862,6 +9089,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "Geri tuşu", "uk_UA": "", @@ -7886,6 +9114,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7910,6 +9139,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7934,6 +9164,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7958,6 +9189,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -7982,6 +9214,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8006,6 +9239,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8030,6 +9264,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8054,6 +9289,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8078,6 +9314,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8102,6 +9339,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8126,6 +9364,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8149,7 +9388,8 @@ "no_NO": "Tøm", "pl_PL": "", "pt_BR": "", - "ru_RU": "Очистить", + "ru_RU": "", + "sv_SE": "Töm", "th_TH": "", "tr_TR": "", "uk_UA": "Очистити", @@ -8173,10 +9413,11 @@ "no_NO": "Numerisk 0", "pl_PL": "", "pt_BR": "", - "ru_RU": "Блок цифр 0", + "ru_RU": "0 (цифровий блок)", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "Блок цифр 0", "zh_CN": "小键盘0", "zh_TW": "數字鍵 0" } @@ -8198,9 +9439,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 1", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "Блок цифр 1", "zh_CN": "小键盘1", "zh_TW": "數字鍵 1" } @@ -8222,9 +9464,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 2", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "2 (цифровий блок)", "zh_CN": "小键盘2", "zh_TW": "數字鍵 2" } @@ -8246,9 +9489,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 3", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "3 (цифровий блок)", "zh_CN": "小键盘3", "zh_TW": "數字鍵 3" } @@ -8270,9 +9514,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 4", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "4 (цифровий блок)", "zh_CN": "小键盘4", "zh_TW": "數字鍵 4" } @@ -8294,9 +9539,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 5", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "5 (цифровий блок)", "zh_CN": "小键盘5", "zh_TW": "數字鍵 5" } @@ -8318,9 +9564,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 6", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "6 (цифровий блок)", "zh_CN": "小键盘6", "zh_TW": "數字鍵 6" } @@ -8342,9 +9589,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 7", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "7 (цифровий блок)", "zh_CN": "小键盘7", "zh_TW": "數字鍵 7" } @@ -8366,9 +9614,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 8", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "8 (цифровий блок)", "zh_CN": "小键盘8", "zh_TW": "數字鍵 8" } @@ -8390,9 +9639,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Блок цифр 9", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "9 (цифровий блок)", "zh_CN": "小键盘9", "zh_TW": "數字鍵 9" } @@ -8414,9 +9664,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "/ (блок цифр)", + "sv_SE": "Keypad /", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "/ (цифровий блок)", "zh_CN": "小键盘/", "zh_TW": "數字鍵除號" } @@ -8438,9 +9689,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "* (блок цифр)", + "sv_SE": "Keypad *", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "* (цифровий блок)", "zh_CN": "小键盘*", "zh_TW": "數字鍵乘號" } @@ -8462,9 +9714,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "- (блок цифр)", + "sv_SE": "Keypad -", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "- (цифровий блок)", "zh_CN": "小键盘-", "zh_TW": "數字鍵減號" } @@ -8486,9 +9739,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "+ (блок цифр)", + "sv_SE": "Keypad +", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "+ (цифровий блок)", "zh_CN": "小键盘+", "zh_TW": "數字鍵加號" } @@ -8510,9 +9764,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": ". (блок цифр)", + "sv_SE": "Keypad ,", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": ". (цифровий блок)", "zh_CN": "小键盘.", "zh_TW": "數字鍵小數點" } @@ -8534,9 +9789,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Enter (блок цифр)", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "Enter (цифровий блок)", "zh_CN": "小键盘回车键", "zh_TW": "數字鍵 Enter" } @@ -8558,6 +9814,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8582,6 +9839,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8606,6 +9864,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8630,6 +9889,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8654,6 +9914,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8678,6 +9939,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8702,6 +9964,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8726,6 +9989,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8750,6 +10014,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8774,6 +10039,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8798,6 +10064,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8822,6 +10089,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8846,6 +10114,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8870,6 +10139,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8894,6 +10164,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8918,6 +10189,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8942,6 +10214,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8966,6 +10239,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8990,6 +10264,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9014,6 +10289,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9038,6 +10314,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9062,6 +10339,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9084,8 +10362,9 @@ "ko_KR": "연동 해제", "no_NO": "Ikke bundet", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Não Atribuído", "ru_RU": "Не привязано", + "sv_SE": "Obunden", "th_TH": "", "tr_TR": "", "uk_UA": "Відв'язати", @@ -9110,6 +10389,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Кнопка лев. стика", + "sv_SE": "L-spakknapp", "th_TH": "", "tr_TR": "", "uk_UA": "L Кнопка Стіку", @@ -9134,6 +10414,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Кнопка пр. стика", + "sv_SE": "R-spakknapp", "th_TH": "", "tr_TR": "", "uk_UA": "R Кнопка Стіку", @@ -9158,6 +10439,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый бампер", + "sv_SE": "Vänster kantknapp", "th_TH": "", "tr_TR": "", "uk_UA": "Лівий Бампер", @@ -9182,6 +10464,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый бампер", + "sv_SE": "Höger kantknapp", "th_TH": "", "tr_TR": "", "uk_UA": "Правий Бампер", @@ -9206,6 +10489,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер", + "sv_SE": "Vänster avtryckare", "th_TH": "", "tr_TR": "", "uk_UA": "Лівий Тригер", @@ -9230,6 +10514,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер", + "sv_SE": "Höger avtryckare", "th_TH": "", "tr_TR": "", "uk_UA": "Правий Тригер", @@ -9254,6 +10539,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вверх", + "sv_SE": "Upp", "th_TH": "", "tr_TR": "", "uk_UA": "Вверх", @@ -9278,6 +10564,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вниз", + "sv_SE": "Ner", "th_TH": "", "tr_TR": "", "uk_UA": "Вниз", @@ -9302,6 +10589,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Влево", + "sv_SE": "Vänster", "th_TH": "", "tr_TR": "", "uk_UA": "Вліво", @@ -9326,6 +10614,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Вправо", + "sv_SE": "Höger", "th_TH": "", "tr_TR": "Sağ", "uk_UA": "Вправо", @@ -9350,6 +10639,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -9374,6 +10664,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "4", "uk_UA": "", @@ -9391,16 +10682,17 @@ "es_ES": "", "fr_FR": "", "he_IL": "", - "it_IT": "", + "it_IT": "Guida", "ja_JP": "", "ko_KR": "가이드", "no_NO": "Veiledning", "pl_PL": "", "pt_BR": "", - "ru_RU": "Кнопка Xbox", + "ru_RU": "Кнопка меню", + "sv_SE": "", "th_TH": "", "tr_TR": "Rehber", - "uk_UA": "", + "uk_UA": "Меню", "zh_CN": "主页键", "zh_TW": "快顯功能表鍵" } @@ -9415,13 +10707,14 @@ "es_ES": "", "fr_FR": "Autre", "he_IL": "", - "it_IT": "", + "it_IT": "Altro", "ja_JP": "", "ko_KR": "기타", "no_NO": "Diverse", "pl_PL": "", "pt_BR": "", "ru_RU": "Прочее", + "sv_SE": "Diverse", "th_TH": "", "tr_TR": "Diğer", "uk_UA": "", @@ -9439,16 +10732,17 @@ "es_ES": "", "fr_FR": "Palette 1", "he_IL": "", - "it_IT": "", + "it_IT": "Tasto extra 1", "ja_JP": "", "ko_KR": "패들 1", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 1", + "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 1", - "uk_UA": "", + "uk_UA": "Додаткова кнопка 1", "zh_CN": "其他按键1", "zh_TW": "其他按鍵 1" } @@ -9463,16 +10757,17 @@ "es_ES": "", "fr_FR": "Palette 2", "he_IL": "", - "it_IT": "", + "it_IT": "Tasto extra 2", "ja_JP": "", "ko_KR": "패들 2", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 2", + "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 2", - "uk_UA": "", + "uk_UA": "Додаткова кнопка 2", "zh_CN": "其他按键2", "zh_TW": "其他按鍵 2" } @@ -9487,16 +10782,17 @@ "es_ES": "", "fr_FR": "Palette 3", "he_IL": "", - "it_IT": "", + "it_IT": "Tasto extra 3", "ja_JP": "", "ko_KR": "패들 3", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 3", + "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 3", - "uk_UA": "", + "uk_UA": "Додаткова кнопка 3", "zh_CN": "其他按键3", "zh_TW": "其他按鍵 3" } @@ -9511,16 +10807,17 @@ "es_ES": "", "fr_FR": "Palette 4", "he_IL": "", - "it_IT": "", + "it_IT": "Tasto extra 4", "ja_JP": "", "ko_KR": "패들 4", "no_NO": "", "pl_PL": "", "pt_BR": "", "ru_RU": "Доп.кнопка 4", + "sv_SE": "", "th_TH": "", "tr_TR": "Pedal 4", - "uk_UA": "", + "uk_UA": "Додаткова кнопка 4", "zh_CN": "其他按键4", "zh_TW": "其他按鍵 4" } @@ -9542,9 +10839,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Тачпад", + "sv_SE": "", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "Сенсорна панель", "zh_CN": "触摸板", "zh_TW": "觸控板" } @@ -9566,6 +10864,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер 0", + "sv_SE": "Vänster avtryckare 0", "th_TH": "", "tr_TR": "Sol Tetik 0", "uk_UA": "Лівий Тригер 0", @@ -9590,6 +10889,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер 0", + "sv_SE": "Höger avtryckare 0", "th_TH": "", "tr_TR": "Sağ Tetik 0", "uk_UA": "Правий Тригер 0", @@ -9614,6 +10914,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый триггер 1", + "sv_SE": "Vänster avtryckare 1", "th_TH": "", "tr_TR": "Sol Tetik 1", "uk_UA": "Лівий Тригер 1", @@ -9638,6 +10939,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый триггер 1", + "sv_SE": "Höger avtryckare 1", "th_TH": "", "tr_TR": "Sağ Tetik 1", "uk_UA": "Правий Тригер 1", @@ -9662,6 +10964,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Левый стик", + "sv_SE": "Vänster spak", "th_TH": "", "tr_TR": "Sol Çubuk", "uk_UA": "Лівий Стік", @@ -9686,6 +10989,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Правый стик", + "sv_SE": "Höger spak", "th_TH": "", "tr_TR": "Sağ çubuk", "uk_UA": "Правий Стік", @@ -9708,8 +11012,9 @@ "ko_KR": "선택된 사용자 프로필 :", "no_NO": "Valgt brukerprofil:", "pl_PL": "Wybrany profil użytkownika:", - "pt_BR": "Perfil de usuário selecionado:", + "pt_BR": "Perfil de Usuário Selecionado:", "ru_RU": "Выбранный пользовательский профиль:", + "sv_SE": "Vald användarprofil:", "th_TH": "เลือกโปรไฟล์ผู้ใช้งาน:", "tr_TR": "Seçili Kullanıcı Profili:", "uk_UA": "Вибраний профіль користувача:", @@ -9732,8 +11037,9 @@ "ko_KR": "프로필 이름 저장", "no_NO": "Lagre profilnavnet", "pl_PL": "Zapisz nazwę profilu", - "pt_BR": "Salvar nome de perfil", + "pt_BR": "Salvar Nome de Perfil", "ru_RU": "Сохранить пользовательский профиль", + "sv_SE": "Spara profilnamn", "th_TH": "บันทึกชื่อโปรไฟล์", "tr_TR": "Profil İsmini Kaydet", "uk_UA": "Зберегти ім'я профілю", @@ -9756,8 +11062,9 @@ "ko_KR": "프로필 이미지 변경", "no_NO": "Endre profilbilde", "pl_PL": "Zmień obrazek profilu", - "pt_BR": "Mudar imagem de perfil", + "pt_BR": "Mudar Imagem de Perfil", "ru_RU": "Изменить аватар", + "sv_SE": "Byt profilbild", "th_TH": "เปลี่ยนรูปโปรไฟล์", "tr_TR": "Profil Resmini Değiştir", "uk_UA": "Змінити зображення профілю", @@ -9780,8 +11087,9 @@ "ko_KR": "사용 가능한 사용자 프로필 :", "no_NO": "Tilgjengelige brukerprofiler:", "pl_PL": "Dostępne profile użytkownika:", - "pt_BR": "Perfis de usuário disponíveis:", + "pt_BR": "Perfis de Usuário Disponíveis:", "ru_RU": "Доступные профили пользователей:", + "sv_SE": "Tillgängliga användarprofiler:", "th_TH": "โปรไฟล์ผู้ใช้ที่ใช้งานได้:", "tr_TR": "Mevcut Kullanıcı Profilleri:", "uk_UA": "Доступні профілі користувачів:", @@ -9804,8 +11112,9 @@ "ko_KR": "프로필 만들기", "no_NO": "Opprett Profil", "pl_PL": "Utwórz profil", - "pt_BR": "Adicionar novo perfil", + "pt_BR": "Criar Perfil", "ru_RU": "Добавить новый профиль", + "sv_SE": "Skapa profil", "th_TH": "สร้างโปรไฟล์ใหม่", "tr_TR": "Yeni Profil Ekle", "uk_UA": "Створити профіль", @@ -9830,6 +11139,7 @@ "pl_PL": "Usuń", "pt_BR": "Apagar", "ru_RU": "Удалить", + "sv_SE": "Ta bort", "th_TH": "ลบ", "tr_TR": "Sil", "uk_UA": "Видалити", @@ -9854,6 +11164,7 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", + "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -9876,8 +11187,9 @@ "ko_KR": "별명 선택", "no_NO": "Velg ett kallenavn", "pl_PL": "Wybierz pseudonim", - "pt_BR": "Escolha um apelido", - "ru_RU": "Укажите никнейм", + "pt_BR": "Escolha um Apelido", + "ru_RU": "Введите никнейм", + "sv_SE": "Välj ett smeknamn", "th_TH": "เลือก ชื่อเล่น", "tr_TR": "Kullanıcı Adı Seç", "uk_UA": "Оберіть псевдонім", @@ -9900,8 +11212,9 @@ "ko_KR": "프로필 이미지 선택", "no_NO": "Valg av profilbilde", "pl_PL": "Wybór Obrazu Profilu", - "pt_BR": "Seleção da imagem de perfil", + "pt_BR": "Seleção da Imagem de Perfil", "ru_RU": "Выбор изображения профиля", + "sv_SE": "Välj profilbild", "th_TH": "เลือก รูปโปรไฟล์ ของคุณ", "tr_TR": "Profil Resmi Seçimi", "uk_UA": "Вибір зображення профілю", @@ -9924,8 +11237,9 @@ "ko_KR": "프로필 이미지를 선택", "no_NO": "Velg et profilbilde", "pl_PL": "Wybierz zdjęcie profilowe", - "pt_BR": "Escolha uma imagem de perfil", + "pt_BR": "Escolha uma Imagem de Perfil", "ru_RU": "Выбор аватара", + "sv_SE": "Välj en profilbild", "th_TH": "เลือก รูปโปรไฟล์", "tr_TR": "Profil Resmi Seç", "uk_UA": "Виберіть зображення профілю", @@ -9950,6 +11264,7 @@ "pl_PL": "Możesz zaimportować niestandardowy obraz profilu lub wybrać awatar z firmware'u systemowego", "pt_BR": "Você pode importar uma imagem customizada, ou selecionar um avatar do firmware", "ru_RU": "Вы можете импортировать собственное изображение или выбрать аватар из системной прошивки.", + "sv_SE": "Du kan importera en anpassad profilbild eller välja en avatar från systemets firmware", "th_TH": "คุณสามารถนำเข้ารูปโปรไฟล์ที่กำหนดเองได้ หรือ เลือกรูปที่มีจากระบบ", "tr_TR": "Özel bir profil resmi içeri aktarabilir veya sistem avatarlarından birini seçebilirsiniz", "uk_UA": "Ви можете імпортувати власне зображення профілю або вибрати аватар із мікропрограми системи", @@ -9972,8 +11287,9 @@ "ko_KR": "이미지 파일 가져오기", "no_NO": "Importer bildefil", "pl_PL": "Importuj Plik Obrazu", - "pt_BR": "Importar arquivo de imagem", + "pt_BR": "Importar Arquivo de Imagem", "ru_RU": "Импорт изображения", + "sv_SE": "Importera bildfil", "th_TH": "นำเข้า ไฟล์รูปภาพ", "tr_TR": "Resim İçeri Aktar", "uk_UA": "Імпорт файлу зображення", @@ -9996,8 +11312,9 @@ "ko_KR": "펌웨어 아바타 선택", "no_NO": "Velg fastvare profilbilde", "pl_PL": "Wybierz domyślny awatar z oprogramowania konsoli", - "pt_BR": "Selecionar avatar do firmware", + "pt_BR": "Selecionar Avatar do Firmware", "ru_RU": "Встроенные аватары", + "sv_SE": "Välj avatar från firmware", "th_TH": "เลือก รูปอวาต้า จากระบบ", "tr_TR": "Yazılım Avatarı Seç", "uk_UA": "Виберіть аватар прошивки ", @@ -10018,10 +11335,11 @@ "it_IT": "Finestra di input", "ja_JP": "入力ダイアログ", "ko_KR": "대화 상자 입력", - "no_NO": "", + "no_NO": "Dialogboksen Inndata", "pl_PL": "Okno Dialogowe Wprowadzania", "pt_BR": "Diálogo de texto", "ru_RU": "Диалоговое окно ввода", + "sv_SE": "Inmatningsdialog", "th_TH": "กล่องโต้ตอบการป้อนข้อมูล", "tr_TR": "Giriş Yöntemi Diyaloğu", "uk_UA": "Діалог введення", @@ -10046,9 +11364,10 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "ОК", + "sv_SE": "Ok", "th_TH": "ตกลง", "tr_TR": "Tamam", - "uk_UA": "Гаразд", + "uk_UA": "", "zh_CN": "完成", "zh_TW": "確定" } @@ -10070,6 +11389,7 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", + "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -10087,18 +11407,19 @@ "es_ES": "", "fr_FR": "Annulation en cours", "he_IL": "", - "it_IT": "Cancellando", + "it_IT": "Annullamento in corso", "ja_JP": "", "ko_KR": "취소하기", "no_NO": "Kansellerer", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Cancelando", + "ru_RU": "Отмена", + "sv_SE": "Avbryter", "th_TH": "", "tr_TR": "", "uk_UA": "Скасування", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "正在取消", + "zh_TW": "正在取消" } }, { @@ -10116,13 +11437,14 @@ "ko_KR": "닫기", "no_NO": "Lukk", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Fechar", + "ru_RU": "Закрыть", + "sv_SE": "Stäng", "th_TH": "", "tr_TR": "", "uk_UA": "Закрити", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "关闭", + "zh_TW": "關閉" } }, { @@ -10140,8 +11462,9 @@ "ko_KR": "프로필 이름 선택", "no_NO": "Velg profilnavnet", "pl_PL": "Wybierz nazwę profilu", - "pt_BR": "Escolha o nome de perfil", + "pt_BR": "Escolha o Nome de Perfil", "ru_RU": "Выберите никнейм", + "sv_SE": "Välj ett profilnamn", "th_TH": "เลือก ชื่อโปรไฟล์", "tr_TR": "Profil İsmini Seç", "uk_UA": "Виберіть ім'я профілю", @@ -10164,8 +11487,9 @@ "ko_KR": "프로필 이름을 입력", "no_NO": "Vennligst skriv inn et profilnavn", "pl_PL": "Wprowadź nazwę profilu", - "pt_BR": "Escreva o nome do perfil", + "pt_BR": "Escreva o Nome do Perfil", "ru_RU": "Пожалуйста, введите никнейм", + "sv_SE": "Ange ett profilnamn", "th_TH": "กรุณาใส่ชื่อโปรไฟล์", "tr_TR": "Lütfen Bir Profil İsmi Girin", "uk_UA": "Будь ласка, введіть ім'я профілю", @@ -10188,8 +11512,9 @@ "ko_KR": "(최대 길이 : {0})", "no_NO": "(Maks lengde: {0})", "pl_PL": "(Maksymalna długość: {0})", - "pt_BR": "(Máximo de caracteres: {0})", + "pt_BR": "(Máximo de Caracteres: {0})", "ru_RU": "(Максимальная длина: {0})", + "sv_SE": "(Max längd: {0})", "th_TH": "(ความยาวสูงสุด: {0})", "tr_TR": "(Maksimum Uzunluk: {0})", "uk_UA": "(Макс. довжина: {0})", @@ -10212,8 +11537,9 @@ "ko_KR": "아바타 선택", "no_NO": "Velg profilbilde", "pl_PL": "Wybierz awatar", - "pt_BR": "Escolher", + "pt_BR": "Escolha o Avatar", "ru_RU": "Выбрать аватар", + "sv_SE": "Välj avatar", "th_TH": "เลือก รูปอวาต้า ของคุณ", "tr_TR": "Seç", "uk_UA": "Вибрати", @@ -10236,8 +11562,9 @@ "ko_KR": "배경색 설정", "no_NO": "Angi bakgrunnsfarge", "pl_PL": "Ustaw kolor tła", - "pt_BR": "Definir cor de fundo", + "pt_BR": "Definir cor de Fundo", "ru_RU": "Установить цвет фона", + "sv_SE": "Välj bakgrundsfärg", "th_TH": "ตั้งค่าสีพื้นหลัง", "tr_TR": "Arka Plan Rengi Ayarla", "uk_UA": "Встановити колір фону", @@ -10262,6 +11589,7 @@ "pl_PL": "Zamknij", "pt_BR": "Fechar", "ru_RU": "Закрыть", + "sv_SE": "Stäng", "th_TH": "ปิด", "tr_TR": "Kapat", "uk_UA": "Закрити", @@ -10284,8 +11612,9 @@ "ko_KR": "프로필 불러오기", "no_NO": "Last inn profil", "pl_PL": "Wczytaj profil", - "pt_BR": "Carregar perfil", + "pt_BR": "Carregar Perfil", "ru_RU": "Загрузить профиль", + "sv_SE": "Läs in profil", "th_TH": "โหลด โปรไฟล์", "tr_TR": "Profil Yükle", "uk_UA": "Завантажити профіль", @@ -10308,13 +11637,14 @@ "ko_KR": "프로필 보기", "no_NO": "Se Profil", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Ver Perfil", + "ru_RU": "Показать профиль", + "sv_SE": "Visa profil", "th_TH": "", "tr_TR": "", "uk_UA": "Показати профіль", "zh_CN": "预览配置文件", - "zh_TW": "" + "zh_TW": "檢視設定檔" } }, { @@ -10332,8 +11662,9 @@ "ko_KR": "프로필 추가", "no_NO": "Legg til profil", "pl_PL": "Dodaj profil", - "pt_BR": "Adicionar perfil", + "pt_BR": "Adicionar Perfil", "ru_RU": "Добавить профиль", + "sv_SE": "Lägg till profil", "th_TH": "เพิ่ม โปรไฟล์", "tr_TR": "Profil Ekle", "uk_UA": "Додати профіль", @@ -10356,8 +11687,9 @@ "ko_KR": "프로필 삭제", "no_NO": "Fjern profil", "pl_PL": "Usuń profil", - "pt_BR": "Remover perfil", + "pt_BR": "Remover Perfil", "ru_RU": "Удалить профиль", + "sv_SE": "Ta bort profil", "th_TH": "ลบ โปรไฟล์", "tr_TR": "Profili Kaldır", "uk_UA": "Видалити профіль", @@ -10380,8 +11712,9 @@ "ko_KR": "프로필 추가", "no_NO": "Lagre Profil", "pl_PL": "Zapisz profil", - "pt_BR": "Salvar perfil", + "pt_BR": "Salvar Perfil", "ru_RU": "Сохранить профиль", + "sv_SE": "Spara profil", "th_TH": "บันทึก โปรไฟล์", "tr_TR": "Profili Kaydet", "uk_UA": "Зберегти профіль", @@ -10404,8 +11737,9 @@ "ko_KR": "스크린샷 찍기", "no_NO": "Ta skjermbilde", "pl_PL": "Zrób zrzut ekranu", - "pt_BR": "Salvar captura de tela", + "pt_BR": "Tirar Captura de tela", "ru_RU": "Сделать снимок экрана", + "sv_SE": "Ta skärmbild", "th_TH": "ถ่ายภาพหน้าจอ", "tr_TR": "Ekran Görüntüsü Al", "uk_UA": "Зробити знімок екрана", @@ -10430,6 +11764,7 @@ "pl_PL": "Ukryj interfejs użytkownika", "pt_BR": "Esconder Interface", "ru_RU": "Скрыть интерфейс", + "sv_SE": "Dölj gränssnittet", "th_TH": "ซ่อน UI", "tr_TR": "Arayüzü Gizle", "uk_UA": "Сховати інтерфейс", @@ -10454,9 +11789,10 @@ "pl_PL": "Uruchom aplikację ", "pt_BR": "Executar Aplicativo", "ru_RU": "Запуск приложения", + "sv_SE": "Kör applikation", "th_TH": "เปิดใช้งานแอปพลิเคชัน", "tr_TR": "Uygulamayı Çalıştır", - "uk_UA": "Запустити додаток", + "uk_UA": "Запустити", "zh_CN": "启动游戏", "zh_TW": "執行應用程式" } @@ -10476,11 +11812,12 @@ "ko_KR": "즐겨찾기 전환", "no_NO": "Vis/Skjul favoritter", "pl_PL": "Przełącz na ulubione", - "pt_BR": "Alternar favorito", + "pt_BR": "Marcar como Favorito", "ru_RU": "Добавить в избранное", + "sv_SE": "Växla som favorit", "th_TH": "สลับรายการโปรด", "tr_TR": "Favori Ayarla", - "uk_UA": "Перемкнути вибране", + "uk_UA": "Додати в обрані", "zh_CN": "收藏", "zh_TW": "加入/移除為我的最愛" } @@ -10500,11 +11837,12 @@ "ko_KR": "게임의 즐겨찾기 상태 전환", "no_NO": "Vis/Skjul favorittstatus for spillet", "pl_PL": "Przełącz status Ulubionej Gry", - "pt_BR": "Marca ou desmarca jogo como favorito", - "ru_RU": "Добавляет игру в избранное и помечает звездочкой", + "pt_BR": "Marca ou desmarca o jogo como favorito", + "ru_RU": "Добавляет игру в избранное и помечает звёздочкой", + "sv_SE": "Växla favoritstatus för spelet", "th_TH": "สลับสถานะเกมที่ชื่นชอบ", "tr_TR": "Oyunu Favorilere Ekle/Çıkar", - "uk_UA": "Перемкнути улюблений статус гри", + "uk_UA": "Додати або вилучити гру з обраних", "zh_CN": "切换游戏的收藏状态", "zh_TW": "切換遊戲的我的最愛狀態" } @@ -10526,6 +11864,7 @@ "pl_PL": "Motyw:", "pt_BR": "Tema:", "ru_RU": "Тема:", + "sv_SE": "Tema:", "th_TH": "ธีม:", "tr_TR": "Tema:", "uk_UA": "Тема:", @@ -10549,7 +11888,8 @@ "no_NO": "Automatisk", "pl_PL": "", "pt_BR": "Automático", - "ru_RU": "", + "ru_RU": "Авто", + "sv_SE": "Automatiskt", "th_TH": "อัตโนมัติ", "tr_TR": "", "uk_UA": "Авто.", @@ -10573,7 +11913,8 @@ "no_NO": "Mørk", "pl_PL": "Ciemny", "pt_BR": "Escuro", - "ru_RU": "Темная", + "ru_RU": "Тёмная", + "sv_SE": "Mörkt", "th_TH": "มืด", "tr_TR": "Karanlık", "uk_UA": "Темна", @@ -10598,6 +11939,7 @@ "pl_PL": "Jasny", "pt_BR": "Claro", "ru_RU": "Светлая", + "sv_SE": "Ljust", "th_TH": "สว่าง", "tr_TR": "Aydınlık", "uk_UA": "Світла", @@ -10622,6 +11964,7 @@ "pl_PL": "Konfiguruj", "pt_BR": "Configurar", "ru_RU": "Настройка", + "sv_SE": "Konfigurera", "th_TH": "กำหนดค่า", "tr_TR": "Ayarla", "uk_UA": "Налаштування", @@ -10646,6 +11989,7 @@ "pl_PL": "Wibracje", "pt_BR": "Vibração", "ru_RU": "Вибрация", + "sv_SE": "Vibration", "th_TH": "การสั่นไหว", "tr_TR": "Titreşim", "uk_UA": "Вібрація", @@ -10668,8 +12012,9 @@ "ko_KR": "강력한 진동 증폭기", "no_NO": "Sterk Vibrasjon multiplikator", "pl_PL": "Mnożnik mocnych wibracji", - "pt_BR": "Multiplicador de vibração forte", + "pt_BR": "Multiplicador de Vibração Forte", "ru_RU": "Множитель сильной вибрации", + "sv_SE": "Försvaga stark vibration", "th_TH": "เพิ่มความแรงการสั่น", "tr_TR": "Güçlü Titreşim Çoklayıcı", "uk_UA": "Множник сильної вібрації", @@ -10692,8 +12037,9 @@ "ko_KR": "약한 진동 증폭기", "no_NO": "Svak Vibrasjon multiplikator", "pl_PL": "Mnożnik słabych wibracji", - "pt_BR": "Multiplicador de vibração fraca", + "pt_BR": "Multiplicador de Vibração Fraca", "ru_RU": "Множитель слабой вибрации", + "sv_SE": "Förstärk svag vibration", "th_TH": "ลดความแรงการสั่น", "tr_TR": "Zayıf Titreşim Seviyesi", "uk_UA": "Множник слабкої вібрації", @@ -10718,10 +12064,11 @@ "pl_PL": "Nie ma zapisanych danych dla {0} [{1:x16}]", "pt_BR": "Não há jogos salvos para {0} [{1:x16}]", "ru_RU": "Нет сохранений для {0} [{1:x16}]", + "sv_SE": "Det finns inget sparat spel för {0} [{1:x16}]", "th_TH": "ไม่มีข้อมูลบันทึกไว้สำหรับ {0} [{1:x16}]", "tr_TR": "{0} [{1:x16}] için kayıt verisi bulunamadı", "uk_UA": "Немає збережених даних для {0} [{1:x16}]", - "zh_CN": "没有{0} [{1:x16}]的游戏存档", + "zh_CN": "没有 {0} [{1:x16}] 的游戏存档", "zh_TW": "沒有 {0} [{1:x16}] 的存檔" } }, @@ -10740,8 +12087,9 @@ "ko_KR": "이 게임의 저장 데이터를 만들겠습니까?", "no_NO": "Vil du lage lagrede data for dette spillet", "pl_PL": "Czy chcesz utworzyć zapis danych dla tej gry?", - "pt_BR": "Gostaria de criar o diretório de salvamento para esse jogo?", + "pt_BR": "Você gostaria de criar dados salvos para este jogo?", "ru_RU": "Создать сохранение для этой игры?", + "sv_SE": "Vill du skapa sparat spel för detta spel?", "th_TH": "คุณต้องการสร้างบันทึกข้อมูลสำหรับเกมนี้หรือไม่?", "tr_TR": "Bu oyun için kayıt verisi oluşturmak ister misiniz?", "uk_UA": "Хочете створити дані збереження для цієї гри?", @@ -10752,121 +12100,126 @@ { "ID": "DialogConfirmationTitle", "Translations": { - "ar_SA": "ريوجينكس - تأكيد", - "de_DE": "Ryujinx - Bestätigung", - "el_GR": "Ryujinx - Επιβεβαίωση", - "en_US": "Ryujinx - Confirmation", - "es_ES": "Ryujinx - Confirmación", + "ar_SA": "{0} - تأكيد", + "de_DE": "{0} - Bestätigung", + "el_GR": "{0} - Επιβεβαίωση", + "en_US": "{0} - Confirmation", + "es_ES": "{0} - Confirmación", "fr_FR": "", - "he_IL": "ריוג'ינקס - אישור", - "it_IT": "Ryujinx - Conferma", - "ja_JP": "Ryujinx - 確認", - "ko_KR": "Ryujinx - 확인", - "no_NO": "Ryujinx - Bekreftelse", - "pl_PL": "Ryujinx - Potwierdzenie", - "pt_BR": "Ryujinx - Confirmação", - "ru_RU": "Ryujinx - Подтверждение", - "th_TH": "Ryujinx - ยืนยัน", - "tr_TR": "Ryujinx - Onay", - "uk_UA": "Ryujinx - Підтвердження", - "zh_CN": "Ryujinx - 确认", - "zh_TW": "Ryujinx - 確認" + "he_IL": "{0} - אישור", + "it_IT": "{0} - Conferma", + "ja_JP": "{0} - 確認", + "ko_KR": "{0} - 확인", + "no_NO": "{0} - Bekreftelse", + "pl_PL": "{0} - Potwierdzenie", + "pt_BR": "{0} - Confirmação", + "ru_RU": "{0} — Подтверждение", + "sv_SE": "{0} - Bekräftelse", + "th_TH": "{0} - ยืนยัน", + "tr_TR": "{0} - Onay", + "uk_UA": "{0} - Підтвердження", + "zh_CN": "{0} - 确认", + "zh_TW": "{0} - 確認" } }, { "ID": "DialogUpdaterTitle", "Translations": { - "ar_SA": "ريوجينكس - المحدث", + "ar_SA": "{0} - المحدث", "de_DE": "", - "el_GR": "Ryujinx - Ενημερωτής", - "en_US": "Ryujinx - Updater", - "es_ES": "Ryujinx - Actualizador", - "fr_FR": "Ryujinx - Mise à Jour", - "he_IL": "ריוג'ינקס - מעדכן", - "it_IT": "Ryujinx - Aggiornamento", - "ja_JP": "Ryujinx - アップデータ", - "ko_KR": "Ryujinx - 업데이터", - "no_NO": "Ryujinx – Oppdaterer", - "pl_PL": "Ryujinx - Asystent aktualizacji", - "pt_BR": "Ryujinx - Atualizador", - "ru_RU": "Ryujinx - Обновление", - "th_TH": "Ryujinx - อัพเดต", - "tr_TR": "Ryujinx - Güncelleyici", - "uk_UA": "Ryujinx - Програма оновлення", - "zh_CN": "Ryujinx - 更新", - "zh_TW": "Ryujinx - 更新程式" + "el_GR": "{0} - Ενημερωτής", + "en_US": "{0} - Updater", + "es_ES": "{0} - Actualizador", + "fr_FR": "{0} - Mise à Jour", + "he_IL": "{0} - מעדכן", + "it_IT": "{0} - Aggiornamento", + "ja_JP": "{0} - アップデータ", + "ko_KR": "{0} - 업데이터", + "no_NO": "{0} – Oppdaterer", + "pl_PL": "{0} - Asystent aktualizacji", + "pt_BR": "{0} - Atualizador", + "ru_RU": "{0} — Обновление", + "sv_SE": "{0} - Uppdatering", + "th_TH": "{0} - อัพเดต", + "tr_TR": "{0} - Güncelleyici", + "uk_UA": "{0} - Програма оновлення", + "zh_CN": "{0} - 更新", + "zh_TW": "{0} - 更新程式" } }, { "ID": "DialogErrorTitle", "Translations": { - "ar_SA": "ريوجينكس - خطأ", - "de_DE": "Ryujinx - Fehler", - "el_GR": "Ryujinx - Σφάλμα", - "en_US": "Ryujinx - Error", + "ar_SA": "{0} - خطأ", + "de_DE": "{0} - Fehler", + "el_GR": "{0} - Σφάλμα", + "en_US": "{0} - Error", "es_ES": "", - "fr_FR": "Ryujinx - Erreur", - "he_IL": "ריוג'ינקס - שגיאה", - "it_IT": "Ryujinx - Errore", - "ja_JP": "Ryujinx - エラー", - "ko_KR": "Ryujinx - 오류", - "no_NO": "Ryujinx - Feil", - "pl_PL": "Ryujinx - Błąd", - "pt_BR": "Ryujinx - Erro", - "ru_RU": "Ryujinx - Ошибка", - "th_TH": "Ryujinx - ผิดพลาด", - "tr_TR": "Ryujinx - Hata", - "uk_UA": "Ryujinx - Помилка", - "zh_CN": "Ryujinx - 错误", - "zh_TW": "Ryujinx - 錯誤" + "fr_FR": "{0} - Erreur", + "he_IL": "{0} - שגיאה", + "it_IT": "{0} - Errore", + "ja_JP": "{0} - エラー", + "ko_KR": "{0} - 오류", + "no_NO": "{0} - Feil", + "pl_PL": "{0} - Błąd", + "pt_BR": "{0} - Erro", + "ru_RU": "{0} — Ошибка", + "sv_SE": "{0} - Fel", + "th_TH": "{0} - ผิดพลาด", + "tr_TR": "{0} - Hata", + "uk_UA": "{0} - Помилка", + "zh_CN": "{0} - 错误", + "zh_TW": "{0} - 錯誤" } }, { "ID": "DialogWarningTitle", "Translations": { - "ar_SA": "ريوجينكس - تحذير", - "de_DE": "Ryujinx - Warnung", - "el_GR": "Ryujinx - Προειδοποίηση", - "en_US": "Ryujinx - Warning", - "es_ES": "Ryujinx - Advertencia", - "fr_FR": "Ryujinx - Avertissement", - "he_IL": "ריוג'ינקס - אזהרה", - "it_IT": "Ryujinx - Avviso", - "ja_JP": "Ryujinx - 警告", - "ko_KR": "Ryujinx - 경고", - "no_NO": "Ryujinx - Advarsel", - "pl_PL": "Ryujinx - Ostrzeżenie", - "pt_BR": "Ryujinx - Alerta", - "ru_RU": "Ryujinx - Предупреждение", - "th_TH": "Ryujinx - คำเตือน", - "tr_TR": "Ryujinx - Uyarı", - "uk_UA": "Ryujinx - Попередження", - "zh_CN": "Ryujinx - 警告", - "zh_TW": "Ryujinx - 警告" + "ar_SA": "{0} - تحذير", + "de_DE": "{0} - Warnung", + "el_GR": "{0} - Προειδοποίηση", + "en_US": "{0} - Warning", + "es_ES": "{0} - Advertencia", + "fr_FR": "{0} - Avertissement", + "he_IL": "{0} - אזהרה", + "it_IT": "{0} - Avviso", + "ja_JP": "{0} - 警告", + "ko_KR": "{0} - 경고", + "no_NO": "{0} - Advarsel", + "pl_PL": "{0} - Ostrzeżenie", + "pt_BR": "{0} - Alerta", + "ru_RU": "{0} — Предупреждение", + "sv_SE": "{0} - Varning", + "th_TH": "{0} - คำเตือน", + "tr_TR": "{0} - Uyarı", + "uk_UA": "{0} - Попередження", + "zh_CN": "{0} - 警告", + "zh_TW": "{0} - 警告" } }, { "ID": "DialogExitTitle", "Translations": { - "ar_SA": "ريوجينكس - الخروج", - "de_DE": "Ryujinx - Beenden", - "el_GR": "Ryujinx - Έξοδος", - "en_US": "Ryujinx - Exit", - "es_ES": "Ryujinx - Salir", - "fr_FR": "Ryujinx - Quitter", - "he_IL": "ריוג'ינקס - יציאה", - "it_IT": "Ryujinx - Esci", - "ja_JP": "Ryujinx - 終了", - "ko_KR": "Ryujinx - 종료", - "no_NO": "Ryujinx - Avslutt", - "pl_PL": "Ryujinx - Wyjdź", - "pt_BR": "Ryujinx - Sair", - "ru_RU": "Ryujinx - Выход", - "th_TH": "Ryujinx - ออก", - "tr_TR": "Ryujinx - Çıkış", - "uk_UA": "Ryujinx - Вихід", - "zh_CN": "Ryujinx - 退出", - "zh_TW": "Ryujinx - 結束" + "ar_SA": "{0} - الخروج", + "de_DE": "{0} - Beenden", + "el_GR": "{0} - Έξοδος", + "en_US": "{0} - Exit", + "es_ES": "{0} - Salir", + "fr_FR": "{0} - Quitter", + "he_IL": "{0} - יציאה", + "it_IT": "{0} - Esci", + "ja_JP": "{0} - 終了", + "ko_KR": "{0} - 종료", + "no_NO": "{0} - Avslutt", + "pl_PL": "{0} - Wyjdź", + "pt_BR": "{0} - Sair", + "ru_RU": "{0} — Выход", + "sv_SE": "{0} - Avslut", + "th_TH": "{0} - ออก", + "tr_TR": "{0} - Çıkış", + "uk_UA": "{0} - Вихід", + "zh_CN": "{0} - 退出", + "zh_TW": "{0} - 結束" } }, { @@ -10886,6 +12239,7 @@ "pl_PL": "Ryujinx napotkał błąd", "pt_BR": "Ryujinx encontrou um erro", "ru_RU": "Ryujinx обнаружил ошибку", + "sv_SE": "Ryujinx har påträffat ett fel", "th_TH": "Ryujinx พบข้อผิดพลาด", "tr_TR": "Ryujinx bir hata ile karşılaştı", "uk_UA": "У Ryujinx сталася помилка", @@ -10910,6 +12264,7 @@ "pl_PL": "Czy na pewno chcesz zamknąć Ryujinx?", "pt_BR": "Tem certeza que deseja fechar o Ryujinx?", "ru_RU": "Вы уверены, что хотите выйти из Ryujinx?", + "sv_SE": "Är du säker på att du vill avsluta Ryujinx?", "th_TH": "คุณแน่ใจหรือไม่ว่าต้องการปิด Ryujinx หรือไม่?", "tr_TR": "Ryujinx'i kapatmak istediğinizden emin misiniz?", "uk_UA": "Ви впевнені, що бажаєте закрити Ryujinx?", @@ -10933,7 +12288,8 @@ "no_NO": "Alle ulagrede data vil gå tapt!", "pl_PL": "Wszystkie niezapisane dane zostaną utracone!", "pt_BR": "Todos os dados que não foram salvos serão perdidos!", - "ru_RU": "Все несохраненные данные будут потеряны", + "ru_RU": "Все несохранённые данные будут потеряны", + "sv_SE": "Allt data som inte sparats kommer att förloras!", "th_TH": "ข้อมูลทั้งหมดที่ไม่ได้บันทึกทั้งหมดจะสูญหาย!", "tr_TR": "Kaydedilmeyen bütün veriler kaybedilecek!", "uk_UA": "Усі незбережені дані буде втрачено!", @@ -10956,8 +12312,9 @@ "ko_KR": "지정된 저장 데이터를 생성하는 동안 오류가 발생 : {0}", "no_NO": "Det oppstod en feil under oppretting av den angitte lagredata: {0}", "pl_PL": "Wystąpił błąd podczas tworzenia określonych zapisanych danych: {0}", - "pt_BR": "Ocorreu um erro ao criar o diretório de salvamento: {0}", + "pt_BR": "Ocorreu um erro ao criar os dados salvos especificados: {0}", "ru_RU": "Произошла ошибка при создании указанных данных сохранения: {0}", + "sv_SE": "Det inträffade ett fel vid skapandet av angivet sparat spel: {0}", "th_TH": "มีข้อผิดพลาดในการสร้างข้อมูลบันทึกที่ระบุ: {0}", "tr_TR": "Belirtilen kayıt verisi oluşturulurken bir hata oluştu: {0}", "uk_UA": "Під час створення вказаних даних збереження сталася помилка: {0}", @@ -10980,8 +12337,9 @@ "ko_KR": "지정된 저장 데이터를 찾는 중 오류가 발생 : {0}", "no_NO": "Det oppstod en feil under oppretting av den angitte lagredata: {0}", "pl_PL": "Wystąpił błąd podczas próby znalezienia określonych zapisanych danych: {0}", - "pt_BR": "Ocorreu um erro ao tentar encontrar o diretório de salvamento: {0}", + "pt_BR": "Ocorreu um erro ao encontrar os dados salvos especificados: {0}", "ru_RU": "Произошла ошибка при поиске указанных данных сохранения: {0}", + "sv_SE": "Det inträffade ett fel vid sökandet av angivet sparat spel: {0}", "th_TH": "มีข้อผิดพลาดในการค้นหาข้อมูลบันทึกที่ระบุไว้: {0}", "tr_TR": "Belirtilen kayıt verisi bulunmaya çalışırken hata: {0}", "uk_UA": "Під час пошуку вказаних даних збереження сталася помилка: {0}", @@ -11004,8 +12362,9 @@ "ko_KR": "압축을 풀 폴더를 선택", "no_NO": "Velg mappen å pakke ut i", "pl_PL": "Wybierz folder, do którego chcesz rozpakować", - "pt_BR": "Escolha o diretório onde os arquivos serão extraídos", + "pt_BR": "Escolha a pasta para extrair", "ru_RU": "Выберите папку для извлечения", + "sv_SE": "Välj en mapp att extrahera till", "th_TH": "เลือกโฟลเดอร์ที่จะแตกไฟล์เข้าไป", "tr_TR": "İçine ayıklanacak klasörü seç", "uk_UA": "Виберіть теку для видобування", @@ -11030,6 +12389,7 @@ "pl_PL": "Wypakowywanie sekcji {0} z {1}...", "pt_BR": "Extraindo seção {0} de {1}...", "ru_RU": "Извлечение {0} раздела из {1}...", + "sv_SE": "Extraherar {0}-sektion från {1}...", "th_TH": "กำลังแตกไฟล์ {0} จากส่วน {1}...", "tr_TR": "{1} den {0} kısmı ayıklanıyor...", "uk_UA": "Видобування розділу {0} з {1}...", @@ -11052,8 +12412,9 @@ "ko_KR": "NCA 단면 추출기", "no_NO": "Ryujinx - NCA Seksjon Ekstraktor", "pl_PL": "Asystent wypakowania sekcji NCA", - "pt_BR": "Extrator de seções NCA", + "pt_BR": "Extrator de Seções NCA", "ru_RU": "Извлечение разделов NCA", + "sv_SE": "Ryujinx - Extrahera NCA-sektion", "th_TH": "เครื่องมือแตกไฟล์ของ NCA", "tr_TR": "NCA Kısmı Ayıklayıcısı", "uk_UA": "Екстрактор розділів NCA", @@ -11078,6 +12439,7 @@ "pl_PL": "Niepowodzenie podczas wypakowywania. W wybranym pliku nie było głównego NCA.", "pt_BR": "Falha na extração. O NCA principal não foi encontrado no arquivo selecionado.", "ru_RU": "Ошибка извлечения. Основной NCA не присутствовал в выбранном файле.", + "sv_SE": "Fel vid extrahering. Main NCA hittades inte i vald fil.", "th_TH": "เกิดความล้มเหลวในการแตกไฟล์เนื่องจากไม่พบ NCA หลักในไฟล์ที่เลือก", "tr_TR": "Ayıklama hatası. Ana NCA seçilen dosyada bulunamadı.", "uk_UA": "Помилка видобування. Основний NCA не був присутній у вибраному файлі.", @@ -11102,6 +12464,7 @@ "pl_PL": "Niepowodzenie podczas wypakowywania. Przeczytaj plik dziennika, aby uzyskać więcej informacji.", "pt_BR": "Falha na extração. Leia o arquivo de log para mais informações.", "ru_RU": "Ошибка извлечения. Прочтите файл журнала для получения дополнительной информации.", + "sv_SE": "Fel vid extrahering. Läs i loggfilen för mer information.", "th_TH": "เกิดความล้มเหลวในการแตกไฟล์ โปรดอ่านไฟล์บันทึกประวัติเพื่อดูข้อมูลเพิ่มเติม", "tr_TR": "Ayıklama hatası. Ek bilgi için kayıt dosyasını okuyun.", "uk_UA": "Помилка видобування. Прочитайте файл журналу для отримання додаткової інформації.", @@ -11126,6 +12489,7 @@ "pl_PL": "Wypakowywanie zakończone pomyślnie.", "pt_BR": "Extração concluída com êxito.", "ru_RU": "Извлечение завершено успешно.", + "sv_SE": "Extraheringen lyckades.", "th_TH": "การแตกไฟล์เสร็จสมบูรณ์แล้ว", "tr_TR": "Ayıklama başarıyla tamamlandı.", "uk_UA": "Видобування успішно завершено.", @@ -11150,6 +12514,7 @@ "pl_PL": "Nie udało się przekonwertować obecnej wersji Ryujinx.", "pt_BR": "Falha ao converter a versão atual do Ryujinx.", "ru_RU": "Не удалось преобразовать текущую версию Ryujinx.", + "sv_SE": "Misslyckades med att konvertera aktuell Ryujinx-version.", "th_TH": "ไม่สามารถแปลงเวอร์ชั่น Ryujinx ปัจจุบันได้", "tr_TR": "Güncel Ryujinx sürümü dönüştürülemedi.", "uk_UA": "Не вдалося конвертувати поточну версію Ryujinx.", @@ -11174,6 +12539,7 @@ "pl_PL": "Anulowanie aktualizacji!", "pt_BR": "Cancelando atualização!", "ru_RU": "Отмена обновления...", + "sv_SE": "Avbryter uppdatering!", "th_TH": "ยกเลิกการอัพเดต!", "tr_TR": "Güncelleme iptal ediliyor!", "uk_UA": "Скасування оновлення!", @@ -11198,6 +12564,7 @@ "pl_PL": "Używasz już najnowszej wersji Ryujinx!", "pt_BR": "Você já está usando a versão mais recente do Ryujinx!", "ru_RU": "Вы используете самую последнюю версию Ryujinx", + "sv_SE": "Du använder redan den senaste versionen av Ryujinx!", "th_TH": "คุณกำลังใช้ Ryujinx เวอร์ชั่นที่อัปเดตล่าสุด!", "tr_TR": "Zaten Ryujinx'in en güncel sürümünü kullanıyorsunuz!", "uk_UA": "Ви вже використовуєте останню версію Ryujinx!", @@ -11222,6 +12589,7 @@ "pl_PL": "Wystąpił błąd podczas próby uzyskania informacji o obecnej wersji z GitHub Release. Może to być spowodowane nową wersją kompilowaną przez GitHub Actions. Spróbuj ponownie za kilka minut.", "pt_BR": "Ocorreu um erro ao tentar obter as informações de atualização do GitHub Release. Isso pode ser causado se uma nova versão estiver sendo compilado pelas Ações do GitHub. Tente novamente em alguns minutos.", "ru_RU": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано тем, что в данный момент в GitHub Actions компилируется новый релиз. Повторите попытку позже.", + "sv_SE": "Ett fel inträffade vid försök att hämta information om utgåvan från GitHub. Detta kan hända om en ny utgåva har kompilerats av GitHub Actions. Försök igen om några minuter.", "th_TH": "เกิดข้อผิดพลาดขณะพยายามรับข้อมูลเวอร์ชั่นจาก GitHub Release ปัญหานี้อาจเกิดขึ้นได้หากมีการรวบรวมเวอร์ชั่นใหม่โดย GitHub โปรดลองอีกครั้งในอีกไม่กี่นาทีข้างหน้า", "tr_TR": "GitHub tarafından sürüm bilgileri alınırken bir hata oluştu. Eğer yeni sürüm için hazırlıklar yapılıyorsa bu hatayı almanız olasıdır. Lütfen birkaç dakika sonra tekrar deneyiniz.", "uk_UA": "Під час спроби отримати інформацію про випуск із GitHub Release сталася помилка. Це може бути спричинено, якщо новий випуск компілюється GitHub Actions. Повторіть спробу через кілька хвилин.", @@ -11244,8 +12612,9 @@ "ko_KR": "GitHub에서 받은 Ryujinx 버전을 변환하지 못했습니다.", "no_NO": "Kan ikke konvertere mottatt Ryujinx-versjon fra GitHub Utgivelse.", "pl_PL": "Nie udało się przekonwertować otrzymanej wersji Ryujinx z Github Release.", - "pt_BR": "Falha ao converter a versão do Ryujinx recebida do AppVeyor.", + "pt_BR": "Falha ao converter a versão Ryujinx recebida do GitHub.", "ru_RU": "Не удалось преобразовать полученную версию Ryujinx из GitHub Release.", + "sv_SE": "Misslyckades med att konvertera mottagen Ryujinx-version från GitHub.", "th_TH": "ไม่สามารถแปลงเวอร์ชั่น Ryujinx ที่ได้รับจาก GitHub Release", "tr_TR": "Github Release'den alınan Ryujinx sürümü dönüştürülemedi.", "uk_UA": "Не вдалося конвертувати отриману версію Ryujinx із випуску GitHub.", @@ -11268,8 +12637,9 @@ "ko_KR": "업데이트 내려받는 중...", "no_NO": "Laster ned oppdatering...", "pl_PL": "Pobieranie aktualizacji...", - "pt_BR": "Baixando atualização...", + "pt_BR": "Baixando Atualização...", "ru_RU": "Загрузка обновления...", + "sv_SE": "Hämtar uppdatering...", "th_TH": "กำลังดาวน์โหลดอัปเดต...", "tr_TR": "Güncelleme İndiriliyor...", "uk_UA": "Завантаження оновлення...", @@ -11292,8 +12662,9 @@ "ko_KR": "업데이트 추출 중...", "no_NO": "Pakker ut oppdatering...", "pl_PL": "Wypakowywanie Aktualizacji...", - "pt_BR": "Extraindo atualização...", + "pt_BR": "Extraindo Atualização...", "ru_RU": "Извлечение обновления...", + "sv_SE": "Extraherar uppdatering...", "th_TH": "กำลังแตกไฟล์อัปเดต...", "tr_TR": "Güncelleme Ayıklanıyor...", "uk_UA": "Видобування оновлення...", @@ -11311,13 +12682,14 @@ "es_ES": "Renombrando actualización...", "fr_FR": "Renommage de la mise à jour...", "he_IL": "משנה את שם העדכון...", - "it_IT": "Rinominazione dell'aggiornamento...", + "it_IT": "Ridenominazione dell'aggiornamento...", "ja_JP": "アップデートをリネーム中...", "ko_KR": "이름 변경 업데이트...", "no_NO": "Endrer navn på oppdatering...", "pl_PL": "Zmiana Nazwy Aktualizacji...", - "pt_BR": "Renomeando atualização...", + "pt_BR": "Renomeando Atualização...", "ru_RU": "Переименование обновления...", + "sv_SE": "Byter namn på uppdatering...", "th_TH": "กำลังลบไฟล์เก่า...", "tr_TR": "Güncelleme Yeniden Adlandırılıyor...", "uk_UA": "Перейменування оновлення...", @@ -11340,8 +12712,9 @@ "ko_KR": "새 업데이트 추가 중...", "no_NO": "Legger til ny oppdatering...", "pl_PL": "Dodawanie Nowej Aktualizacji...", - "pt_BR": "Adicionando nova atualização...", + "pt_BR": "Adicionando Nova Atualização...", "ru_RU": "Добавление нового обновления...", + "sv_SE": "Lägger till ny uppdatering...", "th_TH": "กำลังเพิ่มไฟล์อัปเดตใหม่...", "tr_TR": "Yeni Güncelleme Ekleniyor...", "uk_UA": "Додавання нового оновлення...", @@ -11359,18 +12732,19 @@ "es_ES": "", "fr_FR": "Afficher Changelog", "he_IL": "", - "it_IT": "", + "it_IT": "Mostra il changelog", "ja_JP": "", "ko_KR": "변경 로그 보기", "no_NO": "Vis endringslogg", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Ver Registro de Alterações", + "ru_RU": "Показать список изменений", + "sv_SE": "Visa ändringslogg", "th_TH": "", "tr_TR": "", "uk_UA": "Показати список змін", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "显示更新日志", + "zh_TW": "顯示更新日誌" } }, { @@ -11388,8 +12762,9 @@ "ko_KR": "업데이트가 완료되었습니다!", "no_NO": "Oppdateringen er fullført!", "pl_PL": "Aktualizacja Zakończona!", - "pt_BR": "Atualização concluída!", + "pt_BR": "Atualização Concluída!", "ru_RU": "Обновление завершено", + "sv_SE": "Uppdatering färdig!", "th_TH": "อัปเดตเสร็จสมบูรณ์แล้ว!", "tr_TR": "Güncelleme Tamamlandı!", "uk_UA": "Оновлення завершено!", @@ -11414,6 +12789,7 @@ "pl_PL": "Czy chcesz teraz zrestartować Ryujinx?", "pt_BR": "Deseja reiniciar o Ryujinx agora?", "ru_RU": "Перезапустить Ryujinx?", + "sv_SE": "Vill du starta om Ryujinx nu?", "th_TH": "คุณต้องการรีสตาร์ท Ryujinx ตอนนี้หรือไม่?", "tr_TR": "Ryujinx'i şimdi yeniden başlatmak istiyor musunuz?", "uk_UA": "Перезапустити Ryujinx зараз?", @@ -11438,6 +12814,7 @@ "pl_PL": "Nie masz połączenia z Internetem!", "pt_BR": "Você não está conectado à Internet!", "ru_RU": "Вы не подключены к интернету", + "sv_SE": "Du är inte ansluten till internet!", "th_TH": "คุณไม่ได้เชื่อมต่อกับอินเทอร์เน็ต!", "tr_TR": "İnternete bağlı değilsiniz!", "uk_UA": "Ви не підключені до Інтернету!", @@ -11462,6 +12839,7 @@ "pl_PL": "Sprawdź, czy masz działające połączenie internetowe!", "pt_BR": "Por favor, certifique-se de que você tem uma conexão funcional à Internet!", "ru_RU": "Убедитесь, что у вас работает подключение к интернету", + "sv_SE": "Försäkra dig om att du har en fungerande internetanslutning!", "th_TH": "โปรดตรวจสอบว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตว่ามีการใช้งานได้หรือไม่!", "tr_TR": "Lütfen aktif bir internet bağlantınız olduğunu kontrol edin!", "uk_UA": "Будь ласка, переконайтеся, що у вас є робоче підключення до Інтернету!", @@ -11486,6 +12864,7 @@ "pl_PL": "Nie możesz zaktualizować Dirty wersji Ryujinx!", "pt_BR": "Você não pode atualizar uma compilação Dirty do Ryujinx!", "ru_RU": "Вы не можете обновлять Dirty Build", + "sv_SE": "Du kan inte uppdatera en Dirty build av Ryujinx!", "th_TH": "คุณไม่สามารถอัปเดต Dirty build ของ Ryujinx ได้!", "tr_TR": "Ryujinx'in Dirty build'lerini güncelleyemezsiniz!", "uk_UA": "Ви не можете оновити брудну збірку Ryujinx!", @@ -11506,10 +12885,11 @@ "it_IT": "Scarica Ryujinx da https://ryujinx.app/download se stai cercando una versione supportata.", "ja_JP": "サポートされているバージョンをお探しなら, https://ryujinx.app/download で Ryujinx をダウンロードしてください.", "ko_KR": "지원되는 버전을 찾으신다면 https://ryujinx.app/download 에서 Ryujinx를 내려받으세요.", - "no_NO": "Vennligst last ned Ryujinx på https://ryujinx.org/ hvis du ser etter en støttet versjon.", + "no_NO": "Vennligst last ned Ryujinx på https://ryujinx.app/download hvis du ser etter en støttet versjon.", "pl_PL": "Pobierz Ryujinx ze strony https://ryujinx.app/download, jeśli szukasz obsługiwanej wersji.", "pt_BR": "Por favor, baixe o Ryujinx em https://ryujinx.app/download se está procurando por uma versão suportada.", "ru_RU": "Загрузите Ryujinx по адресу https://ryujinx.app/download если вам нужна поддерживаемая версия.", + "sv_SE": "Hämta Ryujinx från https://ryujinx.app/download om du letar efter en version som stöds.", "th_TH": "โปรดดาวน์โหลด Ryujinx ได้ที่ https://ryujinx.app/download หากคุณกำลังมองหาเวอร์ชั่นที่รองรับ", "tr_TR": "Desteklenen bir sürüm için lütfen Ryujinx'i https://ryujinx.app/download sitesinden indirin.", "uk_UA": "Будь ласка, завантажте Ryujinx на https://ryujinx.app/download, якщо ви шукаєте підтримувану версію.", @@ -11532,8 +12912,9 @@ "ko_KR": "다시 시작 필요", "no_NO": "Omstart Kreves", "pl_PL": "Wymagane Ponowne Uruchomienie", - "pt_BR": "Reinicialização necessária", - "ru_RU": "Требуется перезагрузка", + "pt_BR": "Reinicialização Necessária", + "ru_RU": "Требуется перезапуск", + "sv_SE": "Omstart krävs", "th_TH": "จำเป็นต้องรีสตาร์ทเพื่อให้การอัพเดตสามารถให้งานได้", "tr_TR": "Yeniden Başlatma Gerekli", "uk_UA": "Потрібен перезапуск", @@ -11557,7 +12938,8 @@ "no_NO": "Temaet har blitt lagret. En omstart kreves for å bruke temaet.", "pl_PL": "Motyw został zapisany. Aby zastosować motyw, konieczne jest ponowne uruchomienie.", "pt_BR": "O tema foi salvo. Uma reinicialização é necessária para aplicar o tema.", - "ru_RU": "Тема сохранена. Для применения темы требуется перезапуск.", + "ru_RU": "Тема сохранена. Для применения темы требуется выполнить перезапуск.", + "sv_SE": "Temat har sparats. En omstart krävs för att verkställa ändringen.", "th_TH": "บันทึกธีมแล้ว จำเป็นต้องรีสตาร์ทเพื่อใช้ธีม", "tr_TR": "Tema kaydedildi. Temayı uygulamak için yeniden başlatma gerekiyor.", "uk_UA": "Тему збережено. Щоб застосувати тему, потрібен перезапуск.", @@ -11581,7 +12963,8 @@ "no_NO": "Vil du starte på nytt", "pl_PL": "Czy chcesz uruchomić ponownie?", "pt_BR": "Deseja reiniciar?", - "ru_RU": "Хотите перезапустить", + "ru_RU": "Выполнить перезапуск?", + "sv_SE": "Vill du starta om", "th_TH": "คุณต้องการรีสตาร์ทหรือไม่?", "tr_TR": "Yeniden başlatmak ister misiniz", "uk_UA": "Ви хочете перезапустити", @@ -11599,13 +12982,14 @@ "es_ES": "¿Quieres instalar el firmware incluido en este juego? (Firmware versión {0})", "fr_FR": "Voulez-vous installer le firmware intégré dans ce jeu ? (Firmware {0})", "he_IL": "האם תרצו להתקין את הקושחה המוטמעת במשחק הזה? (קושחה {0})", - "it_IT": "Vuoi installare il firmware incorporato in questo gioco? (Firmware {0})", + "it_IT": "Vuoi installare il firmware incluso in questo gioco? (Firmware {0})", "ja_JP": "このゲームに含まれるファームウェアをインストールしてよろしいですか? (ファームウェア {0})", "ko_KR": "이 게임에 포함된 펌웨어를 설치하시겠습니까?(Firmware {0})", "no_NO": "Ønsker du å installere fastvaren innebygd i dette spillet? (Firmware {0})", "pl_PL": "Czy chcesz zainstalować firmware wbudowany w tę grę? (Firmware {0})", "pt_BR": "Gostaria de instalar o firmware incluso neste jogo? (Firmware {0})", "ru_RU": "Хотите установить прошивку, встроенную в эту игру? (Прошивка {0})", + "sv_SE": "Vill du installera det firmware som är inbäddat i detta spel? (Firmware {0})", "th_TH": "คุณต้องการติดตั้งเฟิร์มแวร์ที่ฝังอยู่ในเกมนี้หรือไม่? (เฟิร์มแวร์ {0})", "tr_TR": "Bu oyunun içine gömülü olan yazılımı yüklemek ister misiniz? (Firmware {0})", "uk_UA": "Бажаєте встановити прошивку, вбудовану в цю гру? (Прошивка {0})", @@ -11630,6 +13014,7 @@ "pl_PL": "Nie znaleziono zainstalowanego oprogramowania, ale Ryujinx był w stanie zainstalować oprogramowanie {0} z dostarczonej gry.\n\nEmulator uruchomi się teraz.", "pt_BR": "Nenhum firmware instalado foi encontrado, mas o Ryujinx conseguiu instalar o firmware {0} a partir do jogo fornecido.\nO emulador será iniciado agora.", "ru_RU": "Установленная прошивка не была найдена, но Ryujinx удалось установить прошивку {0} из предоставленной игры.\nТеперь эмулятор запустится.", + "sv_SE": "Inget installerat firmware hittades men Ryujinx kunde installera firmware {0} från angiven spel.\nEmulatorn kommer nu att startas.", "th_TH": "ไม่พบเฟิร์มแวร์ที่ติดตั้งไว้ แต่ Ryujinx จะติดตั้งเฟิร์มแวร์ได้ {0} จากเกมที่ให้มา\nขณะนี้โปรแกรมจำลองจะเริ่มทำงาน", "tr_TR": "", "uk_UA": "Встановлену прошивку не знайдено, але Ryujinx вдалося встановити прошивку {0} з наданої гри.\nТепер запуститься емулятор.", @@ -11652,8 +13037,9 @@ "ko_KR": "펌웨어가 설치되어 있지 않음", "no_NO": "Ingen fastvare installert", "pl_PL": "Brak Zainstalowanego Firmware'u", - "pt_BR": "Firmware não foi instalado", + "pt_BR": "Nenhum Firmware Instalado", "ru_RU": "Прошивка не установлена", + "sv_SE": "Inget firmware installerat", "th_TH": "ไม่มีการติดตั้งเฟิร์มแวร์", "tr_TR": "Yazılım Yüklü Değil", "uk_UA": "Прошивка не встановлена", @@ -11678,6 +13064,7 @@ "pl_PL": "Firmware {0} został zainstalowany", "pt_BR": "Firmware {0} foi instalado", "ru_RU": "Прошивка {0} была установлена", + "sv_SE": "Firmware {0} installerades", "th_TH": "เฟิร์มแวร์ {0} ติดตั้งแล้ว", "tr_TR": "Yazılım {0} yüklendi", "uk_UA": "Встановлено прошивку {0}", @@ -11702,6 +13089,7 @@ "pl_PL": "Pomyślnie zainstalowano typy plików!", "pt_BR": "Tipos de arquivo instalados com sucesso!", "ru_RU": "Типы файлов успешно установлены", + "sv_SE": "Filtyper har installerats!", "th_TH": "ติดตั้งตามประเภทของไฟล์สำเร็จแล้ว!", "tr_TR": "Dosya uzantıları başarıyla yüklendi!", "uk_UA": "Успішно встановлено типи файлів!", @@ -11726,6 +13114,7 @@ "pl_PL": "Nie udało się zainstalować typów plików.", "pt_BR": "Falha ao instalar tipos de arquivo.", "ru_RU": "Не удалось установить типы файлов.", + "sv_SE": "Misslyckades med att installera filtyper.", "th_TH": "ติดตั้งตามประเภทของไฟล์ไม่สำเร็จ", "tr_TR": "Dosya uzantıları yükleme işlemi başarısız oldu.", "uk_UA": "Не вдалося встановити типи файлів.", @@ -11750,6 +13139,7 @@ "pl_PL": "Pomyślnie odinstalowano typy plików!", "pt_BR": "Tipos de arquivo desinstalados com sucesso!", "ru_RU": "Типы файлов успешно удалены", + "sv_SE": "Filtyper avinstallerades!", "th_TH": "ถอนการติดตั้งตามประเภทของไฟล์สำเร็จแล้ว!", "tr_TR": "Dosya uzantıları başarıyla kaldırıldı!", "uk_UA": "Успішно видалено типи файлів!", @@ -11774,6 +13164,7 @@ "pl_PL": "Nie udało się odinstalować typów plików.", "pt_BR": "Falha ao desinstalar tipos de arquivo.", "ru_RU": "Не удалось удалить типы файлов.", + "sv_SE": "Misslyckades med att avinstallera filtyper.", "th_TH": "ไม่สามารถถอนการติดตั้งตามประเภทของไฟล์ได้", "tr_TR": "Dosya uzantıları kaldırma işlemi başarısız oldu.", "uk_UA": "Не вдалося видалити типи файлів.", @@ -11796,8 +13187,9 @@ "ko_KR": "설정 창 열기", "no_NO": "Åpne innstillinger-vinduet", "pl_PL": "Otwórz Okno Ustawień", - "pt_BR": "Abrir janela de configurações", + "pt_BR": "Abrir Janela de Configurações", "ru_RU": "Открывает окно параметров", + "sv_SE": "Öppna inställningar", "th_TH": "เปิดหน้าต่างการตั้งค่า", "tr_TR": "Seçenekler Penceresini Aç", "uk_UA": "Відкрити вікно налаштувань", @@ -11815,18 +13207,19 @@ "es_ES": "Ventana recortador XCI", "fr_FR": "Fenêtre de réduction de fichiers XCI", "he_IL": "", - "it_IT": "Finestra XCI Trimmer", + "it_IT": "Riduci dimensioni dei file XCI", "ja_JP": "", "ko_KR": "XCI 트리머 창", "no_NO": "XCI Trimmervindu", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Janela de Redução XCI", + "ru_RU": "Окно триммера XCI", + "sv_SE": "XCI-optimerare", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Вікно XCI Тримера", + "zh_CN": "XCI 文件瘦身窗口", + "zh_TW": "XCI 修剪器視窗" } }, { @@ -11844,8 +13237,9 @@ "ko_KR": "컨트롤러 애플릿", "no_NO": "Kontroller Applet", "pl_PL": "Aplet Kontrolera", - "pt_BR": "Applet de controle", + "pt_BR": "Applet de Controle", "ru_RU": "Апплет контроллера", + "sv_SE": "Handkontroller-applet", "th_TH": "คอนโทรลเลอร์ Applet", "tr_TR": "Kumanda Applet'i", "uk_UA": "Аплет контролера", @@ -11863,13 +13257,14 @@ "es_ES": "Error al mostrar cuadro de diálogo: {0}", "fr_FR": "Erreur lors de l'affichage de la boîte de dialogue : {0}", "he_IL": "שגיאה בהצגת דיאלוג ההודעה: {0}", - "it_IT": "Errore nella visualizzazione del Message Dialog: {0}", + "it_IT": "Errore nella visualizzazione della finestra di dialogo: {0}", "ja_JP": "メッセージダイアログ表示エラー: {0}", "ko_KR": "메시지 대화 상자 표시 오류 : {0}", "no_NO": "Feil ved visning av meldings-dialog: {0}", "pl_PL": "Błąd wyświetlania okna Dialogowego Wiadomości: {0}", "pt_BR": "Erro ao exibir diálogo de mensagem: {0}", "ru_RU": "Ошибка отображения сообщения: {0}", + "sv_SE": "Fel vid visning av meddelandedialog: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงกล่องโต้ตอบข้อความ: {0}", "tr_TR": "Mesaj diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу діалогового вікна повідомлення: {0}", @@ -11894,6 +13289,7 @@ "pl_PL": "Błąd wyświetlania Klawiatury Oprogramowania: {0}", "pt_BR": "Erro ao exibir teclado virtual: {0}", "ru_RU": "Ошибка отображения программной клавиатуры: {0}", + "sv_SE": "Fel vid visning av programvarutangentbord: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงซอฟต์แวร์แป้นพิมพ์: {0}", "tr_TR": "Mesaj diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу програмної клавіатури: {0}", @@ -11911,13 +13307,14 @@ "es_ES": "Error al mostrar díalogo ErrorApplet: {0}", "fr_FR": "Erreur lors de l'affichage de la boîte de dialogue ErrorApplet: {0}", "he_IL": "שגיאה בהצגת דיאלוג ErrorApplet: {0}", - "it_IT": "Errore nella visualizzazione dell'ErrorApplet Dialog: {0}", + "it_IT": "Errore nella visualizzazione della finestra dell'ErrorApplet: {0}", "ja_JP": "エラーアプレットダイアログ表示エラー: {0}", "ko_KR": "애플릿 오류류 대화 상자 표시 오류 : {0}", "no_NO": "Feil ved visning av Feilmeldingsdialog: {0}", "pl_PL": "Błąd wyświetlania okna Dialogowego ErrorApplet: {0}", "pt_BR": "Erro ao exibir applet ErrorApplet: {0}", "ru_RU": "Ошибка отображения диалогового окна ErrorApplet: {0}", + "sv_SE": "Fel vid visning av ErrorApplet-dialog: {0}", "th_TH": "เกิดข้อผิดพลาดในการแสดงกล่องโต้ตอบ ข้อผิดพลาดของ Applet: {0}", "tr_TR": "Applet diyaloğu gösterilirken hata: {0}", "uk_UA": "Помилка показу діалогового вікна ErrorApplet: {0}", @@ -11942,6 +13339,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -11966,6 +13364,7 @@ "pl_PL": "\nAby uzyskać więcej informacji o tym, jak naprawić ten błąd, zapoznaj się z naszym Przewodnikiem instalacji.", "pt_BR": "\nPara mais informações sobre como corrigir esse erro, siga nosso Guia de Configuração.", "ru_RU": "\nДля получения дополнительной информации о том, как исправить эту ошибку, следуйте нашему Руководству по установке.", + "sv_SE": "\nFölj vår konfigurationsguide för mer information om hur man rättar till detta fel.", "th_TH": "\nสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีแก้ไขข้อผิดพลาดนี้ โปรดทำตามคำแนะนำในการตั้งค่าของเรา", "tr_TR": "\nBu hatayı düzeltmek adına daha fazla bilgi için kurulum kılavuzumuzu takip edin.", "uk_UA": "\nДля отримання додаткової інформації про те, як виправити цю помилку, дотримуйтесь нашого посібника з налаштування.", @@ -11990,6 +13389,7 @@ "pl_PL": "Błąd Ryujinxa ({0})", "pt_BR": "Erro do Ryujinx ({0})", "ru_RU": "Ошибка Ryujinx ({0})", + "sv_SE": "Ryujinx-fel ({0}", "th_TH": "ข้อผิดพลาด Ryujinx ({0})", "tr_TR": "Ryujinx Hatası ({0})", "uk_UA": "Помилка Ryujinx ({0})", @@ -12007,16 +13407,17 @@ "es_ES": "", "fr_FR": "API Amiibo", "he_IL": "ממשק תכנות אמיבו", - "it_IT": "", + "it_IT": "API Amiibo", "ja_JP": "", "ko_KR": "", "no_NO": "", "pl_PL": "API Amiibo", "pt_BR": "API Amiibo", - "ru_RU": "", + "ru_RU": "API Amiibo", + "sv_SE": "Amiibo-API", "th_TH": "", "tr_TR": "", - "uk_UA": "", + "uk_UA": "API Amiibo", "zh_CN": "", "zh_TW": "" } @@ -12038,6 +13439,7 @@ "pl_PL": "Wystąpił błąd podczas pobierania informacji z API.", "pt_BR": "Um erro ocorreu ao tentar obter informações da API.", "ru_RU": "Произошла ошибка при получении информации из API.", + "sv_SE": "Ett fel inträffade vid hämtning av information från API.", "th_TH": "เกิดข้อผิดพลาดขณะเรียกข้อมูลจาก API", "tr_TR": "API'dan bilgi alırken bir hata oluştu.", "uk_UA": "Під час отримання інформації з API сталася помилка.", @@ -12055,13 +13457,14 @@ "es_ES": "No se pudo conectar al servidor de la API Amiibo. El servicio puede estar caído o tu conexión a internet puede haberse desconectado.", "fr_FR": "Impossible de se connecter au serveur API Amiibo. Le service est peut-être hors service ou vous devriez peut-être vérifier que votre connexion internet est connectée.", "he_IL": "לא ניתן להתחבר לממשק שרת האמיבו. ייתכן שהשירות מושבת או שתצטרך לוודא שהחיבור לאינטרנט שלך מקוון.", - "it_IT": "Impossibile connettersi al server Amiibo API. Il servizio potrebbe essere fuori uso o potresti dover verificare che la tua connessione internet sia online.", + "it_IT": "Impossibile connettersi al server dell'API Amiibo. Il servizio potrebbe non essere disponibile o potresti non essere connesso a Internet.", "ja_JP": "Amiibo API サーバに接続できませんでした. サーバがダウンしているか, インターネット接続に問題があるかもしれません.", "ko_KR": "Amiibo API 서버에 연결할 수 없습니다. 서비스가 다운되었거나 인터넷 연결이 온라인 상태인지 확인이 필요합니다.", "no_NO": "Kan ikke koble til Amiibo API server. Tjenesten kan være nede, eller du må kanskje verifisere at din internettforbindelse er tilkoblet.", "pl_PL": "Nie można połączyć się z serwerem API Amiibo. Usługa może nie działać lub może być konieczne sprawdzenie, czy połączenie internetowe jest online.", "pt_BR": "Não foi possível conectar ao servidor da API Amiibo. O serviço pode estar fora do ar ou você precisa verificar sua conexão com a Internet.", "ru_RU": "Не удалось подключиться к серверу Amiibo API. Служба может быть недоступна или вам может потребоваться проверить ваше интернет-соединение.", + "sv_SE": "Kunde inte ansluta till Amiibo API-server. Tjänsten kanske är nere eller så behöver du kontrollera att din internetanslutning fungerar.", "th_TH": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ Amiibo API บางบริการอาจหยุดทำงาน หรือไม่คุณต้องทำการตรวจสอบว่าอินเทอร์เน็ตของคุณอยู่ในสถานะเชื่อมต่ออยู่หรือไม่", "tr_TR": "Amiibo API sunucusuna bağlanılamadı. Sunucu çevrimdışı olabilir veya uygun bir internet bağlantınızın olduğunu kontrol etmeniz gerekebilir.", "uk_UA": "Неможливо підключитися до сервера Amiibo API. Можливо, служба не працює або вам потрібно перевірити, чи є підключення до Інтернету.", @@ -12079,13 +13482,14 @@ "es_ES": "El perfil {0} no es compatible con el sistema actual de configuración de entrada.", "fr_FR": "Le profil {0} est incompatible avec le système de configuration de manette actuel.", "he_IL": "הפרופיל {0} אינו תואם למערכת תצורת הקלט הנוכחית.", - "it_IT": "Il profilo {0} è incompatibile con l'attuale sistema di configurazione input.", + "it_IT": "Il profilo {0} non è compatibile con l'attuale sistema di configurazione input.", "ja_JP": "プロファイル {0} は現在の入力設定システムと互換性がありません.", "ko_KR": "프로필 {0}은(는) 현재 입력 구성 시스템과 호환되지 않습니다.", "no_NO": "Profil {0} er ikke kompatibel med den gjeldende inndata konfigurasjonen", "pl_PL": "Profil {0} jest niezgodny z bieżącym systemem konfiguracji sterowania.", "pt_BR": "Perfil {0} é incompatível com o sistema de configuração de controle atual.", "ru_RU": "Профиль {0} несовместим с текущей системой конфигурации ввода.", + "sv_SE": "Profilen {0} är inte kompatibel med aktuell konfiguration för inmatning.", "th_TH": "โปรไฟล์ {0} ไม่สามารถทำงานได้กับระบบกำหนดค่าอินพุตปัจจุบัน", "tr_TR": "Profil {0} güncel giriş konfigürasyon sistemi ile uyumlu değil.", "uk_UA": "Профіль {0} несумісний із поточною системою конфігурації вводу.", @@ -12110,6 +13514,7 @@ "pl_PL": "Profil Domyślny nie może zostać nadpisany", "pt_BR": "O perfil Padrão não pode ser substituído", "ru_RU": "Профиль по умолчанию не может быть перезаписан", + "sv_SE": "Standardprofilen kan inte skrivas över", "th_TH": "โปรไฟล์เริ่มต้นไม่สามารถเขียนทับได้", "tr_TR": "Varsayılan Profil'in üstüne yazılamaz", "uk_UA": "Стандартний профіль не можна перезаписати", @@ -12132,8 +13537,9 @@ "ko_KR": "프로필 삭제하기", "no_NO": "Sletter profil", "pl_PL": "Usuwanie Profilu", - "pt_BR": "Apagando perfil", + "pt_BR": "Apagando Perfil", "ru_RU": "Удаление профиля", + "sv_SE": "Tar bort profilen", "th_TH": "กำลังลบโปรไฟล์", "tr_TR": "Profil Siliniyor", "uk_UA": "Видалення профілю", @@ -12158,6 +13564,7 @@ "pl_PL": "Ta czynność jest nieodwracalna, czy na pewno chcesz kontynuować?", "pt_BR": "Essa ação é irreversível, tem certeza que deseja continuar?", "ru_RU": "Это действие необратимо. Вы уверены, что хотите продолжить?", + "sv_SE": "Denna åtgärd går inte att ångra. Är du säker på att du vill fortsätta?", "th_TH": "การดำเนินการนี้ไม่สามารถย้อนกลับได้ คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Bu eylem geri döndürülemez, devam etmek istediğinizden emin misiniz?", "uk_UA": "Цю дію неможливо скасувати. Ви впевнені, що бажаєте продовжити?", @@ -12182,6 +13589,7 @@ "pl_PL": "Uwaga", "pt_BR": "Alerta", "ru_RU": "Внимание", + "sv_SE": "Varning", "th_TH": "คำเตือน", "tr_TR": "Uyarı", "uk_UA": "Увага", @@ -12204,8 +13612,9 @@ "ko_KR": "다음에 부팅할 때, PPTC 재구축을 대기열에 추가하려고 합니다.\n\n{0}\n\n계속하시겠습니까?", "no_NO": "Du er i ferd med å bygge en PPTC i køen ved neste oppstart av:\n\n{0}\n\nEr du sikker på at du vil fortsette?", "pl_PL": "Masz zamiar umieścić w kolejce rekompilację PPTC przy następnym uruchomieniu:\n\n{0}\n\nCzy na pewno chcesz kontynuować?", - "pt_BR": "Você está prestes a apagar o cache PPTC para :\n\n{0}\n\nTem certeza que deseja continuar?", + "pt_BR": "Você está prestes a enfileirar uma reconstrução PPTC na próxima inicialização de:\n\n{0}\n\nTem certeza de que deseja continuar?", "ru_RU": "Вы собираетесь перестроить кэш PPTC при следующем запуске для:\n\n{0}\n\nВы уверены, что хотите продолжить?", + "sv_SE": "Du är på väg att kölägga en PPTC rebuild vid nästa uppstart av:\n\n{0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังตั้งค่าให้มีการสร้าง PPTC ใหม่ในการบูตครั้งถัดไป:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Belirtilen PPTC cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "uk_UA": "Ви збираєтеся видалити кеш PPTC для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", @@ -12228,8 +13637,9 @@ "ko_KR": "{0}에서 PPTC 캐시를 지우는 중 오류 발생 : {1}", "no_NO": "Feil under rensing av PPTC cache ved {0}: {1}", "pl_PL": "Błąd czyszczenia cache PPTC w {0}: {1}", - "pt_BR": "Erro apagando cache PPTC em {0}: {1}", + "pt_BR": "Erro ao limpar cache PPTC em {0}: {1}", "ru_RU": "Ошибка очистки кэша PPTC в {0}: {1}", + "sv_SE": "Fel vid tömning av PPTC-cache i {0}: {1}", "th_TH": "มีข้อผิดพลาดในการล้างแคช PPTC {0}: {1}", "tr_TR": "Belirtilen PPTC cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу PPTC на {0}: {1}", @@ -12237,6 +13647,31 @@ "zh_TW": "在 {0} 清除 PPTC 快取時出錯: {1}" } }, + { + "ID": "DialogPPTCNukeMessage", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "You are about to purge all PPTC data from:\n\n{0}\n\nAre you sure you want to proceed?", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?", + "no_NO": "Du er i ferd med å slette alle PPTC-data fra:\n\n{0}\n\n\nEr du sikker på at du vil fortsette?", + "pl_PL": "", + "pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?", + "ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?", + "zh_CN": "您正要清理 PPTC 数据:\n\n{0}\n\n您确实要继续吗?", + "zh_TW": "" + } + }, { "ID": "DialogShaderDeletionMessage", "Translations": { @@ -12254,6 +13689,7 @@ "pl_PL": "Zamierzasz usunąć cache Shaderów dla :\n\n{0}\n\nNa pewno chcesz kontynuować?", "pt_BR": "Você está prestes a apagar o cache de Shader para :\n\n{0}\n\nTem certeza que deseja continuar?", "ru_RU": "Вы собираетесь удалить кэш шейдеров для:\n\n{0}\n\nВы уверены, что хотите продолжить?", + "sv_SE": "Du är på väg att ta bort shader cache för :\n\n{0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบแคชแสงเงา:\n\n{0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อหรือไม่?", "tr_TR": "Belirtilen Shader cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?", "uk_UA": "Ви збираєтеся видалити кеш шейдерів для:\n\n{0}\n\nВи впевнені, що бажаєте продовжити?", @@ -12276,8 +13712,9 @@ "ko_KR": "{0}에서 셰이더 캐시를 삭제하는 중 오류 발생 : {1}", "no_NO": "Feil under tømming av Shader cache ved {0}: {1}", "pl_PL": "Błąd czyszczenia cache Shaderów w {0}: {1}", - "pt_BR": "Erro apagando o cache de Shader em {0}: {1}", + "pt_BR": "Erro ao limpar o cache do Shader em {0}: {1}", "ru_RU": "Ошибка очистки кэша шейдеров в {0}: {1}", + "sv_SE": "Fel vid tömning av shader cache i {0}: {1}", "th_TH": "เกิดข้อผิดพลาดในการล้าง แคชแสงเงา {0}: {1}", "tr_TR": "Belirtilen Shader cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу шейдерів на {0}: {1}", @@ -12302,6 +13739,7 @@ "pl_PL": "Ryujinx napotkał błąd", "pt_BR": "Ryujinx encontrou um erro", "ru_RU": "Ryujinx обнаружил ошибку", + "sv_SE": "Ryujinx har påträffat ett fel", "th_TH": "Ryujinx พบข้อผิดพลาด", "tr_TR": "Ryujinx bir hata ile karşılaştı", "uk_UA": "У Ryujinx сталася помилка", @@ -12326,6 +13764,7 @@ "pl_PL": "Błąd UI: Wybrana gra nie miała prawidłowego ID tytułu", "pt_BR": "Erro de interface: O jogo selecionado não tem um ID de título válido", "ru_RU": "Ошибка пользовательского интерфейса: выбранная игра не имеет действительного ID.", + "sv_SE": "Gränssnittsfel: Angivet spel saknar ett giltigt title ID", "th_TH": "ข้อผิดพลาดของ UI: เกมที่เลือกไม่มีชื่อ ID ที่ถูกต้อง", "tr_TR": "Arayüz hatası: Seçilen oyun geçerli bir title ID'ye sahip değil", "uk_UA": "Помилка інтерфейсу: вибрана гра не мала дійсного ідентифікатора назви", @@ -12350,6 +13789,7 @@ "pl_PL": "Nie znaleziono prawidłowego firmware'u systemowego w {0}.", "pt_BR": "Um firmware de sistema válido não foi encontrado em {0}.", "ru_RU": "Валидная системная прошивка не найдена в {0}.", + "sv_SE": "Ett giltigt systemfirmware hittades inte i {0}.", "th_TH": "ไม่พบเฟิร์มแวร์ของระบบที่ถูกต้อง {0}.", "tr_TR": "{0} da geçerli bir sistem firmware'i bulunamadı.", "uk_UA": "Дійсна прошивка системи не знайдена в {0}.", @@ -12372,8 +13812,9 @@ "ko_KR": "펌웨어 {0} 설치", "no_NO": "Installer fastvare {0}", "pl_PL": "Zainstaluj Firmware {0}", - "pt_BR": "Instalar firmware {0}", + "pt_BR": "Instalar Firmware {0}", "ru_RU": "Установить прошивку {0}", + "sv_SE": "Installera firmware {0}", "th_TH": "ติดตั้งเฟิร์มแวร์ {0}", "tr_TR": "Firmware {0} Yükle", "uk_UA": "Встановити прошивку {0}", @@ -12398,11 +13839,12 @@ "pl_PL": "Wersja systemu {0} zostanie zainstalowana.", "pt_BR": "A versão do sistema {0} será instalada.", "ru_RU": "Будет установлена версия прошивки {0}.", + "sv_SE": "Systemversion {0} kommer att installeras.", "th_TH": "ระบบเวอร์ชั่น {0} ได้รับการติดตั้งเร็วๆ นี้", "tr_TR": "Sistem sürümü {0} yüklenecek.", "uk_UA": "Буде встановлено версію системи {0}.", "zh_CN": "即将安装系统固件版本 {0} 。", - "zh_TW": "將安裝系統版本 {0}。" + "zh_TW": "即將安裝系統韌體版本 {0}。" } }, { @@ -12415,18 +13857,19 @@ "es_ES": "\n\nEsto reemplazará la versión de sistema actual, {0}.", "fr_FR": "\n\nCela remplacera la version actuelle du système {0}.", "he_IL": "\n\nזה יחליף את גרסת המערכת הנוכחית {0}.", - "it_IT": "\n\nQuesta sostituirà l'attuale versione di sistema {0}.", + "it_IT": "\n\nQuesta sostituirà l'attuale versione del sistema ({0}).", "ja_JP": "\n\n現在のシステムバージョン {0} を置き換えます.", "ko_KR": "\n\n현재 시스템 버전 {0}을(를) 대체합니다.", "no_NO": "\n\nDette erstatter den gjeldende systemversjonen {0}.", "pl_PL": "\n\nZastąpi to obecną wersję systemu {0}.", "pt_BR": "\n\nIsso substituirá a versão do sistema atual {0}.", "ru_RU": "\n\nЭто заменит текущую версию прошивки {0}.", + "sv_SE": "\n\nDetta kommer att ersätta aktuella systemversionen {0}.", "th_TH": "\n\nสิ่งนี้จะแทนที่เวอร์ชั่นของระบบเวอร์ชั่นปัจจุบัน {0}.", "tr_TR": "\n\nBu şimdiki sistem sürümünün yerini alacak {0}.", "uk_UA": "\n\nЦе замінить поточну версію системи {0}.", "zh_CN": "\n\n替换当前系统固件版本 {0} 。", - "zh_TW": "\n\n這將取代目前的系統版本 {0}。" + "zh_TW": "\n\n這將取代目前的系統韌體版本 {0}。" } }, { @@ -12446,6 +13889,7 @@ "pl_PL": "\n\nCzy chcesz kontynuować?", "pt_BR": "\n\nDeseja continuar?", "ru_RU": "\n\nПродолжить?", + "sv_SE": "\n\nVill du fortsätta?", "th_TH": "\n\nคุณต้องการดำเนินการต่อหรือไม่?", "tr_TR": "\n\nDevam etmek istiyor musunuz?", "uk_UA": "\n\nВи хочете продовжити?", @@ -12470,6 +13914,7 @@ "pl_PL": "Instalowanie firmware'u...", "pt_BR": "Instalando firmware...", "ru_RU": "Установка прошивки...", + "sv_SE": "Installerar firmware...", "th_TH": "กำลังติดตั้งเฟิร์มแวร์...", "tr_TR": "Firmware yükleniyor...", "uk_UA": "Встановлення прошивки...", @@ -12494,11 +13939,12 @@ "pl_PL": "Wersja systemu {0} została pomyślnie zainstalowana.", "pt_BR": "Versão do sistema {0} instalada com sucesso.", "ru_RU": "Прошивка версии {0} успешно установлена.", + "sv_SE": "Systemversion {0} har installerats.", "th_TH": "ระบบเวอร์ชั่น {0} ติดตั้งเรียบร้อยแล้ว", "tr_TR": "Sistem sürümü {0} başarıyla yüklendi.", "uk_UA": "Версію системи {0} успішно встановлено.", "zh_CN": "成功安装系统固件版本 {0} 。", - "zh_TW": "成功安裝系統版本 {0}。" + "zh_TW": "成功安裝系統韌體版本 {0}。" } }, { @@ -12511,18 +13957,19 @@ "es_ES": "Se halló un archivo Keys inválido en {0}", "fr_FR": "Un fichier de clés invalide a été trouvé dans {0}", "he_IL": "", - "it_IT": "E' stato trovato un file di chiavi invalido ' {0}", + "it_IT": "È stato trovato un file di chiavi non valido in {0}", "ja_JP": "", "ko_KR": "{0}에서 잘못된 키 파일이 발견", "no_NO": "En ugyldig Keys-fil ble funnet i {0}.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Um arquivo Chaves inválido foi encontrado em {0}", + "ru_RU": "В {0} были найдены некорректные ключи", + "sv_SE": "En ogiltig nyckelfil hittades i {0}", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Виявлено неправильний файл ключів у теці {0}", + "zh_CN": "在 {0} 发现了一个无效的密匙文件", + "zh_TW": "找到無效的金鑰檔案 {0}" } }, { @@ -12535,18 +13982,19 @@ "es_ES": "Instalar Keys", "fr_FR": "Installer des clés", "he_IL": "", - "it_IT": "Installa Chavi", + "it_IT": "Installa chiavi", "ja_JP": "", "ko_KR": "설치 키", "no_NO": "Installere nøkler", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Instalar Chaves", + "ru_RU": "Установить ключи", + "sv_SE": "Installera nycklar", "th_TH": "", "tr_TR": "", "uk_UA": "Встановлення Ключів", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "安装密匙", + "zh_TW": "安裝金鑰" } }, { @@ -12559,18 +14007,19 @@ "es_ES": "Un nuevo archivo Keys será instalado.", "fr_FR": "Nouveau fichier de clés sera installé.", "he_IL": "", - "it_IT": "Un nuovo file di Chiavi sarà intallato.", + "it_IT": "Un nuovo file di chiavi sarà installato.", "ja_JP": "", "ko_KR": "새로운 키 파일이 설치됩니다.", "no_NO": "Ny Keys-fil vil bli installert.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O novo arquivo Chaves será instalado", + "ru_RU": "Будут установлены новые ключи.", + "sv_SE": "Ny nyckelfil kommer att installeras.", "th_TH": "", "tr_TR": "", "uk_UA": "Новий файл Ключів буде встановлено", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "将会安装新密匙文件", + "zh_TW": "將會安裝新增的金鑰檔案。" } }, { @@ -12583,18 +14032,19 @@ "es_ES": "\n\nEsto puede reemplazar algunas de las Keys actualmente instaladas.", "fr_FR": "\n\nCela pourrait remplacer les clés qui sont installés.", "he_IL": "", - "it_IT": "\n\nQuesto potrebbe sovrascrivere alcune delle Chiavi già installate.", + "it_IT": "\n\nAlcune delle chiavi già installate potrebbero essere sovrascritte.", "ja_JP": "", "ko_KR": "\n\n이로 인해 현재 설치된 키 중 일부가 대체될 수 있습니다.", "no_NO": "\n\nDette kan erstatte noen av de nåværende installerte nøklene.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "\n\nIsso pode substituir algumas das chaves instaladas atualmente.", + "ru_RU": "\n\nЭто действие может перезаписать установленные ключи.", + "sv_SE": "\n\nDetta kan ersätta några av de redan installerade nycklarna.", "th_TH": "", "tr_TR": "", "uk_UA": "\n\nЦе замінить собою поточні файли Ключів.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "\n\n这也许会替换掉一些当前已安装的密匙", + "zh_TW": "\n\n這將取代部分已安裝的金鑰。" } }, { @@ -12612,13 +14062,14 @@ "ko_KR": "\n\n계속하시겠습니까?", "no_NO": "\n\nVil du fortsette?", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "\n\nVocê quer continuar?", + "ru_RU": "\n\nХотите продолжить?", + "sv_SE": "\n\nVill du fortsätta?", "th_TH": "", "tr_TR": "", "uk_UA": "\n\nВи хочете продовжити?", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "\n\n你想要继续吗?", + "zh_TW": "\n\n是否繼續?" } }, { @@ -12631,18 +14082,19 @@ "es_ES": "Instalando Keys...", "fr_FR": "Installation des clés...", "he_IL": "", - "it_IT": "Installando le chiavi...", + "it_IT": "Installazione delle chiavi...", "ja_JP": "", "ko_KR": "키 설치 중...", "no_NO": "Installere nøkler...", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Instalando Chaves...", + "ru_RU": "Установка ключей...", + "sv_SE": "Installerar nycklar...", "th_TH": "", "tr_TR": "", "uk_UA": "Встановлення Ключів...", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "安装密匙中。。。", + "zh_TW": "正在安裝金鑰..." } }, { @@ -12660,13 +14112,14 @@ "ko_KR": "새로운 키 파일이 성공적으로 설치되었습니다.", "no_NO": "Ny Keys -fil installert.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Novo arquivo de chaves instalado com sucesso.", + "ru_RU": "Новые ключи были успешно установлены.", + "sv_SE": "Ny nyckelfil installerades.", "th_TH": "", "tr_TR": "", "uk_UA": "Нові ключі встановлено.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "已成功安装新密匙文件", + "zh_TW": "成功安裝新增的金鑰檔案。" } }, { @@ -12679,13 +14132,14 @@ "es_ES": "Si eliminas el perfil seleccionado no quedará ningún otro perfil", "fr_FR": "Il n'y aurait aucun autre profil à ouvrir si le profil sélectionné est supprimé", "he_IL": "לא יהיו פרופילים אחרים שייפתחו אם הפרופיל שנבחר יימחק", - "it_IT": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato", + "it_IT": "Non ci sarebbero altri profili da aprire se il profilo selezionato venisse cancellato", "ja_JP": "選択されたプロファイルを削除すると,プロファイルがひとつも存在しなくなります", "ko_KR": "선택한 프로필을 삭제하면 다른 프로필을 열 수 없음", "no_NO": "Det vil ikke være noen profiler å åpnes hvis valgt profil blir slettet", "pl_PL": "Nie będzie innych profili do otwarcia, jeśli wybrany profil zostanie usunięty", "pt_BR": "Não haveria nenhum perfil selecionado se o perfil atual fosse deletado", "ru_RU": "Если выбранный профиль будет удален, другие профили не будут открываться.", + "sv_SE": "Det skulle inte finnas några andra profiler att öppnas om angiven profil tas bort", "th_TH": "จะไม่มีโปรไฟล์อื่นให้เปิดหากโปรไฟล์ที่เลือกถูกลบ", "tr_TR": "Seçilen profil silinirse kullanılabilen başka profil kalmayacak", "uk_UA": "Якщо вибраний профіль буде видалено, інші профілі не відкриватимуться", @@ -12710,6 +14164,7 @@ "pl_PL": "Czy chcesz usunąć wybrany profil", "pt_BR": "Deseja deletar o perfil selecionado", "ru_RU": "Удалить выбранный профиль?", + "sv_SE": "Vill du ta bort den valda profilen", "th_TH": "คุณต้องการลบโปรไฟล์ที่เลือกหรือไม่?", "tr_TR": "Seçilen profili silmek istiyor musunuz", "uk_UA": "Ви хочете видалити вибраний профіль", @@ -12727,13 +14182,14 @@ "es_ES": "Advertencia - Cambios sin guardar", "fr_FR": "Avertissement - Modifications non enregistrées", "he_IL": "אזהרה - שינויים לא שמורים", - "it_IT": "Attenzione - Modifiche Non Salvate", + "it_IT": "Attenzione - Modifiche non salvate", "ja_JP": "警告 - 保存されていない変更", "ko_KR": "경고 - 저장되지 않은 변경 사항", "no_NO": "Advarsel - Ulagrede endringer", "pl_PL": "Uwaga - Niezapisane zmiany", "pt_BR": "Alerta - Alterações não salvas", "ru_RU": "Внимание - Несохраненные изменения", + "sv_SE": "Varning - Ej sparade ändringar", "th_TH": "คำเตือน - มีการเปลี่ยนแปลงที่ไม่ได้บันทึก", "tr_TR": "Uyarı - Kaydedilmemiş Değişiklikler", "uk_UA": "Увага — Незбережені зміни", @@ -12757,7 +14213,8 @@ "no_NO": "Du har gjort endringer i denne brukerprofilen som ikke er lagret.", "pl_PL": "Wprowadziłeś zmiany dla tego profilu użytkownika, które nie zostały zapisane.", "pt_BR": "Você fez alterações para este perfil de usuário que não foram salvas.", - "ru_RU": "В эту учетную запись внесены изменения, которые не были сохранены.", + "ru_RU": "В эту учётную запись внесены изменения, которые не были сохранены.", + "sv_SE": "Du har gjort ändringar i denna användarprofil som inte har sparats.", "th_TH": "คุณได้ทำการเปลี่ยนแปลงโปรไฟล์ผู้ใช้นี้โดยไม่ได้รับการบันทึก", "tr_TR": "Kullanıcı profilinizde kaydedilmemiş değişiklikler var.", "uk_UA": "Ви зробили зміни у цьому профілю користувача які не було збережено.", @@ -12782,6 +14239,7 @@ "pl_PL": "Czy chcesz odrzucić zmiany?", "pt_BR": "Deseja descartar as alterações?", "ru_RU": "Отменить изменения?", + "sv_SE": "Vill du förkasta dina ändringar?", "th_TH": "คุณต้องการทิ้งการเปลี่ยนแปลงของคุณหรือไม่?", "tr_TR": "Yaptığınız değişiklikleri iptal etmek istediğinize emin misiniz?", "uk_UA": "Бажаєте скасувати зміни?", @@ -12806,6 +14264,7 @@ "pl_PL": "Aktualne ustawienia kontrolera zostały zaktualizowane.", "pt_BR": "As configurações de controle atuais foram atualizadas.", "ru_RU": "Текущие настройки управления обновлены.", + "sv_SE": "Aktuella kontrollerinställningar har uppdaterats.", "th_TH": "การตั้งค่าคอนโทรลเลอร์ปัจจุบันได้รับการอัปเดตแล้ว", "tr_TR": "Geçerli kumanda seçenekleri güncellendi.", "uk_UA": "Поточні налаштування контролера оновлено.", @@ -12830,6 +14289,7 @@ "pl_PL": "Czy chcesz zapisać?", "pt_BR": "Deseja salvar?", "ru_RU": "Сохранить?", + "sv_SE": "Vill du spara?", "th_TH": "คุณต้องการบันทึกหรือไม่?", "tr_TR": "Kaydetmek istiyor musunuz?", "uk_UA": "Ви хочете зберегти?", @@ -12847,13 +14307,14 @@ "es_ES": "{0}. Archivo con error: {1}", "fr_FR": "{0}. Fichier erroné : {1}", "he_IL": "{0}. קובץ שגוי: {1}", - "it_IT": "{0}. Errore File: {1}", + "it_IT": "{0}. Errore file: {1}", "ja_JP": "{0}. エラー発生ファイル: {1}", "ko_KR": "{0}. 오류 파일 : {1}", "no_NO": "{0}. Feilet fil: {1}", "pl_PL": "{0}. Błędny plik: {1}", "pt_BR": "{0}. Arquivo com erro: {1}", "ru_RU": "{0}. Файл с ошибкой: {1}", + "sv_SE": "{0}. Fel i filen: {1}", "th_TH": "{0} ไฟล์เกิดข้อผิดพลาด: {1}", "tr_TR": "{0}. Hatalı Dosya: {1}", "uk_UA": "{0}. Файл з помилкою: {1}", @@ -12878,6 +14339,7 @@ "pl_PL": "Modyfikacja już istnieje", "pt_BR": "O mod já existe", "ru_RU": "Мод уже существует", + "sv_SE": "Modd finns redan", "th_TH": "มีม็อดนี้อยู่แล้ว", "tr_TR": "Mod zaten var", "uk_UA": "Модифікація вже існує", @@ -12902,9 +14364,10 @@ "pl_PL": "Podany katalog nie zawiera modyfikacji!", "pt_BR": "O diretório especificado não contém um mod!", "ru_RU": "Выбранная папка не содержит модов", + "sv_SE": "Den angivna katalogen innehåller inte en modd!", "th_TH": "ไดเร็กทอรีที่ระบุไม่มี ม็อดอยู่!", "tr_TR": "", - "uk_UA": "Вказаний каталог не містить модифікації!", + "uk_UA": "Вказана тека не містить модифікації!", "zh_CN": "指定的目录找不到 MOD 文件!", "zh_TW": "指定資料夾不包含模組!" } @@ -12926,9 +14389,10 @@ "pl_PL": "Nie udało się usunąć: Nie można odnaleźć katalogu nadrzędnego dla modyfikacji \"{0}\"!", "pt_BR": "Falha ao excluir: Não foi possível encontrar o diretório pai do mod \"{0}\"!", "ru_RU": "Невозможно удалить: не удалось найти папку мода \"{0}\"", + "sv_SE": "Misslyckades med att ta bort: Kunde inte hitta föräldrakatalogen för modden \"{0}\"!", "th_TH": "ไม่สามารถลบ: ไม่พบไดเร็กทอรีหลักสำหรับ ม็อด \"{0}\"!", "tr_TR": "Silme Başarısız: \"{0}\" Modu için üst dizin bulunamadı! ", - "uk_UA": "Не видалено: Не знайдено батьківський каталог для модифікації \"{0}\"!", + "uk_UA": "Не видалено: Не знайдено батьківський каталог (теку) для модифікації \"{0}\"!", "zh_CN": "删除失败:找不到 MOD 的父目录“{0}”!", "zh_TW": "刪除失敗: 無法找到模組「{0}」的父資料夾!" } @@ -12950,9 +14414,10 @@ "pl_PL": "Określony plik nie zawiera DLC dla wybranego tytułu!", "pt_BR": "O arquivo especificado não contém DLCs para o título selecionado!", "ru_RU": "Указанный файл не содержит DLC для выбранной игры", + "sv_SE": "Den angivna filen innehåller inte en DLC för angivet spel!", "th_TH": "ไฟล์ที่ระบุไม่มี DLC สำหรับชื่อที่เลือก!", "tr_TR": "Belirtilen dosya seçilen oyun için DLC içermiyor!", - "uk_UA": "Зазначений файл не містить DLC для вибраного заголовку!", + "uk_UA": "Зазначений файл не містить DLC для обраної гри!", "zh_CN": "选择的文件不是当前游戏的 DLC!", "zh_TW": "指定檔案不包含所選遊戲的 DLC!" } @@ -12974,6 +14439,7 @@ "pl_PL": "Masz włączone rejestrowanie śledzenia, które jest przeznaczone tylko dla programistów.", "pt_BR": "Os logs de depuração estão ativos, esse recurso é feito para ser usado apenas por desenvolvedores.", "ru_RU": "У вас включено ведение журнала отладки, предназначенное только для разработчиков.", + "sv_SE": "Du har spårloggning aktiverat som endast är designat att användas av utvecklare.", "th_TH": "คุณได้เปิดใช้งานการบันทึกการติดตาม ซึ่งออกแบบมาเพื่อให้นักพัฒนาใช้เท่านั้น", "tr_TR": "Sadece geliştiriler için dizayn edilen Trace Loglama seçeneği etkin.", "uk_UA": "Ви увімкнули журнал налагодження, призначений лише для розробників.", @@ -12997,7 +14463,8 @@ "no_NO": "For optimal ytelse er det anbefalt å deaktivere spor-logging. Ønsker du å deaktivere spor-logging nå?", "pl_PL": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie rejestrowania śledzenia. Czy chcesz teraz wyłączyć rejestrowanie śledzenia?", "pt_BR": "Para melhor performance, é recomendável desabilitar os logs de depuração. Gostaria de desabilitar os logs de depuração agora?", - "ru_RU": "Для оптимальной производительности рекомендуется отключить ведение журнала отладки. Хотите отключить ведение журнала отладки?", + "ru_RU": "Для оптимальной производительности рекомендуется отключить ведение журнала отладки. Хотите отключить?", + "sv_SE": "Det rekommenderas att inaktivera spårloggning för optimal prestanda. Vill du inaktivera spårloggning nu?", "th_TH": "เพื่อประสิทธิภาพสูงสุด ขอแนะนำให้ปิดใช้งานการบันทึกการติดตาม คุณต้องการปิดใช้การบันทึกการติดตามตอนนี้หรือไม่?", "tr_TR": "En iyi performans için trace loglama'nın devre dışı bırakılması tavsiye edilir. Trace loglama seçeneğini şimdi devre dışı bırakmak ister misiniz?", "uk_UA": "Для оптимальної продуктивності рекомендується вимкнути ведення журналу налагодження. Ви хочете вимкнути ведення журналу налагодження зараз?", @@ -13022,6 +14489,7 @@ "pl_PL": "Masz włączone zrzucanie shaderów, które jest przeznaczone tylko dla programistów.", "pt_BR": "O despejo de shaders está ativo, esse recurso é feito para ser usado apenas por desenvolvedores.", "ru_RU": "У вас включен дамп шейдеров, который предназначен только для разработчиков.", + "sv_SE": "Du har aktiverat shader dumping som endast är designat att användas av utvecklare.", "th_TH": "คุณได้เปิดใช้งาน การดัมพ์เชเดอร์ ซึ่งออกแบบมาเพื่อให้นักพัฒนาใช้งานเท่านั้น", "tr_TR": "Sadece geliştiriler için dizayn edilen Shader Dumping seçeneği etkin.", "uk_UA": "Ви увімкнули скидання шейдерів, призначений лише для розробників.", @@ -13046,6 +14514,7 @@ "pl_PL": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie zrzucania shaderów. Czy chcesz teraz wyłączyć zrzucanie shaderów?", "pt_BR": "Para melhor performance, é recomendável desabilitar o despejo de shaders. Gostaria de desabilitar o despejo de shaders agora?", "ru_RU": "Для оптимальной производительности рекомендуется отключить дамп шейдеров. Хотите отключить дамп шейдеров?", + "sv_SE": "Det rekommenderas att inaktivera shader dumping för optimal prestanda. Vill du inaktivera shader dumping nu?", "th_TH": "เพื่อประสิทธิภาพสูงสุด ขอแนะนำให้ปิดใช้การดัมพ์เชเดอร์ คุณต้องการปิดการใช้งานการ ดัมพ์เชเดอร์ ตอนนี้หรือไม่?", "tr_TR": "En iyi performans için Shader Dumping'in devre dışı bırakılması tavsiye edilir. Shader Dumping seçeneğini şimdi devre dışı bırakmak ister misiniz?", "uk_UA": "Для оптимальної продуктивності рекомендується вимкнути скидання шейдерів. Ви хочете вимкнути скидання шейдерів зараз?", @@ -13070,6 +14539,7 @@ "pl_PL": "Gra została już załadowana", "pt_BR": "Um jogo já foi carregado", "ru_RU": "Игра уже загружена", + "sv_SE": "Ett spel har redan lästs in", "th_TH": "ทำการโหลดเกมเรียบร้อยแล้ว", "tr_TR": "Bir oyun zaten yüklendi", "uk_UA": "Гру вже завантажено", @@ -13094,6 +14564,7 @@ "pl_PL": "Zatrzymaj emulację lub zamknij emulator przed uruchomieniem innej gry.", "pt_BR": "Por favor, pare a emulação ou feche o emulador antes de abrir outro jogo.", "ru_RU": "Пожалуйста, остановите эмуляцию или закройте эмулятор перед запуском другой игры.", + "sv_SE": "Stoppa emuleringen eller stäng emulatorn innan du startar ett annat spel.", "th_TH": "โปรดหยุดการจำลอง หรือปิดโปรแกรมจำลองก่อนที่จะเปิดเกมอื่น", "tr_TR": "Lütfen yeni bir oyun açmadan önce emülasyonu durdurun veya emülatörü kapatın.", "uk_UA": "Зупиніть емуляцію або закрийте емулятор перед запуском іншої гри.", @@ -13118,6 +14589,7 @@ "pl_PL": "Określony plik nie zawiera aktualizacji dla wybranego tytułu!", "pt_BR": "O arquivo especificado não contém atualizações para o título selecionado!", "ru_RU": "Указанный файл не содержит обновлений для выбранного приложения", + "sv_SE": "Angiven fil innehåller inte en uppdatering för angivet spel!", "th_TH": "ไฟล์ที่ระบุไม่มีการอัพเดตสำหรับชื่อเรื่องที่เลือก!", "tr_TR": "Belirtilen dosya seçilen oyun için güncelleme içermiyor!", "uk_UA": "Зазначений файл не містить оновлення для вибраного заголовка!", @@ -13140,8 +14612,9 @@ "ko_KR": "경고 - 후단부 스레딩", "no_NO": "Advarsel - Backend Tråd", "pl_PL": "Ostrzeżenie — Wątki Backend", - "pt_BR": "Alerta - Threading da API gráfica", + "pt_BR": "Alerta - Enfileiramento do Renderizador Gráfico", "ru_RU": "Предупреждение: многопоточность в бэкенде", + "sv_SE": "Varning - Backend Threading", "th_TH": "คำเตือน - การทำเธรดแบ็กเอนด์", "tr_TR": "Uyarı - Backend Threading", "uk_UA": "Попередження - потокове керування сервером", @@ -13165,7 +14638,8 @@ "no_NO": "Ryujinx må startes på nytt etter at dette alternativet er endret slik at det tas i bruk helt. Avhengig av plattformen din, må du kanskje manuelt skru av driveren's egen flertråder når du bruker Ryujinx's.", "pl_PL": "Ryujinx musi zostać ponownie uruchomiony po zmianie tej opcji, aby działał w pełni. W zależności od platformy może być konieczne ręczne wyłączenie sterownika wielowątkowości podczas korzystania z Ryujinx.", "pt_BR": "Ryujinx precisa ser reiniciado após mudar essa opção para que ela tenha efeito. Dependendo da sua plataforma, pode ser preciso desabilitar o multithreading do driver de vídeo quando usar o Ryujinx.", - "ru_RU": "Для применения этой настройки необходимо перезапустить Ryujinx. В зависимости от используемой вами операционной системы вам может потребоваться вручную отключить многопоточность драйвера при использовании Ryujinx.", + "ru_RU": "Для применения этой настройки необходимо перезапустить Ryujinx. В зависимости от используемой вами операционной системы, вам может потребоваться вручную отключить многопоточность драйвера при использовании Ryujinx.", + "sv_SE": "Ryujinx måste startas om efter att denna inställning ändras för att verkställa den. Beroende på din plattform så kanske du måste manuellt inaktivera drivrutinens egna multithreading när Ryujinx används.", "th_TH": "Ryujinx ต้องรีสตาร์ทหลังจากเปลี่ยนตัวเลือกนี้จึงจะใช้งานได้อย่างสมบูรณ์ คุณอาจต้องปิดการใช้งาน มัลติเธรด ของไดรเวอร์ของคุณด้วยตนเองเมื่อใช้ Ryujinx ทั้งนี้ขึ้นอยู่กับแพลตฟอร์มของคุณ", "tr_TR": "Bu seçeneğin tamamen uygulanması için Ryujinx'in kapatıp açılması gerekir. Kullandığınız işletim sistemine bağlı olarak, Ryujinx'in multithreading'ini kullanırken driver'ınızın multithreading seçeneğini kapatmanız gerekebilir.", "uk_UA": "Ryujinx потрібно перезапустити після зміни цього параметра, щоб він застосовувався повністю. Залежно від вашої платформи вам може знадобитися вручну вимкнути власну багатопотоковість драйвера під час використання Ryujinx.", @@ -13190,6 +14664,7 @@ "pl_PL": "Zamierzasz usunąć modyfikacje: {0}\n\nCzy na pewno chcesz kontynuować?", "pt_BR": "Você está prestes a excluir o mod: {0}\n\nTem certeza de que deseja continuar?", "ru_RU": "Вы сейчас удалите мод: {0}\n\nВы уверены, что хотите продолжить?", + "sv_SE": "Du är på väg att ta bort modden: {0}\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบ ม็อด: {0}\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "tr_TR": "", "uk_UA": "Ви збираєтесь видалити модифікацію: {0}\n\nВи дійсно бажаєте продовжити?", @@ -13214,6 +14689,7 @@ "pl_PL": "Zamierzasz usunąć wszystkie modyfikacje dla wybranego tytułu: {0}\n\nCzy na pewno chcesz kontynuować?", "pt_BR": "Você está prestes a excluir todos os mods para este jogo.\n\nTem certeza de que deseja continuar?", "ru_RU": "Вы сейчас удалите все выбранные моды для этой игры.\n\nВы уверены, что хотите продолжить?", + "sv_SE": "Du är på väg att ta bort alla moddar för detta spel.\n\nÄr du säker på att du vill fortsätta?", "th_TH": "คุณกำลังจะลบม็อดทั้งหมดสำหรับชื่อนี้\n\nคุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "tr_TR": "", "uk_UA": "Ви збираєтесь видалити всі модифікації для цього Додатка.\n\nВи дійсно бажаєте продовжити?", @@ -13237,7 +14713,8 @@ "no_NO": "Funksjoner", "pl_PL": "Funkcje", "pt_BR": "Recursos", - "ru_RU": "Функции & Улучшения", + "ru_RU": "Функции", + "sv_SE": "Funktioner", "th_TH": "คุณสมบัติ", "tr_TR": "Özellikler", "uk_UA": "Особливості", @@ -13260,8 +14737,9 @@ "ko_KR": "그래픽 후단부 다중 스레딩 :", "no_NO": "Grafikk Backend Fleroppgavekjøring", "pl_PL": "Wielowątkowość Backendu Graficznego:", - "pt_BR": "Multithreading da API gráfica:", + "pt_BR": "Multi Enfileiramento do Renderizador Gráfico:", "ru_RU": "Многопоточность графического бэкенда:", + "sv_SE": "Multithreading för grafikbakände:", "th_TH": "มัลติเธรด กราฟิกเบื้องหลัง:", "tr_TR": "Grafik Backend Multithreading:", "uk_UA": "Багатопотоковість графічного сервера:", @@ -13286,6 +14764,7 @@ "pl_PL": "", "pt_BR": "Automático", "ru_RU": "Автоматически", + "sv_SE": "Automatiskt", "th_TH": "อัตโนมัติ", "tr_TR": "Otomatik", "uk_UA": "Авто", @@ -13310,6 +14789,7 @@ "pl_PL": "Wyłączone", "pt_BR": "Desligado", "ru_RU": "Выключено", + "sv_SE": "Av", "th_TH": "ปิดการใช้งาน", "tr_TR": "Kapalı", "uk_UA": "Вимкнути", @@ -13334,6 +14814,7 @@ "pl_PL": "Włączone", "pt_BR": "Ligado", "ru_RU": "Включено", + "sv_SE": "På", "th_TH": "เปิดใช้งาน", "tr_TR": "Açık", "uk_UA": "Увімкнути", @@ -13358,6 +14839,7 @@ "pl_PL": "Tak", "pt_BR": "Sim", "ru_RU": "Да", + "sv_SE": "Ja", "th_TH": "ใช่", "tr_TR": "Evet", "uk_UA": "Так", @@ -13382,6 +14864,7 @@ "pl_PL": "Nie", "pt_BR": "Não", "ru_RU": "Нет", + "sv_SE": "Nej", "th_TH": "ไม่ใช่", "tr_TR": "Hayır", "uk_UA": "Ні", @@ -13406,6 +14889,7 @@ "pl_PL": "Nazwa pliku zawiera nieprawidłowe znaki. Proszę spróbuj ponownie.", "pt_BR": "O nome do arquivo contém caracteres inválidos. Por favor, tente novamente.", "ru_RU": "Имя файла содержит недопустимые символы. Пожалуйста, попробуйте еще раз.", + "sv_SE": "Filnamnet innehåller ogiltiga tecken. Försök igen.", "th_TH": "ชื่อไฟล์ประกอบด้วยอักขระที่ไม่ถูกต้อง กรุณาลองอีกครั้ง", "tr_TR": "Dosya adı geçersiz karakter içeriyor. Lütfen tekrar deneyin.", "uk_UA": "Ім'я файлу містить неприпустимі символи. Будь ласка, спробуйте ще раз.", @@ -13430,6 +14914,7 @@ "pl_PL": "Pauza", "pt_BR": "Pausar", "ru_RU": "Пауза эмуляции", + "sv_SE": "Paus", "th_TH": "หยุดชั่วคราว", "tr_TR": "Durdur", "uk_UA": "Пауза", @@ -13454,6 +14939,7 @@ "pl_PL": "Wznów", "pt_BR": "Resumir", "ru_RU": "Продолжить", + "sv_SE": "Återuppta", "th_TH": "ดำเนินการต่อ", "tr_TR": "Devam Et", "uk_UA": "Продовжити", @@ -13477,7 +14963,8 @@ "no_NO": "Klikk for å åpne Ryujinx nettsiden i din standardnettleser.", "pl_PL": "Kliknij, aby otworzyć stronę Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir o site do Ryujinx no seu navegador padrão.", - "ru_RU": "Нажмите, чтобы открыть веб-сайт Ryujinx", + "ru_RU": "Нажмите, чтобы открыть веб-сайт Ryujinx в браузере", + "sv_SE": "Klicka för att öppna Ryujinx webbsida i din webbläsare.", "th_TH": "คลิกเพื่อเปิดเว็บไซต์ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Ryujinx'in websitesini varsayılan tarayıcınızda açmak için tıklayın.", "uk_UA": "Натисніть, щоб відкрити сайт Ryujinx у браузері за замовчування.", @@ -13502,6 +14989,7 @@ "pl_PL": "Ryujinx nie jest w żaden sposób powiązany z Nintendo™,\nani z żadnym z jej partnerów.", "pt_BR": "Ryujinx não é afiliado com a Nintendo™,\nou qualquer um de seus parceiros, de nenhum modo.", "ru_RU": "Ryujinx никоим образом не связан ни с Nintendo™, ни с кем-либо из ее партнеров.", + "sv_SE": "Ryujinx har ingen koppling till Nintendo™,\neller någon av dess samarbetspartners.", "th_TH": "ทางผู้พัฒนาโปรแกรม Ryujinx ไม่มีส่วนเกี่ยวข้องกับทางบริษัท Nintendo™\nหรือพันธมิตรใดๆ ทั้งสิ้น!", "tr_TR": "Ryujinx, Nintendo™ veya ortaklarıyla herhangi bir şekilde bağlantılı değildir.", "uk_UA": "Ryujinx жодним чином не пов’язаний з Nintendo™,\nчи будь-яким із їхніх партнерів.", @@ -13526,6 +15014,7 @@ "pl_PL": "AmiiboAPI (www.amiiboapi.com) jest używane\nw naszej emulacji Amiibo.", "pt_BR": "AmiiboAPI (www.amiiboapi.com) é usado\nem nossa emulação de Amiibo.", "ru_RU": "Amiibo API (www.amiiboapi.com) используется для эмуляции Amiibo.", + "sv_SE": "AmiiboAPI (www.amiiboapi.com) används\ni vår Amiibo-emulation.", "th_TH": "AmiiboAPI (www.amiiboapi.com) ถูกใช้\nในการจำลอง อะมิโบ ของเรา", "tr_TR": "Amiibo emülasyonumuzda \nAmiiboAPI (www.amiiboapi.com) kullanılmaktadır.", "uk_UA": "AmiiboAPI (www.amiiboapi.com) використовується в нашій емуляції Amiibo.", @@ -13550,9 +15039,10 @@ "pl_PL": "Kliknij, aby otworzyć stronę GitHub Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir a página do GitHub do Ryujinx no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть страницу Ryujinx на GitHub", + "sv_SE": "Klicka för att öppna Ryujinx GitHub-sida i din webbläsare.", "th_TH": "คลิกเพื่อเปิดหน้า Github ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Ryujinx'in GitHub sayfasını varsayılan tarayıcınızda açmak için tıklayın.", - "uk_UA": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері за замовчуванням.", + "uk_UA": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері.", "zh_CN": "在浏览器中打开 Ryujinx 的 GitHub 代码库。", "zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 GitHub 網頁。" } @@ -13574,9 +15064,10 @@ "pl_PL": "Kliknij, aby otworzyć zaproszenie na serwer Discord Ryujinx w domyślnej przeglądarce.", "pt_BR": "Clique para abrir um convite ao servidor do Discord do Ryujinx no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть приглашение на сервер Ryujinx в Discord", + "sv_SE": "Klicka för att öppna en inbjudan till Ryujinx Discord-server i din webbläsare.", "th_TH": "คลิกเพื่อเปิดคำเชิญเข้าสู่เซิร์ฟเวอร์ Discord ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Varsayılan tarayıcınızda Ryujinx'in Discord'una bir davet açmak için tıklayın.", - "uk_UA": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері за замовчуванням.", + "uk_UA": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері.", "zh_CN": "在浏览器中打开 Ryujinx 的 Discord 邀请链接。", "zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 Discord 邀請連結。" } @@ -13598,6 +15089,7 @@ "pl_PL": "O Aplikacji:", "pt_BR": "Sobre:", "ru_RU": "О программе:", + "sv_SE": "Om:", "th_TH": "เกี่ยวกับ:", "tr_TR": "Hakkında:", "uk_UA": "Про програму:", @@ -13615,18 +15107,19 @@ "es_ES": "", "fr_FR": "Ryujinx est un émulateur pour la Nintendo Switch™.\nObtenez le dernières nouvelles sur le Discord.\nLes développeurs qui veulent contribuer peuvent en savoir plus sur notre GitHub ou Discord.", "he_IL": "", - "it_IT": "", + "it_IT": "Ryujinx è un emulatore della console Nintendo Switch™.\nRimani aggiornato sulle ultime novità nel nostro server Discord.\nGli sviluppatori interessati a contribuire possono trovare maggiori informazioni su Discord o sulla nostra pagina GitHub.", "ja_JP": "", "ko_KR": "Ryujinx는 Nintendo Switch™용 에뮬레이터입니다.\n모든 최신 소식을 Discord에서 확인하세요.\n기여에 관심이 있는 개발자는 GitHub 또는 Discord에서 자세한 내용을 확인할 수 있습니다.", "no_NO": "Ryujinx er en emulator for Nintendo SwitchTM.\nVennligst støtt oss på Patreon.\nFå alle de siste nyhetene på vår Twitter eller Discord.\nUtviklere som er interessert i å bidra kan finne ut mer på GitHub eller Discord.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Ryujinx é um emulador de Nintendo Switch™.\nReceba todas as últimas notícias em nosso Discord.\nDesenvolvedores interessados em contribuir podem descobrir mais em nosso GitHub ou Discord.", + "ru_RU": "Ryujinx - это эмулятор для Nintendo Switch™.\nПолучайте все последние новости разработки в нашем Discord.\nРазработчики, заинтересованные в участии, могут узнать больше на нашем GitHub или Discord.", + "sv_SE": "Ryujinx är en emulator för Nintendo Switch™.\nFå de senaste nyheterna via vår Discord.\nUtvecklare som är intresserade att bidra kan hitta mer info på vår GitHub eller Discord.", "th_TH": "", "tr_TR": "", - "uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОтримуйте всі останні новини в нашому Discord.\nРозробники, які хочуть зробити внесок, можуть дізнатися більше на нашому GitHub або в Discord.", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОстанні новини можна отримати в нашому Discord.\nРозробники, що бажають долучитись до розробки та зробити свій внесок, можуть отримати більше інформації на нашому GitHub або в Discord.", + "zh_CN": "Ryujinx 是一个 Nintendo Switch™ 模拟器。\n有兴趣做出贡献的开发者可以在我们的 GitHub 或 Discord 上了解更多信息。\n", + "zh_TW": "Ryujinx 是一款 Nintendo Switch™ 模擬器。\n關注我們的 Discord 取得所有最新消息。\n對於有興趣貢獻的開發者,可以在我們的 GitHub 或 Discord 上了解更多資訊。" } }, { @@ -13646,6 +15139,7 @@ "pl_PL": "Utrzymywany Przez:", "pt_BR": "Mantido por:", "ru_RU": "Разработка:", + "sv_SE": "Underhålls av:", "th_TH": "ได้รับการดูแลโดย:", "tr_TR": "Geliştiriciler:", "uk_UA": "Підтримується:", @@ -13663,18 +15157,19 @@ "es_ES": "", "fr_FR": "Anciennement Maintenu par :", "he_IL": "", - "it_IT": "", + "it_IT": "Mantenuto in precedenza da:", "ja_JP": "", "ko_KR": "이전 관리자 :", "no_NO": "Tidligere vedlikeholdt av:", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Anteriormente mantido por:", + "ru_RU": "Поддержка:", + "sv_SE": "Underhölls tidigare av:", "th_TH": "", "tr_TR": "", "uk_UA": "Минулі розробники:", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "曾经的维护者:", + "zh_TW": "過往的維護者:" } }, { @@ -13694,6 +15189,7 @@ "pl_PL": "Kliknij, aby otworzyć stronę Współtwórcy w domyślnej przeglądarce.", "pt_BR": "Clique para abrir a página de contribuidores no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть страницу с участниками", + "sv_SE": "Klicka för att öppna sidan över personer som bidragit till projektet i din webbläsare.", "th_TH": "คลิกเพื่อเปิดหน้าผู้มีส่วนร่วมบนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Katkıda bulunanlar sayfasını varsayılan tarayıcınızda açmak için tıklayın.", "uk_UA": "Натисніть, щоб відкрити сторінку співавторів у вашому браузері за замовчування.", @@ -13718,6 +15214,7 @@ "pl_PL": "Seria Amiibo", "pt_BR": "Franquia Amiibo", "ru_RU": "Серия Amiibo", + "sv_SE": "Amiibo-serie", "th_TH": "", "tr_TR": "Amiibo Serisi", "uk_UA": "Серія Amiibo", @@ -13742,6 +15239,7 @@ "pl_PL": "Postać", "pt_BR": "Personagem", "ru_RU": "Персонаж", + "sv_SE": "Karaktär", "th_TH": "ตัวละคร", "tr_TR": "Karakter", "uk_UA": "Персонаж", @@ -13766,6 +15264,7 @@ "pl_PL": "Zeskanuj", "pt_BR": "Escanear", "ru_RU": "Сканировать", + "sv_SE": "Skanna den", "th_TH": "สแกนเลย", "tr_TR": "Tarat", "uk_UA": "Сканувати", @@ -13788,8 +15287,9 @@ "ko_KR": "모든 Amiibo 표시", "no_NO": "Vis alle Amiibo", "pl_PL": "Pokaż Wszystkie Amiibo", - "pt_BR": "Exibir todos os Amiibos", + "pt_BR": "Exibir Todos os Amiibos", "ru_RU": "Показать все Amiibo", + "sv_SE": "Visa alla Amiibo", "th_TH": "แสดง Amiibo ทั้งหมด", "tr_TR": "Tüm Amiibo'ları Göster", "uk_UA": "Показати всі Amiibo", @@ -13812,12 +15312,13 @@ "ko_KR": "핵 : 무작위 태그 Uuid 사용", "no_NO": "Hack: Bruk tilfeldig tag-Uuid", "pl_PL": "Hack: Użyj losowego UUID tagu", - "pt_BR": "Hack: Usar Uuid de tag aleatório", + "pt_BR": "Hack: Usar Uuid de tag Aleatório", "ru_RU": "Хак: Использовать случайный тег Uuid", + "sv_SE": "Hack: Använd slumpmässig tagg för Uuid", "th_TH": "แฮ็ค: สุ่มแท็ก Uuid", "tr_TR": "Hack: Rastgele bir Uuid kullan", "uk_UA": "Хитрість: Використовувати випадковий тег Uuid", - "zh_CN": "修改:使用随机生成的Amiibo ID", + "zh_CN": "修改:使用随机生成的 Amiibo ID", "zh_TW": "補釘修正:使用隨機標記的 Uuid" } }, @@ -13838,6 +15339,7 @@ "pl_PL": "Włączone", "pt_BR": "Habilitado", "ru_RU": "Включено", + "sv_SE": "Aktiverad", "th_TH": "เปิดใช้งานแล้ว", "tr_TR": "Etkin", "uk_UA": "Увімкнено", @@ -13860,8 +15362,9 @@ "ko_KR": "타이틀 ID", "no_NO": "Tittel ID", "pl_PL": "ID Tytułu", - "pt_BR": "ID do título", + "pt_BR": "ID do Título", "ru_RU": "ID приложения", + "sv_SE": "Titel-ID", "th_TH": "ชื่อไอดี", "tr_TR": "Başlık ID", "uk_UA": "ID заголовка", @@ -13884,8 +15387,9 @@ "ko_KR": "컨테이너 경로", "no_NO": "Beholder bane", "pl_PL": "Ścieżka Kontenera", - "pt_BR": "Caminho do container", + "pt_BR": "Caminho do Contêiner", "ru_RU": "Путь к контейнеру", + "sv_SE": "Container-sökväg", "th_TH": "คอนเทนเนอร์เก็บไฟล์", "tr_TR": "Container Yol", "uk_UA": "Шлях до контейнеру", @@ -13908,8 +15412,9 @@ "ko_KR": "전체 경로", "no_NO": "Fullstendig bane", "pl_PL": "Pełna Ścieżka", - "pt_BR": "Caminho completo", + "pt_BR": "Caminho Completo", "ru_RU": "Полный путь", + "sv_SE": "Fullständig sökväg", "th_TH": "ที่เก็บไฟล์แบบเต็ม", "tr_TR": "Tam Yol", "uk_UA": "Повний шлях", @@ -13932,8 +15437,9 @@ "ko_KR": "모두 제거", "no_NO": "Fjern alle", "pl_PL": "Usuń Wszystkie", - "pt_BR": "Remover todos", + "pt_BR": "Remover Todos", "ru_RU": "Удалить все", + "sv_SE": "Ta bort allt", "th_TH": "ลบทั้งหมด", "tr_TR": "Tümünü kaldır", "uk_UA": "Видалити все", @@ -13956,8 +15462,9 @@ "ko_KR": "모두 활성화", "no_NO": "Aktiver alle", "pl_PL": "Włącz Wszystkie", - "pt_BR": "Habilitar todos", + "pt_BR": "Habilitar Todos", "ru_RU": "Включить все", + "sv_SE": "Aktivera allt", "th_TH": "เปิดใช้งานทั้งหมด", "tr_TR": "Tümünü Aktif Et", "uk_UA": "Увімкнути всі", @@ -13980,8 +15487,9 @@ "ko_KR": "모두 비활성화", "no_NO": "Deaktiver alle", "pl_PL": "Wyłącz Wszystkie", - "pt_BR": "Desabilitar todos", + "pt_BR": "Desabilitar Todos", "ru_RU": "Отключить все", + "sv_SE": "Inaktivera allt", "th_TH": "ปิดใช้งานทั้งหมด", "tr_TR": "Tümünü Devre Dışı Bırak", "uk_UA": "Вимкнути всі", @@ -14006,6 +15514,7 @@ "pl_PL": "Usuń wszystko", "pt_BR": "Apagar Tudo", "ru_RU": "Удалить все", + "sv_SE": "Ta bort allt", "th_TH": "ลบทั้งหมด", "tr_TR": "Hepsini Sil", "uk_UA": "Видалити все", @@ -14028,8 +15537,9 @@ "ko_KR": "언어 변경", "no_NO": "Endre språk", "pl_PL": "Zmień język", - "pt_BR": "Mudar idioma", + "pt_BR": "Mudar Idioma", "ru_RU": "Сменить язык", + "sv_SE": "Byt språk", "th_TH": "เปลี่ยนภาษา", "tr_TR": "Dili Değiştir", "uk_UA": "Змінити мову", @@ -14052,8 +15562,9 @@ "ko_KR": "파일 형식 표시", "no_NO": "Vis Filtyper", "pl_PL": "Pokaż typy plików", - "pt_BR": "Mostrar tipos de arquivo", + "pt_BR": "Mostrar Tipos de Arquivo", "ru_RU": "Показывать форматы файлов", + "sv_SE": "Visa filtyper", "th_TH": "แสดงประเภทของไฟล์", "tr_TR": "Dosya Uzantılarını Göster", "uk_UA": "Показати типи файлів", @@ -14078,6 +15589,7 @@ "pl_PL": "Sortuj", "pt_BR": "Ordenar", "ru_RU": "Сортировка", + "sv_SE": "Sortera", "th_TH": "เรียงลำดับ", "tr_TR": "Sırala", "uk_UA": "Сортувати", @@ -14100,8 +15612,9 @@ "ko_KR": "이름 표시", "no_NO": "Vis navn", "pl_PL": "Pokaż Nazwy", - "pt_BR": "Exibir nomes", + "pt_BR": "Exibir Nomes", "ru_RU": "Показывать названия", + "sv_SE": "Visa namn", "th_TH": "แสดงชื่อ", "tr_TR": "İsimleri Göster", "uk_UA": "Показати назви", @@ -14126,9 +15639,10 @@ "pl_PL": "Ulubione", "pt_BR": "Favorito", "ru_RU": "Избранное", + "sv_SE": "Favorit", "th_TH": "สิ่งที่ชื่นชอบ", "tr_TR": "Favori", - "uk_UA": "Вибрані", + "uk_UA": "Обрані", "zh_CN": "收藏", "zh_TW": "我的最愛" } @@ -14150,6 +15664,7 @@ "pl_PL": "Rosnąco", "pt_BR": "Ascendente", "ru_RU": "По возрастанию", + "sv_SE": "Stigande", "th_TH": "จากน้อยไปมาก", "tr_TR": "Artan", "uk_UA": "За зростанням", @@ -14174,6 +15689,7 @@ "pl_PL": "Malejąco", "pt_BR": "Descendente", "ru_RU": "По убыванию", + "sv_SE": "Fallande", "th_TH": "จากมากไปน้อย", "tr_TR": "Azalan", "uk_UA": "За спаданням", @@ -14197,7 +15713,8 @@ "no_NO": "Funksjoner & forbedringer", "pl_PL": "Funkcje i Ulepszenia", "pt_BR": "Recursos & Melhorias", - "ru_RU": "Функции", + "ru_RU": "Функции и улучшения", + "sv_SE": "Funktioner och förbättringar", "th_TH": "คุณสมบัติ และ การเพิ่มประสิทธิภาพ", "tr_TR": "Özellikler & İyileştirmeler", "uk_UA": "Функції та вдосконалення", @@ -14220,8 +15737,9 @@ "ko_KR": "오류 창", "no_NO": "Feilvindu", "pl_PL": "Okno Błędu", - "pt_BR": "Janela de erro", + "pt_BR": "Janela de Erro", "ru_RU": "Окно ошибки", + "sv_SE": "Felfönster", "th_TH": "หน้าต่างแสดงข้อผิดพลาด", "tr_TR": "Hata Penceresi", "uk_UA": "Вікно помилок", @@ -14244,8 +15762,9 @@ "ko_KR": "\"현재 진행 중인\" 디스코드 활동에 Ryujinx를 표시할지 여부를 선택", "no_NO": "Velg om Ryujinx skal vises på din \"spillende\" Discord aktivitet eller ikke", "pl_PL": "Wybierz, czy chcesz wyświetlać Ryujinx w swojej \"aktualnie grane\" aktywności Discord", - "pt_BR": "Habilita ou desabilita Discord Rich Presence", - "ru_RU": "Включает или отключает отображение статуса \"Играет в игру\" в Discord", + "pt_BR": "Escolha se deseja mostrar Ryujinx ou não na sua atividade do Discord quando estiver usando-o", + "ru_RU": "Включает или отключает отображение статуса «Играет в игру» в Discord", + "sv_SE": "Välj huruvida Ryujinx ska visas på din \"spelar för tillfället\" Discord-aktivitet", "th_TH": "เลือกว่าจะแสดง Ryujinx ในกิจกรรม Discord \"ที่กำลังเล่นอยู่\" ของคุณหรือไม่?", "tr_TR": "Ryujinx'i \"şimdi oynanıyor\" Discord aktivitesinde göstermeyi veya göstermemeyi seçin", "uk_UA": "Виберіть, чи відображати Ryujinx у вашій «поточній грі» в Discord", @@ -14270,9 +15789,10 @@ "pl_PL": "Wprowadź katalog gier aby dodać go do listy", "pt_BR": "Escreva um diretório de jogo para adicionar à lista", "ru_RU": "Введите путь к папке с играми для добавления ее в список выше", + "sv_SE": "Ange en spelkatalog att lägga till i listan", "th_TH": "ป้อนไดเรกทอรี่เกมที่จะทำการเพิ่มลงในรายการ", "tr_TR": "Listeye eklemek için oyun dizini seçin", - "uk_UA": "Введіть каталог ігор, щоб додати до списку", + "uk_UA": "Додайте теку з іграми, щоб додати їх до списку", "zh_CN": "输入要添加的游戏目录", "zh_TW": "輸入要新增到清單中的遊戲資料夾" } @@ -14294,9 +15814,10 @@ "pl_PL": "Dodaj katalog gier do listy", "pt_BR": "Adicionar um diretório de jogo à lista", "ru_RU": "Добавить папку с играми в список", + "sv_SE": "Lägg till en spelkatalog till listan", "th_TH": "เพิ่มไดเรกทอรี่เกมลงในรายการ", "tr_TR": "Listeye oyun dizini ekle", - "uk_UA": "Додати каталог гри до списку", + "uk_UA": "Додати теку з іграми до списку", "zh_CN": "添加游戏目录到列表中", "zh_TW": "新增遊戲資料夾到清單中" } @@ -14318,9 +15839,10 @@ "pl_PL": "Usuń wybrany katalog gier", "pt_BR": "Remover diretório de jogo selecionado", "ru_RU": "Удалить выбранную папку игры", + "sv_SE": "Ta bort vald spelkatalog", "th_TH": "ลบไดเรกทอรี่เกมที่เลือก", "tr_TR": "Seçili oyun dizinini kaldır", - "uk_UA": "Видалити вибраний каталог гри", + "uk_UA": "Видалити вибрану теку гри", "zh_CN": "移除选中的目录", "zh_TW": "移除選取的遊戲資料夾" } @@ -14335,13 +15857,14 @@ "es_ES": "Elige un directorio de carga automática para agregar a la lista", "fr_FR": "Entrez un répertoire de mises à jour/DLC à ajouter à la liste", "he_IL": "", - "it_IT": "Inserisci una directory di \"autoload\" da aggiungere alla lista", + "it_IT": "Inserisci una cartella di caricamento automatico da aggiungere alla lista", "ja_JP": "", "ko_KR": "목록에 추가할 자동 불러오기 디렉터리를 입력", "no_NO": "Angi en autoload-mappe som skal legges til i listen", "pl_PL": "", "pt_BR": "Insira um diretório de carregamento automático para adicionar à lista", - "ru_RU": "", + "ru_RU": "Введите папку автозагрузки для добавления в список", + "sv_SE": "Ange en katalog att automatiskt läsa in till listan", "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ", "tr_TR": "", "uk_UA": "Введіть шлях автозавантаження для додавання до списку", @@ -14359,13 +15882,14 @@ "es_ES": "Agregar un directorio de carga automática a la lista", "fr_FR": "Ajouter un répertoire de mises à jour/DLC à la liste", "he_IL": "", - "it_IT": "Aggiungi una directory di \"autoload\" alla lista", + "it_IT": "Aggiungi una cartella di caricamento automatico alla lista", "ja_JP": "", "ko_KR": "목록에 자동 불러오기 디렉터리 추가", "no_NO": "Legg til en autoload-mappe i listen", "pl_PL": "", "pt_BR": "Adicionar um diretório de carregamento automático à lista", - "ru_RU": "", + "ru_RU": "Добавить папку автозагрузки в список", + "sv_SE": "Lägg till en katalog att automatiskt läsa in till listan", "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ", "tr_TR": "", "uk_UA": "Додайте шлях автозавантаження для додавання до списку", @@ -14383,16 +15907,17 @@ "es_ES": "Eliminar el directorio de carga automática seleccionado", "fr_FR": "Supprimer le répertoire de mises à jour/DLC sélectionné", "he_IL": "", - "it_IT": "Rimuovi la directory di autoload selezionata", + "it_IT": "Rimuovi la cartella di caricamento automatico selezionata", "ja_JP": "", "ko_KR": "선택한 자동 불러오기 디렉터리 제거", "no_NO": "Fjern valgt autoload-mappe", "pl_PL": "", "pt_BR": "Remover o diretório de carregamento automático selecionado", - "ru_RU": "", + "ru_RU": "Убрать папку автозагрузки из списка", + "sv_SE": "Ta bort markerad katalog för automatisk inläsning", "th_TH": "ลบไดเรกทอรีสำหรับโหลดอัตโนมัติที่เลือก", "tr_TR": "", - "uk_UA": "Видалити вибраний каталог автозавантаження", + "uk_UA": "Видалити вибрану теку автозавантаження", "zh_CN": "移除被选中的自动加载目录", "zh_TW": "移除選取的「自動載入 DLC/遊戲更新資料夾」" } @@ -14407,13 +15932,14 @@ "es_ES": "Activa o desactiva los temas personalizados para la interfaz", "fr_FR": "Utilisez un thème personnalisé Avalonia pour modifier l'apparence des menus de l'émulateur", "he_IL": "השתמש בעיצוב מותאם אישית של אבלוניה עבור ה-ממשק הגראפי כדי לשנות את המראה של תפריטי האמולטור", - "it_IT": "Attiva o disattiva temi personalizzati nella GUI", + "it_IT": "Utilizza un tema di Avalonia personalizzato per cambiare l'aspetto dei menù dell'emulatore", "ja_JP": "エミュレータのメニュー外観を変更するためカスタム Avalonia テーマを使用します", "ko_KR": "GUI용 사용자 정의 Avalonia 테마를 사용하여 에뮬레이터 메뉴의 모양 변경", "no_NO": "Bruk et egendefinert Avalonia tema for GUI for å endre utseende til emulatormenyene", "pl_PL": "Użyj niestandardowego motywu Avalonia dla GUI, aby zmienić wygląd menu emulatora", - "pt_BR": "Habilita ou desabilita temas customizados na interface gráfica", + "pt_BR": "Use um tema Avalonia personalizado para a GUI para alterar a aparência dos menus do emulador", "ru_RU": "Включить или отключить пользовательские темы", + "sv_SE": "Använd ett anpassat Avalonia-tema för gränssnittet för att ändra utseendet i emulatormenyerna", "th_TH": "ใช้ธีม Avalonia แบบกำหนดเองสำหรับ GUI เพื่อเปลี่ยนรูปลักษณ์ของเมนูโปรแกรมจำลอง", "tr_TR": "Emülatör pencerelerinin görünümünü değiştirmek için özel bir Avalonia teması kullan", "uk_UA": "Використовуйте користувацьку тему Avalonia для графічного інтерфейсу, щоб змінити вигляд меню емулятора", @@ -14431,13 +15957,14 @@ "es_ES": "Carpeta que contiene los temas personalizados para la interfaz", "fr_FR": "Chemin vers le thème personnalisé de l'interface utilisateur", "he_IL": "נתיב לערכת נושא לממשק גראפי מותאם אישית", - "it_IT": "Percorso al tema GUI personalizzato", + "it_IT": "Percorso al tema dell'interfaccia personalizzato", "ja_JP": "カスタム GUI テーマのパスです", "ko_KR": "사용자 정의 GUI 테마 경로", "no_NO": "Bane til egendefinert GUI-tema", "pl_PL": "Ścieżka do niestandardowego motywu GUI", "pt_BR": "Diretório do tema customizado", - "ru_RU": "Путь к пользовательской теме для интерфейса", + "ru_RU": "Путь к пользовательской теме интерфейса", + "sv_SE": "Sökväg till anpassat gränssnittstema", "th_TH": "ไปยังที่เก็บไฟล์ธีม GUI แบบกำหนดเอง", "tr_TR": "Özel arayüz temasının yolu", "uk_UA": "Шлях до користувацької теми графічного інтерфейсу", @@ -14455,13 +15982,14 @@ "es_ES": "Busca un tema personalizado para la interfaz", "fr_FR": "Parcourir vers un thème personnalisé pour l'interface utilisateur", "he_IL": "חפש עיצוב ממשק גראפי מותאם אישית", - "it_IT": "Sfoglia per cercare un tema GUI personalizzato", + "it_IT": "Scegli un tema dell'interfaccia personalizzato", "ja_JP": "カスタム GUI テーマを参照します", "ko_KR": "사용자 정의 GUI 테마 찾아보기", "no_NO": "Søk etter et egendefinert GUI-tema", "pl_PL": "Wyszukaj niestandardowy motyw GUI", "pt_BR": "Navegar até um tema customizado", "ru_RU": "Просмотр пользовательской темы интерфейса", + "sv_SE": "Bläddra efter ett anpassat gränssnittstema", "th_TH": "เรียกดูธีม GUI ที่กำหนดเอง", "tr_TR": "Özel arayüz teması için göz at", "uk_UA": "Огляд користувацької теми графічного інтерфейсу", @@ -14485,7 +16013,8 @@ "no_NO": "Forankret modus gjør at systemet oppføre seg som en forankret Nintendo Switch. Dette forbedrer grafikkkvaliteten i de fleste spill. Motsatt vil deaktivering av dette gjøre at systemet oppføre seg som en håndholdt Nintendo Switch, noe som reduserer grafikkkvaliteten.\n\nKonfigurer spiller 1 kontroller hvis du planlegger å bruke forankret modus; konfigurer håndholdte kontroller hvis du planlegger å bruke håndholdte modus.\n\nLa PÅ hvis du er usikker.", "pl_PL": "Tryb Zadokowany sprawia, że emulowany system zachowuje się jak zadokowany Nintendo Switch. Poprawia to jakość grafiki w większości gier. I odwrotnie, wyłączenie tej opcji sprawi, że emulowany system będzie zachowywał się jak przenośny Nintendo Switch, zmniejszając jakość grafiki.\n\nSkonfiguruj sterowanie gracza 1, jeśli planujesz używać trybu Zadokowanego; Skonfiguruj sterowanie przenośne, jeśli planujesz używać trybu przenośnego.\n\nPozostaw WŁĄCZONY, jeśli nie masz pewności.", "pt_BR": "O modo TV faz o sistema emulado se comportar como um Nintendo Switch na TV, o que melhora a fidelidade gráfica na maioria dos jogos. Por outro lado, desativar essa opção fará o sistema emulado se comportar como um Nintendo Switch portátil, reduzindo a qualidade gráfica.\n\nConfigure os controles do jogador 1 se planeja usar o modo TV; configure os controles de portátil se planeja usar o modo Portátil.\n\nMantenha ativado se estiver em dúvida.", - "ru_RU": "\"Стационарный\" режим запускает эмулятор, как если бы Nintendo Switch находилась в доке, что улучшает графику и разрешение в большинстве игр. И наоборот, при отключении этого режима эмулятор будет запускать игры в \"Портативном\" режиме, снижая качество графики.\n\nНастройте управление для Игрока 1 если планируете использовать в \"Стационарном\" режиме; настройте портативное управление если планируете использовать эмулятор в \"Портативном\" режиме.\n\nРекомендуется оставить включенным.", + "ru_RU": "\"Стационарный\" режим запускает эмулятор, как если бы Nintendo Switch находилась в доке, что улучшает графику и разрешение в большинстве игр. И наоборот, при отключении этого режима эмулятор будет запускать игры в \"Портативном\" режиме, снижая качество графики.\n\nНастройте управление для Игрока 1 если планируете использовать эмулятор в \"Стационарном\" режиме; настройте портативное управление если планируете использовать эмулятор в \"Портативном\" режиме.\n\nРекомендуется оставить включенным.", + "sv_SE": "Dockat läge gör att det emulerade systemet beter sig som en dockad Nintendo Switch. Detta förbättrar grafiken i de flesta spel. Inaktiveras detta så kommer det emulerade systemet att bete sig som en handhållen Nintendo Switch, vilket reducerar grafikkvaliteten.\n\nKonfigurera kontrollen för Spelare 1 om du planerar att använda dockat läge; konfigurera handhållna kontroller om du planerar att använda handhållet läge.\n\nLämna PÅ om du är osäker.", "th_TH": "ด็อกโหมด ทำให้ระบบจำลองการทำงานเสมือน Nintendo ที่กำลังเชื่อมต่ออยู่ด็อก สิ่งนี้จะปรับปรุงความเสถียรภาพของกราฟิกในเกมส่วนใหญ่ ในทางกลับกัน การปิดใช้จะทำให้ระบบจำลองทำงานเหมือนกับ Nintendo Switch แบบพกพา ส่งผลให้คุณภาพกราฟิกลดลง\n\nแนะนำกำหนดค่าควบคุมของผู้เล่น 1 หากวางแผนที่จะใช้ด็อกโหมด กำหนดค่าการควบคุมแบบ แฮนด์เฮลด์ หากวางแผนที่จะใช้โหมดแฮนด์เฮลด์\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Docked modu emüle edilen sistemin yerleşik Nintendo Switch gibi davranmasını sağlar. Bu çoğu oyunda grafik kalitesini arttırır. Diğer yandan, bu seçeneği devre dışı bırakmak emüle edilen sistemin portatif Ninendo Switch gibi davranmasını sağlayıp grafik kalitesini düşürür.\n\nDocked modu kullanmayı düşünüyorsanız 1. Oyuncu kontrollerini; Handheld modunu kullanmak istiyorsanız portatif kontrollerini konfigüre edin.\n\nEmin değilseniz aktif halde bırakın.", "uk_UA": "У режимі док-станції емульована система веде себе як приєднаний Nintendo Switch. Це покращує точність графіки в більшості ігор. І навпаки, вимкнення цього призведе до того, що емульована система поводитиметься як портативний комутатор Nintendo, погіршуючи якість графіки.\n\nНалаштуйте елементи керування для гравця 1, якщо плануєте використовувати режим док-станції; налаштуйте ручні елементи керування, якщо плануєте використовувати портативний режим.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -14510,6 +16039,7 @@ "pl_PL": "Obsługa bezpośredniego dostępu do klawiatury (HID). Zapewnia dostęp gier do klawiatury jako urządzenia do wprowadzania tekstu.\n\nDziała tylko z grami, które natywnie wspierają użycie klawiatury w urządzeniu Switch hardware.\n\nPozostaw wyłączone w razie braku pewności.", "pt_BR": "Suporte para acesso direto ao teclado (HID). Permite que os jogos acessem seu teclado como um dispositivo de entrada de texto.\n\nFunciona apenas com jogos que suportam o uso de teclado nativamente no hardware do Switch.\n\nDeixe desativado se estiver em dúvida.", "ru_RU": "Поддержка прямого ввода с клавиатуры (HID). Предоставляет игре прямой доступ к клавиатуре в качестве устройства ввода текста.\nРаботает только с играми, которые изначально поддерживают использование клавиатуры с Switch.\nРекомендуется оставить выключенным.", + "sv_SE": "Stöd för direkt tangentbordsåtkomst (HID). Ger spel åtkomst till ditt tangentbord som en textinmatningsenhet.\n\nFungerar endast med spel som har inbyggt stöd för tangentbordsanvändning på Switch-hårdvara.\n\nLämna AV om du är osäker.", "th_TH": "รองรับการเข้าถึงแป้นพิมพ์โดยตรง (HID) ให้เกมเข้าถึงคีย์บอร์ดของคุณเป็นอุปกรณ์ป้อนข้อความ\n\nใช้งานได้กับเกมที่รองรับการใช้งานคีย์บอร์ดบนฮาร์ดแวร์ของ Switch เท่านั้น\n\nหากคุณไม่แน่ใจให้ปิดใช้งานไว้", "tr_TR": "", "uk_UA": "Підтримка прямого доступу до клавіатури (HID). Надає іграм доступ до клавіатури для вводу тексту.\n\nПрацює тільки з іграми, які підтримують клавіатуру на обладнанні Switch.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -14534,9 +16064,10 @@ "pl_PL": "Obsługa bezpośredniego dostępu do myszy (HID). Zapewnia dostęp gier do myszy jako urządzenia wskazującego.\n\nDziała tylko z grami, które natywnie obsługują przyciski myszy w urządzeniu Switch, które są nieliczne i daleko między nimi.\n\nPo włączeniu funkcja ekranu dotykowego może nie działać.\n\nPozostaw wyłączone w razie wątpliwości.", "pt_BR": "Suporte para acesso direto ao mouse (HID). Permite que os jogos acessem seu mouse como um dispositivo de apontamento.\n\nFunciona apenas com jogos que suportam controles de mouse nativamente no hardware do Switch, o que é raro.\n\nQuando ativado, a funcionalidade de tela sensível ao toque pode não funcionar.\n\nDeixe desativado se estiver em dúvida.", "ru_RU": "Поддержка прямого ввода мыши (HID). Предоставляет игре прямой доступ к мыши в качестве указывающего устройства.\nРаботает только с играми, которые изначально поддерживают использование мыши совместно с железом Switch.\nРекомендуется оставить выключенным.", + "sv_SE": "Stöd för direkt musåtkomst (HID). Ger spel åtkomst till din mus som pekdon.\n\nFungerar endast med spel som har inbyggt stöd för muskontroller på Switch-hårdvara, som är endast ett fåtal.\n\nViss pekskärmsfunktionalitet kanske inte fungerar när aktiverat.\n\nLämna AV om du är osäker.", "th_TH": "รองรับการเข้าถึงเมาส์โดยตรง (HID) ให้เกมเข้าถึงเมาส์ของคุณเป็นอุปกรณ์ชี้ตำแหน่ง\n\nใช้งานได้เฉพาะกับเกมที่รองรับการควบคุมเมาส์บนฮาร์ดแวร์ของ Switch เท่านั้น ซึ่งมีอยู่ไม่มากนัก\n\nเมื่อเปิดใช้งาน ฟังก์ชั่นหน้าจอสัมผัสอาจไม่ทำงาน\n\nหากคุณไม่แน่ใจให้ปิดใช้งานไว้", "tr_TR": "", - "uk_UA": "Підтримка прямого доступу до миші (HID). Надає іграм доступ до миші, як пристрій вказування.\n\nПрацює тільки з іграми, які підтримують мишу на обладнанні Switch, їх небагато.\n\nФункціонал сенсорного екрана може не працювати, якщо функція ввімкнена.\n\nЗалиште вимкненим, якщо не впевнені.", + "uk_UA": "Підтримка прямого доступу до миші (HID). Надає іграм доступ до миші, як пристрій вказування.\n\nПрацює тільки з тими іграми, що підтримують мишу на обладнанні Switch (таких небагато).\n\nФункціонал сенсорного екрану може не працювати, якщо увімкнути цю функцію.\n\nЗалиште вимкненим, якщо не впевнені.", "zh_CN": "直接鼠标访问(HID)支持,游戏可以直接访问鼠标作为指针输入设备。\n\n只适用于在 Switch 硬件上原生支持鼠标控制的游戏,这种游戏很少。\n\n启用后,触屏功能可能无法正常工作。\n\n如果不确定,请保持关闭状态。", "zh_TW": "支援滑鼠直接存取 (HID)。遊戲可將滑鼠作為指向裝置使用。\n\n僅適用於在 Switch 硬體上原生支援滑鼠控制的遊戲,這類遊戲很少。\n\n啟用後,觸控螢幕功能可能無法使用。\n\n如果不確定,請保持關閉狀態。" } @@ -14556,8 +16087,9 @@ "ko_KR": "시스템 지역 변경", "no_NO": "Endre systemregion", "pl_PL": "Zmień Region Systemu", - "pt_BR": "Mudar a região do sistema", - "ru_RU": "Сменяет регион прошивки", + "pt_BR": "Mudar a Região do Sistema", + "ru_RU": "Сменяет регион системы", + "sv_SE": "Ändra systemets region", "th_TH": "เปลี่ยนภูมิภาคของระบบ", "tr_TR": "Sistem Bölgesini Değiştir", "uk_UA": "Змінити регіон системи", @@ -14580,8 +16112,9 @@ "ko_KR": "시스템 언어 변경", "no_NO": "Endre systemspråk", "pl_PL": "Zmień język systemu", - "pt_BR": "Mudar o idioma do sistema", - "ru_RU": "Меняет язык прошивки", + "pt_BR": "Mudar o Idioma do Sistema", + "ru_RU": "Меняет язык системы", + "sv_SE": "Ändra systemets språk", "th_TH": "เปลี่ยนภาษาของระบบ", "tr_TR": "Sistem Dilini Değiştir", "uk_UA": "Змінити мову системи", @@ -14604,8 +16137,9 @@ "ko_KR": "시스템 시간대 변경", "no_NO": "Endre systemtidssone", "pl_PL": "Zmień Strefę Czasową Systemu", - "pt_BR": "Mudar o fuso-horário do sistema", - "ru_RU": "Меняет часовой пояс прошивки", + "pt_BR": "Mudar o Fuso-Horário do Sistema", + "ru_RU": "Меняет часовой пояс системы", + "sv_SE": "Ändra systemets tidszon", "th_TH": "เปลี่ยนโซนเวลาของระบบ", "tr_TR": "Sistem Saat Dilimini Değiştir", "uk_UA": "Змінити часовий пояс системи", @@ -14628,11 +16162,12 @@ "ko_KR": "시스템 시간 변경", "no_NO": "Endre systemtid", "pl_PL": "Zmień czas systemowy", - "pt_BR": "Mudar a hora do sistema", - "ru_RU": "Меняет системное время прошивки", + "pt_BR": "Mudar a Data e Hora do Sistema", + "ru_RU": "Меняет системное время системы", + "sv_SE": "Ändra systemtid", "th_TH": "เปลี่ยนเวลาของระบบ", "tr_TR": "Sistem Saatini Değiştir", - "uk_UA": "Змінити час системи", + "uk_UA": "Змінити системний час", "zh_CN": "更改系统时间", "zh_TW": "變更系統時鐘" } @@ -14643,22 +16178,23 @@ "ar_SA": "", "de_DE": "", "el_GR": "", - "en_US": "Resync System Time to match your PC's current date & time.\n\nThis is not an active setting, it can still fall out of sync; in which case just click this button again.", + "en_US": "Sync System Time to match your PC's current date & time.", "es_ES": "", - "fr_FR": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.\n\nCeci n'est pas un paramètrage automatique, la date peut se désynchroniser; dans ce cas là, rappuyer sur le boutton.", + "fr_FR": "Resynchronise la Date du Système pour qu'elle soit la même que celle du PC.", "he_IL": "", - "it_IT": "", + "it_IT": "Sincronizza data e ora del sistema con quelle del PC.", "ja_JP": "", - "ko_KR": "", - "no_NO": "", + "ko_KR": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.", + "no_NO": "Resynkroniser systemtiden slik at den samsvarer med PC-ens gjeldende dato og klokkeslett.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Sincroniza a data e hora do emulador com seu sistema PC", + "ru_RU": "Повторно синхронизирует системное время, чтобы оно соответствовало текущей дате и времени вашего компьютера.", + "sv_SE": "Återsynkronisera systemtiden för att matcha din dators aktuella datum och tid.", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Синхронізувати системний час, щоб він відповідав поточній даті та часу вашого ПК.", + "zh_CN": "重新同步系统时间以匹配您电脑的当前日期和时间。", + "zh_TW": "重新同步系統韌體時間至 PC 目前的日期和時間。" } }, { @@ -14671,16 +16207,17 @@ "es_ES": "Sincronización vertical de la consola emulada. En práctica un limitador del framerate para la mayoría de los juegos; desactivando puede causar que juegos corran a mayor velocidad o que las pantallas de carga tarden más o queden atascados.\n\nSe puede alternar en juego utilizando una tecla de acceso rápido configurable (F1 by default). Recomendamos hacer esto en caso de querer desactivar sincroniziación vertical.\n\nDesactívalo si no sabes qué hacer.", "fr_FR": "La synchronisation verticale de la console émulée. Essentiellement un limiteur de trame pour la majorité des jeux ; le désactiver peut entraîner un fonctionnement plus rapide des jeux ou prolonger ou bloquer les écrans de chargement.\n\nPeut être activé ou désactivé en jeu avec un raccourci clavier de votre choix (F1 par défaut). Nous recommandons de le faire si vous envisagez de le désactiver.\n\nLaissez activé si vous n'êtes pas sûr.", "he_IL": "", - "it_IT": "Sincronizzazione verticale della console Emulata. Essenzialmente un limitatore di frame per la maggior parte dei giochi; disabilitarlo può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata in gioco con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarlo.\n\nLascia ON se non sei sicuro.", + "it_IT": "Sincronizzazione verticale della console emulata. Funziona essenzialmente come un limitatore del framerate per la maggior parte dei giochi; disabilitarla può far girare giochi a velocità più alta, allungare le schermate di caricamento o farle bloccare.\n\nPuò essere attivata mentre giochi con un tasto di scelta rapida (F1 per impostazione predefinita). Ti consigliamo di farlo se hai intenzione di disabilitarla.\n\nNel dubbio, lascia l'opzione attiva.", "ja_JP": "エミュレートされたゲーム機の垂直同期です. 多くのゲームにおいて, フレームリミッタとして機能します. 無効にすると, ゲームが高速で実行されたり, ロード中に時間がかかったり, 止まったりすることがあります.\n\n設定したホットキー(デフォルトではF1)で, ゲーム内で切り替え可能です. 無効にする場合は, この操作を行うことをおすすめします.\n\nよくわからない場合はオンのままにしてください.", "ko_KR": "에뮬레이트된 콘솔의 수직 동기화입니다. 기본적으로 대부분의 게임에서 프레임 제한 기능으로, 비활성화하면 게임이 더 빠른 속도로 실행되거나 로딩 화면이 더 오래 걸리거나 멈출 수 있습니다.\n\n게임 내에서 원하는 단축키(기본값은 F1)로 전환할 수 있습니다. 비활성화하려면 이 작업을 수행하는 것이 좋습니다.\n\n모르면 켬으로 두세요.", "no_NO": "Emuler konsollens loddrett synkronisering. på ett vis en bildefrekvens begrensning for de fleste spill; deaktivering kan få spill til å kjøre med høyere hastighet, eller til å laste skjermene tar lengre tid eller sitter fast.\n\nkan byttes inn i spillet med en hurtigtast for preferansen (F1 som standard). Vi anbefaler å gjøre dette hvis du planlegger å deaktivere dette.\n\nLa være PÅ hvis du er usikker.", "pl_PL": "Synchronizacja pionowa emulowanej konsoli. Zasadniczo ogranicznik klatek dla większości gier; wyłączenie jej może spowodować, że gry będą działać z większą szybkością, ekrany wczytywania wydłużą się lub nawet utkną.\n\nMoże być przełączana w grze za pomocą preferowanego skrótu klawiszowego. Zalecamy to zrobić, jeśli planujesz ją wyłączyć.\n\nW razie wątpliwości pozostaw WŁĄCZONĄ.", "pt_BR": "V-Sync do console emulado. Funciona essencialmente como um limitador de quadros para a maioria dos jogos; desativá-lo pode fazer com que os jogos rodem em uma velocidade mais alta ou que telas de carregamento demorem mais ou travem.\n\nPode ser alternado durante o jogo com uma tecla de atalho de sua preferência (F1 por padrão). Recomendamos isso caso planeje desativá-lo.\n\nMantenha ligado se estiver em dúvida.", "ru_RU": "Эмуляция вертикальной синхронизации консоли, которая ограничивает количество кадров в секунду в большинстве игр; отключение может привести к тому, что игры будут запущены с более высокой частотой кадров, но загрузка игры может занять больше времени, либо игра не запустится вообще.\n\nМожно включать и выключать эту настройку непосредственно в игре с помощью горячих клавиш (F1 по умолчанию). Если планируете отключить вертикальную синхронизацию, рекомендуем настроить горячие клавиши.\n\nРекомендуется оставить включенным.", + "sv_SE": "Emulerade konsollens vertikala synk. I grund och botten en begränsare för bitrutor för de flesta spel; inaktivera den kan orsaka att spel kör på en högre hastighet eller gör att skärmar tar längre tid att läsa eller fastnar i dem.\n\nKan växlas inne i spelet med en snabbtangent som du väljer (F1 som standard). Vi rekommenderar att göra detta om du planerar att inaktivera den.\n\nLämna PÅ om du är osäker.", "th_TH": "Vertical Sync ของคอนโซลจำลอง โดยพื้นฐานแล้วเป็นตัวจำกัดเฟรมสำหรับเกมส่วนใหญ่ การปิดใช้งานอาจทำให้เกมทำงานด้วยความเร็วสูงขึ้น หรือทำให้หน้าจอการโหลดใช้เวลานานขึ้นหรือค้าง\n\nสามารถสลับได้ในเกมด้วยปุ่มลัดตามที่คุณต้องการ (F1 เป็นค่าเริ่มต้น) เราขอแนะนำให้ทำเช่นนี้หากคุณวางแผนที่จะปิดการใช้งาน\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "", - "uk_UA": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.", + "uk_UA": "Емуляція Вертикальної Синхронізації консолі. По суті, це обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.", "zh_CN": "模拟控制台的垂直同步,开启后会降低大部分游戏的帧率。关闭后,可以获得更高的帧率,但也可能导致游戏画面加载耗时更长或卡住。\n\n在游戏中可以使用热键进行切换(默认为 F1 键)。\n\n如果不确定,请保持开启状态。", "zh_TW": "模擬遊戲機的垂直同步。對大多數遊戲來說,它本質上是一個幀率限制器;停用它可能會導致遊戲以更高的速度執行,或使載入畫面耗時更長或卡住。\n\n可以在遊戲中使用快速鍵進行切換 (預設為 F1)。如果您打算停用,我們建議您這樣做。\n\n如果不確定,請保持開啟狀態。" } @@ -14700,11 +16237,12 @@ "ko_KR": "번역된 JIT 함수를 저장하여 게임을 불러올 때마다 번역할 필요가 없도록 합니다.\n\n게임을 처음 부팅한 후 끊김 현상을 줄이고 부팅 시간을 크게 단축합니다.\n\n모르면 켬으로 두세요.", "no_NO": "Lagrer oversatte JIT funksjoner så de ikke trenger og bli oversatt hver gang spillet laster.\n\nKan redusere hakkete spilling og gjør at spillet starter opp raskere ved første oppstart.\n\nLa være PÅ om usikker.", "pl_PL": "Zapisuje przetłumaczone funkcje JIT, dzięki czemu nie muszą być tłumaczone za każdym razem, gdy gra się ładuje.\n\nZmniejsza zacinanie się i znacznie przyspiesza uruchamianie po pierwszym uruchomieniu gry.\n\nJeśli nie masz pewności, pozostaw WŁĄCZONE", - "pt_BR": "Habilita ou desabilita PPTC", + "pt_BR": "Salva funções JIT traduzidas para que elas não precisem ser traduzidas toda vez que o jogo for carregado.\n\nReduz a trepidação e acelera significativamente os tempos de inicialização após a primeira inicialização de um jogo.\n\nDeixe LIGADO se não tiver certeza.", "ru_RU": "Сохраняет скомпилированные JIT-функции для того, чтобы не преобразовывать их по новой каждый раз при запуске игры.\n\nУменьшает статтеры и значительно ускоряет последующую загрузку игр.\n\nРекомендуется оставить включенным.", + "sv_SE": "Sparar översatta JIT-funktioner så att de inte behöver översättas varje gång som spelet läses in.\n\nMinskar stuttering och snabbare på uppstartstiden väsentligt efter första uppstarten av ett spel.\n\nLämna PÅ om du är osäker.", "th_TH": "บันทึกฟังก์ชั่น JIT ที่แปลแล้ว ดังนั้นจึงไม่จำเป็นต้องแปลทุกครั้งที่โหลดเกม\n\nลดอาการกระตุกและเร่งความเร็วการบูตได้อย่างมากหลังจากการบูตครั้งแรกของเกม\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Çevrilen JIT fonksiyonlarını oyun her açıldığında çevrilmek zorunda kalmaması için kaydeder.\n\nTeklemeyi azaltır ve ilk açılıştan sonra oyunların ilk açılış süresini ciddi biçimde hızlandırır.\n\nEmin değilseniz aktif halde bırakın.", - "uk_UA": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.", + "uk_UA": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання (stuttering) та значно прискорює наступні завантаження гри (після першого завантаження).\n\nЗалиште увімкненим, якщо не впевнені.", "zh_CN": "缓存已编译的游戏指令,这样每次游戏加载时就无需重新编译。\n\n可以减少卡顿和启动时间,提高游戏响应速度。\n\n如果不确定,请保持开启状态。", "zh_TW": "儲存已轉譯的 JIT 函數,這樣每次載入遊戲時就無需再轉譯這些函數。\n\n減少遊戲首次啟動後的卡頓現象,並大大加快啟動時間。\n\n如果不確定,請保持開啟狀態。" } @@ -14719,17 +16257,18 @@ "es_ES": "Cargue el PPTC utilizando un tercio de la cantidad de núcleos.", "fr_FR": "Charger le PPTC en utilisant un tiers des coeurs.", "he_IL": "", - "it_IT": "Carica il PPTC usando un terzo dei core.", + "it_IT": "Carica la cache PPTC usando un terzo dei core del processore.", "ja_JP": "", "ko_KR": "코어의 3분의 1을 사용하여 PPTC를 불러옵니다.", "no_NO": "Last inn PPTC med en tredjedel av antall kjerner.", "pl_PL": "", - "pt_BR": "Carregar o PPTC usando um terço da quantidade de núcleos.", - "ru_RU": "", + "pt_BR": "Carrega o PPTC usando um terço da quantidade de núcleos.", + "ru_RU": "Загрузить PPTC, используя треть от количества ядер.", + "sv_SE": "Läs in PPTC med en tredjedel av mängden kärnor.", "th_TH": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์", "tr_TR": "", "uk_UA": "Завантажувати PPTC використовуючи третину від кількості ядер.", - "zh_CN": "使用三分之一的核心数加载PPTC.", + "zh_CN": "使用三分之一的核心数加载 PPTC.", "zh_TW": "使用 CPU 核心數量的三分之一載入 PPTC。" } }, @@ -14748,8 +16287,9 @@ "ko_KR": "게임을 부팅할 때 손상된 파일을 확인하고, 손상된 파일이 감지되면 로그에 해시 오류를 표시합니다.\n\n성능에 영향을 미치지 않으며 문제 해결에 도움이 됩니다.\n\n모르면 켬으로 두세요.", "no_NO": "Sjekker for korrupte filer ved oppstart av et spill, og dersom korrupte filer oppdages, viser en hashfeil i loggen.\n\nhar ingen innvirkning på ytelsen og er ment å hjelpe med feilsøking.\n\nLa være PÅ hvis usikker.", "pl_PL": "Sprawdza pliki podczas uruchamiania gry i jeśli zostaną wykryte uszkodzone pliki, wyświetla w dzienniku błąd hash.\n\nNie ma wpływu na wydajność i ma pomóc w rozwiązywaniu problemów.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Habilita ou desabilita verificação de integridade dos arquivos do jogo", + "pt_BR": "Verifica se há arquivos corrompidos ao inicializar um jogo e, se forem detectados, exibe um erro de hash no log.\n\nNão tem impacto no desempenho e tem como objetivo ajudar na solução de problemas.\n\nDeixe LIGADO se não tiver certeza.", "ru_RU": "Проверяет файлы при загрузке игры и если обнаружены поврежденные файлы, выводит сообщение о поврежденном хэше в журнале.\n\nНе влияет на производительность и необходим для помощи в устранении неполадок.\n\nРекомендуется оставить включенным.", + "sv_SE": "Letar efter skadade filer när ett spel startas upp, och om skadade filer hittas, visas ett kontrollsummefel i loggen.\n\nHar ingen påverkan på prestandan och är tänkt att hjälpa felsökningen.\n\nLämna PÅ om du är osäker.", "th_TH": "ตรวจสอบไฟล์ที่เสียหายเมื่อบูตเกม และหากตรวจพบไฟล์ที่เสียหาย จะแสดงข้อผิดพลาดของแฮชในบันทึก\n\nไม่มีผลกระทบต่อประสิทธิภาพการทำงานและมีไว้เพื่อช่วยในการแก้ไขปัญหา\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Oyun açarken hatalı dosyaların olup olmadığını kontrol eder, ve hatalı dosya bulursa log dosyasında hash hatası görüntüler.\n\nPerformansa herhangi bir etkisi yoktur ve sorun gidermeye yardımcı olur.\n\nEmin değilseniz aktif halde bırakın.", "uk_UA": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -14772,8 +16312,9 @@ "ko_KR": "오디오 렌더링에 사용되는 백엔드를 변경합니다.\n\nSDL2가 선호되는 반면 OpenAL 및 SoundIO는 대체 수단으로 사용됩니다. 더미에는 소리가 나지 않습니다.\n\n모르면 SDL2로 설정하세요.", "no_NO": "Endrer backend brukt til å gjengi lyd.\n\nSDL2 er foretrukket, mens OpenAL og SoundIO brukes som reserveløsning. Dummy kommer ikke til å ha lyd.\n\nSett til SDL2 hvis usikker.", "pl_PL": "Zmienia backend używany do renderowania dźwięku.\n\nSDL2 jest preferowany, podczas gdy OpenAL i SoundIO są używane jako rezerwy. Dummy nie będzie odtwarzać dźwięku.\n\nW razie wątpliwości ustaw SDL2.", - "pt_BR": "Mudar biblioteca de áudio", + "pt_BR": "Altera o módulo usado para renderizar áudio.\n\nSDL2 é o preferido, enquanto OpenAL e SoundIO são usados como fallbacks. Dummy não terá som.\n\nDefina como SDL2 se não tiver certeza.", "ru_RU": "Изменяет используемый аудио бэкенд для рендера звука.\n\nSDL2 является предпочтительным вариантом, в то время как OpenAL и SoundIO используются в качестве резервных.\n\nРекомендуется использование SDL2.", + "sv_SE": "Ändrar bakänden som används för att rendera ljud.\n\nSDL2 är den föredragna, men OpenAL och SoundIO används för att falla tillbaka på. Dummy har inget ljud.\n\nStäll in till SDL2 om du är osäker.", "th_TH": "เปลี่ยนแบ็กเอนด์ที่ใช้ในการเรนเดอร์เสียง\n\nแนะนำเป็น SDL2 ในขณะที่ OpenAL และ SoundIO ถูกใช้เป็นทางเลือกสำรอง ดัมมี่จะไม่มีเสียง\n\nตั้งค่าเป็น SDL2 หากคุณไม่แน่ใจ", "tr_TR": "Ses çıkış motorunu değiştirir.\n\nSDL2 tercih edilen seçenektir, OpenAL ve SoundIO ise alternatif olarak kullanılabilir. Dummy seçeneğinde ses çıkışı olmayacaktır.\n\nEmin değilseniz SDL2 seçeneğine ayarlayın.", "uk_UA": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.", @@ -14796,8 +16337,9 @@ "ko_KR": "게스트 메모리 매핑 및 접속 방법을 변경합니다. 에뮬레이트된 CPU 성능에 큰 영향을 미칩니다.\n\n모르면 호스트 확인 안 함으로 설정합니다.", "no_NO": "Endre hvordan gjesteminne tilordnes og åpnes. Påvirker emulator CPU-ytelsen veldig mye.\n\nSett til HOST UNCHECKED hvis usikker.", "pl_PL": "Zmień sposób mapowania i uzyskiwania dostępu do pamięci gości. Znacznie wpływa na wydajność emulowanego procesora.\n\nUstaw na HOST UNCHECKED, jeśli nie masz pewności.", - "pt_BR": "Muda como a memória do sistema convidado é acessada. Tem um grande impacto na performance da CPU emulada.", - "ru_RU": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить \"Хост не установлен\"", + "pt_BR": "Altera como a memória do convidado é mapeada e acessada. Afeta muito o desempenho da CPU emulada.\n\nDefina como HÓSPEDE SEM VERIFICAÇÃO se não tiver certeza.", + "ru_RU": "Меняет разметку и доступ к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить «Хост не установлен»", + "sv_SE": "Ändra hur gästminne mappas och ges åtkomst till. Påverkar emulerad CPU-prestanda mycket.\n\nStäll in till \"Värd inte kontrollerad\" om du är osäker.", "th_TH": "เปลี่ยนวิธีการเข้าถึงหน่วยความจำของผู้เยี่ยมชม ส่งผลอย่างมากต่อประสิทธิภาพการทำงานของ CPU ที่จำลอง\n\nตั้งค่าเป็น ไม่ได้ตรวจสอบโฮสต์ หากคุณไม่แน่ใจ", "tr_TR": "Guest hafızasının nasıl tahsis edilip erişildiğini değiştirir. Emüle edilen CPU performansını ciddi biçimde etkiler.\n\nEmin değilseniz HOST UNCHECKED seçeneğine ayarlayın.", "uk_UA": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.", @@ -14822,6 +16364,7 @@ "pl_PL": "Użyj tabeli stron oprogramowania do translacji adresów. Najwyższa celność, ale najwolniejsza wydajność.", "pt_BR": "Usar uma tabela de página via software para tradução de endereços. Maior precisão, porém performance mais baixa.", "ru_RU": "Использует таблицу страниц для преобразования адресов. \nСамая высокая точность, но самая низкая производительность.", + "sv_SE": "Använd en programvarubaserad page table för adressöversättning. Högsta noggrannhet men lägsta prestanda.", "th_TH": "ใช้ตารางหน้าซอฟต์แวร์สำหรับการแปลที่อยู่ ความแม่นยำสูงสุดแต่ประสิทธิภาพช้าที่สุด", "tr_TR": "Adres çevirisi için bir işlemci sayfası kullanır. En yüksek doğruluğu ve en yavaş performansı sunar.", "uk_UA": "Використовує програмну таблицю сторінок для перекладу адрес. Найвища точність, але найповільніша продуктивність.", @@ -14846,6 +16389,7 @@ "pl_PL": "Bezpośrednio mapuj pamięć w przestrzeni adresowej hosta. Znacznie szybsza kompilacja i wykonanie JIT.", "pt_BR": "Mapeia memória no espaço de endereço hóspede diretamente. Compilação e execução do JIT muito mais rápida.", "ru_RU": "Прямая разметка памяти в адресном пространстве хоста. \nЗначительно более быстрые запуск и компиляция JIT.", + "sv_SE": "Direkt mappning av minne i host address space. Mycket snabbare JIT-kompilering och körning.", "th_TH": "แมปหน่วยความจำในพื้นที่ที่อยู่โฮสต์โดยตรง การคอมไพล์และดำเนินการของ JIT เร็วขึ้นมาก", "tr_TR": "Hafızayı doğrudan host adres aralığında tahsis eder. Çok daha hızlı JIT derleme ve işletimi sunar.", "uk_UA": "Пряме відображення пам'яті в адресному просторі хосту. Набагато швидша компіляція та виконання JIT.", @@ -14870,6 +16414,7 @@ "pl_PL": "Bezpośrednio mapuj pamięć, ale nie maskuj adresu w przestrzeni adresowej gościa przed uzyskaniem dostępu. Szybciej, ale kosztem bezpieczeństwa. Aplikacja gościa może uzyskać dostęp do pamięci z dowolnego miejsca w Ryujinx, więc w tym trybie uruchamiaj tylko programy, którym ufasz.", "pt_BR": "Mapeia memória diretamente, mas sem limitar o acesso ao espaço de endereçamento do sistema convidado. Mais rápido, porém menos seguro. O aplicativo convidado pode acessar memória de qualquer parte do Ryujinx, então apenas rode programas em que você confia nesse modo.", "ru_RU": "Производит прямую разметку памяти, но не маскирует адрес в гостевом адресном пространстве перед получением доступа. \nБыстро, но небезопасно. Гостевое приложение может получить доступ к памяти из Ryujinx, поэтому в этом режиме рекомендуется запускать только те программы, которым вы доверяете.", + "sv_SE": "Direkt mappning av minne, men maskera inte adressen inom guest address space innan åtkomst. Snabbare men kostar säkerhet. Gästapplikationen kan komma åt minne från överallt i Ryujinx, så kör endast program som du litar på i detta läge.", "th_TH": "แมปหน่วยความจำโดยตรง แต่อย่าตั้งค่าที่อยู่ของผู้เยี่ยมชมก่อนที่จะเข้าถึง เร็วกว่า แต่ต้องแลกกับความปลอดภัย แอปพลิเคชั่นของผู้เยี่ยมชมสามารถเข้าถึงหน่วยความจำได้จากทุกที่ใน Ryujinx แนะนำให้รันเฉพาะโปรแกรมที่คุณเชื่อถือในโหมดนี้", "tr_TR": "Hafızayı doğrudan tahsis eder, ancak host aralığına erişimden önce adresi maskelemez. Daha iyi performansa karşılık emniyetten ödün verir. Misafir uygulama Ryujinx içerisinden istediği hafızaya erişebilir, bu sebeple bu seçenek ile sadece güvendiğiniz uygulamaları çalıştırın.", "uk_UA": "Пряме відображення пам’яті, але не маскує адресу в гостьовому адресному просторі перед доступом. Швидше, але ціною безпеки. Гостьова програма може отримати доступ до пам’яті з будь-якого місця в Ryujinx, тому запускайте в цьому режимі лише програми, яким ви довіряєте.", @@ -14894,6 +16439,7 @@ "pl_PL": "Użyj Hiperwizora zamiast JIT. Znacznie poprawia wydajność, gdy jest dostępny, ale może być niestabilny w swoim obecnym stanie ", "pt_BR": "Usa o Hypervisor em vez de JIT (recompilador dinâmico). Melhora significativamente o desempenho quando disponível, mas pode ser instável no seu estado atual.", "ru_RU": "Использует Hypervisor вместо JIT. Значительно увеличивает производительность, но может работать нестабильно.", + "sv_SE": "Använd hypervisor istället för JIT. Förbättrar prestandan avsevärt när den finns tillgänglig men kan ge ostabilitet i dess aktuella tillstånd.", "th_TH": "ใช้ Hypervisor แทน JIT ปรับปรุงประสิทธิภาพอย่างมากเมื่อพร้อมใช้งาน แต่อาจไม่เสถียรในสถานะปัจจุบัน", "tr_TR": "JIT yerine Hypervisor kullan. Uygun durumlarda performansı büyük oranda arttırır. Ancak şu anki halinde stabil durumda çalışmayabilir.", "uk_UA": "Використання гіпервізор замість JIT. Значно покращує продуктивність, коли доступний, але може бути нестабільним у поточному стані.", @@ -14916,8 +16462,9 @@ "ko_KR": "Switch 개발 모델을 모방하기 위해 8GB DRAM이 포함된 대체 메모리 모드를 활용합니다.\n\n이는 고해상도 텍스처 팩 또는 4K 해상도 모드에만 유용합니다. 성능을 개선하지 않습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Bruker en alternativ minnemodus med 8GiB i DRAM for og etterligne Switch utvikler modeller.\n\nDette er bare nyttig for teksturpakker eller 4k oppløsningsmoduler. Forbedrer IKKE ytelsen.\n\nLa AV hvis usikker.", "pl_PL": "Wykorzystuje alternatywny układ MemoryMode, aby naśladować model rozwojowy Switcha.\n\nJest to przydatne tylko w przypadku pakietów tekstur o wyższej rozdzielczości lub modów w rozdzielczości 4k. NIE poprawia wydajności.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.", - "pt_BR": "Expande a memória do sistema emulado de 4GiB para 6GiB", + "pt_BR": "Utiliza um modo de memória alternativo com 6, 8 ou 12 GB de DRAM para imitar um modelo de desenvolvimento do Switch.\n\nIsso só é útil para pacotes de textura de alta resolução ou mods de resolução 4k. NÃO melhora o desempenho.\n\nDeixe em 4 GB se não tiver certeza.", "ru_RU": "Использует альтернативный макет MemoryMode для имитации использования Nintendo Switch в режиме разработчика.\n\nПолезно только для пакетов текстур с высоким разрешением или модов добавляющих разрешение 4К. Не улучшает производительность.\n\nРекомендуется оставить выключенным.", + "sv_SE": "Använder ett alternativt minnesläge med 8GiB av DRAM för att efterlikna en utvecklingsmodell av Switch.\n\nDetta är endast användbart för texturpaket med högre upplösning eller moddar för 4k-upplösning. Det förbättrar INTE prestandan.\n\nLämna AV om du är osäker.", "th_TH": "ใช้รูปแบบ MemoryMode ทางเลือกเพื่อเลียนแบบโมเดลการพัฒนาสวิตช์\n\nสิ่งนี้มีประโยชน์สำหรับแพ็กพื้นผิวที่มีความละเอียดสูงกว่าหรือม็อดที่มีความละเอียด 4k เท่านั้น\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Emüle edilen sistem hafızasını 4GiB'dan 6GiB'a yükseltir.\n\nBu seçenek yalnızca yüksek çözünürlük doku paketleri veya 4k çözünürlük modları için kullanılır. Performansı artırMAZ!\n\nEmin değilseniz devre dışı bırakın.", "uk_UA": "Використовує альтернативний макет MemoryMode для імітації моделі розробки Switch.\n\nЦе корисно лише для пакетів текстур з вищою роздільною здатністю або модифікацій із роздільною здатністю 4K. НЕ покращує продуктивність.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -14940,37 +16487,39 @@ "ko_KR": "구현되지 않은 Horizon OS 서비스는 무시됩니다. 특정 게임을 부팅할 때, 발생하는 충돌을 우회하는 데 도움이 될 수 있습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Ignorerer ikke implementerte Horisont OS-tjenester. Dette kan hjelpe med å omgå krasj ved oppstart av enkelte spill.\n\nLa AV hvis du er usikker.", "pl_PL": "Ignoruje niezaimplementowane usługi Horizon OS. Może to pomóc w ominięciu awarii podczas uruchamiania niektórych gier.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.", - "pt_BR": "Habilita ou desabilita a opção de ignorar serviços não implementados", + "pt_BR": "Ignora serviços não implementados do Horizon OS. Isso pode ajudar a contornar travamentos ao inicializar certos jogos.\n\nDeixe OFF se não tiver certeza.", "ru_RU": "Игнорирует нереализованные сервисы Horizon в новых прошивках. Эта настройка поможет избежать вылеты при запуске определенных игр.\n\nРекомендуется оставить выключенным.", + "sv_SE": "Ignorerar Horizon OS-tjänster som inte har implementerats. Detta kan avhjälpa krascher när vissa spel startar upp.\n\nLämna AV om du är osäker.", "th_TH": "ละเว้นบริการ Horizon OS ที่ยังไม่ได้ใช้งาน วิธีนี้อาจช่วยในการหลีกเลี่ยงข้อผิดพลาดเมื่อบูตเกมบางเกม\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Henüz programlanmamış Horizon işletim sistemi servislerini görmezden gelir. Bu seçenek belirli oyunların açılırken çökmesinin önüne geçmeye yardımcı olabilir.\n\nEmin değilseniz devre dışı bırakın.", - "uk_UA": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим, якщо не впевнені.", + "uk_UA": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим якщо не впевнені.", "zh_CN": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用了新的未知系统服务,可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后,则无需开启此选项。\n\n如果不确定,请保持关闭状态。", "zh_TW": "忽略未實現的 Horizon OS 服務。這可能有助於在啟動某些遊戲時避免崩潰。\n\n如果不確定,請保持關閉狀態。" } }, { - "ID": "IgnoreAppletTooltip", + "ID": "IgnoreControllerAppletTooltip", "Translations": { - "ar_SA": "لن يظهر مربع الحوار الخارجي \"تطبيق وحدة التحكم\" إذا تم فصل لوحة الألعاب أثناء اللعب. ولن تظهر مطالبة بإغلاق مربع الحوار أو إعداد وحدة تحكم جديدة. وبمجرد إعادة توصيل وحدة التحكم التي تم فصلها سابقًا، ستستأنف اللعبة تلقائيًا.", - "de_DE": "Der externe Dialog \"Controller-Applet\" wird nicht angezeigt, wenn das Gamepad während des Spiels getrennt wird. Es erfolgt keine Aufforderung, den Dialog zu schließen oder einen neuen Controller einzurichten. Sobald der zuvor getrennte Controller wieder angeschlossen wird, wird das Spiel automatisch fortgesetzt.", - "el_GR": "Το εξωτερικό παράθυρο διαλόγου \"Ελεγκτής μικροεφαρμογής\" δεν θα εμφανιστεί εάν το gamepad αποσυνδεθεί κατά τη διάρκεια του παιχνιδιού. Δεν θα σας ζητηθεί να κλείσετε το παράθυρο διαλόγου ή να ρυθμίσετε έναν νέο ελεγκτή. Μόλις επανασυνδεθεί το χειριστήριο που είχε αποσυνδεθεί προηγουμένως, το παιχνίδι θα συνεχιστεί αυτόματα.", - "en_US": "The external dialog \"Controller Applet\" will not appear if the gamepad is disconnected during gameplay. There will be no prompt to close the dialog or set up a new controller. Once the previously disconnected controller is reconnected, the game will automatically resume.", - "es_ES": "El cuadro de diálogo externo \"Applet del controlador\" no aparecerá si el gamepad se desconecta durante el juego. No aparecerá ningún mensaje para cerrar el cuadro de diálogo o configurar un nuevo controlador. Una vez que se vuelva a conectar el controlador que se había desconectado anteriormente, el juego se reanudará automáticamente.", - "fr_FR": "La boîte de dialogue externe \"Programme Manette\" n'apparaîtra pas si la manette est déconnectée en jeu. Il n'y aura aucune boîte de dialogue ouverte pour configurer une nouvelle manette. Une fois que la manette précédemment déconnectée est reconnectée, le jeu reprendra automatiquement. \n\nLaissez désactivé en cas d'incertitude.", - "he_IL": "תיבת הדו-שיח החיצונית \"Controller Applet\" לא תופיע אם ה-Gamepad מנותק במהלך המשחק. לא תהיה הנחיה לסגור את תיבת הדו-שיח או להגדיר בקר חדש. ברגע שהבקר שנותק בעבר יתחבר מחדש, המשחק יתחדש אוטומטית.", - "it_IT": "La finestra di dialogo esterna \"Controller Applet\" non apparirà se il gamepad viene disconnesso durante il gioco. Non ci sarà alcun prompt per chiudere la finestra di dialogo o impostare un nuovo controller. Una volta che il controller disconnesso in precedenza viene ricollegato, il gioco riprenderà automaticamente.", - "ja_JP": "ゲームプレイ中にゲームパッドが切断された場合、外部ダイアログ「コントローラーアプレット」は表示されません。このダイアログを閉じるか、新しいコントローラーを設定するように求めるプロンプトは表示されません。以前に切断されたコントローラーが再接続されると、ゲームは自動的に再開されます。", - "ko_KR": "게임 플레이 중에 게임패드 연결이 끊어지면 외부 대화 상자 \"컨트롤러 애플릿\"이 나타나지 않습니다. 대화 상자를 닫거나 새 컨트롤러를 설정하라는 메시지가 표시되지 않습니다. 이전에 연결이 끊어진 컨트롤러가 다시 연결되면 게임이 자동으로 다시 시작됩니다.", - "no_NO": "Den eksterne dialogboksen «Controller Applet» vises ikke hvis gamepaden kobles fra under spilling. Du blir ikke bedt om å lukke dialogboksen eller konfigurere en ny kontroller. Når den tidligere frakoblede kontrolleren er koblet til igjen, fortsetter spillet automatisk.", - "pl_PL": "Zewnętrzny dialog \"Controller Applet\" nie pojawi się, jeśli gamepad zostanie odłączony podczas rozgrywki. Nie pojawi się monit o zamknięcie dialogu lub skonfigurowanie nowego kontrolera. Po ponownym podłączeniu poprzednio odłączonego kontrolera gra zostanie automatycznie wznowiona.", - "pt_BR": "O diálogo externo \"Controller Applet\" não aparecerá se o gamepad for desconectado durante o jogo. Não haverá prompt para fechar o diálogo ou configurar um novo controle. Assim que o controle desconectado anteriormente for reconectado, o jogo será retomado automaticamente.", - "ru_RU": "Внешний диалог \"Апплет контроллера\" не появится, если геймпад будет отключен во время игры. Не будет предложено закрыть диалог или настроить новый контроллер. После повторного подключения ранее отключенного контроллера игра автоматически возобновится.", - "th_TH": "กล่องโต้ตอบภายนอก \"แอปเพล็ตตัวควบคุม\" จะไม่ปรากฏขึ้นหากแป้นเกมถูกตัดการเชื่อมต่อระหว่างการเล่นเกม จะไม่มีข้อความแจ้งให้ปิดกล่องโต้ตอบหรือตั้งค่าตัวควบคุมใหม่ เมื่อเชื่อมต่อคอนโทรลเลอร์ที่ตัดการเชื่อมต่อก่อนหน้านี้อีกครั้ง เกมจะดำเนินการต่อโดยอัตโนมัติ", - "tr_TR": "Oyun sırasında oyun kumandasının bağlantısı kesilirse, harici \"Controller Applet\" iletişim kutusu görünmez. İletişim kutusunu kapatma veya yeni bir kumanda ayarlama isteği olmaz. Daha önce bağlantısı kesilen kumanda tekrar bağlandığında oyun otomatik olarak devam eder.", - "uk_UA": "Зовнішнє діалогове вікно \"Аплет контролера\" не з’являтиметься, якщо геймпад буде від’єднано під час гри. Не буде запиту закрити діалогове вікно чи налаштувати новий контролер. Після повторного підключення раніше від’єднаного контролера гра автоматично відновиться.", - "zh_CN": "如果游戏手柄在游戏过程中断开连接,则不会出现外部对话框“控制器小程序”。不会提示关闭对话框或设置新控制器。一旦先前断开连接的控制器重新连接,游戏将自动恢复。", - "zh_TW": "如果遊戲手把在遊戲過程中斷開連接,則外部對話方塊「控制器小程式」將不會出現。不會提示關閉對話方塊或設定新控制器。一旦先前斷開的控制器重新連接,遊戲將自動恢復。" + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "The Controller Applet dialog will not appear if the gamepad is disconnected while an application is running.\n\nLeave OFF if unsure.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.", + "ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.", + "zh_CN": "", + "zh_TW": "" } }, { @@ -14983,16 +16532,17 @@ "es_ES": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.", "fr_FR": "Exécute des commandes du backend graphiques sur un second thread.\n\nAccélère la compilation des shaders, réduit les crashs et les lags, améliore les performances sur les pilotes GPU sans support de multithreading. Légère augementation des performances sur les pilotes avec multithreading intégrer.\n\nRéglez sur Auto en cas d'incertitude.", "he_IL": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", - "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Auto.", + "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Automatico.", "ja_JP": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", "ko_KR": "2번째 스레드에서 그래픽 후단부 명령을 실행합니다.\n\n셰이더 컴파일 속도를 높이고, 끊김 현상을 줄이며, 자체 다중 스레딩 지원 없이 GPU 드라이버의 성능을 향상시킵니다. 다중 스레딩이 있는 드라이버에서 성능이 좀 더 좋습니다.\n\n모르면 자동으로 설정합니다.", "no_NO": "Utfører grafikkbackend kommandoer på en annen tråd.\n\nØker hastigheten for shaderkomprimering, reduserer hakking og forbedrer ytelsen til GPU-drivere uten å spre støtten fra sine egne. Litt bedre ytelse på drivere med flertråd.\n\nSett for å AUTO hvis usikker.", "pl_PL": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.", - "pt_BR": "Habilita multithreading do backend gráfico", + "pt_BR": "Executa comandos do renderizador gráfico em um segundo thread.\n\nAcelera a compilação de shader, reduz a gagueira e melhora o desempenho em drivers de GPU sem suporte multithreading próprio. Desempenho ligeiramente melhor em drivers com multithreading.\n\nDefina como AUTO se não tiver certeza.", "ru_RU": "Выполняет команды графического бэкенда на втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах видеоадаптера без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить Автоматически.", + "sv_SE": "Kör kommandon för grafikbakände i en andra tråd.\n\nSnabbar upp shader compilation, minskar stuttering och förbättrar prestandan på GPU-drivrutiner utan stöd för egen multithreading. Något bättre prestanda på drivrutiner med multithreading.\n\nStäll in till AUTO om du är osäker.", "th_TH": "ดำเนินการคำสั่งแบ็กเอนด์กราฟิกบนเธรดที่สอง\n\nเร่งความเร็วการคอมไพล์ ลดการกระตุก และปรับปรุงประสิทธิภาพการทำงานของไดรเวอร์ GPU โดยไม่ต้องรองรับมัลติเธรดในตัว ประสิทธิภาพที่ดีขึ้นเล็กน้อยสำหรับไดรเวอร์ที่มีมัลติเธรด\n\nตั้งเป็น อัตโนมัติ หากคุณไม่แน่ใจ", "tr_TR": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.", - "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто», якщо не впевнені", + "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто» якщо не впевнені", "zh_CN": "在第二个线程上执行图形引擎指令。\n\n可以加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为“自动”。", "zh_TW": "在第二個執行緒上執行圖形後端指令。\n\n在本身不支援多執行緒的 GPU 驅動程式上,可加快著色器編譯、減少卡頓並提高效能。在支援多執行緒的驅動程式上效能略有提升。\n\n如果不確定,請設定為自動。" } @@ -15007,16 +16557,17 @@ "es_ES": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.", "fr_FR": "Exécute des commandes du backend graphiques sur un second thread.\n\nAccélère la compilation des shaders, réduit les crashs et les lags, améliore les performances sur les pilotes GPU sans support de multithreading. Légère augementation des performances sur les pilotes avec multithreading intégrer.\n\nRéglez sur Auto en cas d'incertitude.", "he_IL": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", - "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Auto.", + "it_IT": "Esegue i comandi del backend grafico su un secondo thread.\n\nVelocizza la compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver grafici senza il supporto integrato al multithreading. Migliora leggermente le prestazioni sui driver che supportano il multithreading.\n\nNel dubbio, imposta l'opzione su Automatico.", "ja_JP": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", "ko_KR": "2번째 스레드에서 그래픽 후단부 명령을 실행합니다.\n\n셰이더 컴파일 속도를 높이고 끊김 현상을 줄이며 자체 다중 스레딩 지원 없이 GPU 드라이버의 성능을 향상시킵니다. 다중 스레딩이 있는 드라이버에서 성능이 좀 더 좋습니다.\n\n모르면 자동으로 설정합니다.", "no_NO": "Utfører grafikkbackend kommandoer på en annen tråd.\n\nØker hastigheten for shaderkomprimering, reduserer hakking og forbedrer ytelsen til GPU-drivere uten flertråd støtte. Litt bedre ytelse på drivere med flertråd.\n\nSett for å AUTO hvis usikker.", "pl_PL": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.", - "pt_BR": "Executa comandos do backend gráfico em uma segunda thread. Permite multithreading em tempo de execução da compilação de shader, diminui os travamentos, e melhora performance em drivers sem suporte embutido a multithreading. Pequena variação na performance máxima em drivers com suporte a multithreading. Ryujinx pode precisar ser reiniciado para desabilitar adequadamente o multithreading embutido do driver, ou você pode precisar fazer isso manualmente para ter a melhor performance.", + "pt_BR": "Executa comandos do renderizador gráfico em um segundo thread.\n\nAcelera a compilação de shader, reduz a gagueira e melhora o desempenho em drivers de GPU sem suporte multithreading próprio. Desempenho ligeiramente melhor em drivers com multithreading.\n\nDefina como AUTO se não tiver certeza.", "ru_RU": "Выполняет команды графического бэкенда на втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах видеоадаптера без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить Автоматически.", + "sv_SE": "Kör kommandon för grafikbakände i en andra tråd.\n\nSnabbar upp shader compilation, minskar stuttering och förbättrar prestandan på GPU-drivrutiner utan stöd för egen multithreading. Något bättre prestanda på drivrutiner med multithreading.\n\nStäll in till AUTO om du är osäker.", "th_TH": "ดำเนินการคำสั่งแบ็กเอนด์กราฟิกบนเธรดที่สอง\n\nเร่งความเร็วการคอมไพล์เชเดอร์ ลดการกระตุก และปรับปรุงประสิทธิภาพการทำงานของไดรเวอร์ GPU โดยไม่ต้องรองรับมัลติเธรดในตัว ประสิทธิภาพที่ดีขึ้นเล็กน้อยสำหรับไดรเวอร์ที่มีมัลติเธรด\n\nตั้งเป็น อัตโนมัติ หากคุณไม่แน่ใจ", "tr_TR": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.", - "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\n\nВстановіть значення «Авто», якщо не впевнені.", + "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\n\nВстановіть значення «Авто» якщо не впевнені.", "zh_CN": "在第二个线程上执行图形引擎指令。\n\n可以加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为“自动”。", "zh_TW": "在第二個執行緒上執行圖形後端指令。\n\n在本身不支援多執行緒的 GPU 驅動程式上,可加快著色器編譯、減少卡頓並提高效能。在支援多執行緒的驅動程式上效能略有提升。\n\n如果不確定,請設定為自動。" } @@ -15036,11 +16587,12 @@ "ko_KR": "후속 실행 시 끊김 현상을 줄이는 디스크 셰이더 캐시를 저장합니다.\n\n모르면 켬으로 두세요.", "no_NO": "Lagrer en disk shader cache som reduserer hakking jo flere ganger du spiller.\n\nLa være PÅ om usikker.", "pl_PL": "Zapisuje pamięć podręczną shaderów na dysku, co zmniejsza zacinanie się w kolejnych uruchomieniach.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Habilita ou desabilita o cache de shader", + "pt_BR": "Salva um cache de shader no disco que reduz a trepidação em execuções subsequentes.\n\nDeixe LIGADO se não tiver certeza.", "ru_RU": "Сохраняет кэш шейдеров на диске, для уменьшения статтеров при последующих запусках.\n\nРекомендуется оставить включенным.", + "sv_SE": "Sparar en disk shader cache som minskar stuttering i efterföljande körningar.\n\nLämna PÅ om du är osäker.", "th_TH": "บันทึกแคชแสงเงาของดิสก์ซึ่งช่วยลดการกระตุกในการรันครั้งต่อๆ ไป\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "Sonraki çalışmalarda takılmaları engelleyen bir gölgelendirici disk önbelleğine kaydeder.", - "uk_UA": "Зберігає кеш дискового шейдера, що зменшує затримки під час наступних запусків.\n\nЗалиште увімкненим, якщо не впевнені.", + "uk_UA": "Зберігає кеш дискового шейдера, що зменшує затримки під час наступних запусків.\n\nЗалиште увімкненим якщо не впевнені.", "zh_CN": "模拟器将已编译的着色器保存到硬盘,可以减少游戏再次渲染相同图形导致的卡顿。\n\n如果不确定,请保持开启状态。", "zh_TW": "儲存磁碟著色器快取,減少後續執行時的卡頓。\n\n如果不確定,請保持開啟狀態。" } @@ -15055,13 +16607,14 @@ "es_ES": "Multiplica la resolución de rendereo del juego.\n\nAlgunos juegos podrían no funcionar con esto y verse pixelado al aumentar la resolución; en esos casos, quizás sería necesario buscar mods que de anti-aliasing o que aumenten la resolución interna. Para usar este último, probablemente necesitarás seleccionar Nativa.\n\nEsta opción puede ser modificada mientras que un juego este corriendo haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nTener en cuenta que 4x es excesivo para prácticamente cualquier configuración.", "fr_FR": "Multiplie la résolution de rendu du jeu.\n\nQuelques jeux peuvent ne pas fonctionner avec cette fonctionnalité et sembler pixelisés même lorsque la résolution est augmentée ; pour ces jeux, vous devrez peut-être trouver des mods qui suppriment l'anti-aliasing ou qui augmentent leur résolution de rendu interne. Pour utiliser cette dernière option, vous voudrez probablement sélectionner \"Natif\".\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres sur le côté et expérimenter jusqu'à ce que vous trouviez l'apparence souhaitée pour un jeu.\n\nGardez à l'esprit que 4x est excessif pour pratiquement n'importe quelle configuration.", "he_IL": "", - "it_IT": "Moltiplica la risoluzione di rendering del gioco.\n\nAlcuni giochi potrebbero non funzionare con questa opzione e sembrare pixelati anche quando la risoluzione è aumentata; per quei giochi, potrebbe essere necessario trovare mod che rimuovono l'anti-aliasing o che aumentano la risoluzione di rendering interna. Per quest'ultimo caso, probabilmente dovrai selezionare Nativo (1x).\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nTenete a mente che 4x è troppo per praticamente qualsiasi configurazione.", + "it_IT": "Moltiplica la risoluzione di rendering del gioco.\n\nAlcuni giochi potrebbero non funzionare con questa opzione e sembrare pixelati anche quando la risoluzione è aumentata; per quei giochi, potrebbe essere necessario trovare mod che rimuovono l'anti-aliasing o che aumentano la risoluzione di rendering interna. Per quest'ultimo caso, probabilmente dovrai selezionare Nativo (1x).\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito.\n\nTieni presente che \"4x\" è eccessivo per praticamente qualsiasi configurazione.", "ja_JP": "ゲームのレンダリング解像度倍率を設定します.\n\n解像度を上げてもピクセルのように見えるゲームもあります. そのようなゲームでは, アンチエイリアスを削除するか, 内部レンダリング解像度を上げる mod を見つける必要があるかもしれません. その場合, ようなゲームでは、ネイティブを選択してください.\n\nこのオプションはゲーム実行中に下の「適用」をクリックすることで変更できます. 設定ウィンドウを脇に移動して, ゲームが好みの表示になるよう試してみてください.\n\nどのような設定でも, \"4x\" はやり過ぎであることを覚えておいてください.", "ko_KR": "게임의 렌더링 해상도를 배가시킵니다.\n\n일부 게임에서는 이 기능이 작동하지 않고 해상도가 높아져도 픽셀화되어 보일 수 있습니다. 해당 게임의 경우 앤티 앨리어싱을 제거하거나 내부 렌더링 해상도를 높이는 모드를 찾아야 할 수 있습니다. 후자를 사용하려면 기본을 선택하는 것이 좋습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임이 실행되는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮기고 원하는 게임 모양을 찾을 때까지 실험해 보세요.\n\n4배는 거의 모든 설정에서 과하다는 점을 명심하세요.", "no_NO": "Dobler spillets gjengivelse.\n\nNoen få spill fungerer kanskje ikke med dette aktivert og kan se veldig pikselert ut selv når gjengivelsen er økt; for de spillene, så kan det hende du må bruke modifikasjoner som fjerner anti-aliasing eller som øker den interne gjengivelsen. For og bruke sistnenvte, så vil du helst bruke \"Native\".\n\nHa til tanke at 4x er unødig for virituelt alle maskiner.", "pl_PL": "", "pt_BR": "Multiplica a resolução de renderização do jogo.\n\nAlguns jogos podem não funcionar bem com essa opção e apresentar uma aparência pixelada, mesmo com o aumento da resolução; para esses jogos, talvez seja necessário encontrar mods que removam o anti-aliasing ou aumentem a resolução de renderização interna. Ao usar a segunda opção, provavelmente desejará selecionar Nativa.\n\nEssa opção pode ser alterada enquanto um jogo está em execução, clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nLembre-se de que 4x é exagerado para praticamente qualquer configuração.", - "ru_RU": "Увеличивает разрешение рендера игры.\n\nНекоторые игры могут не работать с этой настройкой и выглядеть смазано даже когда разрешение увеличено. Для таких игр может потребоваться установка модов, которые убирают сглаживание или увеличивают разрешение рендеринга. \nДля использования последнего, вам нужно будет выбрать опцию \"Нативное\".\n\nЭта опция может быть изменена во время игры по нажатию кнопки \"Применить\" ниже. Вы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nИмейте в виду, что \"4x\" является излишеством.", + "ru_RU": "Увеличивает разрешение рендера игры.\n\nНекоторые игры могут не работать с этой настройкой и выглядеть смазано даже когда разрешение увеличено. Для таких игр может потребоваться установка модов, которые убирают сглаживание или увеличивают разрешение рендеринга. \nДля использования последнего, вам нужно будет выбрать опцию «Нативное».\n\nЭта опция может быть изменена во время игры по нажатию кнопки «Применить» ниже. Вы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nИмейте в виду, что «4x» является излишеством.", + "sv_SE": "Multiplicerar spelets renderingsupplösning.\n\nNågra spel kanske inte fungerar med detta och ser pixelerade ut även när upplösningen ökas; för dessa spel så kan du behöva hitta moddar som tar bort anti-aliasing eller som ökar deras interna renderingsupplösning. För att använda det senare, kommer du sannolikt vilja välja Inbyggd.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nTänk på att 4x är overkill för praktiskt taget alla maskiner.", "th_TH": "คูณความละเอียดการเรนเดอร์ของเกม\n\nเกมบางเกมอาจไม่สามารถใช้งานได้และดูเป็นพิกเซลแม้ว่าความละเอียดจะเพิ่มขึ้นก็ตาม สำหรับเกมเหล่านั้น คุณอาจต้องค้นหาม็อดที่ลบรอยหยักของภาพหรือเพิ่มความละเอียดในการเรนเดอร์ภายใน หากต้องการใช้อย่างหลัง คุณอาจต้องเลือก Native\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำมาใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nโปรดทราบว่า 4x นั้นเกินความจำเป็นสำหรับการตั้งค่าแทบทุกประเภท", "tr_TR": "", "uk_UA": "Множить роздільну здатність гри.\n\nДеякі ігри можуть не працювати з цією функцією, і виглядатимуть піксельними; для цих ігор треба знайти модифікації, що зупиняють згладжування або підвищують роздільну здатність. Для останніх модифікацій, вибирайте \"Native\".\n\nЦей параметр можна міняти коли гра запущена кліком на \"Застосувати\"; ви можете перемістити вікно налаштувань і поекспериментувати з видом гри.\n\nМайте на увазі, що 4x це занадто для будь-якого комп'ютера.", @@ -15079,13 +16632,14 @@ "es_ES": "Escalado de resolución de coma flotante, como por ejemplo 1,5. Los valores no íntegros pueden causar errores gráficos o crashes.", "fr_FR": "Échelle de résolution à virgule, telle que : 1.5. Les échelles non intégrales sont plus susceptibles de causer des problèmes ou des crashs.", "he_IL": "שיפור רזולוציית נקודה צפה, כגון 1.5. הוא שיפור לא אינטגרלי הנוטה לגרום יותר בעיות או להקריס.", - "it_IT": "Scala della risoluzione in virgola mobile, come 1,5. Le scale non integrali hanno maggiori probabilità di causare problemi o crash.", + "it_IT": "Scala della risoluzione in virgola mobile, come 1,5. I valori non interi hanno maggiori probabilità di causare problemi o arresti anomali.", "ja_JP": "1.5 のような整数でない倍率を指定すると,問題が発生したりクラッシュしたりする場合があります.", "ko_KR": "부동 소수점 해상도 스케일(예: 1.5)입니다. 적분이 아닌 스케일은 문제나 충돌을 일으킬 가능성이 높습니다.", "no_NO": "Det er mer sannsynlig at flytende punktoppløsning skalaer som 1.5. Ikke-integrerte skalaer forårsaker problemer eller krasj.", "pl_PL": "Skala rozdzielczości zmiennoprzecinkowej, np. 1,5. Skale niecałkowite częściej powodują problemy lub awarie.", "pt_BR": "Escala de resolução de ponto flutuante, como 1.5. Valores não inteiros tem probabilidade maior de causar problemas ou quebras.", "ru_RU": "Масштабирование разрешения с плавающей запятой, например 1,5. Неинтегральное масштабирование с большой вероятностью вызовет сбои в работе.", + "sv_SE": "Skala för floating point resolution, såsom 1.5. Icke-heltalsskalor är mer benägna att orsaka problem eller krasch.", "th_TH": "สเกลความละเอียดจุดทศนิยม เช่น 1.5 ไม่ใช่จำนวนเต็มของสเกล มีแนวโน้มที่จะก่อให้เกิดปัญหาหรือความผิดพลาดได้", "tr_TR": "Küsüratlı çözünürlük ölçeği, 1.5 gibi. Küsüratlı ölçekler hata oluşturmaya ve çökmeye daha yatkındır.", "uk_UA": "Масштаб роздільної здатності з плаваючою комою, наприклад 1,5. Не інтегральні масштаби, швидше за все, спричинять проблеми або збій.", @@ -15103,16 +16657,17 @@ "es_ES": "Nivel de filtrado anisotrópico. Setear en Auto para utilizar el valor solicitado por el juego.", "fr_FR": "Niveau de filtrage anisotrope. Réglez sur Auto pour utiliser la valeur demandée par le jeu.", "he_IL": "", - "it_IT": "Livello del filtro anisotropico. Imposta su Auto per usare il valore richiesto dal gioco.", + "it_IT": "Livello del filtro anisotropico. Imposta su Automatico per usare il valore richiesto dal gioco.", "ja_JP": "異方性フィルタリングのレベルです. ゲームが要求する値を使用する場合は「自動」を設定してください.", "ko_KR": "이방성 필터링 수준입니다. 게임에서 요청한 값을 사용하려면 자동으로 설정하세요.", "no_NO": "Nivå av Anisotropisk filtrering. Sett til Auto for å bruke verdien som kreves av spillet.", "pl_PL": "", "pt_BR": "Nível de Filtragem Anisotrópica. Defina como Automático para usar o valor solicitado pelo jogo.", "ru_RU": "Уровень анизотропной фильтрации. \n\nУстановите значение Автоматически, чтобы использовать значение по умолчанию игры.", + "sv_SE": "Nivå av anisotropisk filtrering. Ställ in till Automatiskt för att använda det värde som begärts av spelet.", "th_TH": "ระดับของ Anisotropic ตั้งค่าเป็นอัตโนมัติเพื่อใช้ค่าพื้นฐานของเกม", "tr_TR": "", - "uk_UA": "Рівень анізотропної фільтрації. Встановіть на «Авто», щоб використовувати значення, яке вимагає гра.", + "uk_UA": "Рівень анізотропної фільтрації. Встановіть «Авто», щоб використовувати значення яке вимагає гра.", "zh_CN": "各向异性过滤等级,可以提高倾斜视角纹理的清晰度。\n当设置为“自动”时,使用游戏自身设定的等级。", "zh_TW": "各向異性過濾等級。設定為自動可使用遊戲要求的值。" } @@ -15125,7 +16680,7 @@ "el_GR": "", "en_US": "Aspect Ratio applied to the renderer window.\n\nOnly change this if you're using an aspect ratio mod for your game, otherwise the graphics will be stretched.\n\nLeave on 16:9 if unsure.", "es_ES": "Relación de aspecto aplicada a la ventana del renderizador.\n\nSolamente modificar esto si estás utilizando un mod de relación de aspecto para su juego, en cualquier otro caso los gráficos se estirarán.\n\nDejar en 16:9 si no sabe que hacer.", - "fr_FR": "Format d'affichage appliqué à la fenêtre du moteur de rendu.\n\nChangez cela uniquement si vous utilisez un mod changeant le format d'affichage pour votre jeu, sinon les graphismes seront étirés.\n\nLaissez sur 16:9 si vous n'êtes pas sûr.", + "fr_FR": "Format\u00A0d'affichage appliqué à la fenêtre du moteur de rendu.\n\nChangez cela uniquement si vous utilisez un mod changeant le format\u00A0d'affichage pour votre jeu, sinon les graphismes seront étirés.\n\nLaissez sur 16:9 si vous n'êtes pas sûr.", "he_IL": "", "it_IT": "Proporzioni dello schermo applicate alla finestra di renderizzazione.\n\nCambialo solo se stai usando una mod di proporzioni per il tuo gioco, altrimenti la grafica verrà allungata.\n\nLasciare il 16:9 se incerto.", "ja_JP": "レンダリングウインドウに適用するアスペクト比です.\n\nゲームにアスペクト比を変更する mod を使用している場合のみ変更してください.\n\nわからない場合は16:9のままにしておいてください.\n", @@ -15134,9 +16689,10 @@ "pl_PL": "", "pt_BR": "Proporção de Tela aplicada à janela do renderizador.\n\nAltere isso apenas se estiver usando um mod de proporção para o seu jogo; caso contrário, os gráficos ficarão esticados.\n\nMantenha em 16:9 se estiver em dúvida.", "ru_RU": "Соотношение сторон окна рендерера.\n\nИзмените эту настройку только если вы используете мод для соотношения сторон, иначе изображение будет растянуто.\n\nРекомендуется настройка 16:9.", + "sv_SE": "Bildförhållande att appliceras på renderarfönstret.\n\nÄndra endast detta om du använder en modd för bildförhållande till ditt spel, annars kommer grafiken att sträckas ut.\n\nLämna den till 16:9 om du är osäker.", "th_TH": "อัตราส่วนภาพที่ใช้กับหน้าต่างตัวแสดงภาพ\n\nเปลี่ยนสิ่งนี้หากคุณใช้ตัวดัดแปลงอัตราส่วนกว้างยาวสำหรับเกมของคุณ ไม่เช่นนั้นกราฟิกจะถูกยืดออก\n\nทิ้งไว้ที่ 16:9 หากไม่แน่ใจ", "tr_TR": "", - "uk_UA": "Співвідношення сторін застосовано до вікна рендера.\n\nМіняйте тільки, якщо використовуєте модифікацію співвідношення сторін для гри, інакше графіка буде розтягнута.\n\nЗалиште на \"16:9\", якщо не впевнені.", + "uk_UA": "Співвідношення сторін застосовано до вікна рендера.\n\nМіняйте тільки, якщо використовуєте модифікацію співвідношення сторін для гри, інакше зображення буде розтягнутим.\n\nЗалиште на \"16:9\", якщо не впевнені.", "zh_CN": "游戏渲染窗口的宽高比。\n\n只有当游戏使用了修改宽高比的 MOD 时才需要修改这个设置,否则图像会被拉伸。\n\n如果不确定,请保持为“16:9”。", "zh_TW": "套用於繪製器視窗的長寬比。\n\n只有在遊戲中使用長寬比模組時才可變更,否則圖形會被拉伸。\n\n如果不確定,請保持 16:9 狀態。" } @@ -15156,11 +16712,12 @@ "ko_KR": "그래픽 셰이더 덤프 경로", "no_NO": "Grafikk Shader Dump bane", "pl_PL": "Ścieżka Zrzutu Shaderów Grafiki", - "pt_BR": "Diretòrio de despejo de shaders", + "pt_BR": "Diretório de Despejo de Shaders", "ru_RU": "Путь с дампами графических шейдеров", + "sv_SE": "Sökväg för Graphics Shaders Dump", "th_TH": "ที่เก็บ ดัมพ์ไฟล์เชเดอร์", "tr_TR": "Grafik Shader Döküm Yolu", - "uk_UA": "Шлях скидання графічних шейдерів", + "uk_UA": "Шлях до дампу графічних шейдерів", "zh_CN": "转储图形着色器的路径", "zh_TW": "圖形著色器傾印路徑" } @@ -15180,11 +16737,12 @@ "ko_KR": "디스크의 로그 파일에 콘솔 기록을 저장합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Lagrer konsoll-logging til en loggfil på harddisken. Påvirker ikke ytelsen.", "pl_PL": "Zapisuje logowanie konsoli w pliku dziennika na dysku. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita log para um arquivo no disco", + "pt_BR": "Salva o log do console em um arquivo de log no disco. Não afeta o desempenho.", "ru_RU": "Включает ведение журнала в файл на диске. Не влияет на производительность.", + "sv_SE": "Sparar konsolloggning till en loggfil på disk. Påverkar inte prestandan.", "th_TH": "บันทึกประวัติคอนโซลลงในไฟล์บันทึก จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Konsol loglarını diskte bir log dosyasına kaydeder. Performansı etkilemez.", - "uk_UA": "Зберігає журнал консолі у файл журналу на диску. Не впливає на продуктивність.", + "uk_UA": "Зберігає консольне ведення журналу у файл на диску. Не впливає на продуктивність.", "zh_CN": "将控制台日志保存到硬盘文件,不影响性能。", "zh_TW": "將控制台日誌儲存到磁碟上的日誌檔案中。不會影響效能。" } @@ -15204,11 +16762,12 @@ "ko_KR": "콘솔에 조각 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut log meldinger i konsollen. Påvirker ikke ytelsen.", "pl_PL": "Wyświetla w konsoli skrótowe komunikaty dziennika. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens de stub", + "pt_BR": "Imprime mensagens de log stub no console. Não afeta o desempenho.", "ru_RU": "Включает ведение журнала-заглушки. Не влияет на производительность.", + "sv_SE": "Skriver ut stubbloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Stub log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення журналу-заглушки на консолі. Не впливає на продуктивність.", + "uk_UA": "Відображає повідомлення журналу-заглушки (tub log) в консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示存根日志,不影响性能。", "zh_TW": "在控制台中輸出日誌訊息。不會影響效能。" } @@ -15228,11 +16787,12 @@ "ko_KR": "콘솔에 정보 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut info loggmeldinger i konsollen. Påvirker ikke ytelse.", "pl_PL": "Wyświetla komunikaty dziennika informacyjnego w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens informativas", + "pt_BR": "Imprime mensagens de log de informações no console. Não afeta o desempenho.", "ru_RU": "Включает вывод сообщений информационного журнала в консоль. Не влияет на производительность.", + "sv_SE": "Skriver ut informationsloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความบันทึกข้อมูลในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Bilgi log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення інформаційного журналу на консолі. Не впливає на продуктивність.", + "uk_UA": "Виводить повідомлення журналу інформації (info log) в консоль. Не впливає на продуктивність.", "zh_CN": "在控制台中显示信息日志,不影响性能。", "zh_TW": "在控制台中輸出資訊日誌訊息。不會影響效能。" } @@ -15252,11 +16812,12 @@ "ko_KR": "콘솔에 경고 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut varselloggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika ostrzeżeń w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens de alerta", + "pt_BR": "Imprime mensagens de log de aviso no console. Não afeta o desempenho.", "ru_RU": "Включает вывод сообщений журнала предупреждений в консоль. Не влияет на производительность.", + "sv_SE": "Skriver ut varningsloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติการเตือนในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Uyarı log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення журналу попереджень у консолі. Не впливає на продуктивність.", + "uk_UA": "Додає повідомлення журналу попереджень (warning log) до консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示警告日志,不影响性能。", "zh_TW": "在控制台中輸出警告日誌訊息。不會影響效能。" } @@ -15276,11 +16837,12 @@ "ko_KR": "콘솔에 오류 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut feilloggmeldinger i konsollen. Påvirker ikke ytelse.", "pl_PL": "Wyświetla w konsoli komunikaty dziennika błędów. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens de erro", + "pt_BR": "Imprime mensagens de log de erro no console. Não afeta o desempenho.", "ru_RU": "Включает вывод сообщений журнала ошибок. Не влияет на производительность.", + "sv_SE": "Skriver ut felloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความบันทึกข้อผิดพลาดในคอนโซล จะไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Hata log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення журналу помилок у консолі. Не впливає на продуктивність.", + "uk_UA": "Додає повідомлення журналу помилок (error log) до консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示错误日志,不影响性能。", "zh_TW": "在控制台中輸出錯誤日誌訊息。不會影響效能。" } @@ -15300,11 +16862,12 @@ "ko_KR": "콘솔에 추적 기록 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut sporbare loggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika śledzenia w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens de rastreamento", + "pt_BR": "Imprime mensagens de log de rastreamento no console. Não afeta o desempenho.", "ru_RU": "Выводит сообщения журнала трассировки в консоли. Не влияет на производительность.", + "sv_SE": "Skriver ut spårloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติการติดตามในคอนโซล ไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Trace log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення журналу трасування на консолі. Не впливає на продуктивність.", + "uk_UA": "Додає повідомлення журналу трасування (trace log) до консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示跟踪日志。", "zh_TW": "在控制台中輸出追蹤日誌訊息。不會影響效能。" } @@ -15324,11 +16887,12 @@ "ko_KR": "콘솔에 게스트 로그 메시지를 출력합니다. 성능에 영향을 주지 않습니다.", "no_NO": "Skriver ut gjesteloggmeldinger i konsollen. påvirker ikke ytelsen.", "pl_PL": "Wyświetla komunikaty dziennika gości w konsoli. Nie wpływa na wydajność.", - "pt_BR": "Habilita ou desabilita exibição de mensagens do programa convidado", + "pt_BR": "Imprime mensagens de log do convidado no console. Não afeta o desempenho.", "ru_RU": "Включает вывод сообщений гостевого журнала. Не влияет на производительность.", + "sv_SE": "Skriver ut gästloggmeddelanden i konsollen. Påverkar inte prestandan.", "th_TH": "พิมพ์ข้อความประวัติของผู้เยี่ยมชมในคอนโซล ไม่ส่งผลกระทบต่อประสิทธิภาพการทำงาน", "tr_TR": "Guest log mesajlarını konsola yazdırır. Performansı etkilemez.", - "uk_UA": "Друкує повідомлення журналу гостей у консолі. Не впливає на продуктивність.", + "uk_UA": "Додає повідомлення журналу гостей (guest log) до консолі. Не впливає на продуктивність.", "zh_CN": "在控制台中显示访客日志,不影响性能。", "zh_TW": "在控制台中輸出客體日誌訊息。不會影響效能。" } @@ -15348,11 +16912,12 @@ "ko_KR": "콘솔에 파일 접속 기록 메시지를 출력합니다.", "no_NO": "Skriver ut filtilgang til loggmeldinger i konsollen.", "pl_PL": "Wyświetla w konsoli komunikaty dziennika dostępu do plików.", - "pt_BR": "Habilita ou desabilita exibição de mensagens do acesso de arquivos", + "pt_BR": "Imprime mensagens de log de acesso a arquivos no console.", "ru_RU": "Включает вывод сообщений журнала доступа к файлам.", + "sv_SE": "Skriver ut loggmeddelanden för filåtkomst i konsollen.", "th_TH": "พิมพ์ข้อความบันทึกการเข้าถึงไฟล์ในคอนโซล", "tr_TR": "Dosya sistemi erişim log mesajlarını konsola yazdırır.", - "uk_UA": "Друкує повідомлення журналу доступу до файлів у консолі.", + "uk_UA": "Виводить повідомлення журналу доступу (access log) до файлів в консоль.", "zh_CN": "在控制台中显示文件访问日志。", "zh_TW": "在控制台中輸出檔案存取日誌訊息。" } @@ -15372,11 +16937,12 @@ "ko_KR": "콘솔에 파일 시스템 접속 기록 출력을 활성화합니다. 가능한 모드는 0-3", "no_NO": "Aktiverer FS tilgang loggutgang til konsollen. Mulige moduser er 0-3", "pl_PL": "Włącza wyjście dziennika dostępu FS do konsoli. Możliwe tryby to 0-3", - "pt_BR": "Habilita exibição de mensagens de acesso ao sistema de arquivos no console. Modos permitidos são 0-3", + "pt_BR": "Habilita a saída do log de acesso FS para o console. Os modos possíveis são 0-3", "ru_RU": "Включает вывод журнала доступа к файловой системе. Возможные режимы: 0-3", + "sv_SE": "Aktiverar loggutdata för filsystemsåtkomst i konsollen. Möjliga lägen är 0-3", "th_TH": "เปิดใช้งาน เอาต์พุตประวัติการเข้าถึง FS ไปยังคอนโซล โหมดที่เป็นไปได้คือ 0-3", "tr_TR": "Konsola FS erişim loglarının yazılmasını etkinleştirir. Kullanılabilir modlar 0-3'tür", - "uk_UA": "Вмикає виведення журналу доступу до FS на консоль. Можливі режими 0-3", + "uk_UA": "Увімкнути виведення журналу доступу (access log) до файлової системи в консоль. Можливі режими: 0-3", "zh_CN": "在控制台中显示文件系统访问日志,可选模式为 0-3。", "zh_TW": "啟用檔案系統存取日誌輸出到控制台中。可能的模式為 0 到 3" } @@ -15391,20 +16957,46 @@ "es_ES": "Usar con cuidado", "fr_FR": "À utiliser avec précaution", "he_IL": "השתמש בזהירות", - "it_IT": "Usa con attenzione", + "it_IT": "Usa con cautela", "ja_JP": "使用上の注意", "ko_KR": "주의해서 사용", "no_NO": "Bruk med forsiktighet", "pl_PL": "Używaj ostrożnie", "pt_BR": "Use com cuidado", "ru_RU": "Используйте с осторожностью", + "sv_SE": "Använd med försiktighet", "th_TH": "โปรดใช้ด้วยความระมัดระวัง", "tr_TR": "Dikkatli kullanın", - "uk_UA": "Використовуйте з обережністю", + "uk_UA": "Використовувати обережно", "zh_CN": "请谨慎使用", "zh_TW": "謹慎使用" } }, + { + "ID": "AvaloniaLogTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Prints Avalonia (UI) log messages in the console.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Skriver ut Avalonia (UI)-loggmeldinger i konsollen.", + "pl_PL": "", + "pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.", + "ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль", + "zh_CN": "在控制台显示 Avalonia (UI) 的日志信息", + "zh_TW": "" + } + }, { "ID": "OpenGlLogLevel", "Translations": { @@ -15420,11 +17012,12 @@ "ko_KR": "적절한 기록 수준이 활성화되어 있어야 함", "no_NO": "Krever riktige loggnivåer aktivert", "pl_PL": "Wymaga włączonych odpowiednich poziomów logów", - "pt_BR": "Requer que os níveis de log apropriados estejaam habilitados", + "pt_BR": "Requer níveis de log apropriados habilitados", "ru_RU": "Требует включения соответствующих уровней ведения журнала", + "sv_SE": "Kräver att lämpliga loggnivåer aktiveras", "th_TH": "จำเป็นต้องเปิดใช้งานระดับบันทึกที่เหมาะสม", "tr_TR": "Uygun log seviyesinin aktif olmasını gerektirir", - "uk_UA": "Потрібно увімкнути відповідні рівні журналу", + "uk_UA": "Потрібно увімкнути відповідні рівні журналу (log)", "zh_CN": "需要启用适当的日志级别", "zh_TW": "需要啟用適當的日誌等級" } @@ -15444,11 +17037,12 @@ "ko_KR": "콘솔에 디버그 기록 메시지를 출력합니다.\n\n담당자가 특별히 요청한 경우에만 이 기능을 사용하십시오. 로그를 읽기 어렵게 만들고 에뮬레이터 성능을 저하시킬 수 있기 때문입니다.", "no_NO": "Skriver ut loggmeldinger i konsollen.\n\nBruk bare dette hvis et medlem har gitt spesifikke instruksjoner, siden det vil gjøre loggene vanskelig å lese og forverre emulatorytelse.", "pl_PL": "Wyświetla komunikaty dziennika debugowania w konsoli.\n\nUżywaj tego tylko na wyraźne polecenie członka załogi, ponieważ utrudni to odczytanie dzienników i pogorszy wydajność emulatora.", - "pt_BR": "Habilita exibição de mensagens de depuração", + "pt_BR": "Imprime mensagens de log de depuração no console.\n\nUse isso somente se for especificamente instruído por um membro da equipe, pois isso tornará os logs difíceis de ler e piorará o desempenho do emulador.", "ru_RU": "Выводит журнал сообщений отладки в консоли.\n\nИспользуйте только в случае просьбы разработчика, так как включение этой функции затруднит чтение журналов и ухудшит работу эмулятора.", + "sv_SE": "Skriver ut felsökningsloggmeddelanden i konsolen.\n\nAnvänd endast detta om det är specifikt instruerat av en medarbetare, eftersom det kommer att göra loggar svåra att läsa och försämra emulatorprestanda.", "th_TH": "พิมพ์ข้อความประวัติการแก้ไขข้อบกพร่องในคอนโซล\n\nใช้สิ่งนี้เฉพาะเมื่อได้รับคำแนะนำจากผู้ดูแลเท่านั้น เนื่องจากจะทำให้บันทึกอ่านยากและทำให้ประสิทธิภาพของโปรแกรมจำลองแย่ลง", "tr_TR": "Debug log mesajlarını konsola yazdırır.\n\nBu seçeneği yalnızca geliştirici üyemiz belirtirse aktifleştirin, çünkü bu seçenek log dosyasını okumayı zorlaştırır ve emülatörün performansını düşürür.", - "uk_UA": "Друкує повідомлення журналу налагодження на консолі.\n\nВикористовуйте це лише за спеціальною вказівкою співробітника, оскільки це ускладнить читання журналів і погіршить роботу емулятора.", + "uk_UA": "Виводить повідомлення журналу налагодження в консолі.\n\nВикористовуйте лише за спеціальною вказівкою розробника, оскільки увімкнення цього параметру ускладнить читання журналів (logs) і погіршить роботу емулятора.", "zh_CN": "在控制台中显示调试日志。\n\n仅在特别需要时使用此功能,因为它会导致日志信息难以阅读,并降低模拟器性能。", "zh_TW": "在控制台中輸出偵錯日誌訊息。\n\n只有在人員特別指示的情況下才能使用,因為這會導致日誌難以閱讀,並降低模擬器效能。" } @@ -15463,16 +17057,17 @@ "es_ES": "Abre el explorador de archivos para elegir un archivo compatible con Switch para cargar", "fr_FR": "Ouvre l'explorateur de fichiers pour choisir un fichier compatible Switch à charger", "he_IL": "פתח סייר קבצים כדי לבחור קובץ תואם סוויץ' לטעינה", - "it_IT": "Apri un file explorer per scegliere un file compatibile Switch da caricare", + "it_IT": "Apri un selettore file per scegliere un file compatibile con Switch da caricare", "ja_JP": "ロードする Switch 互換のファイルを選択するためファイルエクスプローラを開きます", "ko_KR": "파일 탐색기를 열어 불러올 Switch 호환 파일을 선택", "no_NO": "Åpne filutforsker for å velge en Switch kompatibel fil å laste", "pl_PL": "Otwórz eksplorator plików, aby wybrać plik kompatybilny z Switch do wczytania", - "pt_BR": "Abre o navegador de arquivos para seleção de um arquivo do Switch compatível a ser carregado", + "pt_BR": "Abre um explorador de arquivos para escolher um arquivo compatível com o Switch para carregar", "ru_RU": "Открывает файловый менеджер для выбора файла, совместимого с Nintendo Switch.", + "sv_SE": "Öppna en filutforskare för att välja en Switch-kompatibel fil att läsa in", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกไฟล์ที่เข้ากันได้กับ Switch ที่จะโหลด", "tr_TR": "Switch ile uyumlu bir dosya yüklemek için dosya tarayıcısını açar", - "uk_UA": "Відкриває файловий провідник, щоб вибрати для завантаження сумісний файл Switch", + "uk_UA": "Відкриває Файловий провідник, щоб обрати для завантаження сумісний зі Switch файл", "zh_CN": "选择 Switch 游戏文件并加载", "zh_TW": "開啟檔案總管,選擇與 Switch 相容的檔案來載入" } @@ -15487,16 +17082,17 @@ "es_ES": "Abre el explorador de archivos para elegir un archivo desempaquetado y compatible con Switch para cargar", "fr_FR": "Ouvre l'explorateur de fichiers pour choisir une application Switch compatible et décompressée à charger", "he_IL": "פתח סייר קבצים כדי לבחור יישום תואם סוויץ', לא ארוז לטעינה.", - "it_IT": "Apri un file explorer per scegliere un file compatibile Switch, applicazione sfusa da caricare", + "it_IT": "Apri un selettore file per scegliere un'applicazione estratta compatibile con Switch da caricare", "ja_JP": "ロードする Switch 互換の展開済みアプリケーションを選択するためファイルエクスプローラを開きます", "ko_KR": "Switch와 호환되는 압축 해제된 앱을 선택하여 불러오려면 파일 탐색기를 엽니다.", "no_NO": "Åpne en filutforsker for å velge en Switch kompatibel, upakket applikasjon for å laste", "pl_PL": "Otwórz eksplorator plików, aby wybrać zgodną z Switch, rozpakowaną aplikację do załadowania", - "pt_BR": "Abre o navegador de pastas para seleção de pasta extraída do Switch compatível a ser carregada", + "pt_BR": "Abre um explorador de arquivos para escolher um aplicativo descompactado compatível com o Switch para carregar", "ru_RU": "Открывает файловый менеджер для выбора распакованного приложения, совместимого с Nintendo Switch.", + "sv_SE": "Öppna en filutforskare för att välja en Switch-kompatibel, uppackad applikation att läsa in", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกไฟล์ที่เข้ากันได้กับ Switch ที่จะโหลด", "tr_TR": "Switch ile uyumlu ayrıştırılmamış bir uygulama yüklemek için dosya tarayıcısını açar", - "uk_UA": "Відкриває файловий провідник, щоб вибрати сумісну з комутатором розпаковану програму для завантаження", + "uk_UA": "Відкриває Файловий провідник, щоб обрати сумісну зі Switch розпаковану програму для завантаження", "zh_CN": "选择解包后的 Switch 游戏目录并加载", "zh_TW": "開啟檔案總管,選擇與 Switch 相容且未封裝的應用程式來載入" } @@ -15511,17 +17107,18 @@ "es_ES": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar DLC de forma masiva", "fr_FR": "Ouvre l'explorateur de fichier pour choisir un ou plusieurs dossiers duquel charger les DLC", "he_IL": "", - "it_IT": "Apri un esploratore file per scegliere una o più cartelle dalle quali caricare DLC in massa", + "it_IT": "Apri un selettore file per scegliere una o più cartelle dalle quali caricare DLC in blocco", "ja_JP": "", "ko_KR": "파일 탐색기를 열어 DLC를 일괄 불러오기할 폴더를 하나 이상 선택", "no_NO": "Åpne en filutforsker for å velge en eller flere mapper å laste inn DLC fra", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Abre um explorador de arquivos para escolher uma ou mais pastas para carregar DLC em massa", + "ru_RU": "Открывает проводник, для выбора одной или нескольких папок для массовой загрузки DLC", + "sv_SE": "Öppna en filutforskare för att välja en eller flera mappar att läsa in alla DLC från", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลด DLC จำนวนมาก", "tr_TR": "", - "uk_UA": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження DLC", - "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载DLC。", + "uk_UA": "Відкриває Файловий провідник для обрання однієї або декількох тек для масового завантаження DLC", + "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载 DLC。", "zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入 DLC" } }, @@ -15535,16 +17132,17 @@ "es_ES": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar actualizaciones de título de forma masiva", "fr_FR": "Ouvre l'explorateur de fichier pour choisir un ou plusieurs dossiers duquel charger les mises à jour", "he_IL": "", - "it_IT": "Apri un esploratore file per scegliere una o più cartelle dalle quali caricare aggiornamenti in massa", + "it_IT": "Apri un selettore file per scegliere una o più cartelle dalle quali caricare aggiornamenti in blocco", "ja_JP": "", "ko_KR": "파일 탐색기를 열어 하나 이상의 폴더를 선택하여 대량으로 타이틀 업데이트 불러오기", "no_NO": "Åpne en filutforsker for å velge en eller flere mapper som du vil laste inn titteloppdateringer fra", "pl_PL": "", - "pt_BR": "Abra o explorador de arquivos para selecionar uma ou mais pastas e carregar atualizações de jogo em massa.", - "ru_RU": "", + "pt_BR": "Abre um explorador de arquivos para escolher uma ou mais pastas para carregar em massa as atualizações de títulos", + "ru_RU": "Открывает проводник, чтобы выбрать одну или несколько папок для массовой загрузки обновлений приложений", + "sv_SE": "Öppna en filutforskare för att välja en eller flera mappar att läsa in alla titeluppdateringar från", "th_TH": "เปิดตัวสำรวจไฟล์เพื่อเลือกหนึ่งโฟลเดอร์ขึ้นไปเพื่อโหลดไฟล์อัปเดตจำนวนมาก", "tr_TR": "", - "uk_UA": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження оновлень заголовків", + "uk_UA": "Відкриває Файловий Провідник для обрання однієї або декількох тек для масового завантаження оновлень", "zh_CN": "打开文件资源管理器以选择一个或多个文件夹来批量加载游戏更新。", "zh_TW": "開啟檔案總管,選擇一個或多個資料夾來大量載入遊戲更新" } @@ -15564,15 +17162,41 @@ "ko_KR": "Ryujinx 파일 시스템 폴더 열기", "no_NO": "Åpne Ryujinx filsystem-mappen", "pl_PL": "Otwórz folder systemu plików Ryujinx", - "pt_BR": "Abre o diretório do sistema de arquivos do Ryujinx", - "ru_RU": "Открывает папку с файлами Ryujinx. ", + "pt_BR": "Abre a pasta do sistema de arquivos Ryujinx", + "ru_RU": "Открывает папку с файлами Ryujinx", + "sv_SE": "Öppna Ryujinx-filsystemsmappen", "th_TH": "เปิดโฟลเดอร์ระบบไฟล์ Ryujinx", "tr_TR": "Ryujinx dosya sistem klasörünü açar", - "uk_UA": "Відкриває теку файлової системи Ryujinx", + "uk_UA": "Відкриває теку з файлами Ryujinx", "zh_CN": "打开 Ryujinx 模拟器系统目录", "zh_TW": "開啟 Ryujinx 檔案系統資料夾" } }, + { + "ID": "OpenScreenshotFolderTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Open Ryujinx screenshots folder", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "Abre a pasta de capturas de tela do Ryujinx", + "ru_RU": "Открывает папку скриншотов Ryujinx", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "OpenRyujinxLogsTooltip", "Translations": { @@ -15588,11 +17212,12 @@ "ko_KR": "로그가 기록되는 폴더 열기", "no_NO": "Åpner mappen hvor logger er lagret", "pl_PL": "Otwiera folder, w którym zapisywane są logi", - "pt_BR": "Abre o diretório onde os logs são salvos", - "ru_RU": "Открывает папку в которую записываются логи", + "pt_BR": "Abre a pasta onde os logs são gravados", + "ru_RU": "Открывает папку, в которую записываются логи", + "sv_SE": "Öppnar mappen där loggarna har skrivits till", "th_TH": "เปิดโฟลเดอร์ ที่เก็บไฟล์ประวัติ", "tr_TR": "Log dosyalarının bulunduğu klasörü açar", - "uk_UA": "Відкриває теку, куди записуються журнали", + "uk_UA": "Відкриває теку, куди зберігаються журнали (logs)", "zh_CN": "打开日志存放的目录", "zh_TW": "開啟日誌被寫入的資料夾" } @@ -15614,9 +17239,10 @@ "pl_PL": "Wyjdź z Ryujinx", "pt_BR": "Sair do Ryujinx", "ru_RU": "Выйти из Ryujinx", + "sv_SE": "Avsluta Ryujinx", "th_TH": "ออกจากโปรแกรม Ryujinx", "tr_TR": "Ryujinx'ten çıkış yapmayı sağlar", - "uk_UA": "Виходить з Ryujinx", + "uk_UA": "Закриває Ryujinx", "zh_CN": "退出 Ryujinx 模拟器", "zh_TW": "結束 Ryujinx" } @@ -15638,6 +17264,7 @@ "pl_PL": "Otwórz okno ustawień", "pt_BR": "Abrir janela de configurações", "ru_RU": "Открывает окно параметров", + "sv_SE": "Öppna inställningar", "th_TH": "เปิดหน้าต่างการตั้งค่า", "tr_TR": "Seçenekler penceresini açar", "uk_UA": "Відкриває вікно налаштувань", @@ -15660,8 +17287,9 @@ "ko_KR": "사용자 프로필 관리자 창 열기", "no_NO": "Åpne vindu for brukerprofiler", "pl_PL": "Otwórz okno Menedżera Profili Użytkownika", - "pt_BR": "Abrir janela de gerenciamento de perfis", - "ru_RU": "Открыть менеджер учетных записей", + "pt_BR": "Abrir Janela de Gerenciamento de Perfis", + "ru_RU": "Открыть менеджер учётных записей", + "sv_SE": "Öppna hanterare för användarprofiler", "th_TH": "เปิดหน้าต่างตัวจัดการโปรไฟล์ผู้ใช้", "tr_TR": "Kullanıcı profil yöneticisi penceresini açar", "uk_UA": "Відкриває вікно диспетчера профілів користувачів", @@ -15685,7 +17313,8 @@ "no_NO": "Stopp emuleringen av dette spillet og gå tilbake til spill valg", "pl_PL": "Zatrzymaj emulację bieżącej gry i wróć do wyboru gier", "pt_BR": "Parar emulação do jogo atual e voltar a seleção de jogos", - "ru_RU": "Остановка эмуляции текущей игры и возврат к списку игр", + "ru_RU": "Остановка эмуляции текущей игры с последующим возвратом к списку игр", + "sv_SE": "Stoppa emulering av aktuellt spel och återgå till spelväljaren", "th_TH": "หยุดการจำลองของเกมที่เปิดอยู่ในปัจจุบันและกลับไปยังการเลือกเกม", "tr_TR": "Oynanmakta olan oyunun emülasyonunu durdurup oyun seçimine geri döndürür", "uk_UA": "Зупиняє емуляцію поточної гри та повертається до вибору гри", @@ -15709,7 +17338,8 @@ "no_NO": "Se etter oppdateringer til Ryujinx", "pl_PL": "Sprawdź aktualizacje Ryujinx", "pt_BR": "Verificar por atualizações para o Ryujinx", - "ru_RU": "Проверяет наличие обновлений для Ryujinx", + "ru_RU": "Проверяет наличие обновлений Ryujinx", + "sv_SE": "Leta efter uppdateringar för Ryujinx", "th_TH": "ตรวจสอบอัปเดตของ Ryujinx", "tr_TR": "Ryujinx güncellemelerini denetlemeyi sağlar", "uk_UA": "Перевіряє наявність оновлень для Ryujinx", @@ -15732,8 +17362,9 @@ "ko_KR": "정보 창 열기", "no_NO": "Åpne Om Vindu", "pl_PL": "Otwórz Okno Informacje", - "pt_BR": "Abrir janela sobre", + "pt_BR": "Abrir Janela Sobre", "ru_RU": "Открывает окно «О программе»", + "sv_SE": "Öppna Om-fönstret", "th_TH": "เปิดหน้าต่าง เกี่ยวกับ", "tr_TR": "Hakkında penceresini açar", "uk_UA": "Відкриває вікно «Про програму».", @@ -15756,8 +17387,9 @@ "ko_KR": "그리드 크기", "no_NO": "Rutenett størrelse", "pl_PL": "Wielkość siatki", - "pt_BR": "Tamanho da grade", + "pt_BR": "Tamanho da Grade", "ru_RU": "Размер сетки", + "sv_SE": "Rutnätsstorlek", "th_TH": "ขนาดตาราง", "tr_TR": "Öge Boyutu", "uk_UA": "Розмір сітки", @@ -15782,6 +17414,7 @@ "pl_PL": "Zmień rozmiar elementów siatki", "pt_BR": "Mudar tamanho dos items da grade", "ru_RU": "Меняет размер сетки элементов", + "sv_SE": "Ändra objektstorleken för rutnätet", "th_TH": "เปลี่ยนขนาด ของตาราง", "tr_TR": "Grid ögelerinin boyutunu değiştirmeyi sağlar", "uk_UA": "Змінити розмір елементів сітки", @@ -15806,6 +17439,7 @@ "pl_PL": "Brazylijski Portugalski", "pt_BR": "Português do Brasil", "ru_RU": "Португальский язык (Бразилия)", + "sv_SE": "Portugisiska (braziliansk)", "th_TH": "บราซิล โปรตุเกส", "tr_TR": "Brezilya Portekizcesi", "uk_UA": "Португальська (Бразилія)", @@ -15828,8 +17462,9 @@ "ko_KR": "모든 기여자 보기", "no_NO": "Se alle bidragsytere", "pl_PL": "Zobacz Wszystkich Współtwórców", - "pt_BR": "Ver todos os contribuidores", + "pt_BR": "Ver Todos os Contribuidores", "ru_RU": "Посмотреть всех участников", + "sv_SE": "Visa alla som bidragit", "th_TH": "ดูผู้มีส่วนร่วมทั้งหมด", "tr_TR": "Tüm katkıda bulunanları gör", "uk_UA": "Переглянути всіх співавторів", @@ -15854,6 +17489,7 @@ "pl_PL": "Głośność: ", "pt_BR": "Volume:", "ru_RU": "Громкость: ", + "sv_SE": "Volym: ", "th_TH": "ระดับเสียง: ", "tr_TR": "Ses Seviyesi: ", "uk_UA": "Гучність: ", @@ -15876,8 +17512,9 @@ "ko_KR": "음량 변경", "no_NO": "Endre lydenivå", "pl_PL": "Zmień Głośność Dźwięku", - "pt_BR": "Mudar volume do áudio", + "pt_BR": "Mudar Volume do Áudio", "ru_RU": "Изменяет громкость звука", + "sv_SE": "Ändra ljudvolym", "th_TH": "ปรับระดับเสียง", "tr_TR": "Ses seviyesini değiştirir", "uk_UA": "Змінити гучність звуку", @@ -15900,8 +17537,9 @@ "ko_KR": "게스트 인터넷 접속/LAN 모드", "no_NO": "Internett-tilgang for gjeste/LAN-modus", "pl_PL": "Dostęp do Internetu Gościa/Tryb LAN", - "pt_BR": "Habilitar acesso à internet do programa convidado", + "pt_BR": "Acesso à Internet para Convidados/Modo LAN", "ru_RU": "Гостевой доступ в интернет/сетевой режим", + "sv_SE": "Gäståtkomst för Internet/LAN-läge", "th_TH": "การเข้าถึงอินเทอร์เน็ตของผู้เยี่ยมชม/โหมด LAN", "tr_TR": "Guest Internet Erişimi/LAN Modu", "uk_UA": "Гостьовий доступ до Інтернету/режим LAN", @@ -15924,8 +17562,9 @@ "ko_KR": "에뮬레이트된 앱을 인터넷에 연결할 수 있습니다.\n\nLAN 모드가 있는 게임은 이 기능이 활성화되고 시스템이 동일한 접속 포인트에 연결되어 있을 때 서로 연결할 수 있습니다. 이는 실제 콘솔도 포함됩니다.\n\nNintendo 서버 연결을 허용하지 않습니다. 인터넷에 연결을 시도하는 특정 게임에서 충돌이 발생할 수 있습니다.\n\n모르면 끔으로 두세요.", "no_NO": "Tillater emulert applikasjon å koble til Internett.\n\nSpill med en LAN-modus kan koble til hverandre når dette er aktivert og systemene er koblet til det samme tilgangspunktet. Dette inkluderer ekte konsoller også.\n\ntillater IKKE tilkobling til Nintendo servere. Kan forårsake krasjing i enkelte spill som prøver å koble til Internett.\n\nLa stå AV hvis du er usikker.", "pl_PL": "Pozwala emulowanej aplikacji na łączenie się z Internetem.\n\nGry w trybie LAN mogą łączyć się ze sobą, gdy ta opcja jest włączona, a systemy są połączone z tym samym punktem dostępu. Dotyczy to również prawdziwych konsol.\n\nNie pozwala na łączenie się z serwerami Nintendo. Może powodować awarie niektórych gier, które próbują połączyć się z Internetem.\n\nPozostaw WYŁĄCZONE, jeśli nie masz pewności.", - "pt_BR": "Habilita acesso à internet do programa convidado. Se habilitado, o aplicativo vai se comportar como se o sistema Switch emulado estivesse conectado a Internet. Note que em alguns casos, aplicativos podem acessar a Internet mesmo com essa opção desabilitada", + "pt_BR": "Permite que o aplicativo emulado se conecte à Internet.\n\nJogos com modo LAN podem se conectar uns aos outros quando isso está habilitado e os sistemas estão conectados ao mesmo ponto de acesso. Isso inclui consoles reais também.\n\nNÃO permite a conexão com servidores Nintendo. Pode causar travamentos em certos jogos que tentam se conectar à Internet.\n\nDeixe DESLIGADO se não tiver certeza.", "ru_RU": "Позволяет эмулированному приложению подключаться к Интернету.\n\nПри включении этой функции игры с возможностью сетевой игры могут подключаться друг к другу, если все эмуляторы (или реальные консоли) подключены к одной и той же точке доступа.\n\nНЕ разрешает подключение к серверам Nintendo. Может вызвать сбой в некоторых играх, которые пытаются подключиться к Интернету.\n\nРекомендутеся оставить выключенным.", + "sv_SE": "Tillåter det emulerade programmet att ansluta till internet.\n\nSpel med ett LAN-läge kan ansluta till varandra när detta är aktiverat och systemen är anslutna till samma åtkomstpunkt. Detta inkluderar riktiga konsoler också.\n\nTillåter INTE anslutning till Nintendo-servrar. Kan orsaka kraschar i vissa spel som försöker ansluta till internet.\n\nLämna AV om du är osäker.", "th_TH": "อนุญาตให้แอปพลิเคชันจำลองเชื่อมต่ออินเทอร์เน็ต\n\nเกมที่มีโหมด LAN สามารถเชื่อมต่อระหว่างกันได้เมื่อเปิดใช้งานและระบบเชื่อมต่อกับจุดเชื่อมต่อเดียวกัน รวมถึงคอนโซลจริงด้วย\n\nไม่อนุญาตให้มีการเชื่อมต่อกับเซิร์ฟเวอร์ Nintendo อาจทำให้เกิดการหยุดทำงานในบางเกมที่พยายามเชื่อมต่ออินเทอร์เน็ต\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ", "tr_TR": "Emüle edilen uygulamanın internete bağlanmasını sağlar.\n\nLAN modu bulunan oyunlar bu seçenek ile birbirine bağlanabilir ve sistemler aynı access point'e bağlanır. Bu gerçek konsolları da kapsar.\n\nNintendo sunucularına bağlanmayı sağlaMAZ. Internete bağlanmaya çalışan baz oyunların çökmesine sebep olabilr.\n\nEmin değilseniz devre dışı bırakın.", "uk_UA": "Дозволяє емульованій програмі підключатися до Інтернету.\n\nІгри з режимом локальної мережі можуть підключатися одна до одної, якщо це увімкнено, і системи підключені до однієї точки доступу. Сюди входять і справжні консолі.\n\nНЕ дозволяє підключатися до серверів Nintendo. Може призвести до збою в деяких іграх, які намагаються підключитися до Інтернету.\n\nЗалиште вимкненим, якщо не впевнені.", @@ -15948,11 +17587,12 @@ "ko_KR": "치트 관리", "no_NO": "Administrer juksemoduser", "pl_PL": "Zarządzaj Kodami", - "pt_BR": "Gerenciar Cheats", + "pt_BR": "Gerenciar Trapaças", "ru_RU": "Открывает окно управления читами", + "sv_SE": "Hantera fusk", "th_TH": "ฟังก์ชั่นจัดการสูตรโกง", "tr_TR": "Hileleri yönetmeyi sağlar", - "uk_UA": "Керування читами", + "uk_UA": "Відкриває меню керування чит-кодами (cheats)", "zh_CN": "管理当前游戏的金手指", "zh_TW": "管理密技" } @@ -15972,8 +17612,9 @@ "ko_KR": "치트 관리", "no_NO": "Administrer juksemoduser", "pl_PL": "Zarządzaj Kodami", - "pt_BR": "Gerenciar Cheats", + "pt_BR": "Gerenciar Trapaças", "ru_RU": "Управление читами", + "sv_SE": "Hantera fusk", "th_TH": "ฟังก์ชั่นจัดการสูตรโกง", "tr_TR": "Hileleri Yönet", "uk_UA": "Керування читами", @@ -15998,9 +17639,10 @@ "pl_PL": "Zarządzaj modyfikacjami", "pt_BR": "Gerenciar Mods", "ru_RU": "Открывает окно управления модами", + "sv_SE": "Hantera moddar", "th_TH": "ฟังก์ชั่นจัดการม็อด", "tr_TR": "Modları Yönet", - "uk_UA": "Керування модами", + "uk_UA": "Відкриває меню керування модифікаціями (mods)", "zh_CN": "管理当前游戏的 MOD", "zh_TW": "管理模組" } @@ -16022,6 +17664,7 @@ "pl_PL": "Zarządzaj modyfikacjami", "pt_BR": "Gerenciar Mods", "ru_RU": "Управление модами", + "sv_SE": "Hantera moddar", "th_TH": "ฟังก์ชั่นจัดการม็อด", "tr_TR": "Modları Yönet", "uk_UA": "Керування модами", @@ -16046,6 +17689,7 @@ "pl_PL": "Zasięg:", "pt_BR": "Intervalo:", "ru_RU": "Диапазон:", + "sv_SE": "Omfång:", "th_TH": "ขอบเขต:", "tr_TR": "Menzil:", "uk_UA": "Діапазон:", @@ -16056,25 +17700,26 @@ { "ID": "DialogStopEmulationTitle", "Translations": { - "ar_SA": "ريوجينكس - إيقاف المحاكاة", - "de_DE": "Ryujinx - Beende Emulation", - "el_GR": "Ryujinx - Διακοπή εξομοίωσης", - "en_US": "Ryujinx - Stop Emulation", - "es_ES": "Ryujinx - Detener emulación", - "fr_FR": "Ryujinx - Arrêt de l'émulation", - "he_IL": "ריוג'ינקס - עצור אמולציה", - "it_IT": "Ryujinx - Ferma emulazione", - "ja_JP": "Ryujinx - エミュレーションを中止", - "ko_KR": "Ryujinx - 에뮬레이션 중지", - "no_NO": "Ryujinx - Stopp emulasjon", - "pl_PL": "Ryujinx - Zatrzymaj Emulację", - "pt_BR": "Ryujinx - Parar emulação", - "ru_RU": "Ryujinx - Остановка эмуляции", - "th_TH": "Ryujinx - หยุดการจำลอง", - "tr_TR": "Ryujinx - Emülasyonu Durdur", - "uk_UA": "Ryujinx - Зупинити емуляцію", - "zh_CN": "Ryujinx - 停止模拟", - "zh_TW": "Ryujinx - 停止模擬" + "ar_SA": "{0} - إيقاف المحاكاة", + "de_DE": "{0} - Beende Emulation", + "el_GR": "{0} - Διακοπή εξομοίωσης", + "en_US": "{0} - Stop Emulation", + "es_ES": "{0} - Detener emulación", + "fr_FR": "{0} - Arrêt de l'émulation", + "he_IL": "{0} - עצור אמולציה", + "it_IT": "{0} - Ferma emulazione", + "ja_JP": "{0} - エミュレーションを中止", + "ko_KR": "{0} - 에뮬레이션 중지", + "no_NO": "{0} - Stopp emulasjon", + "pl_PL": "{0} - Zatrzymaj Emulację", + "pt_BR": "{0} - Parar emulação", + "ru_RU": "{0} - Остановка эмуляции", + "sv_SE": "{0} - Stoppa emulering", + "th_TH": "{0} - หยุดการจำลอง", + "tr_TR": "{0} - Emülasyonu Durdur", + "uk_UA": "{0} - Зупинити емуляцію", + "zh_CN": "{0} - 停止模拟", + "zh_TW": "{0} - 停止模擬" } }, { @@ -16094,6 +17739,7 @@ "pl_PL": "Czy na pewno chcesz zatrzymać emulację?", "pt_BR": "Tem certeza que deseja parar a emulação?", "ru_RU": "Вы уверены, что хотите остановить эмуляцию?", + "sv_SE": "Är du säker på att du vill stoppa emuleringen?", "th_TH": "คุณแน่ใจหรือไม่ว่าต้องการหยุดการจำลองหรือไม่?", "tr_TR": "Emülasyonu durdurmak istediğinizden emin misiniz?", "uk_UA": "Ви впевнені, що хочете зупинити емуляцію?", @@ -16118,6 +17764,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "Процессор", + "sv_SE": "Processor", "th_TH": "ซีพียู", "tr_TR": "İşlemci", "uk_UA": "ЦП", @@ -16142,6 +17789,7 @@ "pl_PL": "Dżwięk", "pt_BR": "Áudio", "ru_RU": "Аудио", + "sv_SE": "Ljud", "th_TH": "เสียง", "tr_TR": "Ses", "uk_UA": "Аудіо", @@ -16166,6 +17814,7 @@ "pl_PL": "Sieć", "pt_BR": "Rede", "ru_RU": "Сеть", + "sv_SE": "Nätverk", "th_TH": "เครือข่าย", "tr_TR": "Ağ", "uk_UA": "Мережа", @@ -16188,8 +17837,9 @@ "ko_KR": "네트워크 연결", "no_NO": "Nettverk tilkobling", "pl_PL": "Połączenie Sieciowe", - "pt_BR": "Conexão de rede", + "pt_BR": "Conexão de Rede", "ru_RU": "Подключение к сети", + "sv_SE": "Nätverksanslutning", "th_TH": "การเชื่อมต่อเครือข่าย", "tr_TR": "Ağ Bağlantısı", "uk_UA": "Підключення до мережі", @@ -16214,9 +17864,10 @@ "pl_PL": "Cache CPU", "pt_BR": "Cache da CPU", "ru_RU": "Кэш процессора", + "sv_SE": "CPU-cache", "th_TH": "แคชซีพียู", "tr_TR": "İşlemci Belleği", - "uk_UA": "Кеш ЦП", + "uk_UA": "Кеш CPU", "zh_CN": "CPU 缓存", "zh_TW": "CPU 快取" } @@ -16236,11 +17887,12 @@ "ko_KR": "CPU 모드", "no_NO": "Prosessor modus", "pl_PL": "Pamięć CPU", - "pt_BR": "Memória da CPU", - "ru_RU": "Режим процессора", + "pt_BR": "Modo da CPU", + "ru_RU": "Режим работы процессора", + "sv_SE": "CPU-läge", "th_TH": "โหมดซีพียู", "tr_TR": "CPU Hafızası", - "uk_UA": "Пам'ять ЦП", + "uk_UA": "Режим CPU", "zh_CN": "CPU 模式", "zh_TW": "CPU 模式" } @@ -16260,8 +17912,9 @@ "ko_KR": "업데이터가 비활성화되었습니다!", "no_NO": "Oppdatering Deaktivert!", "pl_PL": "Aktualizator Wyłączony!", - "pt_BR": "Atualizador desabilitado!", + "pt_BR": "Atualizador Desabilitado!", "ru_RU": "Средство обновления отключено", + "sv_SE": "Uppdateringar inaktiverade!", "th_TH": "ปิดใช้งานการอัปเดตแล้ว!", "tr_TR": "Güncelleyici Devre Dışı!", "uk_UA": "Програму оновлення вимкнено!", @@ -16269,6 +17922,31 @@ "zh_TW": "更新已停用!" } }, + { + "ID": "UpdaterBackgroundStatusBarButtonText", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Update Available!", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Oppdatering tilgjengelig!", + "pl_PL": "", + "pt_BR": "Atualização Disponível!", + "ru_RU": "Доступно обновление!", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Доступне оновлення!", + "zh_CN": "有可用的更新!", + "zh_TW": "" + } + }, { "ID": "ControllerSettingsRotate90", "Translations": { @@ -16284,8 +17962,9 @@ "ko_KR": "시계 방향으로 90° 회전", "no_NO": "Roter 90° med klokken", "pl_PL": "Obróć o 90° w Prawo", - "pt_BR": "Rodar 90° sentido horário", + "pt_BR": "Rodar 90° Sentido Horário", "ru_RU": "Повернуть на 90° по часовой стрелке", + "sv_SE": "Rotera 90° medurs", "th_TH": "หมุน 90 องศา ตามเข็มนาฬิกา", "tr_TR": "Saat yönünde 90° Döndür", "uk_UA": "Повернути на 90° за годинниковою стрілкою", @@ -16308,11 +17987,12 @@ "ko_KR": "아이콘 크기", "no_NO": "Ikon størrelse", "pl_PL": "Rozmiar ikon", - "pt_BR": "Tamanho do ícone", + "pt_BR": "Tamanho do Ícone", "ru_RU": "Размер обложек", + "sv_SE": "Ikonstorlek", "th_TH": "ขนาดไอคอน", "tr_TR": "Ikon Boyutu", - "uk_UA": "Розмір значка", + "uk_UA": "Розмір обкладинки", "zh_CN": "图标尺寸", "zh_TW": "圖示大小" } @@ -16334,9 +18014,10 @@ "pl_PL": "Zmień rozmiar ikon gry", "pt_BR": "Muda o tamanho do ícone do jogo", "ru_RU": "Меняет размер обложек", + "sv_SE": "Ändra storleken för spelikonerna", "th_TH": "เปลี่ยนขนาดของไอคอนเกม", "tr_TR": "Oyun ikonlarının boyutunu değiştirmeyi sağlar", - "uk_UA": "Змінити розмір значків гри", + "uk_UA": "Змінити розмір обкладинок (значків) ігор", "zh_CN": "更改游戏图标的显示尺寸", "zh_TW": "變更遊戲圖示的大小" } @@ -16356,8 +18037,9 @@ "ko_KR": "콘솔 표시", "no_NO": "Vis konsoll", "pl_PL": "Pokaż Konsolę", - "pt_BR": "Exibir console", + "pt_BR": "Exibir Console", "ru_RU": "Показать консоль", + "sv_SE": "Visa konsoll", "th_TH": "แสดง คอนโซล", "tr_TR": "Konsol'u Göster", "uk_UA": "Показати консоль", @@ -16380,8 +18062,9 @@ "ko_KR": "{0}에서 셰이더 캐시를 삭제하는 중 오류 발생 : {1}", "no_NO": "Feil under tømming av shader cache ved {0}: {1}", "pl_PL": "Błąd podczas czyszczenia cache shaderów w {0}: {1}", - "pt_BR": "Erro ao deletar o shader em {0}: {1}", + "pt_BR": "Erro ao limpar o cache do shader em {0}: {1}", "ru_RU": "Ошибка очистки кэша шейдеров в {0}: {1}", + "sv_SE": "Fel vid tömning av shader cache i {0}: {1}", "th_TH": "เกิดข้อผิดพลาดในการล้างแคชแสงเงา {0}: {1}", "tr_TR": "Belirtilen shader cache temizlenirken hata {0}: {1}", "uk_UA": "Помилка очищення кешу шейдера {0}: {1}", @@ -16406,6 +18089,7 @@ "pl_PL": "Nie znaleziono kluczy", "pt_BR": "Chaves não encontradas", "ru_RU": "Ключи не найдены", + "sv_SE": "Nycklarna hittades inte", "th_TH": "ไม่พบ คีย์", "tr_TR": "Keys bulunamadı", "uk_UA": "Ключі не знайдено", @@ -16430,6 +18114,7 @@ "pl_PL": "Nie znaleziono firmware'u", "pt_BR": "Firmware não encontrado", "ru_RU": "Прошивка не найдена", + "sv_SE": "Firmware hittades inte", "th_TH": "ไม่พบ เฟิร์มแวร์", "tr_TR": "Firmware bulunamadı", "uk_UA": "Прошивка не знайдена", @@ -16447,13 +18132,14 @@ "es_ES": "Error al analizar el firmware", "fr_FR": "Erreur d'analyse du firmware", "he_IL": "שגיאת ניתוח קושחה", - "it_IT": "Errori di analisi del firmware", + "it_IT": "Errore di analisi del firmware", "ja_JP": "ファームウェアのパーズエラー", "ko_KR": "펌웨어 구문 분석 오류", "no_NO": "Fastvare analysefeil", "pl_PL": "Błąd parsowania firmware'u", - "pt_BR": "Erro na leitura do Firmware", + "pt_BR": "Erro de análise de firmware", "ru_RU": "Ошибка извлечения прошивки", + "sv_SE": "Tolkningsfel i firmware", "th_TH": "เกิดข้อผิดพลาดในการวิเคราะห์เฟิร์มแวร์", "tr_TR": "Firmware çözümleme hatası", "uk_UA": "Помилка аналізу прошивки", @@ -16478,9 +18164,10 @@ "pl_PL": "Aplikacja nie znaleziona", "pt_BR": "Aplicativo não encontrado", "ru_RU": "Приложение не найдено", + "sv_SE": "Applikationen hittades inte", "th_TH": "ไม่พบ แอปพลิเคชัน", "tr_TR": "Uygulama bulunamadı", - "uk_UA": "Додаток не знайдено", + "uk_UA": "Застосунок не знайдено", "zh_CN": "找不到游戏程序", "zh_TW": "找不到應用程式" } @@ -16502,6 +18189,7 @@ "pl_PL": "Nieznany błąd", "pt_BR": "Erro desconhecido", "ru_RU": "Неизвестная ошибка", + "sv_SE": "Okänt fel", "th_TH": "ข้อผิดพลาดที่ไม่รู้จัก", "tr_TR": "Bilinmeyen hata", "uk_UA": "Невідома помилка", @@ -16526,6 +18214,7 @@ "pl_PL": "Niezdefiniowany błąd", "pt_BR": "Erro indefinido", "ru_RU": "Неопределенная ошибка", + "sv_SE": "Odefinierat fel", "th_TH": "ข้อผิดพลาดที่ไม่ได้ระบุ", "tr_TR": "Tanımlanmayan hata", "uk_UA": "Невизначена помилка", @@ -16550,6 +18239,7 @@ "pl_PL": "Ryujinx nie mógł znaleźć twojego pliku 'prod.keys'", "pt_BR": "Ryujinx não conseguiu encontrar o seu arquivo 'prod.keys'", "ru_RU": "Ryujinx не удалось найти ваш 'prod.keys' файл", + "sv_SE": "Ryujinx kunde inte hitta din 'prod.keys'-fil", "th_TH": "Ryujinx ไม่พบไฟล์ 'prod.keys' ในเครื่องของคุณ", "tr_TR": "Ryujinx 'prod.keys' dosyasını bulamadı", "uk_UA": "Ryujinx не вдалося знайти ваш файл «prod.keys».", @@ -16574,6 +18264,7 @@ "pl_PL": "Ryujinx nie mógł znaleźć żadnego zainstalowanego firmware'u", "pt_BR": "Ryujinx não conseguiu encontrar nenhum Firmware instalado", "ru_RU": "Ryujinx не удалось найти ни одной установленной прошивки", + "sv_SE": "Ryujinx kunde inte hitta några installerade firmwares", "th_TH": "Ryujinx ไม่พบ เฟิร์มแวร์ที่ติดตั้งไว้ในเครื่องของคุณ", "tr_TR": "Ryujinx yüklü herhangi firmware bulamadı", "uk_UA": "Ryujinx не вдалося знайти встановлену прошивку", @@ -16598,6 +18289,7 @@ "pl_PL": "Ryujinx nie był w stanie zparsować dostarczonego firmware'u. Jest to zwykle spowodowane nieaktualnymi kluczami.", "pt_BR": "Ryujinx não conseguiu ler o Firmware fornecido. Geralmente isso é causado por chaves desatualizadas.", "ru_RU": "Ryujinx не удалось распаковать выбранную прошивку. Обычно это вызвано устаревшими ключами.", + "sv_SE": "Ryujinx kunde inte tolka angiven firmware. Detta sker oftast med utdaterade nycklar.", "th_TH": "Ryujinx ไม่สามารถวิเคราะห์เฟิร์มแวร์ที่ให้มาได้ ซึ่งมักมีสาเหตุมาจากคีย์ที่เก่าจนเกินไป", "tr_TR": "Ryujinx temin edilen firmware'i çözümleyemedi. Bu durum genellikle güncel olmayan keys'den kaynaklanır.", "uk_UA": "Ryujinx не вдалося проаналізувати прошивку. Зазвичай це спричинено застарілими ключами.", @@ -16622,9 +18314,10 @@ "pl_PL": "Ryujinx nie mógł znaleźć prawidłowej aplikacji na podanej ścieżce.", "pt_BR": "Ryujinx não conseguiu encontrar um aplicativo válido no caminho fornecido.", "ru_RU": "Ryujinx не удалось найти валидное приложение по указанному пути.", + "sv_SE": "Ryujinx kunde inte hitta en giltig applikation i angiven sökväg.", "th_TH": "Ryujinx ไม่พบแอปพลิเคชันที่ถูกต้องในที่เก็บไฟล์ที่กำหนด", "tr_TR": "Ryujinx belirtilen yolda geçerli bir uygulama bulamadı.", - "uk_UA": "Ryujinx не вдалося знайти дійсний додаток за вказаним шляхом", + "uk_UA": "Ryujinx не вдалося знайти дійсний застосунок (гру) за вказаним шляхом", "zh_CN": "Ryujinx 模拟器在所选路径中找不到有效的游戏程序。", "zh_TW": "Ryujinx 無法在指定路徑下找到有效的應用程式。" } @@ -16644,8 +18337,9 @@ "ko_KR": "알 수 없는 오류가 발생했습니다!", "no_NO": "En ukjent feil oppstod!", "pl_PL": "Wystąpił nieznany błąd!", - "pt_BR": "Um erro desconhecido foi encontrado!", + "pt_BR": "Ocorreu um erro desconhecido!", "ru_RU": "Произошла неизвестная ошибка", + "sv_SE": "Ett okänt fel inträffade!", "th_TH": "เกิดข้อผิดพลาดที่ไม่รู้จัก!", "tr_TR": "Bilinmeyen bir hata oluştu!", "uk_UA": "Сталася невідома помилка!", @@ -16670,9 +18364,10 @@ "pl_PL": "Wystąpił niezdefiniowany błąd! To nie powinno się zdarzyć, skontaktuj się z deweloperem!", "pt_BR": "Um erro indefinido occoreu! Isso não deveria acontecer, por favor contate um desenvolvedor!", "ru_RU": "Произошла неизвестная ошибка. Этого не должно происходить, пожалуйста, свяжитесь с разработчиками.", + "sv_SE": "Ett odefinierat fel inträffade! Detta ska inte hända. Kontakta en utvecklare!", "th_TH": "เกิดข้อผิดพลาดที่ไม่สามารถระบุได้! สิ่งนี้ไม่ควรเกิดขึ้น โปรดติดต่อผู้พัฒนา!", "tr_TR": "Tanımlanmayan bir hata oluştu! Bu durum ile karşılaşılmamalıydı, lütfen bir geliştirici ile iletişime geçin!", - "uk_UA": "Сталася невизначена помилка! Цього не повинно статися, зверніться до розробника!", + "uk_UA": "Виникла невизначена помилка! Це не повинно було статися. Будь ласка, зверніться до розробника!", "zh_CN": "出现未定义错误!此类错误不应出现,请联系开发者!", "zh_TW": "發生未定義錯誤! 這種情況不應該發生,請聯絡開發人員!" } @@ -16692,8 +18387,9 @@ "ko_KR": "설정 가이드 열기", "no_NO": "Åpne oppsettsveiledningen", "pl_PL": "Otwórz Podręcznik Konfiguracji", - "pt_BR": "Abrir o guia de configuração", + "pt_BR": "Abrir o Guia de Configuração", "ru_RU": "Открыть руководство по установке", + "sv_SE": "Öppna konfigurationsguiden", "th_TH": "เปิดคู่มือการตั้งค่า", "tr_TR": "Kurulum Kılavuzunu Aç", "uk_UA": "Відкрити посібник із налаштування", @@ -16716,11 +18412,12 @@ "ko_KR": "업데이트 없음", "no_NO": "Ingen oppdatering", "pl_PL": "Brak Aktualizacji", - "pt_BR": "Sem atualizações", + "pt_BR": "Sem Atualizações", "ru_RU": "Без обновлений", + "sv_SE": "Ingen uppdatering", "th_TH": "ไม่มีการอัปเดต", "tr_TR": "Güncelleme Yok", - "uk_UA": "Немає оновлень", + "uk_UA": "НБез оновлень", "zh_CN": "无更新(默认版本)", "zh_TW": "沒有更新" } @@ -16729,22 +18426,23 @@ "ID": "TitleUpdateVersionLabel", "Translations": { "ar_SA": "الإصدار: {0}", - "de_DE": "Version {0} - {1}", - "el_GR": "Version {0} - {1}", + "de_DE": "", + "el_GR": "", "en_US": "Version {0}", - "es_ES": "Versión {0} - {1}", + "es_ES": "Versión {0}", "fr_FR": "", - "he_IL": "גרסה {0}", + "he_IL": "גרסה: {0}", "it_IT": "Versione {0}", - "ja_JP": "バージョン {0} - {1}", + "ja_JP": "バージョン {0}", "ko_KR": "버전 {0}", "no_NO": "Versjon {0}", - "pl_PL": "Wersja {0} - {1}", + "pl_PL": "Wersja {0}", "pt_BR": "Versão {0}", - "ru_RU": "Version {0} - {1}", + "ru_RU": "Версия {0}", + "sv_SE": "", "th_TH": "เวอร์ชั่น {0}", - "tr_TR": "Sürüm {0} - {1}", - "uk_UA": "Версія {0} - {1}", + "tr_TR": "Sürüm {0}", + "uk_UA": "Версія {0}", "zh_CN": "游戏更新的版本 {0}", "zh_TW": "版本 {0}" } @@ -16759,13 +18457,14 @@ "es_ES": "Incorporado: Versión {0}", "fr_FR": "Inclus avec le jeu: Version {0}", "he_IL": "", - "it_IT": "In bundle: Versione {0}", + "it_IT": "Incluso: Versione {0}", "ja_JP": "", "ko_KR": "번들 : 버전 {0}", "no_NO": "Pakket: Versjon {0}", "pl_PL": "", "pt_BR": "Empacotado: Versão {0}", - "ru_RU": "", + "ru_RU": "Баднл: Версия {0}", + "sv_SE": "Bundlad: Version {0}", "th_TH": "Bundled: เวอร์ชั่น {0}", "tr_TR": "", "uk_UA": "Комплектні: Версія {0}", @@ -16783,13 +18482,14 @@ "es_ES": "Incorporado:", "fr_FR": "Inclus avec le jeu :", "he_IL": "", - "it_IT": "In bundle:", + "it_IT": "Incluso:", "ja_JP": "", "ko_KR": "번들 :", "no_NO": "Pakket:", "pl_PL": "", "pt_BR": "Empacotado:", - "ru_RU": "", + "ru_RU": "Бандл:", + "sv_SE": "Bundlad:", "th_TH": "", "tr_TR": "", "uk_UA": "Комплектні:", @@ -16812,13 +18512,14 @@ "ko_KR": "일부", "no_NO": "Delvis", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Parcial", + "ru_RU": "Частично", + "sv_SE": "Delvis", "th_TH": "", "tr_TR": "", "uk_UA": "Часткові", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "分区", + "zh_TW": "部分" } }, { @@ -16831,18 +18532,19 @@ "es_ES": "Sin recortar", "fr_FR": "Non réduit", "he_IL": "", - "it_IT": "Non Trimmato", + "it_IT": "Dim. originale", "ja_JP": "", "ko_KR": "트리밍되지 않음", "no_NO": "Ikke trimmet", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Não Reduzido", + "ru_RU": "Не обрезан", + "sv_SE": "Inte optimerad", "th_TH": "", "tr_TR": "", "uk_UA": "Необрізані", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "没有瘦身的", + "zh_TW": "未修剪" } }, { @@ -16855,18 +18557,19 @@ "es_ES": "Recortado", "fr_FR": "Réduit", "he_IL": "", - "it_IT": "Trimmato", + "it_IT": "Dim. ridotta", "ja_JP": "", "ko_KR": "트리밍됨", "no_NO": "Trimmet", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzido", + "ru_RU": "Обрезан", + "sv_SE": "Optimerad", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізані", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "经过瘦身的", + "zh_TW": "已修剪" } }, { @@ -16884,13 +18587,14 @@ "ko_KR": "(실패)", "no_NO": "(Mislyktes)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Falhou", + "ru_RU": "(Ошибка)", + "sv_SE": "(misslyckades)", "th_TH": "", "tr_TR": "", "uk_UA": "(Невдача)", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "(失败)", + "zh_TW": "(失敗)" } }, { @@ -16903,18 +18607,19 @@ "es_ES": "Ahorra {0:n0} Mb", "fr_FR": "Sauvegarde de {0:n0} Mo", "he_IL": "", - "it_IT": "Salva {0:n0} Mb", + "it_IT": "Risparmia {0:n0} MB", "ja_JP": "", "ko_KR": "{0:n0} Mb 저장", "no_NO": "Spare {0:n0} Mb", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Salvar {0:n0} Mb", + "ru_RU": "Сохранить {0:n0} Мб", + "sv_SE": "Spara {0:n0} Mb", "th_TH": "", "tr_TR": "", "uk_UA": "Зберегти {0:n0} Мб", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "能节约 {0:n0} Mb", + "zh_TW": "可節省 {0:n0} Mb" } }, { @@ -16927,66 +18632,69 @@ "es_ES": "{0:n0} Mb ahorrado(s)", "fr_FR": "Sauvegardé {0:n0} Mo", "he_IL": "", - "it_IT": "Salva {0:n0} Mb", + "it_IT": "Risparmiati {0:n0} MB", "ja_JP": "", "ko_KR": "{0:n0}Mb 저장됨", "no_NO": "Spart {0:n0} Mb", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Salvo {0:n0} Mb", + "ru_RU": "Сохранено {0:n0} Мб", + "sv_SE": "Sparade {0:n0} Mb", "th_TH": "", "tr_TR": "", "uk_UA": "Збережено {0:n0} Мб", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "节约了 {0:n0} Mb", + "zh_TW": "已節省 {0:n0} Mb" } }, { "ID": "RyujinxInfo", "Translations": { - "ar_SA": "ريوجينكس - معلومات", + "ar_SA": "{0} - معلومات", "de_DE": "", - "el_GR": "Ryujinx - Πληροφορίες", - "en_US": "Ryujinx - Info", + "el_GR": "{0} - Πληροφορίες", + "en_US": "{0} - Info", "es_ES": "", "fr_FR": "", - "he_IL": "ריוג'ינקס - מידע", - "it_IT": "Ryujinx - Informazioni", - "ja_JP": "Ryujinx - 情報", - "ko_KR": "Ryujinx - 정보", - "no_NO": "Ryujinx - Informasjon", + "he_IL": "{0} - מידע", + "it_IT": "{0} - Informazioni", + "ja_JP": "{0} - 情報", + "ko_KR": "{0} - 정보", + "no_NO": "{0} - Informasjon", "pl_PL": "", - "pt_BR": "Ryujinx - Informação", - "ru_RU": "Ryujinx - Информация", - "th_TH": "Ryujinx – ข้อมูล", - "tr_TR": "Ryujinx - Bilgi", - "uk_UA": "Ryujin x - Інформація", - "zh_CN": "Ryujinx - 信息", - "zh_TW": "Ryujinx - 資訊" + "pt_BR": "{0} - Informação", + "ru_RU": "{0} - Информация", + "sv_SE": "{0} - Information", + "th_TH": "{0} – ข้อมูล", + "tr_TR": "{0} - Bilgi", + "uk_UA": "{0} - Інформація", + "zh_CN": "{0} - 信息", + "zh_TW": "{0} - 資訊" } }, { "ID": "RyujinxConfirm", "Translations": { - "ar_SA": "ريوجينكس - تأكيد", - "de_DE": "Ryujinx - Bestätigung", - "el_GR": "Ryujinx - Επιβεβαίωση", - "en_US": "Ryujinx - Confirmation", - "es_ES": "Ryujinx - Confirmación", + "ar_SA": "{0} - تأكيد", + "de_DE": "{0} - Bestätigung", + "el_GR": "{0} - Επιβεβαίωση", + "en_US": "{0} - Confirmation", + "es_ES": "{0} - Confirmación", "fr_FR": "", - "he_IL": "ריוג'ינקס - אישור", - "it_IT": "Ryujinx - Conferma", - "ja_JP": "Ryujinx - 確認", - "ko_KR": "Ryujinx - 확인", - "no_NO": "Ryujinx - Bekreftelse", - "pl_PL": "Ryujinx - Potwierdzenie", - "pt_BR": "Ryujinx - Confirmação", - "ru_RU": "Ryujinx - Подтверждение", - "th_TH": "Ryujinx - ยืนยัน", - "tr_TR": "Ryujinx - Doğrulama", - "uk_UA": "Ryujinx - Підтвердження", - "zh_CN": "Ryujinx - 确认", - "zh_TW": "Ryujinx - 確認" + "he_IL": "{0} - אישור", + "it_IT": "{0} - Conferma", + "ja_JP": "{0} - 確認", + "ko_KR": "{0} - 확인", + "no_NO": "{0} - Bekreftelse", + "pl_PL": "{0} - Potwierdzenie", + "pt_BR": "{0} - Confirmação", + "ru_RU": "{0} - Подтверждение", + "sv_SE": "{0} - Bekräfta", + "th_TH": "{0} - ยืนยัน", + "tr_TR": "{0} - Doğrulama", + "uk_UA": "{0} - Підтвердження", + "zh_CN": "{0} - 确认", + "zh_TW": "{0} - 確認" } }, { @@ -17006,6 +18714,7 @@ "pl_PL": "Wszystkie typy", "pt_BR": "Todos os tipos", "ru_RU": "Все типы", + "sv_SE": "Alla typer", "th_TH": "ทุกประเภท", "tr_TR": "Tüm türler", "uk_UA": "Всі типи", @@ -17030,6 +18739,7 @@ "pl_PL": "Nigdy", "pt_BR": "Nunca", "ru_RU": "Никогда", + "sv_SE": "Aldrig", "th_TH": "ไม่ต้อง", "tr_TR": "Hiçbir Zaman", "uk_UA": "Ніколи", @@ -17054,6 +18764,7 @@ "pl_PL": "Musi mieć co najmniej {0} znaków", "pt_BR": "Deve ter pelo menos {0} caracteres", "ru_RU": "Должно быть не менее {0} символов.", + "sv_SE": "Får endast vara minst {0} tecken långt", "th_TH": "ต้องมีความยาวของตัวอักษรอย่างน้อย {0} ตัว", "tr_TR": "En az {0} karakter uzunluğunda olmalı", "uk_UA": "Мінімальна кількість символів: {0}", @@ -17078,6 +18789,7 @@ "pl_PL": "Musi mieć długość od {0}-{1} znaków", "pt_BR": "Deve ter entre {0}-{1} caracteres", "ru_RU": "Должно быть {0}-{1} символов", + "sv_SE": "Får endast vara {0}-{1} tecken långt", "th_TH": "ต้องมีความยาวของตัวอักษร {0}-{1} ตัว", "tr_TR": "{0}-{1} karakter uzunluğunda olmalı", "uk_UA": "Має бути {0}-{1} символів", @@ -17100,13 +18812,14 @@ "ko_KR": "캐비닛 대화 상자", "no_NO": "Dialogboks for kabinett", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Diálogo do Gabinete", + "ru_RU": "Сообщение кабинета", + "sv_SE": "Cabinet-dialog", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Сповіщення Cabinet", + "zh_CN": "档案对话框", + "zh_TW": "Cabinet 對話方塊" } }, { @@ -17119,18 +18832,19 @@ "es_ES": "Ingresa el nuevo nombre de tu Amiibo", "fr_FR": "Entrer le nouveau nom de votre Amiibo", "he_IL": "", - "it_IT": "", + "it_IT": "Inserisci il nuovo nome del tuo Amiibo", "ja_JP": "", "ko_KR": "Amiibo의 새 이름 입력하기", "no_NO": "Skriv inn Amiiboens nye navn", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Digite o novo nome do seu Amiibo", + "ru_RU": "Введите новое имя вашего Amiibo", + "sv_SE": "Ange nya namnet för din Amiibo", "th_TH": "", "tr_TR": "", "uk_UA": "Вкажіть Ваше нове ім'я Amiibo", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "输入你的 Amiibo 的新名字", + "zh_TW": "輸入 Amiibo 的新名稱" } }, { @@ -17143,18 +18857,19 @@ "es_ES": "Escanea tu Amiibo ahora.", "fr_FR": "Veuillez scannez votre Amiibo.", "he_IL": "", - "it_IT": "", + "it_IT": "Scansiona ora il tuo Amiibo.", "ja_JP": "", "ko_KR": "지금 Amiibo를 스캔하세요.", "no_NO": "Vennligst skann Amiiboene dine nå.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Por favor, escaneie seu Amiibo agora.", + "ru_RU": "Пожалуйста, отсканируйте свой Amiibo.", + "sv_SE": "Skanna din Amiibo nu.", "th_TH": "", "tr_TR": "", "uk_UA": "Будь ласка, проскануйте Ваш Amiibo.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "请现在扫描你的 Amiibo", + "zh_TW": "請掃描你的 Amiibo。" } }, { @@ -17174,6 +18889,7 @@ "pl_PL": "Klawiatura Oprogramowania", "pt_BR": "Teclado por Software", "ru_RU": "Программная клавиатура", + "sv_SE": "Programvarutangentbord", "th_TH": "ซอฟต์แวร์คีย์บอร์ด", "tr_TR": "Yazılım Klavyesi", "uk_UA": "Програмна клавіатура", @@ -17191,13 +18907,14 @@ "es_ES": "Debe ser sólo 0-9 o '.'", "fr_FR": "Doit être 0-9 ou '.' uniquement", "he_IL": "חייב להיות בין 0-9 או '.' בלבד", - "it_IT": "Deve essere solo 0-9 o '.'", + "it_IT": "Può contenere solo numeri o '.'", "ja_JP": "0-9 または '.' のみでなければなりません", "ko_KR": "0-9 또는 '.'만 가능", "no_NO": "Må kun være 0-9 eller '.'", "pl_PL": "Może składać się jedynie z 0-9 lub '.'", "pt_BR": "Deve ser somente 0-9 ou '.'", "ru_RU": "Должно быть в диапазоне 0-9 или '.'", + "sv_SE": "Får endast vara 0-9 eller '.'", "th_TH": "ต้องเป็น 0-9 หรือ '.' เท่านั้น", "tr_TR": "Sadece 0-9 veya '.' olabilir", "uk_UA": "Повинно бути лише 0-9 або “.”", @@ -17215,13 +18932,14 @@ "es_ES": "Solo deben ser caracteres no CJK", "fr_FR": "Doit être uniquement des caractères non CJK", "he_IL": "מחויב להיות ללא אותיות CJK", - "it_IT": "Deve essere solo caratteri non CJK", + "it_IT": "Può contenere solo caratteri non CJK", "ja_JP": "CJK文字以外のみ", "ko_KR": "CJK 문자가 아닌 문자만 가능", "no_NO": "Må kun være uten CJK-tegn", "pl_PL": "Nie może zawierać znaków CJK", "pt_BR": "Apenas devem ser caracteres não CJK.", "ru_RU": "Не должно быть CJK-символов", + "sv_SE": "Får endast vara icke-CJK-tecken", "th_TH": "ต้องเป็นตัวอักษรที่ไม่ใช่ประเภท CJK เท่านั้น", "tr_TR": "Sadece CJK-characters olmayan karakterler olabilir", "uk_UA": "Повинно бути лише не CJK-символи", @@ -17239,13 +18957,14 @@ "es_ES": "Solo deben ser texto ASCII", "fr_FR": "Doit être uniquement du texte ASCII", "he_IL": "מחויב להיות טקסט אסקיי", - "it_IT": "Deve essere solo testo ASCII", + "it_IT": "Può contenere solo testo ASCII", "ja_JP": "ASCII文字列のみ", "ko_KR": "ASCII 텍스트만 가능", "no_NO": "Må være kun ASCII-tekst", "pl_PL": "Musi zawierać tylko tekst ASCII", "pt_BR": "Deve ser apenas texto ASCII", "ru_RU": "Текст должен быть только в ASCII кодировке", + "sv_SE": "Får endast vara ASCII-text", "th_TH": "ต้องเป็นตัวอักษร ASCII เท่านั้น", "tr_TR": "Sadece ASCII karakterler olabilir", "uk_UA": "Повинно бути лише ASCII текст", @@ -17268,8 +18987,9 @@ "ko_KR": "지원되는 컨트롤러 :", "no_NO": "Støttede kontrollere:", "pl_PL": "Obsługiwane Kontrolery:", - "pt_BR": "", + "pt_BR": "Controladores Suportados:", "ru_RU": "Поддерживаемые геймпады:", + "sv_SE": "Handkontroller som stöds:", "th_TH": "คอนโทรลเลอร์ที่รองรับ:", "tr_TR": "Desteklenen Kumandalar:", "uk_UA": "Підтримувані контролери:", @@ -17294,6 +19014,7 @@ "pl_PL": "Gracze:", "pt_BR": "Jogadores:", "ru_RU": "Игроки:", + "sv_SE": "Spelare:", "th_TH": "ผู้เล่น:", "tr_TR": "Oyuncular:", "uk_UA": "Гравці:", @@ -17316,8 +19037,9 @@ "ko_KR": "현재 구성이 유효하지 않습니다. 설정을 열고 입력을 다시 구성하십시오.", "no_NO": "Din nåværende konfigurasjon er ugyldig. Åpne innstillinger og konfigurer inndata.", "pl_PL": "Twoja aktualna konfiguracja jest nieprawidłowa. Otwórz ustawienia i skonfiguruj swoje wejścia.", - "pt_BR": "", + "pt_BR": "Sua configuração atual é inválida. Abra as configurações e reconfigure suas entradas.", "ru_RU": "Текущая конфигурация некорректна. Откройте параметры и перенастройте управление.", + "sv_SE": "Din aktuella konfiguration är ogiltig. Öppna inställningarna och konfigurera om din inmatning.", "th_TH": "การกำหนดค่าปัจจุบันของคุณไม่ถูกต้อง กรุณาเปิดการตั้งค่าและกำหนดค่าอินพุตของคุณใหม่", "tr_TR": "Halihazırdaki konfigürasyonunuz geçersiz. Ayarları açın ve girişlerinizi yeniden konfigüre edin.", "uk_UA": "Поточна конфігурація невірна. Відкрийте налаштування та переналаштуйте Ваші дані.", @@ -17340,8 +19062,9 @@ "ko_KR": "도킹 모드가 설정되었습니다. 휴대용 제어 기능을 비활성화해야 합니다.", "no_NO": "Docked modus. Håndholdt kontroll skal være deaktivert.", "pl_PL": "Ustawiony tryb zadokowany. Sterowanie przenośne powinno być wyłączone.", - "pt_BR": "", + "pt_BR": "Modo TV definido. O controle portátil deve ser desabilitado.", "ru_RU": "Используется стационарный режим. Управление в портативном режиме должно быть отключено.", + "sv_SE": "Dockat läge angivet. Handhållna kontroller bör inaktiveras.", "th_TH": "ตั้งค่าด็อกโหมด ควรปิดใช้งานการควบคุมแบบแฮนด์เฮลด์", "tr_TR": "Docked mod ayarlandı. Portatif denetim devre dışı bırakılmalı.", "uk_UA": "Встановлений режим в док-станції. Вимкніть портативні контролери.", @@ -17359,13 +19082,14 @@ "es_ES": "Renombrando archivos viejos...", "fr_FR": "Renommage des anciens fichiers...", "he_IL": "משנה שמות של קבצים ישנים...", - "it_IT": "Rinominazione dei vecchi files...", + "it_IT": "Ridenominazione dei vecchi file...", "ja_JP": "古いファイルをリネーム中...", "ko_KR": "오래된 파일 이름 바꾸기...", "no_NO": "Omdøper gamle filer...", "pl_PL": "Zmienianie Nazw Starych Plików...", "pt_BR": "Renomeando arquivos antigos...", "ru_RU": "Переименование старых файлов...", + "sv_SE": "Byter namn på gamla filer...", "th_TH": "กำลังเปลี่ยนชื่อไฟล์เก่า...", "tr_TR": "Eski dosyalar yeniden adlandırılıyor...", "uk_UA": "Перейменування старих файлів...", @@ -17390,6 +19114,7 @@ "pl_PL": "Aktualizator nie mógł zmienić nazwy pliku: {0}", "pt_BR": "O atualizador não conseguiu renomear o arquivo: {0}", "ru_RU": "Программе обновления не удалось переименовать файл: {0}", + "sv_SE": "Uppdateraren kunde inte byta namn på filen: {0}", "th_TH": "โปรแกรมอัปเดตไม่สามารถเปลี่ยนชื่อไฟล์ได้: {0}", "tr_TR": "Güncelleyici belirtilen dosyayı yeniden adlandıramadı: {0}", "uk_UA": "Програмі оновлення не вдалося перейменувати файл: {0}", @@ -17412,8 +19137,9 @@ "ko_KR": "새 파일 추가...", "no_NO": "Legger til nye filer...", "pl_PL": "Dodawanie Nowych Plików...", - "pt_BR": "Adicionando novos arquivos...", + "pt_BR": "Adicionando Novos Arquivos...", "ru_RU": "Добавление новых файлов...", + "sv_SE": "Lägger till nya filer...", "th_TH": "กำลังเพิ่มไฟล์ใหม่...", "tr_TR": "Yeni Dosyalar Ekleniyor...", "uk_UA": "Додавання нових файлів...", @@ -17436,8 +19162,9 @@ "ko_KR": "업데이트 추출...", "no_NO": "Pakker ut oppdatering...", "pl_PL": "Wypakowywanie Aktualizacji...", - "pt_BR": "Extraíndo atualização...", + "pt_BR": "Extraíndo Atualização...", "ru_RU": "Извлечение обновления...", + "sv_SE": "Extraherar uppdatering...", "th_TH": "กำลังแยกการอัปเดต...", "tr_TR": "Güncelleme Ayrıştırılıyor...", "uk_UA": "Видобування оновлення...", @@ -17460,8 +19187,9 @@ "ko_KR": "업데이트 내려받기 중...", "no_NO": "Laster ned oppdatering...", "pl_PL": "Pobieranie Aktualizacji...", - "pt_BR": "Baixando atualização...", + "pt_BR": "Baixando Atualização...", "ru_RU": "Загрузка обновления...", + "sv_SE": "Hämtar uppdatering...", "th_TH": "กำลังดาวน์โหลดอัปเดต...", "tr_TR": "Güncelleme İndiriliyor...", "uk_UA": "Завантаження оновлення...", @@ -17484,8 +19212,9 @@ "ko_KR": "도킹", "no_NO": "Forankret", "pl_PL": "Zadokowany", - "pt_BR": "TV", + "pt_BR": "Dock/TV", "ru_RU": "Стационарный режим", + "sv_SE": "Dockad", "th_TH": "ด็อก", "tr_TR": "", "uk_UA": "Док-станція", @@ -17510,6 +19239,7 @@ "pl_PL": "Przenośny", "pt_BR": "Portátil", "ru_RU": "Портативный режим", + "sv_SE": "Handhållen", "th_TH": "แฮนด์เฮลด์", "tr_TR": "El tipi", "uk_UA": "Портативний", @@ -17532,8 +19262,9 @@ "ko_KR": "연결 오류가 발생했습니다.", "no_NO": "Tilkoblingsfeil", "pl_PL": "Błąd Połączenia.", - "pt_BR": "Erro de conexão.", + "pt_BR": "Erro de Conexão.", "ru_RU": "Ошибка соединения", + "sv_SE": "Anslutningsfel.", "th_TH": "การเชื่อมต่อล้มเหลว", "tr_TR": "Bağlantı Hatası.", "uk_UA": "Помилка з'єднання.", @@ -17558,6 +19289,7 @@ "pl_PL": "{0} i więcej...", "pt_BR": "{0} e mais...", "ru_RU": "{0} и другие...", + "sv_SE": "{0} och fler...", "th_TH": "{0} และอื่นๆ ...", "tr_TR": "{0} ve daha fazla...", "uk_UA": "{0} та інші...", @@ -17582,6 +19314,7 @@ "pl_PL": "Błąd API.", "pt_BR": "Erro de API.", "ru_RU": "Ошибка API.", + "sv_SE": "API-fel.", "th_TH": "ข้อผิดพลาดของ API", "tr_TR": "API Hatası.", "uk_UA": "Помилка API.", @@ -17606,6 +19339,7 @@ "pl_PL": "Wczytywanie {0}", "pt_BR": "Carregando {0}", "ru_RU": "Загрузка {0}", + "sv_SE": "Läser in {0}", "th_TH": "กำลังโหลด {0}", "tr_TR": "{0} Yükleniyor", "uk_UA": "Завантаження {0}", @@ -17617,24 +19351,25 @@ "ID": "CompilingPPTC", "Translations": { "ar_SA": "تجميع الـ‫(PPTC)", - "de_DE": "PTC wird kompiliert", - "el_GR": "Μεταγλώττιση του PTC", - "en_US": "Compiling PTC", - "es_ES": "Compilando PTC", - "fr_FR": "Compilation PTC", - "he_IL": "קימפול PTC", + "de_DE": "PPTC wird kompiliert", + "el_GR": "Μεταγλώττιση του PPTC", + "en_US": "Compiling PPTC", + "es_ES": "Compilando PPTC", + "fr_FR": "Compilation PPTC", + "he_IL": "קימפול PPTC", "it_IT": "Compilazione PPTC", - "ja_JP": "PTC をコンパイル中", - "ko_KR": "PTC 컴파일", - "no_NO": "Sammensetter PTC", - "pl_PL": "Kompilowanie PTC", - "pt_BR": "Compilando PTC", - "ru_RU": "Компиляция PTC", - "th_TH": "กำลังคอมไพล์ PTC", - "tr_TR": "PTC Derleniyor", - "uk_UA": "Компіляція PTC", + "ja_JP": "PPTC をコンパイル中", + "ko_KR": "PPTC 컴파일", + "no_NO": "Sammensetter PPTC", + "pl_PL": "Kompilowanie PPTC", + "pt_BR": "Compilando PPTC", + "ru_RU": "Компиляция PPTC", + "sv_SE": "Kompilerar PPTC", + "th_TH": "กำลังคอมไพล์ PPTC", + "tr_TR": "PPTC Derleniyor", + "uk_UA": "Компіляція PPTC", "zh_CN": "编译 PPTC 缓存中", - "zh_TW": "正在編譯 PTC" + "zh_TW": "正在編譯 PPTC" } }, { @@ -17654,6 +19389,7 @@ "pl_PL": "Kompilowanie Shaderów", "pt_BR": "Compilando Shaders", "ru_RU": "Компиляция шейдеров", + "sv_SE": "Kompilerar shaders", "th_TH": "กำลังคอมไพล์ พื้นผิวและแสงเงา", "tr_TR": "Shaderlar Derleniyor", "uk_UA": "Компіляція шейдерів", @@ -17676,8 +19412,9 @@ "ko_KR": "모든 키보드", "no_NO": "Alle tastaturer", "pl_PL": "Wszystkie klawiatury", - "pt_BR": "Todos os teclados", + "pt_BR": "Todos os Teclados", "ru_RU": "Все клавиатуры", + "sv_SE": "Alla tangentbord", "th_TH": "คีย์บอร์ดทั้งหมด", "tr_TR": "Tüm Klavyeler", "uk_UA": "Всі клавіатури", @@ -17702,6 +19439,7 @@ "pl_PL": "Wybierz obsługiwany plik do otwarcia", "pt_BR": "Selecione um arquivo suportado para abrir", "ru_RU": "Выберите совместимый файл для открытия", + "sv_SE": "Välj en fil som stöds att öppna", "th_TH": "เลือกไฟล์ที่สนับสนุนเพื่อเปิด", "tr_TR": "Açmak için desteklenen bir dosya seçin", "uk_UA": "Виберіть підтримуваний файл для відкриття", @@ -17724,8 +19462,9 @@ "ko_KR": "압축 해제된 게임이 있는 폴더를 선택", "no_NO": "Velg en mappe med et pakket ut spill", "pl_PL": "Wybierz folder z rozpakowaną grą", - "pt_BR": "Selecione um diretório com um jogo extraído", + "pt_BR": "Selecione uma pasta com um jogo descompactado", "ru_RU": "Выберите папку с распакованной игрой", + "sv_SE": "Välj en mapp med ett uppackat spel", "th_TH": "เลือกโฟลเดอร์ที่มีเกมที่แตกไฟล์แล้ว", "tr_TR": "Ayrıştırılmamış oyun içeren bir klasör seçin", "uk_UA": "Виберіть теку з розпакованою грою", @@ -17748,8 +19487,9 @@ "ko_KR": "지원되는 모든 형식", "no_NO": "Alle støttede formater", "pl_PL": "Wszystkie Obsługiwane Formaty", - "pt_BR": "Todos os formatos suportados", + "pt_BR": "Todos os Formatos Suportados", "ru_RU": "Все поддерживаемые форматы", + "sv_SE": "Alla format som stöds", "th_TH": "รูปแบบที่รองรับทั้งหมด", "tr_TR": "Tüm Desteklenen Formatlar", "uk_UA": "Усі підтримувані формати", @@ -17760,25 +19500,26 @@ { "ID": "RyujinxUpdater", "Translations": { - "ar_SA": "محدث ريوجينكس", - "de_DE": "Ryujinx - Updater", - "el_GR": "Ryujinx Ενημερωτής", - "en_US": "Ryujinx Updater", - "es_ES": "Actualizador de Ryujinx", - "fr_FR": "Mise à jour de Ryujinx", - "he_IL": "מעדכן ריוג'ינקס", - "it_IT": "Aggiornamento di Ryujinx", - "ja_JP": "Ryujinx アップデータ", - "ko_KR": "Ryujinx 업데이터", - "no_NO": "Ryujinx Oppgradering", - "pl_PL": "Aktualizator Ryujinx", - "pt_BR": "Atualizador do Ryujinx", - "ru_RU": "Ryujinx - Обновление", - "th_TH": "ตัวอัปเดต Ryujinx", - "tr_TR": "Ryujinx Güncelleyicisi", - "uk_UA": "Програма оновлення Ryujinx", - "zh_CN": "Ryujinx 更新", - "zh_TW": "Ryujinx 更新程式" + "ar_SA": "محدث {0}", + "de_DE": "", + "el_GR": "{0} Ενημερωτής", + "en_US": "{0} Updater", + "es_ES": "Actualizador de {0}", + "fr_FR": "Mise à jour de {0}", + "he_IL": "מעדכן {0}", + "it_IT": "Aggiornamento di {0}", + "ja_JP": "{0} アップデータ", + "ko_KR": "{0} 업데이터", + "no_NO": "{0} Oppgradering", + "pl_PL": "Aktualizator {0}", + "pt_BR": "Atualizador do {0}", + "ru_RU": "{0} Обновление", + "sv_SE": "Uppdaterare för {0}", + "th_TH": "ตัวอัปเดต {0}", + "tr_TR": "{0} Güncelleyicisi", + "uk_UA": "Програма оновлення {0}", + "zh_CN": "{0} 更新", + "zh_TW": "{0} 更新程式" } }, { @@ -17796,8 +19537,9 @@ "ko_KR": "키보드 단축키", "no_NO": "Hurtigtaster for tastatur", "pl_PL": "Skróty Klawiszowe Klawiatury", - "pt_BR": "Atalhos do teclado", + "pt_BR": "Atalhos do Teclado", "ru_RU": "Горячие клавиши", + "sv_SE": "Snabbtangenter för tangentbord", "th_TH": "ปุ่มลัดของคีย์บอร์ด", "tr_TR": "Klavye Kısayolları", "uk_UA": "Гарячі клавіші клавіатури", @@ -17820,8 +19562,9 @@ "ko_KR": "키보드 단축키", "no_NO": "Hurtigtaster for tastatur", "pl_PL": "Skróty Klawiszowe Klawiatury", - "pt_BR": "Atalhos do teclado", + "pt_BR": "Atalhos do Teclado", "ru_RU": "Горячие клавиши", + "sv_SE": "Snabbtangenter för tangentbord", "th_TH": "ปุ่มลัดของคีย์บอร์ด", "tr_TR": "Klavye Kısayolları", "uk_UA": "Гарячі клавіші клавіатури", @@ -17844,8 +19587,9 @@ "ko_KR": "스크린샷 :", "no_NO": "Skjermbilde", "pl_PL": "Zrzut Ekranu:", - "pt_BR": "Captura de tela:", - "ru_RU": "Сделать скриншот:", + "pt_BR": "Captura de Tela:", + "ru_RU": "Скриншот:", + "sv_SE": "Skärmbild:", "th_TH": "ภาพหน้าจอ:", "tr_TR": "Ekran Görüntüsü Al:", "uk_UA": "Знімок екрана:", @@ -17870,6 +19614,7 @@ "pl_PL": "Pokaż UI:", "pt_BR": "Exibir UI:", "ru_RU": "Показать интерфейс:", + "sv_SE": "Visa gränssnitt:", "th_TH": "แสดง UI:", "tr_TR": "Arayüzü Göster:", "uk_UA": "Показати інтерфейс:", @@ -17894,6 +19639,7 @@ "pl_PL": "Pauza:", "pt_BR": "Pausar:", "ru_RU": "Пауза эмуляции:", + "sv_SE": "Paus:", "th_TH": "หยุดชั่วคราว:", "tr_TR": "Durdur:", "uk_UA": "Пауза:", @@ -17918,6 +19664,7 @@ "pl_PL": "Wycisz:", "pt_BR": "Mudo:", "ru_RU": "Выключить звук:", + "sv_SE": "Tyst:", "th_TH": "ปิดเสียง:", "tr_TR": "Sustur:", "uk_UA": "Вимкнути звук:", @@ -17940,8 +19687,9 @@ "ko_KR": "모션 컨트롤 설정", "no_NO": "Innstillinger for bevegelses kontroll", "pl_PL": "Ustawienia Sterowania Ruchowego", - "pt_BR": "Configurações do controle de movimento", + "pt_BR": "Configurações do Controle de Movimento", "ru_RU": "Настройки управления движением", + "sv_SE": "Inställningar för rörelsekontroller", "th_TH": "ตั้งค่าควบคุมการเคลื่อนไหว", "tr_TR": "Hareket Kontrol Seçenekleri", "uk_UA": "Налаштування керування рухом", @@ -17964,8 +19712,9 @@ "ko_KR": "진동 설정", "no_NO": "Innstillinger for Vibrasjon", "pl_PL": "Ustawienia Wibracji", - "pt_BR": "Configurações de vibração", + "pt_BR": "Configurações de Vibração", "ru_RU": "Настройки вибрации", + "sv_SE": "Inställningar för vibration", "th_TH": "ตั้งค่าการสั่นไหว", "tr_TR": "Titreşim Seçenekleri", "uk_UA": "Налаштування вібрації", @@ -17973,6 +19722,31 @@ "zh_TW": "震動設定" } }, + { + "ID": "ControllerLedTitle", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "LED Settings", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "LED 설정", + "no_NO": "LED-innstillinger", + "pl_PL": "", + "pt_BR": "Configurações de LED", + "ru_RU": "Настройки LED-подсветки", + "sv_SE": "LED-inställningar", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Налаштування LED", + "zh_CN": "LED 设置", + "zh_TW": "" + } + }, { "ID": "SettingsSelectThemeFileDialogTitle", "Translations": { @@ -17988,8 +19762,9 @@ "ko_KR": "테마 파일 선택", "no_NO": "Velg tema fil", "pl_PL": "Wybierz Plik Motywu", - "pt_BR": "Selecionar arquivo do tema", + "pt_BR": "Selecionar Arquivo de Tema", "ru_RU": "Выбрать файл темы", + "sv_SE": "Välj temafil", "th_TH": "เลือกธีมไฟล์", "tr_TR": "Tema Dosyası Seç", "uk_UA": "Виберіть файл теми", @@ -18007,13 +19782,14 @@ "es_ES": "Archivo de tema Xaml", "fr_FR": "Fichier thème Xaml", "he_IL": "קובץ ערכת נושא Xaml", - "it_IT": "File del tema xaml", + "it_IT": "File del tema XAML", "ja_JP": "Xaml テーマファイル", "ko_KR": "Xaml 테마 파일", "no_NO": "Xaml tema-fil", "pl_PL": "Plik Motywu Xaml", - "pt_BR": "Arquivo de tema Xaml", + "pt_BR": "Arquivo de Tema Xaml", "ru_RU": "Файл темы Xaml", + "sv_SE": "Xaml-temafil", "th_TH": "ไฟล์ธีมรูปแบบ XAML", "tr_TR": "Xaml Tema Dosyası", "uk_UA": "Файл теми Xaml", @@ -18036,8 +19812,9 @@ "ko_KR": "계정 관리 - 아바타", "no_NO": "Administrer kontoer - Profilbilde", "pl_PL": "Zarządzaj Kontami — Avatar", - "pt_BR": "Gerenciar contas - Avatar", + "pt_BR": "Gerenciar Contas - Avatar", "ru_RU": "Управление аккаунтами - Аватар", + "sv_SE": "Hantera konton - Avatar", "th_TH": "จัดการบัญชี - อวาต้า", "tr_TR": "Hesapları Yönet - Avatar", "uk_UA": "Керування обліковими записами - Аватар", @@ -18062,6 +19839,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -18086,6 +19864,7 @@ "pl_PL": "Nieznane", "pt_BR": "Desconhecido", "ru_RU": "Неизвестно", + "sv_SE": "Okänt", "th_TH": "ไม่รู้จัก", "tr_TR": "Bilinmeyen", "uk_UA": "Невідомо", @@ -18110,6 +19889,7 @@ "pl_PL": "Użycie", "pt_BR": "Uso", "ru_RU": "Применение", + "sv_SE": "Användning", "th_TH": "การใช้งาน", "tr_TR": "Kullanım", "uk_UA": "Використання", @@ -18134,6 +19914,7 @@ "pl_PL": "Zapisywalne", "pt_BR": "Gravável", "ru_RU": "Доступно для записи", + "sv_SE": "Skrivbar", "th_TH": "สามารถเขียนทับได้", "tr_TR": "Yazılabilir", "uk_UA": "Можливість запису", @@ -18156,8 +19937,9 @@ "ko_KR": "DLC 파일 선택", "no_NO": "Velg DLC-filer", "pl_PL": "Wybierz pliki DLC", - "pt_BR": "Selecionar arquivos de DLC", + "pt_BR": "Selecionar Arquivos de DLC", "ru_RU": "Выберите файлы DLC", + "sv_SE": "Välj DLC-filer", "th_TH": "เลือกไฟล์ DLC", "tr_TR": "DLC dosyalarını seç", "uk_UA": "Виберіть файли DLC", @@ -18182,6 +19964,7 @@ "pl_PL": "Wybierz pliki aktualizacji", "pt_BR": "Selecionar arquivos de atualização", "ru_RU": "Выберите файлы обновлений", + "sv_SE": "Välj uppdateringsfiler", "th_TH": "เลือกไฟล์อัพเดต", "tr_TR": "Güncelleme dosyalarını seç", "uk_UA": "Виберіть файли оновлення", @@ -18204,8 +19987,9 @@ "ko_KR": "모드 디렉터리 선택", "no_NO": "Velg modifikasjons mappe", "pl_PL": "Wybierz katalog modów", - "pt_BR": "", + "pt_BR": "Selecione o diretório do mod", "ru_RU": "Выбрать папку с модами", + "sv_SE": "Välj moddkatalog", "th_TH": "เลือกไดเรกทอรี Mods", "tr_TR": "Mod Dizinini Seç", "uk_UA": "Виберіть теку з модами", @@ -18223,18 +20007,19 @@ "es_ES": "Verificar y recortar archivo XCI", "fr_FR": "Vérifier et Réduire le fichier XCI", "he_IL": "", - "it_IT": "Controlla e Trimma i file XCI ", + "it_IT": "Controlla e riduci la dimensione del file XCI", "ja_JP": "", "ko_KR": "XCI 파일 확인 및 정리", "no_NO": "Kontroller og trim XCI-filen", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Verifique e Reduza o Arquivo XCI", + "ru_RU": "Проверить и обрезать XCI файл", + "sv_SE": "Kontrollera och optimera XCI-filer", "th_TH": "", "tr_TR": "", "uk_UA": "Перевірити та Обрізати XCI файл", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "检查并瘦身 XCI 文件", + "zh_TW": "檢查及修剪 XCI 檔案" } }, { @@ -18247,18 +20032,19 @@ "es_ES": "Esta función verificará el espacio vacío y después recortará el archivo XCI para ahorrar espacio en disco", "fr_FR": "Cette fonction va vérifier l'espace vide, puis réduire le fichier XCI pour économiser de l'espace de disque dur.", "he_IL": "", - "it_IT": "Questa funzionalita controllerà prima lo spazio libero e poi trimmerà il file XCI per liberare dello spazio.", + "it_IT": "Questa funzionalità controllerà prima lo spazio libero e poi ridurrà la dimensione del file XCI per risparmiare spazio su disco.", "ja_JP": "", "ko_KR": "이 기능은 먼저 충분한 공간을 확보한 다음 XCI 파일을 트리밍하여 디스크 공간을 절약합니다.", "no_NO": "Denne funksjonen kontrollerer først hvor mye plass som er ledig, og trimmer deretter XCI-filen for å spare diskplass.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Esta função primeiro verificará o espaço vazio e depois reduzirá o arquivo XCI para economizar espaço em disco.", + "ru_RU": "Эта функция сначала проверит наличие пустого пространства, а затем обрежет файл XCI, чтобы сэкономить место на диске.", + "sv_SE": "Denna funktion kommer först att kontrollera ledigt utrymme och sedan optimera XCI-filen för att spara diskutrymme.", "th_TH": "", "tr_TR": "", - "uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Ця функція спочатку перевірить наявність порожнього місця, після чого обріже файл XCI для економії місця на диску.", + "zh_CN": "这个功能将会先检查 XCI 文件,再对其执行瘦身操作以节约磁盘空间。", + "zh_TW": "此功能首先檢查 XCI 檔案是否有可修剪的字元,然後修剪檔案以節省儲存空間。" } }, { @@ -18271,18 +20057,19 @@ "es_ES": "Tamaño de archivo actual: {0:n} MB\nTamaño de datos de juego: {1:n} MB\nAhorro de espacio en disco: {2:n} MB", "fr_FR": "Taille actuelle du fichier: {0:n} MB\nTaille des données de jeux: {1:n} MB\nÉconomie d'espaces sur le disque: {2:n} MB", "he_IL": "", - "it_IT": "Dimensioni Attuali File: {0:n} MB\nDimensioni Dati Gioco: {1:n} MB\nRisparimio Spazio Disco: {2:n} MB", + "it_IT": "Dimensione attuale del file: {0:n} MB\nDimensione dei dati del gioco: {1:n} MB\nRisparmio spazio su disco: {2:n} MB", "ja_JP": "", "ko_KR": "현재 파일 크기 : {0:n}MB\n게임 데이터 크기 : {1:n}MB\n디스크 공간 절약 : {2:n}MB", "no_NO": "Nåværende filstørrelse: 0:n MB\nSpilldatastørrelse: {1:n} MB\nDiskplassbesparelse: {2:n} MB", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Tamanho atual do arquivo: {0:n} MB\nTamanho dos dados do jogo: {1:n} MB\nEconomia de espaço em disco: {2:n} MB", + "ru_RU": "Размер текущего файла: {0:n} Мб\nРазмер игровых данных: {1:n} MB\nЭкономия дискового пространства: {2:n} Мб", + "sv_SE": "Aktuell filstorlek: {0:n} MB\nStorlek för speldata: {1:n} MB\nSparat diskutrymme: {2:n} MB", "th_TH": "", "tr_TR": "", "uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "当前文件大小: {0:n} MB\n游戏数据大小: {1:n} MB\n节约的磁盘空间: {2:n} MB", + "zh_TW": "現在的檔案大小: {0:n} MB\n遊戲資料大小: {1:n} MB\n節省的儲存空間: {2:n} MB" } }, { @@ -18295,18 +20082,19 @@ "es_ES": "El archivo XCI no necesita ser recortado. Verifica los logs para más detalles.", "fr_FR": "Fichier XCI n'a pas besoin d'être réduit. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI non deve essere trimmato. Controlla i log per ulteriori dettagli", + "it_IT": "Non è necessario ridurre la dimensione del file XCI. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 트리밍할 필요가 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen trenger ikke å trimmes. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI não precisa ser reduzido. Verifique os logs para mais detalhes", + "ru_RU": "Файл XCI не нуждается в обрезке. Проверьте логи для получения более подробной информации", + "sv_SE": "XCI-filen behöver inte optimeras. Kontrollera loggen för mer information", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "XCI файл не потребує обрізання. Перевірте журнали (logs) для отримання додаткової інформації", + "zh_CN": "XCI 文件不需要被瘦身。查看日志以获得更多细节。", + "zh_TW": "XCI 檔案不需要修剪。檢查日誌以取得更多資訊" } }, { @@ -18319,18 +20107,19 @@ "es_ES": "El recorte del archivo XCI no puede ser deshecho. Verifica los registros para más detalles.", "fr_FR": "Fichier XCI ne peut pas être dé-réduit. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI non può essere untrimmato. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI non può essere riportato alla sua dimensione originale. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 트리밍을 해제할 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen kan ikke trimmes. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI reduzido não pode ser desfeito. Verifique os logs para mais detalhes", + "ru_RU": "XCI файл не может быть обрезан. Проверьте логи для получения более подробной информации", + "sv_SE": "XCI-filen kan inte avoptimeras. Kontrollera loggen för mer information", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали (logs) для отримання додаткової інформації", + "zh_CN": "XCI 文件不能被瘦身。查看日志以获得更多细节。", + "zh_TW": "XCI 檔案不能被修剪。檢查日誌以取得更多資訊" } }, { @@ -18343,18 +20132,19 @@ "es_ES": "El archivo XCI es de solo Lectura y no se le puede escribir. Lee el registro para más información.", "fr_FR": "Fichier XCI est en Lecture Seule et n'a pas pu être rendu accessible en écriture. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI è in sola lettura e non può essere reso Scrivibile. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI è in sola lettura e non può essere reso accessibile in scrittura. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일은 읽기 전용이므로 쓰기 가능하게 만들 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen er skrivebeskyttet og kunne ikke gjøres skrivbar. Sjekk loggene for mer informasjon", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI é somente leitura e não pôde ser tornado gravável. Verifique os logs para mais detalhes", + "ru_RU": "Файл XCI доступен только для чтения и его невозможно сделать доступным для записи. Проверьте логи для получения более подробной информации", + "sv_SE": "XCI-filen är skrivskyddad och kunde inte göras skrivbar. Kontrollera loggen för mer information", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали (logs) для отримання додаткової інформації", + "zh_CN": "XCI 文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。", + "zh_TW": "XCI 檔案是唯讀,並且無法改成可寫入。檢查日誌以取得更多資訊" } }, { @@ -18367,18 +20157,19 @@ "es_ES": "El archivo XCI ha cambiado de tamaño desde que fue escaneado. Verifica que no se esté escribiendo al archivo y vuelve a intentarlo.", "fr_FR": "Fichier XCI a changé en taille depuis qu'il a été scanné. Vérifier que le fichier n'est pas en cours d'écriture et réessayer.", "he_IL": "", - "it_IT": "Il file XCI ha cambiato dimensioni da quando è stato scansionato. Controlla che il file non stia venendo scritto da qualche altro programma e poi riprova.", + "it_IT": "La dimensione del file XCI è cambiata da quando è stato scansionato. Controlla che il file non stia venendo scritto da qualche altro programma e poi riprova.", "ja_JP": "", "ko_KR": "XCI 파일이 스캔된 후 크기가 변경되었습니다. 파일이 쓰여지고 있지 않은지 확인하고 다시 시도하세요.", "no_NO": "XCI File har endret størrelse siden den ble skannet. Kontroller at det ikke skrives til filen, og prøv på nytt.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI mudou de tamanho desde que foi escaneado. Verifique se o arquivo não está sendo gravado e tente novamente.", + "ru_RU": "Файл XCI изменился в размере после сканирования. Проверьте, не производится ли запись в этот файл, и повторите попытку.", + "sv_SE": "XCI-filen har ändrats i storlek sedan den lästes av. Kontrollera att filen inte skrivs till och försök igen.", "th_TH": "", "tr_TR": "", "uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "XCI 文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。", + "zh_TW": "XCI 檔案大小比較上次的掃瞄已經改變。請檢查檔案是否未被寫入,然後再嘗試。" } }, { @@ -18391,18 +20182,19 @@ "es_ES": "El archivo XCI tiene datos en el área de espacio libre, no es seguro recortar.", "fr_FR": "Fichier XCI a des données dans la zone d'espace libre, ce n'est pas sûr de réduire", "he_IL": "", - "it_IT": "Il file XCI ha dati nello spazio libero, non è sicuro effettuare il trimming", + "it_IT": "Il file XCI contiene dei dati nello spazio libero, non è sicuro ridurne la dimensione", "ja_JP": "", "ko_KR": "XCI 파일에 여유 공간 영역에 데이터가 있으므로 트리밍하는 것이 안전하지 않음", "no_NO": "XCI-filen har data i ledig plass, og det er ikke trygt å trimme den", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI tem dados na área de espaço livre, não é seguro reduzi-lo", + "ru_RU": "XCI файл содержит данные в пустой зоне, обрезать его небезопасно", + "sv_SE": "XCI-filen har data i det lediga utrymmet. Den är inte säker att optimera", "th_TH": "", "tr_TR": "", "uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "XCI 文件的空闲区域内有数据,不能安全瘦身。", + "zh_TW": "XCI 檔案有數據儲存於可節省儲存空間的區域,所以試圖修剪並不安全" } }, { @@ -18415,18 +20207,19 @@ "es_ES": "El archivo XCI contiene datos inválidos. Lee el registro para más información.", "fr_FR": "Fichier XCI contient des données invalides. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI contiene dati invlidi. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI contiene dei dati non validi. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일에 유효하지 않은 데이터가 포함되어 있습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen inneholder ugyldige data. Sjekk loggene for ytterligere detaljer", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI contém dados inválidos. Verifique os logs para obter mais detalhes", + "ru_RU": "Файл XCI содержит недопустимые данные. Проверьте логи для получения дополнительной информации", + "sv_SE": "XCI-filen innehåller ogiltig data. Kontrollera loggen för mer information", "th_TH": "", "tr_TR": "", - "uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали (logs) для отримання додаткової інформації", + "zh_CN": "XCI 文件含有无效数据。查看日志以获得更多细节。", + "zh_TW": "XCI 檔案帶有無效的數據。檢查日誌以取得更多資訊" } }, { @@ -18439,18 +20232,19 @@ "es_ES": "El archivo XCI no se puede abrir para escribirlo. Lee el registro para más información.", "fr_FR": "Fichier XCI n'a pas pu été ouvert pour écriture. Regarder les journaux pour plus de détails", "he_IL": "", - "it_IT": "Il file XCI non può essere aperto per essere scritto. Controlla i log per ulteriori dettagli", + "it_IT": "Il file XCI non può essere aperto in scrittura. Controlla i log per ulteriori dettagli", "ja_JP": "", "ko_KR": "XCI 파일을 쓰기 위해 열 수 없습니다. 자세한 내용은 로그를 확인", "no_NO": "XCI-filen kunne ikke åpnes for skriving. Sjekk loggene for ytterligere detaljer", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O arquivo XCI não pôde ser aberto para gravação. Verifique os logs para mais detalhes", + "ru_RU": "XCI файл не удалось открыть для записи. Проверьте логи для получения дополнительной информации", + "sv_SE": "XCI-filen kunde inte öppnas för skrivning. Kontrollera loggen för mer information", "th_TH": "", "tr_TR": "", "uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "XCI 文件不能被读写。查看日志以获得更多细节。", + "zh_TW": "XCI 檔案不能被寫入。檢查日誌以取得更多資訊" } }, { @@ -18463,18 +20257,19 @@ "es_ES": "El recorte del archivo XCI falló", "fr_FR": "Réduction du fichier XCI a échoué", "he_IL": "", - "it_IT": "Trimming del file XCI fallito", + "it_IT": "Riduzione della dimensione del file XCI fallita", "ja_JP": "", "ko_KR": "XCI 파일 트리밍에 실패", "no_NO": "Trimming av XCI-filen mislyktes", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "A redução do arquivo XCI falhou", + "ru_RU": "Обрезка файла XCI не удалась", + "sv_SE": "Optimering av XCI-filen misslyckades", "th_TH": "", "tr_TR": "", "uk_UA": "Не вдалося обрізати файл XCI", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "XCI 文件瘦身失败", + "zh_TW": "修剪 XCI 檔案失敗" } }, { @@ -18487,18 +20282,19 @@ "es_ES": "La operación fue cancelada", "fr_FR": "L'opération a été annulée", "he_IL": "", - "it_IT": "Operazione Cancellata", + "it_IT": "L'operazione è stata annullata", "ja_JP": "", "ko_KR": "작업이 취소됨", "no_NO": "Operasjonen ble avlyst", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "A operação foi cancelada", + "ru_RU": "Операция была отменена", + "sv_SE": "Åtgärden avbröts", "th_TH": "", "tr_TR": "", "uk_UA": "Операція перервана", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "操作已取消", + "zh_TW": "修剪已取消" } }, { @@ -18511,18 +20307,19 @@ "es_ES": "No se realizó ninguna operación", "fr_FR": "Aucune opération a été faite", "he_IL": "", - "it_IT": "Nessuna operazione è stata effettuata", + "it_IT": "Non è stata effettuata alcuna operazione", "ja_JP": "", "ko_KR": "작업이 수행되지 않음", "no_NO": "Ingen operasjon ble utført", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Nenhuma operação foi realizada", + "ru_RU": "Операция не была проведена", + "sv_SE": "Ingen åtgärd genomfördes", "th_TH": "", "tr_TR": "", "uk_UA": "Операція не проводилася", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "未执行操作", + "zh_TW": "沒有修剪" } }, { @@ -18540,8 +20337,9 @@ "ko_KR": "사용자 프로필 관리자", "no_NO": "Bruker Profiler Behandler", "pl_PL": "Menedżer Profili Użytkowników", - "pt_BR": "Gerenciador de perfis de usuário", - "ru_RU": "Менеджер учетных записей", + "pt_BR": "Gerenciador de Perfis de Usuário", + "ru_RU": "Менеджер учётных записей", + "sv_SE": "Hanterare för användarprofiler", "th_TH": "จัดการโปรไฟล์ผู้ใช้", "tr_TR": "Kullanıcı Profillerini Yönet", "uk_UA": "Менеджер профілів користувачів", @@ -18564,8 +20362,9 @@ "ko_KR": "치트 관리자", "no_NO": "Juksing behandler", "pl_PL": "Menedżer Kodów", - "pt_BR": "Gerenciador de Cheats", + "pt_BR": "Gerenciador de Trapaças", "ru_RU": "Менеджер читов", + "sv_SE": "Fuskhanterare", "th_TH": "จัดการสูตรโกง", "tr_TR": "Oyun Hilelerini Yönet", "uk_UA": "Менеджер читів", @@ -18588,8 +20387,9 @@ "ko_KR": "{0} ({1})의 내려받기 가능한 콘텐츠 관리", "no_NO": "Behandle nedlastbart innhold for {0} ({1})", "pl_PL": "Menedżer Zawartości do Pobrania", - "pt_BR": "Gerenciador de DLC", + "pt_BR": "Gerenciar conteúdo para download para {0} ({1})", "ru_RU": "Управление DLC для {0} ({1})", + "sv_SE": "Hantera hämtningsbart innehåll för {0} ({1})", "th_TH": "จัดการ DLC ที่ดาวน์โหลดได้สำหรับ {0} ({1})", "tr_TR": "Oyun DLC'lerini Yönet", "uk_UA": "Менеджер вмісту для завантаження", @@ -18614,6 +20414,7 @@ "pl_PL": "Zarządzaj modami dla {0} ({1})", "pt_BR": "Gerenciar Mods para {0} ({1})", "ru_RU": "Управление модами для {0} ({1})", + "sv_SE": "Hantera moddar för {0} ({1})", "th_TH": "จัดการม็อดที่ดาวน์โหลดได้สำหรับ {0} ({1})", "tr_TR": "", "uk_UA": "Керувати модами для {0} ({1})", @@ -18636,8 +20437,9 @@ "ko_KR": "타이틀 업데이트 관리자", "no_NO": "Tittel oppdatering behandler", "pl_PL": "Menedżer Aktualizacji Tytułu", - "pt_BR": "Gerenciador de atualizações", + "pt_BR": "Gerenciador de Atualização de Título", "ru_RU": "Менеджер обновлений игр", + "sv_SE": "Hanterare för speluppdateringar", "th_TH": "จัดการอัปเดตหัวข้อ", "tr_TR": "Oyun Güncellemelerini Yönet", "uk_UA": "Менеджер оновлення назв", @@ -18655,18 +20457,19 @@ "es_ES": "Recortador de archivos XCI", "fr_FR": "Rogneur de fichier XCI", "he_IL": "", - "it_IT": "", + "it_IT": "Riduci dimensioni dei file XCI", "ja_JP": "", "ko_KR": "XCI 파일 트리머", - "no_NO": "XCI File Trimmer", + "no_NO": "", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Redutor de Arquivo XCI", + "ru_RU": "Уменьшение размера XCI файлов", + "sv_SE": "Optimera XCI-filer", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка XCI Файлів", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "XCI 文件瘦身器", + "zh_TW": "XCI 檔案修剪器" } }, { @@ -18679,18 +20482,19 @@ "es_ES": "{0} de {1} Título(s) seleccionado(s)", "fr_FR": "{0} sur {1} Fichier(s) Sélectionnés", "he_IL": "", - "it_IT": "{0} di {1} Titolo(i) Selezionati", + "it_IT": "{0} di {1} titoli selezionati", "ja_JP": "", "ko_KR": "{1}개 타이틀 중 {0}개 선택됨", "no_NO": "{0} av {1} Valgte tittel(er)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "{0} de {1} Título(s) Selecionado(s)", + "ru_RU": "{0} из {1} файла(ов) выбрано", + "sv_SE": "{0} av {1} spel markerade", "th_TH": "", "tr_TR": "", "uk_UA": "{0} з {1} тайтл(ів) обрано", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "在 {1} 中选中了 {0} 个游戏 ", + "zh_TW": "已選擇 {1} 之 {0} 的遊戲" } }, { @@ -18703,18 +20507,19 @@ "es_ES": "{0} de {1} Título(s) seleccionado(s) ({2} mostrado(s))", "fr_FR": "{0} sur {1} Fichier(s) Sélectionnés ({2} affiché(s)", "he_IL": "", - "it_IT": "{0} of {1} Titolo(i) Selezionati ({2} visualizzato)", + "it_IT": "{0} di {1} titoli selezionati ({2} visualizzati)", "ja_JP": "", "ko_KR": "{1}개 타이틀 중 {0}개 선택됨({2}개 표시됨)", "no_NO": "{0} av {1} Tittel(er) valgt ({2} vises)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "{0} de {1} Título(s) Selecionado(s) ({2} exibidos)", + "ru_RU": "{0} из {1} файла(ов) выбрано ({2} показано)", + "sv_SE": "{0} av {1} spel markerade ({2} visade)", "th_TH": "", "tr_TR": "", "uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "在 {1} 中选中了 {0} 个游戏 (显示了 {2} 个)", + "zh_TW": "已選擇 {1} 之 {0} 的遊戲 (已顯示 {2} 個)" } }, { @@ -18727,18 +20532,19 @@ "es_ES": "Recortando {0} Título(s)...", "fr_FR": "Réduction de {0} Fichier(s)...", "he_IL": "", - "it_IT": "Trimming {0} Titolo(i)...", + "it_IT": "Riduzione delle dimensioni di {0} titolo/i...", "ja_JP": "", "ko_KR": "{0}개의 타이틀을 트리밍 중...", "no_NO": "Trimming av {0} tittel(er)...", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzindo {0} Título(s)...", + "ru_RU": "Обрезка {0} файла(ов)...", + "sv_SE": "Optimerar {0} spel...", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка {0} тайтл(ів)...", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "{0} 个游戏瘦身中。。。", + "zh_TW": "正在修剪 {0} 個遊戲..." } }, { @@ -18751,18 +20557,19 @@ "es_ES": "Deshaciendo recorte de {0} Título(s)...", "fr_FR": "Dé-Réduction de {0} Fichier(s)...", "he_IL": "", - "it_IT": "Untrimming {0} Titolo(i)...", + "it_IT": "Ripristino alle dimensioni originali di {0} titolo/i...", "ja_JP": "", "ko_KR": "{0}개의 타이틀을 트리밍 해제 중...", "no_NO": "Untrimming {0} Tittel(er)...", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Desfazendo redução {0} Título(s)...", + "ru_RU": "Отмена обрезки {0} файла(ов)...", + "sv_SE": "Avoptimerar {0} spel...", "th_TH": "", "tr_TR": "", "uk_UA": "Необрізаних {0} тайтл(ів)...", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "正在精简 {0} 个游戏", + "zh_TW": "正在反修剪 {0} 個遊戲..." } }, { @@ -18780,13 +20587,14 @@ "ko_KR": "실패", "no_NO": "Mislyktes", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Falhou", + "ru_RU": "Ошибка", + "sv_SE": "Misslyckades", "th_TH": "", "tr_TR": "", "uk_UA": "Невдача", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "失败", + "zh_TW": "失敗" } }, { @@ -18799,18 +20607,19 @@ "es_ES": "Ahorro potencial", "fr_FR": "Économies potentielles d'espace de disque dur", "he_IL": "", - "it_IT": "Potenziali Salvataggi", + "it_IT": "Risparmio potenziale", "ja_JP": "", "ko_KR": "잠재적 비용 절감", "no_NO": "Potensielle besparelser", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Economia Potencial", + "ru_RU": "Потенциально освобождено места", + "sv_SE": "Möjlig besparning", "th_TH": "", "tr_TR": "", "uk_UA": "Потенційна економія", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "潜在的储存空间节省", + "zh_TW": "潛在節省的儲存空間" } }, { @@ -18823,18 +20632,19 @@ "es_ES": "Ahorro real", "fr_FR": "Économies actualles d'espace de disque dur", "he_IL": "", - "it_IT": "Effettivi Salvataggi", + "it_IT": "Risparmio effettivo", "ja_JP": "", "ko_KR": "실제 비용 절감", "no_NO": "Faktiske besparelser", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Economia Real", + "ru_RU": "Реально освобождено места", + "sv_SE": "Faktisk besparning", "th_TH": "", "tr_TR": "", "uk_UA": "Зекономлено", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "实际的储存空间节省", + "zh_TW": "實際節省的儲存空間" } }, { @@ -18847,13 +20657,14 @@ "es_ES": "", "fr_FR": "{0:n0} Mo", "he_IL": "", - "it_IT": "", + "it_IT": "{0:n0} MB", "ja_JP": "", "ko_KR": "{0:n0}MB", "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "", + "ru_RU": "{0:n0} Мб", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "{0:n0} Мб", @@ -18871,18 +20682,19 @@ "es_ES": "Seleccionar mostrado(s)", "fr_FR": "Sélectionner Affiché", "he_IL": "", - "it_IT": "Seleziona Visualizzati", + "it_IT": "Seleziona visualizzati", "ja_JP": "", "ko_KR": "표시됨 선택", "no_NO": "Velg vist", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Marcar Todos", + "ru_RU": "Выбрать то что показано", + "sv_SE": "Markera visade", "th_TH": "", "tr_TR": "", - "uk_UA": "Вибрати показане", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Вибрати показані", + "zh_CN": "选定显示的", + "zh_TW": "選擇已顯示" } }, { @@ -18895,18 +20707,19 @@ "es_ES": "Deseleccionar mostrado(s)", "fr_FR": "Désélectionner Affiché", "he_IL": "", - "it_IT": "Deselziona Visualizzati", + "it_IT": "Deseleziona visualizzati", "ja_JP": "", "ko_KR": "표시됨 선택 취소", "no_NO": "Opphev valg av Vist", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Desmarcar Todos", + "ru_RU": "Отменить выбор показанного", + "sv_SE": "Avmarkera visade", "th_TH": "", "tr_TR": "", "uk_UA": "Скасувати вибір показаного", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "反选显示的", + "zh_TW": "取消選擇已顯示" } }, { @@ -18924,13 +20737,14 @@ "ko_KR": "타이틀", "no_NO": "Tittel", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Título", + "ru_RU": "Приложение", + "sv_SE": "Titel", "th_TH": "", "tr_TR": "", - "uk_UA": "Заголовок", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Назва", + "zh_CN": "标题", + "zh_TW": "名稱" } }, { @@ -18943,18 +20757,19 @@ "es_ES": "Ahorro de espacio", "fr_FR": "Économies de disque dur", "he_IL": "", - "it_IT": "Salvataggio Spazio", + "it_IT": "Spazio risparmiato", "ja_JP": "", "ko_KR": "공간 절약s", "no_NO": "Plassbesparelser", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Economia de Espaço", + "ru_RU": "Сохранение места на диске", + "sv_SE": "Utrymmesbesparning", "th_TH": "", "tr_TR": "", "uk_UA": "Економія місця", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "节省空间", + "zh_TW": "節省的儲存空間" } }, { @@ -18967,18 +20782,19 @@ "es_ES": "Recortar", "fr_FR": "Réduire", "he_IL": "", - "it_IT": "", + "it_IT": "Riduci dimensioni", "ja_JP": "", "ko_KR": "트림", "no_NO": "", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzir XCI", + "ru_RU": "Обрезать", + "sv_SE": "Optimera", "th_TH": "", "tr_TR": "", "uk_UA": "Обрізка", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "瘦身", + "zh_TW": "修剪" } }, { @@ -18991,18 +20807,19 @@ "es_ES": "Deshacer recorte", "fr_FR": "Dé-Réduire", "he_IL": "", - "it_IT": "", + "it_IT": "Riporta alle dimensioni originali", "ja_JP": "", "ko_KR": "언트림", "no_NO": "Utrim", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Desfazer Redução", + "ru_RU": "Отмена обрезки", + "sv_SE": "Avoptimera", "th_TH": "", "tr_TR": "", "uk_UA": "Зшивання", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "取消精简", + "zh_TW": "反修剪" } }, { @@ -19015,16 +20832,17 @@ "es_ES": "{0} nueva(s) actualización(es) agregada(s)", "fr_FR": "{0} nouvelle(s) mise(s) à jour ajoutée(s)", "he_IL": "", - "it_IT": "{0} aggiornamento/i aggiunto/i", + "it_IT": "{0} nuovo/i aggiornamento/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새 업데이트가 추가됨", "no_NO": "{0} ny(e) oppdatering(er) lagt til", "pl_PL": "", "pt_BR": "{0} nova(s) atualização(ões) adicionada(s)", - "ru_RU": "", + "ru_RU": "Добавлено {0} новых обновлений", + "sv_SE": "{0} nya uppdatering(ar) lades till", "th_TH": "{0} อัพเดตที่เพิ่มมาใหม่", "tr_TR": "", - "uk_UA": "{0} нове оновлення додано", + "uk_UA": "{0} нових оновлень додано", "zh_CN": "{0} 个更新被添加", "zh_TW": "已加入 {0} 個遊戲更新" } @@ -19039,13 +20857,14 @@ "es_ES": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.", "fr_FR": "Les mises à jour incluses avec le jeu ne peuvent pas être supprimées mais peuvent être désactivées.", "he_IL": "", - "it_IT": "Gli aggiornamenti inclusi non possono essere eliminati, ma solo disattivati", + "it_IT": "Gli aggiornamenti inclusi non possono essere rimossi, ma solo disabilitati.", "ja_JP": "", "ko_KR": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.", "no_NO": "Medfølgende oppdateringer kan ikke fjernes, bare deaktiveres.", "pl_PL": "", "pt_BR": "Atualizações incorporadas não podem ser removidas, apenas desativadas.", - "ru_RU": "", + "ru_RU": "Обновления бандлов не могут быть удалены, только отключены.", + "sv_SE": "Bundlade uppdateringar kan inte tas bort, endast inaktiveras.", "th_TH": "แพ็คที่อัพเดตมาไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น", "tr_TR": "", "uk_UA": "Вбудовані оновлення не можуть бути видалені, лише вимкнені.", @@ -19068,11 +20887,12 @@ "ko_KR": "{0} [{1}]에 사용 가능한 치트", "no_NO": "Juks tilgjengelig for {0} [{1}]", "pl_PL": "Kody Dostępne dla {0} [{1}]", - "pt_BR": "Cheats disponíveis para {0} [{1}]", + "pt_BR": "Trapaças disponíveis para {0} [{1}]", "ru_RU": "Доступные читы для {0} [{1}]", + "sv_SE": "Fusk tillgängliga för {0} [{1}]", "th_TH": "สูตรโกงมีให้สำหรับ {0} [{1}]", "tr_TR": "{0} için Hile mevcut [{1}]", - "uk_UA": "Коди доступні для {0} [{1}]", + "uk_UA": "Чит-коди доступні для {0} [{1}]", "zh_CN": "适用于 {0} [{1}] 的金手指", "zh_TW": "可用於 {0} [{1}] 的密技" } @@ -19094,6 +20914,7 @@ "pl_PL": "Identyfikator wersji:", "pt_BR": "ID da Build:", "ru_RU": "ID версии:", + "sv_SE": "Bygg-id:", "th_TH": "รหัสการสร้าง:", "tr_TR": "", "uk_UA": "ID збірки:", @@ -19111,17 +20932,18 @@ "es_ES": "", "fr_FR": "Les DLC inclus avec le jeu ne peuvent pas être supprimés mais peuvent être désactivés.", "he_IL": "", - "it_IT": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.", + "it_IT": "I DLC inclusi non possono essere rimossi, ma solo disabilitati.", "ja_JP": "", "ko_KR": "번들 DLC는 제거할 수 없으며 비활성화만 가능합니다.", "no_NO": "Medfølgende DLC kan ikke fjernes, bare deaktiveres.", "pl_PL": "", "pt_BR": "DLCs incorporadas não podem ser removidas, apenas desativadas.", - "ru_RU": "", + "ru_RU": "DLC бандлов не могут быть удалены, только отключены.", + "sv_SE": "Bundlade DLC kan inte tas bort, endast inaktiveras.", "th_TH": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น", "tr_TR": "", - "uk_UA": "Вбудований DLC не може бути видаленим, лише вимкненим.", - "zh_CN": "游戏整合的DLC无法移除,可尝试禁用。", + "uk_UA": "Комплектні DLC (бандли) не можуть бути видаленими, лише вимкненими.", + "zh_CN": "游戏整合的 DLC 无法移除,可尝试禁用。", "zh_TW": "附帶的 DLC 只能被停用而無法被刪除。" } }, @@ -19135,18 +20957,19 @@ "es_ES": "", "fr_FR": "{0} DLC(s) disponibles", "he_IL": "{0} הרחבות משחק", - "it_IT": "", + "it_IT": "{0} DLC disponibile/i", "ja_JP": "", "ko_KR": "{0} DLC 사용 가능", "no_NO": "{0} Nedlastbare innhold(er)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "{0} DLC(s) disponíveis", + "ru_RU": "{0} доступных DLC", + "sv_SE": "{0} DLC(er) tillgängliga", "th_TH": "", "tr_TR": "", "uk_UA": "{0} DLC доступно", "zh_CN": "{0} 个 DLC", - "zh_TW": "" + "zh_TW": "{0} 個可下載內容" } }, { @@ -19159,17 +20982,18 @@ "es_ES": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "he_IL": "", - "it_IT": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i", + "it_IT": "{0} nuovo/i DLC aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "no_NO": "{0} nytt nedlastbart innhold lagt til", "pl_PL": "", "pt_BR": "{0} novo(s) conteúdo(s) para download adicionado(s)", - "ru_RU": "", + "ru_RU": "Добавлено {0} новых DLC", + "sv_SE": "{0} nya hämtningsbara innehåll lades till", "th_TH": "{0} DLC ใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нового завантажувального вмісту додано", - "zh_CN": "{0} 个DLC被添加", + "zh_CN": "{0} 个 DLC 被添加", "zh_TW": "已加入 {0} 個 DLC" } }, @@ -19183,17 +21007,18 @@ "es_ES": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "he_IL": "", - "it_IT": "{0} contenuto/i scaricabile/i aggiunto/i", + "it_IT": "{0} nuovo/i DLC aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "no_NO": "{0} nytt nedlastbart innhold lagt til", "pl_PL": "", "pt_BR": "{0} novo(s) conteúdo(s) para download adicionado(s)", - "ru_RU": "", + "ru_RU": "Добавлено {0} новых DLC", + "sv_SE": "{0} nya hämtningsbara innehåll lades till", "th_TH": "{0} ใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нового завантажувального вмісту додано", - "zh_CN": "{0} 个DLC被添加", + "zh_CN": "{0} 个 DLC 被添加", "zh_TW": "已加入 {0} 個 DLC" } }, @@ -19207,17 +21032,18 @@ "es_ES": "Se eliminaron {0} contenido(s) descargable(s) faltantes", "fr_FR": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)", "he_IL": "", - "it_IT": "{0} contenuto/i scaricabile/i mancante/i rimosso/i", + "it_IT": "{0} DLC mancante/i rimosso/i", "ja_JP": "", "ko_KR": "{0}개의 내려받기 가능한 콘텐츠가 제거됨", "no_NO": "{0} manglende nedlastbart innhold fjernet", "pl_PL": "", "pt_BR": "{0} conteúdo(s) para download ausente(s) removido(s)", - "ru_RU": "", + "ru_RU": "{0} отсутствующих DLC удалено", + "sv_SE": "{0} saknade hämtningsbara innehåll togs bort", "th_TH": "", "tr_TR": "", "uk_UA": "{0} відсутнього завантажувального вмісту видалено", - "zh_CN": "{0} 个失效的DLC已移除", + "zh_CN": "{0} 个失效的 DLC 已移除", "zh_TW": "已刪除 {0} 個遺失的 DLC" } }, @@ -19231,13 +21057,14 @@ "es_ES": "Se agregaron {0} nueva(s) actualización(es)", "fr_FR": "{0} nouvelle(s) mise(s) à jour ajoutée(s)", "he_IL": "", - "it_IT": "{0} aggiornamento/i aggiunto/i", + "it_IT": "{0} nuovo/i aggiornamento/i aggiunto/i", "ja_JP": "", "ko_KR": "{0}개의 새 업데이트가 추가됨", "no_NO": "{0} ny(e) oppdatering(er) lagt til", "pl_PL": "", "pt_BR": "{0} nova(s) atualização(ões) adicionada(s)", - "ru_RU": "", + "ru_RU": "{0} новых обновлений добавлено", + "sv_SE": "{0} nya uppdatering(ar) lades till", "th_TH": "{0} อัพเดตใหม่ที่เพิ่มเข้ามา", "tr_TR": "", "uk_UA": "{0} нових оновлень додано", @@ -19261,7 +21088,8 @@ "no_NO": "{0} manglende oppdatering(er) fjernet", "pl_PL": "", "pt_BR": "{0} atualização(ões) ausente(s) removida(s)", - "ru_RU": "", + "ru_RU": "{0} отсутствующих обновлений удалено", + "sv_SE": "{0} saknade uppdatering(ar) togs bort", "th_TH": "", "tr_TR": "", "uk_UA": "{0} відсутніх оновлень видалено", @@ -19286,6 +21114,7 @@ "pl_PL": "{0} Mod(y/ów)", "pt_BR": "", "ru_RU": "Моды для {0} ", + "sv_SE": "{0} modd(ar)", "th_TH": "{0} ม็อด", "tr_TR": "{0} Mod(lar)", "uk_UA": "{0} мод(ів)", @@ -19310,6 +21139,7 @@ "pl_PL": "Edytuj Zaznaczone", "pt_BR": "Editar selecionado", "ru_RU": "Изменить выбранные", + "sv_SE": "Redigera markerade", "th_TH": "แก้ไขที่เลือกแล้ว", "tr_TR": "Seçiliyi Düzenle", "uk_UA": "Редагувати вибране", @@ -19332,13 +21162,14 @@ "ko_KR": "계속", "no_NO": "Fortsett", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Continuar", + "ru_RU": "Продолжить", + "sv_SE": "Fortsätt", "th_TH": "", "tr_TR": "", "uk_UA": "Продовжити", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "继续", + "zh_TW": "繼續" } }, { @@ -19358,6 +21189,7 @@ "pl_PL": "Anuluj", "pt_BR": "Cancelar", "ru_RU": "Отмена", + "sv_SE": "Avbryt", "th_TH": "ยกเลิก", "tr_TR": "İptal", "uk_UA": "Скасувати", @@ -19382,6 +21214,7 @@ "pl_PL": "Zapisz", "pt_BR": "Salvar", "ru_RU": "Сохранить", + "sv_SE": "Spara", "th_TH": "บันทึก", "tr_TR": "Kaydet", "uk_UA": "Зберегти", @@ -19406,6 +21239,7 @@ "pl_PL": "Odrzuć", "pt_BR": "Descartar", "ru_RU": "Отменить", + "sv_SE": "Förkasta", "th_TH": "ละทิ้ง", "tr_TR": "Iskarta", "uk_UA": "Скасувати", @@ -19428,8 +21262,9 @@ "ko_KR": "일시 중지됨", "no_NO": "Satt på pause", "pl_PL": "Wstrzymano", - "pt_BR": "", + "pt_BR": "Pausado", "ru_RU": "Приостановлено", + "sv_SE": "Pausad", "th_TH": "หยุดชั่วคราว", "tr_TR": "Durduruldu", "uk_UA": "Призупинено", @@ -19452,8 +21287,9 @@ "ko_KR": "프로필 이미지 설정", "no_NO": "Angi profilbilde", "pl_PL": "Ustaw Obraz Profilu", - "pt_BR": "Definir imagem de perfil", + "pt_BR": "Definir Imagem de Perfil", "ru_RU": "Установить аватар", + "sv_SE": "Välj profilbild", "th_TH": "ตั้งค่ารูปโปรไฟล์", "tr_TR": "Profil Resmi Ayarla", "uk_UA": "Встановити зображення профілю", @@ -19476,8 +21312,9 @@ "ko_KR": "이름 필수 입력", "no_NO": "Navn er påkrevd", "pl_PL": "Nazwa jest wymagana", - "pt_BR": "É necessário um nome", + "pt_BR": "Nome é obrigatório", "ru_RU": "Необходимо ввести никнейм", + "sv_SE": "Namn krävs", "th_TH": "จำเป็นต้องระบุชื่อ", "tr_TR": "İsim gerekli", "uk_UA": "Імʼя обовʼязкове", @@ -19500,8 +21337,9 @@ "ko_KR": "프로필 이미지를 설정해야 함", "no_NO": "Profilbilde må være angitt", "pl_PL": "Należy ustawić obraz profilowy", - "pt_BR": "A imagem de perfil deve ser definida", + "pt_BR": "A Imagem de Perfil Deve ser Definida", "ru_RU": "Необходимо установить аватар", + "sv_SE": "Profilbild måste anges", "th_TH": "จำเป็นต้องตั้งค่ารูปโปรไฟล์", "tr_TR": "Profil resmi ayarlanmalıdır", "uk_UA": "Зображення профілю обовʼязкове", @@ -19526,9 +21364,10 @@ "pl_PL": "{0} Aktualizacje dostępne dla {1} ({2})", "pt_BR": "{0} atualizações disponíveis para {1} ({2})", "ru_RU": "Доступные обновления для {0} ({1})", + "sv_SE": "Hantera uppdateringar för {0} ({1})", "th_TH": "จัดการอัพเดตสำหรับ {0} ({1})", "tr_TR": "{0} için güncellemeler mevcut [{1}]", - "uk_UA": "{0} Доступні оновлення для {1} ({2})", + "uk_UA": "Доступні оновлення для {0} ({1})", "zh_CN": "管理 {0} ({1}) 的更新", "zh_TW": "管理 {0} 的更新 ({1})" } @@ -19548,8 +21387,9 @@ "ko_KR": "해상도 증가 :", "no_NO": "Øke oppløsning:", "pl_PL": "Zwiększ Rozdzielczość:", - "pt_BR": "Aumentar a resolução:", + "pt_BR": "Aumentar a Resolução:", "ru_RU": "Увеличить разрешение:", + "sv_SE": "Öka upplösning:", "th_TH": "เพิ่มความละเอียด:", "tr_TR": "Çözünürlüğü artır:", "uk_UA": "Збільшити роздільність:", @@ -19572,8 +21412,9 @@ "ko_KR": "해상도 감소 :", "no_NO": "Reduser oppløsning:", "pl_PL": "Zmniejsz Rozdzielczość:", - "pt_BR": "Diminuir a resolução:", + "pt_BR": "Reduzir a Resolução:", "ru_RU": "Уменьшить разрешение:", + "sv_SE": "Sänk upplösning:", "th_TH": "ลดความละเอียด:", "tr_TR": "Çözünürlüğü azalt:", "uk_UA": "Зменшити роздільність:", @@ -19598,6 +21439,7 @@ "pl_PL": "Nazwa:", "pt_BR": "Nome:", "ru_RU": "Никнейм:", + "sv_SE": "Namn:", "th_TH": "ชื่อ:", "tr_TR": "İsim:", "uk_UA": "Імʼя", @@ -19620,8 +21462,9 @@ "ko_KR": "사용자 ID :", "no_NO": "Bruker ID:", "pl_PL": "ID Użytkownika:", - "pt_BR": "ID de usuário:", + "pt_BR": "ID de Usuário:", "ru_RU": "ID пользователя:", + "sv_SE": "Användar-id:", "th_TH": "รหัสผู้ใช้:", "tr_TR": "Kullanıcı Adı:", "uk_UA": "ID користувача:", @@ -19644,8 +21487,9 @@ "ko_KR": "그래픽 후단부", "no_NO": "Grafikk Backend", "pl_PL": "Backend Graficzny", - "pt_BR": "Backend gráfico", + "pt_BR": "Renderizador Gráfico", "ru_RU": "Графический бэкенд", + "sv_SE": "Grafikbakände", "th_TH": "กราฟิกเบื้องหลัง", "tr_TR": "Grafik Arka Ucu", "uk_UA": "Графічний сервер", @@ -19668,8 +21512,9 @@ "ko_KR": "에뮬레이터에서 사용할 그래픽 후단부를 선택합니다.\n\nVulkan은 드라이버가 최신 상태인 한 모든 최신 그래픽 카드에 전반적으로 더 좋습니다. Vulkan은 또한 모든 GPU 공급업체에서 더 빠른 셰이더 컴파일(덜 끊김)을 제공합니다.\n\nOpenGL은 오래된 Nvidia GPU, Linux의 오래된 AMD GPU 또는 VRAM이 낮은 GPU에서 더 나은 결과를 얻을 수 있지만 셰이더 컴파일 끊김이 더 큽니다.\n\n모르면 Vulkan으로 설정합니다. 최신 그래픽 드라이버를 사용해도 GPU가 Vulkan을 지원하지 않는 경우 OpenGL로 설정하세요..", "no_NO": "Velg grafikkbackend som skal brukes i emulatoren.\n\nVulkan er generelt bedre for alle moderne grafikkort, så lenge driverne er oppdatert. Vulkan har også en raskere sammenstilling av Shader (mindre hakkete) på alle GPU-leverandører.\n\nOpenGL kan oppnå bedre resultater for eldre Nvidia GPU-er, på eldre AMD GPU-er på Linux, eller på GPU-er med lavere VRAM, selv om skyggekompileringsutløser vil være større.\n\nSett til Vulkan hvis du er usikker. Sett til OpenGL hvis ikke GPU-en støtter Vulkan selv med de nyeste grafikkdriverne.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "Выберает бэкенд, который будет использован в эмуляторе.\n\nVulkan является лучшим выбором для всех современных графических карт с актуальными драйверами. В Vulkan также включена более быстрая компиляция шейдеров (меньше статтеров) для всех видеоадаптеров.\n\nПри использовании OpenGL можно достичь лучших результатов на старых видеоадаптерах Nvidia и AMD в Linux или на видеоадаптерах с небольшим количеством видеопамяти, хотя статтеров при компиляции шейдеров будет больше.\n\nРекомендуется использовать Vulkan. Используйте OpenGL, если ваш видеоадаптер не поддерживает Vulkan даже с актуальными драйверами.", + "pt_BR": "Selecione o renderizador gráfico que será usado no emulador.\n\nO Vulkan é melhor no geral para todas as placas de vídeo modernas, desde que seus drivers estejam atualizados. O Vulkan também apresenta compilação de shader mais rápida (menos travamentos) em todos os fornecedores de GPU.\n\nO OpenGL pode obter melhores resultados em GPUs Nvidia antigas, em GPUs AMD antigas no Linux ou em GPUs com VRAM menor, embora os travamentos de compilação de shader sejam maiores.\n\nDefina como Vulkan se não tiver certeza. Defina como OpenGL se sua GPU não suportar Vulkan, mesmo com os drivers gráficos mais recentes.", + "ru_RU": "Выбирает бэкенд, который будет использован в эмуляторе.\n\nVulkan является лучшим выбором для всех современных графических карт с актуальными драйверами. В Vulkan также включена более быстрая компиляция шейдеров (меньше статтеров) для всех видеоадаптеров.\n\nПри использовании OpenGL можно достичь лучших результатов на старых видеоадаптерах Nvidia и AMD в Linux или на видеоадаптерах с небольшим количеством видеопамяти, хотя статтеров при компиляции шейдеров будет больше.\n\nРекомендуется использовать Vulkan. Используйте OpenGL, если ваш видеоадаптер не поддерживает Vulkan даже с актуальными драйверами.", + "sv_SE": "Väljer den grafikbakände som ska användas i emulatorn.\n\nVulkan är oftast bättre för alla moderna grafikkort, så länge som deras drivrutiner är uppdaterade. Vulkan har också funktioner för snabbare shader compilation (mindre stuttering) för alla GPU-tillverkare.\n\nOpenGL kan nå bättre resultat på gamla Nvidia GPU:er, på äldre AMD GPU:er på Linux, eller på GPU:er med lägre VRAM, även om shader compilation stuttering kommer att vara större.\n\nStäll in till Vulkan om du är osäker. Ställ in till OpenGL om du GPU inte har stöd för Vulkan även med de senaste grafikdrivrutinerna.", "th_TH": "เลือกกราฟิกเบื้องหลังที่จะใช้ในโปรแกรมจำลอง\n\nโดยรวมแล้ว Vulkan นั้นดีกว่าสำหรับการ์ดจอรุ่นใหม่ทั้งหมด ตราบใดที่ไดรเวอร์ยังอัพเดทอยู่เสมอ Vulkan ยังมีคุณสมบัติการคอมไพล์เชเดอร์ที่เร็วขึ้น(และลดอาการกระตุก) สำหรับ GPU อื่นๆทุกอัน\n\nOpenGL อาจได้รับผลลัพธ์ที่ดีกว่าบน Nvidia GPU รุ่นเก่า, AMD GPU รุ่นเก่าบน Linux หรือบน GPU ที่มี VRAM น้อย แม้ว่าการคอมไพล์เชเดอร์ จะทำให้อาการกระตุกมากขึ้นก็ตาม\n\nตั้งค่าเป็น Vulkan หากไม่แน่ใจ ตั้งค่าเป็น OpenGL หาก GPU ของคุณไม่รองรับ Vulkan แม้จะมีไดรเวอร์กราฟิกล่าสุดก็ตาม", "tr_TR": "", "uk_UA": "Виберіть backend графіки, що буде використовуватись в емуляторі.\n\n\"Vulkan\" краще для всіх сучасних відеокарт, якщо драйвери вчасно оновлюються. У Vulkan також швидше компілюються шейдери (менше \"заїкання\" зображення) на відеокартах всіх компаній.\n\n\"OpenGL\" може дати кращі результати на старих відеокартах Nvidia, старих відеокартах AMD на Linux, або на відеокартах з маленькою кількістю VRAM, але \"заїкання\" через компіляцію шейдерів будуть частіші.\n\nЯкщо не впевнені, встановіть на \"Vulkan\". Встановіть на \"OpenGL\", якщо Ваша відеокарта не підтримує Vulkan навіть на останніх драйверах.", @@ -19677,6 +21522,56 @@ "zh_TW": "選擇模擬器將使用的圖形後端。\n\n只要驅動程式是最新的,Vulkan 對所有現代顯示卡來說都更好用。Vulkan 還能在所有 GPU 廠商上實現更快的著色器編譯 (減少卡頓)。\n\nOpenGL 在舊式 Nvidia GPU、Linux 上的舊式 AMD GPU 或 VRAM 較低的 GPU 上可能會取得更好的效果,不過著色器編譯的卡頓會更嚴重。\n\n如果不確定,請設定為 Vulkan。如果您的 GPU 使用最新的圖形驅動程式也不支援 Vulkan,請設定為 OpenGL。" } }, + { + "ID": "SettingsTabGraphicsBackendAuto", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Auto", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "Automatico", + "ja_JP": "", + "ko_KR": "자동", + "no_NO": "", + "pl_PL": "", + "pt_BR": "Automático", + "ru_RU": "Авто", + "sv_SE": "Automatiskt", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Автоматично", + "zh_CN": "自动", + "zh_TW": "自動" + } + }, + { + "ID": "SettingsTabGraphicsBackendAutoTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Uses Vulkan.\nOn an ARM Mac, and when playing a game that runs well under it, uses the Metal backend.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "Utilizza Vulkan.\nSu un Mac con processore ARM, utilizza il backend Metal nei giochi che funzionano bene con quest'ultimo.", + "ja_JP": "", + "ko_KR": "Vulkan을 사용합니다.\nARM 맥에서 해당 플랫폼에서 잘 실행되는 게임을 플레이하는 경우 Metal 후단부를 사용합니다.", + "no_NO": "Bruker Vulkan \nPå en ARM Mac, og når du spiller et spill som kjører bra under den, bruker du Metal-backend.", + "pl_PL": "", + "pt_BR": "Usa Vulkan.\nEm um Mac ARM, e ao jogar um jogo que roda bem nele, usa o renderizador Metal.", + "ru_RU": "Использует Vulkan.\nНа Mac с ARM процессорами используется Metal, если игра с ним совместима и хорошо работает.", + "sv_SE": "Använder Vulkan.\nPå en ARM Mac och vid spel som körs bra på den så används Metal-bakänden.", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Використовує Vulkan.\nНа Mac з ARM-архітектурою, якщо гра добре працює з Vulkan, використовується графічний рушій Metal.", + "zh_CN": "使用 Vulkan。\n在 ARM Mac 上,当玩在其下运行良好的游戏时,使用 Metal 后端。", + "zh_TW": "使用Vulkan。\n在 ARM Mac 上,如果遊戲執行性能良好時,則將使用 Metal 後端。" + } + }, { "ID": "SettingsEnableTextureRecompression", "Translations": { @@ -19692,8 +21587,9 @@ "ko_KR": "텍스처 재압축 활성화", "no_NO": "Aktiver teksturkomprimering", "pl_PL": "Włącz Rekompresję Tekstur", - "pt_BR": "Habilitar recompressão de texturas", + "pt_BR": "Habilitar Recompressão de Texturas", "ru_RU": "Пережимать текстуры", + "sv_SE": "Aktivera Texture Recompression", "th_TH": "เปิดใช้งาน การบีบอัดพื้นผิวอีกครั้ง", "tr_TR": "Yeniden Doku Sıkıştırılmasını Aktif Et", "uk_UA": "Увімкнути рекомпресію текстури", @@ -19716,8 +21612,9 @@ "ko_KR": "VRAM 사용량을 줄이기 위해 ASTC 텍스처를 압축합니다.\n\n이 텍스처 형식을 사용하는 게임에는 Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder, The Legend of Zelda: Tears of the Kingdom이 있습니다.\n\n4GiB VRAM 이하의 그래픽 카드는 이러한 게임을 실행하는 동안 어느 시점에서 충돌할 가능성이 있습니다.\n\n위에서 언급한 게임에서 VRAM이 부족한 경우에만 활성화합니다. 모르면 끔으로 두세요.", "no_NO": "Kompresser ASTC-teksturer for å redusere VRAM-bruk.\n\nSpill som bruker dette teksturformatet, inkluderer Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder and The Legend of Zelda: Tears of the Kingdom.\n\nGrafikkkort med 4GiB VRAM eller mindre, vil sannsynligvis krasje på et tidspunkt når spillene kjører.\n\nAktiver bare hvis du går tom for VRAM på nevnte spill. La AV om du er usikker.", "pl_PL": "", - "pt_BR": "", + "pt_BR": "Compacta texturas ASTC para reduzir o uso de VRAM.\n\nJogos que usam esse formato de textura incluem Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder e The Legend of Zelda: Tears of the Kingdom.\n\nPlacas gráficas com 4GB VRAM ou menos provavelmente travarão em algum momento durante a execução desses jogos.\n\nHabilite somente se estiver ficando sem VRAM nos jogos mencionados acima. Deixe DESLIGADO se não tiver certeza.", "ru_RU": "Сжатие ASTC текстур для уменьшения использования VRAM. \n\nИгры, использующие этот формат текстур: Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder и The Legend of Zelda: Tears of the Kingdom. \nНа видеоадаптерах с 4GiB видеопамяти или менее возможны вылеты при запуске этих игр. \n\nВключите, только если у вас заканчивается видеопамять в вышеупомянутых играх. \n\nРекомендуется оставить выключенным.", + "sv_SE": "Komprimerar ASTC-texturer för att minska VRAM-användning.\n\nSpel som använder detta texturformat inkluderar Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder och The Legend of Zelda: Tears of the Kingdom.\n\nGrafikkort med 4GiB VRAM eller mindre kommer sannolikt krascha någon gång när du kör dessa spel.\n\nAktivera endast om du har slut på VRAM på ovan nämnda spel. Lämna AV om du är osäker.", "th_TH": "บีบอัดพื้นผิว ASTC เพื่อลดการใช้งาน VRAM\n\nเกมที่ใช้รูปแบบพื้นผิวนี้ ได้แก่ Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder และ The Legend of Zelda: Tears of the Kingdom\n\nการ์ดจอที่มี 4GiB VRAM หรือน้อยกว่ามีแนวโน้มที่จะพังในบางจุดขณะเล่นเกมเหล่านี้\n\nเปิดใช้งานเฉพาะในกรณีที่ VRAM ของคุณใกล้หมดในเกมที่กล่าวมาข้างต้น ปล่อยให้ปิดหากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Стискає текстури ASTC, щоб зменшити використання VRAM.\n\nЦим форматом текстур користуються такі ігри, як Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder і The Legend of Zelda: Tears of the Kingdom.\n\nЦі ігри, скоріше всього крашнуться на відеокартах з розміром VRAM в 4 Гб і менше.\n\nВмикайте тільки якщо у Вас закінчується VRAM на цих іграх. Залиште на \"Вимкнути\", якщо не впевнені.", @@ -19740,8 +21637,9 @@ "ko_KR": "기본 GPU", "no_NO": "Foretrukket GPU", "pl_PL": "Preferowane GPU", - "pt_BR": "GPU preferencial", + "pt_BR": "GPU Preferida", "ru_RU": "Предпочтительный видеоадаптер", + "sv_SE": "Föredragen GPU", "th_TH": "GPU ที่ต้องการ", "tr_TR": "Kullanılan GPU", "uk_UA": "Бажаний GPU", @@ -19759,13 +21657,14 @@ "es_ES": "Selecciona la tarjeta gráfica que se utilizará con los back-end de gráficos Vulkan.\n\nNo afecta la GPU que utilizará OpenGL.\n\nFije a la GPU marcada como \"dGUP\" ante dudas. Si no hay una, no haga modificaciones.", "fr_FR": "Sélectionnez la carte graphique qui sera utilisée avec l'interface graphique Vulkan.\n\nCela ne change pas le GPU qu'OpenGL utilisera.\n\nChoisissez le GPU noté \"dGPU\" si vous n'êtes pas sûr. S'il n'y en a pas, ne pas modifier.", "he_IL": "בחר את הכרטיס הגראפי שישומש עם הגראפיקה של וולקאן.\n\nדבר זה לא משפיע על הכרטיס הגראפי שישומש עם OpenGL.\n\nמוטב לבחור את ה-GPU המסומן כ-\"dGPU\" אם אינכם בטוחים, אם זו לא אופצייה, אל תשנו דבר.", - "it_IT": "Seleziona la scheda grafica che verrà usata con la backend grafica Vulkan.\n\nNon influenza la GPU che userà OpenGL.\n\nImposta la GPU contrassegnata come \"dGPU\" se non sei sicuro. Se non ce n'è una, lascia intatta quest'impostazione.", + "it_IT": "Seleziona la scheda grafica che verrà usata con il backend grafico Vulkan.\n\nL'opzione non modifica la GPU usata da OpenGL.\n\nNel dubbio, seleziona la GPU contrassegnata come \"dGPU\". Se non ce n'è una, lascia intatta questa opzione.", "ja_JP": "Vulkanグラフィックスバックエンドで使用されるグラフィックスカードを選択します.\n\nOpenGLが使用するGPUには影響しません.\n\n不明な場合は, \"dGPU\" としてフラグが立っているGPUに設定します. ない場合はそのままにします.", "ko_KR": "Vulkan 그래픽 후단부와 함께 사용할 그래픽 카드를 선택하세요.\n\nOpenGL에서 사용할 GPU에는 영향을 미치지 않습니다.\n\n모르면 \"dGPU\"로 플래그가 지정된 GPU로 설정하세요. 없으면 그대로 두세요.", "no_NO": "Velg grafikkkortet som skal brukes sammen med Vulkan grafikkbackenden\n\nPåvirker ikke GPU-er som OpenGL skal bruke.\n\nSett til GPU-merket som \"dGPU\" hvis usikker. Hvis det ikke det er en, la være uberørt.", "pl_PL": "Wybierz kartę graficzną, która będzie używana z backendem graficznym Vulkan.\n\nNie wpływa na GPU używane przez OpenGL.\n\nW razie wątpliwości ustaw flagę GPU jako \"dGPU\". Jeśli żadnej nie ma, pozostaw nietknięte.", - "pt_BR": "Selecione a placa de vídeo que será usada com o backend gráfico Vulkan.\n\nNão afeta a GPU que OpenGL usará.\n\nSelecione \"dGPU\" em caso de dúvida. Se não houver nenhuma, não mexa.", - "ru_RU": "Выберает видеоадаптер, который будет использоваться графическим бэкендом Vulkan.\n\nЭта настройка не влияет на видеоадаптер, который будет использоваться с OpenGL.\n\nЕсли вы не уверены что нужно выбрать, используйте графический процессор, помеченный как \"dGPU\". Если его нет, оставьте выбор по умолчанию.", + "pt_BR": "Selecione a placa de vídeo que será usada com o renderizador gráfico Vulkan.\n\nNão afeta a GPU que OpenGL usará.\n\nSelecione \"dGPU\" em caso de dúvida. Se não houver nenhuma, não mexa.", + "ru_RU": "Выберает видеоадаптер, который будет использоваться графическим бэкендом Vulkan.\n\nЭта настройка не влияет на видеоадаптер, который будет использоваться с OpenGL.\n\nЕсли вы не уверены что нужно выбрать, используйте графический процессор, помеченный как «dGPU». Если его нет, оставьте выбор по умолчанию.", + "sv_SE": "Välj grafikkortet som ska användas med Vulkan-grafikbakänden.\n\nPåverkar inte GPU:n som OpenGL använder.\n\nStäll in till den GPU som flaggats som \"dGPU\" om osäker. Om det inte finns någon, lämna orörd.", "th_TH": "เลือกการ์ดจอที่จะใช้กับแบ็กเอนด์กราฟิก Vulkan\n\nไม่ส่งผลต่อ GPU ที่ OpenGL จะใช้\n\nตั้งค่าเป็น GPU ที่ถูกตั้งค่าสถานะเป็น \"dGPU\" ถ้าหากคุณไม่แน่ใจ ,หากไม่มีก็ปล่อยทิ้งไว้โดยไม่ต้องแตะต้องมัน", "tr_TR": "Vulkan Grafik Arka Ucu ile kullanılacak Ekran Kartını Seçin.\n\nOpenGL'nin kullanacağı GPU'yu etkilemez.\n\n Emin değilseniz \"dGPU\" olarak işaretlenmiş GPU'ya ayarlayın. Eğer yoksa, dokunmadan bırakın.\n", "uk_UA": "Виберіть відеокарту, яка використовуватиметься з графічним сервером Vulkan.\n\nНе впливає на графічний процесор, який використовуватиме OpenGL.\n\nВстановіть графічний процесор, позначений як «dGPU», якщо не впевнені. Якщо такого немає, не чіпайте.", @@ -19788,8 +21687,9 @@ "ko_KR": "Ryujinx 다시 시작 필요", "no_NO": "Ryujinx Omstart nødvendig", "pl_PL": "Wymagane Zrestartowanie Ryujinx", - "pt_BR": "Reinicialização do Ryujinx necessária", + "pt_BR": "Reinicialização do Ryujinx Necessária", "ru_RU": "Требуется перезапуск Ryujinx", + "sv_SE": "Omstart av Ryujinx krävs", "th_TH": "จำเป็นต้องรีสตาร์ท Ryujinx", "tr_TR": "Ryujinx'i Yeniden Başlatma Gerekli", "uk_UA": "Необхідно перезапустити Ryujinx", @@ -19807,13 +21707,14 @@ "es_ES": "La configuración de la GPU o del back-end de los gráficos fue modificada. Es necesario reiniciar para que se aplique.", "fr_FR": "Les paramètres de l'interface graphique ou du GPU ont été modifiés. Cela nécessitera un redémarrage pour être appliqué", "he_IL": "הגדרות אחראי גרפיקה או כרטיס גראפי שונו. זה ידרוש הפעלה מחדש כדי להחיל שינויים", - "it_IT": "Le impostazioni della backend grafica o della GPU sono state modificate. Questo richiederà un riavvio perché le modifiche siano applicate", + "it_IT": "Le impostazioni del backend grafico o della GPU sono state modificate. È necessario un riavvio per applicare le modifiche", "ja_JP": "グラフィックスバックエンドまたはGPUの設定が変更されました. 変更を適用するには再起動する必要があります", "ko_KR": "그래픽 후단부 또는 GPU 설정이 수정되었습니다. 이를 적용하려면 다시 시작이 필요", "no_NO": "Grafikk Backend eller GPU-innstillinger er endret. Dette krever en omstart for å aktiveres", "pl_PL": "Zmieniono ustawienia Backendu Graficznego lub GPU. Będzie to wymagało ponownego uruchomienia", - "pt_BR": "Configurações do backend gráfico ou da GPU foram alteradas. Uma reinicialização é necessária para que as mudanças tenham efeito.", + "pt_BR": "Configurações do renderizador gráfico ou da GPU foram alteradas. Uma reinicialização é necessária para que as mudanças tenham efeito.", "ru_RU": "Графический бэкенд или настройки графического процессора были изменены. Требуется перезапуск для вступления в силу изменений.", + "sv_SE": "Grafikbakänden eller GPU-inställningar har ändrats. Detta kräver en omstart", "th_TH": "การตั้งค่ากราฟิกเบื้องหลังหรือ GPU ได้รับการแก้ไขแล้ว สิ่งนี้จะต้องมีการรีสตาร์ทจึงจะสามารถใช้งานได้", "tr_TR": "Grafik Motoru ya da GPU ayarları değiştirildi. Bu işlemin uygulanması için yeniden başlatma gerekli.", "uk_UA": "Налаштування графічного сервера або GPU було змінено. Для цього знадобиться перезапуск", @@ -19838,6 +21739,7 @@ "pl_PL": "Czy chcesz zrestartować teraz?", "pt_BR": "Deseja reiniciar agora?", "ru_RU": "Перезапустить сейчас?", + "sv_SE": "Vill du starta om nu?", "th_TH": "คุณต้องการรีสตาร์ทตอนนี้หรือไม่?", "tr_TR": "Şimdi yeniden başlatmak istiyor musunuz?", "uk_UA": "Бажаєте перезапустити зараз?", @@ -19862,6 +21764,7 @@ "pl_PL": "Czy chcesz zaktualizować Ryujinx do najnowszej wersji?", "pt_BR": "Você quer atualizar o Ryujinx para a última versão?", "ru_RU": "Обновить Ryujinx до последней версии?", + "sv_SE": "Vill du uppdatera Ryujinx till senaste versionen?", "th_TH": "คุณต้องการอัพเดต Ryujinx เป็นเวอร์ชั่นล่าสุดหรือไม่?", "tr_TR": "Ryujinx'i en son sürüme güncellemek ister misiniz?", "uk_UA": "Бажаєте оновити Ryujinx до останньої версії?", @@ -19884,8 +21787,9 @@ "ko_KR": "음량 증가 :", "no_NO": "Øk Volum:", "pl_PL": "Zwiększ Głośność:", - "pt_BR": "Aumentar volume:", + "pt_BR": "Aumentar Volume:", "ru_RU": "Увеличить громкость:", + "sv_SE": "Öka volym:", "th_TH": "เพิ่มระดับเสียง:", "tr_TR": "Sesi Arttır:", "uk_UA": "Збільшити гучність:", @@ -19908,8 +21812,9 @@ "ko_KR": "음량 감소 :", "no_NO": "Reduser Volum:", "pl_PL": "Zmniejsz Głośność:", - "pt_BR": "Diminuir volume:", + "pt_BR": "Diminuir Volume:", "ru_RU": "Уменьшить громкость:", + "sv_SE": "Sänk volym:", "th_TH": "ลดระดับเสียง:", "tr_TR": "Sesi Azalt:", "uk_UA": "Зменшити гучність:", @@ -19932,8 +21837,9 @@ "ko_KR": "매크로 HLE 활성화", "no_NO": "Aktiver Makro HLE", "pl_PL": "Włącz Macro HLE", - "pt_BR": "Habilitar emulação de alto nível para Macros", + "pt_BR": "Habilitar Macro HLE", "ru_RU": "Использовать макрос высокоуровневой эмуляции видеоадаптера", + "sv_SE": "Aktivera Macro HLE", "th_TH": "เปิดใช้งาน มาโคร HLE", "tr_TR": "Macro HLE'yi Aktifleştir", "uk_UA": "Увімкнути макрос HLE", @@ -19957,7 +21863,8 @@ "no_NO": "High-level emulering av GPU makrokode.\n\nForbedrer ytelse, men kan forårsake grafiske glitches i noen spill.\n\nForlat PÅ hvis usikker.", "pl_PL": "Wysokopoziomowa emulacja kodu GPU Macro.\n\nPoprawia wydajność, ale może powodować błędy graficzne w niektórych grach.\n\nW razie wątpliwości pozostaw WŁĄCZONE.", "pt_BR": "Habilita emulação de alto nível de códigos Macro da GPU.\n\nMelhora a performance, mas pode causar problemas gráficos em alguns jogos.\n\nEm caso de dúvida, deixe ATIVADO.", - "ru_RU": "Высокоуровневая эмуляции макрокода видеоадаптера.\n\nПовышает производительность, но может вызывать графические артефакты в некоторых играх.\n\nРекомендуется оставить включенным.", + "ru_RU": "Высокоуровневая эмуляция макрокода видеоадаптера.\n\nПовышает производительность, но может вызывать графические артефакты в некоторых играх.\n\nРекомендуется оставить включенным.", + "sv_SE": "Högnivåemulering av GPU Macro-kod.\n\nFörbättrar prestandan men kan orsaka grafiska glitches i vissa spel.\n\nLämna PÅ om du är osäker.", "th_TH": "การจำลองระดับสูงของโค้ดมาโคร GPU\n\nปรับปรุงประสิทธิภาพ แต่อาจทำให้เกิดข้อผิดพลาดด้านกราฟิกในบางเกม\n\nเปิดทิ้งไว้หากคุณไม่แน่ใจ", "tr_TR": "GPU Macro kodunun yüksek seviye emülasyonu.\n\nPerformansı arttırır, ama bazı oyunlarda grafik hatalarına yol açabilir.\n\nEmin değilseniz AÇIK bırakın.", "uk_UA": "Високорівнева емуляція коду макросу GPU.\n\nПокращує продуктивність, але може викликати графічні збої в деяких іграх.\n\nЗалиште увімкненим, якщо не впевнені.", @@ -19980,8 +21887,9 @@ "ko_KR": "색 공간 통과", "no_NO": "Fargeromsgjennomgang", "pl_PL": "Przekazywanie przestrzeni kolorów", - "pt_BR": "Passagem de Espaço Cor", + "pt_BR": "Passagem do Espaço de Cores", "ru_RU": "Пропускать цветовое пространство", + "sv_SE": "Genomströmning av färgrymd", "th_TH": "ทะลุผ่านพื้นที่สี", "tr_TR": "Renk Alanı Geçişi", "uk_UA": "Наскрізний колірний простір", @@ -20004,8 +21912,9 @@ "ko_KR": "Vulkan 후단부가 색 공간을 지정하지 않고 색상 정보를 전달하도록 지시합니다. 넓은 색역 화면 표시 장치를 사용하는 사용자의 경우 색상 정확성을 희생하고 더 생생한 색상이 나올 수 있습니다.", "no_NO": "Dirigerer Vulkan backenden til å gå gjennom farge informasjonen uten og spesifisere en fargeromsgjennomgang. For brukere med en bred spillvisning kan dette resultere i mer vibrerende farger og få riktig farge.", "pl_PL": "Nakazuje API Vulkan przekazywać informacje o kolorze bez określania przestrzeni kolorów. Dla użytkowników z wyświetlaczami o szerokim zakresie kolorów może to skutkować bardziej żywymi kolorami, kosztem ich poprawności.", - "pt_BR": "Direciona o backend Vulkan para passar informações de cores sem especificar um espaço de cores. Para usuários com telas de ampla gama, isso pode resultar em cores mais vibrantes, ao custo da correção de cores.", + "pt_BR": "Direciona o renderizador Vulkan para passar informações de cores sem especificar um espaço de cores. Para usuários com telas de ampla gama, isso pode resultar em cores mais vibrantes, ao custo da correção de cores.", "ru_RU": "Направляет бэкенд Vulkan на передачу информации о цвете без указания цветового пространства. Для пользователей с экранами с расширенной гаммой данная настройка приводит к получению более ярких цветов за счет снижения корректности цветопередачи.", + "sv_SE": "Dirigerar Vulkan-bakänden att skicka genom färginformation utan att ange en färgrymd. För användare med breda gamut-skärmar kan detta resultera i mer levande färger på bekostnad av färgkorrekthet.", "th_TH": "สั่งให้แบ็กเอนด์ Vulkan ส่งผ่านข้อมูลสีโดยไม่ต้องระบุค่าของสี สำหรับผู้ใช้ที่มีการแสดงกระจายตัวของสี อาจส่งผลให้สีสดใสมากขึ้น โดยต้องแลกกับความถูกต้องของสี", "tr_TR": "Vulkan Backend'ini renk alanı belirtmeden renk bilgisinden geçmeye yönlendirir. Geniş gam ekranlı kullanıcılar için bu, renk doğruluğu pahasına daha canlı renklerle sonuçlanabilir.", "uk_UA": "Дозволяє серверу Vulkan передавати інформацію про колір без вказівки колірного простору. Для користувачів з екранами з широкою гамою це може призвести до більш яскравих кольорів, але шляхом втрати коректності передачі кольору.", @@ -20028,8 +21937,9 @@ "ko_KR": "음량", "no_NO": "", "pl_PL": "Głoś", - "pt_BR": "", + "pt_BR": "Volume", "ru_RU": "Громкость", + "sv_SE": "Volym", "th_TH": "ระดับเสียง", "tr_TR": "Ses", "uk_UA": "Гуч.", @@ -20052,8 +21962,9 @@ "ko_KR": "저장 관리", "no_NO": "Administrer lagring", "pl_PL": "Zarządzaj Zapisami", - "pt_BR": "Gerenciar jogos salvos", + "pt_BR": "Gerenciar Jogos Salvos", "ru_RU": "Управление сохранениями", + "sv_SE": "Hantera sparade spel", "th_TH": "จัดการบันทึก", "tr_TR": "Kayıtları Yönet", "uk_UA": "Керувати збереженнями", @@ -20078,6 +21989,7 @@ "pl_PL": "Czy chcesz usunąć zapis użytkownika dla tej gry?", "pt_BR": "Deseja apagar o jogo salvo do usuário para este jogo?", "ru_RU": "Удалить сохранения для этой игры?", + "sv_SE": "Vill du ta bort användarsparade spel för detta spel?", "th_TH": "คุณต้องการลบบันทึกผู้ใช้สำหรับเกมนี้หรือไม่?", "tr_TR": "Bu oyun için kullanıcı kaydını silmek istiyor musunuz?", "uk_UA": "Ви хочете видалити збереження користувача для цієї гри?", @@ -20102,6 +22014,7 @@ "pl_PL": "Ta czynność nie jest odwracalna.", "pt_BR": "Esta ação não é reversível.", "ru_RU": "Данное действие является необратимым.", + "sv_SE": "Denna åtgärd går inte att ångra.", "th_TH": "การดำเนินการนี้ไม่สามารถย้อนกลับได้", "tr_TR": "Bu eylem geri alınamaz.", "uk_UA": "Цю дію не можна скасувати.", @@ -20124,8 +22037,9 @@ "ko_KR": "{0} ({1})에 대한 저장 관리", "no_NO": "Administrer lagring for {0} ({1})", "pl_PL": "Zarządzaj Zapisami dla {0}", - "pt_BR": "Gerenciar jogos salvos para {0}", + "pt_BR": "Gerenciar Jogos Salvos para {0}", "ru_RU": "Редактирование сохранений для {0} ({1})", + "sv_SE": "Hantera sparade spel för {0} ({1})", "th_TH": "จัดการบันทึกสำหรับ {0} ({1})", "tr_TR": "{0} için Kayıt Dosyalarını Yönet", "uk_UA": "Керувати збереженнями для {0}", @@ -20148,8 +22062,9 @@ "ko_KR": "관리자 저장", "no_NO": "Lagre behandler", "pl_PL": "Menedżer Zapisów", - "pt_BR": "Gerenciador de jogos salvos", + "pt_BR": "Gerenciador de Jogos Salvos", "ru_RU": "Менеджер сохранений", + "sv_SE": "Sparhanterare", "th_TH": "จัดการบันทึก", "tr_TR": "Kayıt Yöneticisi", "uk_UA": "Менеджер збереження", @@ -20165,7 +22080,7 @@ "el_GR": "Όνομα", "en_US": "Name", "es_ES": "Nombre", - "fr_FR": "Nom ", + "fr_FR": "Nom\u00A0", "he_IL": "שם", "it_IT": "Nome", "ja_JP": "名称", @@ -20174,6 +22089,7 @@ "pl_PL": "Nazwa", "pt_BR": "Nome", "ru_RU": "Название", + "sv_SE": "Namn", "th_TH": "ชื่อ", "tr_TR": "İsim", "uk_UA": "Назва", @@ -20198,6 +22114,7 @@ "pl_PL": "Rozmiar", "pt_BR": "Tamanho", "ru_RU": "Размер", + "sv_SE": "Storlek", "th_TH": "ขนาด", "tr_TR": "Boyut", "uk_UA": "Розмір", @@ -20222,6 +22139,7 @@ "pl_PL": "Wyszukaj", "pt_BR": "Buscar", "ru_RU": "Поиск", + "sv_SE": "Sök", "th_TH": "ค้นหา", "tr_TR": "Ara", "uk_UA": "Пошук", @@ -20244,8 +22162,9 @@ "ko_KR": "잃어버린 계정 복구", "no_NO": "Gjenopprett tapte kontoer", "pl_PL": "Odzyskaj Utracone Konta", - "pt_BR": "Recuperar contas perdidas", - "ru_RU": "Восстановить учетные записи", + "pt_BR": "Recuperar Contas Perdidas", + "ru_RU": "Восстановить учётные записи", + "sv_SE": "Återskapa förlorade konton", "th_TH": "กู้คืนบัญชีที่สูญหาย", "tr_TR": "Kayıp Hesapları Kurtar", "uk_UA": "Відновлення профілів", @@ -20270,6 +22189,7 @@ "pl_PL": "Odzyskaj", "pt_BR": "Recuperar", "ru_RU": "Восстановление", + "sv_SE": "Återskapa", "th_TH": "กู้คืน", "tr_TR": "Kurtar", "uk_UA": "Відновити", @@ -20294,6 +22214,7 @@ "pl_PL": "Znaleziono zapisy dla następujących kont", "pt_BR": "Jogos salvos foram encontrados para as seguintes contas", "ru_RU": "Были найдены сохранения для следующих аккаунтов", + "sv_SE": "Sparade spel hittades för följande konton", "th_TH": "พบบันทึกสำหรับบัญชีดังต่อไปนี้", "tr_TR": "Aşağıdaki hesaplar için kayıtlar bulundu", "uk_UA": "Знайдено збереження для наступних облікових записів", @@ -20317,7 +22238,8 @@ "no_NO": "Ingen profiler å gjenopprette", "pl_PL": "Brak profili do odzyskania", "pt_BR": "Nenhum perfil para recuperar", - "ru_RU": "Нет учетных записей для восстановления", + "ru_RU": "Нет учётных записей для восстановления", + "sv_SE": "Inga profiler att återskapa", "th_TH": "ไม่มีโปรไฟล์ที่สามารถกู้คืนได้", "tr_TR": "Kurtarılacak profil bulunamadı", "uk_UA": "Немає профілів для відновлення", @@ -20335,13 +22257,14 @@ "es_ES": "Aplica antia-aliasing al rendereo del juego.\n\nFXAA desenfocará la mayor parte del la iamgen, mientras que SMAA intentará encontrar bordes irregulares y suavizarlos.\n\nNo se recomienda usar en conjunto con filtro de escala FSR.\n\nEsta opción puede ser modificada mientras que esté corriendo el juego haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDejar en NADA si no está seguro.", "fr_FR": "FXAA floute la plupart de l'image, tandis que SMAA tente de détecter les contours dentelés et de les lisser.\n\nIl n'est pas recommandé de l'utiliser en conjonction avec le filtre de mise à l'échelle FSR.\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres sur le côté et expérimenter jusqu'à ce que vous trouviez l'apparence souhaitée pour un jeu.\n\nLaissez sur AUCUN si vous n'êtes pas sûr.", "he_IL": "", - "it_IT": "Applica anti-aliasing al rendering del gioco.\n\nFXAA sfocerà la maggior parte dell'immagine, mentre SMAA tenterà di trovare bordi frastagliati e lisciarli.\n\nNon si consiglia di usarlo in combinazione con il filtro di scala FSR.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nLasciare su Nessuno se incerto.", + "it_IT": "Applica l'anti-aliasing al rendering del gioco.\n\nFXAA rende la maggior parte dell'immagine sfocata, mentre SMAA tenta di rilevare e smussare i bordi frastagliati.\n\nSi consiglia di non usarlo in combinazione con il filtro di scaling FSR.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nNel dubbio, lascia su Nessuno.", "ja_JP": "ゲームレンダリングにアンチエイリアスを適用します.\n\nFXAAは画像の大部分をぼかし, SMAAはギザギザのエッジを見つけて滑らかにします.\n\nFSRスケーリングフィルタとの併用は推奨しません.\n\nこのオプションは, ゲーム実行中に下の「適用」をクリックして変更できます. 設定ウィンドウを脇に移動し, ゲームが好みの表示になるように試してみてください.\n\n不明な場合は「なし」のままにしておいてください.", "ko_KR": "게임 렌더에 앤티 앨리어싱을 적용합니다.\n\nFXAA는 이미지 대부분을 흐리게 처리하지만 SMAA는 들쭉날쭉한 가장자리를 찾아 부드럽게 처리합니다.\n\nFSR 스케일링 필터와 함께 사용하지 않는 것이 좋습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임을 실행하는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮겨 원하는 게임의 모습을 찾을 때까지 실험해 볼 수 있습니다.\n\n모르면 없음으로 두세요.", "no_NO": "Aktiverer anti-aliasing til spill render.\n\nFXAA vil gjøre det meste av bildet, mens SMAA vil forsøke å finne berørte kanter og glatte dem ut.\n\nAnbefales ikke til bruk i forbindelse med FSR-skaleringsfilteret.\n\nDette valget kan endres mens et spill kjører ved å klikke \"Apply\" nedenfor; du kan bare flytte innstillingsvinduet til du finner det foretrukne utseendet til et spill.\n\nForlat på NONE hvis usikker.", "pl_PL": "", "pt_BR": "Aplica anti-aliasing à renderização do jogo.\n\nFXAA borrará a maior parte da imagem, enquanto SMAA tentará identificar e suavizar bordas serrilhadas.\n\nNão é recomendado usar em conjunto com o filtro de escala FSR.\n\nEssa opção pode ser alterada enquanto o jogo está em execução clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nDeixe em NENHUM se estiver em dúvida.", - "ru_RU": "Применимое сглаживание для рендера.\n\nFXAA размывает большую часть изображения, SMAA попытается найти \"зазубренные\" края и сгладить их.\n\nНе рекомендуется использовать вместе с масштабирующим фильтром FSR.\n\nЭта опция может быть изменена во время игры по нажатию \"Применить\" ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не найдёте подходящую настройку игры.\n\nРекомендуется использовать \"Нет\".", + "ru_RU": "Применимое сглаживание для рендера.\n\nFXAA размывает большую часть изображения, SMAA попытается найти «зазубренные» края и сгладить их.\n\nНе рекомендуется использовать вместе с масштабирующим фильтром FSR.\n\nЭта опция может быть изменена во время игры по нажатию «Применить» ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не найдёте подходящую настройку игры.\n\nРекомендуется использовать «Нет».", + "sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.", "th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Немає\", якщо не впевнені.", @@ -20359,13 +22282,14 @@ "es_ES": "Suavizado de bordes:", "fr_FR": "Anticrénelage :", "he_IL": "החלקת-עקומות:", - "it_IT": "", + "it_IT": "Anti-aliasing:", "ja_JP": "アンチエイリアス:", "ko_KR": "앤티 앨리어싱 :", "no_NO": "Kantutjevning:", "pl_PL": "Antyaliasing:", - "pt_BR": "Anti-serrilhado:", + "pt_BR": "Anti-Serrilhado:", "ru_RU": "Сглаживание:", + "sv_SE": "Antialiasing:", "th_TH": "ลดการฉีกขาดของภาพ:", "tr_TR": "Kenar Yumuşatma:", "uk_UA": "Згладжування:", @@ -20383,13 +22307,14 @@ "es_ES": "Filtro de escalado:", "fr_FR": "Filtre de mise à l'échelle :", "he_IL": "מסנן מידת איכות:", - "it_IT": "Filtro di scala:", + "it_IT": "Filtro di scaling:", "ja_JP": "スケーリングフィルタ:", "ko_KR": "크기 조정 필터 :", "no_NO": "Skaleringsfilter:", "pl_PL": "Filtr skalowania:", - "pt_BR": "Filtro de escala:", + "pt_BR": "Filtro de Escala:", "ru_RU": "Интерполяция:", + "sv_SE": "Skalningsfilter:", "th_TH": "ปรับขนาดตัวกรอง:", "tr_TR": "Ölçekleme Filtresi:", "uk_UA": "Фільтр масштабування:", @@ -20407,16 +22332,17 @@ "es_ES": "Elija el filtro de escala que se aplicará al utilizar la escala de resolución.\n\nBilinear funciona bien para juegos 3D y es una opción predeterminada segura.\n\nSe recomienda el bilinear para juegos de pixel art.\n\nFSR 1.0 es simplemente un filtro de afilado, no se recomienda su uso con FXAA o SMAA.\n\nEsta opción se puede cambiar mientras se ejecuta un juego haciendo clic en \"Aplicar\" a continuación; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDéjelo en BILINEAR si no está seguro.", "fr_FR": "Choisissez le filtre de mise à l'échelle qui sera appliqué lors de l'utilisation de la mise à l'échelle de la résolution.\n\nLe filtre bilinéaire fonctionne bien pour les jeux en 3D et constitue une option par défaut sûre.\n\nLe filtre le plus proche est recommandé pour les jeux de pixel art.\n\nFSR 1.0 est simplement un filtre de netteté, non recommandé pour une utilisation avec FXAA ou SMAA.\n\nCette option peut être modifiée pendant qu'un jeu est en cours d'exécution en cliquant sur \"Appliquer\" ci-dessous ; vous pouvez simplement déplacer la fenêtre des paramètres de côté et expérimenter jusqu'à ce que vous trouviez l'aspect souhaité pour un jeu.\n\nLaissez sur BILINÉAIRE si vous n'êtes pas sûr.", "he_IL": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", - "it_IT": "Scegli il filtro di scaling che verrà applicato quando si utilizza o scaling di risoluzione.\n\nBilineare funziona bene per i giochi 3D ed è un'opzione predefinita affidabile.\n\nNearest è consigliato per i giochi in pixel art.\n\nFSR 1.0 è solo un filtro di nitidezza, non raccomandato per l'uso con FXAA o SMAA.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nLasciare su Bilineare se incerto.", + "it_IT": "Scegli il filtro di scaling che verrà applicato quando si utilizza lo scaling della risoluzione.\n\nBilineare funziona bene per i giochi 3D ed è un'opzione predefinita affidabile.\n\nNearest è consigliato per i giochi in pixel art.\n\nFSR 1.0 è solo un filtro di nitidezza, sconsigliato per l'uso con FXAA o SMAA.\n\nLo scaling ad area è consigliato quando si riducono delle risoluzioni che sono più grandi della finestra di output. Può essere usato per ottenere un effetto di anti-aliasing supercampionato quando si riduce di più di 2x.\n\nQuesta opzione può essere modificata mentre un gioco è in esecuzione facendo clic su \"Applica\" qui sotto; puoi semplicemente spostare la finestra delle impostazioni da parte e sperimentare fino a quando non trovi il tuo look preferito per un gioco.\n\nNel dubbio, lascia su Bilineare.", "ja_JP": "解像度変更時に適用されるスケーリングフィルタを選択します.\n\nBilinearは3Dゲームに適しており, 安全なデフォルトオプションです.\n\nピクセルアートゲームにはNearestを推奨します.\n\nFSR 1.0は単なるシャープニングフィルタであり, FXAAやSMAAとの併用は推奨されません.\n\nこのオプションは, ゲーム実行中に下の「適用」をクリックすることで変更できます. 設定ウィンドウを脇に移動し, ゲームが好みの表示になるように試してみてください.\n\n不明な場合はBilinearのままにしておいてください.", "ko_KR": "해상도 스케일을 사용할 때 적용될 스케일링 필터를 선택합니다.\n\n쌍선형은 3D 게임에 적합하며 안전한 기본 옵션입니다.\n\nNearest는 픽셀 아트 게임에 권장됩니다.\n\nFSR 1.0은 단순히 선명도 필터일 뿐이며 FXAA 또는 SMAA와 함께 사용하는 것은 권장되지 않습니다.\n\nArea 스케일링은 출력 창보다 큰 해상도를 다운스케일링할 때 권장됩니다. 2배 이상 다운스케일링할 때 슈퍼샘플링된 앤티앨리어싱 효과를 얻는 데 사용할 수 있습니다.\n\n이 옵션은 아래의 \"적용\"을 클릭하여 게임을 실행하는 동안 변경할 수 있습니다. 설정 창을 옆으로 옮겨 원하는 게임 모양을 찾을 때까지 실험하면 됩니다.\n\n모르면 쌍선형을 그대로 두세요.", "no_NO": "Velg det skaleringsfilteret som skal brukes når du bruker oppløsningsskalaen.\n\nBilinear fungerer godt for 3D-spill og er et trygt standardalternativ.\n\nNærmeste anbefales for pixel kunst-spill.\n\nFSR 1.0 er bare et skarpere filter, ikke anbefalt for bruk med FXAA eller SMAA.\n\nOmrådeskalering anbefales når nedskalering er større enn utgangsvinduet. Den kan brukes til å oppnå en superprøvetaket anti-aliasingseffekt når en nedskalerer med mer enn 2x.\n\nDette valget kan endres mens et spill kjører ved å klikke \"Apply\" nedenfor; du kan bare flytte innstillingsvinduet til du finner det foretrukne utseendet til et spill.\n\nLa være på BILINEAR hvis usikker.", "pl_PL": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", "pt_BR": "Escolha o filtro de escala que será aplicado ao usar a escala de resolução.\n\nBilinear funciona bem para jogos 3D e é uma opção padrão segura.\n\nNearest é recomendado para jogos em pixel art.\n\nFSR 1.0 é apenas um filtro de nitidez, não recomendado para uso com FXAA ou SMAA.\n\nEssa opção pode ser alterada enquanto o jogo está em execução, clicando em \"Aplicar\" abaixo; basta mover a janela de configurações para o lado e experimentar até encontrar o visual preferido para o jogo.\n\nMantenha em BILINEAR se estiver em dúvida.", - "ru_RU": "Фильтрация текстур, которая будет применяться при масштабировании.\n\nБилинейная хорошо работает для 3D-игр и является настройкой по умолчанию.\n\nСтупенчатая рекомендуется для пиксельных игр.\n\nFSR это фильтр резкости, который не рекомендуется использовать с FXAA или SMAA.\n\nЭта опция может быть изменена во время игры по нажатию кнопки \"Применить\" ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nРекомендуется использовать \"Билинейная\".", + "ru_RU": "Фильтрация текстур, которая будет применяться при масштабировании.\n\nБилинейная хорошо работает для 3D-игр и является настройкой по умолчанию.\n\nСтупенчатая рекомендуется для пиксельных игр.\n\nFSR это фильтр резкости, который не рекомендуется использовать с FXAA или SMAA.\n\nЗональная рекомендуется в случае использования разрешения больше разрешения окна. Можно использовать для достижения эффекта суперсемплига (SSAA) при даунскейле более чем в 2 раза.\n\nЭта опция может быть изменена во время игры по нажатию кнопки «Применить» ниже; \nВы можете просто переместить окно настроек в сторону и поэкспериментировать, пока не подберете подходящие настройки для конкретной игры.\n\nРекомендуется использовать «Билинейная».", + "sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.", "th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม", "tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", - "uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - це просто фільтр різкості, не рекомендується використовувати разом з FXAA або SMAA.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Білінійний\", якщо не впевнені.", + "uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна змінювати під час гри кліком на \"Застосувати\" нижче; ви можете відсунути вікно налаштувань і поекспериментувати з тим, як відображатиметься гра.\n\nЗалиште на \"Білінійний\", якщо не впевнені.", "zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear(双线性过滤)对于3D游戏效果较好,是一个安全的默认选项。\n\nNearest(最近邻过滤)推荐用于像素艺术游戏。\n\nFSR(超级分辨率锐画)只是一个锐化过滤器,不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea(局部过滤),当渲染分辨率大于窗口实际分辨率,推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时,通过点击下面的“应用”按钮可以使设置生效;你可以将设置窗口移开,并试验找到您喜欢的游戏画面效果。\n\n如果不确定,请保持为“Bilinear(双线性过滤)”。", "zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更;您只需將設定視窗移到一旁,然後進行試驗,直到找到您喜歡的遊戲效果。\n\n如果不確定,請保持雙線性 (Bilinear) 狀態。" } @@ -20438,6 +22364,7 @@ "pl_PL": "Dwuliniowe", "pt_BR": "", "ru_RU": "Билинейная", + "sv_SE": "Bilinjär", "th_TH": "", "tr_TR": "", "uk_UA": "Білінійний", @@ -20462,6 +22389,7 @@ "pl_PL": "Najbliższe", "pt_BR": "", "ru_RU": "Ступенчатая", + "sv_SE": "Närmaste", "th_TH": "ใกล้สุด", "tr_TR": "", "uk_UA": "Найближчий", @@ -20486,6 +22414,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -20508,13 +22437,14 @@ "ko_KR": "영역", "no_NO": "Område", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Área", + "ru_RU": "Зональная", + "sv_SE": "Yta", "th_TH": "", "tr_TR": "", "uk_UA": "", "zh_CN": "Area(区域过滤)", - "zh_TW": "" + "zh_TW": "區域" } }, { @@ -20534,6 +22464,7 @@ "pl_PL": "Poziom", "pt_BR": "Nível", "ru_RU": "Уровень", + "sv_SE": "Nivå", "th_TH": "ระดับ", "tr_TR": "Seviye", "uk_UA": "Рівень", @@ -20557,10 +22488,11 @@ "no_NO": "Definer FSR 1,0 skarpere nivå. Høyere er skarpere.", "pl_PL": "Ustaw poziom ostrzeżenia FSR 1.0. Wyższy jest ostrzejszy.", "pt_BR": "Defina o nível de nitidez do FSR 1.0. Quanto maior, mais nítido.", - "ru_RU": "Выбор режима работы FSR 1.0. Выше - четче.", + "ru_RU": "Выбор режима работы FSR 1.0. Выше — четче.", + "sv_SE": "Ställ in nivå för FSR 1.0 sharpening. Högre är skarpare.", "th_TH": "ตั้งค่าระดับความคมชัด FSR 1.0 ยิ่งสูงกว่าจะยิ่งคมชัดกว่า", "tr_TR": "", - "uk_UA": "Встановити рівень різкості в FSR 1.0. Чим вище - тим різкіше.", + "uk_UA": "Встановити рівень різкості FSR 1.0. Чим вище - тим різкіше.", "zh_CN": "设置 FSR 1.0 的锐化等级,数值越高,图像越锐利。", "zh_TW": "設定 FSR 1.0 銳化等級。越高越清晰。" } @@ -20582,6 +22514,7 @@ "pl_PL": "SMAA Niskie", "pt_BR": "SMAA Baixo", "ru_RU": "SMAA Низкое", + "sv_SE": "SMAA låg", "th_TH": "SMAA ต่ำ", "tr_TR": "Düşük SMAA", "uk_UA": "SMAA Низький", @@ -20606,6 +22539,7 @@ "pl_PL": "SMAA Średnie", "pt_BR": "SMAA Médio", "ru_RU": "SMAA Среднее", + "sv_SE": "SMAA medium", "th_TH": "SMAA ปานกลาง", "tr_TR": "Orta SMAA", "uk_UA": "SMAA Середній", @@ -20630,6 +22564,7 @@ "pl_PL": "SMAA Wysokie", "pt_BR": "SMAA Alto", "ru_RU": "SMAA Высокое", + "sv_SE": "SMAA hög", "th_TH": "SMAA สูง", "tr_TR": "Yüksek SMAA", "uk_UA": "SMAA Високий", @@ -20654,6 +22589,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "SMAA Ультра", + "sv_SE": "SMAA ultra", "th_TH": "SMAA สูงมาก", "tr_TR": "En Yüksek SMAA", "uk_UA": "SMAA Ультра", @@ -20671,13 +22607,14 @@ "es_ES": "Editar usuario", "fr_FR": "Modifier Utilisateur", "he_IL": "ערוך משתמש", - "it_IT": "Modificare L'Utente", + "it_IT": "Modifica utente", "ja_JP": "ユーザを編集", "ko_KR": "사용자 편집", "no_NO": "Rediger bruker", "pl_PL": "Edytuj użytkownika", - "pt_BR": "Editar usuário", + "pt_BR": "Editar Usuário", "ru_RU": "Редактирование пользователя", + "sv_SE": "Redigera användare", "th_TH": "แก้ไขผู้ใช้", "tr_TR": "Kullanıcıyı Düzenle", "uk_UA": "Редагувати користувача", @@ -20695,13 +22632,14 @@ "es_ES": "Crear Usuario", "fr_FR": "Créer Utilisateur", "he_IL": "צור משתמש", - "it_IT": "Crea Un Utente", + "it_IT": "Crea utente", "ja_JP": "ユーザを作成", "ko_KR": "사용자 만들기", "no_NO": "Opprett bruker", "pl_PL": "Utwórz użytkownika", "pt_BR": "Criar usuário", "ru_RU": "Создание пользователя", + "sv_SE": "Skapa användare", "th_TH": "สร้างผู้ใช้", "tr_TR": "Kullanıcı Oluştur", "uk_UA": "Створити користувача", @@ -20721,11 +22659,12 @@ "he_IL": "ממשק רשת", "it_IT": "Interfaccia di rete:", "ja_JP": "ネットワークインタフェース:", - "ko_KR": "네트워크 인터페이스:", + "ko_KR": "네트워크 인터페이스 :", "no_NO": "Nettverksgrensesnitt", "pl_PL": "Interfejs sieci:", - "pt_BR": "Interface de rede:", + "pt_BR": "Interface de Rede:", "ru_RU": "Сетевой интерфейс:", + "sv_SE": "Nätverksgränssnitt:", "th_TH": "เชื่อมต่อเครือข่าย:", "tr_TR": "Ağ Bağlantısı:", "uk_UA": "Мережевий інтерфейс:", @@ -20749,7 +22688,8 @@ "no_NO": "Nettverksgrensesnittets grensesnitt brukt for LAN/LDN funksjoner.\n\ni konjuksjon med en VPN eller XLink Kai og ett spill med LAN støtte, kan bli brukt til og spoofe ett \"samme-nettverk\" tilkobling over nettet.\n\nLa være på DEFAULT om usikker.", "pl_PL": "Interfejs sieciowy używany dla funkcji LAN/LDN.\n\nw połączeniu z VPN lub XLink Kai i grą z obsługą sieci LAN, może być użyty do spoofowania połączenia z tą samą siecią przez Internet.\n\nZostaw DOMYŚLNE, jeśli nie ma pewności.", "pt_BR": "A interface de rede usada para recursos de LAN/LDN.\n\nEm conjunto com uma VPN ou XLink Kai e um jogo com suporte a LAN, pode ser usada para simular uma conexão na mesma rede pela Internet.\n\nMantenha em PADRÃO se estiver em dúvida.", - "ru_RU": "Сетевой интерфейс, используемый для функций LAN/LDN.\n\nМожет использоваться для игры через интернет в сочетании с VPN или XLink Kai и игрой с поддержкой LAN.\n\nРекомендуется использовать \"По умолчанию\".", + "ru_RU": "Сетевой интерфейс, используемый для функций LAN/LDN.\n\nМожет использоваться для игры через интернет в сочетании с VPN или XLink Kai и игрой с поддержкой LAN.\n\nРекомендуется использовать «По умолчанию».", + "sv_SE": "Nätverksgränssnittet som används för LAN/LDN-funktioner.\n\nTillsammans med en VPN eller XLink Kai och ett spel med LAN-stöd så kan detta användas för att spoofa en same-network-anslutning över internet.\n\nLämna som STANDARD om du är osäker.", "th_TH": "อินเทอร์เฟซเครือข่ายที่ใช้สำหรับคุณสมบัติ LAN/LDN\n\nเมื่อใช้ร่วมกับ VPN หรือ XLink Kai และเกมที่รองรับ LAN สามารถใช้เพื่อปลอมการเชื่อมต่อเครือข่ายเดียวกันผ่านทางอินเทอร์เน็ต\n\nปล่อยให้เป็น ค่าเริ่มต้น หากคุณไม่แน่ใจ", "tr_TR": "", "uk_UA": "Мережевий інтерфейс, що використовується для LAN/LDN.\n\nРазом з VPN або XLink Kai, і грою що підтримує LAN, може імітувати з'єднання в однаковій мережі через Інтернет.", @@ -20774,6 +22714,7 @@ "pl_PL": "Domyślny", "pt_BR": "Padrão", "ru_RU": "По умолчанию", + "sv_SE": "Standard", "th_TH": "ค่าเริ่มต้น", "tr_TR": "Varsayılan", "uk_UA": "Стандартний", @@ -20798,6 +22739,7 @@ "pl_PL": "Pakuje Shadery ", "pt_BR": "Empacotamento de Shaders", "ru_RU": "Упаковка шейдеров", + "sv_SE": "Paketering av Shaders", "th_TH": "รวม Shaders เข้าด้วยกัน", "tr_TR": "Gölgeler Paketleniyor", "uk_UA": "Пакування шейдерів", @@ -20820,8 +22762,9 @@ "ko_KR": "GitHub에서 변경 내역 보기", "no_NO": "Vis endringslogg på GitHub", "pl_PL": "Zobacz listę zmian na GitHubie", - "pt_BR": "Ver mudanças no GitHub", - "ru_RU": "Список изменений на GitHub", + "pt_BR": "Ver Mudanças no GitHub", + "ru_RU": "Показать список изменений на GitHub", + "sv_SE": "Visa ändringslogg på GitHub", "th_TH": "ดูประวัติการเปลี่ยนแปลงบน GitHub", "tr_TR": "GitHub'da Değişiklikleri Görüntüle", "uk_UA": "Переглянути журнал змін на GitHub", @@ -20839,13 +22782,14 @@ "es_ES": "Haga clic para abrir el registro de cambios para esta versión en su navegador predeterminado.", "fr_FR": "Cliquez pour ouvrir le changelog de cette version dans votre navigateur par défaut.", "he_IL": "לחץ כדי לפתוח את יומן השינויים עבור גרסה זו בדפדפן ברירת המחדל שלך.", - "it_IT": "Clicca per aprire il changelog per questa versione nel tuo browser predefinito.", + "it_IT": "Clicca per aprire il changelog di questa versione nel tuo browser predefinito.", "ja_JP": "クリックして, このバージョンの更新履歴をデフォルトのブラウザで開きます.", "ko_KR": "기본 브라우저에서 이 버전의 변경 내역을 열람하려면 클릭하세요.", "no_NO": "Klikk for å åpne endringsloggen for denne versjonen i din nettleser.", "pl_PL": "Kliknij, aby otworzyć listę zmian dla tej wersji w domyślnej przeglądarce.", "pt_BR": "Clique para abrir o relatório de alterações para esta versão no seu navegador padrão.", "ru_RU": "Нажмите, чтобы открыть список изменений для этой версии", + "sv_SE": "Klicka för att öppna ändringsloggen för denna version i din standardwebbläsare.", "th_TH": "คลิกเพื่อเปิดประวัติการเปลี่ยนแปลงสำหรับเวอร์ชั่นนี้ บนเบราว์เซอร์เริ่มต้นของคุณ", "tr_TR": "Kullandığınız versiyon için olan değişiklikleri varsayılan tarayıcınızda görmek için tıklayın", "uk_UA": "Клацніть, щоб відкрити журнал змін для цієї версії у стандартному браузері.", @@ -20868,8 +22812,9 @@ "ko_KR": "멀티플레이어", "no_NO": "Flerspiller", "pl_PL": "Gra Wieloosobowa", - "pt_BR": "", + "pt_BR": "Multijogador", "ru_RU": "Мультиплеер", + "sv_SE": "Flerspelare", "th_TH": "ผู้เล่นหลายคน", "tr_TR": "Çok Oyunculu", "uk_UA": "Мережева гра", @@ -20894,6 +22839,7 @@ "pl_PL": "Tryb:", "pt_BR": "Modo:", "ru_RU": "Режим:", + "sv_SE": "Läge:", "th_TH": "โหมด:", "tr_TR": "Mod:", "uk_UA": "Режим:", @@ -20917,7 +22863,8 @@ "no_NO": "Endre LDN flerspillermodus.\n\nLdnMitm vil endre lokal trådløst/lokal spillfunksjonalitet i spill som skal fungere som om den var LAN, noe som tillater lokal, samme nettverk forbindelser med andre Ryujinx instanser og hacket Nintendo Switch konsoller som har installert ldn_mitm-modulen.\n\nFlerspiller krever at alle spillerne er på samme versjon (dvs. Super Smash Bros. Ultimat v13.0.1 kan ikke koble til v13.0.0).\n\nForlat DEAKTIVERT hvis usikker.", "pl_PL": "", "pt_BR": "Alterar o modo multiplayer LDN.\n\nLdnMitm modificará a funcionalidade de jogo sem fio/local nos jogos para funcionar como se fosse LAN, permitindo conexões locais, na mesma rede, com outras instâncias do Ryujinx e consoles Nintendo Switch hackeados que possuem o módulo ldn_mitm instalado.\n\nO multiplayer exige que todos os jogadores estejam na mesma versão do jogo (ex.: Super Smash Bros. Ultimate v13.0.1 não consegue se conectar à v13.0.0).\n\nDeixe DESATIVADO se estiver em dúvida.", - "ru_RU": "Меняет многопользовательский режим LDN.\n\nLdnMitm модифицирует функциональность локальной беспроводной/игры на одном устройстве в играх, позволяя играть с другими пользователями Ryujinx или взломанными консолями Nintendo Switch с установленным модулем ldn_mitm, находящимися в одной локальной сети друг с другом.\n\nМногопользовательская игра требует наличия у всех игроков одной и той же версии игры (т.е. Super Smash Bros. Ultimate v13.0.1 не может подключиться к v13.0.0).\n\nРекомендуется оставить отключенным.", + "ru_RU": "Меняет многопользовательский режим LDN.\n\nLdnMitm модифицирует функциональность локальной беспроводной/игры на одном устройстве в играх, позволяя играть с другими пользователями Ryujinx или взломанными консолями Nintendo Switch с установленным модулем ldn_mitm, находящимися в одной локальной сети друг с другом.\n\nМногопользовательская игра требует наличия у всех игроков одной и той же версии игры (т.е. Super Smash Bros. Ultimate v13.0.1 не может подключиться к v13.0.0).\n\nРекомендуется оставить выключенным.", + "sv_SE": "Ändra LDN-flerspelarläge\n\nLdnMitm kommer att ändra lokal funktionalitet för trådlös/lokalt spel att fungera som om det vore ett LAN, vilket ger stöd för anslutningar med local och same-network med andra Ryujinx-instanser och hackade Nintendo Switch-konsoller som har modulen ldn_mitm installerad.\n\nFlerspelare kräver att alla spelare har samma spelversion (t.ex. Super Smash Bros. Ultimate v13.0.1 kan inte ansluta till v13.0.0).\n\nLämna INAKTIVERAD om du är osäker.", "th_TH": "เปลี่ยนโหมดผู้เล่นหลายคนของ LDN\n\nLdnMitm จะปรับเปลี่ยนฟังก์ชันการเล่นแบบไร้สาย/ภายใน จะให้เกมทำงานเหมือนกับว่าเป็น LAN ช่วยให้สามารถเชื่อมต่อภายในเครือข่ายเดียวกันกับอินสแตนซ์ Ryujinx อื่น ๆ และคอนโซล Nintendo Switch ที่ถูกแฮ็กซึ่งมีโมดูล ldn_mitm ติดตั้งอยู่\n\nผู้เล่นหลายคนต้องการให้ผู้เล่นทุกคนอยู่ในเกมเวอร์ชันเดียวกัน (เช่น Super Smash Bros. Ultimate v13.0.1 ไม่สามารถเชื่อมต่อกับ v13.0.0)\n\nปล่อยให้ปิดการใช้งานหากไม่แน่ใจ", "tr_TR": "", "uk_UA": "Змінити LDN мультиплеєру.\n\nLdnMitm змінить функціонал бездротової/локальної гри в іграх, щоб вони працювали так, ніби це LAN, що дозволяє локальні підключення в тій самій мережі з іншими екземплярами Ryujinx та хакнутими консолями Nintendo Switch, які мають встановлений модуль ldn_mitm.\n\nМультиплеєр вимагає, щоб усі гравці були на одній і тій же версії гри (наприклад Super Smash Bros. Ultimate v13.0.1 не зможе під'єднатися до v13.0.0).\n\nЗалиште на \"Вимкнено\", якщо не впевнені, ", @@ -20942,6 +22889,7 @@ "pl_PL": "Wyłączone", "pt_BR": "Desativado", "ru_RU": "Отключено", + "sv_SE": "Inaktiverad", "th_TH": "ปิดใช้งาน", "tr_TR": "Devre Dışı", "uk_UA": "Вимкнено", @@ -20966,6 +22914,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -20990,6 +22939,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -21012,13 +22962,14 @@ "ko_KR": "P2P 네트워크 호스팅 비활성화(대기 시간이 늘어날 수 있음)", "no_NO": "Deaktiver P2P-nettverkshosting (kan øke ventetiden)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Desabilitar hospedagem de rede P2P (pode aumentar a latência)", + "ru_RU": "Отключить хостинг P2P-сетей (может увеличить задержку)", + "sv_SE": "Inaktivera P2P-nätverkshosting (kan öka latens)", "th_TH": "", "tr_TR": "", "uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "禁用 P2P 网络连接 (也许会增加延迟)", + "zh_TW": "停用對等網路代管 (P2P Network Hosting) (可能增加網路延遲)" } }, { @@ -21036,13 +22987,14 @@ "ko_KR": "P2P 네트워크 호스팅을 비활성화하면 피어가 직접 연결하지 않고 마스터 서버를 통해 프록시합니다.", "no_NO": "Deaktiver P2P-nettverkshosting, så vil andre brukere gå via hovedserveren i stedet for å koble seg direkte til deg.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Desabilite a hospedagem de rede P2P, os pares farão proxy através do servidor mestre em vez de se conectarem a você diretamente.", + "ru_RU": "Отключая хостинг P2P-сетей, пользователи будут проксироваться через главный сервер, а не подключаться к вам напрямую.", + "sv_SE": "Inaktivera P2P-nätverkshosting, motparter kommer skickas genom masterservern isället för att ansluta direkt till dig.", "th_TH": "", "tr_TR": "", "uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "禁用 P2P 网络连接,对方将通过主服务器进行连接,而不是直接连接到您。", + "zh_TW": "停用對等網路代管 (P2P Network Hosting), 用戶群會經過代理何服器而非直接連線至你的主機。" } }, { @@ -21060,13 +23012,14 @@ "ko_KR": "네트워크 암호 문구 :", "no_NO": "Nettverkspassord:", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Senha de Rede:", + "ru_RU": "Cетевой пароль:", + "sv_SE": "Lösenfras för nätverk:", "th_TH": "", "tr_TR": "", "uk_UA": "Мережевий пароль:", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "网络密码:", + "zh_TW": "網路密碼片語 (passphrase):" } }, { @@ -21084,13 +23037,14 @@ "ko_KR": "귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.", "no_NO": "Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Você só poderá ver jogos hospedados com a mesma senha que você.", + "ru_RU": "Вы сможете видеть только те игры, в которых используется тот же пароль, что и у вас.", + "sv_SE": "Du kommer endast kunna se hostade spel med samma lösenfras som du.", "th_TH": "", "tr_TR": "", "uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "您只能看到与您使用相同密码的游戏房间。", + "zh_TW": "你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。" } }, { @@ -21108,13 +23062,14 @@ "ko_KR": "Ryujinx-<8 hex chars> 형식으로 암호를 입력하세요. 귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.", "no_NO": "Skriv inn en passordfrase i formatet Ryujinx-<8 heks tegn>. Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Insira uma frase-senha no formato Ryujinx-<8 hex chars>. Você só poderá ver jogos hospedados com a mesma frase-senha que você.", + "ru_RU": "Введите пароль в формате Ryujinx-<8 шестнадцатеричных символов>. Вы сможете видеть только те игры, в которых используется тот же пароль, что и у вас.", + "sv_SE": "Ange en lösenfras i formatet Ryujinx-<8 hextecken>. Du kommer endast kunna se hostade spel med samma lösenfras som du.", "th_TH": "", "tr_TR": "", "uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "以 Ryujinx-<8个十六进制字符> 的格式输入密码。您只能看到与您使用相同密码的游戏房间。", + "zh_TW": "以「Ryujinx-<8 個十六進制數字>」的格式輸入密碼片語 (passphrase)。你只會看到與你的密碼片語 (passphrase) 相同的遊戲房間。" } }, { @@ -21132,13 +23087,14 @@ "ko_KR": "(일반)", "no_NO": "(offentlig)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "(público)", + "ru_RU": "(публичный)", + "sv_SE": "(publik)", "th_TH": "", "tr_TR": "", "uk_UA": "(публічний)", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "(公开的)", + "zh_TW": "(公開模式)" } }, { @@ -21156,13 +23112,14 @@ "ko_KR": "무작위 생성", "no_NO": "Generer tilfeldig", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Gerar Aleatório", + "ru_RU": "Сгенерировать рандомно", + "sv_SE": "Generera slumpmässigt", "th_TH": "", "tr_TR": "", "uk_UA": "Згенерувати випадкову", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "随机生成", + "zh_TW": "隨機產生" } }, { @@ -21180,13 +23137,14 @@ "ko_KR": "다른 플레이어와 공유할 수 있는 새로운 암호 문구를 생성합니다.", "no_NO": "Genererer en ny passordfrase, som kan deles med andre spillere.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Gera uma nova senha, que pode ser compartilhada com outros jogadores.", + "ru_RU": "Генерирует новый пароль, который можно передать другим игрокам.", + "sv_SE": "Genererar en ny lösenfras som kan delas med andra spelare.", "th_TH": "", "tr_TR": "", "uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "生成一个新的密码,可以与其他玩家共享。", + "zh_TW": "產生一組新的密碼片語 (passphrase), 以供分享給其他玩家。" } }, { @@ -21204,13 +23162,14 @@ "ko_KR": "지우기", "no_NO": "Slett", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Limpar", + "ru_RU": "Очистить", + "sv_SE": "Töm", "th_TH": "", "tr_TR": "", "uk_UA": "Очистити", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "清除", + "zh_TW": "清除" } }, { @@ -21228,13 +23187,14 @@ "ko_KR": "현재 암호를 지우고 공용 네트워크로 돌아갑니다.", "no_NO": "Sletter den gjeldende passordfrasen og går tilbake til det offentlige nettverket.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Limpa a senha atual, retornando à rede pública.", + "ru_RU": "Очищает текущий пароль, возвращаясь в публичную сеть.", + "sv_SE": "Tömmer aktuell lösenfras och återgår till det publika nätverket.", "th_TH": "", "tr_TR": "", "uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "清除当前密码,返回公共网络。", + "zh_TW": "清除現有的密碼片語 (passphrase), 藉此公開網路連線。" } }, { @@ -21252,13 +23212,14 @@ "ko_KR": "유효하지 않은 암호입니다! \"Ryujinx-<8 hex chars>\" 형식이어야 합니다.", "no_NO": "Ugyldig passordfrase! Må være i formatet \"Ryujinx-<8 hex tegn>\"", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Frase-senha inválida! Deve estar no formato \"Ryujinx-<8 hex chars>\"", + "ru_RU": "Неверный пароль! Пароль должен быть в формате «Ryujinx-<8 шестнадцатеричных символов>»", + "sv_SE": "Ogiltig lösenfras! Måste vara i formatet \"Ryujinx-<8 hextecken>\"", "th_TH": "", "tr_TR": "", "uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "无效密码!密码的格式必须是\"Ryujinx-<8个十六进制字符>\"", + "zh_TW": "無效的密碼片語 (passphrase)! 密碼片語必須是以「Ryujinx-<8 個十六進制數字>」的格式輸入" } }, { @@ -21277,12 +23238,13 @@ "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "", + "ru_RU": "Вертикальная синхронизация:", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "Вертикальна синхронізація (VSync):", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "垂直同步(VSync)", + "zh_TW": "垂直同步:" } }, { @@ -21295,18 +23257,19 @@ "es_ES": "", "fr_FR": "Activer le taux de rafraîchissement customisé (Expérimental)", "he_IL": "", - "it_IT": "", + "it_IT": "Attiva la frequenza di aggiornamento personalizzata (sperimentale)", "ja_JP": "", "ko_KR": "사용자 정의 주사율 활성화(실험적)", "no_NO": "Aktiver egendefinert oppdateringsfrekvens (eksperimentell)", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Habilitar taxa de atualização personalizada (Experimental)", + "ru_RU": "Включить пользовательскую частоту кадров (Экспериментально)", + "sv_SE": "Aktivera anpassad uppdateringsfrekvens (experimentell)", "th_TH": "", "tr_TR": "", "uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "启动自定义刷新率(实验性功能)", + "zh_TW": "啟用自訂的重新整理頻率 (實驗性功能)" } }, { @@ -21317,7 +23280,7 @@ "el_GR": "", "en_US": "Switch", "es_ES": "", - "fr_FR": "Switch", + "fr_FR": "", "he_IL": "", "it_IT": "", "ja_JP": "", @@ -21325,7 +23288,8 @@ "no_NO": "", "pl_PL": "", "pt_BR": "", - "ru_RU": "", + "ru_RU": "Консоль", + "sv_SE": "", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -21343,18 +23307,19 @@ "es_ES": "", "fr_FR": "Sans Limite", "he_IL": "", - "it_IT": "", + "it_IT": "Nessun limite", "ja_JP": "", "ko_KR": "무제한", "no_NO": "Ubegrenset", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Ilimitado", + "ru_RU": "Без ограничений", + "sv_SE": "Obunden", "th_TH": "", "tr_TR": "", "uk_UA": "Безмежна", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "无限制", + "zh_TW": "沒有限制" } }, { @@ -21367,186 +23332,194 @@ "es_ES": "", "fr_FR": "Taux de Rafraîchissement Customisé", "he_IL": "", - "it_IT": "", + "it_IT": "Frequenza di aggiornamento personalizzata", "ja_JP": "", "ko_KR": "사용자 정의 주사율", "no_NO": "Egendefinert oppdateringsfrekvens", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Taxa de Atualização Personalizada", + "ru_RU": "Пользовательская частота кадров", + "sv_SE": "Anpassad uppdateringsfrekvens", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "自定义刷新率", + "zh_TW": "自訂的重新整理頻率" } }, { "ID": "SettingsTabSystemVSyncModeTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. \"Unbounded\" ist eine unbegrenzte Bildwiederholfrequenz.", "el_GR": "", "en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate.", "es_ES": "", "fr_FR": "VSync émulé. 'Switch' émule le taux de rafraîchissement de la Switch (60Hz). 'Sans Limite' est un taux de rafraîchissement qui n'est pas limité.", "he_IL": "", - "it_IT": "", + "it_IT": "Sincronizzazione verticale emulata. \"Switch\" emula la frequenza di aggiornamento di Nintendo Switch (60Hz). \"Nessun limite\" non impone alcun limite alla frequenza di aggiornamento.", "ja_JP": "", "ko_KR": "에뮬레이트된 수직 동기화. '스위치'는 스위치의 60Hz 주사율을 에뮬레이트합니다. '무한'은 무제한 주사율입니다.", "no_NO": "Emulert vertikal synkronisering. «Switch» emulerer Switchs oppdateringsfrekvens på 60 Hz. «Ubegrenset» er en ubegrenset oppdateringsfrekvens.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Sincronização vertical emulada. 'Switch' emula a taxa de atualização de 60 Hz do Switch. 'Ilimitada' é uma taxa de atualização sem limite.", + "ru_RU": "Эмулированная вертикальная синхронизация. «Консоль» эмулирует частоту обновления консоли, равную 60 Гц. «Без ограничений» — неограниченная частота кадров.", + "sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens.", "th_TH": "", "tr_TR": "", - "uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень.", + "zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。", + "zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。" } }, { "ID": "SettingsTabSystemVSyncModeTooltipCustom", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. „Unbounded“ ist eine unbegrenzte Bildwiederholfrequenz. „Benutzerdefinierte Bildwiederholfrequenz“ emuliert die angegebene benutzerdefinierte Bildwiederholfrequenz.", "el_GR": "", "en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate. 'Custom Refresh Rate' emulates the specified custom refresh rate.", "es_ES": "", "fr_FR": "VSync émulé. 'Switch' émule le taux de rafraîchissement de la Switch (60Hz). 'Sans Limite' est un taux de rafraîchissement qui n'est pas limité. 'Taux de Rafraîchissement Customisé' émule le taux de rafraîchissement spécifié.", "he_IL": "", - "it_IT": "", + "it_IT": "Sincronizzazione verticale emulata. \"Switch\" emula la frequenza di aggiornamento di Nintendo Switch (60Hz). \"Nessun limite\" non impone alcun limite alla frequenza di aggiornamento. \"Frequenza di aggiornamento personalizzata\" emula la frequenza di aggiornamento specificata.", "ja_JP": "", "ko_KR": "에뮬레이트된 수직 동기화. '스위치'는 스위치의 60Hz 주사율을 에뮬레이트합니다. '무한'은 무제한 주사율입니다. '사용자 지정'은 지정된 사용자 지정 주사율을 에뮬레이트합니다.", "no_NO": "Emulert vertikal synkronisering. «Switch» emulerer Switchs oppdateringsfrekvens på 60 Hz. «Ubegrenset» er en ubegrenset oppdateringsfrekvens. «Egendefinert» emulerer den angitte egendefinerte oppdateringsfrekvensen.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Sincronização Vertical Emulada. 'Switch' emula a taxa de atualização de 60 Hz do Switch. 'Ilimitada' é uma taxa de atualização sem limite. 'Taxa de atualização personalizada' emula a taxa de atualização personalizada especificada.", + "ru_RU": "Эмулированная вертикальная синхронизация. «Консоль» эмулирует частоту обновления консоли, равную 60 Гц. «Без ограничений» — неограниченная частота кадров. «Пользовательска частота кадров» эмулирует выбранную пользователем частоту кадров.", + "sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens. 'Anpassad uppdateringsfrekvens' emulerar den angivna anpassade uppdateringsfrekvensen.", "th_TH": "", "tr_TR": "", - "uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.", + "zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。", + "zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。" } }, { "ID": "SettingsTabSystemEnableCustomVSyncIntervalTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Ermöglicht es dem Benutzer, eine emulierte Bildwiederholfrequenz festzulegen. In einigen Titeln kann dies die Geschwindigkeit der Spiel-Logik erhöhen oder verringern. In anderen Titeln kann dies dazu führen, dass die FPS auf ein Vielfaches der Bildwiederholfrequenz begrenzt werden oder zu unvorhersehbarem Verhalten führen. Dies ist eine experimentelle Funktion, ohne Garantien dafür, wie sich das Gameplay auswirkt. \n\nLassen Sie diese Option deaktiviert, wenn Sie sich nicht sicher sind.", "el_GR": "", "en_US": "Allows the user to specify an emulated refresh rate. In some titles, this may speed up or slow down the rate of gameplay logic. In other titles, it may allow for capping FPS at some multiple of the refresh rate, or lead to unpredictable behavior. This is an experimental feature, with no guarantees for how gameplay will be affected. \n\nLeave OFF if unsure.", "es_ES": "", "fr_FR": "Permet à l'utilisateur de spécifier un taux de rafraîchissement émulé. Dans certains jeux, ceci pourrait accélérer ou ralentir le taux de logique du gameplay. Dans d'autre titres, cela permettrait limiter le FPS à un multiple du taux de rafraîchissement, ou conduire à un comportement imprévisible. Ceci est une fonctionnalité expérimentale, avec aucune garanties pour comment le gameplay sera affecté. \n\nLaisser désactiver en cas de doute.", "he_IL": "", - "it_IT": "", + "it_IT": "Consente all'utente di specificare una frequenza di aggiornamento emulata. In alcuni titoli potrebbe aumentare o diminuire la velocità del gameplay, mentre in altri potrebbe consentire di limitare il framerate a un multiplo della frequenza di aggiornamento, o causare comportamenti imprevedibili. Questa funzionalità è sperimentale, e non ci sono certezze sul modo in cui influenzerà il gameplay.\n\nNel dubbio, lascia l'opzione disattivata.", "ja_JP": "", "ko_KR": "사용자가 에뮬레이트된 화면 주사율을 지정할 수 있습니다. 일부 타이틀에서는 게임플레이 로직 속도가 빨라지거나 느려질 수 있습니다. 다른 타이틀에서는 주사율의 배수로 FPS를 제한하거나 예측할 수 없는 동작으로 이어질 수 있습니다. 이는 실험적 기능으로 게임 플레이에 어떤 영향을 미칠지 보장할 수 없습니다. \n\n모르면 끔으로 두세요.", "no_NO": "Gjør det mulig for brukeren å angi en emulert oppdateringsfrekvens. I noen titler kan dette øke eller senke hastigheten på spillogikken. I andre titler kan det gjøre det mulig å begrense FPS til et multiplum av oppdateringsfrekvensen, eller føre til uforutsigbar oppførsel. Dette er en eksperimentell funksjon, og det gis ingen garantier for hvordan spillingen påvirkes. \n\nLa AV stå hvis du er usikker.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Permite que o usuário especifique uma taxa de atualização emulada. Em alguns títulos, isso pode acelerar ou desacelerar a taxa de lógica do jogo. Em outros títulos, pode permitir limitar o FPS em algum múltiplo da taxa de atualização ou levar a um comportamento imprevisível. Este é um recurso experimental, sem garantias de como o jogo será afetado. \n\nDeixe OFF se não tiver certeza.", + "ru_RU": "Позволяет пользователю указать эмулируемую частоту кадров. В некоторых играх это может ускорить или замедлить скорость логики игрового процесса. В других играх это может позволить ограничить FPS на уровне, кратном частоте обновления, или привести к непредсказуемому поведению. Это экспериментальная функция, и нет никаких гарантий того, как она повлияет на игровой процесс. \n\nОставьте выключенным, если не уверены.", + "sv_SE": "Låter användaren ange en emulerad uppdateringsfrekvens. För vissa spel så kan detta snabba upp eller ner frekvensen för spellogiken. I andra spel så kan detta tillåta att bildfrekvensen kapas för delar av uppdateringsfrekvensen eller leda till oväntat beteende. Detta är en experimentell funktion utan några garantier för hur spelet påverkas. \n\nLämna AV om du är osäker.", "th_TH": "", "tr_TR": "", - "uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. Натомість в інших іграх ця функція може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як вона вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.", + "zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将 FPS 限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。", + "zh_TW": "容許使用者自訂模擬的重新整理頻率。你可能會在某些遊戲裡感受到加快或減慢的遊戲速度;其他遊戲裡則可能會容許限制最高的 FPS 至重新整理頻率的倍數,或引起未知遊戲行為。這是實驗性功能,且沒有保證遊戲會穩定執行。\n\n如果不確定,請保持關閉狀態。" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalValueTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Der Zielwert für die benutzerdefinierte Bildwiederholfrequenz.", "el_GR": "", "en_US": "The custom refresh rate target value.", "es_ES": "", "fr_FR": "La valeur cible du taux de rafraîchissement customisé.", "he_IL": "", - "it_IT": "", + "it_IT": "Il valore desiderato della frequenza di aggiornamento personalizzata.", "ja_JP": "", "ko_KR": "사용자 정의 주사율 목표 값입니다.", "no_NO": "Den egendefinerte målverdien for oppdateringsfrekvens.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "O valor de meta da taxa de atualização personalizada.", + "ru_RU": "Заданное значение частоты кадров", + "sv_SE": "Målvärde för anpassad uppdateringsfrekvens.", "th_TH": "", "tr_TR": "", "uk_UA": "Цільове значення користувацької частоти оновлення.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "目标自定义刷新率值。", + "zh_TW": "自訂的重新整理頻率數值。" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalSliderTooltip", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Die benutzerdefinierte Bildwiederholfrequenz als Prozentsatz der normalen Switch-Bildwiederholfrequenz.", "el_GR": "", "en_US": "The custom refresh rate, as a percentage of the normal Switch refresh rate.", "es_ES": "", "fr_FR": "Le taux de rafraîchissement customisé, comme un pourcentage du taux de rafraîchissement normal de la Switch.", "he_IL": "", - "it_IT": "", + "it_IT": "La frequenza di aggiornamento personalizzata, espressa in percentuale della normale frequenza di aggiornamento di Switch.", "ja_JP": "", "ko_KR": "일반 스위치 주사율의 백분율로 나타낸 사용자 지정 주사율입니다.", "no_NO": "Den egendefinerte oppdateringsfrekvensen, i prosent av den normale oppdateringsfrekvensen for Switch-konsollen.", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "A taxa de atualização personalizada, como uma porcentagem da taxa de atualização normal do Switch.", + "ru_RU": "Пользовательская частота кадров в процентах от обычной частоты обновления на консоли.", + "sv_SE": "Anpassad uppdateringsfrekvens, som en procentdel av den normala uppdateringsfrekvensen för Switch.", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "自定义刷新率,占正常SWitch刷新率的百分比值。", + "zh_TW": "以 Nintendo Switch 重新整理頻率的百分比自訂重新整理頻率。" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalPercentage", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Benutzerdefinierte Bildwiederholfrequenz %:", "el_GR": "", "en_US": "Custom Refresh Rate %:", "es_ES": "", "fr_FR": "Pourcentage du Taux de Rafraîchissement Customisé :", "he_IL": "", - "it_IT": "", + "it_IT": "Frequenza di aggiornamento personalizzata (%):", "ja_JP": "", "ko_KR": "사용자 정의 주사율 % :", "no_NO": "Egendefinert oppdateringsfrekvens %:", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Taxa de Atualização Personalizada %:", + "ru_RU": "Пользовательская частота кадров %:", + "sv_SE": "Anpassad uppdateringsfrekvens %:", "th_TH": "", "tr_TR": "", "uk_UA": "Користувацька частота оновлення %:", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "自定义刷新率值 %:", + "zh_TW": "自訂重新整理頻率 %:" } }, { "ID": "SettingsTabSystemCustomVSyncIntervalValue", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Wert für benutzerdefinierte Bildwiederholfrequenz:", "el_GR": "", "en_US": "Custom Refresh Rate Value:", "es_ES": "", "fr_FR": "Valeur du Taux de Rafraîchissement Customisé :", "he_IL": "", - "it_IT": "", + "it_IT": "Valore della frequenza di aggiornamento personalizzata:", "ja_JP": "", "ko_KR": "사용자 정의 주사율 값 :", "no_NO": "Egendefinert verdi for oppdateringsfrekvens:", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Valor da Taxa de Atualização Personalizada:", + "ru_RU": "Значение пользовательской частоты кадров:", + "sv_SE": "Värde för anpassad uppdateringsfrekvens:", "th_TH": "", "tr_TR": "", - "uk_UA": "Значення користувацька частота оновлення:", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Значення користувацької частоти оновлення:", + "zh_CN": "自定义刷新率值:", + "zh_TW": "自訂重新整理頻率數值:" } }, { @@ -21559,89 +23532,543 @@ "es_ES": "", "fr_FR": "Intervalle", "he_IL": "", - "it_IT": "", + "it_IT": "Intervallo", "ja_JP": "", "ko_KR": "간격", "no_NO": "Intervall", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Intervalo", + "ru_RU": "Интервал", + "sv_SE": "Intervall", "th_TH": "", "tr_TR": "", - "uk_UA": "", - "zh_CN": "", - "zh_TW": "" + "uk_UA": "Інтервал", + "zh_CN": "间隔", + "zh_TW": "間隔" } }, { "ID": "SettingsTabHotkeysToggleVSyncModeHotkey", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "VSync-Modus umschalten:", "el_GR": "", "en_US": "Toggle VSync mode:", "es_ES": "", "fr_FR": "Activer/Désactiver mode VSync :", "he_IL": "", - "it_IT": "", + "it_IT": "Cambia modalità VSync:", "ja_JP": "", "ko_KR": "수직 동기화 모드 전환 :", "no_NO": "Veksle mellom VSync-modus:", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Alternar Modo VSync:", + "ru_RU": "Выбрать режим вертикальной синхронизации:", + "sv_SE": "Växla VSync-läge:", "th_TH": "", "tr_TR": "", "uk_UA": "Перемкнути VSync режим:", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "设置 VSync 模式:", + "zh_TW": "切換 VSync 模式:" } }, { "ID": "SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Benutzerdefinierte Bildwiederholfrequenz erhöhen:", "el_GR": "", "en_US": "Raise custom refresh rate", "es_ES": "", "fr_FR": "Augmenter le taux de rafraîchissement customisé :", "he_IL": "", - "it_IT": "", + "it_IT": "Aumenta la frequenza di aggiornamento personalizzata:", "ja_JP": "", "ko_KR": "사용자 정의 주사율 증가", "no_NO": "Øk den egendefinerte oppdateringsfrekvensen", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Aumentar Taxa de Atualização:", + "ru_RU": "Повышение пользовательской частоты кадров", + "sv_SE": "Höj anpassad uppdateringsfrekvens", "th_TH": "", "tr_TR": "", "uk_UA": "Підвищити користувацьку частоту оновлення", - "zh_CN": "", - "zh_TW": "" + "zh_CN": "提高自定义刷新率:", + "zh_TW": "提高自訂的重新整理頻率" } }, { "ID": "SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey", "Translations": { "ar_SA": "", - "de_DE": "", + "de_DE": "Benutzerdefinierte Bildwiederholfrequenz senken:", "el_GR": "", "en_US": "Lower custom refresh rate:", "es_ES": "", "fr_FR": "Baisser le taux de rafraîchissement customisé :", "he_IL": "", - "it_IT": "", + "it_IT": "Riduci la frequenza di aggiornamento personalizzata:", "ja_JP": "", "ko_KR": "사용자 정의 주사율 감소", "no_NO": "Lavere tilpasset oppdateringsfrekvens", "pl_PL": "", - "pt_BR": "", - "ru_RU": "", + "pt_BR": "Reduzir Taxa de Atualização:", + "ru_RU": "Понижение пользовательской частоты кадров", + "sv_SE": "Sänk anpassad uppdateringsfrekvens", "th_TH": "", "tr_TR": "", "uk_UA": "Понизити користувацьку частоту оновлення", - "zh_CN": "", + "zh_CN": "降低自定义刷新率:", + "zh_TW": "降低自訂的重新整理頻率" + } + }, + { + "ID": "CompatibilityListLastUpdated", + "Translations": { + "ar_SA": "", + "de_DE": "Zuletzt aktualisiert: {0}", + "el_GR": "", + "en_US": "Last updated: {0}", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "최종 업데이트 : {0}", + "no_NO": "Sist oppdatert: {0}", + "pl_PL": "", + "pt_BR": "Última atualização: {0}", + "ru_RU": "Последнее обновление: {0}", + "sv_SE": "Senast uppdaterad: {0}", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Останнє оновлення: {0}", + "zh_CN": "最后更新于: {0}", + "zh_TW": "上次更新時間: {0}" + } + }, + { + "ID": "CompatibilityListWarning", + "Translations": { + "ar_SA": "", + "de_DE": "Diese Kompatibilitätsliste könnte veraltete Einträge enthalten. Teste dennoch Spiele im \"Ingame\"-Status.", + "el_GR": "", + "en_US": "This compatibility list might contain out of date entries.\nDo not be opposed to testing games in the \"Ingame\" status.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "이 호환성 목록에는 오래된 항목이 포함되어 있을 수 있습니다.\n\"게임 내\" 상태에서 게임을 테스트하는 것을 반대하지 마십시오.", + "no_NO": "Denne kompatibilitetslisten kan inneholde oppføringer som er tomme for data.\nVær ikke imot å teste spill i statusen «Ingame».", + "pl_PL": "", + "pt_BR": "Esta lista de compatibilidade pode estar desatualizada.\nNão se oponha a testar os jogos", + "ru_RU": "В списке совместимости могут содержаться устаревшие записи.\nНе стестняйтесь тестировать игр в статусе «Запускается»", + "sv_SE": "Denna kompatibilitetslista kan innehålla utdaterade poster.\nTesta gärna spelen som listas med \"Spelproblem\"-status.", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Цей список сумісності може містити застарілі дані.\nНе відмовляйтеся від тестування ігор що мають статус \"Запускаються\".", + "zh_CN": "此兼容性列表可能包含过时的条目。\n不要只测试 \"进入游戏\" 状态的游戏。", + "zh_TW": "這個相容性列表可能含有已過時的紀錄。\n敬請繼續測試「大致可遊玩 (Ingame)」狀態的遊戲並回報以更新紀錄。" + } + }, + { + "ID": "CompatibilityListSearchBoxWatermark", + "Translations": { + "ar_SA": "", + "de_DE": "Kompatibilitätseinträge durchsuchen...", + "el_GR": "", + "en_US": "Search compatibility entries...", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "호환성 항목 검색...", + "no_NO": "Søk i kompatibilitetsoppføringer...", + "pl_PL": "", + "pt_BR": "Pesquisa de compatibilidade", + "ru_RU": "Поиск записей о совместимости...", + "sv_SE": "Sök i kompatibilitetsposter...", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Перевірити сумісність гри...", + "zh_CN": "正在搜索兼容性条目...", + "zh_TW": "搜尋相容性列表紀錄..." + } + }, + { + "ID": "CompatibilityListOpen", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Open Compatibility List", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "호환성 목록 열기", + "no_NO": "Åpne kompatibilitetslisten", + "pl_PL": "", + "pt_BR": "Lista de Compatibilidade", + "ru_RU": "Открыть список совместимости", + "sv_SE": "Öppna kompatibilitetslistan", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Відкрити Список Сумісності", + "zh_CN": "打开兼容性列表", + "zh_TW": "開啟相容性列表" + } + }, + { + "ID": "CompatibilityListOnlyShowOwnedGames", + "Translations": { + "ar_SA": "", + "de_DE": "Nur eigene Spiele anzeigen", + "el_GR": "", + "en_US": "Only show owned games", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "보유 게임만 표시", + "no_NO": "Vis bare eide spill", + "pl_PL": "", + "pt_BR": "Mostrar apenas jogos disponíveis", + "ru_RU": "Показывать только свои игры", + "sv_SE": "Visa endast ägda spel", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Показувати лише ігри в наявності", + "zh_CN": "仅显示拥有的游戏", + "zh_TW": "只顯示已擁有的遊戲" + } + }, + { + "ID": "CompatibilityListPlayable", + "Translations": { + "ar_SA": "", + "de_DE": "Spielbar", + "el_GR": "", + "en_US": "Playable", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "플레이 가능", + "no_NO": "Spillbar", + "pl_PL": "", + "pt_BR": "Jogável", + "ru_RU": "Играбельно", + "sv_SE": "Spelbart", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Оптимально", + "zh_CN": "可游玩", + "zh_TW": "可暢順遊玩" + } + }, + { + "ID": "CompatibilityListIngame", + "Translations": { + "ar_SA": "", + "de_DE": "Im Spiel", + "el_GR": "", + "en_US": "Ingame", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "게임 내", + "no_NO": "", + "pl_PL": "", + "pt_BR": "No jogo", + "ru_RU": "Запускается", + "sv_SE": "Spelproblem", + "th_TH": "", + "tr_TR": "", + "uk_UA": "З недоліками", + "zh_CN": "进入游戏", + "zh_TW": "大致可遊玩" + } + }, + { + "ID": "CompatibilityListMenus", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Menus", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "메뉴", + "no_NO": "Menyer", + "pl_PL": "", + "pt_BR": "Menu", + "ru_RU": "Меню", + "sv_SE": "Menyer", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Меню", + "zh_CN": "菜单", + "zh_TW": "只開啟至遊戲開始功能表" + } + }, + { + "ID": "CompatibilityListBoots", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Boots", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "부츠", + "no_NO": "Starter", + "pl_PL": "", + "pt_BR": "Inicializa", + "ru_RU": "Стартует", + "sv_SE": "Startar", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускається", + "zh_CN": "启动", + "zh_TW": "只能啟動" + } + }, + { + "ID": "CompatibilityListNothing", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Nothing", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "없음", + "no_NO": "Ingenting", + "pl_PL": "", + "pt_BR": "Nada", + "ru_RU": "Ничего", + "sv_SE": "Ingenting", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Не працює", + "zh_CN": "什么都没有", + "zh_TW": "無法啟動" + } + }, + { + "ID": "CompatibilityListPlayableTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Boots and plays without any crashes or GPU bugs of any kind, and at a speed fast enough to reasonably enjoy on an average PC.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.", + "pl_PL": "", + "pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.", + "ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.", + "zh_CN": "启动和游戏时不会出现任何崩溃或任何类型的 GPU bug 且速度足够快可以在一般 PC 上尽情游玩。", + "zh_TW": "" + } + }, + { + "ID": "CompatibilityListIngameTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Boots and goes in-game but suffers from one or more of the following: crashes, deadlocks, GPU bugs, distractingly bad audio, or is simply too slow. Game still might able to be played all the way through, but not as the game is intended to play.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.", + "pl_PL": "", + "pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.", + "ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.", + "zh_CN": "可以成功启动并进入游戏但可能会遇到以下一种或多种问题: 崩溃、卡死、GPU bug、令人无法接受的音频,或者只是太慢。仍然可以继续进行游戏,但是可能无法达到预期。", + "zh_TW": "" + } + }, + { + "ID": "CompatibilityListMenusTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Boots and goes past the title screen but does not make it into main gameplay.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Starter opp og går forbi tittelskjermen, men kommer ikke inn i hovedspillet.", + "pl_PL": "", + "pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.", + "ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.", + "zh_CN": "可以启动并通过标题画面但是无法进入到主要的游戏流程。", + "zh_TW": "" + } + }, + { + "ID": "CompatibilityListBootsTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "Startet, kommt aber nicht über den Titelbildschirm hinaus.", + "el_GR": "", + "en_US": "Boots but does not make it past the title screen.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Starter, men kommer ikke lenger enn til tittelskjermen.", + "pl_PL": "", + "pt_BR": "Inizializa, mas não passa da tela de título.", + "ru_RU": "Загружается, но не проходит дальше титульного экрана.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Запускається, але не відображає навіть початкового екрану.", + "zh_CN": "可以启动但是无法通过标题画面。", + "zh_TW": "" + } + }, + { + "ID": "CompatibilityListNothingTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "Startet nicht oder zeigt keine Anzeichen von Aktivität.", + "el_GR": "", + "en_US": "Does not boot or shows no signs of activity.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.", + "pl_PL": "", + "pt_BR": "Não inicializa ou não mostra sinais de atividade.", + "ru_RU": "Не запускается или не подаёт признаков жизни.", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Взагалі не запускається.", + "zh_CN": "无法启动或显示无任何动静。", + "zh_TW": "" + } + }, + { + "ID": "ExtractAocListHeader", + "Translations": { + "ar_SA": "", + "de_DE": "Wähle ein DLC zum Extrahieren aus", + "el_GR": "", + "en_US": "Select a DLC to Extract", + "es_ES": "", + "fr_FR": "Choisissez un DLC à extraire", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "추출할 DLC 선택", + "no_NO": "Velg en DLC og hente ut", + "pl_PL": "", + "pt_BR": "Selecione um DLC para Extrair", + "ru_RU": "Выберите DLC для извлечения", + "sv_SE": "Välj en DLC att extrahera", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Оберіть DLC які бажаєте вилучити", + "zh_CN": "选择一个要解压的 DLC", + "zh_TW": "" + } + }, + { + "ID": "GameInfoRpcImage", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Rich Presence Image", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Rikt nærværsbilde", + "pl_PL": "", + "pt_BR": "Imagem da Presença do Discord", + "ru_RU": "Изображение для статуса активности", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Зображення картки активності Discord", + "zh_CN": "Rich Presence 图像", + "zh_TW": "" + } + }, + { + "ID": "GameInfoRpcDynamic", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Dynamic Rich Presence", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "Dynamisk og rik tilstedeværelse", + "pl_PL": "", + "pt_BR": "Presença Dinâmica do Discord", + "ru_RU": "Динамический статус активности", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "Динамічна картка активності Discord", + "zh_CN": "动态 Rich Presence", "zh_TW": "" } } diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs index aa8238fc6..3ebfee751 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs @@ -12,7 +12,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; -using Ryujinx.Graphics.Metal; using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; @@ -310,11 +309,6 @@ namespace Ryujinx.Headless preferredGpuId); } - if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS()) - { - return new MetalRenderer(metalWindow.GetLayer); - } - return new OpenGLRenderer(); } diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.cs b/src/Ryujinx/Headless/HeadlessRyujinx.cs index 12158176a..9a69c56dd 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.cs @@ -1,13 +1,11 @@ using CommandLine; using Gommon; -using LibHac.Tools.FsSystem; -using Ryujinx.Audio.Backends.SDL2; +using Ryujinx.Ava; +using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; -using Ryujinx.Common.Configuration.Hid.Controller.Motion; -using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; using Ryujinx.Common.Logging.Targets; @@ -15,14 +13,9 @@ using Ryujinx.Common.SystemInterop; using Ryujinx.Common.Utilities; using Ryujinx.Cpu; using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu.Shader; -using Ryujinx.Graphics.OpenGL; -using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan.MoltenVK; -using Ryujinx.Headless.SDL2.OpenGL; -using Ryujinx.Headless.SDL2.Vulkan; using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; @@ -31,22 +24,16 @@ using Ryujinx.Input; using Ryujinx.Input.HLE; using Ryujinx.Input.SDL2; using Ryujinx.SDL2.Common; -using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.IO; -using System.Text.Json; +using System.Linq; using System.Threading; -using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId; -using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; -using Key = Ryujinx.Common.Configuration.Hid.Key; -namespace Ryujinx.Headless.SDL2 +namespace Ryujinx.Headless { - class Program + public partial class HeadlessRyujinx { - public static string Version { get; private set; } - private static VirtualFileSystem _virtualFileSystem; private static ContentManager _contentManager; private static AccountManager _accountManager; @@ -56,20 +43,18 @@ namespace Ryujinx.Headless.SDL2 private static Switch _emulationContext; private static WindowBase _window; private static WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution; - private static List _inputConfiguration; + private static List _inputConfiguration = []; private static bool _enableKeyboard; private static bool _enableMouse; private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - static void Main(string[] args) + public static void Entrypoint(string[] args) { - Version = ReleaseInformation.Version; - // Make process DPI aware for proper window sizing on high-res screens. ForceDpiAware.Windows(); - Console.Title = $"Ryujinx Console {Version} (Headless SDL2)"; + Console.Title = $"HeadlessRyujinx Console {Program.Version}"; if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) { @@ -97,7 +82,7 @@ namespace Ryujinx.Headless.SDL2 } Parser.Default.ParseArguments(args) - .WithParsed(Load) + .WithParsed(options => Load(args, options)) .WithNotParsed(errors => { Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:"); @@ -105,239 +90,86 @@ namespace Ryujinx.Headless.SDL2 errors.ForEach(err => Logger.Error?.PrintMsg(LogClass.Application, $" - {err.Tag}")); }); } - - private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) + + public static void ReloadConfig(string customConfigPath = null) { - if (inputId == null) + string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); + string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); + + string configurationPath = null; + + // Now load the configuration as the other subsystems are now registered + if (customConfigPath != null && File.Exists(customConfigPath)) { - if (index == PlayerIndex.Player1) - { - Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard."); - - // Default to keyboard - inputId = "0"; - } - else - { - Logger.Info?.Print(LogClass.Application, $"{index} not configured"); - - return null; - } + configurationPath = customConfigPath; + } + else if (File.Exists(localConfigurationPath)) + { + configurationPath = localConfigurationPath; + } + else if (File.Exists(appDataConfigurationPath)) + { + configurationPath = appDataConfigurationPath; } - IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId); - - bool isKeyboard = true; - - if (gamepad == null) + if (configurationPath == null) { - gamepad = _inputManager.GamepadDriver.GetGamepad(inputId); - isKeyboard = false; + // No configuration, we load the default values and save it to disk + configurationPath = appDataConfigurationPath; + Logger.Notice.Print(LogClass.Application, $"No configuration file found. Saving default configuration to: {configurationPath}"); - if (gamepad == null) - { - Logger.Error?.Print(LogClass.Application, $"{index} gamepad not found (\"{inputId}\")"); - - return null; - } - } - - string gamepadName = gamepad.Name; - - gamepad.Dispose(); - - InputConfig config; - - if (inputProfileName == null || inputProfileName.Equals("default")) - { - if (isKeyboard) - { - config = new StandardKeyboardInputConfig - { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.WindowKeyboard, - Id = null, - ControllerType = ControllerType.JoyconPair, - LeftJoycon = new LeftJoyconCommonConfig - { - DpadUp = Key.Up, - DpadDown = Key.Down, - DpadLeft = Key.Left, - DpadRight = Key.Right, - ButtonMinus = Key.Minus, - ButtonL = Key.E, - ButtonZl = Key.Q, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound, - }, - - LeftJoyconStick = new JoyconConfigKeyboardStick - { - StickUp = Key.W, - StickDown = Key.S, - StickLeft = Key.A, - StickRight = Key.D, - StickButton = Key.F, - }, - - RightJoycon = new RightJoyconCommonConfig - { - ButtonA = Key.Z, - ButtonB = Key.X, - ButtonX = Key.C, - ButtonY = Key.V, - ButtonPlus = Key.Plus, - ButtonR = Key.U, - ButtonZr = Key.O, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound, - }, - - RightJoyconStick = new JoyconConfigKeyboardStick - { - StickUp = Key.I, - StickDown = Key.K, - StickLeft = Key.J, - StickRight = Key.L, - StickButton = Key.H, - }, - }; - } - else - { - bool isNintendoStyle = gamepadName.Contains("Nintendo"); - - config = new StandardControllerInputConfig - { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.GamepadSDL2, - Id = null, - ControllerType = ControllerType.JoyconPair, - DeadzoneLeft = 0.1f, - DeadzoneRight = 0.1f, - RangeLeft = 1.0f, - RangeRight = 1.0f, - TriggerThreshold = 0.5f, - LeftJoycon = new LeftJoyconCommonConfig - { - DpadUp = ConfigGamepadInputId.DpadUp, - DpadDown = ConfigGamepadInputId.DpadDown, - DpadLeft = ConfigGamepadInputId.DpadLeft, - DpadRight = ConfigGamepadInputId.DpadRight, - ButtonMinus = ConfigGamepadInputId.Minus, - ButtonL = ConfigGamepadInputId.LeftShoulder, - ButtonZl = ConfigGamepadInputId.LeftTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, - }, - - LeftJoyconStick = new JoyconConfigControllerStick - { - Joystick = ConfigStickInputId.Left, - StickButton = ConfigGamepadInputId.LeftStick, - InvertStickX = false, - InvertStickY = false, - Rotate90CW = false, - }, - - RightJoycon = new RightJoyconCommonConfig - { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, - ButtonPlus = ConfigGamepadInputId.Plus, - ButtonR = ConfigGamepadInputId.RightShoulder, - ButtonZr = ConfigGamepadInputId.RightTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, - }, - - RightJoyconStick = new JoyconConfigControllerStick - { - Joystick = ConfigStickInputId.Right, - StickButton = ConfigGamepadInputId.RightStick, - InvertStickX = false, - InvertStickY = false, - Rotate90CW = false, - }, - - Motion = new StandardMotionConfigController - { - MotionBackend = MotionInputBackendType.GamepadDriver, - EnableMotion = true, - Sensitivity = 100, - GyroDeadzone = 1, - }, - Rumble = new RumbleConfigController - { - StrongRumble = 1f, - WeakRumble = 1f, - EnableRumble = false, - }, - }; - } + ConfigurationState.Instance.LoadDefault(); + ConfigurationState.Instance.ToFileFormat().SaveConfig(configurationPath); } else { - string profileBasePath; + Logger.Notice.Print(LogClass.Application, $"Loading configuration from: {configurationPath}"); - if (isKeyboard) + if (ConfigurationFileFormat.TryLoad(configurationPath, out ConfigurationFileFormat configurationFileFormat)) { - profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "keyboard"); + ConfigurationState.Instance.Load(configurationFileFormat, configurationPath); } else { - profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "controller"); - } + Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location: {configurationPath}"); - string path = Path.Combine(profileBasePath, inputProfileName + ".json"); - - if (!File.Exists(path)) - { - Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" not found for \"{inputId}\""); - - return null; - } - - try - { - config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig); - } - catch (JsonException) - { - Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" parsing failed for \"{inputId}\""); - - return null; + ConfigurationState.Instance.LoadDefault(); } } - - config.Id = inputId; - config.PlayerIndex = index; - - string inputTypeName = isKeyboard ? "Keyboard" : "Gamepad"; - - Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\""); - - // If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0. - if (config is StandardControllerInputConfig controllerConfig) - { - if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f) - { - controllerConfig.RangeLeft = 1.0f; - controllerConfig.RangeRight = 1.0f; - - Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration"); - } - } - - return config; } - static void Load(Options option) + static void Load(string[] originalArgs, Options option) { - AppDataManager.Initialize(option.BaseDataDir); + Initialize(); + bool useLastUsedProfile = false; + + if (option.InheritConfig) + { + option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile); + } + + AppDataManager.Initialize(option.BaseDataDir); + + if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out UserProfile profile)) + option.UserProfile = profile.Name; + + // Check if keys exists. + if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"))) + { + if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys")))) + { + Logger.Error?.Print(LogClass.Application, "Keys not found"); + } + } + + ReloadConfig(); + + if (option.InheritConfig) + { + option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance); + } + _virtualFileSystem = VirtualFileSystem.CreateInstance(); _libHacHorizonManager = new LibHacHorizonManager(); @@ -352,7 +184,7 @@ namespace Ryujinx.Headless.SDL2 _inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver()); - GraphicsConfig.EnableShaderCache = true; + GraphicsConfig.EnableShaderCache = !option.DisableShaderCache; if (OperatingSystem.IsMacOS()) { @@ -363,15 +195,13 @@ namespace Ryujinx.Headless.SDL2 } } - IGamepad gamepad; - if (option.ListInputIds) { Logger.Info?.Print(LogClass.Application, "Input Ids:"); foreach (string id in _inputManager.KeyboardDriver.GamepadsIds) { - gamepad = _inputManager.KeyboardDriver.GetGamepad(id); + IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(id); Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); @@ -380,7 +210,7 @@ namespace Ryujinx.Headless.SDL2 foreach (string id in _inputManager.GamepadDriver.GamepadsIds) { - gamepad = _inputManager.GamepadDriver.GetGamepad(id); + IGamepad gamepad = _inputManager.GamepadDriver.GetGamepad(id); Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); @@ -397,22 +227,12 @@ namespace Ryujinx.Headless.SDL2 return; } - _inputConfiguration = new List(); + _inputConfiguration ??= []; _enableKeyboard = option.EnableKeyboard; _enableMouse = option.EnableMouse; - - static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) - { - InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index); - - if (inputConfig != null) - { - _inputConfiguration.Add(inputConfig); - } - } - + LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1); - LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); + LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); LoadPlayerConfiguration(option.InputProfile3Name, option.InputId3, PlayerIndex.Player3); LoadPlayerConfiguration(option.InputProfile4Name, option.InputId4, PlayerIndex.Player4); LoadPlayerConfiguration(option.InputProfile5Name, option.InputId5, PlayerIndex.Player5); @@ -420,7 +240,7 @@ namespace Ryujinx.Headless.SDL2 LoadPlayerConfiguration(option.InputProfile7Name, option.InputId7, PlayerIndex.Player7); LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8); LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld); - + if (_inputConfiguration.Count == 0) { return; @@ -431,7 +251,7 @@ namespace Ryujinx.Headless.SDL2 Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub); Logger.SetEnable(LogLevel.Info, !option.LoggingDisableInfo); Logger.SetEnable(LogLevel.Warning, !option.LoggingDisableWarning); - Logger.SetEnable(LogLevel.Error, option.LoggingEnableError); + Logger.SetEnable(LogLevel.Error, !option.LoggingDisableError); Logger.SetEnable(LogLevel.Trace, option.LoggingEnableTrace); Logger.SetEnable(LogLevel.Guest, !option.LoggingDisableGuest); Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog); @@ -468,6 +288,10 @@ namespace Ryujinx.Headless.SDL2 GraphicsConfig.EnableMacroHLE = !option.DisableMacroHLE; DriverUtilities.InitDriverConfig(option.BackendThreading == BackendThreading.Off); + + if (_inputConfiguration.OfType() + .Any(ic => ic?.Led?.UseRainbow ?? false)) + Rainbow.Enable(); while (true) { @@ -481,7 +305,28 @@ namespace Ryujinx.Headless.SDL2 _userChannelPersistence.ShouldRestart = false; } - _inputManager.Dispose(); + try + { + _inputManager.Dispose(); + } catch {} + + return; + + void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) + { + if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0) + { + Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured."); + return; + } + + InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index); + + if (inputConfig != null) + { + _inputConfiguration.Add(inputConfig); + } + } } private static void SetupProgressHandler() @@ -500,96 +345,21 @@ namespace Ryujinx.Headless.SDL2 { string label = state switch { - LoadState => $"PTC : {current}/{total}", - ShaderCacheState => $"Shaders : {current}/{total}", - _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"), + LoadState => "PTC", + ShaderCacheState => "Shaders", + _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}") }; - Logger.Info?.Print(LogClass.Application, label); + Logger.Info?.Print(LogClass.Application, $"{label} : {current}/{total}"); } private static WindowBase CreateWindow(Options options) { - return options.GraphicsBackend == GraphicsBackend.Vulkan - ? new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet) - : new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet); - } - - private static IRenderer CreateRenderer(Options options, WindowBase window) - { - if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow) + return options.GraphicsBackend switch { - string preferredGpuId = string.Empty; - Vk api = Vk.GetApi(); - - if (!string.IsNullOrEmpty(options.PreferredGPUVendor)) - { - string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant(); - var devices = VulkanRenderer.GetPhysicalDevices(api); - - foreach (var device in devices) - { - if (device.Vendor.ToLowerInvariant() == preferredGpuVendor) - { - preferredGpuId = device.Id; - break; - } - } - } - - return new VulkanRenderer( - api, - (instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))), - vulkanWindow.GetRequiredInstanceExtensions, - preferredGpuId); - } - - return new OpenGLRenderer(); - } - - private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) - { - BackendThreading threadingMode = options.BackendThreading; - - bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); - - if (threadedGAL) - { - renderer = new ThreadedRenderer(renderer); - } - - HLEConfiguration configuration = new(_virtualFileSystem, - _libHacHorizonManager, - _contentManager, - _accountManager, - _userChannelPersistence, - renderer, - new SDL2HardwareDeviceDriver(), - options.DramSize, - window, - options.SystemLanguage, - options.SystemRegion, - options.VSyncMode, - !options.DisableDockedMode, - !options.DisablePTC, - options.EnableInternetAccess, - !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, - options.FsGlobalAccessLogMode, - options.SystemTimeOffset, - options.SystemTimeZone, - options.MemoryManagerMode, - options.IgnoreMissingServices, - options.AspectRatio, - options.AudioVolume, - options.UseHypervisor ?? true, - options.MultiplayerLanInterfaceId, - Common.Configuration.Multiplayer.MultiplayerMode.Disabled, - false, - string.Empty, - string.Empty, - options.CustomVSyncInterval); - - return new Switch(configuration); + GraphicsBackend.Vulkan => new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet), + _ => new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet) + }; } private static void ExecutionEntrypoint() diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index ce75b1d87..66bee8875 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -49,6 +49,9 @@ + + + @@ -56,6 +59,8 @@ + + @@ -75,7 +80,6 @@ - @@ -136,4 +140,4 @@ - \ No newline at end of file + diff --git a/src/Ryujinx/UI/Renderer/RendererHost.cs b/src/Ryujinx/UI/Renderer/RendererHost.cs index 4bf10d0d7..4b3025128 100644 --- a/src/Ryujinx/UI/Renderer/RendererHost.cs +++ b/src/Ryujinx/UI/Renderer/RendererHost.cs @@ -1,12 +1,15 @@ -using Avalonia; +using Avalonia; using Avalonia.Controls; +using Avalonia.Media; +using Ryujinx.Ava.Utilities.Configuration; +using Ryujinx.Common; using Ryujinx.Common.Configuration; -using Ryujinx.UI.Common.Configuration; +using Ryujinx.Common.Logging; using System; namespace Ryujinx.Ava.UI.Renderer { - public partial class RendererHost : UserControl, IDisposable + public class RendererHost : UserControl, IDisposable { public readonly EmbeddedWindow EmbeddedWindow; @@ -15,20 +18,54 @@ namespace Ryujinx.Ava.UI.Renderer public RendererHost() { - InitializeComponent(); + Focusable = true; + FlowDirection = FlowDirection.LeftToRight; - if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl) + EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch { - EmbeddedWindow = new EmbeddedWindowOpenGL(); - } - else - { - EmbeddedWindow = new EmbeddedWindowVulkan(); - } + GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), + GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), + _ => throw new NotSupportedException() + }; Initialize(); } + public GraphicsBackend Backend => + EmbeddedWindow switch + { + EmbeddedWindowVulkan => GraphicsBackend.Vulkan, + EmbeddedWindowOpenGL => GraphicsBackend.OpenGl, + _ => throw new NotImplementedException() + }; + + public RendererHost(string titleId) + { + Focusable = true; + FlowDirection = FlowDirection.LeftToRight; + + EmbeddedWindow = +#pragma warning disable CS8509 + TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend) switch +#pragma warning restore CS8509 + { + GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), + GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), + }; + + string backendText = EmbeddedWindow switch + { + EmbeddedWindowVulkan => "Vulkan", + EmbeddedWindowOpenGL => "OpenGL", + _ => throw new NotImplementedException() + }; + + Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend ({ConfigurationState.Instance.Graphics.GraphicsBackend.Value}): {backendText}"); + + Initialize(); + } + + private void Initialize() { EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated; -- 2.47.1 From 9dc14d43cf437adcf0633def3001044fb6dc1cb1 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 21 Feb 2025 21:01:49 -0600 Subject: [PATCH 3/3] fix more revert jank --- src/Ryujinx.Common/TitleIDs.cs | 48 ---- .../DiskCache/ParallelDiskCacheLoader.cs | 4 - src/Ryujinx/AppHost.cs | 2 +- src/Ryujinx/Ryujinx.csproj | 24 ++ src/Ryujinx/UI/Renderer/RendererHost.cs | 6 +- .../UI/ViewModels/MainWindowViewModel.cs | 3 +- .../UI/ViewModels/SettingsHacksViewModel.cs | 23 -- .../UI/ViewModels/SettingsViewModel.cs | 215 ++++++++---------- .../UI/Views/Settings/SettingsCPUView.axaml | 3 +- .../UI/Views/Settings/SettingsHacksView.axaml | 33 --- .../Utilities/AppLibrary/ApplicationData.cs | 1 - 11 files changed, 126 insertions(+), 236 deletions(-) diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs index 1bf788c96..82be1572f 100644 --- a/src/Ryujinx.Common/TitleIDs.cs +++ b/src/Ryujinx.Common/TitleIDs.cs @@ -10,54 +10,6 @@ namespace Ryujinx.Common { public static ReactiveObject> CurrentApplication { get; } = new(); - public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend) - { - switch (currentBackend) - { - case GraphicsBackend.Metal when !OperatingSystem.IsMacOS(): - case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS(): - return GraphicsBackend.Vulkan; - case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal: - return currentBackend; - } - - if (!RunningPlatform.IsArmMac) - return GraphicsBackend.Vulkan; - - return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan; - } - - public static readonly string[] GreatMetalTitles = - [ - "01009b500007c000", // ARMS - "0100a5c00d162000", // Cuphead - "010023800d64a000", // Deltarune - "01003a30012c0000", // LEGO City Undercover - "010048701995e000", // Luigi's Manion 2 HD - "010028600EBDA000", // Mario 3D World - "0100152000022000", // Mario Kart 8 Deluxe - "010075a016a3a000", // Persona 4 Arena Ultimax - "0100187003A36000", // Pokémon: Let's Go, Eevee! - "010003f003a34000", // Pokémon: Let's Go, Pikachu! - "01008C0016544000", // Sea of Stars - "01006A800016E000", // Smash Ultimate - "01006bb00c6f0000", // The Legend of Zelda: Link's Awakening - - // These ones have small issues, but those happen on Vulkan as well: - "01006f8002326000", // Animal Crossings: New Horizons - "01009bf0072d4000", // Captain Toad: Treasure Tracker - "01009510001ca000", // Fast RMX - "01005CA01580E000", // Persona 5 Royal - "0100b880154fc000", // Persona 5 The Royal (Japan) - "010015100b514000", // Super Mario Bros. Wonder - "0100000000010000", // Super Mario Odyssey - - // Further testing is appreciated, I did not test the entire game: - //"010076f0049a2000", // Bayonetta - //"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon - //"0100f4300bf2c000", // New Pokemon Snap - ]; - public static string GetDiscordGameAsset(string titleId) => DiscordGameAssetKeys.Contains(titleId) ? titleId : "game"; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs index ea79e41c9..a0d3e8c15 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs @@ -1,4 +1,3 @@ -using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; @@ -367,9 +366,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache { try { - if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay)) - Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]); - AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute); _asyncTranslationQueue.Add(asyncTranslation, _cancellationToken); } diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index ed1cd7486..8cc196a58 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -891,7 +891,7 @@ namespace Ryujinx.Ava VirtualFileSystem.ReloadKeySet(); // Initialize Renderer. - GraphicsBackend backend = TitleIDs.SelectGraphicsBackend(ApplicationId.ToString("X16"), ConfigurationState.Instance.Graphics.GraphicsBackend); + GraphicsBackend backend = ConfigurationState.Instance.Graphics.GraphicsBackend; IRenderer renderer = backend switch { diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 66bee8875..7d0b22231 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -130,12 +130,36 @@ + + Assets\ShortcutFiles\shortcut-template.desktop + + + Assets\ShortcutFiles\shortcut-launch-script.sh + + + Assets\ShortcutFiles\shortcut-template.plist + + + Assets\RyujinxGameCompatibility.csv + + + + + + + + + + + + + diff --git a/src/Ryujinx/UI/Renderer/RendererHost.cs b/src/Ryujinx/UI/Renderer/RendererHost.cs index 4b3025128..69275ecb2 100644 --- a/src/Ryujinx/UI/Renderer/RendererHost.cs +++ b/src/Ryujinx/UI/Renderer/RendererHost.cs @@ -45,9 +45,9 @@ namespace Ryujinx.Ava.UI.Renderer FlowDirection = FlowDirection.LeftToRight; EmbeddedWindow = -#pragma warning disable CS8509 - TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend) switch -#pragma warning restore CS8509 +#pragma warning disable CS8524 + ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch +#pragma warning restore CS8524 { GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 21db4c310..23cafbc13 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -141,7 +141,8 @@ namespace Ryujinx.Ava.UI.ViewModels // For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left. // The border gets reduced to colored pixels in the 4 corners. public static readonly Bitmap IconBitmap = - new(Assembly.GetAssembly(typeof(MainWindowViewModel))!.GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!); + new(Assembly.GetAssembly(typeof(MainWindowViewModel))! + .GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!); public MainWindow Window { get; init; } diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index 5096a716d..167b8a857 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -16,21 +16,6 @@ namespace Ryujinx.Ava.UI.ViewModels } [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; - [ObservableProperty] private bool _shaderTranslationDelayEnabled = ConfigurationState.Instance.Hacks.EnableShaderTranslationDelay; - private int _shaderTranslationSleepDelay = ConfigurationState.Instance.Hacks.ShaderTranslationDelay; - - public string ShaderTranslationDelayValueText => $"{ShaderTranslationDelay}ms"; - - public int ShaderTranslationDelay - { - get => _shaderTranslationSleepDelay; - set - { - _shaderTranslationSleepDelay = value; - - OnPropertiesChanged(nameof(ShaderTranslationDelay), nameof(ShaderTranslationDelayValueText)); - } - } public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { @@ -44,13 +29,5 @@ namespace Ryujinx.Ava.UI.ViewModels "there is a low chance that the game will softlock, " + "the submenu won't show up, while background music is still there."); }); - - public static string ShaderTranslationDelayTooltip { get; } = Lambda.String(sb => - { - sb.AppendLine("This hack applies the delay you specify every time shaders are attempted to be translated.") - .AppendLine(); - - sb.Append("Configurable via slider, only when this option is enabled."); - }); } } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 0824e3f86..689d872a1 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -1,6 +1,8 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL2; @@ -9,23 +11,24 @@ using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Windows; +using Ryujinx.Ava.Utilities.Configuration; +using Ryujinx.Ava.Utilities.Configuration.System; +using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using Ryujinx.UI.Common.Configuration; -using Ryujinx.UI.Common.Configuration.System; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.NetworkInformation; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; using System.Threading.Tasks; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; @@ -45,10 +48,9 @@ namespace Ryujinx.Ava.UI.ViewModels private int _resolutionScale; private int _graphicsBackendMultithreadingIndex; private float _volume; - private bool _isVulkanAvailable = true; - private bool _gameDirectoryChanged; - private bool _autoloadDirectoryChanged; - private readonly List _gpuIds = new(); + [ObservableProperty] private bool _isVulkanAvailable = true; + [ObservableProperty] private bool _gameListNeedsRefresh; + private readonly List _gpuIds = []; private int _graphicsBackendIndex; private int _scalingFilter; private int _scalingFilterLevel; @@ -62,7 +64,9 @@ namespace Ryujinx.Ava.UI.ViewModels private int _networkInterfaceIndex; private int _multiplayerModeIndex; private string _ldnPassphrase; - private string _LdnServer; + [ObservableProperty] private string _ldnServer; + + public SettingsHacksViewModel DirtyHacks { get; } public int ResolutionScale { @@ -71,8 +75,7 @@ namespace Ryujinx.Ava.UI.ViewModels { _resolutionScale = value; - OnPropertyChanged(nameof(CustomResolutionScale)); - OnPropertyChanged(nameof(IsCustomResolutionScaleActive)); + OnPropertiesChanged(nameof(CustomResolutionScale), nameof(IsCustomResolutionScaleActive)); } } @@ -109,45 +112,8 @@ namespace Ryujinx.Ava.UI.ViewModels } } - public bool IsVulkanAvailable - { - get => _isVulkanAvailable; - set - { - _isVulkanAvailable = value; - - OnPropertyChanged(); - } - } - public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS(); - public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64; - - public bool GameDirectoryChanged - { - get => _gameDirectoryChanged; - set - { - _gameDirectoryChanged = value; - - OnPropertyChanged(); - } - } - - public bool AutoloadDirectoryChanged - { - get => _autoloadDirectoryChanged; - set - { - _autoloadDirectoryChanged = value; - - OnPropertyChanged(); - } - } - - public bool IsMacOS => OperatingSystem.IsMacOS(); - public bool EnableDiscordIntegration { get; set; } public bool CheckUpdatesOnStart { get; set; } public bool ShowConfirmExit { get; set; } @@ -155,17 +121,20 @@ namespace Ryujinx.Ava.UI.ViewModels public bool RememberWindowState { get; set; } public bool ShowTitleBar { get; set; } public int HideCursor { get; set; } + public int UpdateCheckerType { get; set; } public bool EnableDockedMode { get; set; } public bool EnableKeyboard { get; set; } public bool EnableMouse { get; set; } + public bool DisableInputWhenOutOfFocus { get; set; } + + public int FocusLostActionType { get; set; } + public VSyncMode VSyncMode { get => _vSyncMode; set { - if (value == VSyncMode.Custom || - value == VSyncMode.Switch || - value == VSyncMode.Unbounded) + if (value is VSyncMode.Custom or VSyncMode.Switch or VSyncMode.Unbounded) { _vSyncMode = value; OnPropertyChanged(); @@ -181,19 +150,13 @@ namespace Ryujinx.Ava.UI.ViewModels int newInterval = (int)((value / 100f) * 60); _customVSyncInterval = newInterval; _customVSyncIntervalPercentageProxy = value; - OnPropertyChanged((nameof(CustomVSyncInterval))); - OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText))); + OnPropertiesChanged( + nameof(CustomVSyncInterval), + nameof(CustomVSyncIntervalPercentageText)); } } - public string CustomVSyncIntervalPercentageText - { - get - { - string text = CustomVSyncIntervalPercentageProxy.ToString() + "%"; - return text; - } - } + public string CustomVSyncIntervalPercentageText => CustomVSyncIntervalPercentageProxy + "%"; public bool EnableCustomVSyncInterval { @@ -221,8 +184,9 @@ namespace Ryujinx.Ava.UI.ViewModels _customVSyncInterval = value; int newPercent = (int)((value / 60f) * 100); _customVSyncIntervalPercentageProxy = newPercent; - OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy)); - OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText)); + OnPropertiesChanged( + nameof(CustomVSyncIntervalPercentageProxy), + nameof(CustomVSyncIntervalPercentageText)); OnPropertyChanged(); } } @@ -236,7 +200,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTextureRecompression { get; set; } public bool EnableMacroHLE { get; set; } public bool EnableColorSpacePassthrough { get; set; } - public bool ColorSpacePassthroughAvailable => IsMacOS; + public bool ColorSpacePassthroughAvailable => RunningPlatform.IsMacOS; public bool EnableFileLog { get; set; } public bool EnableStub { get; set; } public bool EnableInfo { get; set; } @@ -245,6 +209,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTrace { get; set; } public bool EnableGuest { get; set; } public bool EnableFsAccessLog { get; set; } + public bool EnableAvaloniaLog { get; set; } public bool EnableDebug { get; set; } public bool IsOpenAlEnabled { get; set; } public bool IsSoundIoEnabled { get; set; } @@ -252,10 +217,13 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsCustomResolutionScaleActive => _resolutionScale == 4; public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr; - public bool IsVulkanSelected => GraphicsBackendIndex == 0; + public bool IsVulkanSelected => + GraphicsBackendIndex == 1 || (GraphicsBackendIndex == 0 && !OperatingSystem.IsMacOS()); public bool UseHypervisor { get; set; } public bool DisableP2P { get; set; } + public bool ShowDirtyHacks => ConfigurationState.Instance.Hacks.ShowDirtyHacks; + public string TimeZone { get; set; } public string ShaderDumpPath { get; set; } @@ -329,6 +297,8 @@ namespace Ryujinx.Ava.UI.ViewModels } } + [ObservableProperty] private bool _matchSystemTime; + public DateTimeOffset CurrentDate { get; set; } public TimeSpan CurrentTime { get; set; } @@ -351,7 +321,6 @@ namespace Ryujinx.Ava.UI.ViewModels set { _networkInterfaceIndex = value != -1 ? value : 0; - ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]]; } } @@ -361,32 +330,21 @@ namespace Ryujinx.Ava.UI.ViewModels set { _multiplayerModeIndex = value; - ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex; } } - [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] - private static partial Regex LdnPassphraseRegex(); - public bool IsInvalidLdnPassphraseVisible { get; set; } - public string LdnServer - { - get => _LdnServer; - set - { - _LdnServer = value; - OnPropertyChanged(); - } - } - public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this() { _virtualFileSystem = virtualFileSystem; _contentManager = contentManager; + if (Program.PreviewerDetached) { Task.Run(LoadTimeZones); + + DirtyHacks = new SettingsHacksViewModel(this); } } @@ -406,6 +364,8 @@ namespace Ryujinx.Ava.UI.ViewModels { Task.Run(LoadAvailableGpus); LoadCurrentConfiguration(); + + DirtyHacks = new SettingsHacksViewModel(this); } } @@ -427,16 +387,16 @@ namespace Ryujinx.Ava.UI.ViewModels { AvailableGpus.Clear(); - var devices = VulkanRenderer.GetPhysicalDevices(); + DeviceInfo[] devices = VulkanRenderer.GetPhysicalDevices(); if (devices.Length == 0) { IsVulkanAvailable = false; - GraphicsBackendIndex = 1; + GraphicsBackendIndex = 2; } else { - foreach (var device in devices) + foreach (DeviceInfo device in devices) { await Dispatcher.UIThread.InvokeAsync(() => { @@ -454,18 +414,6 @@ namespace Ryujinx.Ava.UI.ViewModels Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(PreferredGpuIndex))); } - public void MatchSystemTime() - { - var dto = DateTimeOffset.Now; - - CurrentDate = new DateTimeOffset(dto.Year, dto.Month, dto.Day, 0, 0, 0, dto.Offset); - - CurrentTime = dto.TimeOfDay; - - OnPropertyChanged(nameof(CurrentDate)); - OnPropertyChanged(nameof(CurrentTime)); - } - public async Task LoadTimeZones() { _timeZoneContentManager = new TimeZoneContentManager(); @@ -511,7 +459,7 @@ namespace Ryujinx.Ava.UI.ViewModels private bool ValidateLdnPassphrase(string passphrase) { - return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && LdnPassphraseRegex().IsMatch(passphrase)); + return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && Patterns.LdnPassphrase.IsMatch(passphrase)); } public void ValidateAndSetTimeZone(string location) @@ -530,10 +478,11 @@ namespace Ryujinx.Ava.UI.ViewModels EnableDiscordIntegration = config.EnableDiscordIntegration; CheckUpdatesOnStart = config.CheckUpdatesOnStart; ShowConfirmExit = config.ShowConfirmExit; - IgnoreApplet = config.IgnoreApplet; RememberWindowState = config.RememberWindowState; ShowTitleBar = config.ShowTitleBar; HideCursor = (int)config.HideCursor.Value; + UpdateCheckerType = (int)config.UpdateCheckerType.Value; + FocusLostActionType = (int)config.FocusLostActionType.Value; GameDirectories.Clear(); GameDirectories.AddRange(config.UI.GameDirs.Value); @@ -553,6 +502,7 @@ namespace Ryujinx.Ava.UI.ViewModels EnableDockedMode = config.System.EnableDockedMode; EnableKeyboard = config.Hid.EnableKeyboard; EnableMouse = config.Hid.EnableMouse; + DisableInputWhenOutOfFocus = config.Hid.DisableInputWhenOutOfFocus; // Keyboard Hotkeys KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value); @@ -568,12 +518,15 @@ namespace Ryujinx.Ava.UI.ViewModels CurrentDate = currentDateTime.Date; CurrentTime = currentDateTime.TimeOfDay; - EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value; + MatchSystemTime = config.System.MatchSystemTime; + + EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval; CustomVSyncInterval = config.Graphics.CustomVSyncInterval; VSyncMode = config.Graphics.VSyncMode; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; DramSize = config.System.DramSize; IgnoreMissingServices = config.System.IgnoreMissingServices; + IgnoreApplet = config.System.IgnoreControllerApplet; // CPU EnablePptc = config.System.EnablePtc; @@ -616,13 +569,14 @@ namespace Ryujinx.Ava.UI.ViewModels EnableGuest = config.Logger.EnableGuest; EnableDebug = config.Logger.EnableDebug; EnableFsAccessLog = config.Logger.EnableFsAccessLog; + EnableAvaloniaLog = config.Logger.EnableAvaloniaLog; FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode; OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value; MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value; - DisableP2P = config.Multiplayer.DisableP2p.Value; - LdnPassphrase = config.Multiplayer.LdnPassphrase.Value; - LdnServer = config.Multiplayer.LdnServer.Value; + DisableP2P = config.Multiplayer.DisableP2p; + LdnPassphrase = config.Multiplayer.LdnPassphrase; + LdnServer = config.Multiplayer.LdnServer; } public void SaveSettings() @@ -633,22 +587,13 @@ namespace Ryujinx.Ava.UI.ViewModels config.EnableDiscordIntegration.Value = EnableDiscordIntegration; config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart; config.ShowConfirmExit.Value = ShowConfirmExit; - config.IgnoreApplet.Value = IgnoreApplet; config.RememberWindowState.Value = RememberWindowState; config.ShowTitleBar.Value = ShowTitleBar; config.HideCursor.Value = (HideCursorMode)HideCursor; - - if (_gameDirectoryChanged) - { - List gameDirs = new(GameDirectories); - config.UI.GameDirs.Value = gameDirs; - } - - if (_autoloadDirectoryChanged) - { - List autoloadDirs = new(AutoloadDirectories); - config.UI.AutoloadDirs.Value = autoloadDirs; - } + config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType; + config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType; + config.UI.GameDirs.Value = [..GameDirectories]; + config.UI.AutoloadDirs.Value = [..AutoloadDirectories]; config.UI.BaseStyle.Value = BaseStyleIndex switch { @@ -662,26 +607,29 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.EnableDockedMode.Value = EnableDockedMode; config.Hid.EnableKeyboard.Value = EnableKeyboard; config.Hid.EnableMouse.Value = EnableMouse; + config.Hid.DisableInputWhenOutOfFocus.Value = DisableInputWhenOutOfFocus; // Keyboard Hotkeys config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig(); // System config.System.Region.Value = (Region)Region; + + if (config.System.Language.Value != (Language)Language) + GameListNeedsRefresh = true; + config.System.Language.Value = (Language)Language; - if (_validTzRegions.Contains(TimeZone)) { config.System.TimeZone.Value = TimeZone; } + config.System.MatchSystemTime.Value = MatchSystemTime; config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds()); - config.Graphics.VSyncMode.Value = VSyncMode; - config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval; - config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval; config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.DramSize.Value = DramSize; config.System.IgnoreMissingServices.Value = IgnoreMissingServices; + config.System.IgnoreControllerApplet.Value = IgnoreApplet; // CPU config.System.EnablePtc.Value = EnablePptc; @@ -690,6 +638,9 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.UseHypervisor.Value = UseHypervisor; // Graphics + config.Graphics.VSyncMode.Value = VSyncMode; + config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval; + config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval; config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex; config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex); config.Graphics.EnableShaderCache.Value = EnableShaderCache; @@ -736,6 +687,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.Logger.EnableGuest.Value = EnableGuest; config.Logger.EnableDebug.Value = EnableDebug; config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog; + config.Logger.EnableAvaloniaLog.Value = EnableAvaloniaLog; config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode; config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel; @@ -744,16 +696,18 @@ namespace Ryujinx.Ava.UI.ViewModels config.Multiplayer.DisableP2p.Value = DisableP2P; config.Multiplayer.LdnPassphrase.Value = LdnPassphrase; config.Multiplayer.LdnServer.Value = LdnServer; + + // Dirty Hacks + config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); MainWindow.UpdateGraphicsConfig(); - MainWindow.MainWindowViewModel.VSyncModeSettingChanged(); + RyujinxApp.MainWindow.ViewModel.VSyncModeSettingChanged(); SaveSettingsEvent?.Invoke(); - _gameDirectoryChanged = false; - _autoloadDirectoryChanged = false; + GameListNeedsRefresh = false; } private static void RevertIfNotSaved() @@ -772,6 +726,25 @@ namespace Ryujinx.Ava.UI.ViewModels CloseWindow?.Invoke(); } + [ObservableProperty] private bool _wantsToReset; + + public AsyncRelayCommand ResetButton => Commands.Create(async () => + { + if (!WantsToReset) return; + + CloseWindow?.Invoke(); + ConfigurationState.Instance.LoadDefault(); + ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); + RyujinxApp.MainWindow.LoadApplications(); + + await ContentDialogHelper.CreateInfoDialog( + $"Your {RyujinxApp.FullAppName} configuration has been reset.", + "", + string.Empty, + LocaleManager.Instance[LocaleKeys.SettingsButtonClose], + "Configuration Reset"); + }); + public void CancelButton() { RevertIfNotSaved(); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml index c7f03a45d..62f087510 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml @@ -6,6 +6,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -69,7 +70,7 @@ diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml index 9c597d65f..4cf96366a 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml @@ -43,39 +43,6 @@ Text="Xenoblade Chronicles 2 Menu Softlock Fix" /> - - - - - - - - - diff --git a/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs b/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs index 2658352d7..192a2768b 100644 --- a/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs +++ b/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs @@ -16,7 +16,6 @@ using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.Loaders.Processes.Extensions; using System; using System.IO; -using System.Text; using System.Text.Json.Serialization; namespace Ryujinx.Ava.Utilities.AppLibrary -- 2.47.1