diff --git a/.editorconfig b/.editorconfig index 8a3054287..ae4c97662 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,19 +1,31 @@ # Remove the line below if you want to inherit .editorconfig settings from higher directories root = true -# C# files -[*.cs] +[*] #### Core EditorConfig Options #### +# Set default charset +charset = utf-8 + # Indentation and spacing indent_size = 4 indent_style = space tab_width = 4 # New line preferences -end_of_line = crlf -insert_final_newline = false +end_of_line = lf +insert_final_newline = true + +# JSON files +[*.json] + +# Indentation and spacing +indent_size = 2 +tab_width = 2 + +# C# files +[*.cs] #### .NET Coding Conventions #### @@ -59,7 +71,7 @@ dotnet_style_prefer_simplified_interpolation = true:suggestion dotnet_style_readonly_field = true:suggestion # Parameter preferences -dotnet_code_quality_unused_parameters = all:suggestion +dotnet_code_quality_unused_parameters = all:silent #### C# Coding Conventions #### @@ -85,7 +97,7 @@ csharp_style_expression_bodied_properties = true:silent # Pattern matching preferences csharp_style_pattern_matching_over_as_with_null_check = true:suggestion csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_switch_expression = false:silent # Null-checking preferences csharp_style_conditional_delegate_call = true:suggestion @@ -94,6 +106,7 @@ csharp_style_conditional_delegate_call = true:suggestion csharp_prefer_static_local_function = true:suggestion csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent csharp_style_prefer_readonly_struct = true +csharp_style_prefer_method_group_conversion = true # Code-block preferences csharp_prefer_braces = true:silent @@ -109,6 +122,7 @@ csharp_style_prefer_range_operator = true:suggestion csharp_style_throw_expression = true:suggestion csharp_style_unused_value_assignment_preference = discard_variable:suggestion csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_style_implicit_object_creation_when_type_is_apparent = true # 'using' directive preferences csharp_using_directive_placement = outside_namespace:silent @@ -140,7 +154,6 @@ csharp_space_after_dot = false csharp_space_after_keywords_in_control_flow_statements = true csharp_space_after_semicolon_in_for_statement = true csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = false csharp_space_before_colon_in_inheritance_clause = true csharp_space_before_comma = false csharp_space_before_dot = false @@ -158,23 +171,31 @@ csharp_space_between_square_brackets = false # Wrapping preferences csharp_preserve_single_line_blocks = true -csharp_preserve_single_line_statements = true +csharp_preserve_single_line_statements = false #### Naming styles #### # Naming rules -dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface -dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i +dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion +dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface +dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion dotnet_naming_rule.types_should_be_pascal_case.symbols = types -dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.types_should_be_pascal_case.style = PascalCase dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = PascalCase + +dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.symbols = private_static_readonly_fields +dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.severity = suggestion +dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.style = _camelCase + +dotnet_naming_rule.local_constants_should_be_pascal_case.symbols = local_constants +dotnet_naming_rule.local_constants_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.local_constants_should_be_pascal_case.style = PascalCase # Symbol specifications @@ -190,14 +211,62 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected dotnet_naming_symbols.non_field_members.required_modifiers = -# Naming styles +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = static, readonly + +dotnet_naming_symbols.local_constants.applicable_kinds = local +dotnet_naming_symbols.local_constants.applicable_accessibilities = local +dotnet_naming_symbols.local_constants.required_modifiers = const -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = -dotnet_naming_style.pascal_case.capitalization = pascal_case +# Naming styles -dotnet_naming_style.begins_with_i.required_prefix = I -dotnet_naming_style.begins_with_i.required_suffix = -dotnet_naming_style.begins_with_i.word_separator = -dotnet_naming_style.begins_with_i.capitalization = pascal_case \ No newline at end of file +dotnet_naming_style._camelCase.required_prefix = _ +dotnet_naming_style._camelCase.required_suffix = +dotnet_naming_style._camelCase.word_separator = +dotnet_naming_style._camelCase.capitalization = camel_case + +dotnet_naming_style.PascalCase.required_prefix = +dotnet_naming_style.PascalCase.required_suffix = +dotnet_naming_style.PascalCase.word_separator = +dotnet_naming_style.PascalCase.capitalization = pascal_case + +dotnet_naming_style.IPascalCase.required_prefix = I +dotnet_naming_style.IPascalCase.required_suffix = +dotnet_naming_style.IPascalCase.word_separator = +dotnet_naming_style.IPascalCase.capitalization = pascal_case + +# TODO: +# .NET 8 migration (new warnings are caused by the NET 8 C# compiler and analyzer) +# The following info messages might need to be fixed in the source code instead of hiding the actual message +# Without the following lines, dotnet format would fail +# Disable "Collection initialization can be simplified" +dotnet_diagnostic.IDE0028.severity = none +dotnet_diagnostic.IDE0300.severity = none +dotnet_diagnostic.IDE0301.severity = none +dotnet_diagnostic.IDE0302.severity = none +dotnet_diagnostic.IDE0305.severity = none +# Disable "'new' expression can be simplified" +dotnet_diagnostic.IDE0090.severity = none +# Disable "Use primary constructor" +dotnet_diagnostic.IDE0290.severity = none +# Disable "Member '' does not access instance data and can be marked as static" +dotnet_diagnostic.CA1822.severity = none +# Disable "Change type of field '' from '' to '' for improved performance" +dotnet_diagnostic.CA1859.severity = none +# Disable "Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array" +dotnet_diagnostic.CA1861.severity = none +# Disable "Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'" +dotnet_diagnostic.CA1862.severity = none + +[src/Ryujinx.HLE/HOS/Services/**.cs] +# Disable "mark members as static" rule for services +dotnet_diagnostic.CA1822.severity = none + +[src/Ryujinx.Ava/UI/ViewModels/**.cs] +# Disable "mark members as static" rule for ViewModels +dotnet_diagnostic.CA1822.severity = none + +[src/Ryujinx.Tests/Cpu/*.cs] +# Disable naming rules for CPU tests +dotnet_diagnostic.IDE1006.severity = none diff --git a/.github/ISSUE_TEMPLATE/missing_shader_instruction.yml b/.github/ISSUE_TEMPLATE/missing_shader_instruction.yml new file mode 100644 index 000000000..df37859a5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/missing_shader_instruction.yml @@ -0,0 +1,19 @@ +name: Missing Shader Instruction +description: Shader Instruction is missing in Ryujinx. +title: "[GPU]" +labels: [gpu, not-implemented] +body: + - type: textarea + id: instruction + attributes: + label: Shader instruction + description: What shader instruction is missing? + validations: + required: true + - type: textarea + id: required + attributes: + label: Required by + description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction. + validations: + required: true diff --git a/.github/csc.json b/.github/csc.json new file mode 100644 index 000000000..2b960edd1 --- /dev/null +++ b/.github/csc.json @@ -0,0 +1,18 @@ +{ + "problemMatcher": [ + { + "owner": "csc", + "pattern": [ + { + "regexp": "^((?:\\\\|/)(?:[^\\\\/:]+(?:\\\\|/))+[^\\\\/]+)\\((\\d+),(\\d+)\\):\\s+([a-zA-Z]+)\\s+([^:]+):\\s+([^[]+)\\s+\\[", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6 + } + ] + } + ] +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1516f8a7d..491676acb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,7 +13,7 @@ updates: - package-ecosystem: nuget directory: / - open-pull-requests-limit: 5 + open-pull-requests-limit: 10 schedule: interval: daily labels: @@ -22,3 +22,19 @@ updates: - marysaka commit-message: prefix: nuget + groups: + Avalonia: + patterns: + - "*Avalonia*" + Silk.NET: + patterns: + - "Silk.NET*" + OpenTK: + patterns: + - "OpenTK*" + SixLabors: + patterns: + - "SixLabors*" + NUnit: + patterns: + - "NUnit*" diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..027448437 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,35 @@ +audio: +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.Audio*/**' + +cpu: +- changed-files: + - any-glob-to-any-file: ['src/ARMeilleure/**', 'src/Ryujinx.Cpu/**', 'src/Ryujinx.Memory/**'] + +gpu: +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.Graphics.*/**', 'src/Spv.Generator/**', 'src/Ryujinx.ShaderTools/**'] + +'graphics-backend:opengl': +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.Graphics.OpenGL/**' + +'graphics-backend:vulkan': +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**'] + +gui: +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.Ui.Common/**', 'src/Ryujinx.Ui.LocaleGenerator/**', 'src/Ryujinx.Ava/**'] + +horizon: +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.HLE/**', 'src/Ryujinx.Horizon/**'] + +kernel: +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.HLE/HOS/Kernel/**' + +infra: +- changed-files: + - any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props'] diff --git a/.github/reviewers.yml b/.github/reviewers.yml new file mode 100644 index 000000000..052594f23 --- /dev/null +++ b/.github/reviewers.yml @@ -0,0 +1,32 @@ +audio: + - marysaka + +cpu: + - gdkchan + - riperiperi + - marysaka + - LDj3SNuD + +gpu: + - gdkchan + - riperiperi + - marysaka + +gui: + - Ack77 + - emmauss + - TSRBerry + - marysaka + +horizon: + - gdkchan + - Ack77 + - marysaka + - TSRBerry + +infra: + - marysaka + - TSRBerry + +default: + - '@developers' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 843dd492a..cf4fdf051 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,27 +1,18 @@ name: Build job on: - workflow_dispatch: - inputs: {} - #push: - # branches: [ master ] - # paths-ignore: - # - '.github/*' - # - '.github/ISSUE_TEMPLATE/**' - # - '*.yml' - # - 'README.md' - pull_request: - branches: [ master ] - paths-ignore: - - '.github/*' - - '.github/ISSUE_TEMPLATE/**' - - '*.yml' - - 'README.md' + workflow_call: + +env: + POWERSHELL_TELEMETRY_OPTOUT: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + RYUJINX_BASE_VERSION: "1.1.0" jobs: build: - name: ${{ matrix.os }} (${{ matrix.configuration }}) + name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }}) runs-on: ${{ matrix.os }} + timeout-minutes: 45 strategy: matrix: os: [ubuntu-latest, macOS-latest, windows-latest] @@ -33,57 +24,135 @@ jobs: RELEASE_ZIP_OS_NAME: linux_x64 - os: macOS-latest - OS_NAME: MacOS x64 + OS_NAME: macOS x64 DOTNET_RUNTIME_IDENTIFIER: osx-x64 RELEASE_ZIP_OS_NAME: osx_x64 - os: windows-latest OS_NAME: Windows x64 - DOTNET_RUNTIME_IDENTIFIER: win10-x64 + DOTNET_RUNTIME_IDENTIFIER: win-x64 RELEASE_ZIP_OS_NAME: win_x64 fail-fast: false - env: - POWERSHELL_TELEMETRY_OPTOUT: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - RYUJINX_BASE_VERSION: "1.1.0" steps: - - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v3 + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 with: - dotnet-version: 7.0.x + global-json-file: global.json + + - name: Overwrite csc problem matcher + run: echo "::add-matcher::.github/csc.json" + - name: Get git short hash id: git_short_hash run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT shell: bash + - name: Build run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER + - name: Test - run: dotnet test --no-build -c "${{ matrix.configuration }}" + uses: TSRBerry/unstable-commands@v1 + with: + commands: dotnet test --no-build -c "${{ matrix.configuration }}" + timeout-minutes: 10 + retry-codes: 139 + - name: Publish Ryujinx run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + - name: Publish Ryujinx.Headless.SDL2 run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + - name: Publish Ryujinx.Ava run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + + - name: Set executable bit + run: | + chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh + chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh + chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh + if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' + - name: Upload Ryujinx artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + - name: Upload Ryujinx.Headless.SDL2 artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish_sdl2_headless - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + - name: Upload Ryujinx.Ava artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish_ava - if: github.event_name == 'pull_request' \ No newline at end of file + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + + build_macos: + name: macOS Universal (${{ matrix.configuration }}) + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + matrix: + configuration: [ Debug, Release ] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Setup LLVM 14 + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 14 + + - name: Install rcodesign + run: | + mkdir -p $HOME/.bin + gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz' + tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1 + rm apple-codesign.tar.gz + mv rcodesign $HOME/.bin/ + echo "$HOME/.bin" >> $GITHUB_PATH + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get git short hash + id: git_short_hash + run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + + - name: Publish macOS Ryujinx.Ava + run: | + ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER" + + - name: Publish macOS Ryujinx.Headless.SDL2 + run: | + ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER" + + - name: Upload Ryujinx.Ava artifact + uses: actions/upload-artifact@v4 + with: + name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal + path: "publish_ava/*.tar.gz" + if: github.event_name == 'pull_request' + + - name: Upload Ryujinx.Headless.SDL2 artifact + uses: actions/upload-artifact@v4 + with: + name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal + path: "publish_headless/*.tar.gz" + if: github.event_name == 'pull_request' diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 000000000..5311a67f6 --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,74 @@ +name: Perform checks + +on: + pull_request: + branches: [ master ] + paths: + - '**' + - '!.github/**' + - '!*.yml' + - '!*.config' + - '!README.md' + - '.github/workflows/*.yml' + +permissions: + pull-requests: write + checks: write + +concurrency: + group: pr-checks-${{ github.event.number }} + cancel-in-progress: true + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Overwrite csc problem matcher + run: echo "::add-matcher::.github/csc.json" + + - run: dotnet restore + + - name: Print dotnet format version + run: dotnet format --version + + - name: Run dotnet format whitespace + run: | + dotnet format whitespace --verify-no-changes --report ./whitespace-report.json -v d + + # For some unknown reason this step sometimes fails with exit code 139 (segfault?), + # so in that case we'll try again (3 tries max). + - name: Run dotnet format style + uses: TSRBerry/unstable-commands@v1 + with: + commands: dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d + timeout-minutes: 5 + retry-codes: 139 + + # For some unknown reason this step sometimes fails with exit code 139 (segfault?), + # so in that case we'll try again (3 tries max). + - name: Run dotnet format analyzers + uses: TSRBerry/unstable-commands@v1 + with: + commands: dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d + timeout-minutes: 5 + retry-codes: 139 + + - name: Upload report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: dotnet-format + path: ./*-report.json + + pr_build: + uses: ./.github/workflows/build.yml + needs: format + secrets: inherit diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 86a80eabf..f529bea03 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -12,6 +12,7 @@ concurrency: flatpak-release jobs: release: + timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }} runs-on: ubuntu-latest env: @@ -23,11 +24,11 @@ jobs: RYUJINX_VERSION: "${{ inputs.ryujinx_version }}" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: path: Ryujinx - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: Ryujinx/global.json @@ -37,7 +38,7 @@ jobs: run: | echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: flathub/org.ryujinx.Ryujinx token: ${{ secrets.RYUJINX_BOT_PAT }} @@ -48,7 +49,9 @@ jobs: run: python -m pip install PyYAML lxml - name: Restore Nuget packages - run: dotnet restore Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} + # With .NET 8.0.100, Microsoft.NET.ILLink.Tasks isn't restored by default and only seems to appears when publishing. + # So we just publish to grab the dependencies + run: dotnet publish -c Release -r linux-x64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained - name: Generate nuget_sources.json shell: python diff --git a/.github/workflows/nightly_pr_comment.yml b/.github/workflows/nightly_pr_comment.yml index bc3d1c43f..f59a6be1f 100644 --- a/.github/workflows/nightly_pr_comment.yml +++ b/.github/workflows/nightly_pr_comment.yml @@ -1,12 +1,15 @@ name: Comment PR artifacts links + on: workflow_run: - workflows: ['Build job'] + workflows: ['Perform checks'] types: [completed] + jobs: pr_comment: if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest + timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }} steps: - uses: actions/github-script@v6 with: @@ -65,4 +68,4 @@ jobs: } else { core.info(`Creating a comment`); await github.rest.issues.createComment({repo, owner, issue_number, body}); - } + } \ No newline at end of file diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml new file mode 100644 index 000000000..93aa89626 --- /dev/null +++ b/.github/workflows/pr_triage.yml @@ -0,0 +1,47 @@ +name: "Pull Request Triage" +on: + pull_request_target: + types: [opened, ready_for_review] + +jobs: + triage: + permissions: + contents: read + pull-requests: write + + runs-on: ubuntu-latest + + steps: + # Grab sources to get latest labeler.yml + - name: Fetch sources + uses: actions/checkout@v4 + with: + # Ensure we pin the source origin as pull_request_target run under forks. + fetch-depth: 0 + repository: Ryujinx/Ryujinx + ref: master + + - name: Checkout Ryujinx-Mako + uses: actions/checkout@v4 + with: + repository: Ryujinx/Ryujinx-Mako + ref: master + path: '.ryujinx-mako' + + - name: Setup Ryujinx-Mako + uses: ./.ryujinx-mako/.github/actions/setup-mako + + - name: Update labels based on changes + uses: actions/labeler@v5 + with: + sync-labels: true + dot: true + + - name: Assign reviewers + run: | + poetry -n -C .ryujinx-mako run ryujinx-mako update-reviewers ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml + shell: bash + env: + MAKO_APP_ID: ${{ secrets.MAKO_APP_ID }} + MAKO_PRIVATE_KEY: ${{ secrets.MAKO_PRIVATE_KEY }} + MAKO_INSTALLATION_ID: ${{ secrets.MAKO_INSTALLATION_ID }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 914e5e33e..7a4b13d7d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,10 @@ on: push: branches: [ master ] paths-ignore: - - '.github/*' - - '.github/ISSUE_TEMPLATE/**' + - '.github/**' - '*.yml' + - '*.json' + - '*.config' - 'README.md' concurrency: release @@ -22,19 +23,61 @@ env: RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master" jobs: + tag: + name: Create tag + runs-on: ubuntu-20.04 + steps: + - name: Get version info + id: version_info + run: | + echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT + shell: bash + + - name: Create tag + uses: actions/github-script@v6 + with: + script: | + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', + sha: context.sha + }) + release: - runs-on: windows-latest + name: Release ${{ matrix.OS_NAME }} + runs-on: ${{ matrix.os }} + timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }} + strategy: + matrix: + os: [ ubuntu-latest, windows-latest ] + include: + - os: ubuntu-latest + OS_NAME: Linux x64 + DOTNET_RUNTIME_IDENTIFIER: linux-x64 + RELEASE_ZIP_OS_NAME: linux_x64 + + - os: windows-latest + OS_NAME: Windows x64 + DOTNET_RUNTIME_IDENTIFIER: win-x64 + RELEASE_ZIP_OS_NAME: win_x64 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v3 + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json + + - name: Overwrite csc problem matcher + run: echo "::add-matcher::.github/csc.json" + - name: Get version info id: version_info run: | echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT shell: bash + - name: Configure for release run: | sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs @@ -43,58 +86,48 @@ jobs: sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs shell: bash + - name: Create output dir run: "mkdir release_output" - - name: Publish Windows + + - name: Publish run: | - dotnet publish -c Release -r win10-x64 -o ./publish_windows/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true - dotnet publish -c Release -r win10-x64 -o ./publish_windows_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true - dotnet publish -c Release -r win10-x64 -o ./publish_windows_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true + dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true + dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true + dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true + - name: Packing Windows builds + if: matrix.os == 'windows-latest' run: | - pushd publish_windows + pushd publish_gtk 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish popd - pushd publish_windows_sdl2_headless + pushd publish_sdl2_headless 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish popd - pushd publish_windows_ava + pushd publish_ava 7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish popd shell: bash - - name: Publish Linux - run: | - dotnet publish -c Release -r linux-x64 -o ./publish_linux/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true - dotnet publish -c Release -r linux-x64 -o ./publish_linux_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true - dotnet publish -c Release -r linux-x64 -o ./publish_linux_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true - - name: Packing Linux builds + if: matrix.os == 'ubuntu-latest' run: | - pushd publish_linux - tar --exclude "publish/Ryujinx" --exclude "publish/Ryujinx.sh" -cvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish - python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx" "publish/Ryujinx" - python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh" - gzip -9 < ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz - rm ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar + pushd publish_gtk + chmod +x publish/Ryujinx.sh publish/Ryujinx + tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish popd - pushd publish_linux_sdl2_headless - tar --exclude "publish/Ryujinx.Headless.SDL2" --exclude "publish/Ryujinx.sh" -cvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish - python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2" - python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh" - gzip -9 < ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz - rm ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar + pushd publish_sdl2_headless + chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2 + tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish popd - pushd publish_linux_ava - tar --exclude "publish/Ryujinx.Ava" --exclude "publish/Ryujinx.sh" -cvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish - python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Ava" "publish/Ryujinx.Ava" - python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh" - gzip -9 < ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz - rm ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar + pushd publish_ava + chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava + tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish popd shell: bash @@ -105,27 +138,81 @@ jobs: artifacts: "release_output/*.tar.gz,release_output/*.zip" tag: ${{ steps.version_info.outputs.build_version }} body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)." + omitBodyDuringUpdate: true allowUpdates: true - removeArtifacts: true replacesArtifacts: true owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} token: ${{ secrets.RELEASE_TOKEN }} - - name: Create tag - uses: actions/github-script@v5 + macos_release: + name: Release MacOS universal + runs-on: ubuntu-latest + timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 with: - script: | - github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', - sha: context.sha - }) + global-json-file: global.json + + - name: Setup LLVM 15 + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 15 + + - name: Install rcodesign + run: | + mkdir -p $HOME/.bin + gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz' + tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1 + rm apple-codesign.tar.gz + mv rcodesign $HOME/.bin/ + echo "$HOME/.bin" >> $GITHUB_PATH + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get version info + id: version_info + run: | + echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + + - name: Configure for release + run: | + sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + + - name: Publish macOS Ryujinx.Ava + run: | + ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release + + - name: Publish macOS Ryujinx.Headless.SDL2 + run: | + ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release + + - name: Pushing new release + uses: ncipollo/release-action@v1 + with: + name: ${{ steps.version_info.outputs.build_version }} + artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz" + tag: ${{ steps.version_info.outputs.build_version }} + body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)." + omitBodyDuringUpdate: true + allowUpdates: true + replacesArtifacts: true + owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} + repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} + token: ${{ secrets.RELEASE_TOKEN }} flatpak_release: uses: ./.github/workflows/flatpak.yml needs: release with: ryujinx_version: "1.1.${{ github.run_number }}" - secrets: inherit \ No newline at end of file + secrets: inherit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..366eb8435 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,147 @@ +# Contribution to Ryujinx + +You can contribute to Ryujinx with PRs, testing of PRs and issues. Contributing code and other implementations is greatly appreciated alongside simply filing issues for problems you encounter. +Please read the entire document before continuing as it can potentially save everyone involved a significant amount of time. + +# Quick Links + +* [Code Style Documentation](docs/coding-guidelines/coding-style.md) +* [Pull Request Guidelines](docs/workflow/pr-guide.md) + +## Reporting Issues + +We always welcome bug reports, feature proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible. + +### Identify Where to Report + +The Ryujinx codebase is distributed across multiple repositories in the [Ryujinx organization](https://github.com/Ryujinx). Depending on the feedback you might want to file the issue on a different repo. Here are a few common repos: + +* [Ryujinx/Ryujinx](https://github.com/Ryujinx/Ryujinx) Ryujinx core project files. +* [Ryujinx/Ryujinx-Games-List](https://github.com/Ryujinx/Ryujinx-Games-List) Ryujinx game compatibility list. +* [Ryujinx/Ryujinx-Website](https://github.com/Ryujinx/Ryujinx-Website) Ryujinx website source code. +* [Ryujinx/Ryujinx-Ldn-Website](https://github.com/Ryujinx/Ryujinx-Ldn-Website) Ryujinx LDN website source code. + +### Finding Existing Issues + +Before filing a new issue, please search our [open issues](https://github.com/Ryujinx/Ryujinx/issues) to check if it already exists. + +If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog. + +### Writing a Good Feature Request + +Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D). + +### Writing a Good Bug Report + +Good bug reports make it easier for maintainers to verify and root cause the underlying problem. The better a bug report, the faster the problem will be resolved. +Ideally, a bug report should contain the following information: + +* A high-level description of the problem. +* A _minimal reproduction_, i.e. the smallest time commitment/configuration required to reproduce the wrong behavior. This can be in the form of a small homebrew application, or by providing a save file and reproduction steps for a specific game. +* A description of the _expected behavior_, contrasted with the _actual behavior_ observed. +* Information on the environment: OS/distro, CPU, GPU (including driver), RAM etc. +* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically. +* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds? + +When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D). + +## Contributing Changes + +Project maintainers will merge changes that both improve the project and meet our standards for code quality. + +The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryujinx/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance. + +### DOs and DON'Ts + +Please do: + +* **DO** follow our [coding style](docs/coding-guidelines/coding-style.md) (C# code-specific). +* **DO** give priority to the current style of the project or file you're changing even if it diverges from the general guidelines. +* **DO** keep the discussions focused. When a new or related topic comes up + it's often better to create new issue than to side track the discussion. +* **DO** clearly state on an issue that you are going to take on implementing it. +* **DO** blog and tweet (or whatever) about your contributions, frequently! + +Please do not: + +* **DON'T** make PRs for style changes. +* **DON'T** surprise us with big pull requests. Instead, file an issue and talk with us on Discord to start + a discussion so we can agree on a direction before you invest a large amount + of time. +* **DON'T** commit code that you didn't write. If you find code that you think is a good fit to add to Ryujinx, file an issue or talk to us on Discord to start a discussion before proceeding. +* **DON'T** submit PRs that alter licensing related files or headers. If you believe there's a problem with them, file an issue and we'll be happy to discuss it. + +### Suggested Workflow + +We use and recommend the following workflow: + +1. Create or find an issue for your work. + - You can skip this step for trivial changes. + - Get agreement from the team and the community that your proposed change is a good one if it is of significant size or changes core functionality. + - Clearly state that you are going to take on implementing it, if that's the case. You can request that the issue be assigned to you. Note: The issue filer and the implementer don't have to be the same person. +2. Create a personal fork of the repository on GitHub (if you don't already have one). +3. In your fork, create a branch off of main (`git checkout -b mybranch`). + - Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork. +4. Make and commit your changes to your branch. + - [Build Instructions](https://github.com/Ryujinx/Ryujinx#building) explains how to build and test. + - Commit messages should be clear statements of action and intent. +6. Build the repository with your changes. + - Make sure that the builds are clean. + - Make sure that `dotnet format` has been run and any corrections tested and committed. +7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch. + - State in the description what issue or improvement your change is addressing. + - Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryujinx/Ryujinx/actions) to check for outstanding errors. +8. Wait for feedback or approval of your changes from the [core development team](https://github.com/orgs/Ryujinx/teams/developers) + - Details about the pull request [review procedure](docs/workflow/ci/pr-guide.md). +9. When the team members have signed off, and all checks are green, your PR will be merged. + - The next official build will automatically include your change. + - You can delete the branch you used for making the change. + +### Good First Issues + +The team marks the most straightforward issues as [good first issues](https://github.com/Ryujinx/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase. + +### Commit Messages + +Please format commit messages as follows (based on [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)): + +``` +Summarize change in 50 characters or less + +Provide more detail after the first line. Leave one blank line below the +summary and wrap all lines at 72 characters or less. + +If the change fixes an issue, leave another blank line after the final +paragraph and indicate which issue is fixed in the specific format +below. + +Fix #42 +``` + +Also do your best to factor commits appropriately, not too large with unrelated things in the same commit, and not too small with the same small change applied N times in N different commits. + +### PR - CI Process + +The [Ryujinx continuous integration](https://github.com/Ryujinx/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change. + +If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure: +* `dotnet format` has not been run on the PR and has outstanding stylistic issues. +* There is an error within the PR that fails a test or errors the compiler. +* Random failure of the workflow can occasionally result in a CI failure. In this scenario a maintainer will manually restart the job. + +### PR Feedback + +Ryujinx team and community members will provide feedback on your change. Community feedback is highly valued. You may see the absence of team feedback if the community has already provided good review feedback. + +Two Ryujinx team members must review and approve every PR prior to merge. They will often reply with "LGTM, see nit". That means that the PR will be merged once the feedback is resolved. "LGTM" == "looks good to me". + +There are lots of thoughts and [approaches](https://github.com/antlr/antlr4-cpp/blob/master/CONTRIBUTING.md#emoji) for how to efficiently discuss changes. It is best to be clear and explicit with your feedback. Please be patient with people who might not understand the finer details about your approach to feedback. + +#### Copying Changes from Other Projects + +Ryujinx uses some implementations and frameworks from other projects. The following rules must be followed for PRs that include changes from another project: + +- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence). +- The license of the file is left in-tact. +- The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryujinx/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed. + diff --git a/Directory.Packages.props b/Directory.Packages.props index 4759c9ba5..c163cb0bf 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,38 +3,41 @@ true - - - - - - - + + + + + + + - - - + + + - - + + - - + + + + - - - - + + + + - + + @@ -43,11 +46,9 @@ - - - - + + + - \ No newline at end of file diff --git a/README.md b/README.md index 7021abc45..b2f95cc1f 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ The latest automatic build for Windows, macOS, and Linux can be found on the [Of If you wish to build the emulator yourself, follow these steps: ### Step 1 -Install the X64 version of [.NET 7.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/7.0). +Install the X64 version of [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0). ### Step 2 Either use `git clone https://github.com/Ryujinx/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files. @@ -141,3 +141,5 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY - [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system. - [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation. +- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes. +- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation. diff --git a/Ryujinx.sln b/Ryujinx.sln index f9b28c1ba..bb196cabc 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -39,7 +39,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory.Tests", "src\Ryujinx.Tests.Memory\Ryujinx.Tests.Memory.csproj", "{D1CC5322-7325-4F6B-9625-194B30BE1296}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Memory", "src\Ryujinx.Tests.Memory\Ryujinx.Tests.Memory.csproj", "{D1CC5322-7325-4F6B-9625-194B30BE1296}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Cpu", "src\Ryujinx.Cpu\Ryujinx.Cpu.csproj", "{3DF35E3D-D844-4399-A9A1-A9E923264C17}" EndProject @@ -256,4 +256,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {110169B3-3328-4730-8AB0-BA05BEF75C1A} EndGlobalSection -EndGlobal \ No newline at end of file +EndGlobal diff --git a/distribution/legal/THIRDPARTY.md b/distribution/legal/THIRDPARTY.md index 4cc8b7a45..5caa03771 100644 --- a/distribution/legal/THIRDPARTY.md +++ b/distribution/legal/THIRDPARTY.md @@ -681,4 +681,33 @@ END OF TERMS AND CONDITIONS ``` - \ No newline at end of file + + +# ShellLink (MIT) +
+ See License + + ``` + MIT License + + Copyright (c) 2017 Yorick Koster, Securify B.V. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + ``` +
diff --git a/distribution/linux/Ryujinx.desktop b/distribution/linux/Ryujinx.desktop index 19cc5d6cc..a4550d104 100644 --- a/distribution/linux/Ryujinx.desktop +++ b/distribution/linux/Ryujinx.desktop @@ -3,8 +3,8 @@ Version=1.0 Name=Ryujinx Type=Application Icon=Ryujinx -Exec=env DOTNET_EnableAlternateStackCheck=1 Ryujinx %f -Comment=A Nintendo Switch Emulator +Exec=Ryujinx.sh %f +Comment=Plays Nintendo Switch applications GenericName=Nintendo Switch Emulator Terminal=false Categories=Game;Emulator; diff --git a/distribution/linux/Ryujinx.sh b/distribution/linux/Ryujinx.sh index ccb8d65e1..f356cad01 100644 --- a/distribution/linux/Ryujinx.sh +++ b/distribution/linux/Ryujinx.sh @@ -1,6 +1,6 @@ #!/bin/sh -SCRIPT_DIR=$(dirname $(realpath $0)) +SCRIPT_DIR=$(dirname "$(realpath "$0")") RYUJINX_BIN="Ryujinx" if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then @@ -11,4 +11,10 @@ if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then RYUJINX_BIN="Ryujinx.Headless.SDL2" fi -env DOTNET_EnableAlternateStackCheck=1 "$SCRIPT_DIR/$RYUJINX_BIN" "$@" +COMMAND="env DOTNET_EnableAlternateStackCheck=1" + +if command -v gamemoderun > /dev/null 2>&1; then + COMMAND="$COMMAND gamemoderun" +fi + +$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" \ No newline at end of file diff --git a/distribution/linux/shortcut-template.desktop b/distribution/linux/shortcut-template.desktop new file mode 100644 index 000000000..6bee0f8d1 --- /dev/null +++ b/distribution/linux/shortcut-template.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Version=1.0 +Name={0} +Type=Application +Icon={1} +Exec={2} %f +Comment=Nintendo Switch application +GenericName=Nintendo Switch Emulator +Terminal=false +Categories=Game;Emulator; +Keywords=Switch;Nintendo;Emulator; +StartupWMClass=Ryujinx +PrefersNonDefaultGPU=true diff --git a/distribution/macos/Info.plist b/distribution/macos/Info.plist index 6c3f7717c..53929f95e 100644 --- a/distribution/macos/Info.plist +++ b/distribution/macos/Info.plist @@ -10,14 +10,25 @@ Ryujinx CFBundleIconFile Ryujinx.icns - CFBundleTypeExtensions - - nca - nro - nso - nsp - xci - + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + nca + nro + nso + nsp + xci + + CFBundleTypeName + Nintendo Switch File + CFBundleTypeRole + Viewer + LSHandlerRank + Default + + CFBundleIdentifier org.ryujinx.Ryujinx CFBundleInfoDictionaryVersion @@ -39,10 +50,120 @@ CSResourcesFileMapped NSHumanReadableCopyright - Copyright © 2018 - 2022 Ryujinx Team and Contributors. + Copyright © 2018 - 2023 Ryujinx Team and Contributors. LSApplicationCategoryType public.app-category.games LSMinimumSystemVersion - 11.0 + 12.0 + UTExportedTypeDeclarations + + + UTTypeDescription + Extensible Application Markup Language + UTTypeConformsTo + + public.xml + + UTTypeIdentifier + com.ryujinx.xaml + UTTypeTagSpecification + + public.filename-extension + + xaml + + + + + UTTypeDescription + Nintendo Submission Package + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nsp + UTTypeTagSpecification + + public.filename-extension + + nsp + + + + + UTTypeDescription + Nintendo Switch Cartridge + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.xci + UTTypeTagSpecification + + public.filename-extension + + xci + + + + + UTTypeDescription + Nintendo Content Archive + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nca + UTTypeTagSpecification + + public.filename-extension + + nca + + + + + UTTypeDescription + Nintendo Relocatable Object + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nro + UTTypeTagSpecification + + public.filename-extension + + nro + + + + + UTTypeDescription + Nintendo Shared Object + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nso + UTTypeTagSpecification + + public.filename-extension + + nso + + + + + LSEnvironment + + DOTNET_DefaultStackSize + 200000 + diff --git a/distribution/macos/create_macos_release.sh b/distribution/macos/create_macos_build_ava.sh similarity index 69% rename from distribution/macos/create_macos_release.sh rename to distribution/macos/create_macos_build_ava.sh index 59eb1efd2..80594a40a 100755 --- a/distribution/macos/create_macos_release.sh +++ b/distribution/macos/create_macos_build_ava.sh @@ -2,8 +2,8 @@ set -e -if [ "$#" -ne 6 ]; then - echo "usage " +if [ "$#" -lt 7 ]; then + echo "usage " exit 1 fi @@ -17,8 +17,16 @@ OUTPUT_DIRECTORY=$(readlink -f "$3") ENTITLEMENTS_FILE_PATH=$(readlink -f "$4") VERSION=$5 SOURCE_REVISION_ID=$6 +CONFIGURATION=$7 +EXTRA_ARGS=$8 + +if [ "$VERSION" == "1.1.0" ]; +then + RELEASE_TAR_FILE_NAME=test-ava-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar +else + RELEASE_TAR_FILE_NAME=test-ava-ryujinx-$VERSION-macos_universal.app.tar +fi -RELEASE_TAR_FILE_NAME=Ryujinx-$VERSION-macos_universal.app.tar ARM64_APP_BUNDLE="$TEMP_DIRECTORY/output_arm64/Ryujinx.app" X64_APP_BUNDLE="$TEMP_DIRECTORY/output_x64/Ryujinx.app" UNIVERSAL_APP_BUNDLE="$OUTPUT_DIRECTORY/Ryujinx.app" @@ -27,12 +35,12 @@ EXECUTABLE_SUB_PATH=Contents/MacOS/Ryujinx rm -rf "$TEMP_DIRECTORY" mkdir -p "$TEMP_DIRECTORY" -DOTNET_COMMON_ARGS="-p:DebugType=embedded -p:Version=$VERSION -p:SourceRevisionId=$SOURCE_REVISION_ID --self-contained true" +DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS) dotnet restore -dotnet build -c Release src/Ryujinx.Ava -dotnet publish -c Release -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava -dotnet publish -c Release -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava +dotnet build -c "$CONFIGURATION" src/Ryujinx.Ava +dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava +dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava # Get rid of the support library for ARMeilleure for x64 (that's only for arm64) rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib" @@ -68,7 +76,7 @@ else LIPO=lipo fi -# Make it the executable universal +# Make the executable universal $LIPO "$ARM64_APP_BUNDLE/$EXECUTABLE_SUB_PATH" "$X64_APP_BUNDLE/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_APP_BUNDLE/$EXECUTABLE_SUB_PATH" -create # Patch up the Info.plist to have appropriate version @@ -87,19 +95,19 @@ then # NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes. # cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign" - echo "Usign rcodesign for ad-hoc signing" + echo "Using rcodesign for ad-hoc signing" rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$UNIVERSAL_APP_BUNDLE" else - echo "Usign codesign for ad-hoc signing" + echo "Using codesign for ad-hoc signing" codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$UNIVERSAL_APP_BUNDLE" fi echo "Creating archive" pushd "$OUTPUT_DIRECTORY" -tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf $RELEASE_TAR_FILE_NAME Ryujinx.app 1> /dev/null -python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" $RELEASE_TAR_FILE_NAME "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx" -gzip -9 < $RELEASE_TAR_FILE_NAME > $RELEASE_TAR_FILE_NAME.gz -rm $RELEASE_TAR_FILE_NAME +tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf "$RELEASE_TAR_FILE_NAME" Ryujinx.app 1> /dev/null +python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx" +gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz" +rm "$RELEASE_TAR_FILE_NAME" popd echo "Done" \ No newline at end of file diff --git a/distribution/macos/create_macos_build_headless.sh b/distribution/macos/create_macos_build_headless.sh new file mode 100755 index 000000000..a439aef45 --- /dev/null +++ b/distribution/macos/create_macos_build_headless.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +set -e + +if [ "$#" -lt 7 ]; then + echo "usage " + exit 1 +fi + +mkdir -p "$1" +mkdir -p "$2" +mkdir -p "$3" + +BASE_DIR=$(readlink -f "$1") +TEMP_DIRECTORY=$(readlink -f "$2") +OUTPUT_DIRECTORY=$(readlink -f "$3") +ENTITLEMENTS_FILE_PATH=$(readlink -f "$4") +VERSION=$5 +SOURCE_REVISION_ID=$6 +CONFIGURATION=$7 +EXTRA_ARGS=$8 + +if [ "$VERSION" == "1.1.0" ]; +then + RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar +else + RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar +fi + +ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64" +X64_OUTPUT="$TEMP_DIRECTORY/publish_x64" +UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish" +EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2 + +rm -rf "$TEMP_DIRECTORY" +mkdir -p "$TEMP_DIRECTORY" + +DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS) + +dotnet restore +dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2 +dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2 +dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2 + +# Get rid of the support library for ARMeilleure for x64 (that's only for arm64) +rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib" + +# Get rid of libsoundio from arm64 builds as we don't have a arm64 variant +# TODO: remove this once done +rm -rf "$TEMP_DIRECTORY/publish_arm64/libsoundio.dylib" + +rm -rf "$OUTPUT_DIRECTORY" +mkdir -p "$OUTPUT_DIRECTORY" + +# Let's copy one of the two different outputs and remove the executable +cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT" +rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" + +# Make it libraries universal +python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib" + +if ! [ -x "$(command -v lipo)" ]; +then + if ! [ -x "$(command -v llvm-lipo-14)" ]; + then + LIPO=llvm-lipo + else + LIPO=llvm-lipo-14 + fi +else + LIPO=lipo +fi + +# Make the executable universal +$LIPO "$ARM64_OUTPUT/$EXECUTABLE_SUB_PATH" "$X64_OUTPUT/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" -create + +# Now sign it +if ! [ -x "$(command -v codesign)" ]; +then + if ! [ -x "$(command -v rcodesign)" ]; + then + echo "Cannot find rcodesign on your system, please install rcodesign." + exit 1 + fi + + # NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes. + # cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign" + echo "Using rcodesign for ad-hoc signing" + for FILE in "$UNIVERSAL_OUTPUT"/*; do + if [[ $(file "$FILE") == *"Mach-O"* ]]; then + rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$FILE" + fi + done +else + echo "Using codesign for ad-hoc signing" + for FILE in "$UNIVERSAL_OUTPUT"/*; do + if [[ $(file "$FILE") == *"Mach-O"* ]]; then + codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE" + fi + done +fi + +echo "Creating archive" +pushd "$OUTPUT_DIRECTORY" +tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null +python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2" +gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz" +rm "$RELEASE_TAR_FILE_NAME" +popd + +echo "Done" \ No newline at end of file diff --git a/distribution/macos/shortcut-launch-script.sh b/distribution/macos/shortcut-launch-script.sh new file mode 100644 index 000000000..784d780aa --- /dev/null +++ b/distribution/macos/shortcut-launch-script.sh @@ -0,0 +1,8 @@ +#!/bin/sh +launch_arch="$(uname -m)" +if [ "$(sysctl -in sysctl.proc_translated)" = "1" ] +then + launch_arch="arm64" +fi + +arch -$launch_arch {0} {1} diff --git a/distribution/macos/shortcut-template.plist b/distribution/macos/shortcut-template.plist new file mode 100644 index 000000000..27a9e46a9 --- /dev/null +++ b/distribution/macos/shortcut-template.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + {0} + CFBundleGetInfoString + {1} + CFBundleIconFile + {2} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleVersion + 1.0 + NSHighResolutionCapable + + CSResourcesFileMapped + + NSHumanReadableCopyright + Copyright © 2018 - 2023 Ryujinx Team and Contributors. + LSApplicationCategoryType + public.app-category.games + LSMinimumSystemVersion + 11.0 + UIPrerenderedIcon + + LSEnvironment + + DOTNET_DefaultStackSize + 200000 + + + diff --git a/distribution/macos/updater.sh b/distribution/macos/updater.sh index b60ac34df..12e4c3aa1 100755 --- a/distribution/macos/updater.sh +++ b/distribution/macos/updater.sh @@ -5,7 +5,7 @@ set -e INSTALL_DIRECTORY=$1 NEW_APP_DIRECTORY=$2 APP_PID=$3 -APP_ARGUMENTS="${@:4}" +APP_ARGUMENTS=("${@:4}") error_handler() { local lineno="$1" @@ -27,13 +27,31 @@ error_handler() { trap 'error_handler ${LINENO}' ERR -# Wait for Ryujinx to exit -# NOTE: in case no fds are open, lsof could be returning with a process still living. -# We wait 1s and assume the process stopped after that -lsof -p $APP_PID +r 1 &>/dev/null +# Wait for Ryujinx to exit. +# If the main process is still acitve, we wait for 1 second and check it again. +# After the fifth time checking, this script exits with status 1. + +attempt=0 +while true; do + if lsof -p "$APP_PID" +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then + if [ "$attempt" -eq 4 ]; then + exit 1 + fi + sleep 1 + else + break + fi + (( attempt++ )) +done + sleep 1 # Now replace and reopen. rm -rf "$INSTALL_DIRECTORY" mv "$NEW_APP_DIRECTORY" "$INSTALL_DIRECTORY" -open -a "$INSTALL_DIRECTORY" --args "$APP_ARGUMENTS" + +if [ "$#" -le 3 ]; then + open -a "$INSTALL_DIRECTORY" +else + open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}" +fi \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..2213086f6 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,40 @@ +# Documents Index + +This repo includes several documents that explain both high-level and low-level concepts about Ryujinx and its functions. These are very useful for contributors, to get context that can be very difficult to acquire from just reading code. + +Intro to Ryujinx +================== + +Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#. +* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions. +* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. +* Audio output is entirely supported via C# wrappers for SDL2, with OpenAL & libsoundio as fallbacks. + +Getting Started +=============== + +- [Installing the .NET SDK](https://dotnet.microsoft.com/download) +- [Official .NET Docs](https://docs.microsoft.com/dotnet/core/) + +Contributing (Building, testing, benchmarking, profiling, etc.) +=============== + +If you want to contribute a code change to this repo, start here. + +- [Contributor Guide](../CONTRIBUTING.md) + +Coding Guidelines +================= + +- [C# coding style](coding-guidelines/coding-style.md) +- [Service Implementation Guidelines - WIP](https://gist.github.com/gdkchan/84ba88cd50efbe58d1babfaa7cd7c455) + +Project Docs +================= + +To be added. Many project files will contain basic XML docs for key functions and classes in the meantime. + +Other Information +================= + +- N/A diff --git a/docs/coding-guidelines/coding-style.md b/docs/coding-guidelines/coding-style.md new file mode 100644 index 000000000..9c84055d6 --- /dev/null +++ b/docs/coding-guidelines/coding-style.md @@ -0,0 +1,116 @@ +# C# Coding Style + +The general rule we follow is "use Visual Studio defaults". +Using an IDE that supports the `.editorconfig` standard will make this much simpler. + +1. We use [Allman style](http://en.wikipedia.org/wiki/Indent_style#Allman_style) braces, where each brace begins on a new line. A single line statement block can go without braces but the block must be properly indented on its own line and must not be nested in other statement blocks that use braces (See rule 18 for more details). One exception is that a `using` statement is permitted to be nested within another `using` statement by starting on the following line at the same indentation level, even if the nested `using` contains a controlled block. +2. We use four spaces of indentation (no tabs). +3. We use `_camelCase` for internal and private fields and use `readonly` where possible. Prefix internal and private instance fields with `_`, static fields with `s_` and thread static fields with `t_`. When used on static fields, `readonly` should come after `static` (e.g. `static readonly` not `readonly static`). Public fields should be used sparingly and should use PascalCasing with no prefix when used. +4. We avoid `this.` unless absolutely necessary. +5. We always specify the visibility, even if it's the default (e.g. + `private string _foo` not `string _foo`). Visibility should be the first modifier (e.g. + `public abstract` not `abstract public`). +6. Namespace imports should be specified at the top of the file, *outside* of `namespace` declarations. +7. Avoid more than one empty line at any time. For example, do not have two + blank lines between members of a type. +8. Avoid spurious free spaces. + For example avoid `if (someVar == 0)...`, where the dots mark the spurious free spaces. + Consider enabling "View White Space (Ctrl+R, Ctrl+W)" or "Edit -> Advanced -> View White Space" if using Visual Studio to aid detection. +9. If a file happens to differ in style from these guidelines (e.g. private members are named `m_member` + rather than `_member`), the existing style in that file takes precedence. +10. We only use `var` when the type is explicitly named on the right-hand side, typically due to either `new` or an explicit cast, e.g. `var stream = new FileStream(...)` not `var stream = OpenStandardInput()`. + - Similarly, target-typed `new()` can only be used when the type is explicitly named on the left-hand side, in a variable definition statement or a field definition statement. e.g. `FileStream stream = new(...);`, but not `stream = new(...);` (where the type was specified on a previous line). +11. We use language keywords instead of BCL types (e.g. `int, string, float` instead of `Int32, String, Single`, etc) for both type references as well as method calls (e.g. `int.Parse` instead of `Int32.Parse`). See issue [#13976](https://github.com/dotnet/runtime/issues/13976) for examples. +12. We use PascalCasing to name all our constant local variables and fields. The only exception is for interop code where the constant value should exactly match the name and value of the code you are calling via interop. +13. We use PascalCasing for all method names, including local functions. +14. We use ```nameof(...)``` instead of ```"..."``` whenever possible and relevant. +15. Fields should be specified at the top within type declarations. +16. When including non-ASCII characters in the source code use Unicode escape sequences (\uXXXX) instead of literal characters. Literal non-ASCII characters occasionally get garbled by a tool or editor. +17. When using labels (for goto), indent the label one less than the current indentation. +18. When using a single-statement if, we follow these conventions: + - Never use single-line form (for example: `if (source == null) throw new ArgumentNullException("source");`) + - Using braces is always accepted, and required if any block of an `if`/`else if`/.../`else` compound statement uses braces or if a single statement body spans multiple lines. + - Braces may be omitted only if the body of *every* block associated with an `if`/`else if`/.../`else` compound statement is placed on a single line. +19. Make all internal and private types static or sealed unless derivation from them is required. As with any implementation detail, they can be changed if/when derivation is required in the future. +20. XML docs should be used when writing interfaces or when a class/method is deemed sufficient in scope or complexity. +21. So-called [Magic Numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)) should be defined as named constants before use (for example `for (int i = 56; i < 68; i++)` could read `for (int i = _currentAge; i < _retireAge; i++)`). + This may be ignored for trivial or syntactically common statements. + +An [EditorConfig](https://editorconfig.org "EditorConfig homepage") file (`.editorconfig`) has been provided at the root of the runtime repository, enabling C# auto-formatting conforming to the above guidelines. + +### Example File: + +``ShaderCache.cs:`` + +```C# +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Logging; +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Engine.Threed; +using Ryujinx.Graphics.Gpu.Engine.Types; +using Ryujinx.Graphics.Gpu.Image; +using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Gpu.Shader.DiskCache; +using Ryujinx.Graphics.Shader; +using Ryujinx.Graphics.Shader.Translation; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace Ryujinx.Graphics.Gpu.Shader +{ + /// + /// Memory cache of shader code. + /// + class ShaderCache : IDisposable + { + /// + /// Default flags used on the shader translation process. + /// + public const TranslationFlags DefaultFlags = TranslationFlags.DebugMode; + + private readonly struct TranslatedShader + { + public readonly CachedShaderStage Shader; + public readonly ShaderProgram Program; + + public TranslatedShader(CachedShaderStage shader, ShaderProgram program) + { + Shader = shader; + Program = program; + } + } + ... + + /// + /// Processes the queue of shaders that must save their binaries to the disk cache. + /// + public void ProcessShaderCacheQueue() + { + // Check to see if the binaries for previously compiled shaders are ready, and save them out. + + while (_programsToSaveQueue.TryPeek(out ProgramToSave programToSave)) + { + ProgramLinkStatus result = programToSave.HostProgram.CheckProgramLink(false); + + if (result != ProgramLinkStatus.Incomplete) + { + if (result == ProgramLinkStatus.Success) + { + _cacheWriter.AddShader(programToSave.CachedProgram, programToSave.BinaryCode ?? programToSave.HostProgram.GetBinary()); + } + + _programsToSaveQueue.Dequeue(); + } + else + { + break; + } + } + } + } +} +``` + +For other languages, our current best guidance is consistency. When editing files, keep new code and changes consistent with the style in the files. For new files, it should conform to the style for that component. If there is a completely new component, anything that is reasonably broadly accepted is fine. diff --git a/docs/workflow/pr-guide.md b/docs/workflow/pr-guide.md new file mode 100644 index 000000000..cc2c5900b --- /dev/null +++ b/docs/workflow/pr-guide.md @@ -0,0 +1,56 @@ +# Pull Request Guide + +## Contributing Rules + +All contributions to Ryujinx/Ryujinx repository are made via pull requests (PRs) rather than through direct commits. The pull requests are reviewed and merged by the maintainers after a review and at least two approvals from the core development team. + +To merge pull requests, you must have write permissions in the repository. + +## Quick Code Review Rules + +* Do not mix unrelated changes in one pull request. For example, a code style change should never be mixed with a bug fix. +* All changes should follow the existing code style. You can read more about our code style at [docs/coding-guidelines](../coding-guidelines/coding-style.md). +* Adding external dependencies is to be avoided unless not doing so would introduce _significant_ complexity. Any dependency addition should be justified and discussed before merge. +* Use Draft pull requests for changes you are still working on but want early CI loop feedback. When you think your changes are ready for review, [change the status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request) of your pull request. +* Rebase your changes when required or directly requested. Changes should always be commited on top of the upstream branch, not the other way around. +* If you are asked to make changes during the review process do them as a new commit. +* Only resolve GitHub conversations with reviewers once they have been addressed with a commit, or via a mutual agreement. + +## Pull Request Ownership + +Every pull request will have automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned. + +If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github). + +## Pull Request Builds + +When submitting a PR to the `Ryujinx/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion. + +## Review Turnaround Times + +Ryujinx is a project that is maintained by volunteers on a completely free-time basis. As such we cannot guarantee any particular timeframe for pull request review and approval. Weeks to months are common for larger (>500 line) PRs but there are some additional best practises to avoid review purgatory. + +* Make the reviewers life easier wherever possible. Make use of descriptive commit names, code comments and XML docs where applicable. +* If there is disagreement on feedback then always lean on the side of the development team and community over any personal opinion. +* We're human. We miss things. We forget things. If there has been radio silence on your changes for a substantial period of time then do not hesitate to reach out directly either with something simple like "bump" on GitHub or a directly on Discord. + +To re-iterate, make the review as easy for us as possible, respond promptly and be comfortable to interact directly with us for anything else. + +## Merging Pull Requests + +Anyone with write access can merge a pull request manually when the following conditions have been met: + +* The PR has been approved by two reviewers and any other objections are addressed. + * You can request follow up reviews from the original reviewers if they requested changes. +* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of your PR. + +Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them. + +## Blocking Pull Request Merging + +If for whatever reason you would like to move your pull request back to an in-progress status to avoid merging it in the current form, you can turn the PR into a draft PR by selecting the option under the reviewers section. Alternatively, you can do that by adding [WIP] prefix to the pull request title. + +## Old Pull Request Policy + +From time to time we will review older PRs and check them for relevance. If we find the PR is inactive or no longer applies, we will close it. As the PR owner, you can simply reopen it if you feel your closed PR needs our attention. + diff --git a/global.json b/global.json index 39ccef0d0..391ba3c2a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.200", + "version": "8.0.100", "rollForward": "latestFeature" } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/ARMeilleure.csproj b/src/ARMeilleure/ARMeilleure.csproj index fa5551154..550e50c26 100644 --- a/src/ARMeilleure/ARMeilleure.csproj +++ b/src/ARMeilleure/ARMeilleure.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 true diff --git a/src/ARMeilleure/Allocators.cs b/src/ARMeilleure/Allocators.cs index deabf9a26..fba302657 100644 --- a/src/ARMeilleure/Allocators.cs +++ b/src/ARMeilleure/Allocators.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Common; +using ARMeilleure.Common; using System; using System.Runtime.CompilerServices; @@ -23,10 +23,7 @@ static class Allocators [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ArenaAllocator GetAllocator(ref ArenaAllocator alloc, uint pageSize, uint pageCount) { - if (alloc == null) - { - alloc = new ArenaAllocator(pageSize, pageCount); - } + alloc ??= new ArenaAllocator(pageSize, pageCount); return alloc; } diff --git a/src/ARMeilleure/CodeGen/Arm64/Arm64Optimizer.cs b/src/ARMeilleure/CodeGen/Arm64/Arm64Optimizer.cs index fdd4d0241..00ffd1958 100644 --- a/src/ARMeilleure/CodeGen/Arm64/Arm64Optimizer.cs +++ b/src/ARMeilleure/CodeGen/Arm64/Arm64Optimizer.cs @@ -221,7 +221,7 @@ private static (Operand, Multiplier) GetIndexOp(ref Operand baseOp, OperandType 2 => Multiplier.x4, 3 => Multiplier.x8, 4 => Multiplier.x16, - _ => Multiplier.x1 + _ => Multiplier.x1, }; baseOp = indexOnSrc2 ? src1 : src2; diff --git a/src/ARMeilleure/CodeGen/Arm64/ArmCondition.cs b/src/ARMeilleure/CodeGen/Arm64/ArmCondition.cs index db27a8104..5db898591 100644 --- a/src/ARMeilleure/CodeGen/Arm64/ArmCondition.cs +++ b/src/ARMeilleure/CodeGen/Arm64/ArmCondition.cs @@ -5,22 +5,22 @@ namespace ARMeilleure.CodeGen.Arm64 { enum ArmCondition { - Eq = 0, - Ne = 1, + Eq = 0, + Ne = 1, GeUn = 2, LtUn = 3, - Mi = 4, - Pl = 5, - Vs = 6, - Vc = 7, + Mi = 4, + Pl = 5, + Vs = 6, + Vc = 7, GtUn = 8, LeUn = 9, - Ge = 10, - Lt = 11, - Gt = 12, - Le = 13, - Al = 14, - Nv = 15 + Ge = 10, + Lt = 11, + Gt = 12, + Le = 13, + Al = 14, + Nv = 15, } static class ComparisonArm64Extensions @@ -29,6 +29,7 @@ public static ArmCondition ToArmCondition(this Comparison comp) { return comp switch { +#pragma warning disable IDE0055 // Disable formatting Comparison.Equal => ArmCondition.Eq, Comparison.NotEqual => ArmCondition.Ne, Comparison.Greater => ArmCondition.Gt, @@ -39,8 +40,9 @@ public static ArmCondition ToArmCondition(this Comparison comp) Comparison.Less => ArmCondition.Lt, Comparison.GreaterOrEqualUI => ArmCondition.GeUn, Comparison.LessUI => ArmCondition.LtUn, +#pragma warning restore IDE0055 - _ => throw new ArgumentException(null, nameof(comp)) + _ => throw new ArgumentException(null, nameof(comp)), }; } } diff --git a/src/ARMeilleure/CodeGen/Arm64/ArmExtensionType.cs b/src/ARMeilleure/CodeGen/Arm64/ArmExtensionType.cs index 062a6d0b7..20ccfd4ba 100644 --- a/src/ARMeilleure/CodeGen/Arm64/ArmExtensionType.cs +++ b/src/ARMeilleure/CodeGen/Arm64/ArmExtensionType.cs @@ -9,6 +9,6 @@ enum ArmExtensionType Sxtb = 4, Sxth = 5, Sxtw = 6, - Sxtx = 7 + Sxtx = 7, } } diff --git a/src/ARMeilleure/CodeGen/Arm64/ArmShiftType.cs b/src/ARMeilleure/CodeGen/Arm64/ArmShiftType.cs index d223a1464..f32407c43 100644 --- a/src/ARMeilleure/CodeGen/Arm64/ArmShiftType.cs +++ b/src/ARMeilleure/CodeGen/Arm64/ArmShiftType.cs @@ -6,6 +6,6 @@ enum ArmShiftType Lsl = 0, Lsr = 1, Asr = 2, - Ror = 3 + Ror = 3, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/Assembler.cs b/src/ARMeilleure/CodeGen/Arm64/Assembler.cs index 0ec0be7cb..41684faf2 100644 --- a/src/ARMeilleure/CodeGen/Arm64/Assembler.cs +++ b/src/ARMeilleure/CodeGen/Arm64/Assembler.cs @@ -188,7 +188,7 @@ public void Fmov(Operand rd, Operand rn, bool topHalf) uint rmode = topHalf ? 1u << 19 : 0u; uint ftype = rd.Type == OperandType.FP64 || rn.Type == OperandType.FP64 ? 1u << 22 : 0u; - uint sf = rd.Type == OperandType.I64 || rn.Type == OperandType.I64 ? SfFlag : 0u; + uint sf = rd.Type == OperandType.I64 || rn.Type == OperandType.I64 ? SfFlag : 0u; WriteUInt32(0x1e260000u | (opcode << 16) | rmode | ftype | sf | EncodeReg(rd) | (EncodeReg(rn) << 5)); } @@ -992,7 +992,7 @@ private static uint GetLdpStpInstruction(uint intInst, uint vecInst, int imm, Op { OperandType.FP32 => 0, OperandType.FP64 => 1, - _ => 2 + _ => 2, }; instruction = vecInst | ((uint)opc << 30); @@ -1124,10 +1124,11 @@ public static int GetScaleForType(OperandType type) OperandType.FP32 => 2, OperandType.FP64 => 3, OperandType.V128 => 4, - _ => throw new ArgumentException($"Invalid type {type}.") + _ => throw new ArgumentException($"Invalid type {type}."), }; } +#pragma warning disable IDE0051 // Remove unused private member private void WriteInt16(short value) { WriteUInt16((ushort)value); @@ -1142,6 +1143,7 @@ private void WriteByte(byte value) { _stream.WriteByte(value); } +#pragma warning restore IDE0051 private void WriteUInt16(ushort value) { diff --git a/src/ARMeilleure/CodeGen/Arm64/CallingConvention.cs b/src/ARMeilleure/CodeGen/Arm64/CallingConvention.cs index fda8d7867..a487c2ed3 100644 --- a/src/ARMeilleure/CodeGen/Arm64/CallingConvention.cs +++ b/src/ARMeilleure/CodeGen/Arm64/CallingConvention.cs @@ -93,4 +93,4 @@ public static int GetVecReturnRegister() return 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGenCommon.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGenCommon.cs index 8d1e597ba..1f0148d5e 100644 --- a/src/ARMeilleure/CodeGen/Arm64/CodeGenCommon.cs +++ b/src/ARMeilleure/CodeGen/Arm64/CodeGenCommon.cs @@ -88,4 +88,4 @@ public static bool TryEncodeBitMask(ulong value, out int immN, out int immS, out return true; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGenContext.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGenContext.cs index 0dd5355f4..12ebabddd 100644 --- a/src/ARMeilleure/CodeGen/Arm64/CodeGenContext.cs +++ b/src/ARMeilleure/CodeGen/Arm64/CodeGenContext.cs @@ -14,7 +14,7 @@ class CodeGenContext private const int CbnzInstLength = 4; private const int LdrLitInstLength = 4; - private Stream _stream; + private readonly Stream _stream; public int StreamOffset => (int)_stream.Length; @@ -32,7 +32,7 @@ class CodeGenContext private readonly Dictionary _visitedBlocks; private readonly Dictionary> _pendingBranches; - private struct ConstantPoolEntry + private readonly struct ConstantPoolEntry { public readonly int Offset; public readonly Symbol Symbol; @@ -58,7 +58,7 @@ public ConstantPoolEntry(int offset, Symbol symbol) private readonly bool _relocatable; - public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksCount, bool relocatable) + public CodeGenContext(AllocationResult allocResult, int maxCallArgs, bool relocatable) { _stream = MemoryStreamManager.Shared.GetStream(); @@ -93,10 +93,10 @@ public void EnterBlock(BasicBlock block) if (_pendingBranches.TryGetValue(block, out var list)) { - foreach (var tuple in list) + foreach ((ArmCondition condition, long branchPos) in list) { - _stream.Seek(tuple.BranchPos, SeekOrigin.Begin); - WriteBranch(tuple.Condition, target); + _stream.Seek(branchPos, SeekOrigin.Begin); + WriteBranch(condition, target); } _stream.Seek(target, SeekOrigin.Begin); @@ -284,4 +284,4 @@ private void WriteUInt64(ulong value) _stream.WriteByte((byte)(value >> 56)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs index fc4fa976e..2df86671a 100644 --- a/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs +++ b/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Numerics; - using static ARMeilleure.IntermediateRepresentation.Operand; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -31,15 +30,16 @@ private enum AccessSize { Byte, Hword, - Auto + Auto, } - private static Action[] _instTable; + private static readonly Action[] _instTable; static CodeGenerator() { _instTable = new Action[EnumUtils.GetCount(typeof(Instruction))]; +#pragma warning disable IDE0055 // Disable formatting Add(Instruction.Add, GenerateAdd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); @@ -48,7 +48,7 @@ static CodeGenerator() Add(Instruction.BranchIf, GenerateBranchIf); Add(Instruction.ByteSwap, GenerateByteSwap); Add(Instruction.Call, GenerateCall); - //Add(Instruction.Clobber, GenerateClobber); + // Add(Instruction.Clobber, GenerateClobber); Add(Instruction.Compare, GenerateCompare); Add(Instruction.CompareAndSwap, GenerateCompareAndSwap); Add(Instruction.CompareAndSwap16, GenerateCompareAndSwap16); @@ -100,6 +100,7 @@ static CodeGenerator() Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend8, GenerateZeroExtend8); +#pragma warning restore IDE0055 static void Add(Instruction inst, Action func) { @@ -131,7 +132,7 @@ public static CompiledFunction Generate(CompilerContext cctx) StackAllocator stackAlloc = new(); - PreAllocator.RunPass(cctx, stackAlloc, out int maxCallArgs); + PreAllocator.RunPass(cctx, out int maxCallArgs); Logger.EndPass(PassName.PreAllocation, cfg); @@ -168,11 +169,9 @@ public static CompiledFunction Generate(CompilerContext cctx) Logger.StartPass(PassName.CodeGeneration); - //Console.Error.WriteLine(IRDumper.GetDump(cfg)); - bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0; - CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable); + CodeGenContext context = new(allocResult, maxCallArgs, relocatable); UnwindInfo unwindInfo = WritePrologue(context); @@ -294,7 +293,7 @@ private static void GenerateBitwiseExclusiveOr(CodeGenContext context, Operation private static void GenerateBitwiseNot(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -332,7 +331,7 @@ private static void GenerateBranchIf(CodeGenContext context, Operation operation private static void GenerateByteSwap(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -366,15 +365,15 @@ private static void GenerateCompareAndSwap(CodeGenContext context, Operation ope { if (operation.SourcesCount == 5) // CompareAndSwap128 has 5 sources, compared to CompareAndSwap64/32's 3. { - Operand actualLow = operation.GetDestination(0); - Operand actualHigh = operation.GetDestination(1); - Operand temp0 = operation.GetDestination(2); - Operand temp1 = operation.GetDestination(3); - Operand address = operation.GetSource(0); - Operand expectedLow = operation.GetSource(1); + Operand actualLow = operation.GetDestination(0); + Operand actualHigh = operation.GetDestination(1); + Operand temp0 = operation.GetDestination(2); + Operand temp1 = operation.GetDestination(3); + Operand address = operation.GetSource(0); + Operand expectedLow = operation.GetSource(1); Operand expectedHigh = operation.GetSource(2); - Operand desiredLow = operation.GetSource(3); - Operand desiredHigh = operation.GetSource(4); + Operand desiredLow = operation.GetSource(3); + Operand desiredHigh = operation.GetSource(4); GenerateAtomicDcas( context, @@ -390,11 +389,11 @@ private static void GenerateCompareAndSwap(CodeGenContext context, Operation ope } else { - Operand actual = operation.GetDestination(0); - Operand result = operation.GetDestination(1); - Operand address = operation.GetSource(0); + Operand actual = operation.GetDestination(0); + Operand result = operation.GetDestination(1); + Operand address = operation.GetSource(0); Operand expected = operation.GetSource(1); - Operand desired = operation.GetSource(2); + Operand desired = operation.GetSource(2); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Auto); } @@ -402,22 +401,22 @@ private static void GenerateCompareAndSwap(CodeGenContext context, Operation ope private static void GenerateCompareAndSwap16(CodeGenContext context, Operation operation) { - Operand actual = operation.GetDestination(0); - Operand result = operation.GetDestination(1); - Operand address = operation.GetSource(0); + Operand actual = operation.GetDestination(0); + Operand result = operation.GetDestination(1); + Operand address = operation.GetSource(0); Operand expected = operation.GetSource(1); - Operand desired = operation.GetSource(2); + Operand desired = operation.GetSource(2); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Hword); } private static void GenerateCompareAndSwap8(CodeGenContext context, Operation operation) { - Operand actual = operation.GetDestination(0); - Operand result = operation.GetDestination(1); - Operand address = operation.GetSource(0); + Operand actual = operation.GetDestination(0); + Operand result = operation.GetDestination(1); + Operand address = operation.GetSource(0); Operand expected = operation.GetSource(1); - Operand desired = operation.GetSource(2); + Operand desired = operation.GetSource(2); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Byte); } @@ -446,13 +445,13 @@ private static void GenerateConditionalSelect(CodeGenContext context, Operation Debug.Assert(dest.Type.IsInteger()); Debug.Assert(src1.Type == OperandType.I32); - context.Assembler.Cmp (src1, Const(src1.Type, 0)); + context.Assembler.Cmp(src1, Const(src1.Type, 0)); context.Assembler.Csel(dest, src2, src3, ArmCondition.Ne); } private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64); @@ -462,7 +461,7 @@ private static void GenerateConvertI64ToI32(CodeGenContext context, Operation op private static void GenerateConvertToFP(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); @@ -481,7 +480,7 @@ private static void GenerateConvertToFP(CodeGenContext context, Operation operat private static void GenerateConvertToFPUI(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); @@ -493,7 +492,7 @@ private static void GenerateConvertToFPUI(CodeGenContext context, Operation oper private static void GenerateCopy(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); EnsureSameType(dest, source); @@ -525,7 +524,7 @@ private static void GenerateCopy(CodeGenContext context, Operation operation) private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); EnsureSameType(dest, source); @@ -537,9 +536,9 @@ private static void GenerateCountLeadingZeros(CodeGenContext context, Operation private static void GenerateDivide(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand dividend = operation.GetSource(0); - Operand divisor = operation.GetSource(1); + Operand divisor = operation.GetSource(1); ValidateBinOp(dest, dividend, divisor); @@ -555,9 +554,9 @@ private static void GenerateDivide(CodeGenContext context, Operation operation) private static void GenerateDivideUI(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand dividend = operation.GetSource(0); - Operand divisor = operation.GetSource(1); + Operand divisor = operation.GetSource(1); ValidateBinOp(dest, dividend, divisor); @@ -566,7 +565,7 @@ private static void GenerateDivideUI(CodeGenContext context, Operation operation private static void GenerateLoad(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = operation.GetSource(0); context.Assembler.Ldr(value, address); @@ -574,7 +573,7 @@ private static void GenerateLoad(CodeGenContext context, Operation operation) private static void GenerateLoad16(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = operation.GetSource(0); Debug.Assert(value.Type.IsInteger()); @@ -584,7 +583,7 @@ private static void GenerateLoad16(CodeGenContext context, Operation operation) private static void GenerateLoad8(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = operation.GetSource(0); Debug.Assert(value.Type.IsInteger()); @@ -643,7 +642,7 @@ private static void GenerateMultiply64HighUI(CodeGenContext context, Operation o private static void GenerateNegate(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -730,7 +729,7 @@ private static void GenerateShiftRightUI(CodeGenContext context, Operation opera private static void GenerateSignExtend16(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -740,7 +739,7 @@ private static void GenerateSignExtend16(CodeGenContext context, Operation opera private static void GenerateSignExtend32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -750,7 +749,7 @@ private static void GenerateSignExtend32(CodeGenContext context, Operation opera private static void GenerateSignExtend8(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -760,7 +759,7 @@ private static void GenerateSignExtend8(CodeGenContext context, Operation operat private static void GenerateFill(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand offset = operation.GetSource(0); Debug.Assert(offset.Kind == OperandKind.Constant); @@ -801,7 +800,7 @@ private static void GenerateSpillArg(CodeGenContext context, Operation operation private static void GenerateStackAlloc(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand offset = operation.GetSource(0); Debug.Assert(offset.Kind == OperandKind.Constant); @@ -813,7 +812,7 @@ private static void GenerateStackAlloc(CodeGenContext context, Operation operati private static void GenerateStore(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = operation.GetSource(0); context.Assembler.Str(value, address); @@ -821,7 +820,7 @@ private static void GenerateStore(CodeGenContext context, Operation operation) private static void GenerateStore16(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = operation.GetSource(0); Debug.Assert(value.Type.IsInteger()); @@ -831,7 +830,7 @@ private static void GenerateStore16(CodeGenContext context, Operation operation) private static void GenerateStore8(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = operation.GetSource(0); Debug.Assert(value.Type.IsInteger()); @@ -878,7 +877,7 @@ private static void GenerateTailcall(CodeGenContext context, Operation operation private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); if (dest != default) @@ -1024,7 +1023,7 @@ private static void GenerateVectorZero(CodeGenContext context, Operation operati private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); @@ -1034,7 +1033,7 @@ private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); @@ -1044,7 +1043,7 @@ private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation private static void GenerateZeroExtend16(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1054,7 +1053,7 @@ private static void GenerateZeroExtend16(CodeGenContext context, Operation opera private static void GenerateZeroExtend32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1070,7 +1069,7 @@ private static void GenerateZeroExtend32(CodeGenContext context, Operation opera private static void GenerateZeroExtend8(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1080,7 +1079,7 @@ private static void GenerateZeroExtend8(CodeGenContext context, Operation operat private static UnwindInfo WritePrologue(CodeGenContext context) { - List pushEntries = new List(); + List pushEntries = new(); Operand rsp = Register(SpRegister); @@ -1570,11 +1569,13 @@ private static void EnsureSameType(Operand op1, Operand op2, Operand op3) Debug.Assert(op1.Type == op3.Type); } +#pragma warning disable IDE0051 // Remove unused private member private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4) { Debug.Assert(op1.Type == op2.Type); Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op4.Type); } +#pragma warning restore IDE0051 } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs index aaa00bb65..b87370557 100644 --- a/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs +++ b/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs @@ -179,6 +179,35 @@ public static void GenerateOperation(CodeGenContext context, Operation operation (uint)operation.GetSource(2).AsInt32()); break; + case IntrinsicType.Vector128Unary: + GenerateVectorUnary( + context, + 1, + 0, + info.Inst, + operation.Destination, + operation.GetSource(0)); + break; + case IntrinsicType.Vector128Binary: + GenerateVectorBinary( + context, + 1, + 0, + info.Inst, + operation.Destination, + operation.GetSource(0), + operation.GetSource(1)); + break; + case IntrinsicType.Vector128BinaryRd: + GenerateVectorUnary( + context, + 1, + 0, + info.Inst, + operation.Destination, + operation.GetSource(1)); + break; + case IntrinsicType.VectorUnary: GenerateVectorUnary( context, @@ -659,4 +688,4 @@ private static void GenerateVectorInsertByElem( context.Assembler.WriteInstruction(instruction, rd, rn); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs b/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs index 99ff299e9..86afc2b4d 100644 --- a/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs +++ b/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs @@ -1,7 +1,4 @@ using System; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.Arm; using System.Runtime.Versioning; @@ -35,7 +32,7 @@ static HardwareCapabilities() } } -#region Linux + #region Linux private const ulong AT_HWCAP = 16; private const ulong AT_HWCAP2 = 26; @@ -46,88 +43,88 @@ static HardwareCapabilities() [Flags] public enum LinuxFeatureFlagsHwCap : ulong { - Fp = 1 << 0, - Asimd = 1 << 1, - Evtstrm = 1 << 2, - Aes = 1 << 3, - Pmull = 1 << 4, - Sha1 = 1 << 5, - Sha2 = 1 << 6, - Crc32 = 1 << 7, - Atomics = 1 << 8, - FpHp = 1 << 9, - AsimdHp = 1 << 10, - CpuId = 1 << 11, - AsimdRdm = 1 << 12, - Jscvt = 1 << 13, - Fcma = 1 << 14, - Lrcpc = 1 << 15, - DcpOp = 1 << 16, - Sha3 = 1 << 17, - Sm3 = 1 << 18, - Sm4 = 1 << 19, - AsimdDp = 1 << 20, - Sha512 = 1 << 21, - Sve = 1 << 22, - AsimdFhm = 1 << 23, - Dit = 1 << 24, - Uscat = 1 << 25, - Ilrcpc = 1 << 26, - FlagM = 1 << 27, - Ssbs = 1 << 28, - Sb = 1 << 29, - Paca = 1 << 30, - Pacg = 1UL << 31 + Fp = 1 << 0, + Asimd = 1 << 1, + Evtstrm = 1 << 2, + Aes = 1 << 3, + Pmull = 1 << 4, + Sha1 = 1 << 5, + Sha2 = 1 << 6, + Crc32 = 1 << 7, + Atomics = 1 << 8, + FpHp = 1 << 9, + AsimdHp = 1 << 10, + CpuId = 1 << 11, + AsimdRdm = 1 << 12, + Jscvt = 1 << 13, + Fcma = 1 << 14, + Lrcpc = 1 << 15, + DcpOp = 1 << 16, + Sha3 = 1 << 17, + Sm3 = 1 << 18, + Sm4 = 1 << 19, + AsimdDp = 1 << 20, + Sha512 = 1 << 21, + Sve = 1 << 22, + AsimdFhm = 1 << 23, + Dit = 1 << 24, + Uscat = 1 << 25, + Ilrcpc = 1 << 26, + FlagM = 1 << 27, + Ssbs = 1 << 28, + Sb = 1 << 29, + Paca = 1 << 30, + Pacg = 1UL << 31, } [Flags] public enum LinuxFeatureFlagsHwCap2 : ulong { - Dcpodp = 1 << 0, - Sve2 = 1 << 1, - SveAes = 1 << 2, - SvePmull = 1 << 3, - SveBitperm = 1 << 4, - SveSha3 = 1 << 5, - SveSm4 = 1 << 6, - FlagM2 = 1 << 7, - Frint = 1 << 8, - SveI8mm = 1 << 9, - SveF32mm = 1 << 10, - SveF64mm = 1 << 11, - SveBf16 = 1 << 12, - I8mm = 1 << 13, - Bf16 = 1 << 14, - Dgh = 1 << 15, - Rng = 1 << 16, - Bti = 1 << 17, - Mte = 1 << 18, - Ecv = 1 << 19, - Afp = 1 << 20, - Rpres = 1 << 21, - Mte3 = 1 << 22, - Sme = 1 << 23, - Sme_i16i64 = 1 << 24, - Sme_f64f64 = 1 << 25, - Sme_i8i32 = 1 << 26, - Sme_f16f32 = 1 << 27, - Sme_b16f32 = 1 << 28, - Sme_f32f32 = 1 << 29, - Sme_fa64 = 1 << 30, - Wfxt = 1UL << 31, - Ebf16 = 1UL << 32, - Sve_Ebf16 = 1UL << 33, - Cssc = 1UL << 34, - Rprfm = 1UL << 35, - Sve2p1 = 1UL << 36 + Dcpodp = 1 << 0, + Sve2 = 1 << 1, + SveAes = 1 << 2, + SvePmull = 1 << 3, + SveBitperm = 1 << 4, + SveSha3 = 1 << 5, + SveSm4 = 1 << 6, + FlagM2 = 1 << 7, + Frint = 1 << 8, + SveI8mm = 1 << 9, + SveF32mm = 1 << 10, + SveF64mm = 1 << 11, + SveBf16 = 1 << 12, + I8mm = 1 << 13, + Bf16 = 1 << 14, + Dgh = 1 << 15, + Rng = 1 << 16, + Bti = 1 << 17, + Mte = 1 << 18, + Ecv = 1 << 19, + Afp = 1 << 20, + Rpres = 1 << 21, + Mte3 = 1 << 22, + Sme = 1 << 23, + Sme_i16i64 = 1 << 24, + Sme_f64f64 = 1 << 25, + Sme_i8i32 = 1 << 26, + Sme_f16f32 = 1 << 27, + Sme_b16f32 = 1 << 28, + Sme_f32f32 = 1 << 29, + Sme_fa64 = 1 << 30, + Wfxt = 1UL << 31, + Ebf16 = 1UL << 32, + Sve_Ebf16 = 1UL << 33, + Cssc = 1UL << 34, + Rprfm = 1UL << 35, + Sve2p1 = 1UL << 36, } public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0; public static LinuxFeatureFlagsHwCap2 LinuxFeatureInfoHwCap2 { get; } = 0; -#endregion + #endregion -#region macOS + #region macOS [LibraryImport("libSystem.dylib", SetLastError = true)] private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize); @@ -143,7 +140,7 @@ private static bool CheckSysctlName(string name) return false; } - private static string[] _sysctlNames = new string[] + private static readonly string[] _sysctlNames = new string[] { "hw.optional.floatingpoint", "hw.optional.AdvSIMD", @@ -153,26 +150,26 @@ private static bool CheckSysctlName(string name) "hw.optional.arm.FEAT_LSE", "hw.optional.armv8_crc32", "hw.optional.arm.FEAT_SHA1", - "hw.optional.arm.FEAT_SHA256" + "hw.optional.arm.FEAT_SHA256", }; [Flags] public enum MacOsFeatureFlags { - Fp = 1 << 0, + Fp = 1 << 0, AdvSimd = 1 << 1, - Fp16 = 1 << 2, - Aes = 1 << 3, - Pmull = 1 << 4, - Lse = 1 << 5, - Crc32 = 1 << 6, - Sha1 = 1 << 7, - Sha256 = 1 << 8 + Fp16 = 1 << 2, + Aes = 1 << 3, + Pmull = 1 << 4, + Lse = 1 << 5, + Crc32 = 1 << 6, + Sha1 = 1 << 7, + Sha256 = 1 << 8, } public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0; -#endregion + #endregion public static bool SupportsAdvSimd => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Asimd) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.AdvSimd); public static bool SupportsAes => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Aes) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Aes); diff --git a/src/ARMeilleure/CodeGen/Arm64/IntrinsicInfo.cs b/src/ARMeilleure/CodeGen/Arm64/IntrinsicInfo.cs index 8695db903..956fc778d 100644 --- a/src/ARMeilleure/CodeGen/Arm64/IntrinsicInfo.cs +++ b/src/ARMeilleure/CodeGen/Arm64/IntrinsicInfo.cs @@ -1,8 +1,8 @@ namespace ARMeilleure.CodeGen.Arm64 { - struct IntrinsicInfo + readonly struct IntrinsicInfo { - public uint Inst { get; } + public uint Inst { get; } public IntrinsicType Type { get; } public IntrinsicInfo(uint inst, IntrinsicType type) @@ -11,4 +11,4 @@ public IntrinsicInfo(uint inst, IntrinsicType type) Type = type; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs b/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs index a309d56d9..dbd5bdd10 100644 --- a/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs +++ b/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs @@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.Arm64 { static class IntrinsicTable { - private static IntrinsicInfo[] _intrinTable; + private static readonly IntrinsicInfo[] _intrinTable; static IntrinsicTable() { _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; +#pragma warning disable IDE0055 // Disable formatting Add(Intrinsic.Arm64AbsS, new IntrinsicInfo(0x5e20b800u, IntrinsicType.ScalarUnary)); Add(Intrinsic.Arm64AbsV, new IntrinsicInfo(0x0e20b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AddhnV, new IntrinsicInfo(0x0e204000u, IntrinsicType.VectorTernaryRd)); @@ -19,8 +20,8 @@ static IntrinsicTable() Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary)); Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary)); - Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary)); - Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary)); + Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd)); + Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd)); Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise)); @@ -448,6 +449,7 @@ static IntrinsicTable() Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary)); +#pragma warning restore IDE0055 } private static void Add(Intrinsic intrin, IntrinsicInfo info) @@ -460,4 +462,4 @@ public static IntrinsicInfo GetInfo(Intrinsic intrin) return _intrinTable[(int)intrin]; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs b/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs index 800eca93c..7538575c9 100644 --- a/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs +++ b/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs @@ -23,6 +23,10 @@ enum IntrinsicType ScalarTernaryShlRd, ScalarTernaryShrRd, + Vector128Unary, + Vector128Binary, + Vector128BinaryRd, + VectorUnary, VectorUnaryBitwise, VectorUnaryByElem, @@ -50,10 +54,7 @@ enum IntrinsicType VectorTernaryShlRd, VectorTernaryShrRd, - Vector128Unary, - Vector128Binary, - GetRegister, - SetRegister + SetRegister, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs b/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs index 6ea9d2397..f66bb66e6 100644 --- a/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs +++ b/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs @@ -1,4 +1,3 @@ -using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; @@ -31,7 +30,7 @@ public bool TryGetValue(ulong value, OperandType type, out Operand local) } } - public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out int maxCallArgs) + public static void RunPass(CompilerContext cctx, out int maxCallArgs) { maxCallArgs = -1; @@ -41,7 +40,7 @@ public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext) { - ConstantDict constants = new ConstantDict(); + ConstantDict constants = new(); Operation nextNode; @@ -92,7 +91,7 @@ public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out InsertReturnCopy(block.Operations, node); break; case Instruction.Tailcall: - InsertTailcallCopies(constants, block.Operations, stackAlloc, node, node); + InsertTailcallCopies(constants, block.Operations, node, node); break; } } @@ -138,10 +137,7 @@ private static void InsertConstantRegCopies(ConstantDict constants, IntrusiveLis { src2 = node.GetSource(1); - Operand temp = src1; - - src1 = src2; - src2 = temp; + (src2, src1) = (src1, src2); node.SetSource(0, src1); node.SetSource(1, src2); @@ -265,9 +261,9 @@ private static void InsertCallCopies(ConstantDict constants, IntrusiveList sources = new List + List sources = new() { - operation.GetSource(0) + operation.GetSource(0), }; int argsCount = operation.SourcesCount - 1; @@ -302,10 +298,10 @@ private static void InsertCallCopies(ConstantDict constants, IntrusiveList nodes, - StackAllocator stackAlloc, Operation node, Operation operation) { - List sources = new List + List sources = new() { - operation.GetSource(0) + operation.GetSource(0), }; int argsCount = operation.SourcesCount - 1; @@ -403,7 +397,7 @@ private static void InsertTailcallCopies( if (source.Type == OperandType.V128 && passOnReg) { // V128 is a struct, we pass each half on a GPR if possible. - Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); + Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); @@ -519,7 +513,7 @@ private static void InsertReturnCopy(IntrusiveList nodes, Operation n if (source.Type == OperandType.V128) { - Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); + Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0))); @@ -746,6 +740,7 @@ private static bool IsSameOperandDestSrc1(Intrinsic intrinsic) info.Type == IntrinsicType.ScalarTernaryFPRdByElem || info.Type == IntrinsicType.ScalarTernaryShlRd || info.Type == IntrinsicType.ScalarTernaryShrRd || + info.Type == IntrinsicType.Vector128BinaryRd || info.Type == IntrinsicType.VectorBinaryRd || info.Type == IntrinsicType.VectorInsertByElem || info.Type == IntrinsicType.VectorTernaryRd || diff --git a/src/ARMeilleure/CodeGen/CompiledFunction.cs b/src/ARMeilleure/CodeGen/CompiledFunction.cs index 0560bf2e9..3844cbfc9 100644 --- a/src/ARMeilleure/CodeGen/CompiledFunction.cs +++ b/src/ARMeilleure/CodeGen/CompiledFunction.cs @@ -35,9 +35,9 @@ readonly struct CompiledFunction /// Relocation info internal CompiledFunction(byte[] code, UnwindInfo unwindInfo, RelocInfo relocInfo) { - Code = code; + Code = code; UnwindInfo = unwindInfo; - RelocInfo = relocInfo; + RelocInfo = relocInfo; } /// @@ -65,4 +65,4 @@ public T MapWithPointer(out IntPtr codePointer) return Marshal.GetDelegateForFunctionPointer(codePointer); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Linking/RelocEntry.cs b/src/ARMeilleure/CodeGen/Linking/RelocEntry.cs index a27bfded2..d103bc395 100644 --- a/src/ARMeilleure/CodeGen/Linking/RelocEntry.cs +++ b/src/ARMeilleure/CodeGen/Linking/RelocEntry.cs @@ -35,4 +35,4 @@ public override string ToString() return $"({nameof(Position)} = {Position}, {nameof(Symbol)} = {Symbol})"; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Linking/RelocInfo.cs b/src/ARMeilleure/CodeGen/Linking/RelocInfo.cs index caaf08e3d..01ff0347b 100644 --- a/src/ARMeilleure/CodeGen/Linking/RelocInfo.cs +++ b/src/ARMeilleure/CodeGen/Linking/RelocInfo.cs @@ -29,4 +29,4 @@ public RelocInfo(RelocEntry[] entries) _entries = entries; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Linking/Symbol.cs b/src/ARMeilleure/CodeGen/Linking/Symbol.cs index 39e0c3eb1..5559afe09 100644 --- a/src/ARMeilleure/CodeGen/Linking/Symbol.cs +++ b/src/ARMeilleure/CodeGen/Linking/Symbol.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.Linking { diff --git a/src/ARMeilleure/CodeGen/Linking/SymbolType.cs b/src/ARMeilleure/CodeGen/Linking/SymbolType.cs index b05b69692..29011a762 100644 --- a/src/ARMeilleure/CodeGen/Linking/SymbolType.cs +++ b/src/ARMeilleure/CodeGen/Linking/SymbolType.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.CodeGen.Linking +namespace ARMeilleure.CodeGen.Linking { /// /// Types of . @@ -23,6 +23,6 @@ enum SymbolType : byte /// /// Refers to a special symbol which is handled by . /// - Special + Special, } } diff --git a/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs b/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs index 9e243d378..5f0e37721 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System.Diagnostics; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs b/src/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs index c5a22a537..be3dff58c 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs @@ -164,7 +164,7 @@ public static void RunPass(Operation operation) } break; - case Instruction.Multiply: + case Instruction.Multiply: if (type == OperandType.I32) { EvaluateBinaryI32(operation, (x, y) => x * y); @@ -343,4 +343,4 @@ private static void EvaluateBinaryI64(Operation operation, Func buffer, Operation copyOp) { // Propagate copy source operand to all uses of the destination operand. - Operand dest = copyOp.Destination; + Operand dest = copyOp.Destination; Operand source = copyOp.GetSource(0); Span uses = dest.GetUses(ref buffer); @@ -249,4 +249,4 @@ private static bool IsPropagableCopy(Operation operation) return operation.Destination.Type == operation.GetSource(0).Type; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Optimizations/Simplification.cs b/src/ARMeilleure/CodeGen/Optimizations/Simplification.cs index a439d6424..53a7f3ede 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/Simplification.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/Simplification.cs @@ -171,13 +171,12 @@ private static bool IsConstEqual(Operand operand, ulong comparand) private static ulong AllOnes(OperandType type) { - switch (type) + return type switch { - case OperandType.I32: return ~0U; - case OperandType.I64: return ~0UL; - } - - throw new ArgumentException("Invalid operand type \"" + type + "\"."); + OperandType.I32 => ~0U, + OperandType.I64 => ~0UL, + _ => throw new ArgumentException("Invalid operand type \"" + type + "\"."), + }; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs b/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs index e94df159c..e63c4da0d 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.Operation.Factory; diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/AllocationResult.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/AllocationResult.cs index 43e5c7e2c..7b9c2f77f 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/AllocationResult.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/AllocationResult.cs @@ -4,7 +4,7 @@ readonly struct AllocationResult { public int IntUsedRegisters { get; } public int VecUsedRegisters { get; } - public int SpillRegionSize { get; } + public int SpillRegionSize { get; } public AllocationResult( int intUsedRegisters, @@ -13,7 +13,7 @@ public AllocationResult( { IntUsedRegisters = intUsedRegisters; VecUsedRegisters = vecUsedRegisters; - SpillRegionSize = spillRegionSize; + SpillRegionSize = spillRegionSize; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs index 587b1a024..af10330ba 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs @@ -1,7 +1,6 @@ using ARMeilleure.IntermediateRepresentation; using System; using System.Collections.Generic; - using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operation.Factory; @@ -13,16 +12,16 @@ private class ParallelCopy { private readonly struct Copy { - public Register Dest { get; } + public Register Dest { get; } public Register Source { get; } public OperandType Type { get; } public Copy(Register dest, Register source, OperandType type) { - Dest = dest; + Dest = dest; Source = source; - Type = type; + Type = type; } } @@ -42,19 +41,19 @@ public void AddCopy(Register dest, Register source, OperandType type) public void Sequence(List sequence) { - Dictionary locations = new Dictionary(); - Dictionary sources = new Dictionary(); + Dictionary locations = new(); + Dictionary sources = new(); - Dictionary types = new Dictionary(); + Dictionary types = new(); - Queue pendingQueue = new Queue(); - Queue readyQueue = new Queue(); + Queue pendingQueue = new(); + Queue readyQueue = new(); foreach (Copy copy in _copies) { locations[copy.Source] = copy.Source; - sources[copy.Dest] = copy.Source; - types[copy.Dest] = copy.Type; + sources[copy.Dest] = copy.Source; + types[copy.Dest] = copy.Type; pendingQueue.Enqueue(copy.Dest); } @@ -91,7 +90,7 @@ public void Sequence(List sequence) } } - copyDest = current; + copyDest = current; origSource = sources[copyDest]; copySource = locations[origSource]; @@ -186,10 +185,7 @@ public void AddSplit(LiveInterval left, LiveInterval right) private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType type) { - if (_fillQueue == null) - { - _fillQueue = new Queue(); - } + _fillQueue ??= new Queue(); Operand register = GetRegister(right.Register, type); Operand offset = Const(left.SpillOffset); @@ -201,10 +197,7 @@ private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType typ private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type) { - if (_spillQueue == null) - { - _spillQueue = new Queue(); - } + _spillQueue ??= new Queue(); Operand offset = Const(right.SpillOffset); Operand register = GetRegister(left.Register, type); @@ -216,10 +209,7 @@ private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType ty private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType type) { - if (_parallelCopy == null) - { - _parallelCopy = new ParallelCopy(); - } + _parallelCopy ??= new ParallelCopy(); _parallelCopy.AddCopy(right.Register, left.Register, type); @@ -228,7 +218,7 @@ private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType typ public Operation[] Sequence() { - List sequence = new List(); + List sequence = new(); if (_spillQueue != null) { @@ -256,4 +246,4 @@ private static Operand GetRegister(Register reg, OperandType type) return Register(reg.Index, reg.Type, type); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs index 25952c775..5f1d6ce89 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs @@ -20,7 +20,7 @@ private readonly struct BlockInfo public BlockInfo(bool hasCall, int intFixedRegisters, int vecFixedRegisters) { - HasCall = hasCall; + HasCall = hasCall; IntFixedRegisters = intFixedRegisters; VecFixedRegisters = vecFixedRegisters; } @@ -39,7 +39,7 @@ private struct LocalInfo private int _first; private int _last; - public bool IsBlockLocal => _first == _last; + public readonly bool IsBlockLocal => _first == _last; public LocalInfo(OperandType type, int uses, int blkIndex) { @@ -53,7 +53,7 @@ public LocalInfo(OperandType type, int uses, int blkIndex) SpillOffset = default; _first = -1; - _last = -1; + _last = -1; SetBlockIndex(blkIndex); } @@ -348,17 +348,17 @@ Operand AllocateRegister(Operand local) if (dest.Type.IsInteger()) { intLocalFreeRegisters &= ~(1 << selectedReg); - intUsedRegisters |= 1 << selectedReg; + intUsedRegisters |= 1 << selectedReg; } else { vecLocalFreeRegisters &= ~(1 << selectedReg); - vecUsedRegisters |= 1 << selectedReg; + vecUsedRegisters |= 1 << selectedReg; } } else { - info.Register = default; + info.Register = default; info.SpillOffset = Const(stackAlloc.Allocate(dest.Type.GetSizeInBytes())); } } @@ -382,7 +382,7 @@ Operand AllocateRegister(Operand local) : GetSpillTemp(dest, vecSpillTempRegisters, ref vecLocalAsg); info.Sequence = sequence; - info.Temp = temp; + info.Temp = temp; } dest = temp; @@ -408,7 +408,7 @@ Operand AllocateRegister(Operand local) private static int SelectSpillTemps(int mask0, int mask1) { int selection = 0; - int count = 0; + int count = 0; while (count < MaxIROperands && mask0 != 0) { @@ -451,4 +451,4 @@ private static int UsesCount(Operand local) return local.AssignmentsCount + local.UsesCount; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/IRegisterAllocator.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/IRegisterAllocator.cs index 8f236c253..7d4ce2ea6 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/IRegisterAllocator.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/IRegisterAllocator.cs @@ -9,4 +9,4 @@ AllocationResult RunPass( StackAllocator stackAlloc, RegisterMasks regMasks); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs index d80157afb..f156e0886 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs @@ -14,7 +14,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators // http://www.christianwimmer.at/Publications/Wimmer04a/Wimmer04a.pdf class LinearScanAllocator : IRegisterAllocator { - private const int InstructionGap = 2; + private const int InstructionGap = 2; private const int InstructionGapMask = InstructionGap - 1; private HashSet _blockEdges; @@ -33,7 +33,7 @@ private class AllocationContext public StackAllocator StackAlloc { get; } - public BitMap Active { get; } + public BitMap Active { get; } public BitMap Inactive { get; } public int IntUsedRegisters { get; set; } @@ -47,9 +47,9 @@ private class AllocationContext public AllocationContext(StackAllocator stackAlloc, RegisterMasks masks, int intervalsCount) { StackAlloc = stackAlloc; - Masks = masks; + Masks = masks; - Active = new BitMap(Allocators.Default, intervalsCount); + Active = new BitMap(Allocators.Default, intervalsCount); Inactive = new BitMap(Allocators.Default, intervalsCount); PopulateFreePositions(RegisterType.Integer, out _intFreePositions, out _intFreePositionsCount); @@ -443,7 +443,7 @@ private static int GetHighestValueIndex(Span span) if (highest < current) { - highest = current; + highest = current; selected = index; if (current == int.MaxValue) @@ -485,9 +485,9 @@ private void SplitAndSpillOverlappingIntervals(AllocationContext context, LiveIn private void SplitAndSpillOverlappingInterval( AllocationContext context, - LiveInterval current, - LiveInterval interval, - int registersCount) + LiveInterval current, + LiveInterval interval, + int registersCount) { // If there's a next use after the start of the current interval, // we need to split the spilled interval twice, and re-insert it @@ -530,8 +530,8 @@ private void SplitAndSpillOverlappingInterval( private void InsertInterval(LiveInterval interval, int registersCount) { Debug.Assert(interval.UsesCount != 0, "Trying to insert a interval without uses."); - Debug.Assert(!interval.IsEmpty, "Trying to insert a empty interval."); - Debug.Assert(!interval.IsSpilled, "Trying to insert a spilled interval."); + Debug.Assert(!interval.IsEmpty, "Trying to insert a empty interval."); + Debug.Assert(!interval.IsSpilled, "Trying to insert a spilled interval."); int startIndex = registersCount * 2; @@ -545,9 +545,9 @@ private void InsertInterval(LiveInterval interval, int registersCount) _intervals.Insert(insertIndex, interval); } - private void Spill(AllocationContext context, LiveInterval interval) + private static void Spill(AllocationContext context, LiveInterval interval) { - Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval."); + Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval."); Debug.Assert(interval.UsesCount == 0, "Trying to spill a interval with uses."); // We first check if any of the siblings were spilled, if so we can reuse @@ -561,7 +561,7 @@ private void Spill(AllocationContext context, LiveInterval interval) private void InsertSplitCopies() { - Dictionary copyResolvers = new Dictionary(); + Dictionary copyResolvers = new(); CopyResolver GetCopyResolver(int position) { @@ -668,18 +668,15 @@ bool IsSplitEdgeBlock(BasicBlock block) continue; } - int lEnd = _blockRanges[block.Index].End - 1; + int lEnd = _blockRanges[block.Index].End - 1; int rStart = _blockRanges[succIndex].Start; - LiveInterval left = interval.GetSplitChild(lEnd); + LiveInterval left = interval.GetSplitChild(lEnd); LiveInterval right = interval.GetSplitChild(rStart); if (left != default && right != default && left != right) { - if (copyResolver == null) - { - copyResolver = new CopyResolver(); - } + copyResolver ??= new CopyResolver(); copyResolver.AddSplit(left, right); } @@ -856,14 +853,14 @@ private void BuildIntervals(ControlFlowGraph cfg, AllocationContext context) int mapSize = _intervals.Count; - BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count]; + BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveKill = new BitMap[cfg.Blocks.Count]; // Compute local live sets. for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) { - BitMap liveGen = new BitMap(Allocators.Default, mapSize); - BitMap liveKill = new BitMap(Allocators.Default, mapSize); + BitMap liveGen = new(Allocators.Default, mapSize); + BitMap liveKill = new(Allocators.Default, mapSize); for (Operation node = block.Operations.First; node != default; node = node.ListNext) { @@ -910,17 +907,17 @@ void VisitDestination(Operand dest) } } - blkLiveGen [block.Index] = liveGen; + blkLiveGen[block.Index] = liveGen; blkLiveKill[block.Index] = liveKill; } // Compute global live sets. - BitMap[] blkLiveIn = new BitMap[cfg.Blocks.Count]; + BitMap[] blkLiveIn = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveOut = new BitMap[cfg.Blocks.Count]; for (int index = 0; index < cfg.Blocks.Count; index++) { - blkLiveIn [index] = new BitMap(Allocators.Default, mapSize); + blkLiveIn[index] = new BitMap(Allocators.Default, mapSize); blkLiveOut[index] = new BitMap(Allocators.Default, mapSize); } @@ -945,9 +942,9 @@ void VisitDestination(Operand dest) BitMap liveIn = blkLiveIn[block.Index]; - liveIn.Set (liveOut); + liveIn.Set(liveOut); liveIn.Clear(blkLiveKill[block.Index]); - liveIn.Set (blkLiveGen [block.Index]); + liveIn.Set(blkLiveGen[block.Index]); } } while (modified); @@ -969,7 +966,7 @@ void VisitDestination(Operand dest) int instCount = Math.Max(block.Operations.Count, 1); int blockStart = operationPos - instCount * InstructionGap; - int blockEnd = operationPos; + int blockEnd = operationPos; _blockRanges[block.Index] = new LiveRange(blockStart, blockEnd); @@ -1061,7 +1058,7 @@ private void AddIntervalCallerSavedReg(int mask, int operationPos, RegisterType { int regIndex = BitOperations.TrailingZeroCount(mask); - Register callerSavedReg = new Register(regIndex, regType); + Register callerSavedReg = new(regIndex, regType); LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)]; @@ -1098,4 +1095,4 @@ private static bool IsLocalOrRegister(OperandKind kind) kind == OperandKind.Register; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs index d739ad281..333d3951b 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs @@ -240,8 +240,10 @@ public int NextUseAfter(int position) public LiveInterval Split(int position) { - LiveInterval result = new(Local, Parent); - result.End = End; + LiveInterval result = new(Local, Parent) + { + End = End, + }; LiveRange prev = PrevRange; LiveRange curr = CurrRange; @@ -393,4 +395,4 @@ IEnumerable GetRanges() return string.Join(", ", GetRanges()); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs index 06b979ead..84b892f42 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.RegisterAllocators { @@ -8,8 +8,8 @@ unsafe struct LiveIntervalList private int _count; private int _capacity; - public int Count => _count; - public Span Span => new(_items, _count); + public readonly int Count => _count; + public readonly Span Span => new(_items, _count); public void Add(LiveInterval interval) { @@ -37,4 +37,4 @@ public void Add(LiveInterval interval) _count++; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveRange.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveRange.cs index e38b5190d..412d597e8 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveRange.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveRange.cs @@ -71,4 +71,4 @@ public override string ToString() return $"[{Start}, {End})"; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/RegisterMasks.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/RegisterMasks.cs index bc948f95f..e6972cf0f 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/RegisterMasks.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/RegisterMasks.cs @@ -5,8 +5,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { readonly struct RegisterMasks { - public int IntAvailableRegisters { get; } - public int VecAvailableRegisters { get; } + public int IntAvailableRegisters { get; } + public int VecAvailableRegisters { get; } public int IntCallerSavedRegisters { get; } public int VecCallerSavedRegisters { get; } public int IntCalleeSavedRegisters { get; } @@ -22,13 +22,13 @@ public RegisterMasks( int vecCalleeSavedRegisters, int registersCount) { - IntAvailableRegisters = intAvailableRegisters; - VecAvailableRegisters = vecAvailableRegisters; + IntAvailableRegisters = intAvailableRegisters; + VecAvailableRegisters = vecAvailableRegisters; IntCallerSavedRegisters = intCallerSavedRegisters; VecCallerSavedRegisters = vecCallerSavedRegisters; IntCalleeSavedRegisters = intCalleeSavedRegisters; VecCalleeSavedRegisters = vecCalleeSavedRegisters; - RegistersCount = registersCount; + RegistersCount = registersCount; } public int GetAvailableRegisters(RegisterType type) @@ -47,4 +47,4 @@ public int GetAvailableRegisters(RegisterType type) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/StackAllocator.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/StackAllocator.cs index 038312fed..13995bc8d 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/StackAllocator.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/StackAllocator.cs @@ -22,4 +22,4 @@ public int Allocate(int sizeInBytes) return offset; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs index c89f0854d..806002f83 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.RegisterAllocators { @@ -6,15 +6,15 @@ unsafe struct UseList { private int* _items; private int _capacity; - private int _count; - public int Count => _count; - public int FirstUse => _count > 0 ? _items[_count - 1] : LiveInterval.NotFound; - public Span Span => new(_items, _count); + public int Count { get; private set; } + + public readonly int FirstUse => Count > 0 ? _items[Count - 1] : LiveInterval.NotFound; + public readonly Span Span => new(_items, Count); public void Add(int position) { - if (_count + 1 > _capacity) + if (Count + 1 > _capacity) { var oldSpan = Span; @@ -28,7 +28,7 @@ public void Add(int position) // Use positions are usually inserted in descending order, so inserting in descending order is faster, // since the number of half exchanges is reduced. - int i = _count - 1; + int i = Count - 1; while (i >= 0 && _items[i] < position) { @@ -36,19 +36,19 @@ public void Add(int position) } _items[i + 1] = position; - _count++; + Count++; } - public int NextUse(int position) + public readonly int NextUse(int position) { int index = NextUseIndex(position); return index != LiveInterval.NotFound ? _items[index] : LiveInterval.NotFound; } - public int NextUseIndex(int position) + public readonly int NextUseIndex(int position) { - int i = _count - 1; + int i = Count - 1; if (i == -1 || position > _items[0]) { @@ -69,16 +69,18 @@ public UseList Split(int position) // Since the list is in descending order, the new split list takes the front of the list and the current // list takes the back of the list. - UseList result = new(); - result._count = index + 1; - result._capacity = result._count; + UseList result = new() + { + Count = index + 1, + }; + result._capacity = result.Count; result._items = _items; - _count = _count - result._count; - _capacity = _count; - _items = _items + result._count; + Count -= result.Count; + _capacity = Count; + _items += result.Count; return result; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Unwinding/UnwindInfo.cs b/src/ARMeilleure/CodeGen/Unwinding/UnwindInfo.cs index 3d0bc21d5..127b84231 100644 --- a/src/ARMeilleure/CodeGen/Unwinding/UnwindInfo.cs +++ b/src/ARMeilleure/CodeGen/Unwinding/UnwindInfo.cs @@ -13,4 +13,4 @@ public UnwindInfo(UnwindPushEntry[] pushEntries, int prologSize) PrologSize = prologSize; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs b/src/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs index 4a8288a28..2045019a3 100644 --- a/src/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs +++ b/src/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs @@ -2,10 +2,10 @@ namespace ARMeilleure.CodeGen.Unwinding { enum UnwindPseudoOp { - PushReg = 0, - SetFrame = 1, + PushReg = 0, + SetFrame = 1, AllocStack = 2, - SaveReg = 3, - SaveXmm128 = 4 + SaveReg = 3, + SaveXmm128 = 4, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/Unwinding/UnwindPushEntry.cs b/src/ARMeilleure/CodeGen/Unwinding/UnwindPushEntry.cs index fd8ea402b..507ace598 100644 --- a/src/ARMeilleure/CodeGen/Unwinding/UnwindPushEntry.cs +++ b/src/ARMeilleure/CodeGen/Unwinding/UnwindPushEntry.cs @@ -17,4 +17,4 @@ public UnwindPushEntry(UnwindPseudoOp pseudoOp, int prologOffset, int regIndex = StackOffsetOrAllocSize = stackOffsetOrAllocSize; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/Assembler.cs b/src/ARMeilleure/CodeGen/X86/Assembler.cs index 67736a31f..55bf07248 100644 --- a/src/ARMeilleure/CodeGen/X86/Assembler.cs +++ b/src/ARMeilleure/CodeGen/X86/Assembler.cs @@ -15,7 +15,7 @@ partial class Assembler private const int OpModRMBits = 24; - private const byte RexPrefix = 0x40; + private const byte RexPrefix = 0x40; private const byte RexWPrefix = 0x48; private const byte LockPrefix = 0xf0; @@ -799,7 +799,7 @@ private void WriteInstruction(Operand dest, Operand source, OperandType type, X8 { JumpIndex = _jumps.Count - 1, Position = (int)_stream.Position, - Symbol = source.Symbol + Symbol = source.Symbol, }); } @@ -959,7 +959,7 @@ private void WriteOpCode( } } - bool needsSibByte = false; + bool needsSibByte = false; bool needsDisplacement = false; int sib = 0; @@ -971,7 +971,7 @@ private void WriteOpCode( X86Register baseRegLow = (X86Register)(baseReg.Index & 0b111); - needsSibByte = memOp.Index != default || baseRegLow == X86Register.Rsp; + needsSibByte = memOp.Index != default || baseRegLow == X86Register.Rsp; needsDisplacement = memOp.Displacement != 0 || baseRegLow == X86Register.Rbp; if (needsDisplacement) @@ -1049,7 +1049,7 @@ private void WriteOpCode( InstructionFlags.Prefix66 => 1, InstructionFlags.PrefixF3 => 2, InstructionFlags.PrefixF2 => 3, - _ => 0 + _ => 0, }; if (src1 != default) @@ -1081,11 +1081,19 @@ private void WriteOpCode( switch (opCodeHigh) { - case 0xf: vexByte1 |= 1; break; - case 0xf38: vexByte1 |= 2; break; - case 0xf3a: vexByte1 |= 3; break; + case 0xf: + vexByte1 |= 1; + break; + case 0xf38: + vexByte1 |= 2; + break; + case 0xf3a: + vexByte1 |= 3; + break; - default: Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}."); break; + default: + Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}."); + break; } vexByte2 |= (rexPrefix & 8) << 4; @@ -1191,11 +1199,19 @@ private void WriteEvexInst( switch ((ushort)(opCode >> 8)) { - case 0xf00: mm = 0b01; break; - case 0xf38: mm = 0b10; break; - case 0xf3a: mm = 0b11; break; + case 0xf00: + mm = 0b01; + break; + case 0xf38: + mm = 0b10; + break; + case 0xf3a: + mm = 0b11; + break; - default: Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}."); break; + default: + Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}."); + break; } WriteByte( @@ -1217,7 +1233,7 @@ private void WriteEvexInst( InstructionFlags.Prefix66 => 0b01, InstructionFlags.PrefixF3 => 0b10, InstructionFlags.PrefixF2 => 0b11, - _ => 0 + _ => 0, }; WriteByte( (byte)( @@ -1233,11 +1249,19 @@ private void WriteEvexInst( byte ll = 0b00; switch (registerWidth) { - case 128: ll = 0b00; break; - case 256: ll = 0b01; break; - case 512: ll = 0b10; break; + case 128: + ll = 0b00; + break; + case 256: + ll = 0b01; + break; + case 512: + ll = 0b10; + break; - default: Debug.Fail($"Invalid EVEX vector register width {registerWidth}."); break; + default: + Debug.Fail($"Invalid EVEX vector register width {registerWidth}."); + break; } // Embedded broadcast in the case of a memory operand bool bcast = broadcast; @@ -1315,10 +1339,7 @@ void SetRegisterHighBit(Register reg, int bit) ref Jump jump = ref jumps[i]; // If jump target not resolved yet, resolve it. - if (jump.JumpTarget == null) - { - jump.JumpTarget = _labels[jump.JumpLabel]; - } + jump.JumpTarget ??= _labels[jump.JumpLabel]; long jumpTarget = jump.JumpTarget.Value; long offset = jumpTarget - jump.JumpPosition; @@ -1556,4 +1577,4 @@ private void WriteUInt64(ulong value) _stream.WriteByte((byte)(value >> 56)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs b/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs index e6a2ff07f..8910e8891 100644 --- a/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs +++ b/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Diagnostics.CodeAnalysis; namespace ARMeilleure.CodeGen.X86 { @@ -12,47 +13,48 @@ public static bool SupportsVexPrefix(X86Instruction inst) private const int BadOp = 0; [Flags] + [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")] private enum InstructionFlags { - None = 0, - RegOnly = 1 << 0, - Reg8Src = 1 << 1, + None = 0, + RegOnly = 1 << 0, + Reg8Src = 1 << 1, Reg8Dest = 1 << 2, - RexW = 1 << 3, - Vex = 1 << 4, - Evex = 1 << 5, + RexW = 1 << 3, + Vex = 1 << 4, + Evex = 1 << 5, - PrefixBit = 16, + PrefixBit = 16, PrefixMask = 7 << PrefixBit, - Prefix66 = 1 << PrefixBit, - PrefixF3 = 2 << PrefixBit, - PrefixF2 = 4 << PrefixBit + Prefix66 = 1 << PrefixBit, + PrefixF3 = 2 << PrefixBit, + PrefixF2 = 4 << PrefixBit, } private readonly struct InstructionInfo { - public int OpRMR { get; } - public int OpRMImm8 { get; } + public int OpRMR { get; } + public int OpRMImm8 { get; } public int OpRMImm32 { get; } - public int OpRImm64 { get; } - public int OpRRM { get; } + public int OpRImm64 { get; } + public int OpRRM { get; } public InstructionFlags Flags { get; } public InstructionInfo( - int opRMR, - int opRMImm8, - int opRMImm32, - int opRImm64, - int opRRM, + int opRMR, + int opRMImm8, + int opRMImm32, + int opRImm64, + int opRRM, InstructionFlags flags) { - OpRMR = opRMR; - OpRMImm8 = opRMImm8; + OpRMR = opRMR; + OpRMImm8 = opRMImm8; OpRMImm32 = opRMImm32; - OpRImm64 = opRImm64; - OpRRM = opRRM; - Flags = flags; + OpRImm64 = opRImm64; + OpRRM = opRRM; + Flags = flags; } } @@ -62,6 +64,7 @@ static Assembler() { _instTable = new InstructionInfo[(int)X86Instruction.Count]; +#pragma warning disable IDE0055 // Disable formatting // Name RM/R RM/I8 RM/I32 R/I64 R/RM Flags Add(X86Instruction.Add, new InstructionInfo(0x00000001, 0x00000083, 0x00000081, BadOp, 0x00000003, InstructionFlags.None)); Add(X86Instruction.Addpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f58, InstructionFlags.Vex | InstructionFlags.Prefix66)); @@ -285,6 +288,7 @@ static Assembler() Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None)); Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex)); +#pragma warning restore IDE0055 static void Add(X86Instruction inst, in InstructionInfo info) { diff --git a/src/ARMeilleure/CodeGen/X86/CallConvName.cs b/src/ARMeilleure/CodeGen/X86/CallConvName.cs index be3676282..6208da1ec 100644 --- a/src/ARMeilleure/CodeGen/X86/CallConvName.cs +++ b/src/ARMeilleure/CodeGen/X86/CallConvName.cs @@ -3,6 +3,6 @@ namespace ARMeilleure.CodeGen.X86 enum CallConvName { SystemV, - Windows + Windows, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/CallingConvention.cs b/src/ARMeilleure/CodeGen/X86/CallingConvention.cs index 953fef5b0..8433aaea9 100644 --- a/src/ARMeilleure/CodeGen/X86/CallingConvention.cs +++ b/src/ARMeilleure/CodeGen/X86/CallingConvention.cs @@ -20,6 +20,7 @@ public static int GetIntCallerSavedRegisters() { if (GetCurrentCallConv() == CallConvName.Windows) { +#pragma warning disable IDE0055 // Disable formatting return (1 << (int)X86Register.Rax) | (1 << (int)X86Register.Rcx) | (1 << (int)X86Register.Rdx) | @@ -39,6 +40,7 @@ public static int GetIntCallerSavedRegisters() (1 << (int)X86Register.R9) | (1 << (int)X86Register.R10) | (1 << (int)X86Register.R11); +#pragma warning restore IDE0055 } } @@ -90,22 +92,32 @@ public static X86Register GetIntArgumentRegister(int index) { switch (index) { - case 0: return X86Register.Rcx; - case 1: return X86Register.Rdx; - case 2: return X86Register.R8; - case 3: return X86Register.R9; + case 0: + return X86Register.Rcx; + case 1: + return X86Register.Rdx; + case 2: + return X86Register.R8; + case 3: + return X86Register.R9; } } else /* if (GetCurrentCallConv() == CallConvName.SystemV) */ { switch (index) { - case 0: return X86Register.Rdi; - case 1: return X86Register.Rsi; - case 2: return X86Register.Rdx; - case 3: return X86Register.Rcx; - case 4: return X86Register.R8; - case 5: return X86Register.R9; + case 0: + return X86Register.Rdi; + case 1: + return X86Register.Rsi; + case 2: + return X86Register.Rdx; + case 3: + return X86Register.Rcx; + case 4: + return X86Register.R8; + case 5: + return X86Register.R9; } } @@ -155,4 +167,4 @@ public static CallConvName GetCurrentCallConv() : CallConvName.SystemV; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs b/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs index 237ecee4e..ae83ea80c 100644 --- a/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs +++ b/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; namespace ARMeilleure.CodeGen.X86 { diff --git a/src/ARMeilleure/CodeGen/X86/CodeGenContext.cs b/src/ARMeilleure/CodeGen/X86/CodeGenContext.cs index 899487241..d4d4c2058 100644 --- a/src/ARMeilleure/CodeGen/X86/CodeGenContext.cs +++ b/src/ARMeilleure/CodeGen/X86/CodeGenContext.cs @@ -30,7 +30,7 @@ public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksC Assembler = new Assembler(_stream, relocatable); CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize); - XmmSaveRegionSize = xmmSaveRegionSize; + XmmSaveRegionSize = xmmSaveRegionSize; } private static int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize) @@ -102,4 +102,4 @@ private Operand GetLabel(BasicBlock block) return label; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/src/ARMeilleure/CodeGen/X86/CodeGenerator.cs index e7179b517..9e94a077f 100644 --- a/src/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/src/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -17,7 +17,7 @@ namespace ARMeilleure.CodeGen.X86 static class CodeGenerator { private const int RegistersCount = 16; - private const int PageSize = 0x1000; + private const int PageSize = 0x1000; private const int StackGuardSize = 0x2000; private static readonly Action[] _instTable; @@ -26,6 +26,7 @@ static CodeGenerator() { _instTable = new Action[EnumUtils.GetCount(typeof(Instruction))]; +#pragma warning disable IDE0055 // Disable formatting Add(Instruction.Add, GenerateAdd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); @@ -85,6 +86,7 @@ static CodeGenerator() Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend8, GenerateZeroExtend8); +#pragma warning restore IDE0055 static void Add(Instruction inst, Action func) { @@ -203,290 +205,290 @@ private static void GenerateOperation(CodeGenContext context, Operation operatio switch (info.Type) { case IntrinsicType.Comis_: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); - - switch (operation.Intrinsic) { - case Intrinsic.X86Comisdeq: - context.Assembler.Comisd(src1, src2); - context.Assembler.Setcc(dest, X86Condition.Equal); - break; - - case Intrinsic.X86Comisdge: - context.Assembler.Comisd(src1, src2); - context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); - break; - - case Intrinsic.X86Comisdlt: - context.Assembler.Comisd(src1, src2); - context.Assembler.Setcc(dest, X86Condition.Below); - break; - - case Intrinsic.X86Comisseq: - context.Assembler.Comiss(src1, src2); - context.Assembler.Setcc(dest, X86Condition.Equal); - break; - - case Intrinsic.X86Comissge: - context.Assembler.Comiss(src1, src2); - context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); - break; - - case Intrinsic.X86Comisslt: - context.Assembler.Comiss(src1, src2); - context.Assembler.Setcc(dest, X86Condition.Below); - break; - } + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); - context.Assembler.Movzx8(dest, dest, OperandType.I32); + switch (operation.Intrinsic) + { + case Intrinsic.X86Comisdeq: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Equal); + break; + + case Intrinsic.X86Comisdge: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); + break; + + case Intrinsic.X86Comisdlt: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Below); + break; + + case Intrinsic.X86Comisseq: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Equal); + break; + + case Intrinsic.X86Comissge: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); + break; + + case Intrinsic.X86Comisslt: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Below); + break; + } - break; - } + context.Assembler.Movzx8(dest, dest, OperandType.I32); + + break; + } case IntrinsicType.Mxcsr: - { - Operand offset = operation.GetSource(0); + { + Operand offset = operation.GetSource(0); - Debug.Assert(offset.Kind == OperandKind.Constant); - Debug.Assert(offset.Type == OperandType.I32); + Debug.Assert(offset.Kind == OperandKind.Constant); + Debug.Assert(offset.Type == OperandType.I32); - int offs = offset.AsInt32() + context.CallArgsRegionSize; + int offs = offset.AsInt32() + context.CallArgsRegionSize; - Operand rsp = Register(X86Register.Rsp); - Operand memOp = MemoryOp(OperandType.I32, rsp, default, Multiplier.x1, offs); + Operand rsp = Register(X86Register.Rsp); + Operand memOp = MemoryOp(OperandType.I32, rsp, default, Multiplier.x1, offs); - Debug.Assert(HardwareCapabilities.SupportsSse || HardwareCapabilities.SupportsVexEncoding); + Debug.Assert(HardwareCapabilities.SupportsSse || HardwareCapabilities.SupportsVexEncoding); - if (operation.Intrinsic == Intrinsic.X86Ldmxcsr) - { - Operand bits = operation.GetSource(1); - Debug.Assert(bits.Type == OperandType.I32); + if (operation.Intrinsic == Intrinsic.X86Ldmxcsr) + { + Operand bits = operation.GetSource(1); + Debug.Assert(bits.Type == OperandType.I32); - context.Assembler.Mov(memOp, bits, OperandType.I32); - context.Assembler.Ldmxcsr(memOp); - } - else if (operation.Intrinsic == Intrinsic.X86Stmxcsr) - { - Operand dest = operation.Destination; - Debug.Assert(dest.Type == OperandType.I32); + context.Assembler.Mov(memOp, bits, OperandType.I32); + context.Assembler.Ldmxcsr(memOp); + } + else if (operation.Intrinsic == Intrinsic.X86Stmxcsr) + { + Operand dest = operation.Destination; + Debug.Assert(dest.Type == OperandType.I32); - context.Assembler.Stmxcsr(memOp); - context.Assembler.Mov(dest, memOp, OperandType.I32); - } + context.Assembler.Stmxcsr(memOp); + context.Assembler.Mov(dest, memOp, OperandType.I32); + } - break; - } + break; + } case IntrinsicType.PopCount: - { - Operand dest = operation.Destination; - Operand source = operation.GetSource(0); + { + Operand dest = operation.Destination; + Operand source = operation.GetSource(0); - EnsureSameType(dest, source); + EnsureSameType(dest, source); - Debug.Assert(dest.Type.IsInteger()); + Debug.Assert(dest.Type.IsInteger()); - context.Assembler.Popcnt(dest, source, dest.Type); + context.Assembler.Popcnt(dest, source, dest.Type); - break; - } + break; + } case IntrinsicType.Unary: - { - Operand dest = operation.Destination; - Operand source = operation.GetSource(0); + { + Operand dest = operation.Destination; + Operand source = operation.GetSource(0); - EnsureSameType(dest, source); + EnsureSameType(dest, source); - Debug.Assert(!dest.Type.IsInteger()); + Debug.Assert(!dest.Type.IsInteger()); - context.Assembler.WriteInstruction(info.Inst, dest, source); + context.Assembler.WriteInstruction(info.Inst, dest, source); - break; - } + break; + } case IntrinsicType.UnaryToGpr: - { - Operand dest = operation.Destination; - Operand source = operation.GetSource(0); + { + Operand dest = operation.Destination; + Operand source = operation.GetSource(0); - Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger()); + Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger()); - if (operation.Intrinsic == Intrinsic.X86Cvtsi2si) - { - if (dest.Type == OperandType.I32) + if (operation.Intrinsic == Intrinsic.X86Cvtsi2si) { - context.Assembler.Movd(dest, source); // int _mm_cvtsi128_si32(__m128i a) + if (dest.Type == OperandType.I32) + { + context.Assembler.Movd(dest, source); // int _mm_cvtsi128_si32(__m128i a) + } + else /* if (dest.Type == OperandType.I64) */ + { + context.Assembler.Movq(dest, source); // __int64 _mm_cvtsi128_si64(__m128i a) + } } - else /* if (dest.Type == OperandType.I64) */ + else { - context.Assembler.Movq(dest, source); // __int64 _mm_cvtsi128_si64(__m128i a) + context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type); } - } - else - { - context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type); - } - break; - } + break; + } case IntrinsicType.Binary: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); - EnsureSameType(dest, src1); + EnsureSameType(dest, src1); - if (!HardwareCapabilities.SupportsVexEncoding) - { - EnsureSameReg(dest, src1); - } + if (!HardwareCapabilities.SupportsVexEncoding) + { + EnsureSameReg(dest, src1); + } - Debug.Assert(!dest.Type.IsInteger()); - Debug.Assert(!src2.Type.IsInteger() || src2.Kind == OperandKind.Constant); + Debug.Assert(!dest.Type.IsInteger()); + Debug.Assert(!src2.Type.IsInteger() || src2.Kind == OperandKind.Constant); - context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); + context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); - break; - } + break; + } case IntrinsicType.BinaryGpr: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); - EnsureSameType(dest, src1); + EnsureSameType(dest, src1); - if (!HardwareCapabilities.SupportsVexEncoding) - { - EnsureSameReg(dest, src1); - } + if (!HardwareCapabilities.SupportsVexEncoding) + { + EnsureSameReg(dest, src1); + } - Debug.Assert(!dest.Type.IsInteger() && src2.Type.IsInteger()); + Debug.Assert(!dest.Type.IsInteger() && src2.Type.IsInteger()); - context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type); + context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type); - break; - } + break; + } case IntrinsicType.Crc32: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); - EnsureSameReg(dest, src1); + EnsureSameReg(dest, src1); - Debug.Assert(dest.Type.IsInteger() && src1.Type.IsInteger() && src2.Type.IsInteger()); + Debug.Assert(dest.Type.IsInteger() && src1.Type.IsInteger() && src2.Type.IsInteger()); - context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type); + context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type); - break; - } + break; + } case IntrinsicType.BinaryImm: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); - EnsureSameType(dest, src1); + EnsureSameType(dest, src1); - if (!HardwareCapabilities.SupportsVexEncoding) - { - EnsureSameReg(dest, src1); - } + if (!HardwareCapabilities.SupportsVexEncoding) + { + EnsureSameReg(dest, src1); + } - Debug.Assert(!dest.Type.IsInteger() && src2.Kind == OperandKind.Constant); + Debug.Assert(!dest.Type.IsInteger() && src2.Kind == OperandKind.Constant); - context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte()); + context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte()); - break; - } + break; + } case IntrinsicType.Ternary: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); - Operand src3 = operation.GetSource(2); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + Operand src3 = operation.GetSource(2); - EnsureSameType(dest, src1, src2, src3); + EnsureSameType(dest, src1, src2, src3); - Debug.Assert(!dest.Type.IsInteger()); + Debug.Assert(!dest.Type.IsInteger()); - if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding) - { - context.Assembler.WriteInstruction(X86Instruction.Vblendvpd, dest, src1, src2, src3); - } - else if (info.Inst == X86Instruction.Blendvps && HardwareCapabilities.SupportsVexEncoding) - { - context.Assembler.WriteInstruction(X86Instruction.Vblendvps, dest, src1, src2, src3); - } - else if (info.Inst == X86Instruction.Pblendvb && HardwareCapabilities.SupportsVexEncoding) - { - context.Assembler.WriteInstruction(X86Instruction.Vpblendvb, dest, src1, src2, src3); - } - else - { - EnsureSameReg(dest, src1); + if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding) + { + context.Assembler.WriteInstruction(X86Instruction.Vblendvpd, dest, src1, src2, src3); + } + else if (info.Inst == X86Instruction.Blendvps && HardwareCapabilities.SupportsVexEncoding) + { + context.Assembler.WriteInstruction(X86Instruction.Vblendvps, dest, src1, src2, src3); + } + else if (info.Inst == X86Instruction.Pblendvb && HardwareCapabilities.SupportsVexEncoding) + { + context.Assembler.WriteInstruction(X86Instruction.Vpblendvb, dest, src1, src2, src3); + } + else + { + EnsureSameReg(dest, src1); - Debug.Assert(src3.GetRegister().Index == 0); + Debug.Assert(src3.GetRegister().Index == 0); - context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); - } + context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); + } - break; - } + break; + } case IntrinsicType.TernaryImm: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); - Operand src3 = operation.GetSource(2); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + Operand src3 = operation.GetSource(2); - EnsureSameType(dest, src1, src2); + EnsureSameType(dest, src1, src2); - if (!HardwareCapabilities.SupportsVexEncoding) - { - EnsureSameReg(dest, src1); - } + if (!HardwareCapabilities.SupportsVexEncoding) + { + EnsureSameReg(dest, src1); + } - Debug.Assert(!dest.Type.IsInteger() && src3.Kind == OperandKind.Constant); + Debug.Assert(!dest.Type.IsInteger() && src3.Kind == OperandKind.Constant); - context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte()); + context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte()); - break; - } + break; + } case IntrinsicType.Fma: - { - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); - Operand src2 = operation.GetSource(1); - Operand src3 = operation.GetSource(2); + { + Operand dest = operation.Destination; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + Operand src3 = operation.GetSource(2); - Debug.Assert(HardwareCapabilities.SupportsVexEncoding); + Debug.Assert(HardwareCapabilities.SupportsVexEncoding); - Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register); - Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory); + Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register); + Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory); - EnsureSameType(dest, src1, src2, src3); - Debug.Assert(dest.Type == OperandType.V128); + EnsureSameType(dest, src1, src2, src3); + Debug.Assert(dest.Type == OperandType.V128); - Debug.Assert(dest.Value == src1.Value); + Debug.Assert(dest.Value == src1.Value); - context.Assembler.WriteInstruction(info.Inst, dest, src2, src3); + context.Assembler.WriteInstruction(info.Inst, dest, src2, src3); - break; - } + break; + } } } else @@ -592,7 +594,7 @@ private static void GenerateBitwiseExclusiveOr(CodeGenContext context, Operation private static void GenerateBitwiseNot(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -630,7 +632,7 @@ private static void GenerateBranchIf(CodeGenContext context, Operation operation private static void GenerateByteSwap(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -761,19 +763,19 @@ private static void GenerateConditionalSelect(CodeGenContext context, Operation Operand src2 = operation.GetSource(1); Operand src3 = operation.GetSource(2); - EnsureSameReg (dest, src3); + EnsureSameReg(dest, src3); EnsureSameType(dest, src2, src3); Debug.Assert(dest.Type.IsInteger()); Debug.Assert(src1.Type == OperandType.I32); - context.Assembler.Test (src1, src1, src1.Type); + context.Assembler.Test(src1, src1, src1.Type); context.Assembler.Cmovcc(dest, src2, dest.Type, X86Condition.NotEqual); } private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64); @@ -783,7 +785,7 @@ private static void GenerateConvertI64ToI32(CodeGenContext context, Operation op private static void GenerateConvertToFP(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); @@ -794,7 +796,7 @@ private static void GenerateConvertToFP(CodeGenContext context, Operation operat if (source.Type.IsInteger()) { - context.Assembler.Xorps (dest, dest, dest); + context.Assembler.Xorps(dest, dest, dest); context.Assembler.Cvtsi2ss(dest, dest, source, source.Type); } else /* if (source.Type == OperandType.FP64) */ @@ -810,7 +812,7 @@ private static void GenerateConvertToFP(CodeGenContext context, Operation operat if (source.Type.IsInteger()) { - context.Assembler.Xorps (dest, dest, dest); + context.Assembler.Xorps(dest, dest, dest); context.Assembler.Cvtsi2sd(dest, dest, source, source.Type); } else /* if (source.Type == OperandType.FP32) */ @@ -824,7 +826,7 @@ private static void GenerateConvertToFP(CodeGenContext context, Operation operat private static void GenerateCopy(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); EnsureSameType(dest, source); @@ -837,7 +839,7 @@ private static void GenerateCopy(CodeGenContext context, Operation operation) return; } - if (dest.Kind == OperandKind.Register && + if (dest.Kind == OperandKind.Register && source.Kind == OperandKind.Constant && source.Value == 0) { // Assemble "mov reg, 0" as "xor reg, reg" as the later is more efficient. @@ -855,7 +857,7 @@ private static void GenerateCopy(CodeGenContext context, Operation operation) private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); EnsureSameType(dest, source); @@ -888,9 +890,9 @@ private static void GenerateCountLeadingZeros(CodeGenContext context, Operation private static void GenerateDivide(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand dividend = operation.GetSource(0); - Operand divisor = operation.GetSource(1); + Operand divisor = operation.GetSource(1); if (!dest.Type.IsInteger()) { @@ -938,7 +940,7 @@ private static void GenerateDivideUI(CodeGenContext context, Operation operation private static void GenerateFill(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand offset = operation.GetSource(0); Debug.Assert(offset.Kind == OperandKind.Constant); @@ -954,7 +956,7 @@ private static void GenerateFill(CodeGenContext context, Operation operation) private static void GenerateLoad(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = Memory(operation.GetSource(0), value.Type); GenerateLoad(context, address, value); @@ -962,7 +964,7 @@ private static void GenerateLoad(CodeGenContext context, Operation operation) private static void GenerateLoad16(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = Memory(operation.GetSource(0), value.Type); Debug.Assert(value.Type.IsInteger()); @@ -972,7 +974,7 @@ private static void GenerateLoad16(CodeGenContext context, Operation operation) private static void GenerateLoad8(CodeGenContext context, Operation operation) { - Operand value = operation.Destination; + Operand value = operation.Destination; Operand address = Memory(operation.GetSource(0), value.Type); Debug.Assert(value.Type.IsInteger()); @@ -1039,7 +1041,7 @@ private static void GenerateMultiply64HighUI(CodeGenContext context, Operation o private static void GenerateNegate(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); ValidateUnOp(dest, source); @@ -1102,7 +1104,7 @@ private static void GenerateShiftRightUI(CodeGenContext context, Operation opera private static void GenerateSignExtend16(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1112,7 +1114,7 @@ private static void GenerateSignExtend16(CodeGenContext context, Operation opera private static void GenerateSignExtend32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1122,7 +1124,7 @@ private static void GenerateSignExtend32(CodeGenContext context, Operation opera private static void GenerateSignExtend8(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1158,7 +1160,7 @@ private static void GenerateSpill(CodeGenContext context, Operation operation, i private static void GenerateStackAlloc(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand offset = operation.GetSource(0); Debug.Assert(offset.Kind == OperandKind.Constant); @@ -1174,7 +1176,7 @@ private static void GenerateStackAlloc(CodeGenContext context, Operation operati private static void GenerateStore(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = Memory(operation.GetSource(0), value.Type); GenerateStore(context, address, value); @@ -1182,7 +1184,7 @@ private static void GenerateStore(CodeGenContext context, Operation operation) private static void GenerateStore16(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = Memory(operation.GetSource(0), value.Type); Debug.Assert(value.Type.IsInteger()); @@ -1192,7 +1194,7 @@ private static void GenerateStore16(CodeGenContext context, Operation operation) private static void GenerateStore8(CodeGenContext context, Operation operation) { - Operand value = operation.GetSource(1); + Operand value = operation.GetSource(1); Operand address = Memory(operation.GetSource(0), value.Type); Debug.Assert(value.Type.IsInteger()); @@ -1231,7 +1233,7 @@ private static void GenerateTailcall(CodeGenContext context, Operation operation private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(!dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1278,7 +1280,7 @@ private static void GenerateVectorExtract(CodeGenContext context, Operation oper mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8); context.Assembler.Pshufd(src1, src1, (byte)mask0); - context.Assembler.Movd (dest, src1); + context.Assembler.Movd(dest, src1); context.Assembler.Pshufd(src1, src1, (byte)mask1); } } @@ -1294,11 +1296,11 @@ private static void GenerateVectorExtract(CodeGenContext context, Operation oper } else { - const byte mask = 0b01_00_11_10; + const byte Mask = 0b01_00_11_10; - context.Assembler.Pshufd(src1, src1, mask); - context.Assembler.Movq (dest, src1); - context.Assembler.Pshufd(src1, src1, mask); + context.Assembler.Pshufd(src1, src1, Mask); + context.Assembler.Movq(dest, src1); + context.Assembler.Pshufd(src1, src1, Mask); } } else @@ -1308,7 +1310,7 @@ private static void GenerateVectorExtract(CodeGenContext context, Operation oper (index == 1 && dest.Type == OperandType.FP64)) { context.Assembler.Movhlps(dest, dest, src1); - context.Assembler.Movq (dest, dest); + context.Assembler.Movq(dest, dest); } else { @@ -1455,11 +1457,11 @@ void InsertIntSse2(int words) int mask0 = 0b11_10_01_00; int mask1 = 0b11_10_01_00; - mask0 = BitUtils.RotateRight(mask0, index * 2, 8); + mask0 = BitUtils.RotateRight(mask0, index * 2, 8); mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8); context.Assembler.Pshufd(src1, src1, (byte)mask0); // Lane to be inserted in position 0. - context.Assembler.Movss (dest, src1, src2); // dest[127:0] = src1[127:32] | src2[31:0] + context.Assembler.Movss(dest, src1, src2); // dest[127:0] = src1[127:32] | src2[31:0] context.Assembler.Pshufd(dest, dest, (byte)mask1); // Inserted lane in original position. if (dest.GetRegister() != src1.GetRegister()) @@ -1555,7 +1557,7 @@ private static void GenerateVectorZero(CodeGenContext context, Operation operati private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); @@ -1565,7 +1567,7 @@ private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); @@ -1575,7 +1577,7 @@ private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation private static void GenerateZeroExtend16(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1585,7 +1587,7 @@ private static void GenerateZeroExtend16(CodeGenContext context, Operation opera private static void GenerateZeroExtend32(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1601,7 +1603,7 @@ private static void GenerateZeroExtend32(CodeGenContext context, Operation opera private static void GenerateZeroExtend8(CodeGenContext context, Operation operation) { - Operand dest = operation.Destination; + Operand dest = operation.Destination; Operand source = operation.GetSource(0); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); @@ -1613,13 +1615,25 @@ private static void GenerateLoad(CodeGenContext context, Operand address, Operan { switch (value.Type) { - case OperandType.I32: context.Assembler.Mov (value, address, OperandType.I32); break; - case OperandType.I64: context.Assembler.Mov (value, address, OperandType.I64); break; - case OperandType.FP32: context.Assembler.Movd (value, address); break; - case OperandType.FP64: context.Assembler.Movq (value, address); break; - case OperandType.V128: context.Assembler.Movdqu(value, address); break; - - default: Debug.Assert(false); break; + case OperandType.I32: + context.Assembler.Mov(value, address, OperandType.I32); + break; + case OperandType.I64: + context.Assembler.Mov(value, address, OperandType.I64); + break; + case OperandType.FP32: + context.Assembler.Movd(value, address); + break; + case OperandType.FP64: + context.Assembler.Movq(value, address); + break; + case OperandType.V128: + context.Assembler.Movdqu(value, address); + break; + + default: + Debug.Assert(false); + break; } } @@ -1627,13 +1641,25 @@ private static void GenerateStore(CodeGenContext context, Operand address, Opera { switch (value.Type) { - case OperandType.I32: context.Assembler.Mov (address, value, OperandType.I32); break; - case OperandType.I64: context.Assembler.Mov (address, value, OperandType.I64); break; - case OperandType.FP32: context.Assembler.Movd (address, value); break; - case OperandType.FP64: context.Assembler.Movq (address, value); break; - case OperandType.V128: context.Assembler.Movdqu(address, value); break; - - default: Debug.Assert(false); break; + case OperandType.I32: + context.Assembler.Mov(address, value, OperandType.I32); + break; + case OperandType.I64: + context.Assembler.Mov(address, value, OperandType.I64); + break; + case OperandType.FP32: + context.Assembler.Movd(address, value); + break; + case OperandType.FP64: + context.Assembler.Movq(address, value); + break; + case OperandType.V128: + context.Assembler.Movdqu(address, value); + break; + + default: + Debug.Assert(false); + break; } } @@ -1670,21 +1696,21 @@ private static bool MatchOperation(Operation node, Instruction inst, OperandType [Conditional("DEBUG")] private static void ValidateUnOp(Operand dest, Operand source) { - EnsureSameReg (dest, source); + EnsureSameReg(dest, source); EnsureSameType(dest, source); } [Conditional("DEBUG")] private static void ValidateBinOp(Operand dest, Operand src1, Operand src2) { - EnsureSameReg (dest, src1); + EnsureSameReg(dest, src1); EnsureSameType(dest, src1, src2); } [Conditional("DEBUG")] private static void ValidateShift(Operand dest, Operand src1, Operand src2) { - EnsureSameReg (dest, src1); + EnsureSameReg(dest, src1); EnsureSameType(dest, src1); Debug.Assert(dest.Type.IsInteger() && src2.Type == OperandType.I32); @@ -1722,7 +1748,7 @@ private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operan private static UnwindInfo WritePrologue(CodeGenContext context) { - List pushEntries = new List(); + List pushEntries = new(); Operand rsp = Register(X86Register.Rsp); @@ -1827,11 +1853,11 @@ private static void GenerateInlineStackProbe(CodeGenContext context, int size) // that the OS will map all pages that we'll use. We do that by // doing a dummy read on those pages, forcing a page fault and // the OS to map them. If they are already mapped, nothing happens. - const int pageMask = PageSize - 1; + const int PageMask = PageSize - 1; - size = (size + pageMask) & ~pageMask; + size = (size + PageMask) & ~PageMask; - Operand rsp = Register(X86Register.Rsp); + Operand rsp = Register(X86Register.Rsp); Operand temp = Register(CallingConvention.GetIntReturnRegister()); for (int offset = PageSize; offset < size; offset += PageSize) @@ -1862,4 +1888,4 @@ private static Operand Xmm(X86Register register) return Operand.Factory.Register((int)register, RegisterType.Vector, OperandType.V128); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs b/src/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs index 07cdcd096..4f6f1e87b 100644 --- a/src/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs +++ b/src/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs @@ -47,7 +47,7 @@ private static uint GetXcr0Eax() 0xc3, // ret }; - using MemoryBlock memGetXcr0 = new MemoryBlock((ulong)asmGetXcr0.Length); + using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length); memGetXcr0.Write(0, asmGetXcr0); @@ -62,7 +62,7 @@ private static uint GetXcr0Eax() public enum FeatureFlags1Edx { Sse = 1 << 25, - Sse2 = 1 << 26 + Sse2 = 1 << 26, } [Flags] @@ -79,7 +79,7 @@ public enum FeatureFlags1Ecx Xsave = 1 << 26, Osxsave = 1 << 27, Avx = 1 << 28, - F16c = 1 << 29 + F16c = 1 << 29, } [Flags] @@ -90,7 +90,7 @@ public enum FeatureFlags7Ebx Avx512dq = 1 << 17, Sha = 1 << 29, Avx512bw = 1 << 30, - Avx512vl = 1 << 31 + Avx512vl = 1 << 31, } [Flags] @@ -106,7 +106,7 @@ public enum Xcr0FlagsEax YmmHi128 = 1 << 2, Opmask = 1 << 5, ZmmHi256 = 1 << 6, - Hi16Zmm = 1 << 7 + Hi16Zmm = 1 << 7, } public static FeatureFlags1Edx FeatureInfo1Edx { get; } @@ -141,4 +141,4 @@ public enum Xcr0FlagsEax public static bool SupportsVexEncoding => SupportsAvx && !ForceLegacySse; public static bool SupportsEvexEncoding => SupportsAvx512F && !ForceLegacySse; } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/IntrinsicInfo.cs b/src/ARMeilleure/CodeGen/X86/IntrinsicInfo.cs index 302bf4d3c..16054c616 100644 --- a/src/ARMeilleure/CodeGen/X86/IntrinsicInfo.cs +++ b/src/ARMeilleure/CodeGen/X86/IntrinsicInfo.cs @@ -3,7 +3,7 @@ namespace ARMeilleure.CodeGen.X86 readonly struct IntrinsicInfo { public X86Instruction Inst { get; } - public IntrinsicType Type { get; } + public IntrinsicType Type { get; } public IntrinsicInfo(X86Instruction inst, IntrinsicType type) { @@ -11,4 +11,4 @@ public IntrinsicInfo(X86Instruction inst, IntrinsicType type) Type = type; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/IntrinsicTable.cs b/src/ARMeilleure/CodeGen/X86/IntrinsicTable.cs index e3d94b7ae..daa1f8f60 100644 --- a/src/ARMeilleure/CodeGen/X86/IntrinsicTable.cs +++ b/src/ARMeilleure/CodeGen/X86/IntrinsicTable.cs @@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.X86 { static class IntrinsicTable { - private static IntrinsicInfo[] _intrinTable; + private static readonly IntrinsicInfo[] _intrinTable; static IntrinsicTable() { _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; +#pragma warning disable IDE0055 // Disable formatting Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary)); Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary)); Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary)); @@ -185,6 +186,7 @@ static IntrinsicTable() Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm)); Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary)); Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary)); +#pragma warning restore IDE0055 } private static void Add(Intrinsic intrin, IntrinsicInfo info) @@ -197,4 +199,4 @@ public static IntrinsicInfo GetInfo(Intrinsic intrin) return _intrinTable[(int)intrin]; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/IntrinsicType.cs b/src/ARMeilleure/CodeGen/X86/IntrinsicType.cs index 5a9c14afa..7c3ef354d 100644 --- a/src/ARMeilleure/CodeGen/X86/IntrinsicType.cs +++ b/src/ARMeilleure/CodeGen/X86/IntrinsicType.cs @@ -13,6 +13,6 @@ enum IntrinsicType Crc32, Ternary, TernaryImm, - Fma + Fma, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/Mxcsr.cs b/src/ARMeilleure/CodeGen/X86/Mxcsr.cs index c61eac31a..719afe59e 100644 --- a/src/ARMeilleure/CodeGen/X86/Mxcsr.cs +++ b/src/ARMeilleure/CodeGen/X86/Mxcsr.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.X86 { @@ -10,6 +10,6 @@ enum Mxcsr Rlo = 1 << 13, // Round Mode low bit. Um = 1 << 11, // Underflow Mask. Dm = 1 << 8, // Denormal Mask. - Daz = 1 << 6 // Denormals Are Zero. + Daz = 1 << 6, // Denormals Are Zero. } } diff --git a/src/ARMeilleure/CodeGen/X86/PreAllocator.cs b/src/ARMeilleure/CodeGen/X86/PreAllocator.cs index cb742d67f..590c35c7b 100644 --- a/src/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/src/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -104,11 +104,11 @@ public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out case Instruction.Tailcall: if (callConv == CallConvName.Windows) { - PreAllocatorWindows.InsertTailcallCopies(block.Operations, stackAlloc, node); + PreAllocatorWindows.InsertTailcallCopies(block.Operations, node); } else { - PreAllocatorSystemV.InsertTailcallCopies(block.Operations, stackAlloc, node); + PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node); } break; @@ -177,10 +177,7 @@ protected static void InsertConstantRegCopies(IntrusiveList nodes, Op { src2 = node.GetSource(1); - Operand temp = src1; - - src1 = src2; - src2 = temp; + (src2, src1) = (src1, src2); node.SetSource(0, src1); node.SetSource(1, src2); @@ -228,151 +225,151 @@ protected static void InsertConstrainedRegCopies(IntrusiveList nodes, case Instruction.CompareAndSwap: case Instruction.CompareAndSwap16: case Instruction.CompareAndSwap8: - { - OperandType type = node.GetSource(1).Type; - - if (type == OperandType.V128) { - // Handle the many restrictions of the compare and exchange (16 bytes) instruction: - // - The expected value should be in RDX:RAX. - // - The new value to be written should be in RCX:RBX. - // - The value at the memory location is loaded to RDX:RAX. - void SplitOperand(Operand source, Operand lr, Operand hr) + OperandType type = node.GetSource(1).Type; + + if (type == OperandType.V128) { - nodes.AddBefore(node, Operation(Instruction.VectorExtract, lr, source, Const(0))); - nodes.AddBefore(node, Operation(Instruction.VectorExtract, hr, source, Const(1))); - } + // Handle the many restrictions of the compare and exchange (16 bytes) instruction: + // - The expected value should be in RDX:RAX. + // - The new value to be written should be in RCX:RBX. + // - The value at the memory location is loaded to RDX:RAX. + void SplitOperand(Operand source, Operand lr, Operand hr) + { + nodes.AddBefore(node, Operation(Instruction.VectorExtract, lr, source, Const(0))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, hr, source, Const(1))); + } - Operand rax = Gpr(X86Register.Rax, OperandType.I64); - Operand rbx = Gpr(X86Register.Rbx, OperandType.I64); - Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); - Operand rdx = Gpr(X86Register.Rdx, OperandType.I64); + Operand rax = Gpr(X86Register.Rax, OperandType.I64); + Operand rbx = Gpr(X86Register.Rbx, OperandType.I64); + Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); + Operand rdx = Gpr(X86Register.Rdx, OperandType.I64); - SplitOperand(node.GetSource(1), rax, rdx); - SplitOperand(node.GetSource(2), rbx, rcx); + SplitOperand(node.GetSource(1), rax, rdx); + SplitOperand(node.GetSource(2), rbx, rcx); - Operation operation = node; + Operation operation = node; - node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); - nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); + node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); + nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); - operation.SetDestinations(new Operand[] { rdx, rax }); - operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx }); - } - else - { - // Handle the many restrictions of the compare and exchange (32/64) instruction: - // - The expected value should be in (E/R)AX. - // - The value at the memory location is loaded to (E/R)AX. - Operand expected = node.GetSource(1); - Operand newValue = node.GetSource(2); + operation.SetDestinations(new Operand[] { rdx, rax }); + operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx }); + } + else + { + // Handle the many restrictions of the compare and exchange (32/64) instruction: + // - The expected value should be in (E/R)AX. + // - The value at the memory location is loaded to (E/R)AX. + Operand expected = node.GetSource(1); + Operand newValue = node.GetSource(2); - Operand rax = Gpr(X86Register.Rax, expected.Type); + Operand rax = Gpr(X86Register.Rax, expected.Type); - nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected)); + nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected)); - // We need to store the new value into a temp, since it may - // be a constant, and this instruction does not support immediate operands. - Operand temp = Local(newValue.Type); + // We need to store the new value into a temp, since it may + // be a constant, and this instruction does not support immediate operands. + Operand temp = Local(newValue.Type); - nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue)); + nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue)); - node.SetSources(new Operand[] { node.GetSource(0), rax, temp }); + node.SetSources(new Operand[] { node.GetSource(0), rax, temp }); - nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); + nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); - node.Destination = rax; - } + node.Destination = rax; + } - break; - } + break; + } case Instruction.Divide: case Instruction.DivideUI: - { - // Handle the many restrictions of the division instructions: - // - The dividend is always in RDX:RAX. - // - The result is always in RAX. - // - Additionally it also writes the remainder in RDX. - if (dest.Type.IsInteger()) { - Operand src1 = node.GetSource(0); + // Handle the many restrictions of the division instructions: + // - The dividend is always in RDX:RAX. + // - The result is always in RAX. + // - Additionally it also writes the remainder in RDX. + if (dest.Type.IsInteger()) + { + Operand src1 = node.GetSource(0); - Operand rax = Gpr(X86Register.Rax, src1.Type); - Operand rdx = Gpr(X86Register.Rdx, src1.Type); + Operand rax = Gpr(X86Register.Rax, src1.Type); + Operand rdx = Gpr(X86Register.Rdx, src1.Type); - nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); - nodes.AddBefore(node, Operation(Instruction.Clobber, rdx)); + nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); + nodes.AddBefore(node, Operation(Instruction.Clobber, rdx)); - nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); + nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); - node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) }); - node.Destination = rax; - } + node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) }); + node.Destination = rax; + } - break; - } + break; + } case Instruction.Extended: - { - bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd || + { + bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd || node.Intrinsic == Intrinsic.X86Blendvps || node.Intrinsic == Intrinsic.X86Pblendvb; - // BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported. - // SHA256RNDS2 always has an implied XMM0 as a last operand. - if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2) - { - Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128); + // BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported. + // SHA256RNDS2 always has an implied XMM0 as a last operand. + if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2) + { + Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128); - nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, node.GetSource(2))); + nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, node.GetSource(2))); - node.SetSource(2, xmm0); - } + node.SetSource(2, xmm0); + } - break; - } + break; + } case Instruction.Multiply64HighSI: case Instruction.Multiply64HighUI: - { - // Handle the many restrictions of the i64 * i64 = i128 multiply instructions: - // - The multiplicand is always in RAX. - // - The lower 64-bits of the result is always in RAX. - // - The higher 64-bits of the result is always in RDX. - Operand src1 = node.GetSource(0); + { + // Handle the many restrictions of the i64 * i64 = i128 multiply instructions: + // - The multiplicand is always in RAX. + // - The lower 64-bits of the result is always in RAX. + // - The higher 64-bits of the result is always in RDX. + Operand src1 = node.GetSource(0); - Operand rax = Gpr(X86Register.Rax, src1.Type); - Operand rdx = Gpr(X86Register.Rdx, src1.Type); + Operand rax = Gpr(X86Register.Rax, src1.Type); + Operand rdx = Gpr(X86Register.Rdx, src1.Type); - nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); + nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); - node.SetSource(0, rax); + node.SetSource(0, rax); - nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx)); + nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx)); - node.SetDestinations(new Operand[] { rdx, rax }); + node.SetDestinations(new Operand[] { rdx, rax }); - break; - } + break; + } case Instruction.RotateRight: case Instruction.ShiftLeft: case Instruction.ShiftRightSI: case Instruction.ShiftRightUI: - { - // The shift register is always implied to be CL (low 8-bits of RCX or ECX). - if (node.GetSource(1).Kind == OperandKind.LocalVariable) { - Operand rcx = Gpr(X86Register.Rcx, OperandType.I32); + // The shift register is always implied to be CL (low 8-bits of RCX or ECX). + if (node.GetSource(1).Kind == OperandKind.LocalVariable) + { + Operand rcx = Gpr(X86Register.Rcx, OperandType.I32); - nodes.AddBefore(node, Operation(Instruction.Copy, rcx, node.GetSource(1))); + nodes.AddBefore(node, Operation(Instruction.Copy, rcx, node.GetSource(1))); - node.SetSource(1, rcx); - } + node.SetSource(1, rcx); + } - break; - } + break; + } } } @@ -459,7 +456,7 @@ private static void GenerateConvertToFPUI(IntrusiveList nodes, Operat // Unsigned integer to FP conversions are not supported on X86. // We need to turn them into signed integer to FP conversions, and // adjust the final result. - Operand dest = node.Destination; + Operand dest = node.Destination; Operand source = node.GetSource(0); Debug.Assert(source.Type.IsInteger(), $"Invalid source type \"{source.Type}\"."); @@ -472,8 +469,8 @@ private static void GenerateConvertToFPUI(IntrusiveList nodes, Operat // and then use the 64-bits signed conversion instructions. Operand zex = Local(OperandType.I64); - node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source)); - node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex)); + node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source)); + nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex)); } else /* if (source.Type == OperandType.I64) */ { @@ -487,15 +484,15 @@ private static void GenerateConvertToFPUI(IntrusiveList nodes, Operat // --- This can be done efficiently by adding the result to itself. // -- Then, we need to add the least significant bit that was shifted out. // --- We can convert the least significant bit to float, and add it to the result. - Operand lsb = Local(OperandType.I64); + Operand lsb = Local(OperandType.I64); Operand half = Local(OperandType.I64); Operand lsbF = Local(dest.Type); - node = nodes.AddAfter(node, Operation(Instruction.Copy, lsb, source)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, lsb, source)); node = nodes.AddAfter(node, Operation(Instruction.Copy, half, source)); - node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L))); node = nodes.AddAfter(node, Operation(Instruction.ShiftRightUI, half, half, Const(1))); node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, lsbF, lsb)); @@ -513,7 +510,7 @@ private static void GenerateNegate(IntrusiveList nodes, Operation nod // There's no SSE FP negate instruction, so we need to transform that into // a XOR of the value to be negated with a mask with the highest bit set. // This also produces -0 for a negation of the value 0. - Operand dest = node.Destination; + Operand dest = node.Destination; Operand source = node.GetSource(0); Debug.Assert(dest.Type == OperandType.FP32 || @@ -569,14 +566,14 @@ private static void GenerateVectorInsert8(IntrusiveList nodes, Operat if ((index & 1) != 0) { node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp1, temp1)); - node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); - node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); + node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } else { node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp2, temp2)); - node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); - node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); @@ -709,16 +706,11 @@ private static bool IsVexSameOperandDestSrc1(Operation operation) private static bool HasConstSrc1(Instruction inst) { - switch (inst) + return inst switch { - case Instruction.Copy: - case Instruction.LoadArgument: - case Instruction.Spill: - case Instruction.SpillArg: - return true; - } - - return false; + Instruction.Copy or Instruction.LoadArgument or Instruction.Spill or Instruction.SpillArg => true, + _ => false, + }; } private static bool HasConstSrc2(Instruction inst) @@ -762,15 +754,15 @@ private static bool IsCommutative(Operation operation) case Instruction.BranchIf: case Instruction.Compare: - { - Operand comp = operation.GetSource(2); + { + Operand comp = operation.GetSource(2); - Debug.Assert(comp.Kind == OperandKind.Constant); + Debug.Assert(comp.Kind == OperandKind.Constant); - var compType = (Comparison)comp.AsInt32(); + var compType = (Comparison)comp.AsInt32(); - return compType == Comparison.Equal || compType == Comparison.NotEqual; - } + return compType == Comparison.Equal || compType == Comparison.NotEqual; + } } return false; @@ -793,4 +785,4 @@ private static bool IsXmmIntrinsic(Operation operation) return info.Type != IntrinsicType.Crc32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/PreAllocatorSystemV.cs b/src/ARMeilleure/CodeGen/X86/PreAllocatorSystemV.cs index a84d5050d..e754cb09b 100644 --- a/src/ARMeilleure/CodeGen/X86/PreAllocatorSystemV.cs +++ b/src/ARMeilleure/CodeGen/X86/PreAllocatorSystemV.cs @@ -1,4 +1,3 @@ -using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; @@ -15,9 +14,9 @@ public static void InsertCallCopies(IntrusiveList nodes, Operation no { Operand dest = node.Destination; - List sources = new List + List sources = new() { - node.GetSource(0) + node.GetSource(0), }; int argsCount = node.SourcesCount - 1; @@ -52,10 +51,10 @@ public static void InsertCallCopies(IntrusiveList nodes, Operation no if (source.Type == OperandType.V128 && passOnReg) { // V128 is a struct, we pass each half on a GPR if possible. - Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); + Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); - nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1))); continue; @@ -91,7 +90,7 @@ public static void InsertCallCopies(IntrusiveList nodes, Operation no { if (dest.Type == OperandType.V128) { - Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); + Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operation operation = node; @@ -116,11 +115,11 @@ public static void InsertCallCopies(IntrusiveList nodes, Operation no } } - public static void InsertTailcallCopies(IntrusiveList nodes, StackAllocator stackAlloc, Operation node) + public static void InsertTailcallCopies(IntrusiveList nodes, Operation node) { - List sources = new List + List sources = new() { - node.GetSource(0) + node.GetSource(0), }; int argsCount = node.SourcesCount - 1; @@ -251,11 +250,11 @@ public static Operation InsertLoadArgumentCopy( // V128 is a struct, we pass each half on a GPR if possible. Operand pArg = Local(OperandType.V128); - Operand argLReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount), OperandType.I64); + Operand argLReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount), OperandType.I64); Operand argHReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount + 1), OperandType.I64); Operation copyL = Operation(Instruction.VectorCreateScalar, pArg, argLReg); - Operation copyH = Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1)); + Operation copyH = Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1)); cctx.Cfg.Entry.Operations.AddFirst(copyH); cctx.Cfg.Entry.Operations.AddFirst(copyL); @@ -313,7 +312,7 @@ public static void InsertReturnCopy(IntrusiveList nodes, Operation no if (source.Type == OperandType.V128) { - Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); + Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0))); @@ -331,4 +330,4 @@ public static void InsertReturnCopy(IntrusiveList nodes, Operation no } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/PreAllocatorWindows.cs b/src/ARMeilleure/CodeGen/X86/PreAllocatorWindows.cs index 45319e6a5..10a2bd129 100644 --- a/src/ARMeilleure/CodeGen/X86/PreAllocatorWindows.cs +++ b/src/ARMeilleure/CodeGen/X86/PreAllocatorWindows.cs @@ -155,7 +155,7 @@ int AllocateOnStack(int size) node.SetSources(sources); } - public static void InsertTailcallCopies(IntrusiveList nodes, StackAllocator stackAlloc, Operation node) + public static void InsertTailcallCopies(IntrusiveList nodes, Operation node) { int argsCount = node.SourcesCount - 1; int maxArgs = CallingConvention.GetArgumentsOnRegsCount(); @@ -324,4 +324,4 @@ public static void InsertReturnCopy( node.SetSources(Array.Empty()); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/X86Condition.cs b/src/ARMeilleure/CodeGen/X86/X86Condition.cs index c82cbdec5..70699a207 100644 --- a/src/ARMeilleure/CodeGen/X86/X86Condition.cs +++ b/src/ARMeilleure/CodeGen/X86/X86Condition.cs @@ -5,22 +5,22 @@ namespace ARMeilleure.CodeGen.X86 { enum X86Condition { - Overflow = 0x0, - NotOverflow = 0x1, - Below = 0x2, - AboveOrEqual = 0x3, - Equal = 0x4, - NotEqual = 0x5, - BelowOrEqual = 0x6, - Above = 0x7, - Sign = 0x8, - NotSign = 0x9, - ParityEven = 0xa, - ParityOdd = 0xb, - Less = 0xc, + Overflow = 0x0, + NotOverflow = 0x1, + Below = 0x2, + AboveOrEqual = 0x3, + Equal = 0x4, + NotEqual = 0x5, + BelowOrEqual = 0x6, + Above = 0x7, + Sign = 0x8, + NotSign = 0x9, + ParityEven = 0xa, + ParityOdd = 0xb, + Less = 0xc, GreaterOrEqual = 0xd, - LessOrEqual = 0xe, - Greater = 0xf + LessOrEqual = 0xe, + Greater = 0xf, } static class ComparisonX86Extensions @@ -29,6 +29,7 @@ public static X86Condition ToX86Condition(this Comparison comp) { return comp switch { +#pragma warning disable IDE0055 // Disable formatting Comparison.Equal => X86Condition.Equal, Comparison.NotEqual => X86Condition.NotEqual, Comparison.Greater => X86Condition.Greater, @@ -39,9 +40,10 @@ public static X86Condition ToX86Condition(this Comparison comp) Comparison.Less => X86Condition.Less, Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual, Comparison.LessUI => X86Condition.Below, +#pragma warning restore IDE0055 - _ => throw new ArgumentException(null, nameof(comp)) + _ => throw new ArgumentException(null, nameof(comp)), }; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/X86Instruction.cs b/src/ARMeilleure/CodeGen/X86/X86Instruction.cs index 9a85c516f..e1979011d 100644 --- a/src/ARMeilleure/CodeGen/X86/X86Instruction.cs +++ b/src/ARMeilleure/CodeGen/X86/X86Instruction.cs @@ -226,6 +226,6 @@ enum X86Instruction Xorpd, Xorps, - Count + Count, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs b/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs index 98a19b9a2..690ca5043 100644 --- a/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs +++ b/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs @@ -1,4 +1,4 @@ -using ARMeilleure.CodeGen.Optimizations; +using ARMeilleure.CodeGen.Optimizations; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System.Collections.Generic; @@ -215,7 +215,7 @@ private static (Operand, Multiplier) GetIndexOp(ref Operand baseOp) 1 => Multiplier.x2, 2 => Multiplier.x4, 3 => Multiplier.x8, - _ => Multiplier.x1 + _ => Multiplier.x1, }; baseOp = indexOnSrc2 ? src1 : src2; diff --git a/src/ARMeilleure/CodeGen/X86/X86Register.cs b/src/ARMeilleure/CodeGen/X86/X86Register.cs index 01f63e311..0a6563663 100644 --- a/src/ARMeilleure/CodeGen/X86/X86Register.cs +++ b/src/ARMeilleure/CodeGen/X86/X86Register.cs @@ -1,5 +1,8 @@ +using System.Diagnostics.CodeAnalysis; + namespace ARMeilleure.CodeGen.X86 { + [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")] enum X86Register { Invalid = -1, @@ -12,8 +15,8 @@ enum X86Register Rbp = 5, Rsi = 6, Rdi = 7, - R8 = 8, - R9 = 9, + R8 = 8, + R9 = 9, R10 = 10, R11 = 11, R12 = 12, @@ -21,21 +24,21 @@ enum X86Register R14 = 14, R15 = 15, - Xmm0 = 0, - Xmm1 = 1, - Xmm2 = 2, - Xmm3 = 3, - Xmm4 = 4, - Xmm5 = 5, - Xmm6 = 6, - Xmm7 = 7, - Xmm8 = 8, - Xmm9 = 9, + Xmm0 = 0, + Xmm1 = 1, + Xmm2 = 2, + Xmm3 = 3, + Xmm4 = 4, + Xmm5 = 5, + Xmm6 = 6, + Xmm7 = 7, + Xmm8 = 8, + Xmm9 = 9, Xmm10 = 10, Xmm11 = 11, Xmm12 = 12, Xmm13 = 13, Xmm14 = 14, - Xmm15 = 15 + Xmm15 = 15, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Common/AddressTable.cs b/src/ARMeilleure/Common/AddressTable.cs index 9db2d00de..fcab3a202 100644 --- a/src/ARMeilleure/Common/AddressTable.cs +++ b/src/ARMeilleure/Common/AddressTable.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Diagnostics; +using ARMeilleure.Diagnostics; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -9,7 +9,7 @@ namespace ARMeilleure.Common /// Represents a table of guest address to a value. /// /// Type of the value - unsafe class AddressTable : IDisposable where TEntry : unmanaged + public unsafe class AddressTable : IDisposable where TEntry : unmanaged { /// /// Represents a level in an . diff --git a/src/ARMeilleure/Common/Allocator.cs b/src/ARMeilleure/Common/Allocator.cs index 247a8e8bc..6905a614f 100644 --- a/src/ARMeilleure/Common/Allocator.cs +++ b/src/ARMeilleure/Common/Allocator.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Common { diff --git a/src/ARMeilleure/Common/ArenaAllocator.cs b/src/ARMeilleure/Common/ArenaAllocator.cs index bce6794ad..ce8e33913 100644 --- a/src/ARMeilleure/Common/ArenaAllocator.cs +++ b/src/ARMeilleure/Common/ArenaAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -82,8 +82,10 @@ public Span AllocateSpan(ulong count) where T : unmanaged } else { - _page = new PageInfo(); - _page.Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize); + _page = new PageInfo + { + Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize), + }; _pages.Add(_page); } @@ -106,7 +108,7 @@ public void Reset() // Free excess pages that was allocated. while (_pages.Count > _pageCount) { - NativeAllocator.Instance.Free(_pages[_pages.Count - 1].Pointer); + NativeAllocator.Instance.Free(_pages[^1].Pointer); _pages.RemoveAt(_pages.Count - 1); } @@ -125,12 +127,13 @@ public void Reset() // If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time. int now = Environment.TickCount; - int count = (now - _lastReset) switch { + int count = (now - _lastReset) switch + { >= 5000 => 0, >= 2500 => 50, >= 1000 => 100, - >= 10 => 1500, - _ => 5000 + >= 10 => 1500, + _ => 5000, }; for (int i = _pages.Count - 1; i >= 0; i--) diff --git a/src/ARMeilleure/Common/BitMap.cs b/src/ARMeilleure/Common/BitMap.cs index 27ef031f3..94d47ea59 100644 --- a/src/ARMeilleure/Common/BitMap.cs +++ b/src/ARMeilleure/Common/BitMap.cs @@ -138,7 +138,7 @@ private void EnsureCapacity(int size) var newSpan = new Span(_masks, _count); oldSpan.CopyTo(newSpan); - newSpan.Slice(oldSpan.Length).Clear(); + newSpan[oldSpan.Length..].Clear(); _allocator.Free(oldMask); } @@ -176,8 +176,8 @@ public struct Enumerator : IEnumerator private int _bit; private readonly BitMap _map; - public int Current => (int)_index * IntSize + _bit; - object IEnumerator.Current => Current; + public readonly int Current => (int)_index * IntSize + _bit; + readonly object IEnumerator.Current => Current; public Enumerator(BitMap map) { @@ -214,9 +214,9 @@ public bool MoveNext() return true; } - public void Reset() { } + public readonly void Reset() { } - public void Dispose() { } + public readonly void Dispose() { } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Common/Counter.cs b/src/ARMeilleure/Common/Counter.cs index d7210d159..6db9561ca 100644 --- a/src/ARMeilleure/Common/Counter.cs +++ b/src/ARMeilleure/Common/Counter.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Common { diff --git a/src/ARMeilleure/Common/EntryTable.cs b/src/ARMeilleure/Common/EntryTable.cs index 6f2057979..625e3f73f 100644 --- a/src/ARMeilleure/Common/EntryTable.cs +++ b/src/ARMeilleure/Common/EntryTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Numerics; diff --git a/src/ARMeilleure/Common/NativeAllocator.cs b/src/ARMeilleure/Common/NativeAllocator.cs index 71c04a9b1..93c48adda 100644 --- a/src/ARMeilleure/Common/NativeAllocator.cs +++ b/src/ARMeilleure/Common/NativeAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace ARMeilleure.Common diff --git a/src/ARMeilleure/Decoders/Block.cs b/src/ARMeilleure/Decoders/Block.cs index f296d299d..bb88170da 100644 --- a/src/ARMeilleure/Decoders/Block.cs +++ b/src/ARMeilleure/Decoders/Block.cs @@ -5,10 +5,10 @@ namespace ARMeilleure.Decoders { class Block { - public ulong Address { get; set; } + public ulong Address { get; set; } public ulong EndAddress { get; set; } - public Block Next { get; set; } + public Block Next { get; set; } public Block Branch { get; set; } public bool Exit { get; set; } @@ -43,14 +43,14 @@ public void Split(Block rightBlock) rightBlock.EndAddress = EndAddress; - rightBlock.Next = Next; + rightBlock.Next = Next; rightBlock.Branch = Branch; rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); EndAddress = rightBlock.Address; - Next = rightBlock; + Next = rightBlock; Branch = null; OpCodes.RemoveRange(splitIndex, splitCount); @@ -58,9 +58,9 @@ public void Split(Block rightBlock) private static int BinarySearch(List opCodes, ulong address) { - int left = 0; + int left = 0; int middle = 0; - int right = opCodes.Count - 1; + int right = opCodes.Count - 1; while (left <= right) { @@ -92,10 +92,10 @@ public OpCode GetLastOp() { if (OpCodes.Count > 0) { - return OpCodes[OpCodes.Count - 1]; + return OpCodes[^1]; } return null; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/Condition.cs b/src/ARMeilleure/Decoders/Condition.cs index 727f897da..961825a10 100644 --- a/src/ARMeilleure/Decoders/Condition.cs +++ b/src/ARMeilleure/Decoders/Condition.cs @@ -2,22 +2,22 @@ namespace ARMeilleure.Decoders { enum Condition { - Eq = 0, - Ne = 1, + Eq = 0, + Ne = 1, GeUn = 2, LtUn = 3, - Mi = 4, - Pl = 5, - Vs = 6, - Vc = 7, + Mi = 4, + Pl = 5, + Vs = 6, + Vc = 7, GtUn = 8, LeUn = 9, - Ge = 10, - Lt = 11, - Gt = 12, - Le = 13, - Al = 14, - Nv = 15 + Ge = 10, + Lt = 11, + Gt = 12, + Le = 13, + Al = 14, + Nv = 15, } static class ConditionExtensions @@ -29,4 +29,4 @@ public static Condition Invert(this Condition cond) return (Condition)((int)cond ^ 1); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/DataOp.cs b/src/ARMeilleure/Decoders/DataOp.cs index 464d00898..f99fd5e70 100644 --- a/src/ARMeilleure/Decoders/DataOp.cs +++ b/src/ARMeilleure/Decoders/DataOp.cs @@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders { enum DataOp { - Adr = 0, + Adr = 0, Arithmetic = 1, - Logical = 2, - BitField = 3 + Logical = 2, + BitField = 3, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/Decoder.cs b/src/ARMeilleure/Decoders/Decoder.cs index 426465aaa..66d286928 100644 --- a/src/ARMeilleure/Decoders/Decoder.cs +++ b/src/ARMeilleure/Decoders/Decoder.cs @@ -20,11 +20,11 @@ static class Decoder public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode) { - List blocks = new List(); + List blocks = new(); - Queue workQueue = new Queue(); + Queue workQueue = new(); - Dictionary visited = new Dictionary(); + Dictionary visited = new(); Debug.Assert(MaxInstsPerFunctionLowCq <= MaxInstsPerFunction); @@ -38,7 +38,9 @@ Block GetBlock(ulong blkAddress) { block = new Block(blkAddress); - if ((dMode != DecoderMode.MultipleBlocks && visited.Count >= 1) || opsCount > instructionLimit || !memory.IsMapped(blkAddress)) + if ((dMode != DecoderMode.MultipleBlocks && visited.Count >= 1) || + opsCount > instructionLimit || + (visited.Count > 0 && !memory.IsMapped(blkAddress))) { block.Exit = true; block.EndAddress = blkAddress; @@ -163,7 +165,7 @@ public static bool BinarySearch(List blocks, ulong address, out int index { index = 0; - int left = 0; + int left = 0; int right = blocks.Count - 1; while (left <= right) @@ -196,9 +198,9 @@ public static bool BinarySearch(List blocks, ulong address, out int index private static void FillBlock( IMemoryManager memory, - ExecutionMode mode, - Block block, - ulong limitAddress) + ExecutionMode mode, + Block block, + ulong limitAddress) { ulong address = block.Address; int itBlockSize = 0; @@ -241,12 +243,12 @@ private static bool IsBranch(OpCode opCode) private static bool IsUnconditionalBranch(OpCode opCode) { return opCode is OpCodeBImmAl || - opCode is OpCodeBReg || IsAarch32UnconditionalBranch(opCode); + opCode is OpCodeBReg || IsAarch32UnconditionalBranch(opCode); } private static bool IsAarch32UnconditionalBranch(OpCode opCode) { - if (!(opCode is OpCode32 op)) + if (opCode is not OpCode32 op) { return false; } @@ -290,9 +292,9 @@ private static bool IsAarch32Branch(OpCode opCode) if (opCode is IOpCode32Mem opMem) { - rt = opMem.Rt; - rn = opMem.Rn; - wBack = opMem.WBack; + rt = opMem.Rt; + rn = opMem.Rn; + wBack = opMem.WBack; isLoad = opMem.IsLoad; // For the dual load, we also need to take into account the @@ -304,12 +306,12 @@ private static bool IsAarch32Branch(OpCode opCode) } else if (opCode is IOpCode32MemMult opMemMult) { - const int pcMask = 1 << RegisterAlias.Aarch32Pc; + const int PCMask = 1 << RegisterAlias.Aarch32Pc; - rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0; - rn = opMemMult.Rn; - wBack = opMemMult.PostOffset != 0; - isLoad = opMemMult.IsLoad; + rt = (opMemMult.RegisterMask & PCMask) != 0 ? RegisterAlias.Aarch32Pc : 0; + rn = opMemMult.Rn; + wBack = opMemMult.PostOffset != 0; + isLoad = opMemMult.IsLoad; } else { @@ -388,4 +390,4 @@ public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, Executio } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/DecoderHelper.cs b/src/ARMeilleure/Decoders/DecoderHelper.cs index 5227e6a19..35e573955 100644 --- a/src/ARMeilleure/Decoders/DecoderHelper.cs +++ b/src/ARMeilleure/Decoders/DecoderHelper.cs @@ -10,7 +10,7 @@ static DecoderHelper() Imm8ToFP64Table = BuildImm8ToFP64Table(); } - public static readonly uint[] Imm8ToFP32Table; + public static readonly uint[] Imm8ToFP32Table; public static readonly ulong[] Imm8ToFP64Table; private static uint[] BuildImm8ToFP32Table() @@ -40,47 +40,47 @@ private static ulong[] BuildImm8ToFP64Table() // abcdefgh -> aBbbbbbc defgh000 00000000 00000000 (B = ~b) private static uint ExpandImm8ToFP32(uint imm) { - uint MoveBit(uint bits, int from, int to) + static uint MoveBit(uint bits, int from, int to) { return ((bits >> from) & 1U) << to; } return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) | - MoveBit(imm, 6, 29) | MoveBit( imm, 6, 28) | - MoveBit(imm, 6, 27) | MoveBit( imm, 6, 26) | - MoveBit(imm, 6, 25) | MoveBit( imm, 5, 24) | - MoveBit(imm, 4, 23) | MoveBit( imm, 3, 22) | - MoveBit(imm, 2, 21) | MoveBit( imm, 1, 20) | + MoveBit(imm, 6, 29) | MoveBit(imm, 6, 28) | + MoveBit(imm, 6, 27) | MoveBit(imm, 6, 26) | + MoveBit(imm, 6, 25) | MoveBit(imm, 5, 24) | + MoveBit(imm, 4, 23) | MoveBit(imm, 3, 22) | + MoveBit(imm, 2, 21) | MoveBit(imm, 1, 20) | MoveBit(imm, 0, 19); } // abcdefgh -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = ~b) private static ulong ExpandImm8ToFP64(ulong imm) { - ulong MoveBit(ulong bits, int from, int to) + static ulong MoveBit(ulong bits, int from, int to) { return ((bits >> from) & 1UL) << to; } return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) | - MoveBit(imm, 6, 61) | MoveBit( imm, 6, 60) | - MoveBit(imm, 6, 59) | MoveBit( imm, 6, 58) | - MoveBit(imm, 6, 57) | MoveBit( imm, 6, 56) | - MoveBit(imm, 6, 55) | MoveBit( imm, 6, 54) | - MoveBit(imm, 5, 53) | MoveBit( imm, 4, 52) | - MoveBit(imm, 3, 51) | MoveBit( imm, 2, 50) | - MoveBit(imm, 1, 49) | MoveBit( imm, 0, 48); + MoveBit(imm, 6, 61) | MoveBit(imm, 6, 60) | + MoveBit(imm, 6, 59) | MoveBit(imm, 6, 58) | + MoveBit(imm, 6, 57) | MoveBit(imm, 6, 56) | + MoveBit(imm, 6, 55) | MoveBit(imm, 6, 54) | + MoveBit(imm, 5, 53) | MoveBit(imm, 4, 52) | + MoveBit(imm, 3, 51) | MoveBit(imm, 2, 50) | + MoveBit(imm, 1, 49) | MoveBit(imm, 0, 48); } public struct BitMask { public long WMask; public long TMask; - public int Pos; - public int Shift; + public int Pos; + public int Shift; public bool IsUndefined; - public static BitMask Invalid => new BitMask { IsUndefined = true }; + public static BitMask Invalid => new() { IsUndefined = true }; } public static BitMask DecodeBitMask(int opCode, bool immediate) @@ -88,7 +88,7 @@ public static BitMask DecodeBitMask(int opCode, bool immediate) int immS = (opCode >> 10) & 0x3f; int immR = (opCode >> 16) & 0x3f; - int n = (opCode >> 22) & 1; + int n = (opCode >> 22) & 1; int sf = (opCode >> 31) & 1; int length = BitUtils.HighestBitSet((~immS & 0x3f) | (n << 6)); @@ -115,7 +115,7 @@ public static BitMask DecodeBitMask(int opCode, bool immediate) if (r > 0) { - wMask = BitUtils.RotateRight(wMask, r, size); + wMask = BitUtils.RotateRight(wMask, r, size); wMask &= BitUtils.FillWithOnes(size); } @@ -124,8 +124,8 @@ public static BitMask DecodeBitMask(int opCode, bool immediate) WMask = BitUtils.Replicate(wMask, size), TMask = BitUtils.Replicate(tMask, size), - Pos = immS, - Shift = immR + Pos = immS, + Shift = immR, }; } @@ -164,4 +164,4 @@ public static bool VectorArgumentsInvalid(bool q, params int[] args) return false; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/DecoderMode.cs b/src/ARMeilleure/Decoders/DecoderMode.cs index 553620847..708d5c8fb 100644 --- a/src/ARMeilleure/Decoders/DecoderMode.cs +++ b/src/ARMeilleure/Decoders/DecoderMode.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { enum DecoderMode { @@ -6,4 +6,4 @@ enum DecoderMode SingleBlock, SingleInstruction, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode.cs b/src/ARMeilleure/Decoders/IOpCode.cs index 37ba7a4c6..9d5e3bf7a 100644 --- a/src/ARMeilleure/Decoders/IOpCode.cs +++ b/src/ARMeilleure/Decoders/IOpCode.cs @@ -14,4 +14,4 @@ interface IOpCode OperandType GetOperandType(); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32.cs b/src/ARMeilleure/Decoders/IOpCode32.cs index 126c10690..578925dee 100644 --- a/src/ARMeilleure/Decoders/IOpCode32.cs +++ b/src/ARMeilleure/Decoders/IOpCode32.cs @@ -6,4 +6,4 @@ interface IOpCode32 : IOpCode uint GetPc(); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32Alu.cs b/src/ARMeilleure/Decoders/IOpCode32Alu.cs index 69fee164c..a85ef44ad 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Alu.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Alu.cs @@ -5,4 +5,4 @@ interface IOpCode32Alu : IOpCode32, IOpCode32HasSetFlags int Rd { get; } int Rn { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32AluBf.cs b/src/ARMeilleure/Decoders/IOpCode32AluBf.cs index 206c2965e..d1fe59039 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluBf.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluBf.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluBf { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluImm.cs b/src/ARMeilleure/Decoders/IOpCode32AluImm.cs index 342fb8f6c..b89990187 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluImm : IOpCode32Alu { @@ -6,4 +6,4 @@ interface IOpCode32AluImm : IOpCode32Alu bool IsRotated { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32AluImm16.cs b/src/ARMeilleure/Decoders/IOpCode32AluImm16.cs index cd128f657..dd42a70b1 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluImm16.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluImm16.cs @@ -4,4 +4,4 @@ interface IOpCode32AluImm16 : IOpCode32Alu { int Immediate { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32AluReg.cs b/src/ARMeilleure/Decoders/IOpCode32AluReg.cs index 1612cc5c9..1a35e664c 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluReg : IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs b/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs index e899a6592..37a2c1000 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluRsImm : IOpCode32Alu { @@ -7,4 +7,4 @@ interface IOpCode32AluRsImm : IOpCode32Alu ShiftType ShiftType { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs b/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs index 879db0593..ed9859fc0 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluRsReg : IOpCode32Alu { @@ -7,4 +7,4 @@ interface IOpCode32AluRsReg : IOpCode32Alu ShiftType ShiftType { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32AluUx.cs b/src/ARMeilleure/Decoders/IOpCode32AluUx.cs index d03c7e219..d390f6b81 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluUx.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluUx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluUx : IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/IOpCode32BImm.cs b/src/ARMeilleure/Decoders/IOpCode32BImm.cs index ec7db2c26..8d22d5c40 100644 --- a/src/ARMeilleure/Decoders/IOpCode32BImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32BImm.cs @@ -1,4 +1,4 @@ namespace ARMeilleure.Decoders { interface IOpCode32BImm : IOpCode32, IOpCodeBImm { } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32BReg.cs b/src/ARMeilleure/Decoders/IOpCode32BReg.cs index 097ab4275..9badc9858 100644 --- a/src/ARMeilleure/Decoders/IOpCode32BReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32BReg.cs @@ -4,4 +4,4 @@ interface IOpCode32BReg : IOpCode32 { int Rm { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32Exception.cs b/src/ARMeilleure/Decoders/IOpCode32Exception.cs index 8f0fb81a0..c38af9078 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Exception.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Exception.cs @@ -1,7 +1,7 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32Exception { int Id { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs b/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs index 71ca6d19c..fd9337d9b 100644 --- a/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs +++ b/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs @@ -1,7 +1,7 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32HasSetFlags { bool? SetFlags { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32Mem.cs b/src/ARMeilleure/Decoders/IOpCode32Mem.cs index 6664ddffd..a34bc0e2a 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Mem.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Mem.cs @@ -13,4 +13,4 @@ interface IOpCode32Mem : IOpCode32 int Immediate { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32MemEx.cs b/src/ARMeilleure/Decoders/IOpCode32MemEx.cs index aca7200a5..5f6b9321e 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemEx.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32MemEx : IOpCode32Mem { diff --git a/src/ARMeilleure/Decoders/IOpCode32MemMult.cs b/src/ARMeilleure/Decoders/IOpCode32MemMult.cs index 4b891bc1b..0c5e48f22 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemMult.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemMult.cs @@ -12,4 +12,4 @@ interface IOpCode32MemMult : IOpCode32 int Offset { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32MemReg.cs b/src/ARMeilleure/Decoders/IOpCode32MemReg.cs index 7fe1b0229..6a63f7f69 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemReg.cs @@ -1,7 +1,7 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32MemReg : IOpCode32Mem { int Rm { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32MemRsImm.cs b/src/ARMeilleure/Decoders/IOpCode32MemRsImm.cs index 65b7ee0b4..3407e98ac 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemRsImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemRsImm.cs @@ -5,4 +5,4 @@ interface IOpCode32MemRsImm : IOpCode32Mem int Rm { get; } ShiftType ShiftType { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCode32Simd.cs b/src/ARMeilleure/Decoders/IOpCode32Simd.cs index 687254d92..0dccd2679 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Simd.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Simd.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32Simd : IOpCode32, IOpCodeSimd { } } diff --git a/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs b/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs index a0cb669c7..a8e646092 100644 --- a/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32SimdImm : IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/IOpCodeAlu.cs b/src/ARMeilleure/Decoders/IOpCodeAlu.cs index b8c28513d..059769ba9 100644 --- a/src/ARMeilleure/Decoders/IOpCodeAlu.cs +++ b/src/ARMeilleure/Decoders/IOpCodeAlu.cs @@ -7,4 +7,4 @@ interface IOpCodeAlu : IOpCode DataOp DataOp { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeAluImm.cs b/src/ARMeilleure/Decoders/IOpCodeAluImm.cs index 02f4c997b..40a69cc90 100644 --- a/src/ARMeilleure/Decoders/IOpCodeAluImm.cs +++ b/src/ARMeilleure/Decoders/IOpCodeAluImm.cs @@ -4,4 +4,4 @@ interface IOpCodeAluImm : IOpCodeAlu { long Immediate { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeAluRs.cs b/src/ARMeilleure/Decoders/IOpCodeAluRs.cs index 22540b11a..eec956982 100644 --- a/src/ARMeilleure/Decoders/IOpCodeAluRs.cs +++ b/src/ARMeilleure/Decoders/IOpCodeAluRs.cs @@ -3,8 +3,8 @@ namespace ARMeilleure.Decoders interface IOpCodeAluRs : IOpCodeAlu { int Shift { get; } - int Rm { get; } + int Rm { get; } ShiftType ShiftType { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeAluRx.cs b/src/ARMeilleure/Decoders/IOpCodeAluRx.cs index 9d16be787..e5a8559d8 100644 --- a/src/ARMeilleure/Decoders/IOpCodeAluRx.cs +++ b/src/ARMeilleure/Decoders/IOpCodeAluRx.cs @@ -3,8 +3,8 @@ namespace ARMeilleure.Decoders interface IOpCodeAluRx : IOpCodeAlu { int Shift { get; } - int Rm { get; } + int Rm { get; } IntType IntType { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeBImm.cs b/src/ARMeilleure/Decoders/IOpCodeBImm.cs index 958bff28d..9ce7512a1 100644 --- a/src/ARMeilleure/Decoders/IOpCodeBImm.cs +++ b/src/ARMeilleure/Decoders/IOpCodeBImm.cs @@ -4,4 +4,4 @@ interface IOpCodeBImm : IOpCode { long Immediate { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeCond.cs b/src/ARMeilleure/Decoders/IOpCodeCond.cs index 9808f7c08..6604f19a2 100644 --- a/src/ARMeilleure/Decoders/IOpCodeCond.cs +++ b/src/ARMeilleure/Decoders/IOpCodeCond.cs @@ -4,4 +4,4 @@ interface IOpCodeCond : IOpCode { Condition Cond { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeLit.cs b/src/ARMeilleure/Decoders/IOpCodeLit.cs index 74084a457..434e4da88 100644 --- a/src/ARMeilleure/Decoders/IOpCodeLit.cs +++ b/src/ARMeilleure/Decoders/IOpCodeLit.cs @@ -2,10 +2,10 @@ namespace ARMeilleure.Decoders { interface IOpCodeLit : IOpCode { - int Rt { get; } + int Rt { get; } long Immediate { get; } - int Size { get; } - bool Signed { get; } - bool Prefetch { get; } + int Size { get; } + bool Signed { get; } + bool Prefetch { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IOpCodeSimd.cs b/src/ARMeilleure/Decoders/IOpCodeSimd.cs index 056ef045c..598d9d7f8 100644 --- a/src/ARMeilleure/Decoders/IOpCodeSimd.cs +++ b/src/ARMeilleure/Decoders/IOpCodeSimd.cs @@ -4,4 +4,4 @@ interface IOpCodeSimd : IOpCode { int Size { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/InstDescriptor.cs b/src/ARMeilleure/Decoders/InstDescriptor.cs index 577ff3946..c35c754a9 100644 --- a/src/ARMeilleure/Decoders/InstDescriptor.cs +++ b/src/ARMeilleure/Decoders/InstDescriptor.cs @@ -4,15 +4,15 @@ namespace ARMeilleure.Decoders { readonly struct InstDescriptor { - public static InstDescriptor Undefined => new InstDescriptor(InstName.Und, InstEmit.Und); + public static InstDescriptor Undefined => new(InstName.Und, InstEmit.Und); - public InstName Name { get; } + public InstName Name { get; } public InstEmitter Emitter { get; } public InstDescriptor(InstName name, InstEmitter emitter) { - Name = name; + Name = name; Emitter = emitter; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/InstEmitter.cs b/src/ARMeilleure/Decoders/InstEmitter.cs index a8b526569..43bfcdca3 100644 --- a/src/ARMeilleure/Decoders/InstEmitter.cs +++ b/src/ARMeilleure/Decoders/InstEmitter.cs @@ -3,4 +3,4 @@ namespace ARMeilleure.Decoders { delegate void InstEmitter(ArmEmitterContext context); -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/IntType.cs b/src/ARMeilleure/Decoders/IntType.cs index 244e96805..937a569aa 100644 --- a/src/ARMeilleure/Decoders/IntType.cs +++ b/src/ARMeilleure/Decoders/IntType.cs @@ -2,13 +2,13 @@ namespace ARMeilleure.Decoders { enum IntType { - UInt8 = 0, + UInt8 = 0, UInt16 = 1, UInt32 = 2, UInt64 = 3, - Int8 = 4, - Int16 = 5, - Int32 = 6, - Int64 = 7 + Int8 = 4, + Int16 = 5, + Int32 = 6, + Int64 = 7, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode.cs b/src/ARMeilleure/Decoders/OpCode.cs index f9aed7924..c8123308b 100644 --- a/src/ARMeilleure/Decoders/OpCode.cs +++ b/src/ARMeilleure/Decoders/OpCode.cs @@ -5,8 +5,8 @@ namespace ARMeilleure.Decoders { class OpCode : IOpCode { - public ulong Address { get; } - public int RawOpCode { get; } + public ulong Address { get; } + public int RawOpCode { get; } public int OpCodeSizeInBytes { get; protected set; } = 4; @@ -14,13 +14,13 @@ class OpCode : IOpCode public RegisterSize RegisterSize { get; protected set; } - public static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode(inst, address, opCode); + public static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new(inst, address, opCode); public OpCode(InstDescriptor inst, ulong address, int opCode) { Instruction = inst; - Address = address; - RawOpCode = opCode; + Address = address; + RawOpCode = opCode; RegisterSize = RegisterSize.Int64; } @@ -30,15 +30,14 @@ public OpCode(InstDescriptor inst, ulong address, int opCode) public int GetBitsCount() { - switch (RegisterSize) + return RegisterSize switch { - case RegisterSize.Int32: return 32; - case RegisterSize.Int64: return 64; - case RegisterSize.Simd64: return 64; - case RegisterSize.Simd128: return 128; - } - - throw new InvalidOperationException(); + RegisterSize.Int32 => 32, + RegisterSize.Int64 => 64, + RegisterSize.Simd64 => 64, + RegisterSize.Simd128 => 128, + _ => throw new InvalidOperationException(), + }; } public OperandType GetOperandType() @@ -46,4 +45,4 @@ public OperandType GetOperandType() return RegisterSize == RegisterSize.Int32 ? OperandType.I32 : OperandType.I64; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32.cs b/src/ARMeilleure/Decoders/OpCode32.cs index c2f14145b..a2be01e9a 100644 --- a/src/ARMeilleure/Decoders/OpCode32.cs +++ b/src/ARMeilleure/Decoders/OpCode32.cs @@ -31,4 +31,4 @@ public uint GetPc() } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32Alu.cs b/src/ARMeilleure/Decoders/OpCode32Alu.cs index 1625aee0a..8634f5ce9 100644 --- a/src/ARMeilleure/Decoders/OpCode32Alu.cs +++ b/src/ARMeilleure/Decoders/OpCode32Alu.cs @@ -17,4 +17,4 @@ public OpCode32Alu(InstDescriptor inst, ulong address, int opCode) : base(inst, SetFlags = ((opCode >> 20) & 1) != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32AluBf.cs b/src/ARMeilleure/Decoders/OpCode32AluBf.cs index 0cee34e6d..c34784428 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluBf.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluBf.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluBf : OpCode32, IOpCode32AluBf { diff --git a/src/ARMeilleure/Decoders/OpCode32AluImm.cs b/src/ARMeilleure/Decoders/OpCode32AluImm.cs index b5435aaf1..c8b05e6bc 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluImm.cs @@ -20,4 +20,4 @@ public OpCode32AluImm(InstDescriptor inst, ulong address, int opCode) : base(ins IsRotated = shift != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32AluImm16.cs b/src/ARMeilleure/Decoders/OpCode32AluImm16.cs index e24edeb41..2af35bd51 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluImm16.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluImm16.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluImm16 : OpCode32Alu, IOpCode32AluImm16 { diff --git a/src/ARMeilleure/Decoders/OpCode32AluMla.cs b/src/ARMeilleure/Decoders/OpCode32AluMla.cs index 2cd2b9dcc..bc5d23908 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluMla.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluMla.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluMla : OpCode32, IOpCode32AluMla { diff --git a/src/ARMeilleure/Decoders/OpCode32AluReg.cs b/src/ARMeilleure/Decoders/OpCode32AluReg.cs index 493a977f0..9ef7571cf 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluReg : OpCode32Alu, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCode32AluRsImm.cs b/src/ARMeilleure/Decoders/OpCode32AluRsImm.cs index c2dee6c9a..4b2c5897a 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluRsImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluRsImm.cs @@ -2,7 +2,7 @@ namespace ARMeilleure.Decoders { class OpCode32AluRsImm : OpCode32Alu, IOpCode32AluRsImm { - public int Rm { get; } + public int Rm { get; } public int Immediate { get; } public ShiftType ShiftType { get; } @@ -11,10 +11,10 @@ class OpCode32AluRsImm : OpCode32Alu, IOpCode32AluRsImm public OpCode32AluRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rm = (opCode >> 0) & 0xf; + Rm = (opCode >> 0) & 0xf; Immediate = (opCode >> 7) & 0x1f; ShiftType = (ShiftType)((opCode >> 5) & 3); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs b/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs index 04740d086..6379b3bde 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluRsReg : OpCode32Alu, IOpCode32AluRsReg { diff --git a/src/ARMeilleure/Decoders/OpCode32AluUmull.cs b/src/ARMeilleure/Decoders/OpCode32AluUmull.cs index bf80df3ff..44b7ea154 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluUmull.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluUmull.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluUmull : OpCode32, IOpCode32AluUmull { diff --git a/src/ARMeilleure/Decoders/OpCode32AluUx.cs b/src/ARMeilleure/Decoders/OpCode32AluUx.cs index 57068675d..68da302fc 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluUx.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluUx.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32BImm.cs b/src/ARMeilleure/Decoders/OpCode32BImm.cs index f2959b331..e7f5d6db1 100644 --- a/src/ARMeilleure/Decoders/OpCode32BImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32BImm.cs @@ -26,4 +26,4 @@ public OpCode32BImm(InstDescriptor inst, ulong address, int opCode) : base(inst, } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32BReg.cs b/src/ARMeilleure/Decoders/OpCode32BReg.cs index d4f5f7601..8939c0de3 100644 --- a/src/ARMeilleure/Decoders/OpCode32BReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32BReg.cs @@ -11,4 +11,4 @@ public OpCode32BReg(InstDescriptor inst, ulong address, int opCode) : base(inst, Rm = opCode & 0xf; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32Exception.cs b/src/ARMeilleure/Decoders/OpCode32Exception.cs index b4edcc100..51a535e43 100644 --- a/src/ARMeilleure/Decoders/OpCode32Exception.cs +++ b/src/ARMeilleure/Decoders/OpCode32Exception.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32Exception : OpCode32, IOpCode32Exception { diff --git a/src/ARMeilleure/Decoders/OpCode32Mem.cs b/src/ARMeilleure/Decoders/OpCode32Mem.cs index ceb1e49f5..8a2421996 100644 --- a/src/ARMeilleure/Decoders/OpCode32Mem.cs +++ b/src/ARMeilleure/Decoders/OpCode32Mem.cs @@ -9,9 +9,9 @@ class OpCode32Mem : OpCode32, IOpCode32Mem public int Immediate { get; protected set; } - public bool Index { get; } - public bool Add { get; } - public bool WBack { get; } + public bool Index { get; } + public bool Add { get; } + public bool WBack { get; } public bool Unprivileged { get; } public bool IsLoad { get; } @@ -24,16 +24,16 @@ public OpCode32Mem(InstDescriptor inst, ulong address, int opCode) : base(inst, Rn = (opCode >> 16) & 0xf; bool isLoad = (opCode & (1 << 20)) != 0; - bool w = (opCode & (1 << 21)) != 0; - bool u = (opCode & (1 << 23)) != 0; - bool p = (opCode & (1 << 24)) != 0; + bool w = (opCode & (1 << 21)) != 0; + bool u = (opCode & (1 << 23)) != 0; + bool p = (opCode & (1 << 24)) != 0; - Index = p; - Add = u; - WBack = !p || w; + Index = p; + Add = u; + WBack = !p || w; Unprivileged = !p && w; IsLoad = isLoad || inst.Name == InstName.Ldrd; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32MemImm.cs b/src/ARMeilleure/Decoders/OpCode32MemImm.cs index 3af4b6f7c..fa10e04ee 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemImm.cs @@ -9,4 +9,4 @@ public OpCode32MemImm(InstDescriptor inst, ulong address, int opCode) : base(ins Immediate = opCode & 0xfff; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32MemImm8.cs b/src/ARMeilleure/Decoders/OpCode32MemImm8.cs index 1b8a57de4..248ee8e65 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemImm8.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemImm8.cs @@ -12,4 +12,4 @@ public OpCode32MemImm8(InstDescriptor inst, ulong address, int opCode) : base(in Immediate = imm4L | (imm4H << 4); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs b/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs index 520113f46..0f0b37eac 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemLdEx : OpCode32Mem, IOpCode32MemEx { diff --git a/src/ARMeilleure/Decoders/OpCode32MemMult.cs b/src/ARMeilleure/Decoders/OpCode32MemMult.cs index 522b96bb9..6e39e3479 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemMult.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemMult.cs @@ -7,8 +7,8 @@ class OpCode32MemMult : OpCode32, IOpCode32MemMult public int Rn { get; } public int RegisterMask { get; } - public int Offset { get; } - public int PostOffset { get; } + public int Offset { get; } + public int PostOffset { get; } public bool IsLoad { get; } @@ -19,9 +19,9 @@ public OpCode32MemMult(InstDescriptor inst, ulong address, int opCode) : base(in Rn = (opCode >> 16) & 0xf; bool isLoad = (opCode & (1 << 20)) != 0; - bool w = (opCode & (1 << 21)) != 0; - bool u = (opCode & (1 << 23)) != 0; - bool p = (opCode & (1 << 24)) != 0; + bool w = (opCode & (1 << 21)) != 0; + bool u = (opCode & (1 << 23)) != 0; + bool p = (opCode & (1 << 24)) != 0; RegisterMask = opCode & 0xffff; @@ -49,4 +49,4 @@ public OpCode32MemMult(InstDescriptor inst, ulong address, int opCode) : base(in IsLoad = isLoad; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32MemReg.cs b/src/ARMeilleure/Decoders/OpCode32MemReg.cs index 786f37fab..d8f1c29b2 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemReg : OpCode32Mem, IOpCode32MemReg { diff --git a/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs b/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs index e1284cf7e..b0e5aa4b9 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemRsImm : OpCode32Mem, IOpCode32MemRsImm { diff --git a/src/ARMeilleure/Decoders/OpCode32MemStEx.cs b/src/ARMeilleure/Decoders/OpCode32MemStEx.cs index dcf93b224..180a9b5ac 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemStEx.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemStEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemStEx : OpCode32Mem, IOpCode32MemEx { diff --git a/src/ARMeilleure/Decoders/OpCode32Mrs.cs b/src/ARMeilleure/Decoders/OpCode32Mrs.cs index c34a8b997..b681b54c0 100644 --- a/src/ARMeilleure/Decoders/OpCode32Mrs.cs +++ b/src/ARMeilleure/Decoders/OpCode32Mrs.cs @@ -2,8 +2,8 @@ namespace ARMeilleure.Decoders { class OpCode32Mrs : OpCode32 { - public bool R { get; } - public int Rd { get; } + public bool R { get; } + public int Rd { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32Mrs(inst, address, opCode); diff --git a/src/ARMeilleure/Decoders/OpCode32MsrReg.cs b/src/ARMeilleure/Decoders/OpCode32MsrReg.cs index d897ffd80..dcd06aa01 100644 --- a/src/ARMeilleure/Decoders/OpCode32MsrReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32MsrReg.cs @@ -1,14 +1,14 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { class OpCode32MsrReg : OpCode32 { - public bool R { get; } - public int Mask { get; } - public int Rd { get; } + public bool R { get; } + public int Mask { get; } + public int Rd { get; } public bool Banked { get; } - public int Rn { get; } + public int Rn { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32MsrReg(inst, address, opCode); diff --git a/src/ARMeilleure/Decoders/OpCode32Sat.cs b/src/ARMeilleure/Decoders/OpCode32Sat.cs index 621def27c..35c5cf47a 100644 --- a/src/ARMeilleure/Decoders/OpCode32Sat.cs +++ b/src/ARMeilleure/Decoders/OpCode32Sat.cs @@ -21,4 +21,4 @@ public OpCode32Sat(InstDescriptor inst, ulong address, int opCode) : base(inst, ShiftType = (ShiftType)((opCode >> 5) & 2); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32Sat16.cs b/src/ARMeilleure/Decoders/OpCode32Sat16.cs index 51061b079..01f4d3b23 100644 --- a/src/ARMeilleure/Decoders/OpCode32Sat16.cs +++ b/src/ARMeilleure/Decoders/OpCode32Sat16.cs @@ -15,4 +15,4 @@ public OpCode32Sat16(InstDescriptor inst, ulong address, int opCode) : base(inst SatImm = (opCode >> 16) & 0xf; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32Simd.cs b/src/ARMeilleure/Decoders/OpCode32Simd.cs index 636aa0a82..1e69b2341 100644 --- a/src/ARMeilleure/Decoders/OpCode32Simd.cs +++ b/src/ARMeilleure/Decoders/OpCode32Simd.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32Simd : OpCode32SimdBase { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdBase.cs b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs index 4382fc2aa..d0634a0e1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdBase.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Decoders { @@ -24,27 +24,21 @@ abstract class OpCode32SimdBase : OpCode32, IOpCode32Simd protected int GetQuadwordIndex(int index) { - switch (RegisterSize) + return RegisterSize switch { - case RegisterSize.Simd128: - case RegisterSize.Simd64: - return index >> 1; - } - - throw new InvalidOperationException(); + RegisterSize.Simd128 or RegisterSize.Simd64 => index >> 1, + _ => throw new InvalidOperationException(), + }; } protected int GetQuadwordSubindex(int index) { - switch (RegisterSize) + return RegisterSize switch { - case RegisterSize.Simd128: - return 0; - case RegisterSize.Simd64: - return index & 1; - } - - throw new InvalidOperationException(); + RegisterSize.Simd128 => 0, + RegisterSize.Simd64 => index & 1, + _ => throw new InvalidOperationException(), + }; } protected OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode) diff --git a/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs b/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs index ba190de96..c0c8277a9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { /// /// A special alias that always runs in 64 bit int, to speed up binary ops a little. diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs b/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs index 445e67819..d8bc109e7 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCmpZ : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs b/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs new file mode 100644 index 000000000..200df73ad --- /dev/null +++ b/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs @@ -0,0 +1,23 @@ +namespace ARMeilleure.Decoders +{ + class OpCode32SimdCvtFFixed : OpCode32Simd + { + public int Fbits { get; protected set; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, false); + public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, true); + + public OpCode32SimdCvtFFixed(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb) + { + Opc = (opCode >> 8) & 0x1; + + Size = Opc == 1 ? 0 : 2; + Fbits = 64 - ((opCode >> 16) & 0x3f); + + if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm)) + { + Instruction = InstDescriptor.Undefined; + } + } + } +} diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs b/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs index 41cf4d884..ee8f94a4e 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCvtFI : OpCode32SimdS { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCvtTB.cs b/src/ARMeilleure/Decoders/OpCode32SimdCvtTB.cs index a95b32ab0..d3beb4bfd 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCvtTB.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCvtTB.cs @@ -15,8 +15,8 @@ public OpCode32SimdCvtTB(InstDescriptor inst, ulong address, int opCode, bool is { IsThumb = isThumb; - Op = ((opCode >> 16) & 0x1) != 0; - T = ((opCode >> 7) & 0x1) != 0; + Op = ((opCode >> 16) & 0x1) != 0; + T = ((opCode >> 7) & 0x1) != 0; Size = ((opCode >> 8) & 0x1); RegisterSize = Size == 1 ? RegisterSize.Int64 : RegisterSize.Int32; @@ -41,4 +41,4 @@ public OpCode32SimdCvtTB(InstDescriptor inst, ulong address, int opCode, bool is } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs index c455b5b4e..b6cdff088 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupElem : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs b/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs index 31546ea31..57adea5e6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupGP : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdExt.cs b/src/ARMeilleure/Decoders/OpCode32SimdExt.cs index 6dbb5b662..4fe9f25db 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdExt.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdExt.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdExt : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdImm.cs index bf0ca527d..9e931e791 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm : OpCode32SimdBase, IOpCode32SimdImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs b/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs index fa00a935a..55df1ba6e 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm44 : OpCode32, IOpCode32SimdImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdLong.cs index 8d64d673a..5c068de16 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdLong : OpCode32SimdBase { @@ -14,9 +14,15 @@ public OpCode32SimdLong(InstDescriptor inst, ulong address, int opCode, bool isT // The value must be a power of 2, otherwise it is the encoding of another instruction. switch (imm3h) { - case 1: Size = 0; break; - case 2: Size = 1; break; - case 4: Size = 2; break; + case 1: + Size = 0; + break; + case 2: + Size = 1; + break; + case 4: + Size = 2; + break; } U = ((opCode >> (isThumb ? 28 : 24)) & 0x1) != 0; diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs index c933a5ad2..86870dfea 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemImm : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs index a16a03d3b..c3b8670f8 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemMult : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs index da88eed27..6a18211c6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs @@ -1,15 +1,15 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { class OpCode32SimdMemPair : OpCode32, IOpCode32Simd { - private static int[] _regsMap = + private static readonly int[] _regsMap = { 1, 1, 4, 2, 1, 1, 3, 1, 1, 1, 2, 1, - 1, 1, 1, 1 + 1, 1, 1, 1, }; public int Vd { get; } diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs index 35dd41c29..5df45000f 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs index 5afd34883..35b8cc9f1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGp : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs index 2d6931199..4399fb3c0 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs index 7816665f3..f6fce7d99 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdReg.cs b/src/ARMeilleure/Decoders/OpCode32SimdReg.cs index 1c46b0e01..eaf17b8c6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdReg : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs index 173c52652..147de44ba 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegElem : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs index b87ac4130..8aea44cb0 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegElemLong : OpCode32SimdRegElem { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs index 110693835..1349fb479 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegLong : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs index 8168e83fd..2dfb0074d 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegS : OpCode32SimdS { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs index fd2b3bf1d..6f9c639f9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegWide : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRev.cs b/src/ARMeilleure/Decoders/OpCode32SimdRev.cs index cb64765f4..26d8be2b9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRev.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRev.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRev : OpCode32SimdCmpZ { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdS.cs b/src/ARMeilleure/Decoders/OpCode32SimdS.cs index 63c03c019..0bb62cb52 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdS.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdS.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdS : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs index 37fd714a4..a6667ba19 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSel : OpCode32SimdRegS { @@ -13,11 +13,11 @@ public OpCode32SimdSel(InstDescriptor inst, ulong address, int opCode, bool isTh } } - enum OpCode32SimdSelMode : int + enum OpCode32SimdSelMode { Eq = 0, Vs, Ge, - Gt + Gt, } } diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs index 55ddc3958..040dce6f1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImm : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs index 6b1b0ad1e..13d89ca42 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImmLong : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs index 5351e65ff..ce1e79069 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImmNarrow : OpCode32SimdShImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs b/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs index 61a9f3870..9b6f47321 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSpecial : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs b/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs index 5b715535a..8f8fa4b03 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSqrte : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs b/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs index c4fb4b9ce..fcac9e014 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdTbl : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32System.cs b/src/ARMeilleure/Decoders/OpCode32System.cs index 89e93349b..f6f5e0f96 100644 --- a/src/ARMeilleure/Decoders/OpCode32System.cs +++ b/src/ARMeilleure/Decoders/OpCode32System.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32System : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCodeAdr.cs b/src/ARMeilleure/Decoders/OpCodeAdr.cs index 9655c766c..080280404 100644 --- a/src/ARMeilleure/Decoders/OpCodeAdr.cs +++ b/src/ARMeilleure/Decoders/OpCodeAdr.cs @@ -6,14 +6,14 @@ class OpCodeAdr : OpCode public long Immediate { get; } - public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeAdr(inst, address, opCode); + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeAdr(inst, address, opCode); public OpCodeAdr(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Rd = opCode & 0x1f; - Immediate = DecoderHelper.DecodeImmS19_2(opCode); + Immediate = DecoderHelper.DecodeImmS19_2(opCode); Immediate |= ((long)opCode >> 29) & 3; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeAlu.cs b/src/ARMeilleure/Decoders/OpCodeAlu.cs index 4d7f03a71..1619ecd8e 100644 --- a/src/ARMeilleure/Decoders/OpCodeAlu.cs +++ b/src/ARMeilleure/Decoders/OpCodeAlu.cs @@ -11,8 +11,8 @@ class OpCodeAlu : OpCode, IOpCodeAlu public OpCodeAlu(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rd = (opCode >> 0) & 0x1f; - Rn = (opCode >> 5) & 0x1f; + Rd = (opCode >> 0) & 0x1f; + Rn = (opCode >> 5) & 0x1f; DataOp = (DataOp)((opCode >> 24) & 0x3); RegisterSize = (opCode >> 31) != 0 @@ -20,4 +20,4 @@ public OpCodeAlu(InstDescriptor inst, ulong address, int opCode) : base(inst, ad : RegisterSize.Int32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeAluBinary.cs b/src/ARMeilleure/Decoders/OpCodeAluBinary.cs index e8b10656a..4413581ca 100644 --- a/src/ARMeilleure/Decoders/OpCodeAluBinary.cs +++ b/src/ARMeilleure/Decoders/OpCodeAluBinary.cs @@ -11,4 +11,4 @@ public OpCodeAluBinary(InstDescriptor inst, ulong address, int opCode) : base(in Rm = (opCode >> 16) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeAluImm.cs b/src/ARMeilleure/Decoders/OpCodeAluImm.cs index 91aa95531..0d2f7202f 100644 --- a/src/ARMeilleure/Decoders/OpCodeAluImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeAluImm.cs @@ -33,8 +33,8 @@ public OpCodeAluImm(InstDescriptor inst, ulong address, int opCode) : base(inst, } else { - throw new ArgumentException(nameof(opCode)); + throw new ArgumentException($"Invalid data operation: {DataOp}", nameof(opCode)); } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeAluRs.cs b/src/ARMeilleure/Decoders/OpCodeAluRs.cs index 949833363..47a47e7d0 100644 --- a/src/ARMeilleure/Decoders/OpCodeAluRs.cs +++ b/src/ARMeilleure/Decoders/OpCodeAluRs.cs @@ -3,7 +3,7 @@ namespace ARMeilleure.Decoders class OpCodeAluRs : OpCodeAlu, IOpCodeAluRs { public int Shift { get; } - public int Rm { get; } + public int Rm { get; } public ShiftType ShiftType { get; } @@ -22,8 +22,8 @@ public OpCodeAluRs(InstDescriptor inst, ulong address, int opCode) : base(inst, Shift = shift; - Rm = (opCode >> 16) & 0x1f; + Rm = (opCode >> 16) & 0x1f; ShiftType = (ShiftType)((opCode >> 22) & 0x3); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeAluRx.cs b/src/ARMeilleure/Decoders/OpCodeAluRx.cs index d39da9e74..c21486788 100644 --- a/src/ARMeilleure/Decoders/OpCodeAluRx.cs +++ b/src/ARMeilleure/Decoders/OpCodeAluRx.cs @@ -3,7 +3,7 @@ namespace ARMeilleure.Decoders class OpCodeAluRx : OpCodeAlu, IOpCodeAluRx { public int Shift { get; } - public int Rm { get; } + public int Rm { get; } public IntType IntType { get; } @@ -11,9 +11,9 @@ class OpCodeAluRx : OpCodeAlu, IOpCodeAluRx public OpCodeAluRx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Shift = (opCode >> 10) & 0x7; + Shift = (opCode >> 10) & 0x7; IntType = (IntType)((opCode >> 13) & 0x7); - Rm = (opCode >> 16) & 0x1f; + Rm = (opCode >> 16) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBImm.cs b/src/ARMeilleure/Decoders/OpCodeBImm.cs index e302516e2..2848c1409 100644 --- a/src/ARMeilleure/Decoders/OpCodeBImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeBImm.cs @@ -8,4 +8,4 @@ class OpCodeBImm : OpCode, IOpCodeBImm public OpCodeBImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBImmAl.cs b/src/ARMeilleure/Decoders/OpCodeBImmAl.cs index 47ae5f562..6c4b28c6c 100644 --- a/src/ARMeilleure/Decoders/OpCodeBImmAl.cs +++ b/src/ARMeilleure/Decoders/OpCodeBImmAl.cs @@ -9,4 +9,4 @@ public OpCodeBImmAl(InstDescriptor inst, ulong address, int opCode) : base(inst, Immediate = (long)address + DecoderHelper.DecodeImm26_2(opCode); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBImmCmp.cs b/src/ARMeilleure/Decoders/OpCodeBImmCmp.cs index a52465699..c477ddecf 100644 --- a/src/ARMeilleure/Decoders/OpCodeBImmCmp.cs +++ b/src/ARMeilleure/Decoders/OpCodeBImmCmp.cs @@ -17,4 +17,4 @@ public OpCodeBImmCmp(InstDescriptor inst, ulong address, int opCode) : base(inst : RegisterSize.Int32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBImmCond.cs b/src/ARMeilleure/Decoders/OpCodeBImmCond.cs index b57a7ea85..7a51a0720 100644 --- a/src/ARMeilleure/Decoders/OpCodeBImmCond.cs +++ b/src/ARMeilleure/Decoders/OpCodeBImmCond.cs @@ -22,4 +22,4 @@ public OpCodeBImmCond(InstDescriptor inst, ulong address, int opCode) : base(ins Immediate = (long)address + DecoderHelper.DecodeImmS19_2(opCode); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBImmTest.cs b/src/ARMeilleure/Decoders/OpCodeBImmTest.cs index bad984055..f989e59e4 100644 --- a/src/ARMeilleure/Decoders/OpCodeBImmTest.cs +++ b/src/ARMeilleure/Decoders/OpCodeBImmTest.cs @@ -2,7 +2,7 @@ namespace ARMeilleure.Decoders { class OpCodeBImmTest : OpCodeBImm { - public int Rt { get; } + public int Rt { get; } public int Bit { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeBImmTest(inst, address, opCode); @@ -13,8 +13,8 @@ public OpCodeBImmTest(InstDescriptor inst, ulong address, int opCode) : base(ins Immediate = (long)address + DecoderHelper.DecodeImmS14_2(opCode); - Bit = (opCode >> 19) & 0x1f; + Bit = (opCode >> 19) & 0x1f; Bit |= (opCode >> 26) & 0x20; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBReg.cs b/src/ARMeilleure/Decoders/OpCodeBReg.cs index b5dcbfd8e..3b84cf5c0 100644 --- a/src/ARMeilleure/Decoders/OpCodeBReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeBReg.cs @@ -8,7 +8,7 @@ class OpCodeBReg : OpCode public OpCodeBReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - int op4 = (opCode >> 0) & 0x1f; + int op4 = (opCode >> 0) & 0x1f; int op2 = (opCode >> 16) & 0x1f; if (op2 != 0b11111 || op4 != 0b00000) @@ -21,4 +21,4 @@ public OpCodeBReg(InstDescriptor inst, ulong address, int opCode) : base(inst, a Rn = (opCode >> 5) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeBfm.cs b/src/ARMeilleure/Decoders/OpCodeBfm.cs index 8e1c78361..d51efade2 100644 --- a/src/ARMeilleure/Decoders/OpCodeBfm.cs +++ b/src/ARMeilleure/Decoders/OpCodeBfm.cs @@ -4,8 +4,8 @@ class OpCodeBfm : OpCodeAlu { public long WMask { get; } public long TMask { get; } - public int Pos { get; } - public int Shift { get; } + public int Pos { get; } + public int Shift { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeBfm(inst, address, opCode); @@ -22,8 +22,8 @@ public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, ad WMask = bm.WMask; TMask = bm.TMask; - Pos = bm.Pos; + Pos = bm.Pos; Shift = bm.Shift; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeCcmp.cs b/src/ARMeilleure/Decoders/OpCodeCcmp.cs index aa47146f8..d40353486 100644 --- a/src/ARMeilleure/Decoders/OpCodeCcmp.cs +++ b/src/ARMeilleure/Decoders/OpCodeCcmp.cs @@ -4,7 +4,7 @@ namespace ARMeilleure.Decoders { class OpCodeCcmp : OpCodeAlu, IOpCodeCond { - public int Nzcv { get; } + public int Nzcv { get; } protected int RmImm; public Condition Cond { get; } @@ -22,11 +22,11 @@ public OpCodeCcmp(InstDescriptor inst, ulong address, int opCode) : base(inst, a return; } - Nzcv = (opCode >> 0) & 0xf; - Cond = (Condition)((opCode >> 12) & 0xf); - RmImm = (opCode >> 16) & 0x1f; + Nzcv = (opCode >> 0) & 0xf; + Cond = (Condition)((opCode >> 12) & 0xf); + RmImm = (opCode >> 16) & 0x1f; Rd = RegisterAlias.Zr; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeCcmpImm.cs b/src/ARMeilleure/Decoders/OpCodeCcmpImm.cs index 3548f2da8..9d6acf196 100644 --- a/src/ARMeilleure/Decoders/OpCodeCcmpImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeCcmpImm.cs @@ -8,4 +8,4 @@ class OpCodeCcmpImm : OpCodeCcmp, IOpCodeAluImm public OpCodeCcmpImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeCcmpReg.cs b/src/ARMeilleure/Decoders/OpCodeCcmpReg.cs index d5df3b102..349afa120 100644 --- a/src/ARMeilleure/Decoders/OpCodeCcmpReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeCcmpReg.cs @@ -12,4 +12,4 @@ class OpCodeCcmpReg : OpCodeCcmp, IOpCodeAluRs public OpCodeCcmpReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeCsel.cs b/src/ARMeilleure/Decoders/OpCodeCsel.cs index 4b8dc7fdd..418962e08 100644 --- a/src/ARMeilleure/Decoders/OpCodeCsel.cs +++ b/src/ARMeilleure/Decoders/OpCodeCsel.cs @@ -10,8 +10,8 @@ class OpCodeCsel : OpCodeAlu, IOpCodeCond public OpCodeCsel(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rm = (opCode >> 16) & 0x1f; + Rm = (opCode >> 16) & 0x1f; Cond = (Condition)((opCode >> 12) & 0xf); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeException.cs b/src/ARMeilleure/Decoders/OpCodeException.cs index 6b72138ee..eee636405 100644 --- a/src/ARMeilleure/Decoders/OpCodeException.cs +++ b/src/ARMeilleure/Decoders/OpCodeException.cs @@ -11,4 +11,4 @@ public OpCodeException(InstDescriptor inst, ulong address, int opCode) : base(in Id = (opCode >> 5) & 0xffff; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMem.cs b/src/ARMeilleure/Decoders/OpCodeMem.cs index 0ba2bcd18..9b4e5ff3e 100644 --- a/src/ARMeilleure/Decoders/OpCodeMem.cs +++ b/src/ARMeilleure/Decoders/OpCodeMem.cs @@ -2,18 +2,18 @@ namespace ARMeilleure.Decoders { class OpCodeMem : OpCode { - public int Rt { get; protected set; } - public int Rn { get; protected set; } - public int Size { get; protected set; } + public int Rt { get; protected set; } + public int Rn { get; protected set; } + public int Size { get; protected set; } public bool Extend64 { get; protected set; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMem(inst, address, opCode); public OpCodeMem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rt = (opCode >> 0) & 0x1f; - Rn = (opCode >> 5) & 0x1f; + Rt = (opCode >> 0) & 0x1f; + Rn = (opCode >> 5) & 0x1f; Size = (opCode >> 30) & 0x3; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMemEx.cs b/src/ARMeilleure/Decoders/OpCodeMemEx.cs index 899024853..1dc73140f 100644 --- a/src/ARMeilleure/Decoders/OpCodeMemEx.cs +++ b/src/ARMeilleure/Decoders/OpCodeMemEx.cs @@ -3,14 +3,14 @@ namespace ARMeilleure.Decoders class OpCodeMemEx : OpCodeMem { public int Rt2 { get; } - public int Rs { get; } + public int Rs { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemEx(inst, address, opCode); public OpCodeMemEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Rt2 = (opCode >> 10) & 0x1f; - Rs = (opCode >> 16) & 0x1f; + Rs = (opCode >> 16) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMemImm.cs b/src/ARMeilleure/Decoders/OpCodeMemImm.cs index d6ed2282f..4d5eeb1ed 100644 --- a/src/ARMeilleure/Decoders/OpCodeMemImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeMemImm.cs @@ -2,18 +2,18 @@ namespace ARMeilleure.Decoders { class OpCodeMemImm : OpCodeMem { - public long Immediate { get; protected set; } - public bool WBack { get; protected set; } - public bool PostIdx { get; protected set; } - protected bool Unscaled { get; } + public long Immediate { get; protected set; } + public bool WBack { get; protected set; } + public bool PostIdx { get; protected set; } + protected bool Unscaled { get; } private enum MemOp { - Unscaled = 0, - PostIndexed = 1, + Unscaled = 0, + PostIndexed = 1, Unprivileged = 2, - PreIndexed = 3, - Unsigned + PreIndexed = 3, + Unsigned, } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemImm(inst, address, opCode); @@ -21,13 +21,13 @@ private enum MemOp public OpCodeMemImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Extend64 = ((opCode >> 22) & 3) == 2; - WBack = ((opCode >> 24) & 1) == 0; + WBack = ((opCode >> 24) & 1) == 0; // The type is not valid for the Unsigned Immediate 12-bits encoding, // because the bits 11:10 are used for the larger Immediate offset. MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned; - PostIdx = type == MemOp.PostIndexed; + PostIdx = type == MemOp.PostIndexed; Unscaled = type == MemOp.Unscaled || type == MemOp.Unprivileged; @@ -50,4 +50,4 @@ public OpCodeMemImm(InstDescriptor inst, ulong address, int opCode) : base(inst, } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMemLit.cs b/src/ARMeilleure/Decoders/OpCodeMemLit.cs index 986d66340..8712a78e3 100644 --- a/src/ARMeilleure/Decoders/OpCodeMemLit.cs +++ b/src/ARMeilleure/Decoders/OpCodeMemLit.cs @@ -2,11 +2,11 @@ namespace ARMeilleure.Decoders { class OpCodeMemLit : OpCode, IOpCodeLit { - public int Rt { get; } + public int Rt { get; } public long Immediate { get; } - public int Size { get; } - public bool Signed { get; } - public bool Prefetch { get; } + public int Size { get; } + public bool Signed { get; } + public bool Prefetch { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemLit(inst, address, opCode); @@ -18,11 +18,27 @@ public OpCodeMemLit(InstDescriptor inst, ulong address, int opCode) : base(inst, switch ((opCode >> 30) & 3) { - case 0: Size = 2; Signed = false; Prefetch = false; break; - case 1: Size = 3; Signed = false; Prefetch = false; break; - case 2: Size = 2; Signed = true; Prefetch = false; break; - case 3: Size = 0; Signed = false; Prefetch = true; break; + case 0: + Size = 2; + Signed = false; + Prefetch = false; + break; + case 1: + Size = 3; + Signed = false; + Prefetch = false; + break; + case 2: + Size = 2; + Signed = true; + Prefetch = false; + break; + case 3: + Size = 0; + Signed = false; + Prefetch = true; + break; } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMemPair.cs b/src/ARMeilleure/Decoders/OpCodeMemPair.cs index 21018033d..eb696cfeb 100644 --- a/src/ARMeilleure/Decoders/OpCodeMemPair.cs +++ b/src/ARMeilleure/Decoders/OpCodeMemPair.cs @@ -8,11 +8,11 @@ class OpCodeMemPair : OpCodeMemImm public OpCodeMemPair(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rt2 = (opCode >> 10) & 0x1f; - WBack = ((opCode >> 23) & 0x1) != 0; - PostIdx = ((opCode >> 23) & 0x3) == 1; + Rt2 = (opCode >> 10) & 0x1f; + WBack = ((opCode >> 23) & 0x1) != 0; + PostIdx = ((opCode >> 23) & 0x3) == 1; Extend64 = ((opCode >> 30) & 0x3) == 1; - Size = ((opCode >> 31) & 0x1) | 2; + Size = ((opCode >> 31) & 0x1) | 2; DecodeImm(opCode); } @@ -22,4 +22,4 @@ protected void DecodeImm(int opCode) Immediate = ((long)(opCode >> 15) << 57) >> (57 - Size); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMemReg.cs b/src/ARMeilleure/Decoders/OpCodeMemReg.cs index 73d6c5d2c..9b0d15959 100644 --- a/src/ARMeilleure/Decoders/OpCodeMemReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeMemReg.cs @@ -3,7 +3,7 @@ namespace ARMeilleure.Decoders class OpCodeMemReg : OpCodeMem { public bool Shift { get; } - public int Rm { get; } + public int Rm { get; } public IntType IntType { get; } @@ -11,10 +11,10 @@ class OpCodeMemReg : OpCodeMem public OpCodeMemReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Shift = ((opCode >> 12) & 0x1) != 0; - IntType = (IntType)((opCode >> 13) & 0x7); - Rm = (opCode >> 16) & 0x1f; - Extend64 = ((opCode >> 22) & 0x3) == 2; + Shift = ((opCode >> 12) & 0x1) != 0; + IntType = (IntType)((opCode >> 13) & 0x7); + Rm = (opCode >> 16) & 0x1f; + Extend64 = ((opCode >> 22) & 0x3) == 2; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMov.cs b/src/ARMeilleure/Decoders/OpCodeMov.cs index 50af88cb9..a2914b71c 100644 --- a/src/ARMeilleure/Decoders/OpCodeMov.cs +++ b/src/ARMeilleure/Decoders/OpCodeMov.cs @@ -22,9 +22,9 @@ public OpCodeMov(InstDescriptor inst, ulong address, int opCode) : base(inst, ad return; } - Rd = (opCode >> 0) & 0x1f; - Immediate = (opCode >> 5) & 0xffff; - Bit = (opCode >> 21) & 0x3; + Rd = (opCode >> 0) & 0x1f; + Immediate = (opCode >> 5) & 0xffff; + Bit = (opCode >> 21) & 0x3; Bit <<= 4; @@ -35,4 +35,4 @@ public OpCodeMov(InstDescriptor inst, ulong address, int opCode) : base(inst, ad : RegisterSize.Int32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeMul.cs b/src/ARMeilleure/Decoders/OpCodeMul.cs index 31d140a65..9b1dd37b8 100644 --- a/src/ARMeilleure/Decoders/OpCodeMul.cs +++ b/src/ARMeilleure/Decoders/OpCodeMul.cs @@ -13,4 +13,4 @@ public OpCodeMul(InstDescriptor inst, ulong address, int opCode) : base(inst, ad Rm = (opCode >> 16) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimd.cs b/src/ARMeilleure/Decoders/OpCodeSimd.cs index 85713690a..bd34d74d9 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimd.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimd.cs @@ -2,18 +2,18 @@ namespace ARMeilleure.Decoders { class OpCodeSimd : OpCode, IOpCodeSimd { - public int Rd { get; } - public int Rn { get; } - public int Opc { get; } + public int Rd { get; } + public int Rn { get; } + public int Opc { get; } public int Size { get; protected set; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimd(inst, address, opCode); public OpCodeSimd(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rd = (opCode >> 0) & 0x1f; - Rn = (opCode >> 5) & 0x1f; - Opc = (opCode >> 15) & 0x3; + Rd = (opCode >> 0) & 0x1f; + Rn = (opCode >> 5) & 0x1f; + Opc = (opCode >> 15) & 0x3; Size = (opCode >> 22) & 0x3; RegisterSize = ((opCode >> 30) & 1) != 0 @@ -21,4 +21,4 @@ public OpCodeSimd(InstDescriptor inst, ulong address, int opCode) : base(inst, a : RegisterSize.Simd64; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdCvt.cs b/src/ARMeilleure/Decoders/OpCodeSimdCvt.cs index 05b32941a..e50cf12e6 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdCvt.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdCvt.cs @@ -9,7 +9,7 @@ class OpCodeSimdCvt : OpCodeSimd public OpCodeSimdCvt(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { int scale = (opCode >> 10) & 0x3f; - int sf = (opCode >> 31) & 0x1; + int sf = (opCode >> 31) & 0x1; FBits = 64 - scale; @@ -18,4 +18,4 @@ public OpCodeSimdCvt(InstDescriptor inst, ulong address, int opCode) : base(inst : RegisterSize.Int32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdExt.cs b/src/ARMeilleure/Decoders/OpCodeSimdExt.cs index a0e264d9d..0a3359e13 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdExt.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdExt.cs @@ -11,4 +11,4 @@ public OpCodeSimdExt(InstDescriptor inst, ulong address, int opCode) : base(inst Imm4 = (opCode >> 11) & 0xf; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdFcond.cs b/src/ARMeilleure/Decoders/OpCodeSimdFcond.cs index aa16e0c19..510cd3101 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdFcond.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdFcond.cs @@ -10,7 +10,7 @@ class OpCodeSimdFcond : OpCodeSimdReg, IOpCodeCond public OpCodeSimdFcond(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Nzcv = (opCode >> 0) & 0xf; + Nzcv = (opCode >> 0) & 0xf; Cond = (Condition)((opCode >> 12) & 0xf); } } diff --git a/src/ARMeilleure/Decoders/OpCodeSimdFmov.cs b/src/ARMeilleure/Decoders/OpCodeSimdFmov.cs index 9f9062b8d..662abe284 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdFmov.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdFmov.cs @@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders { class OpCodeSimdFmov : OpCode, IOpCodeSimd { - public int Rd { get; } + public int Rd { get; } public long Immediate { get; } - public int Size { get; } + public int Size { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdFmov(inst, address, opCode); @@ -16,7 +16,7 @@ public OpCodeSimdFmov(InstDescriptor inst, ulong address, int opCode) : base(ins long imm; - Rd = (opCode >> 0) & 0x1f; + Rd = (opCode >> 0) & 0x1f; imm = (opCode >> 13) & 0xff; if (type == 0) @@ -29,4 +29,4 @@ public OpCodeSimdFmov(InstDescriptor inst, ulong address, int opCode) : base(ins } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs b/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs index 02f74d030..b006cc954 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { public static class OpCodeSimdHelper { @@ -52,17 +52,20 @@ public static (long Immediate, int Size) GetSimdImmediateAndSize(int cMode, int else if ((modeHigh & 0b110) == 0b100) { // 16-bits shifted Immediate. - size = 1; imm <<= (modeHigh & 1) << 3; + size = 1; + imm <<= (modeHigh & 1) << 3; } else if ((modeHigh & 0b100) == 0b000) { // 32-bits shifted Immediate. - size = 2; imm <<= modeHigh << 3; + size = 2; + imm <<= modeHigh << 3; } else if ((modeHigh & 0b111) == 0b110) { // 32-bits shifted Immediate (fill with ones). - size = 2; imm = ShlOnes(imm, 8 << modeLow); + size = 2; + imm = ShlOnes(imm, 8 << modeLow); } else { diff --git a/src/ARMeilleure/Decoders/OpCodeSimdImm.cs b/src/ARMeilleure/Decoders/OpCodeSimdImm.cs index eeca77096..3f4bad7f7 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdImm.cs @@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders { class OpCodeSimdImm : OpCode, IOpCodeSimd { - public int Rd { get; } + public int Rd { get; } public long Immediate { get; } - public int Size { get; } + public int Size { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdImm(inst, address, opCode); @@ -13,14 +13,14 @@ public OpCodeSimdImm(InstDescriptor inst, ulong address, int opCode) : base(inst Rd = opCode & 0x1f; int cMode = (opCode >> 12) & 0xf; - int op = (opCode >> 29) & 0x1; + int op = (opCode >> 29) & 0x1; - int modeLow = cMode & 1; + int modeLow = cMode & 1; int modeHigh = cMode >> 1; long imm; - imm = ((uint)opCode >> 5) & 0x1f; + imm = ((uint)opCode >> 5) & 0x1f; imm |= ((uint)opCode >> 11) & 0xe0; if (modeHigh == 0b111) @@ -67,17 +67,20 @@ public OpCodeSimdImm(InstDescriptor inst, ulong address, int opCode) : base(inst else if ((modeHigh & 0b110) == 0b100) { // 16-bits shifted Immediate. - Size = 1; imm <<= (modeHigh & 1) << 3; + Size = 1; + imm <<= (modeHigh & 1) << 3; } else if ((modeHigh & 0b100) == 0b000) { // 32-bits shifted Immediate. - Size = 2; imm <<= modeHigh << 3; + Size = 2; + imm <<= modeHigh << 3; } else if ((modeHigh & 0b111) == 0b110) { // 32-bits shifted Immediate (fill with ones). - Size = 2; imm = ShlOnes(imm, 8 << modeLow); + Size = 2; + imm = ShlOnes(imm, 8 << modeLow); } else { @@ -104,4 +107,4 @@ private static long ShlOnes(long value, int shift) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdIns.cs b/src/ARMeilleure/Decoders/OpCodeSimdIns.cs index f6f9249d1..95436879c 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdIns.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdIns.cs @@ -23,14 +23,22 @@ public OpCodeSimdIns(InstDescriptor inst, ulong address, int opCode) : base(inst switch (Size) { - case 1: Size = 0; break; - case 2: Size = 1; break; - case 4: Size = 2; break; - case 8: Size = 3; break; + case 1: + Size = 0; + break; + case 2: + Size = 1; + break; + case 4: + Size = 2; + break; + case 8: + Size = 3; + break; } - SrcIndex = imm4 >> Size; + SrcIndex = imm4 >> Size; DstIndex = imm5 >> (Size + 1); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemImm.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemImm.cs index c11594cb0..14a9d7c9c 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemImm.cs @@ -25,4 +25,4 @@ public OpCodeSimdMemImm(InstDescriptor inst, ulong address, int opCode) : base(i Extend64 = false; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemLit.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemLit.cs index 8e2129661..efa558bf9 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemLit.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemLit.cs @@ -2,10 +2,10 @@ namespace ARMeilleure.Decoders { class OpCodeSimdMemLit : OpCode, IOpCodeSimd, IOpCodeLit { - public int Rt { get; } + public int Rt { get; } public long Immediate { get; } - public int Size { get; } - public bool Signed => false; + public int Size { get; } + public bool Signed => false; public bool Prefetch => false; public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemLit(inst, address, opCode); @@ -28,4 +28,4 @@ public OpCodeSimdMemLit(InstDescriptor inst, ulong address, int opCode) : base(i Size = opc + 2; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemMs.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemMs.cs index 8922c18f6..c05b52494 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemMs.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemMs.cs @@ -2,10 +2,10 @@ namespace ARMeilleure.Decoders { class OpCodeSimdMemMs : OpCodeMemReg, IOpCodeSimd { - public int Reps { get; } - public int SElems { get; } - public int Elems { get; } - public bool WBack { get; } + public int Reps { get; } + public int SElems { get; } + public int Elems { get; } + public bool WBack { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemMs(inst, address, opCode); @@ -13,18 +13,41 @@ public OpCodeSimdMemMs(InstDescriptor inst, ulong address, int opCode) : base(in { switch ((opCode >> 12) & 0xf) { - case 0b0000: Reps = 1; SElems = 4; break; - case 0b0010: Reps = 4; SElems = 1; break; - case 0b0100: Reps = 1; SElems = 3; break; - case 0b0110: Reps = 3; SElems = 1; break; - case 0b0111: Reps = 1; SElems = 1; break; - case 0b1000: Reps = 1; SElems = 2; break; - case 0b1010: Reps = 2; SElems = 1; break; - - default: Instruction = InstDescriptor.Undefined; return; + case 0b0000: + Reps = 1; + SElems = 4; + break; + case 0b0010: + Reps = 4; + SElems = 1; + break; + case 0b0100: + Reps = 1; + SElems = 3; + break; + case 0b0110: + Reps = 3; + SElems = 1; + break; + case 0b0111: + Reps = 1; + SElems = 1; + break; + case 0b1000: + Reps = 1; + SElems = 2; + break; + case 0b1010: + Reps = 2; + SElems = 1; + break; + + default: + Instruction = InstDescriptor.Undefined; + return; } - Size = (opCode >> 10) & 3; + Size = (opCode >> 10) & 3; WBack = ((opCode >> 23) & 1) != 0; bool q = ((opCode >> 30) & 1) != 0; @@ -45,4 +68,4 @@ public OpCodeSimdMemMs(InstDescriptor inst, ulong address, int opCode) : base(in Elems = (GetBitsCount() >> 3) >> Size; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemPair.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemPair.cs index 1ab953679..697163896 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemPair.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemPair.cs @@ -13,4 +13,4 @@ public OpCodeSimdMemPair(InstDescriptor inst, ulong address, int opCode) : base( DecodeImm(opCode); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemReg.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemReg.cs index 9ea6dda37..be7b25b9d 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemReg.cs @@ -18,4 +18,4 @@ public OpCodeSimdMemReg(InstDescriptor inst, ulong address, int opCode) : base(i Extend64 = false; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdMemSs.cs b/src/ARMeilleure/Decoders/OpCodeSimdMemSs.cs index 44abdd389..5bc614e19 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdMemSs.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdMemSs.cs @@ -2,21 +2,21 @@ namespace ARMeilleure.Decoders { class OpCodeSimdMemSs : OpCodeMemReg, IOpCodeSimd { - public int SElems { get; } - public int Index { get; } + public int SElems { get; } + public int Index { get; } public bool Replicate { get; } - public bool WBack { get; } + public bool WBack { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemSs(inst, address, opCode); public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - int size = (opCode >> 10) & 3; - int s = (opCode >> 12) & 1; + int size = (opCode >> 10) & 3; + int s = (opCode >> 12) & 1; int sElems = (opCode >> 12) & 2; - int scale = (opCode >> 14) & 3; - int l = (opCode >> 22) & 1; - int q = (opCode >> 30) & 1; + int scale = (opCode >> 14) & 3; + int l = (opCode >> 22) & 1; + int q = (opCode >> 30) & 1; sElems |= (opCode >> 21) & 1; @@ -27,63 +27,63 @@ public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(in switch (scale) { case 1: - { - if ((size & 1) != 0) { - Instruction = InstDescriptor.Undefined; + if ((size & 1) != 0) + { + Instruction = InstDescriptor.Undefined; - return; - } - - index >>= 1; - - break; - } + return; + } - case 2: - { - if ((size & 2) != 0 || - ((size & 1) != 0 && s != 0)) - { - Instruction = InstDescriptor.Undefined; + index >>= 1; - return; + break; } - if ((size & 1) != 0) - { - index >>= 3; - - scale = 3; - } - else + case 2: { - index >>= 2; + if ((size & 2) != 0 || + ((size & 1) != 0 && s != 0)) + { + Instruction = InstDescriptor.Undefined; + + return; + } + + if ((size & 1) != 0) + { + index >>= 3; + + scale = 3; + } + else + { + index >>= 2; + } + + break; } - break; - } - case 3: - { - if (l == 0 || s != 0) { - Instruction = InstDescriptor.Undefined; + if (l == 0 || s != 0) + { + Instruction = InstDescriptor.Undefined; - return; - } + return; + } - scale = size; + scale = size; - Replicate = true; + Replicate = true; - break; - } + break; + } } - Index = index; + Index = index; SElems = sElems; - Size = scale; + Size = scale; Extend64 = false; @@ -94,4 +94,4 @@ public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(in : RegisterSize.Simd64; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdReg.cs b/src/ARMeilleure/Decoders/OpCodeSimdReg.cs index ac4f71dae..40f9b1c53 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdReg.cs @@ -3,16 +3,16 @@ namespace ARMeilleure.Decoders class OpCodeSimdReg : OpCodeSimd { public bool Bit3 { get; } - public int Ra { get; } - public int Rm { get; protected set; } + public int Ra { get; } + public int Rm { get; protected set; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdReg(inst, address, opCode); public OpCodeSimdReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Bit3 = ((opCode >> 3) & 0x1) != 0; - Ra = (opCode >> 10) & 0x1f; - Rm = (opCode >> 16) & 0x1f; + Bit3 = ((opCode >> 3) & 0x1) != 0; + Ra = (opCode >> 10) & 0x1f; + Rm = (opCode >> 16) & 0x1f; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdRegElem.cs b/src/ARMeilleure/Decoders/OpCodeSimdRegElem.cs index 92368deea..bb248ab6b 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdRegElem.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdRegElem.cs @@ -12,7 +12,7 @@ public OpCodeSimdRegElem(InstDescriptor inst, ulong address, int opCode) : base( { case 1: Index = (opCode >> 20) & 3 | - (opCode >> 9) & 4; + (opCode >> 9) & 4; Rm &= 0xf; @@ -24,8 +24,10 @@ public OpCodeSimdRegElem(InstDescriptor inst, ulong address, int opCode) : base( break; - default: Instruction = InstDescriptor.Undefined; break; + default: + Instruction = InstDescriptor.Undefined; + break; } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSimdRegElemF.cs b/src/ARMeilleure/Decoders/OpCodeSimdRegElemF.cs index d46dd57ed..c97bd787e 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdRegElemF.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdRegElemF.cs @@ -26,7 +26,9 @@ public OpCodeSimdRegElemF(InstDescriptor inst, ulong address, int opCode) : base break; - default: Instruction = InstDescriptor.Undefined; break; + default: + Instruction = InstDescriptor.Undefined; + break; } } } diff --git a/src/ARMeilleure/Decoders/OpCodeSimdTbl.cs b/src/ARMeilleure/Decoders/OpCodeSimdTbl.cs index 9c631e485..3a7ef6aba 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdTbl.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdTbl.cs @@ -9,4 +9,4 @@ public OpCodeSimdTbl(InstDescriptor inst, ulong address, int opCode) : base(inst Size = ((opCode >> 13) & 3) + 1; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeSystem.cs b/src/ARMeilleure/Decoders/OpCodeSystem.cs index 4d79421a8..215134153 100644 --- a/src/ARMeilleure/Decoders/OpCodeSystem.cs +++ b/src/ARMeilleure/Decoders/OpCodeSystem.cs @@ -2,7 +2,7 @@ namespace ARMeilleure.Decoders { class OpCodeSystem : OpCode { - public int Rt { get; } + public int Rt { get; } public int Op2 { get; } public int CRm { get; } public int CRn { get; } @@ -13,12 +13,12 @@ class OpCodeSystem : OpCode public OpCodeSystem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rt = (opCode >> 0) & 0x1f; - Op2 = (opCode >> 5) & 0x7; - CRm = (opCode >> 8) & 0xf; - CRn = (opCode >> 12) & 0xf; - Op1 = (opCode >> 16) & 0x7; + Rt = (opCode >> 0) & 0x1f; + Op2 = (opCode >> 5) & 0x7; + CRm = (opCode >> 8) & 0xf; + CRn = (opCode >> 12) & 0xf; + Op1 = (opCode >> 16) & 0x7; Op0 = ((opCode >> 19) & 0x1) | 2; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT16.cs b/src/ARMeilleure/Decoders/OpCodeT16.cs index 9c3d6b006..de946b961 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16.cs @@ -12,4 +12,4 @@ public OpCodeT16(InstDescriptor inst, ulong address, int opCode) : base(inst, ad OpCodeSizeInBytes = 2; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs b/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs index 95f180548..683d638a8 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs @@ -1,6 +1,6 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { - class OpCodeT16AddSubImm3: OpCodeT16, IOpCode32AluImm + class OpCodeT16AddSubImm3 : OpCodeT16, IOpCode32AluImm { public int Rd { get; } public int Rn { get; } @@ -15,8 +15,8 @@ class OpCodeT16AddSubImm3: OpCodeT16, IOpCode32AluImm public OpCodeT16AddSubImm3(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rd = (opCode >> 0) & 0x7; - Rn = (opCode >> 3) & 0x7; + Rd = (opCode >> 0) & 0x7; + Rn = (opCode >> 3) & 0x7; Immediate = (opCode >> 6) & 0x7; IsRotated = false; } diff --git a/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs b/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs index 2a407b2d2..201fc8aab 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AddSubReg : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs b/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs index 673a46045..122698d7e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluImm8 : OpCodeT16, IOpCode32AluImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs b/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs index b23f8fe03..f67a75f96 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluImmZero : OpCodeT16, IOpCode32AluImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs b/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs index 6d5ac8fd3..5458f65f2 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluRegHigh : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs b/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs index b37b4f661..f86f48bd4 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluRegLow : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs b/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs index f230b20e2..5ed8a4e6c 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BImm11 : OpCodeT16, IOpCode32BImm { @@ -8,7 +8,7 @@ class OpCodeT16BImm11 : OpCodeT16, IOpCode32BImm public OpCodeT16BImm11(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - int imm = (opCode << 21) >> 20; + int imm = (opCode << 21) >> 20; Immediate = GetPc() + imm; } } diff --git a/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs b/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs index 5f6842983..85318e5be 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BImm8 : OpCodeT16, IOpCode32BImm { @@ -10,7 +10,7 @@ public OpCodeT16BImm8(InstDescriptor inst, ulong address, int opCode) : base(ins { Cond = (Condition)((opCode >> 8) & 0xf); - int imm = (opCode << 24) >> 23; + int imm = (opCode << 24) >> 23; Immediate = GetPc() + imm; } } diff --git a/src/ARMeilleure/Decoders/OpCodeT16BReg.cs b/src/ARMeilleure/Decoders/OpCodeT16BReg.cs index 3122cd07e..da2a007a5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BReg : OpCodeT16, IOpCode32BReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16Exception.cs b/src/ARMeilleure/Decoders/OpCodeT16Exception.cs index bb0050834..8ccdf09ba 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16Exception.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16Exception.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16Exception : OpCodeT16, IOpCode32Exception { diff --git a/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs b/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs index 8c3de689e..ea435a79b 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs b/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs index 20ef31e27..e9b383989 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using System; namespace ARMeilleure.Decoders @@ -36,23 +36,13 @@ public OpCodeT16MemImm5(InstDescriptor inst, ulong address, int opCode) : base(i break; } - switch (inst.Name) + Immediate = inst.Name switch { - case InstName.Str: - case InstName.Ldr: - Immediate = ((opCode >> 6) & 0x1f) << 2; - break; - case InstName.Strb: - case InstName.Ldrb: - Immediate = ((opCode >> 6) & 0x1f); - break; - case InstName.Strh: - case InstName.Ldrh: - Immediate = ((opCode >> 6) & 0x1f) << 1; - break; - default: - throw new InvalidOperationException(); - } + InstName.Str or InstName.Ldr => ((opCode >> 6) & 0x1f) << 2, + InstName.Strb or InstName.Ldrb => ((opCode >> 6) & 0x1f), + InstName.Strh or InstName.Ldrh => ((opCode >> 6) & 0x1f) << 1, + _ => throw new InvalidOperationException(), + }; } } } diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs b/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs index f8c16e299..63a452ad3 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs b/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs index f4185cfcb..92b027a6e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using System; using System.Numerics; @@ -27,7 +27,7 @@ public OpCodeT16MemMult(InstDescriptor inst, ulong address, int opCode) : base(i { InstName.Ldm => true, InstName.Stm => false, - _ => throw new InvalidOperationException() + _ => throw new InvalidOperationException(), }; } } diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs b/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs index 71100112e..17d6966b2 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16MemReg : OpCodeT16, IOpCode32MemReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs b/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs index a038b915b..ed42679a5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs b/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs index 9d7b0d203..28d5db4d9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using ARMeilleure.State; using System; using System.Numerics; diff --git a/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs b/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs index a540026ec..18e7b9e2e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16ShiftImm : OpCodeT16, IOpCode32AluRsImm { @@ -15,8 +15,8 @@ class OpCodeT16ShiftImm : OpCodeT16, IOpCode32AluRsImm public OpCodeT16ShiftImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rd = (opCode >> 0) & 0x7; - Rm = (opCode >> 3) & 0x7; + Rd = (opCode >> 0) & 0x7; + Rm = (opCode >> 3) & 0x7; Immediate = (opCode >> 6) & 0x1F; ShiftType = (ShiftType)((opCode >> 11) & 3); } diff --git a/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs b/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs index 9f8982814..ce47dfb5d 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16ShiftReg : OpCodeT16, IOpCode32AluRsReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT32.cs b/src/ARMeilleure/Decoders/OpCodeT32.cs index cf43d4298..87a0520d9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32 : OpCode32 { @@ -12,4 +12,4 @@ public OpCodeT32(InstDescriptor inst, ulong address, int opCode) : base(inst, ad OpCodeSizeInBytes = 4; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32Alu.cs b/src/ARMeilleure/Decoders/OpCodeT32Alu.cs index a81b3b3dc..cdef007a9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32Alu.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32Alu.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32Alu : OpCodeT32, IOpCode32Alu { @@ -17,4 +17,4 @@ public OpCodeT32Alu(InstDescriptor inst, ulong address, int opCode) : base(inst, SetFlags = ((opCode >> 20) & 1) != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs b/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs index 0895c29b4..ce88964c9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Common; +using ARMeilleure.Common; using System.Runtime.Intrinsics; namespace ARMeilleure.Decoders @@ -35,4 +35,4 @@ public OpCodeT32AluImm(InstDescriptor inst, ulong address, int opCode) : base(in } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluImm12.cs b/src/ARMeilleure/Decoders/OpCodeT32AluImm12.cs index 31de63dd3..12b65a100 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluImm12.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluImm12.cs @@ -13,4 +13,4 @@ public OpCodeT32AluImm12(InstDescriptor inst, ulong address, int opCode) : base( Immediate = (opCode & 0xff) | ((opCode >> 4) & 0x700) | ((opCode >> 15) & 0x800); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluReg.cs b/src/ARMeilleure/Decoders/OpCodeT32AluReg.cs index a487f55a6..4ac983470 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluReg.cs @@ -11,4 +11,4 @@ public OpCodeT32AluReg(InstDescriptor inst, ulong address, int opCode) : base(in Rm = (opCode >> 0) & 0xf; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs b/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs index 1c9ba7a2c..dad0d9575 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs @@ -1,8 +1,8 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32AluRsImm : OpCodeT32Alu, IOpCode32AluRsImm { - public int Rm { get; } + public int Rm { get; } public int Immediate { get; } public ShiftType ShiftType { get; } @@ -11,10 +11,10 @@ class OpCodeT32AluRsImm : OpCodeT32Alu, IOpCode32AluRsImm public OpCodeT32AluRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rm = (opCode >> 0) & 0xf; + Rm = (opCode >> 0) & 0xf; Immediate = ((opCode >> 6) & 3) | ((opCode >> 10) & 0x1c); ShiftType = (ShiftType)((opCode >> 4) & 3); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs b/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs index b6da8abdb..793f82627 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32BImm20 : OpCodeT32, IOpCode32BImm { @@ -24,4 +24,4 @@ public OpCodeT32BImm20(InstDescriptor inst, ulong address, int opCode) : base(in Cond = (Condition)((opCode >> 22) & 0xf); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs b/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs index 774ec3a64..d35ab8a45 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; namespace ARMeilleure.Decoders { @@ -32,4 +32,4 @@ public OpCodeT32BImm24(InstDescriptor inst, ulong address, int opCode) : base(in Immediate = pc + imm32; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs b/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs index 7838604b2..aac8dbfba 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32MemImm12 : OpCodeT32, IOpCode32Mem { @@ -22,4 +22,4 @@ public OpCodeT32MemImm12(InstDescriptor inst, ulong address, int opCode) : base( IsLoad = ((opCode >> 20) & 1) != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs b/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs index d8b7763cb..d80ce86c5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32MemImm8 : OpCodeT32, IOpCode32Mem { @@ -18,7 +18,7 @@ public OpCodeT32MemImm8(InstDescriptor inst, ulong address, int opCode) : base(i Rn = (opCode >> 16) & 0xf; Index = ((opCode >> 10) & 1) != 0; - Add = ((opCode >> 9) & 1) != 0; + Add = ((opCode >> 9) & 1) != 0; WBack = ((opCode >> 8) & 1) != 0; Immediate = opCode & 0xff; @@ -26,4 +26,4 @@ public OpCodeT32MemImm8(InstDescriptor inst, ulong address, int opCode) : base(i IsLoad = ((opCode >> 20) & 1) != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs b/src/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs index 7a078c489..51f5042f2 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs @@ -20,7 +20,7 @@ public OpCodeT32MemImm8D(InstDescriptor inst, ulong address, int opCode) : base( Rn = (opCode >> 16) & 0xf; Index = ((opCode >> 24) & 1) != 0; - Add = ((opCode >> 23) & 1) != 0; + Add = ((opCode >> 23) & 1) != 0; WBack = ((opCode >> 21) & 1) != 0; Immediate = (opCode & 0xff) << 2; @@ -28,4 +28,4 @@ public OpCodeT32MemImm8D(InstDescriptor inst, ulong address, int opCode) : base( IsLoad = ((opCode >> 20) & 1) != 0; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemMult.cs b/src/ARMeilleure/Decoders/OpCodeT32MemMult.cs index a9ba306dc..d155842a6 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemMult.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemMult.cs @@ -7,8 +7,8 @@ class OpCodeT32MemMult : OpCodeT32, IOpCode32MemMult public int Rn { get; } public int RegisterMask { get; } - public int Offset { get; } - public int PostOffset { get; } + public int Offset { get; } + public int PostOffset { get; } public bool IsLoad { get; } @@ -19,9 +19,9 @@ public OpCodeT32MemMult(InstDescriptor inst, ulong address, int opCode) : base(i Rn = (opCode >> 16) & 0xf; bool isLoad = (opCode & (1 << 20)) != 0; - bool w = (opCode & (1 << 21)) != 0; - bool u = (opCode & (1 << 23)) != 0; - bool p = (opCode & (1 << 24)) != 0; + bool w = (opCode & (1 << 21)) != 0; + bool u = (opCode & (1 << 23)) != 0; + bool p = (opCode & (1 << 24)) != 0; RegisterMask = opCode & 0xffff; @@ -49,4 +49,4 @@ public OpCodeT32MemMult(InstDescriptor inst, ulong address, int opCode) : base(i IsLoad = isLoad; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32MovImm16.cs b/src/ARMeilleure/Decoders/OpCodeT32MovImm16.cs index 5161892bb..2f871c740 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MovImm16.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MovImm16.cs @@ -4,8 +4,6 @@ class OpCodeT32MovImm16 : OpCodeT32Alu, IOpCode32AluImm16 { public int Immediate { get; } - public bool IsRotated => false; - public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MovImm16(inst, address, opCode); public OpCodeT32MovImm16(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) @@ -13,4 +11,4 @@ public OpCodeT32MovImm16(InstDescriptor inst, ulong address, int opCode) : base( Immediate = (opCode & 0xff) | ((opCode >> 4) & 0x700) | ((opCode >> 15) & 0x800) | ((opCode >> 4) & 0xf000); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeT32Tb.cs b/src/ARMeilleure/Decoders/OpCodeT32Tb.cs index 527754b1f..0a4d2a6c4 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32Tb.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32Tb.cs @@ -13,4 +13,4 @@ public OpCodeT32Tb(InstDescriptor inst, ulong address, int opCode) : base(inst, Rn = (opCode >> 16) & 0xf; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/OpCodeTable.cs b/src/ARMeilleure/Decoders/OpCodeTable.cs index 4f3599583..9e13bd9b5 100644 --- a/src/ARMeilleure/Decoders/OpCodeTable.cs +++ b/src/ARMeilleure/Decoders/OpCodeTable.cs @@ -13,7 +13,7 @@ static class OpCodeTable private readonly struct InstInfo { - public int Mask { get; } + public int Mask { get; } public int Value { get; } public InstDescriptor Inst { get; } @@ -22,24 +22,25 @@ private readonly struct InstInfo public InstInfo(int mask, int value, InstDescriptor inst, MakeOp makeOp) { - Mask = mask; - Value = value; - Inst = inst; + Mask = mask; + Value = value; + Inst = inst; MakeOp = makeOp; } } - private static List AllInstA32 = new(); - private static List AllInstT32 = new(); - private static List AllInstA64 = new(); + private static readonly List _allInstA32 = new(); + private static readonly List _allInstT32 = new(); + private static readonly List _allInstA64 = new(); - private static InstInfo[][] InstA32FastLookup = new InstInfo[FastLookupSize][]; - private static InstInfo[][] InstT32FastLookup = new InstInfo[FastLookupSize][]; - private static InstInfo[][] InstA64FastLookup = new InstInfo[FastLookupSize][]; + private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][]; + private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][]; + private static readonly InstInfo[][] _instA64FastLookup = new InstInfo[FastLookupSize][]; static OpCodeTable() { -#region "OpCode Table (AArch64)" +#pragma warning disable IDE0055 // Disable formatting + #region "OpCode Table (AArch64)" // Base SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstName.Adc, InstEmit.Adc, OpCodeAluRs.Create); SetA64("x0111010000xxxxx000000xxxxxxxxxx", InstName.Adcs, InstEmit.Adcs, OpCodeAluRs.Create); @@ -329,6 +330,7 @@ static OpCodeTable() SetA64("011111100x110000110010xxxxxxxxxx", InstName.Fmaxnmp_S, InstEmit.Fmaxnmp_S, OpCodeSimd.Create); SetA64("0>1011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnmp_V, InstEmit.Fmaxnmp_V, OpCodeSimdReg.Create); SetA64("0110111000110000110010xxxxxxxxxx", InstName.Fmaxnmv_V, InstEmit.Fmaxnmv_V, OpCodeSimd.Create); + SetA64("011111100x110000111110xxxxxxxxxx", InstName.Fmaxp_S, InstEmit.Fmaxp_S, OpCodeSimd.Create); SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, OpCodeSimdReg.Create); SetA64("0110111000110000111110xxxxxxxxxx", InstName.Fmaxv_V, InstEmit.Fmaxv_V, OpCodeSimd.Create); SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, OpCodeSimdReg.Create); @@ -338,6 +340,7 @@ static OpCodeTable() SetA64("011111101x110000110010xxxxxxxxxx", InstName.Fminnmp_S, InstEmit.Fminnmp_S, OpCodeSimd.Create); SetA64("0>1011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnmp_V, InstEmit.Fminnmp_V, OpCodeSimdReg.Create); SetA64("0110111010110000110010xxxxxxxxxx", InstName.Fminnmv_V, InstEmit.Fminnmv_V, OpCodeSimd.Create); + SetA64("011111101x110000111110xxxxxxxxxx", InstName.Fminp_S, InstEmit.Fminp_S, OpCodeSimd.Create); SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, OpCodeSimdReg.Create); SetA64("0110111010110000111110xxxxxxxxxx", InstName.Fminv_V, InstEmit.Fminv_V, OpCodeSimd.Create); SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, OpCodeSimdRegElemF.Create); @@ -638,9 +641,9 @@ static OpCodeTable() SetA64("0x001110<<100001001010xxxxxxxxxx", InstName.Xtn_V, InstEmit.Xtn_V, OpCodeSimd.Create); SetA64("0>001110<<0xxxxx001110xxxxxxxxxx", InstName.Zip1_V, InstEmit.Zip1_V, OpCodeSimdReg.Create); SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", InstName.Zip2_V, InstEmit.Zip2_V, OpCodeSimdReg.Create); -#endregion + #endregion -#region "OpCode Table (AArch32, A32)" + #region "OpCode Table (AArch32, A32)" // Base SetA32("<<<<0010101xxxxxxxxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCode32AluImm.Create); SetA32("<<<<0000101xxxxxxxxxxxxxxxx0xxxx", InstName.Adc, InstEmit32.Adc, OpCode32AluRsImm.Create); @@ -882,177 +885,178 @@ static OpCodeTable() SetVfp("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32); // ASIMD - SetAsimd("111100111x110000xxx0001101x0xxx0", InstName.Aesd_V, InstEmit32.Aesd_V, OpCode32Simd.Create, OpCode32Simd.CreateT32); - SetAsimd("111100111x110000xxx0001100x0xxx0", InstName.Aese_V, InstEmit32.Aese_V, OpCode32Simd.Create, OpCode32Simd.CreateT32); - SetAsimd("111100111x110000xxx0001111x0xxx0", InstName.Aesimc_V, InstEmit32.Aesimc_V, OpCode32Simd.Create, OpCode32Simd.CreateT32); - SetAsimd("111100111x110000xxx0001110x0xxx0", InstName.Aesmc_V, InstEmit32.Aesmc_V, OpCode32Simd.Create, OpCode32Simd.CreateT32); - SetAsimd("111100110x00xxx0xxx01100x1x0xxx0", InstName.Sha256h_V, InstEmit32.Sha256h_V, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("111100110x01xxx0xxx01100x1x0xxx0", InstName.Sha256h2_V, InstEmit32.Sha256h2_V, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("111100111x111010xxx0001111x0xxx0", InstName.Sha256su0_V, InstEmit32.Sha256su0_V, OpCode32Simd.Create, OpCode32Simd.CreateT32); - SetAsimd("111100110x10xxx0xxx01100x1x0xxx0", InstName.Sha256su1_V, InstEmit32.Sha256su1_V, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("1111001x0x<xxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); - SetAsimd("111101000x10xxxxxxxx000x<>>xxxxxxx100101x1xxx0", InstName.Vqrshrn, InstEmit32.Vqrshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("111100111x>>>xxxxxxx100001x1xxx0", InstName.Vqrshrun, InstEmit32.Vqrshrun, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("1111001x1x>>>xxxxxxx100100x1xxx0", InstName.Vqshrn, InstEmit32.Vqshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("111100111x>>>xxxxxxx100000x1xxx0", InstName.Vqshrun, InstEmit32.Vqshrun, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("1111001x0xxxxxxxxxxx0010xxx1xxxx", InstName.Vqsub, InstEmit32.Vqsub, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, OpCode32SimdSqrte.Create, OpCode32SimdSqrte.CreateT32); - SetAsimd("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("111100111x11xx00xxxx000<>>xxxxxxx0010>xx1xxxx", InstName.Vrshr, InstEmit32.Vrshr, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); - SetAsimd("111100101x>>>xxxxxxx100001x1xxx0", InstName.Vrshrn, InstEmit32.Vrshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, OpCode32SimdSqrte.Create, OpCode32SimdSqrte.CreateT32); - SetAsimd("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("1111001x1x>>>xxxxxxx0011>xx1xxxx", InstName.Vrsra, InstEmit32.Vrsra, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); - SetAsimd("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); - SetAsimd("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); - SetAsimd("1111001x1x>>>xxxxxxx101000x1xxxx", InstName.Vshll, InstEmit32.Vshll, OpCode32SimdShImmLong.Create, OpCode32SimdShImmLong.CreateT32); // A1 encoding. - SetAsimd("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); - SetAsimd("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); - SetAsimd("1111001x1x>>>xxxxxxx0001>xx1xxxx", InstName.Vsra, InstEmit32.Vsra, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); - SetAsimd("111101001x00xxxxxxxx0000xxx0xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); - SetAsimd("111101001x00xxxxxxxx0100xx0xxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); - SetAsimd("111101001x00xxxxxxxx1000x000xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); - SetAsimd("111101001x00xxxxxxxx1000x011xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); - SetAsimd("111101000x00xxxxxxxx0111xx0xxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create, OpCode32SimdMemPair.CreateT32); // Regs = 1. - SetAsimd("111101000x00xxxxxxxx1010xx<xxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); + SetAsimd("111101000x10xxxxxxxx000x<>>xxxxxxx100101x1xxx0", InstName.Vqrshrn, InstEmit32.Vqrshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("111100111x>>>xxxxxxx100001x1xxx0", InstName.Vqrshrun, InstEmit32.Vqrshrun, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("1111001x1x>>>xxxxxxx100100x1xxx0", InstName.Vqshrn, InstEmit32.Vqshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("111100111x>>>xxxxxxx100000x1xxx0", InstName.Vqshrun, InstEmit32.Vqshrun, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("1111001x0xxxxxxxxxxx0010xxx1xxxx", InstName.Vqsub, InstEmit32.Vqsub, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); + SetAsimd("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, OpCode32SimdSqrte.Create, OpCode32SimdSqrte.CreateT32); + SetAsimd("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); + SetAsimd("111100111x11xx00xxxx000<>>xxxxxxx0010>xx1xxxx", InstName.Vrshr, InstEmit32.Vrshr, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); + SetAsimd("111100101x>>>xxxxxxx100001x1xxx0", InstName.Vrshrn, InstEmit32.Vrshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, OpCode32SimdSqrte.Create, OpCode32SimdSqrte.CreateT32); + SetAsimd("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); + SetAsimd("1111001x1x>>>xxxxxxx0011>xx1xxxx", InstName.Vrsra, InstEmit32.Vrsra, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); + SetAsimd("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); + SetAsimd("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, OpCode32SimdReg.Create, OpCode32SimdReg.CreateT32); + SetAsimd("1111001x1x>>>xxxxxxx101000x1xxxx", InstName.Vshll, InstEmit32.Vshll, OpCode32SimdShImmLong.Create, OpCode32SimdShImmLong.CreateT32); // A1 encoding. + SetAsimd("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); + SetAsimd("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, OpCode32SimdShImmNarrow.Create, OpCode32SimdShImmNarrow.CreateT32); + SetAsimd("1111001x1x>>>xxxxxxx0001>xx1xxxx", InstName.Vsra, InstEmit32.Vsra, OpCode32SimdShImm.Create, OpCode32SimdShImm.CreateT32); + SetAsimd("111101001x00xxxxxxxx0000xxx0xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); + SetAsimd("111101001x00xxxxxxxx0100xx0xxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); + SetAsimd("111101001x00xxxxxxxx1000x000xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); + SetAsimd("111101001x00xxxxxxxx1000x011xxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create, OpCode32SimdMemSingle.CreateT32); + SetAsimd("111101000x00xxxxxxxx0111xx0xxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create, OpCode32SimdMemPair.CreateT32); // Regs = 1. + SetAsimd("111101000x00xxxxxxxx1010xx< allInsts, Func ToFastLookupIndex) + private static void FillFastLookupTable(InstInfo[][] table, List allInsts, Func toFastLookupIndex) { List[] temp = new List[FastLookupSize]; @@ -1315,8 +1320,8 @@ private static void FillFastLookupTable(InstInfo[][] table, List allIn foreach (InstInfo inst in allInsts) { - int mask = ToFastLookupIndex(inst.Mask); - int value = ToFastLookupIndex(inst.Value); + int mask = toFastLookupIndex(inst.Mask); + int value = toFastLookupIndex(inst.Value); for (int index = 0; index < temp.Length; index++) { @@ -1335,22 +1340,21 @@ private static void FillFastLookupTable(InstInfo[][] table, List allIn private static void SetA32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) { - Set(encoding, AllInstA32, new InstDescriptor(name, emitter), makeOp); + Set(encoding, _allInstA32, new InstDescriptor(name, emitter), makeOp); } private static void SetT16(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) { encoding = "xxxxxxxxxxxxxxxx" + encoding; - Set(encoding, AllInstT32, new InstDescriptor(name, emitter), makeOp); + Set(encoding, _allInstT32, new InstDescriptor(name, emitter), makeOp); } private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) { string reversedEncoding = $"{encoding.AsSpan(16)}{encoding.AsSpan(0, 16)}"; - MakeOp reversedMakeOp = - (inst, address, opCode) + OpCode ReversedMakeOp(InstDescriptor inst, ulong address, int opCode) => makeOp(inst, address, (int)BitOperations.RotateRight((uint)opCode, 16)); - Set(reversedEncoding, AllInstT32, new InstDescriptor(name, emitter), reversedMakeOp); + Set(reversedEncoding, _allInstT32, new InstDescriptor(name, emitter), ReversedMakeOp); } private static void SetVfp(string encoding, InstName name, InstEmitter emitter, MakeOp makeOpA32, MakeOp makeOpT32) @@ -1395,12 +1399,12 @@ private static void SetAsimd(string encoding, InstName name, InstEmitter emitter private static void SetA64(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) { - Set(encoding, AllInstA64, new InstDescriptor(name, emitter), makeOp); + Set(encoding, _allInstA64, new InstDescriptor(name, emitter), makeOp); } private static void Set(string encoding, List list, InstDescriptor inst, MakeOp makeOp) { - int bit = encoding.Length - 1; + int bit = encoding.Length - 1; int value = 0; int xMask = 0; int xBits = 0; @@ -1439,7 +1443,7 @@ private static void Set(string encoding, List list, InstDescriptor ins } else if (chr != '0') { - throw new ArgumentException(nameof(encoding)); + throw new ArgumentException($"Invalid encoding: {encoding}", nameof(encoding)); } } @@ -1470,17 +1474,17 @@ private static void Set(string encoding, List list, InstDescriptor ins public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode) { - return GetInstFromList(InstA32FastLookup[ToFastLookupIndexA(opCode)], opCode); + return GetInstFromList(_instA32FastLookup[ToFastLookupIndexA(opCode)], opCode); } public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode) { - return GetInstFromList(InstT32FastLookup[ToFastLookupIndexT(opCode)], opCode); + return GetInstFromList(_instT32FastLookup[ToFastLookupIndexT(opCode)], opCode); } public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode) { - return GetInstFromList(InstA64FastLookup[ToFastLookupIndexA(opCode)], opCode); + return GetInstFromList(_instA64FastLookup[ToFastLookupIndexA(opCode)], opCode); } private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode) diff --git a/src/ARMeilleure/Decoders/Optimizations/TailCallRemover.cs b/src/ARMeilleure/Decoders/Optimizations/TailCallRemover.cs index 17c17812d..9d988f0c9 100644 --- a/src/ARMeilleure/Decoders/Optimizations/TailCallRemover.cs +++ b/src/ARMeilleure/Decoders/Optimizations/TailCallRemover.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace ARMeilleure.Decoders.Optimizations @@ -17,26 +17,26 @@ public static Block[] RunPass(ulong entryAddress, List blocks) throw new InvalidOperationException("Function entry point is not contained in a block."); } - const ulong allowance = 4; + const ulong Allowance = 4; Block entryBlock = blocks[entryBlockId]; Block startBlock = entryBlock; - Block endBlock = entryBlock; + Block endBlock = entryBlock; int startBlockIndex = entryBlockId; - int endBlockIndex = entryBlockId; + int endBlockIndex = entryBlockId; for (int i = entryBlockId + 1; i < blocks.Count; i++) // Search forwards. { Block block = blocks[i]; - if (endBlock.EndAddress < block.Address - allowance) + if (endBlock.EndAddress < block.Address - Allowance) { break; // End of contiguous function. } - endBlock = block; + endBlock = block; endBlockIndex = i; } @@ -44,12 +44,12 @@ public static Block[] RunPass(ulong entryAddress, List blocks) { Block block = blocks[i]; - if (startBlock.Address > block.EndAddress + allowance) + if (startBlock.Address > block.EndAddress + Allowance) { break; // End of contiguous function. } - startBlock = block; + startBlock = block; startBlockIndex = i; } @@ -57,7 +57,7 @@ public static Block[] RunPass(ulong entryAddress, List blocks) { return blocks.ToArray(); // Nothing to do here. } - + // Mark branches whose target is outside of the contiguous region as an exit block. for (int i = startBlockIndex; i <= endBlockIndex; i++) { @@ -69,7 +69,7 @@ public static Block[] RunPass(ulong entryAddress, List blocks) } } - var newBlocks = new List(blocks.Count); + var newBlocks = new List(blocks.Count); // Finally, rebuild decoded block list, ignoring blocks outside the contiguous range. for (int i = 0; i < blocks.Count; i++) diff --git a/src/ARMeilleure/Decoders/RegisterSize.cs b/src/ARMeilleure/Decoders/RegisterSize.cs index c9cea03ed..7c00984e8 100644 --- a/src/ARMeilleure/Decoders/RegisterSize.cs +++ b/src/ARMeilleure/Decoders/RegisterSize.cs @@ -5,6 +5,6 @@ enum RegisterSize Int32, Int64, Simd64, - Simd128 + Simd128, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Decoders/ShiftType.cs b/src/ARMeilleure/Decoders/ShiftType.cs index 8583f16ad..43b738f3f 100644 --- a/src/ARMeilleure/Decoders/ShiftType.cs +++ b/src/ARMeilleure/Decoders/ShiftType.cs @@ -5,6 +5,6 @@ enum ShiftType Lsl = 0, Lsr = 1, Asr = 2, - Ror = 3 + Ror = 3, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Diagnostics/IRDumper.cs b/src/ARMeilleure/Diagnostics/IRDumper.cs index 3d1a60e58..16833d085 100644 --- a/src/ARMeilleure/Diagnostics/IRDumper.cs +++ b/src/ARMeilleure/Diagnostics/IRDumper.cs @@ -34,7 +34,9 @@ private void Indent() for (int index = 0; index < _indentLevel; index++) { +#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings _builder.Append(Indentation); +#pragma warning restore CA1834 } } @@ -110,10 +112,18 @@ private void DumpOperand(Operand operand) switch (reg.Type) { - case RegisterType.Flag: _builder.Append('b'); break; - case RegisterType.FpFlag: _builder.Append('f'); break; - case RegisterType.Integer: _builder.Append('r'); break; - case RegisterType.Vector: _builder.Append('v'); break; + case RegisterType.Flag: + _builder.Append('b'); + break; + case RegisterType.FpFlag: + _builder.Append('f'); + break; + case RegisterType.Integer: + _builder.Append('r'); + break; + case RegisterType.Vector: + _builder.Append('v'); + break; } _builder.Append(reg.Index); @@ -145,9 +155,15 @@ private void DumpOperand(Operand operand) switch (memOp.Scale) { - case Multiplier.x2: _builder.Append("*2"); break; - case Multiplier.x4: _builder.Append("*4"); break; - case Multiplier.x8: _builder.Append("*8"); break; + case Multiplier.x2: + _builder.Append("*2"); + break; + case Multiplier.x4: + _builder.Append("*4"); + break; + case Multiplier.x8: + _builder.Append("*8"); + break; } } @@ -308,4 +324,4 @@ private static string GetTypeName(OperandType type) }; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Diagnostics/Logger.cs b/src/ARMeilleure/Diagnostics/Logger.cs index 07a60667e..d7f61230c 100644 --- a/src/ARMeilleure/Diagnostics/Logger.cs +++ b/src/ARMeilleure/Diagnostics/Logger.cs @@ -8,7 +8,7 @@ static class Logger { private static long _startTime; - private static long[] _accumulatedTime; + private static readonly long[] _accumulatedTime; static Logger() { @@ -53,4 +53,4 @@ private static void WriteOutput(string text) Console.WriteLine(text); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Diagnostics/PassName.cs b/src/ARMeilleure/Diagnostics/PassName.cs index e34bf0d2f..2d87659f0 100644 --- a/src/ARMeilleure/Diagnostics/PassName.cs +++ b/src/ARMeilleure/Diagnostics/PassName.cs @@ -14,6 +14,6 @@ enum PassName RegisterAllocation, CodeGeneration, - Count + Count, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Diagnostics/Symbols.cs b/src/ARMeilleure/Diagnostics/Symbols.cs index 6bde62f56..be74d2b5b 100644 --- a/src/ARMeilleure/Diagnostics/Symbols.cs +++ b/src/ARMeilleure/Diagnostics/Symbols.cs @@ -1,6 +1,7 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Text; namespace ARMeilleure.Diagnostics { @@ -33,9 +34,7 @@ static Symbols() public static string Get(ulong address) { - string result; - - if (_symbols.TryGetValue(address, out result)) + if (_symbols.TryGetValue(address, out string result)) { return result; } @@ -49,13 +48,15 @@ public static string Get(ulong address) ulong diff = address - symbol.Start; ulong rem = diff % symbol.ElementSize; - result = symbol.Name + "_" + diff / symbol.ElementSize; + StringBuilder resultBuilder = new(); + resultBuilder.Append($"{symbol.Name}_{diff / symbol.ElementSize}"); if (rem != 0) { - result += "+" + rem; + resultBuilder.Append($"+{rem}"); } + result = resultBuilder.ToString(); _symbols.TryAdd(address, result); return result; diff --git a/src/ARMeilleure/Diagnostics/TranslatorEventSource.cs b/src/ARMeilleure/Diagnostics/TranslatorEventSource.cs index a4f17844d..2e1be8c51 100644 --- a/src/ARMeilleure/Diagnostics/TranslatorEventSource.cs +++ b/src/ARMeilleure/Diagnostics/TranslatorEventSource.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.Tracing; +using System.Diagnostics.Tracing; using System.Threading; namespace ARMeilleure.Diagnostics @@ -19,19 +19,19 @@ public TranslatorEventSource() { _rejitQueueCounter = new PollingCounter("rejit-queue-length", this, () => _rejitQueue) { - DisplayName = "Rejit Queue Length" + DisplayName = "Rejit Queue Length", }; _funcTabSizeCounter = new PollingCounter("addr-tab-alloc", this, () => _funcTabSize / 1024d / 1024d) { DisplayName = "AddressTable Total Bytes Allocated", - DisplayUnits = "MiB" + DisplayUnits = "MiB", }; _funcTabLeafSizeCounter = new PollingCounter("addr-tab-leaf-alloc", this, () => _funcTabLeafSize / 1024d / 1024d) { DisplayName = "AddressTable Total Leaf Bytes Allocated", - DisplayUnits = "MiB" + DisplayUnits = "MiB", }; } diff --git a/src/ARMeilleure/Instructions/CryptoHelper.cs b/src/ARMeilleure/Instructions/CryptoHelper.cs index e517c75d2..ba68cebb3 100644 --- a/src/ARMeilleure/Instructions/CryptoHelper.cs +++ b/src/ARMeilleure/Instructions/CryptoHelper.cs @@ -7,7 +7,8 @@ namespace ARMeilleure.Instructions { static class CryptoHelper { -#region "LookUp Tables" + #region "LookUp Tables" +#pragma warning disable IDE1006 // Naming rule violation private static ReadOnlySpan _sBox => new byte[] { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, @@ -25,7 +26,7 @@ static class CryptoHelper 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, }; private static ReadOnlySpan _invSBox => new byte[] @@ -45,7 +46,7 @@ static class CryptoHelper 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, }; private static ReadOnlySpan _gfMul02 => new byte[] @@ -65,7 +66,7 @@ static class CryptoHelper 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, - 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, }; private static ReadOnlySpan _gfMul03 => new byte[] @@ -85,7 +86,7 @@ static class CryptoHelper 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, - 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, }; private static ReadOnlySpan _gfMul09 => new byte[] @@ -105,7 +106,7 @@ static class CryptoHelper 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, - 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46 + 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, }; private static ReadOnlySpan _gfMul0B => new byte[] @@ -125,7 +126,7 @@ static class CryptoHelper 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, - 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3 + 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, }; private static ReadOnlySpan _gfMul0D => new byte[] @@ -145,7 +146,7 @@ static class CryptoHelper 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, - 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97 + 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, }; private static ReadOnlySpan _gfMul0E => new byte[] @@ -165,23 +166,24 @@ static class CryptoHelper 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, - 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d + 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, }; private static ReadOnlySpan _srPerm => new byte[] { - 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 + 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, }; private static ReadOnlySpan _isrPerm => new byte[] { - 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 + 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11, }; -#endregion +#pragma warning restore IDE1006 + #endregion public static V128 AesInvMixColumns(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int columns = 0; columns <= 3; columns++) @@ -204,7 +206,7 @@ public static V128 AesInvMixColumns(V128 op) public static V128 AesInvShiftRows(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int idx = 0; idx <= 15; idx++) @@ -217,7 +219,7 @@ public static V128 AesInvShiftRows(V128 op) public static V128 AesInvSubBytes(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int idx = 0; idx <= 15; idx++) @@ -230,7 +232,7 @@ public static V128 AesInvSubBytes(V128 op) public static V128 AesMixColumns(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int columns = 0; columns <= 3; columns++) @@ -253,7 +255,7 @@ public static V128 AesMixColumns(V128 op) public static V128 AesShiftRows(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int idx = 0; idx <= 15; idx++) @@ -266,7 +268,7 @@ public static V128 AesShiftRows(V128 op) public static V128 AesSubBytes(V128 op) { - byte[] inState = op.ToArray(); + byte[] inState = op.ToArray(); byte[] outState = new byte[16]; for (int idx = 0; idx <= 15; idx++) diff --git a/src/ARMeilleure/Instructions/InstEmitAlu.cs b/src/ARMeilleure/Instructions/InstEmitAlu.cs index e0d10e77d..ac17c32a7 100644 --- a/src/ARMeilleure/Instructions/InstEmitAlu.cs +++ b/src/ARMeilleure/Instructions/InstEmitAlu.cs @@ -3,7 +3,6 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System.Diagnostics; - using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -12,7 +11,7 @@ namespace ARMeilleure.Instructions { static partial class InstEmit { - public static void Adc(ArmEmitterContext context) => EmitAdc(context, setFlags: false); + public static void Adc(ArmEmitterContext context) => EmitAdc(context, setFlags: false); public static void Adcs(ArmEmitterContext context) => EmitAdc(context, setFlags: true); private static void EmitAdc(ArmEmitterContext context, bool setFlags) @@ -87,7 +86,7 @@ public static void Asrv(ArmEmitterContext context) SetAluDOrZR(context, context.ShiftRightSI(GetAluN(context), GetAluMShift(context))); } - public static void Bic(ArmEmitterContext context) => EmitBic(context, setFlags: false); + public static void Bic(ArmEmitterContext context) => EmitBic(context, setFlags: false); public static void Bics(ArmEmitterContext context) => EmitBic(context, setFlags: true); private static void EmitBic(ArmEmitterContext context, bool setFlags) @@ -190,7 +189,7 @@ public static void Lsrv(ArmEmitterContext context) SetAluDOrZR(context, context.ShiftRightUI(GetAluN(context), GetAluMShift(context))); } - public static void Sbc(ArmEmitterContext context) => EmitSbc(context, setFlags: false); + public static void Sbc(ArmEmitterContext context) => EmitSbc(context, setFlags: false); public static void Sbcs(ArmEmitterContext context) => EmitSbc(context, setFlags: true); private static void EmitSbc(ArmEmitterContext context, bool setFlags) @@ -281,16 +280,16 @@ private static Operand EmitReverseBits64Op(ArmEmitterContext context, Operand op Debug.Assert(op.Type == OperandType.I64); Operand val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xaaaaaaaaaaaaaaaaul)), Const(1)), - context.ShiftLeft (context.BitwiseAnd(op, Const(0x5555555555555555ul)), Const(1))); + context.ShiftLeft(context.BitwiseAnd(op, Const(0x5555555555555555ul)), Const(1))); val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xccccccccccccccccul)), Const(2)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x3333333333333333ul)), Const(2))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x3333333333333333ul)), Const(2))); val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xf0f0f0f0f0f0f0f0ul)), Const(4)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x0f0f0f0f0f0f0f0ful)), Const(4))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x0f0f0f0f0f0f0f0ful)), Const(4))); val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xff00ff00ff00ff00ul)), Const(8)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x00ff00ff00ff00fful)), Const(8))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x00ff00ff00ff00fful)), Const(8))); val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xffff0000ffff0000ul)), Const(16)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x0000ffff0000fffful)), Const(16))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x0000ffff0000fffful)), Const(16))); return context.BitwiseOr(context.ShiftRightUI(val, Const(32)), context.ShiftLeft(val, Const(32))); } @@ -340,7 +339,7 @@ private static Operand EmitReverseBytes32_64Op(ArmEmitterContext context, Operan Operand val = EmitReverseBytes16_64Op(context, op); return context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xffff0000ffff0000ul)), Const(16)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x0000ffff0000fffful)), Const(16))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x0000ffff0000fffful)), Const(16))); } public static void Rev64(ArmEmitterContext context) diff --git a/src/ARMeilleure/Instructions/InstEmitAlu32.cs b/src/ARMeilleure/Instructions/InstEmitAlu32.cs index 584ada7e0..3a5e71bcc 100644 --- a/src/ARMeilleure/Instructions/InstEmitAlu32.cs +++ b/src/ARMeilleure/Instructions/InstEmitAlu32.cs @@ -2,13 +2,14 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; - +using System.Diagnostics.CodeAnalysis; using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.Instructions { + [SuppressMessage("Style", "IDE0059: Remove unnecessary value assignment")] static partial class InstEmit32 { public static void Add(ArmEmitterContext context) diff --git a/src/ARMeilleure/Instructions/InstEmitAluHelper.cs b/src/ARMeilleure/Instructions/InstEmitAluHelper.cs index 994878ad7..4d4a31f7b 100644 --- a/src/ARMeilleure/Instructions/InstEmitAluHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitAluHelper.cs @@ -26,7 +26,7 @@ public static bool ShouldSetFlags(ArmEmitterContext context) public static void EmitNZFlagsCheck(ArmEmitterContext context, Operand d) { - SetFlag(context, PState.NFlag, context.ICompareLess (d, Const(d.Type, 0))); + SetFlag(context, PState.NFlag, context.ICompareLess(d, Const(d.Type, 0))); SetFlag(context, PState.ZFlag, context.ICompareEqual(d, Const(d.Type, 0))); } @@ -196,60 +196,73 @@ public static Operand GetAluM(ArmEmitterContext context, bool setCarry = true) { // ARM32. case IOpCode32AluImm op: - { - if (ShouldSetFlags(context) && op.IsRotated && setCarry) { - SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31)); + if (ShouldSetFlags(context) && op.IsRotated && setCarry) + { + SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31)); + } + + return Const(op.Immediate); } + case IOpCode32AluImm16 op: return Const(op.Immediate); - } - - case IOpCode32AluImm16 op: return Const(op.Immediate); - case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry); - case IOpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry); + case IOpCode32AluRsImm op: + return GetMShiftedByImmediate(context, op, setCarry); + case IOpCode32AluRsReg op: + return GetMShiftedByReg(context, op, setCarry); - case IOpCode32AluReg op: return GetIntA32(context, op.Rm); + case IOpCode32AluReg op: + return GetIntA32(context, op.Rm); // ARM64. case IOpCodeAluImm op: - { - if (op.GetOperandType() == OperandType.I32) - { - return Const((int)op.Immediate); - } - else { - return Const(op.Immediate); + if (op.GetOperandType() == OperandType.I32) + { + return Const((int)op.Immediate); + } + else + { + return Const(op.Immediate); + } } - } case IOpCodeAluRs op: - { - Operand value = GetIntOrZR(context, op.Rm); - - switch (op.ShiftType) { - case ShiftType.Lsl: value = context.ShiftLeft (value, Const(op.Shift)); break; - case ShiftType.Lsr: value = context.ShiftRightUI(value, Const(op.Shift)); break; - case ShiftType.Asr: value = context.ShiftRightSI(value, Const(op.Shift)); break; - case ShiftType.Ror: value = context.RotateRight (value, Const(op.Shift)); break; - } + Operand value = GetIntOrZR(context, op.Rm); - return value; - } + switch (op.ShiftType) + { + case ShiftType.Lsl: + value = context.ShiftLeft(value, Const(op.Shift)); + break; + case ShiftType.Lsr: + value = context.ShiftRightUI(value, Const(op.Shift)); + break; + case ShiftType.Asr: + value = context.ShiftRightSI(value, Const(op.Shift)); + break; + case ShiftType.Ror: + value = context.RotateRight(value, Const(op.Shift)); + break; + } + + return value; + } case IOpCodeAluRx op: - { - Operand value = GetExtendedM(context, op.Rm, op.IntType); + { + Operand value = GetExtendedM(context, op.Rm, op.IntType); - value = context.ShiftLeft(value, Const(op.Shift)); + value = context.ShiftLeft(value, Const(op.Shift)); - return value; - } + return value; + } - default: throw InvalidOpCodeType(context.CurrOp); + default: + throw InvalidOpCodeType(context.CurrOp); } } @@ -269,9 +282,15 @@ public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode3 { switch (op.ShiftType) { - case ShiftType.Lsr: shift = 32; break; - case ShiftType.Asr: shift = 32; break; - case ShiftType.Ror: shift = 1; break; + case ShiftType.Lsr: + shift = 32; + break; + case ShiftType.Asr: + shift = 32; + break; + case ShiftType.Ror: + shift = 1; + break; } } @@ -281,9 +300,15 @@ public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode3 switch (op.ShiftType) { - case ShiftType.Lsl: m = GetLslC(context, m, setCarry, shift); break; - case ShiftType.Lsr: m = GetLsrC(context, m, setCarry, shift); break; - case ShiftType.Asr: m = GetAsrC(context, m, setCarry, shift); break; + case ShiftType.Lsl: + m = GetLslC(context, m, setCarry, shift); + break; + case ShiftType.Lsr: + m = GetLsrC(context, m, setCarry, shift); + break; + case ShiftType.Asr: + m = GetAsrC(context, m, setCarry, shift); + break; case ShiftType.Ror: if (op.Immediate != 0) { @@ -306,9 +331,15 @@ public static int DecodeImmShift(ShiftType shiftType, int shift) { switch (shiftType) { - case ShiftType.Lsr: shift = 32; break; - case ShiftType.Asr: shift = 32; break; - case ShiftType.Ror: shift = 1; break; + case ShiftType.Lsr: + shift = 32; + break; + case ShiftType.Asr: + shift = 32; + break; + case ShiftType.Ror: + shift = 1; + break; } } @@ -328,10 +359,18 @@ public static Operand GetMShiftedByReg(ArmEmitterContext context, IOpCode32AluRs switch (op.ShiftType) { - case ShiftType.Lsl: shiftResult = EmitLslC(context, m, setCarry, s, shiftIsZero); break; - case ShiftType.Lsr: shiftResult = EmitLsrC(context, m, setCarry, s, shiftIsZero); break; - case ShiftType.Asr: shiftResult = EmitAsrC(context, m, setCarry, s, shiftIsZero); break; - case ShiftType.Ror: shiftResult = EmitRorC(context, m, setCarry, s, shiftIsZero); break; + case ShiftType.Lsl: + shiftResult = EmitLslC(context, m, setCarry, s, shiftIsZero); + break; + case ShiftType.Lsr: + shiftResult = EmitLsrC(context, m, setCarry, s, shiftIsZero); + break; + case ShiftType.Asr: + shiftResult = EmitAsrC(context, m, setCarry, s, shiftIsZero); + break; + case ShiftType.Ror: + shiftResult = EmitRorC(context, m, setCarry, s, shiftIsZero); + break; } return context.ConditionalSelect(shiftIsZero, zeroResult, shiftResult); diff --git a/src/ARMeilleure/Instructions/InstEmitBfm.cs b/src/ARMeilleure/Instructions/InstEmitBfm.cs index 46a7ddddd..aaf228756 100644 --- a/src/ARMeilleure/Instructions/InstEmitBfm.cs +++ b/src/ARMeilleure/Instructions/InstEmitBfm.cs @@ -84,9 +84,9 @@ public static void Sbfm(ArmEmitterContext context) { Operand res = GetIntOrZR(context, op.Rn); - res = context.ShiftLeft (res, Const(bitsCount - 1 - op.Pos)); + res = context.ShiftLeft(res, Const(bitsCount - 1 - op.Pos)); res = context.ShiftRightSI(res, Const(bitsCount - 1)); - res = context.BitwiseAnd (res, Const(res.Type, ~op.TMask)); + res = context.BitwiseAnd(res, Const(res.Type, ~op.TMask)); Operand n2 = GetBfmN(context); @@ -193,4 +193,4 @@ private static Operand GetBfmN(ArmEmitterContext context) return context.BitwiseAnd(context.RotateRight(res, Const(op.Shift)), Const(res.Type, mask)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitCcmp.cs b/src/ARMeilleure/Instructions/InstEmitCcmp.cs index 7f0beb6cb..a71fc2689 100644 --- a/src/ARMeilleure/Instructions/InstEmitCcmp.cs +++ b/src/ARMeilleure/Instructions/InstEmitCcmp.cs @@ -2,7 +2,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; - using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitHelper; @@ -20,7 +19,7 @@ private static void EmitCcmp(ArmEmitterContext context, bool isNegated) OpCodeCcmp op = (OpCodeCcmp)context.CurrOp; Operand lblTrue = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); EmitCondBranch(context, lblTrue, op.Cond); @@ -58,4 +57,4 @@ private static void EmitCcmp(ArmEmitterContext context, bool isNegated) context.MarkLabel(lblEnd); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitCsel.cs b/src/ARMeilleure/Instructions/InstEmitCsel.cs index 926b9a9ed..1cd936b31 100644 --- a/src/ARMeilleure/Instructions/InstEmitCsel.cs +++ b/src/ARMeilleure/Instructions/InstEmitCsel.cs @@ -1,7 +1,6 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; - using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -15,10 +14,10 @@ private enum CselOperation None, Increment, Invert, - Negate + Negate, } - public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None); + public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None); public static void Csinc(ArmEmitterContext context) => EmitCsel(context, CselOperation.Increment); public static void Csinv(ArmEmitterContext context) => EmitCsel(context, CselOperation.Invert); public static void Csneg(ArmEmitterContext context) => EmitCsel(context, CselOperation.Negate); @@ -50,4 +49,4 @@ private static void EmitCsel(ArmEmitterContext context, CselOperation cselOp) SetIntOrZR(context, op.Rd, d); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitDiv.cs b/src/ARMeilleure/Instructions/InstEmitDiv.cs index 39a5c32e6..728462ed4 100644 --- a/src/ARMeilleure/Instructions/InstEmitDiv.cs +++ b/src/ARMeilleure/Instructions/InstEmitDiv.cs @@ -1,7 +1,6 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -23,7 +22,7 @@ private static void EmitDiv(ArmEmitterContext context, bool unsigned) Operand divisorIsZero = context.ICompareEqual(m, Const(m.Type, 0)); Operand lblBadDiv = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); context.BranchIfTrue(lblBadDiv, divisorIsZero); @@ -33,7 +32,7 @@ private static void EmitDiv(ArmEmitterContext context, bool unsigned) bool is32Bits = op.RegisterSize == RegisterSize.Int32; Operand intMin = is32Bits ? Const(int.MinValue) : Const(long.MinValue); - Operand minus1 = is32Bits ? Const(-1) : Const(-1L); + Operand minus1 = is32Bits ? Const(-1) : Const(-1L); Operand nIsIntMin = context.ICompareEqual(n, intMin); Operand mIsMinus1 = context.ICompareEqual(m, minus1); @@ -51,7 +50,7 @@ private static void EmitDiv(ArmEmitterContext context, bool unsigned) Operand d = unsigned ? context.DivideUI(n, m) - : context.Divide (n, m); + : context.Divide(n, m); SetAluDOrZR(context, d); diff --git a/src/ARMeilleure/Instructions/InstEmitException.cs b/src/ARMeilleure/Instructions/InstEmitException.cs index 0baaa87d7..d30fb2fbd 100644 --- a/src/ARMeilleure/Instructions/InstEmitException.cs +++ b/src/ARMeilleure/Instructions/InstEmitException.cs @@ -52,4 +52,4 @@ public static void Und(ArmEmitterContext context) context.Return(Const(op.Address)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitException32.cs b/src/ARMeilleure/Instructions/InstEmitException32.cs index ec0c32bf9..57af1522b 100644 --- a/src/ARMeilleure/Instructions/InstEmitException32.cs +++ b/src/ARMeilleure/Instructions/InstEmitException32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/Instructions/InstEmitFlow.cs b/src/ARMeilleure/Instructions/InstEmitFlow.cs index c40eb55cf..a986bf66f 100644 --- a/src/ARMeilleure/Instructions/InstEmitFlow.cs +++ b/src/ARMeilleure/Instructions/InstEmitFlow.cs @@ -53,7 +53,7 @@ public static void Br(ArmEmitterContext context) } public static void Cbnz(ArmEmitterContext context) => EmitCb(context, onNotZero: true); - public static void Cbz(ArmEmitterContext context) => EmitCb(context, onNotZero: false); + public static void Cbz(ArmEmitterContext context) => EmitCb(context, onNotZero: false); private static void EmitCb(ArmEmitterContext context, bool onNotZero) { @@ -70,7 +70,7 @@ public static void Ret(ArmEmitterContext context) } public static void Tbnz(ArmEmitterContext context) => EmitTb(context, onNotZero: true); - public static void Tbz(ArmEmitterContext context) => EmitTb(context, onNotZero: false); + public static void Tbz(ArmEmitterContext context) => EmitTb(context, onNotZero: false); private static void EmitTb(ArmEmitterContext context, bool onNotZero) { @@ -104,4 +104,4 @@ private static void EmitBranch(ArmEmitterContext context, Operand value, bool on } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitFlow32.cs b/src/ARMeilleure/Instructions/InstEmitFlow32.cs index 3a7707ee9..289d3f483 100644 --- a/src/ARMeilleure/Instructions/InstEmitFlow32.cs +++ b/src/ARMeilleure/Instructions/InstEmitFlow32.cs @@ -82,7 +82,7 @@ public static void Bx(ArmEmitterContext context) } public static void Cbnz(ArmEmitterContext context) => EmitCb(context, onNotZero: true); - public static void Cbz(ArmEmitterContext context) => EmitCb(context, onNotZero: false); + public static void Cbz(ArmEmitterContext context) => EmitCb(context, onNotZero: false); private static void EmitCb(ArmEmitterContext context, bool onNotZero) { @@ -109,7 +109,7 @@ public static void It(ArmEmitterContext context) } public static void Tbb(ArmEmitterContext context) => EmitTb(context, halfword: false); - public static void Tbh(ArmEmitterContext context) => EmitTb(context, halfword: true); + public static void Tbh(ArmEmitterContext context) => EmitTb(context, halfword: true); private static void EmitTb(ArmEmitterContext context, bool halfword) { @@ -133,4 +133,4 @@ private static void EmitTb(ArmEmitterContext context, bool halfword) EmitVirtualJump(context, targetAddress, isReturn: false); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs index 6ac329085..2009bafda 100644 --- a/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs @@ -75,66 +75,66 @@ Operand Inverse(Operand val) break; case Condition.GtUn: - { - Operand c = GetFlag(PState.CFlag); - Operand z = GetFlag(PState.ZFlag); + { + Operand c = GetFlag(PState.CFlag); + Operand z = GetFlag(PState.ZFlag); - value = context.BitwiseAnd(c, Inverse(z)); + value = context.BitwiseAnd(c, Inverse(z)); - break; - } + break; + } case Condition.LeUn: - { - Operand c = GetFlag(PState.CFlag); - Operand z = GetFlag(PState.ZFlag); + { + Operand c = GetFlag(PState.CFlag); + Operand z = GetFlag(PState.ZFlag); - value = context.BitwiseOr(Inverse(c), z); + value = context.BitwiseOr(Inverse(c), z); - break; - } + break; + } case Condition.Ge: - { - Operand n = GetFlag(PState.NFlag); - Operand v = GetFlag(PState.VFlag); + { + Operand n = GetFlag(PState.NFlag); + Operand v = GetFlag(PState.VFlag); - value = context.ICompareEqual(n, v); + value = context.ICompareEqual(n, v); - break; - } + break; + } case Condition.Lt: - { - Operand n = GetFlag(PState.NFlag); - Operand v = GetFlag(PState.VFlag); + { + Operand n = GetFlag(PState.NFlag); + Operand v = GetFlag(PState.VFlag); - value = context.ICompareNotEqual(n, v); + value = context.ICompareNotEqual(n, v); - break; - } + break; + } case Condition.Gt: - { - Operand n = GetFlag(PState.NFlag); - Operand z = GetFlag(PState.ZFlag); - Operand v = GetFlag(PState.VFlag); + { + Operand n = GetFlag(PState.NFlag); + Operand z = GetFlag(PState.ZFlag); + Operand v = GetFlag(PState.VFlag); - value = context.BitwiseAnd(Inverse(z), context.ICompareEqual(n, v)); + value = context.BitwiseAnd(Inverse(z), context.ICompareEqual(n, v)); - break; - } + break; + } case Condition.Le: - { - Operand n = GetFlag(PState.NFlag); - Operand z = GetFlag(PState.ZFlag); - Operand v = GetFlag(PState.VFlag); + { + Operand n = GetFlag(PState.NFlag); + Operand z = GetFlag(PState.ZFlag); + Operand v = GetFlag(PState.VFlag); - value = context.BitwiseOr(z, context.ICompareNotEqual(n, v)); + value = context.BitwiseOr(z, context.ICompareNotEqual(n, v)); - break; - } + break; + } } return value; diff --git a/src/ARMeilleure/Instructions/InstEmitHash32.cs b/src/ARMeilleure/Instructions/InstEmitHash32.cs index 5d39f8afc..30c893a78 100644 --- a/src/ARMeilleure/Instructions/InstEmitHash32.cs +++ b/src/ARMeilleure/Instructions/InstEmitHash32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using static ARMeilleure.Instructions.InstEmitHashHelper; diff --git a/src/ARMeilleure/Instructions/InstEmitHashHelper.cs b/src/ARMeilleure/Instructions/InstEmitHashHelper.cs index 55a03a4f6..9b1ad8721 100644 --- a/src/ARMeilleure/Instructions/InstEmitHashHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitHashHelper.cs @@ -1,4 +1,4 @@ -// https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf +// https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; @@ -45,7 +45,7 @@ public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand } else { - string name = (size, castagnoli) switch + string name = (size, castagnoli) switch { (0, false) => nameof(SoftFallback.Crc32b), (1, false) => nameof(SoftFallback.Crc32h), @@ -55,7 +55,7 @@ public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand (1, true) => nameof(SoftFallback.Crc32ch), (2, true) => nameof(SoftFallback.Crc32cw), (3, true) => nameof(SoftFallback.Crc32cx), - _ => throw new ArgumentOutOfRangeException(nameof(size)) + _ => throw new ArgumentOutOfRangeException(nameof(size)), }; return context.Call(typeof(SoftFallback).GetMethod(name), crc, value); @@ -71,9 +71,15 @@ private static Operand EmitCrc32Optimized(ArmEmitterContext context, Operand crc switch (size) { - case 0: data = context.VectorInsert8(context.VectorZero(), data, 0); break; - case 1: data = context.VectorInsert16(context.VectorZero(), data, 0); break; - case 2: data = context.VectorInsert(context.VectorZero(), data, 0); break; + case 0: + data = context.VectorInsert8(context.VectorZero(), data, 0); + break; + case 1: + data = context.VectorInsert16(context.VectorZero(), data, 0); + break; + case 2: + data = context.VectorInsert(context.VectorZero(), data, 0); + break; } int bitsize = 8 << size; diff --git a/src/ARMeilleure/Instructions/InstEmitHelper.cs b/src/ARMeilleure/Instructions/InstEmitHelper.cs index a22bb3fb7..7a515f94f 100644 --- a/src/ARMeilleure/Instructions/InstEmitHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitHelper.cs @@ -16,13 +16,25 @@ public static Operand GetExtendedM(ArmEmitterContext context, int rm, IntType ty switch (type) { - case IntType.UInt8: value = context.ZeroExtend8 (value.Type, value); break; - case IntType.UInt16: value = context.ZeroExtend16(value.Type, value); break; - case IntType.UInt32: value = context.ZeroExtend32(value.Type, value); break; - - case IntType.Int8: value = context.SignExtend8 (value.Type, value); break; - case IntType.Int16: value = context.SignExtend16(value.Type, value); break; - case IntType.Int32: value = context.SignExtend32(value.Type, value); break; + case IntType.UInt8: + value = context.ZeroExtend8(value.Type, value); + break; + case IntType.UInt16: + value = context.ZeroExtend16(value.Type, value); + break; + case IntType.UInt32: + value = context.ZeroExtend32(value.Type, value); + break; + + case IntType.Int8: + value = context.SignExtend8(value.Type, value); + break; + case IntType.Int16: + value = context.SignExtend16(value.Type, value); + break; + case IntType.Int32: + value = context.SignExtend32(value.Type, value); + break; } return value; @@ -100,78 +112,51 @@ public static int GetRegisterAlias(Aarch32Mode mode, int regIndex) public static int GetBankedRegisterAlias(Aarch32Mode mode, int regIndex) { - switch (regIndex) + return regIndex switch { - case 8: return mode == Aarch32Mode.Fiq - ? RegisterAlias.R8Fiq - : RegisterAlias.R8Usr; - - case 9: return mode == Aarch32Mode.Fiq - ? RegisterAlias.R9Fiq - : RegisterAlias.R9Usr; - - case 10: return mode == Aarch32Mode.Fiq - ? RegisterAlias.R10Fiq - : RegisterAlias.R10Usr; - - case 11: return mode == Aarch32Mode.Fiq - ? RegisterAlias.R11Fiq - : RegisterAlias.R11Usr; - - case 12: return mode == Aarch32Mode.Fiq - ? RegisterAlias.R12Fiq - : RegisterAlias.R12Usr; - - case 13: - switch (mode) - { - case Aarch32Mode.User: - case Aarch32Mode.System: return RegisterAlias.SpUsr; - case Aarch32Mode.Fiq: return RegisterAlias.SpFiq; - case Aarch32Mode.Irq: return RegisterAlias.SpIrq; - case Aarch32Mode.Supervisor: return RegisterAlias.SpSvc; - case Aarch32Mode.Abort: return RegisterAlias.SpAbt; - case Aarch32Mode.Hypervisor: return RegisterAlias.SpHyp; - case Aarch32Mode.Undefined: return RegisterAlias.SpUnd; - - default: throw new ArgumentException(nameof(mode)); - } - - case 14: - switch (mode) - { - case Aarch32Mode.User: - case Aarch32Mode.Hypervisor: - case Aarch32Mode.System: return RegisterAlias.LrUsr; - case Aarch32Mode.Fiq: return RegisterAlias.LrFiq; - case Aarch32Mode.Irq: return RegisterAlias.LrIrq; - case Aarch32Mode.Supervisor: return RegisterAlias.LrSvc; - case Aarch32Mode.Abort: return RegisterAlias.LrAbt; - case Aarch32Mode.Undefined: return RegisterAlias.LrUnd; - - default: throw new ArgumentException(nameof(mode)); - } - - default: throw new ArgumentOutOfRangeException(nameof(regIndex)); - } +#pragma warning disable IDE0055 // Disable formatting + 8 => mode == Aarch32Mode.Fiq ? RegisterAlias.R8Fiq : RegisterAlias.R8Usr, + 9 => mode == Aarch32Mode.Fiq ? RegisterAlias.R9Fiq : RegisterAlias.R9Usr, + 10 => mode == Aarch32Mode.Fiq ? RegisterAlias.R10Fiq : RegisterAlias.R10Usr, + 11 => mode == Aarch32Mode.Fiq ? RegisterAlias.R11Fiq : RegisterAlias.R11Usr, + 12 => mode == Aarch32Mode.Fiq ? RegisterAlias.R12Fiq : RegisterAlias.R12Usr, + 13 => mode switch + { + Aarch32Mode.User or Aarch32Mode.System => RegisterAlias.SpUsr, + Aarch32Mode.Fiq => RegisterAlias.SpFiq, + Aarch32Mode.Irq => RegisterAlias.SpIrq, + Aarch32Mode.Supervisor => RegisterAlias.SpSvc, + Aarch32Mode.Abort => RegisterAlias.SpAbt, + Aarch32Mode.Hypervisor => RegisterAlias.SpHyp, + Aarch32Mode.Undefined => RegisterAlias.SpUnd, + _ => throw new ArgumentException($"No such AArch32Mode: {mode}", nameof(mode)), + }, + 14 => mode switch + { + Aarch32Mode.User or Aarch32Mode.Hypervisor or Aarch32Mode.System => RegisterAlias.LrUsr, + Aarch32Mode.Fiq => RegisterAlias.LrFiq, + Aarch32Mode.Irq => RegisterAlias.LrIrq, + Aarch32Mode.Supervisor => RegisterAlias.LrSvc, + Aarch32Mode.Abort => RegisterAlias.LrAbt, + Aarch32Mode.Undefined => RegisterAlias.LrUnd, + _ => throw new ArgumentException($"No such AArch32Mode: {mode}", nameof(mode)), + }, + _ => throw new ArgumentOutOfRangeException(nameof(regIndex), regIndex, null), +#pragma warning restore IDE0055 + }; } public static bool IsA32Return(ArmEmitterContext context) { - switch (context.CurrOp) + return context.CurrOp switch { - case IOpCode32MemMult op: - return true; // Setting PC using LDM is nearly always a return. - case OpCode32AluRsImm op: - return op.Rm == RegisterAlias.Aarch32Lr; - case OpCode32AluRsReg op: - return op.Rm == RegisterAlias.Aarch32Lr; - case OpCode32AluReg op: - return op.Rm == RegisterAlias.Aarch32Lr; - case OpCode32Mem op: - return op.Rn == RegisterAlias.Aarch32Sp && op.WBack && !op.Index; // Setting PC to an address stored on the stack is nearly always a return. - } - return false; + IOpCode32MemMult => true, // Setting PC using LDM is nearly always a return. + OpCode32AluRsImm op => op.Rm == RegisterAlias.Aarch32Lr, + OpCode32AluRsReg op => op.Rm == RegisterAlias.Aarch32Lr, + OpCode32AluReg op => op.Rm == RegisterAlias.Aarch32Lr, + OpCode32Mem op => op.Rn == RegisterAlias.Aarch32Sp && op.WBack && !op.Index, // Setting PC to an address stored on the stack is nearly always a return. + _ => false, + }; } public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0) diff --git a/src/ARMeilleure/Instructions/InstEmitMemory.cs b/src/ARMeilleure/Instructions/InstEmitMemory.cs index 7baed14c8..840099f9c 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemory.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemory.cs @@ -26,7 +26,7 @@ public static void Adrp(ArmEmitterContext context) SetIntOrZR(context, op.Rd, Const(address)); } - public static void Ldr(ArmEmitterContext context) => EmitLdr(context, signed: false); + public static void Ldr(ArmEmitterContext context) => EmitLdr(context, signed: false); public static void Ldrs(ArmEmitterContext context) => EmitLdr(context, signed: true); private static void EmitLdr(ArmEmitterContext context, bool signed) @@ -89,7 +89,7 @@ void EmitLoad(int rt, Operand ldAddr) Operand address = GetAddress(context); Operand address2 = GetAddress(context, 1L << op.Size); - EmitLoad(op.Rt, address); + EmitLoad(op.Rt, address); EmitLoad(op.Rt2, address2); EmitWBackIfNeeded(context, address); @@ -113,7 +113,7 @@ public static void Stp(ArmEmitterContext context) Operand address = GetAddress(context); Operand address2 = GetAddress(context, 1L << op.Size); - EmitStore(context, address, op.Rt, op.Size); + EmitStore(context, address, op.Rt, op.Size); EmitStore(context, address2, op.Rt2, op.Size); EmitWBackIfNeeded(context, address); @@ -126,42 +126,42 @@ private static Operand GetAddress(ArmEmitterContext context, long addend = 0) switch (context.CurrOp) { case OpCodeMemImm op: - { - address = context.Copy(GetIntOrSP(context, op.Rn)); - - // Pre-indexing. - if (!op.PostIdx) - { - address = context.Add(address, Const(op.Immediate + addend)); - } - else if (addend != 0) { - address = context.Add(address, Const(addend)); + address = context.Copy(GetIntOrSP(context, op.Rn)); + + // Pre-indexing. + if (!op.PostIdx) + { + address = context.Add(address, Const(op.Immediate + addend)); + } + else if (addend != 0) + { + address = context.Add(address, Const(addend)); + } + + break; } - break; - } - case OpCodeMemReg op: - { - Operand n = GetIntOrSP(context, op.Rn); + { + Operand n = GetIntOrSP(context, op.Rn); - Operand m = GetExtendedM(context, op.Rm, op.IntType); + Operand m = GetExtendedM(context, op.Rm, op.IntType); - if (op.Shift) - { - m = context.ShiftLeft(m, Const(op.Size)); - } + if (op.Shift) + { + m = context.ShiftLeft(m, Const(op.Size)); + } - address = context.Add(n, m); + address = context.Add(n, m); - if (addend != 0) - { - address = context.Add(address, Const(addend)); - } + if (addend != 0) + { + address = context.Add(address, Const(addend)); + } - break; - } + break; + } } return address; @@ -181,4 +181,4 @@ private static void EmitWBackIfNeeded(ArmEmitterContext context, Operand address } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitMemory32.cs b/src/ARMeilleure/Instructions/InstEmitMemory32.cs index 17ec97aa6..cee06700d 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemory32.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemory32.cs @@ -3,7 +3,6 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitMemoryHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -12,18 +11,18 @@ namespace ARMeilleure.Instructions { static partial class InstEmit32 { - private const int ByteSizeLog2 = 0; + private const int ByteSizeLog2 = 0; private const int HWordSizeLog2 = 1; - private const int WordSizeLog2 = 2; + private const int WordSizeLog2 = 2; private const int DWordSizeLog2 = 3; [Flags] enum AccessType { - Store = 0, - Signed = 1, - Load = 2, - Ordered = 4, + Store = 0, + Signed = 1, + Load = 2, + Ordered = 4, Exclusive = 8, LoadZx = Load, @@ -47,7 +46,7 @@ public static void Ldm(ArmEmitterContext context) SetIntA32(context, op.Rn, context.Add(n, Const(op.PostOffset))); } - int mask = op.RegisterMask; + int mask = op.RegisterMask; int offset = 0; for (int register = 0; mask != 0; mask >>= 1, register++) @@ -101,7 +100,7 @@ public static void Stm(ArmEmitterContext context) Operand baseAddress = context.Add(n, Const(op.Offset)); - int mask = op.RegisterMask; + int mask = op.RegisterMask; int offset = 0; for (int register = 0; mask != 0; mask >>= 1, register++) @@ -161,7 +160,7 @@ private static void EmitLoadOrStore(ArmEmitterContext context, int size, AccessT if (op.Index || op.WBack) { temp = op.Add - ? context.Add (n, m) + ? context.Add(n, m) : context.Subtract(n, m); } @@ -200,7 +199,7 @@ void Load(int rt, int offs, int loadSize) if (size == DWordSizeLog2) { Operand lblBigEndian = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag)); @@ -233,7 +232,7 @@ void Store(int rt, int offs, int storeSize) if (size == DWordSizeLog2) { Operand lblBigEndian = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag)); @@ -262,4 +261,4 @@ public static void Adr(ArmEmitterContext context) SetIntA32(context, op.Rd, Const(op.Immediate)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitMemoryEx.cs b/src/ARMeilleure/Instructions/InstEmitMemoryEx.cs index c7ed01e34..8c95b33c5 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemoryEx.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemoryEx.cs @@ -3,7 +3,6 @@ using ARMeilleure.Translation; using System; using System.Diagnostics; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitMemoryExHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -15,10 +14,10 @@ static partial class InstEmit [Flags] private enum AccessType { - None = 0, - Ordered = 1, + None = 0, + Ordered = 1, Exclusive = 2, - OrderedEx = Ordered | Exclusive + OrderedEx = Ordered | Exclusive, } public static void Clrex(ArmEmitterContext context) @@ -34,10 +33,10 @@ public static void Csdb(ArmEmitterContext context) public static void Dmb(ArmEmitterContext context) => EmitBarrier(context); public static void Dsb(ArmEmitterContext context) => EmitBarrier(context); - public static void Ldar(ArmEmitterContext context) => EmitLdr(context, AccessType.Ordered); + public static void Ldar(ArmEmitterContext context) => EmitLdr(context, AccessType.Ordered); public static void Ldaxr(ArmEmitterContext context) => EmitLdr(context, AccessType.OrderedEx); - public static void Ldxr(ArmEmitterContext context) => EmitLdr(context, AccessType.Exclusive); - public static void Ldxp(ArmEmitterContext context) => EmitLdp(context, AccessType.Exclusive); + public static void Ldxr(ArmEmitterContext context) => EmitLdr(context, AccessType.Exclusive); + public static void Ldxp(ArmEmitterContext context) => EmitLdp(context, AccessType.Exclusive); public static void Ldaxp(ArmEmitterContext context) => EmitLdp(context, AccessType.OrderedEx); private static void EmitLdr(ArmEmitterContext context, AccessType accType) @@ -54,7 +53,7 @@ private static void EmitLoadEx(ArmEmitterContext context, AccessType accType, bo { OpCodeMemEx op = (OpCodeMemEx)context.CurrOp; - bool ordered = (accType & AccessType.Ordered) != 0; + bool ordered = (accType & AccessType.Ordered) != 0; bool exclusive = (accType & AccessType.Exclusive) != 0; if (ordered) @@ -80,17 +79,17 @@ private static void EmitLoadEx(ArmEmitterContext context, AccessType accType, bo Operand valueHigh = context.ShiftRightUI(value, Const(32)); - SetIntOrZR(context, op.Rt, valueLow); + SetIntOrZR(context, op.Rt, valueLow); SetIntOrZR(context, op.Rt2, valueHigh); } else if (op.Size == 3) { Operand value = EmitLoadExclusive(context, address, exclusive, 4); - Operand valueLow = context.VectorExtract(OperandType.I64, value, 0); + Operand valueLow = context.VectorExtract(OperandType.I64, value, 0); Operand valueHigh = context.VectorExtract(OperandType.I64, value, 1); - SetIntOrZR(context, op.Rt, valueLow); + SetIntOrZR(context, op.Rt, valueLow); SetIntOrZR(context, op.Rt2, valueHigh); } else @@ -112,10 +111,10 @@ public static void Prfm(ArmEmitterContext context) // Memory Prefetch, execute as no-op. } - public static void Stlr(ArmEmitterContext context) => EmitStr(context, AccessType.Ordered); + public static void Stlr(ArmEmitterContext context) => EmitStr(context, AccessType.Ordered); public static void Stlxr(ArmEmitterContext context) => EmitStr(context, AccessType.OrderedEx); - public static void Stxr(ArmEmitterContext context) => EmitStr(context, AccessType.Exclusive); - public static void Stxp(ArmEmitterContext context) => EmitStp(context, AccessType.Exclusive); + public static void Stxr(ArmEmitterContext context) => EmitStr(context, AccessType.Exclusive); + public static void Stxp(ArmEmitterContext context) => EmitStp(context, AccessType.Exclusive); public static void Stlxp(ArmEmitterContext context) => EmitStp(context, AccessType.OrderedEx); private static void EmitStr(ArmEmitterContext context, AccessType accType) @@ -132,7 +131,7 @@ private static void EmitStoreEx(ArmEmitterContext context, AccessType accType, b { OpCodeMemEx op = (OpCodeMemEx)context.CurrOp; - bool ordered = (accType & AccessType.Ordered) != 0; + bool ordered = (accType & AccessType.Ordered) != 0; bool exclusive = (accType & AccessType.Exclusive) != 0; Operand address = context.Copy(GetIntOrSP(context, op.Rn)); @@ -153,8 +152,8 @@ private static void EmitStoreEx(ArmEmitterContext context, AccessType accType, b } else /* if (op.Size == 3) */ { - value = context.VectorInsert(context.VectorZero(), t, 0); - value = context.VectorInsert(value, t2, 1); + value = context.VectorInsert(context.VectorZero(), t, 0); + value = context.VectorInsert(value, t2, 1); } EmitStoreExclusive(context, address, value, exclusive, op.Size + 1, op.Rs, a32: false); @@ -175,4 +174,4 @@ private static void EmitBarrier(ArmEmitterContext context) context.MemoryBarrier(); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitMemoryEx32.cs b/src/ARMeilleure/Instructions/InstEmitMemoryEx32.cs index c0b6fc39d..150218827 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemoryEx32.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemoryEx32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs b/src/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs index 9a69442a6..7fca5b853 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs @@ -1,7 +1,6 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -33,7 +32,7 @@ public static Operand EmitLoadExclusive(ArmEmitterContext context, Operand addre Operand arg0 = context.LoadArgument(OperandType.I64, 0); - Operand exAddrPtr = context.Add(arg0, Const((long)NativeContext.GetExclusiveAddressOffset())); + Operand exAddrPtr = context.Add(arg0, Const((long)NativeContext.GetExclusiveAddressOffset())); Operand exValuePtr = context.Add(arg0, Const((long)NativeContext.GetExclusiveValueOffset())); context.Store(exAddrPtr, context.BitwiseAnd(address, Const(address.Type, GetExclusiveAddressMask()))); @@ -118,14 +117,14 @@ void SetRs(Operand value) 1 => context.Load16(exValuePtr), 2 => context.Load(OperandType.I32, exValuePtr), 3 => context.Load(OperandType.I64, exValuePtr), - _ => context.Load(OperandType.V128, exValuePtr) + _ => context.Load(OperandType.V128, exValuePtr), }; Operand currValue = size switch { 0 => context.CompareAndSwap8(physAddr, exValue, value), 1 => context.CompareAndSwap16(physAddr, exValue, value), - _ => context.CompareAndSwap(physAddr, exValue, value) + _ => context.CompareAndSwap(physAddr, exValue, value), }; // STEP 3: Check if we succeeded by comparing expected and in-memory values. @@ -133,14 +132,14 @@ void SetRs(Operand value) if (size == 4) { - Operand currValueLow = context.VectorExtract(OperandType.I64, currValue, 0); + Operand currValueLow = context.VectorExtract(OperandType.I64, currValue, 0); Operand currValueHigh = context.VectorExtract(OperandType.I64, currValue, 1); - Operand exValueLow = context.VectorExtract(OperandType.I64, exValue, 0); + Operand exValueLow = context.VectorExtract(OperandType.I64, exValue, 0); Operand exValueHigh = context.VectorExtract(OperandType.I64, exValue, 1); storeFailed = context.BitwiseOr( - context.ICompareNotEqual(currValueLow, exValueLow), + context.ICompareNotEqual(currValueLow, exValueLow), context.ICompareNotEqual(currValueHigh, exValueHigh)); } else diff --git a/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index f97e395ce..a807eed51 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -5,7 +5,6 @@ using ARMeilleure.Translation.PTC; using System; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -20,7 +19,7 @@ private enum Extension { Zx, Sx32, - Sx64 + Sx64, } public static void EmitLoadZx(ArmEmitterContext context, Operand address, int rt, int size) @@ -66,9 +65,15 @@ private static void EmitLoad(ArmEmitterContext context, Operand address, Extensi switch (size) { - case 0: value = context.SignExtend8 (destType, value); break; - case 1: value = context.SignExtend16(destType, value); break; - case 2: value = context.SignExtend32(destType, value); break; + case 0: + value = context.SignExtend8(destType, value); + break; + case 1: + value = context.SignExtend16(destType, value); + break; + case 2: + value = context.SignExtend32(destType, value); + break; } } @@ -128,7 +133,7 @@ public static Operand EmitReadInt(ArmEmitterContext context, Operand address, in Operand temp = context.AllocateLocal(size == 3 ? OperandType.I64 : OperandType.I32); Operand lblSlowPath = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: false, size); @@ -136,10 +141,18 @@ public static Operand EmitReadInt(ArmEmitterContext context, Operand address, in switch (size) { - case 0: value = context.Load8 (physAddr); break; - case 1: value = context.Load16(physAddr); break; - case 2: value = context.Load (OperandType.I32, physAddr); break; - case 3: value = context.Load (OperandType.I64, physAddr); break; + case 0: + value = context.Load8(physAddr); + break; + case 1: + value = context.Load16(physAddr); + break; + case 2: + value = context.Load(OperandType.I32, physAddr); + break; + case 3: + value = context.Load(OperandType.I64, physAddr); + break; } context.Copy(temp, value); @@ -161,7 +174,7 @@ public static Operand EmitReadInt(ArmEmitterContext context, Operand address, in private static void EmitReadInt(ArmEmitterContext context, Operand address, int rt, int size) { Operand lblSlowPath = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: false, size); @@ -169,10 +182,18 @@ private static void EmitReadInt(ArmEmitterContext context, Operand address, int switch (size) { - case 0: value = context.Load8 (physAddr); break; - case 1: value = context.Load16(physAddr); break; - case 2: value = context.Load (OperandType.I32, physAddr); break; - case 3: value = context.Load (OperandType.I64, physAddr); break; + case 0: + value = context.Load8(physAddr); + break; + case 1: + value = context.Load16(physAddr); + break; + case 2: + value = context.Load(OperandType.I32, physAddr); + break; + case 3: + value = context.Load(OperandType.I64, physAddr); + break; } SetInt(context, rt, value); @@ -204,7 +225,7 @@ public static Operand EmitReadIntAligned(ArmEmitterContext context, Operand addr 1 => context.Load16(physAddr), 2 => context.Load(OperandType.I32, physAddr), 3 => context.Load(OperandType.I64, physAddr), - _ => context.Load(OperandType.V128, physAddr) + _ => context.Load(OperandType.V128, physAddr), }; } @@ -217,7 +238,7 @@ private static void EmitReadVector( int size) { Operand lblSlowPath = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: false, size); @@ -225,11 +246,21 @@ private static void EmitReadVector( switch (size) { - case 0: value = context.VectorInsert8 (vector, context.Load8(physAddr), elem); break; - case 1: value = context.VectorInsert16(vector, context.Load16(physAddr), elem); break; - case 2: value = context.VectorInsert (vector, context.Load(OperandType.I32, physAddr), elem); break; - case 3: value = context.VectorInsert (vector, context.Load(OperandType.I64, physAddr), elem); break; - case 4: value = context.Load (OperandType.V128, physAddr); break; + case 0: + value = context.VectorInsert8(vector, context.Load8(physAddr), elem); + break; + case 1: + value = context.VectorInsert16(vector, context.Load16(physAddr), elem); + break; + case 2: + value = context.VectorInsert(vector, context.Load(OperandType.I32, physAddr), elem); + break; + case 3: + value = context.VectorInsert(vector, context.Load(OperandType.I64, physAddr), elem); + break; + case 4: + value = context.Load(OperandType.V128, physAddr); + break; } context.Copy(GetVec(rt), value); @@ -254,7 +285,7 @@ private static Operand VectorCreate(ArmEmitterContext context, Operand value) private static void EmitWriteInt(ArmEmitterContext context, Operand address, int rt, int size) { Operand lblSlowPath = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: true, size); @@ -267,10 +298,18 @@ private static void EmitWriteInt(ArmEmitterContext context, Operand address, int switch (size) { - case 0: context.Store8 (physAddr, value); break; - case 1: context.Store16(physAddr, value); break; - case 2: context.Store (physAddr, value); break; - case 3: context.Store (physAddr, value); break; + case 0: + context.Store8(physAddr, value); + break; + case 1: + context.Store16(physAddr, value); + break; + case 2: + context.Store(physAddr, value); + break; + case 3: + context.Store(physAddr, value); + break; } if (!context.Memory.Type.IsHostMapped()) @@ -321,7 +360,7 @@ private static void EmitWriteVector( int size) { Operand lblSlowPath = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: true, size); @@ -329,11 +368,21 @@ private static void EmitWriteVector( switch (size) { - case 0: context.Store8 (physAddr, context.VectorExtract8(value, elem)); break; - case 1: context.Store16(physAddr, context.VectorExtract16(value, elem)); break; - case 2: context.Store (physAddr, context.VectorExtract(OperandType.I32, value, elem)); break; - case 3: context.Store (physAddr, context.VectorExtract(OperandType.I64, value, elem)); break; - case 4: context.Store (physAddr, value); break; + case 0: + context.Store8(physAddr, context.VectorExtract8(value, elem)); + break; + case 1: + context.Store16(physAddr, context.VectorExtract16(value, elem)); + break; + case 2: + context.Store(physAddr, context.VectorExtract(OperandType.I32, value, elem)); + break; + case 3: + context.Store(physAddr, context.VectorExtract(OperandType.I64, value, elem)); + break; + case 4: + context.Store(physAddr, value); + break; } if (!context.Memory.Type.IsHostMapped()) @@ -464,10 +513,18 @@ private static Operand EmitReadIntFallback(ArmEmitterContext context, Operand ad switch (size) { - case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); break; - case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); break; - case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); break; - case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break; + case 0: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); + break; + case 1: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); + break; + case 2: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); + break; + case 3: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); + break; } return context.Call(info, address); @@ -485,21 +542,39 @@ private static void EmitReadVectorFallback( switch (size) { - case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); break; - case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); break; - case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); break; - case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break; - case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)); break; + case 0: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); + break; + case 1: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); + break; + case 2: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); + break; + case 3: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); + break; + case 4: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)); + break; } Operand value = context.Call(info, address); switch (size) { - case 0: value = context.VectorInsert8 (vector, value, elem); break; - case 1: value = context.VectorInsert16(vector, value, elem); break; - case 2: value = context.VectorInsert (vector, value, elem); break; - case 3: value = context.VectorInsert (vector, value, elem); break; + case 0: + value = context.VectorInsert8(vector, value, elem); + break; + case 1: + value = context.VectorInsert16(vector, value, elem); + break; + case 2: + value = context.VectorInsert(vector, value, elem); + break; + case 3: + value = context.VectorInsert(vector, value, elem); + break; } context.Copy(GetVec(rt), value); @@ -511,10 +586,18 @@ private static void EmitWriteIntFallback(ArmEmitterContext context, Operand addr switch (size) { - case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); break; - case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); break; - case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); break; - case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); break; + case 0: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); + break; + case 1: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); + break; + case 2: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); + break; + case 3: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); + break; } Operand value = GetInt(context, rt); @@ -538,11 +621,21 @@ private static void EmitWriteVectorFallback( switch (size) { - case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); break; - case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); break; - case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); break; - case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); break; - case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)); break; + case 0: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); + break; + case 1: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); + break; + case 2: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); + break; + case 3: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); + break; + case 4: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)); + break; } Operand value = default; @@ -551,10 +644,18 @@ private static void EmitWriteVectorFallback( { switch (size) { - case 0: value = context.VectorExtract8 (GetVec(rt), elem); break; - case 1: value = context.VectorExtract16(GetVec(rt), elem); break; - case 2: value = context.VectorExtract (OperandType.I32, GetVec(rt), elem); break; - case 3: value = context.VectorExtract (OperandType.I64, GetVec(rt), elem); break; + case 0: + value = context.VectorExtract8(GetVec(rt), elem); + break; + case 1: + value = context.VectorExtract16(GetVec(rt), elem); + break; + case 2: + value = context.VectorExtract(OperandType.I32, GetVec(rt), elem); + break; + case 3: + value = context.VectorExtract(OperandType.I64, GetVec(rt), elem); + break; } } else @@ -585,18 +686,14 @@ private static void SetInt(ArmEmitterContext context, int rt, Operand value) // ARM32 helpers. public static Operand GetMemM(ArmEmitterContext context, bool setCarry = true) { - switch (context.CurrOp) + return context.CurrOp switch { - case IOpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry); - - case IOpCode32MemReg op: return GetIntA32(context, op.Rm); - - case IOpCode32Mem op: return Const(op.Immediate); - - case OpCode32SimdMemImm op: return Const(op.Immediate); - - default: throw InvalidOpCodeType(context.CurrOp); - } + IOpCode32MemRsImm op => GetMShiftedByImmediate(context, op, setCarry), + IOpCode32MemReg op => GetIntA32(context, op.Rm), + IOpCode32Mem op => Const(op.Immediate), + OpCode32SimdMemImm op => Const(op.Immediate), + _ => throw InvalidOpCodeType(context.CurrOp), + }; } private static Exception InvalidOpCodeType(OpCode opCode) @@ -614,9 +711,15 @@ public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode3 { switch (op.ShiftType) { - case ShiftType.Lsr: shift = 32; break; - case ShiftType.Asr: shift = 32; break; - case ShiftType.Ror: shift = 1; break; + case ShiftType.Lsr: + shift = 32; + break; + case ShiftType.Asr: + shift = 32; + break; + case ShiftType.Ror: + shift = 1; + break; } } @@ -626,9 +729,15 @@ public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode3 switch (op.ShiftType) { - case ShiftType.Lsl: m = InstEmitAluHelper.GetLslC(context, m, setCarry, shift); break; - case ShiftType.Lsr: m = InstEmitAluHelper.GetLsrC(context, m, setCarry, shift); break; - case ShiftType.Asr: m = InstEmitAluHelper.GetAsrC(context, m, setCarry, shift); break; + case ShiftType.Lsl: + m = InstEmitAluHelper.GetLslC(context, m, setCarry, shift); + break; + case ShiftType.Lsr: + m = InstEmitAluHelper.GetLsrC(context, m, setCarry, shift); + break; + case ShiftType.Asr: + m = InstEmitAluHelper.GetAsrC(context, m, setCarry, shift); + break; case ShiftType.Ror: if (op.Immediate != 0) { diff --git a/src/ARMeilleure/Instructions/InstEmitMove.cs b/src/ARMeilleure/Instructions/InstEmitMove.cs index d551bf2da..f23ac333b 100644 --- a/src/ARMeilleure/Instructions/InstEmitMove.cs +++ b/src/ARMeilleure/Instructions/InstEmitMove.cs @@ -38,4 +38,4 @@ public static void Movz(ArmEmitterContext context) SetIntOrZR(context, op.Rd, Const(op.GetOperandType(), op.Immediate)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitMul.cs b/src/ARMeilleure/Instructions/InstEmitMul.cs index 65d11b30d..89dc09938 100644 --- a/src/ARMeilleure/Instructions/InstEmitMul.cs +++ b/src/ARMeilleure/Instructions/InstEmitMul.cs @@ -2,7 +2,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; - +using System.Diagnostics.CodeAnalysis; using static ARMeilleure.Instructions.InstEmitHelper; namespace ARMeilleure.Instructions @@ -33,14 +33,15 @@ private static void EmitMul(ArmEmitterContext context, bool isAdd) public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract); [Flags] + [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")] private enum MullFlags { Subtract = 0, - Add = 1 << 0, - Signed = 1 << 1, + Add = 1 << 0, + Signed = 1 << 1, - SignedAdd = Signed | Add, - SignedSubtract = Signed | Subtract + SignedAdd = Signed | Add, + SignedSubtract = Signed | Subtract, } private static void EmitMull(ArmEmitterContext context, MullFlags flags) @@ -97,4 +98,4 @@ public static void Umulh(ArmEmitterContext context) SetIntOrZR(context, op.Rd, d); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitMul32.cs b/src/ARMeilleure/Instructions/InstEmitMul32.cs index 0822f92c3..b9966ad1d 100644 --- a/src/ARMeilleure/Instructions/InstEmitMul32.cs +++ b/src/ARMeilleure/Instructions/InstEmitMul32.cs @@ -1,9 +1,8 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; - using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -20,7 +19,7 @@ private enum MullFlags Signed = 1 << 2, SignedAdd = Signed | Add, - SignedSubtract = Signed | Subtract + SignedSubtract = Signed | Subtract, } public static void Mla(ArmEmitterContext context) @@ -287,14 +286,14 @@ public static void Umaal(ArmEmitterContext context) { IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; - Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn)); - Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm)); + Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn)); + Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm)); Operand dHi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.RdHi)); Operand dLo = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.RdLo)); Operand res = context.Multiply(n, m); - res = context.Add(res, dHi); - res = context.Add(res, dLo); + res = context.Add(res, dHi); + res = context.Add(res, dLo); Operand hi = context.ConvertI64ToI32(context.ShiftRightUI(res, Const(32))); Operand lo = context.ConvertI64ToI32(res); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/src/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs index 7e7f26b1a..543aab023 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs @@ -7,7 +7,6 @@ using ARMeilleure.Translation; using System; using System.Diagnostics; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper32; @@ -185,11 +184,12 @@ public static void Clz_V(ArmEmitterContext context) int eSize = 8 << op.Size; - Operand res = eSize switch { - 8 => Clz_V_I8 (context, GetVec(op.Rn)), + Operand res = eSize switch + { + 8 => Clz_V_I8(context, GetVec(op.Rn)), 16 => Clz_V_I16(context, GetVec(op.Rn)), 32 => Clz_V_I32(context, GetVec(op.Rn)), - _ => default + _ => default, }; if (res != default) @@ -230,14 +230,14 @@ private static Operand Clz_V_I8(ArmEmitterContext context, Operand arg) Operand clzTable = X86GetScalar(context, 0x01_01_01_01_02_02_03_04); Operand maskLow = X86GetAllElements(context, 0x0f_0f_0f_0f); - Operand c04 = X86GetAllElements(context, 0x04_04_04_04); + Operand c04 = X86GetAllElements(context, 0x04_04_04_04); // CLZ of low 4 bits of elements in arg. Operand loClz = context.AddIntrinsic(Intrinsic.X86Pshufb, clzTable, arg); // Get the high 4 bits of elements in arg. Operand hiArg = context.AddIntrinsic(Intrinsic.X86Psrlw, arg, Const(4)); - hiArg = context.AddIntrinsic(Intrinsic.X86Pand, hiArg, maskLow); + hiArg = context.AddIntrinsic(Intrinsic.X86Pand, hiArg, maskLow); // CLZ of high 4 bits of elements in arg. Operand hiClz = context.AddIntrinsic(Intrinsic.X86Pshufb, clzTable, hiArg); @@ -257,8 +257,8 @@ private static Operand Clz_V_I16(ArmEmitterContext context, Operand arg) } Operand maskSwap = X86GetElements(context, 0x80_0f_80_0d_80_0b_80_09, 0x80_07_80_05_80_03_80_01); - Operand maskLow = X86GetAllElements(context, 0x00ff_00ff); - Operand c0008 = X86GetAllElements(context, 0x0008_0008); + Operand maskLow = X86GetAllElements(context, 0x00ff_00ff); + Operand c0008 = X86GetAllElements(context, 0x0008_0008); // CLZ pair of high 8 and low 8 bits of elements in arg. Operand hiloClz = Clz_V_I8(context, arg); @@ -282,12 +282,14 @@ private static Operand Clz_V_I32(ArmEmitterContext context, Operand arg) return default; } +#pragma warning disable IDE0055 // Disable formatting Operand AddVectorI32(Operand op0, Operand op1) => context.AddIntrinsic(Intrinsic.X86Paddd, op0, op1); Operand SubVectorI32(Operand op0, Operand op1) => context.AddIntrinsic(Intrinsic.X86Psubd, op0, op1); Operand ShiftRightVectorUI32(Operand op0, int imm8) => context.AddIntrinsic(Intrinsic.X86Psrld, op0, Const(imm8)); Operand OrVector(Operand op0, Operand op1) => context.AddIntrinsic(Intrinsic.X86Por, op0, op1); Operand AndVector(Operand op0, Operand op1) => context.AddIntrinsic(Intrinsic.X86Pand, op0, op1); Operand NotVector(Operand op0) => context.AddIntrinsic(Intrinsic.X86Pandn, op0, context.VectorOne()); +#pragma warning restore IDE0055 Operand c55555555 = X86GetAllElements(context, 0x55555555); Operand c33333333 = X86GetAllElements(context, 0x33333333); @@ -311,24 +313,24 @@ private static Operand Clz_V_I32(ArmEmitterContext context, Operand arg) // Count leading 1s, which is the population count. tmp0 = ShiftRightVectorUI32(res, 1); tmp0 = AndVector(tmp0, c55555555); - res = SubVectorI32(res, tmp0); + res = SubVectorI32(res, tmp0); tmp0 = ShiftRightVectorUI32(res, 2); tmp0 = AndVector(tmp0, c33333333); tmp1 = AndVector(res, c33333333); - res = AddVectorI32(tmp0, tmp1); + res = AddVectorI32(tmp0, tmp1); tmp0 = ShiftRightVectorUI32(res, 4); tmp0 = AddVectorI32(tmp0, res); - res = AndVector(tmp0, c0f0f0f0f); + res = AndVector(tmp0, c0f0f0f0f); tmp0 = ShiftRightVectorUI32(res, 8); - res = AddVectorI32(tmp0, res); + res = AddVectorI32(tmp0, res); tmp0 = ShiftRightVectorUI32(res, 16); - res = AddVectorI32(tmp0, res); + res = AddVectorI32(tmp0, res); - res = AndVector(res, c0000003f); + res = AndVector(res, c0000003f); return res; } @@ -881,6 +883,31 @@ public static void Fmaxnmv_V(ArmEmitterContext context) } } + public static void Fmaxp_S(ArmEmitterContext context) + { + if (Optimizations.UseAdvSimd) + { + InstEmitSimdHelperArm64.EmitScalarUnaryOpF(context, Intrinsic.Arm64FmaxpS); + } + else if (Optimizations.FastFP && Optimizations.UseSse41) + { + EmitSse2ScalarPairwiseOpF(context, (op1, op2) => + { + return EmitSse41ProcessNaNsOpF(context, (op1, op2) => + { + return EmitSse2VectorMaxMinOpF(context, op1, op2, isMax: true); + }, scalar: true, op1, op2); + }); + } + else + { + EmitScalarPairwiseOpF(context, (op1, op2) => + { + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); + }); + } + } + public static void Fmaxp_V(ArmEmitterContext context) { if (Optimizations.UseAdvSimd) @@ -1079,6 +1106,31 @@ public static void Fminnmv_V(ArmEmitterContext context) } } + public static void Fminp_S(ArmEmitterContext context) + { + if (Optimizations.UseAdvSimd) + { + InstEmitSimdHelperArm64.EmitScalarUnaryOpF(context, Intrinsic.Arm64FminpS); + } + else if (Optimizations.FastFP && Optimizations.UseSse41) + { + EmitSse2ScalarPairwiseOpF(context, (op1, op2) => + { + return EmitSse41ProcessNaNsOpF(context, (op1, op2) => + { + return EmitSse2VectorMaxMinOpF(context, op1, op2, isMax: false); + }, scalar: true, op1, op2); + }); + } + else + { + EmitScalarPairwiseOpF(context, (op1, op2) => + { + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); + }); + } + } + public static void Fminp_V(ArmEmitterContext context) { if (Optimizations.UseAdvSimd) @@ -2436,8 +2488,8 @@ public static void Frsqrts_S(ArmEmitterContext context) // Fused. if (sizeF == 0) { - Operand maskHalf = X86GetScalar(context, 0.5f); - Operand maskThree = X86GetScalar(context, 3f); + Operand maskHalf = X86GetScalar(context, 0.5f); + Operand maskThree = X86GetScalar(context, 3f); Operand maskOneHalf = X86GetScalar(context, 1.5f); if (Optimizations.UseFma) @@ -2457,8 +2509,8 @@ public static void Frsqrts_S(ArmEmitterContext context) // Fused. } else /* if (sizeF == 1) */ { - Operand maskHalf = X86GetScalar(context, 0.5d); - Operand maskThree = X86GetScalar(context, 3d); + Operand maskHalf = X86GetScalar(context, 0.5d); + Operand maskThree = X86GetScalar(context, 3d); Operand maskOneHalf = X86GetScalar(context, 1.5d); if (Optimizations.UseFma) @@ -2505,8 +2557,8 @@ public static void Frsqrts_V(ArmEmitterContext context) // Fused. if (sizeF == 0) { - Operand maskHalf = X86GetAllElements(context, 0.5f); - Operand maskThree = X86GetAllElements(context, 3f); + Operand maskHalf = X86GetAllElements(context, 0.5f); + Operand maskThree = X86GetAllElements(context, 3f); Operand maskOneHalf = X86GetAllElements(context, 1.5f); if (Optimizations.UseFma) @@ -2519,7 +2571,7 @@ public static void Frsqrts_V(ArmEmitterContext context) // Fused. res = context.AddIntrinsic(Intrinsic.X86Subps, maskThree, res); } - res = context.AddIntrinsic(Intrinsic.X86Mulps, maskHalf, res); + res = context.AddIntrinsic(Intrinsic.X86Mulps, maskHalf, res); res = EmitSse41RecipStepSelectOpF(context, n, m, res, maskOneHalf, scalar: false, sizeF); if (op.RegisterSize == RegisterSize.Simd64) @@ -2531,8 +2583,8 @@ public static void Frsqrts_V(ArmEmitterContext context) // Fused. } else /* if (sizeF == 1) */ { - Operand maskHalf = X86GetAllElements(context, 0.5d); - Operand maskThree = X86GetAllElements(context, 3d); + Operand maskHalf = X86GetAllElements(context, 0.5d); + Operand maskThree = X86GetAllElements(context, 3d); Operand maskOneHalf = X86GetAllElements(context, 1.5d); if (Optimizations.UseFma) @@ -2545,7 +2597,7 @@ public static void Frsqrts_V(ArmEmitterContext context) // Fused. res = context.AddIntrinsic(Intrinsic.X86Subpd, maskThree, res); } - res = context.AddIntrinsic(Intrinsic.X86Mulpd, maskHalf, res); + res = context.AddIntrinsic(Intrinsic.X86Mulpd, maskHalf, res); res = EmitSse41RecipStepSelectOpF(context, n, m, res, maskOneHalf, scalar: false, sizeF); context.Copy(GetVec(op.Rd), res); @@ -2824,10 +2876,10 @@ public static void Pmull_V(ArmEmitterContext context) for (int i = 0; i < 8; i++) { Operand mask = context.AddIntrinsic(Intrinsic.X86Psllw, n, Const(15 - i)); - mask = context.AddIntrinsic(Intrinsic.X86Psraw, mask, Const(15)); + mask = context.AddIntrinsic(Intrinsic.X86Psraw, mask, Const(15)); Operand tmp = context.AddIntrinsic(Intrinsic.X86Psllw, m, Const(i)); - tmp = context.AddIntrinsic(Intrinsic.X86Pand, tmp, mask); + tmp = context.AddIntrinsic(Intrinsic.X86Pand, tmp, mask); res = context.AddIntrinsic(Intrinsic.X86Pxor, res, tmp); } @@ -2839,12 +2891,12 @@ public static void Pmull_V(ArmEmitterContext context) for (int i = 0; i < 64; i++) { Operand mask = context.AddIntrinsic(Intrinsic.X86Movlhps, n, n); - mask = context.AddIntrinsic(Intrinsic.X86Psllq, mask, Const(63 - i)); - mask = context.AddIntrinsic(Intrinsic.X86Psrlq, mask, Const(63)); - mask = context.AddIntrinsic(Intrinsic.X86Psubq, zero, mask); + mask = context.AddIntrinsic(Intrinsic.X86Psllq, mask, Const(63 - i)); + mask = context.AddIntrinsic(Intrinsic.X86Psrlq, mask, Const(63)); + mask = context.AddIntrinsic(Intrinsic.X86Psubq, zero, mask); Operand tmp = EmitSse2Sll_128(context, m, i); - tmp = context.AddIntrinsic(Intrinsic.X86Pand, tmp, mask); + tmp = context.AddIntrinsic(Intrinsic.X86Pand, tmp, mask); res = context.AddIntrinsic(Intrinsic.X86Pxor, res, tmp); } @@ -3119,7 +3171,7 @@ public static void Shadd_V(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.AddIntrinsic(Intrinsic.X86Pand, n, m); + Operand res = context.AddIntrinsic(Intrinsic.X86Pand, n, m); Operand res2 = context.AddIntrinsic(Intrinsic.X86Pxor, n, m); Intrinsic shiftInst = op.Size == 1 ? Intrinsic.X86Psraw : Intrinsic.X86Psrad; @@ -4058,7 +4110,7 @@ public static void Uhadd_V(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.AddIntrinsic(Intrinsic.X86Pand, n, m); + Operand res = context.AddIntrinsic(Intrinsic.X86Pand, n, m); Operand res2 = context.AddIntrinsic(Intrinsic.X86Pxor, n, m); Intrinsic shiftInst = op.Size == 1 ? Intrinsic.X86Psrlw : Intrinsic.X86Psrld; @@ -4594,7 +4646,7 @@ private static void EmitAddLongPairwise(ArmEmitterContext context, bool signed, { int pairIndex = index << 1; - Operand ne0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed); + Operand ne0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed); Operand ne1 = EmitVectorExtract(context, op.Rn, pairIndex + 1, op.Size, signed); Operand e = context.Add(ne0, ne1); @@ -4686,7 +4738,7 @@ private static Operand EmitMax64Op(ArmEmitterContext context, Operand op1, Opera Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64); Operand cmp = signed - ? context.ICompareGreaterOrEqual (op1, op2) + ? context.ICompareGreaterOrEqual(op1, op2) : context.ICompareGreaterOrEqualUI(op1, op2); return context.ConditionalSelect(cmp, op1, op2); @@ -4697,7 +4749,7 @@ private static Operand EmitMin64Op(ArmEmitterContext context, Operand op1, Opera Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64); Operand cmp = signed - ? context.ICompareLessOrEqual (op1, op2) + ? context.ICompareLessOrEqual(op1, op2) : context.ICompareLessOrEqualUI(op1, op2); return context.ConditionalSelect(cmp, op1, op2); @@ -4852,10 +4904,10 @@ public static void EmitSse2VectorIsNaNOpF( Operand mask1 = context.AddIntrinsic(Intrinsic.X86Cmpps, opF, opF, Const((int)CmpCondition.UnorderedQ)); - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Pand, opF, qMask); - mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, mask2, qMask, Const((int)CmpCondition.Equal)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Pand, opF, qMask); + mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, mask2, qMask, Const((int)CmpCondition.Equal)); - qNaNMask = isQNaN == null || (bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andps, mask2, mask1) : default; + qNaNMask = isQNaN == null || (bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andps, mask2, mask1) : default; sNaNMask = isQNaN == null || !(bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andnps, mask2, mask1) : default; } else /* if ((op.Size & 1) == 1) */ @@ -4866,10 +4918,10 @@ public static void EmitSse2VectorIsNaNOpF( Operand mask1 = context.AddIntrinsic(Intrinsic.X86Cmppd, opF, opF, Const((int)CmpCondition.UnorderedQ)); - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Pand, opF, qMask); - mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, mask2, qMask, Const((int)CmpCondition.Equal)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Pand, opF, qMask); + mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, mask2, qMask, Const((int)CmpCondition.Equal)); - qNaNMask = isQNaN == null || (bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andpd, mask2, mask1) : default; + qNaNMask = isQNaN == null || (bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andpd, mask2, mask1) : default; sNaNMask = isQNaN == null || !(bool)isQNaN ? context.AddIntrinsic(Intrinsic.X86Andnpd, mask2, mask1) : default; } } @@ -4895,11 +4947,11 @@ public static Operand EmitSse41ProcessNaNsOpF( Operand qMask = scalar ? X86GetScalar(context, 1 << QBit) : X86GetAllElements(context, 1 << QBit); - Operand resNaNMask = context.AddIntrinsic(Intrinsic.X86Pandn, mSNaNMask, nQNaNMask); - resNaNMask = context.AddIntrinsic(Intrinsic.X86Por, resNaNMask, nSNaNMask); + Operand resNaNMask = context.AddIntrinsic(Intrinsic.X86Pandn, mSNaNMask, nQNaNMask); + resNaNMask = context.AddIntrinsic(Intrinsic.X86Por, resNaNMask, nSNaNMask); Operand resNaN = context.AddIntrinsic(Intrinsic.X86Blendvps, mCopy, nCopy, resNaNMask); - resNaN = context.AddIntrinsic(Intrinsic.X86Por, resNaN, qMask); + resNaN = context.AddIntrinsic(Intrinsic.X86Por, resNaN, qMask); Operand resMask = context.AddIntrinsic(Intrinsic.X86Cmpps, nCopy, mCopy, Const((int)CmpCondition.OrderedQ)); @@ -4929,11 +4981,11 @@ public static Operand EmitSse41ProcessNaNsOpF( Operand qMask = scalar ? X86GetScalar(context, 1L << QBit) : X86GetAllElements(context, 1L << QBit); - Operand resNaNMask = context.AddIntrinsic(Intrinsic.X86Pandn, mSNaNMask, nQNaNMask); - resNaNMask = context.AddIntrinsic(Intrinsic.X86Por, resNaNMask, nSNaNMask); + Operand resNaNMask = context.AddIntrinsic(Intrinsic.X86Pandn, mSNaNMask, nQNaNMask); + resNaNMask = context.AddIntrinsic(Intrinsic.X86Por, resNaNMask, nSNaNMask); Operand resNaN = context.AddIntrinsic(Intrinsic.X86Blendvpd, mCopy, nCopy, resNaNMask); - resNaN = context.AddIntrinsic(Intrinsic.X86Por, resNaN, qMask); + resNaN = context.AddIntrinsic(Intrinsic.X86Por, resNaN, qMask); Operand resMask = context.AddIntrinsic(Intrinsic.X86Cmppd, nCopy, mCopy, Const((int)CmpCondition.OrderedQ)); @@ -4964,10 +5016,10 @@ private static Operand EmitSse2VectorMaxMinOpF(ArmEmitterContext context, Operan Operand mask = X86GetAllElements(context, -0f); Operand res = context.AddIntrinsic(isMax ? Intrinsic.X86Maxps : Intrinsic.X86Minps, n, m); - res = context.AddIntrinsic(Intrinsic.X86Andnps, mask, res); + res = context.AddIntrinsic(Intrinsic.X86Andnps, mask, res); Operand resSign = context.AddIntrinsic(isMax ? Intrinsic.X86Pand : Intrinsic.X86Por, n, m); - resSign = context.AddIntrinsic(Intrinsic.X86Andps, mask, resSign); + resSign = context.AddIntrinsic(Intrinsic.X86Andps, mask, resSign); return context.AddIntrinsic(Intrinsic.X86Por, res, resSign); } @@ -4976,10 +5028,10 @@ private static Operand EmitSse2VectorMaxMinOpF(ArmEmitterContext context, Operan Operand mask = X86GetAllElements(context, -0d); Operand res = context.AddIntrinsic(isMax ? Intrinsic.X86Maxpd : Intrinsic.X86Minpd, n, m); - res = context.AddIntrinsic(Intrinsic.X86Andnpd, mask, res); + res = context.AddIntrinsic(Intrinsic.X86Andnpd, mask, res); Operand resSign = context.AddIntrinsic(isMax ? Intrinsic.X86Pand : Intrinsic.X86Por, n, m); - resSign = context.AddIntrinsic(Intrinsic.X86Andpd, mask, resSign); + resSign = context.AddIntrinsic(Intrinsic.X86Andpd, mask, resSign); return context.AddIntrinsic(Intrinsic.X86Por, res, resSign); } @@ -5003,7 +5055,7 @@ private static Operand EmitSse41MaxMinNumOpF( if (sizeF == 0) { Operand negInfMask = scalar - ? X86GetScalar (context, isMaxNum ? float.NegativeInfinity : float.PositiveInfinity) + ? X86GetScalar(context, isMaxNum ? float.NegativeInfinity : float.PositiveInfinity) : X86GetAllElements(context, isMaxNum ? float.NegativeInfinity : float.PositiveInfinity); Operand nMask = context.AddIntrinsic(Intrinsic.X86Andnps, mQNaNMask, nQNaNMask); @@ -5038,7 +5090,7 @@ private static Operand EmitSse41MaxMinNumOpF( else /* if (sizeF == 1) */ { Operand negInfMask = scalar - ? X86GetScalar (context, isMaxNum ? double.NegativeInfinity : double.PositiveInfinity) + ? X86GetScalar(context, isMaxNum ? double.NegativeInfinity : double.PositiveInfinity) : X86GetAllElements(context, isMaxNum ? double.NegativeInfinity : double.PositiveInfinity); Operand nMask = context.AddIntrinsic(Intrinsic.X86Andnpd, mQNaNMask, nQNaNMask); @@ -5072,7 +5124,7 @@ private enum AddSub { None, Add, - Subtract + Subtract, } private static void EmitSse41VectorMul_AddSub(ArmEmitterContext context, AddSub addSub) @@ -5187,10 +5239,10 @@ private static void EmitSse41VectorUabdOp( Intrinsic subInst = X86PsubInstruction[size]; - Operand res = context.AddIntrinsic(subInst, n, m); + Operand res = context.AddIntrinsic(subInst, n, m); Operand res2 = context.AddIntrinsic(subInst, m, n); - res = context.AddIntrinsic(Intrinsic.X86Pand, cmpMask, res); + res = context.AddIntrinsic(Intrinsic.X86Pand, cmpMask, res); res2 = context.AddIntrinsic(Intrinsic.X86Pandn, cmpMask, res2); res = context.AddIntrinsic(Intrinsic.X86Por, res, res2); @@ -5214,7 +5266,7 @@ private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, in } Operand high = context.AddIntrinsic(Intrinsic.X86Pslldq, op, Const(8)); - high = context.AddIntrinsic(Intrinsic.X86Psrlq, high, Const(64 - shift)); + high = context.AddIntrinsic(Intrinsic.X86Psrlq, high, Const(64 - shift)); Operand low = context.AddIntrinsic(Intrinsic.X86Psllq, op, Const(shift)); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs b/src/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs index a9994e412..27608ebf8 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs @@ -1,8 +1,7 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; - using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -190,7 +189,7 @@ public static void Vdup(ArmEmitterContext context) 2 => context.Multiply(context.ZeroExtend32(OperandType.I64, insert), Const(0x0000000100000001u)), 1 => context.Multiply(context.ZeroExtend16(OperandType.I64, insert), Const(0x0001000100010001u)), 0 => context.Multiply(context.ZeroExtend8(OperandType.I64, insert), Const(0x0101010101010101u)), - _ => throw new InvalidOperationException($"Invalid Vdup size \"{op.Size}\".") + _ => throw new InvalidOperationException($"Invalid Vdup size \"{op.Size}\"."), }; InsertScalar(context, op.Vd, insert); @@ -212,7 +211,7 @@ public static void Vdup_1(ArmEmitterContext context) 2 => context.Multiply(context.ZeroExtend32(OperandType.I64, insert), Const(0x0000000100000001u)), 1 => context.Multiply(context.ZeroExtend16(OperandType.I64, insert), Const(0x0001000100010001u)), 0 => context.Multiply(context.ZeroExtend8(OperandType.I64, insert), Const(0x0101010101010101u)), - _ => throw new InvalidOperationException($"Invalid Vdup size \"{op.Size}\".") + _ => throw new InvalidOperationException($"Invalid Vdup size \"{op.Size}\"."), }; InsertScalar(context, op.Vd, insert); @@ -1654,7 +1653,7 @@ private static void EmitSse41MaxMinNumOpF32(ArmEmitterContext context, bool isMa { IOpCode32Simd op = (IOpCode32Simd)context.CurrOp; - Func genericEmit = (n, m) => + Operand genericEmit(Operand n, Operand m) { Operand nNum = context.Copy(n); Operand mNum = context.Copy(m); @@ -1688,7 +1687,7 @@ private static void EmitSse41MaxMinNumOpF32(ArmEmitterContext context, bool isMa return context.AddIntrinsic(isMaxNum ? Intrinsic.X86Maxpd : Intrinsic.X86Minpd, nNum, mNum); } - }; + } if (scalar) { diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCmp.cs b/src/ARMeilleure/Instructions/InstEmitSimdCmp.cs index c32b64ba1..aab677869 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCmp.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCmp.cs @@ -3,7 +3,6 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -493,7 +492,7 @@ private static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp; Operand lblTrue = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); context.BranchIfTrue(lblTrue, InstEmitFlowHelper.GetCondTrue(context, op.Cond)); @@ -510,7 +509,7 @@ private static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs private static void EmitSetNzcv(ArmEmitterContext context, int nzcv) { - Operand Extract(int value, int bit) + static Operand Extract(int value, int bit) { if (bit != 0) { @@ -532,7 +531,7 @@ private static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; - bool cmpWithZero = !(op is OpCodeSimdFcond) ? op.Bit3 : false; + bool cmpWithZero = op is not OpCodeSimdFcond && op.Bit3; if (Optimizations.FastFP && (signalNaNs ? Optimizations.UseAvx : Optimizations.UseSse2)) { diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index a990e057d..1d68bce6b 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs b/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs index db24e0290..6226e35ae 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs @@ -17,7 +17,11 @@ public static void Aesd_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } @@ -38,7 +42,11 @@ public static void Aese_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } @@ -58,7 +66,11 @@ public static void Aesimc_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesimc, n); } @@ -78,7 +90,11 @@ public static void Aesmc_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n); + } + else if (Optimizations.UseAesni) { Operand roundKey = context.VectorZero(); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs index f713a388c..7a0c981e7 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; @@ -17,7 +17,11 @@ public static void Aesd_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } @@ -38,7 +42,11 @@ public static void Aese_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } @@ -58,7 +66,11 @@ public static void Aesimc_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n); + } + else if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesimc, n); } @@ -78,7 +90,11 @@ public static void Aesmc_V(ArmEmitterContext context) Operand res; - if (Optimizations.UseAesni) + if (Optimizations.UseArm64Aes) + { + res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n); + } + else if (Optimizations.UseAesni) { Operand roundKey = context.VectorZero(); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt.cs index 652ad397c..3363a7c77 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -67,8 +66,8 @@ public static void Fcvt_S(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, n, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); - res = context.AddIntrinsic(Intrinsic.X86Pslldq, res, Const(14)); // VectorZeroUpper112() - res = context.AddIntrinsic(Intrinsic.X86Psrldq, res, Const(14)); + res = context.AddIntrinsic(Intrinsic.X86Pslldq, res, Const(14)); // VectorZeroUpper112() + res = context.AddIntrinsic(Intrinsic.X86Psrldq, res, Const(14)); context.Copy(GetVec(op.Rd), res); } @@ -92,7 +91,7 @@ public static void Fcvt_S(ArmEmitterContext context) Debug.Assert(!Optimizations.ForceLegacySse); Operand res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, GetVec(op.Rn)); - res = context.VectorZeroUpper96(res); + res = context.VectorZeroUpper96(res); context.Copy(GetVec(op.Rd), res); } @@ -116,7 +115,7 @@ public static void Fcvt_S(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), n); - res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); + res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); context.Copy(GetVec(op.Rd), res); } @@ -140,8 +139,8 @@ public static void Fcvt_S(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, GetVec(op.Rn)); - res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res); - res = context.VectorZeroUpper64(res); + res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res); + res = context.VectorZeroUpper64(res); context.Copy(GetVec(op.Rd), res); } @@ -273,7 +272,7 @@ public static void Fcvtl_V(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand res = op.RegisterSize == RegisterSize.Simd128 ? context.AddIntrinsic(Intrinsic.X86Movhlps, n, n) : n; - res = context.AddIntrinsic(Intrinsic.X86Cvtps2pd, res); + res = context.AddIntrinsic(Intrinsic.X86Cvtps2pd, res); context.Copy(GetVec(op.Rd), res); } @@ -284,7 +283,7 @@ public static void Fcvtl_V(ArmEmitterContext context) Operand n = GetVec(op.Rn); Operand res = op.RegisterSize == RegisterSize.Simd128 ? context.AddIntrinsic(Intrinsic.X86Movhlps, n, n) : n; - res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, res); + res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, res); context.Copy(GetVec(op.Rd), res); } @@ -387,10 +386,10 @@ public static void Fcvtn_V(ArmEmitterContext context) Intrinsic movInst = op.RegisterSize == RegisterSize.Simd128 ? Intrinsic.X86Movlhps : Intrinsic.X86Movhlps; Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtpd2ps, GetVec(op.Rn)); - nInt = context.AddIntrinsic(Intrinsic.X86Movlhps, nInt, nInt); + nInt = context.AddIntrinsic(Intrinsic.X86Movlhps, nInt, nInt); Operand res = context.VectorZeroUpper64(d); - res = context.AddIntrinsic(movInst, res, nInt); + res = context.AddIntrinsic(movInst, res, nInt); context.Copy(d, res); } @@ -404,10 +403,10 @@ public static void Fcvtn_V(ArmEmitterContext context) Intrinsic movInst = op.RegisterSize == RegisterSize.Simd128 ? Intrinsic.X86Movlhps : Intrinsic.X86Movhlps; Operand nInt = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, n, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); - nInt = context.AddIntrinsic(Intrinsic.X86Movlhps, nInt, nInt); + nInt = context.AddIntrinsic(Intrinsic.X86Movlhps, nInt, nInt); Operand res = context.VectorZeroUpper64(d); - res = context.AddIntrinsic(movInst, res, nInt); + res = context.AddIntrinsic(movInst, res, nInt); context.Copy(d, res); } @@ -1225,15 +1224,15 @@ public static Operand EmitSse2CvtDoubleToInt64OpF(ArmEmitterContext context, Ope { Debug.Assert(opF.Type == OperandType.V128); - Operand longL = context.AddIntrinsicLong (Intrinsic.X86Cvtsd2si, opF); // opFL - Operand res = context.VectorCreateScalar(longL); + Operand longL = context.AddIntrinsicLong(Intrinsic.X86Cvtsd2si, opF); // opFL + Operand res = context.VectorCreateScalar(longL); if (!scalar) { - Operand opFH = context.AddIntrinsic (Intrinsic.X86Movhlps, res, opF); // res doesn't matter. - Operand longH = context.AddIntrinsicLong (Intrinsic.X86Cvtsd2si, opFH); - Operand resH = context.VectorCreateScalar(longH); - res = context.AddIntrinsic (Intrinsic.X86Movlhps, res, resH); + Operand opFH = context.AddIntrinsic(Intrinsic.X86Movhlps, res, opF); // res doesn't matter. + Operand longH = context.AddIntrinsicLong(Intrinsic.X86Cvtsd2si, opFH); + Operand resH = context.VectorCreateScalar(longH); + res = context.AddIntrinsic(Intrinsic.X86Movlhps, res, resH); } return res; @@ -1244,14 +1243,14 @@ private static Operand EmitSse2CvtInt64ToDoubleOp(ArmEmitterContext context, Ope Debug.Assert(op.Type == OperandType.V128); Operand longL = context.AddIntrinsicLong(Intrinsic.X86Cvtsi2si, op); // opL - Operand res = context.AddIntrinsic (Intrinsic.X86Cvtsi2sd, context.VectorZero(), longL); + Operand res = context.AddIntrinsic(Intrinsic.X86Cvtsi2sd, context.VectorZero(), longL); if (!scalar) { - Operand opH = context.AddIntrinsic (Intrinsic.X86Movhlps, res, op); // res doesn't matter. + Operand opH = context.AddIntrinsic(Intrinsic.X86Movhlps, res, op); // res doesn't matter. Operand longH = context.AddIntrinsicLong(Intrinsic.X86Cvtsi2si, opH); - Operand resH = context.AddIntrinsic (Intrinsic.X86Cvtsi2sd, res, longH); // res doesn't matter. - res = context.AddIntrinsic (Intrinsic.X86Movlhps, res, resH); + Operand resH = context.AddIntrinsic(Intrinsic.X86Cvtsi2sd, res, longH); // res doesn't matter. + res = context.AddIntrinsic(Intrinsic.X86Movlhps, res, resH); } return res; @@ -1278,7 +1277,7 @@ private static void EmitSse2ScvtfOp(ArmEmitterContext context, bool scalar) int fpScaled = 0x3F800000 - fBits * 0x800000; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); res = context.AddIntrinsic(Intrinsic.X86Mulps, res, fpScaledMask); @@ -1307,7 +1306,7 @@ private static void EmitSse2ScvtfOp(ArmEmitterContext context, bool scalar) long fpScaled = 0x3FF0000000000000L - fBits * 0x10000000000000L; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); res = context.AddIntrinsic(Intrinsic.X86Mulpd, res, fpScaledMask); @@ -1334,16 +1333,16 @@ private static void EmitSse2UcvtfOp(ArmEmitterContext context, bool scalar) if (sizeF == 0) { Operand mask = scalar // 65536.000f (1 << 16) - ? X86GetScalar (context, 0x47800000) + ? X86GetScalar(context, 0x47800000) : X86GetAllElements(context, 0x47800000); Operand res = context.AddIntrinsic(Intrinsic.X86Psrld, n, Const(16)); - res = context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, res); - res = context.AddIntrinsic(Intrinsic.X86Mulps, res, mask); + res = context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, res); + res = context.AddIntrinsic(Intrinsic.X86Mulps, res, mask); Operand res2 = context.AddIntrinsic(Intrinsic.X86Pslld, n, Const(16)); - res2 = context.AddIntrinsic(Intrinsic.X86Psrld, res2, Const(16)); - res2 = context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, res2); + res2 = context.AddIntrinsic(Intrinsic.X86Psrld, res2, Const(16)); + res2 = context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, res2); res = context.AddIntrinsic(Intrinsic.X86Addps, res, res2); @@ -1355,7 +1354,7 @@ private static void EmitSse2UcvtfOp(ArmEmitterContext context, bool scalar) int fpScaled = 0x3F800000 - fBits * 0x800000; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); res = context.AddIntrinsic(Intrinsic.X86Mulps, res, fpScaledMask); @@ -1375,16 +1374,16 @@ private static void EmitSse2UcvtfOp(ArmEmitterContext context, bool scalar) else /* if (sizeF == 1) */ { Operand mask = scalar // 4294967296.0000000d (1L << 32) - ? X86GetScalar (context, 0x41F0000000000000L) + ? X86GetScalar(context, 0x41F0000000000000L) : X86GetAllElements(context, 0x41F0000000000000L); - Operand res = context.AddIntrinsic (Intrinsic.X86Psrlq, n, Const(32)); - res = EmitSse2CvtInt64ToDoubleOp(context, res, scalar); - res = context.AddIntrinsic (Intrinsic.X86Mulpd, res, mask); + Operand res = context.AddIntrinsic(Intrinsic.X86Psrlq, n, Const(32)); + res = EmitSse2CvtInt64ToDoubleOp(context, res, scalar); + res = context.AddIntrinsic(Intrinsic.X86Mulpd, res, mask); - Operand res2 = context.AddIntrinsic (Intrinsic.X86Psllq, n, Const(32)); - res2 = context.AddIntrinsic (Intrinsic.X86Psrlq, res2, Const(32)); - res2 = EmitSse2CvtInt64ToDoubleOp(context, res2, scalar); + Operand res2 = context.AddIntrinsic(Intrinsic.X86Psllq, n, Const(32)); + res2 = context.AddIntrinsic(Intrinsic.X86Psrlq, res2, Const(32)); + res2 = EmitSse2CvtInt64ToDoubleOp(context, res2, scalar); res = context.AddIntrinsic(Intrinsic.X86Addpd, res, res2); @@ -1396,7 +1395,7 @@ private static void EmitSse2UcvtfOp(ArmEmitterContext context, bool scalar) long fpScaled = 0x3FF0000000000000L - fBits * 0x10000000000000L; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); res = context.AddIntrinsic(Intrinsic.X86Mulpd, res, fpScaledMask); @@ -1423,7 +1422,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode if (sizeF == 0) { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (op is OpCodeSimdShImm fixedOp) { @@ -1433,7 +1432,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode int fpScaled = 0x3F800000 + fBits * 0x800000; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask); @@ -1451,7 +1450,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes); Operand fpMaxValMask = scalar // 2.14748365E9f (2147483648) - ? X86GetScalar (context, 0x4F000000) + ? X86GetScalar(context, 0x4F000000) : X86GetAllElements(context, 0x4F000000); nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); @@ -1472,7 +1471,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode else /* if (sizeF == 1) */ { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (op is OpCodeSimdShImm fixedOp) { @@ -1482,7 +1481,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode long fpScaled = 0x3FF0000000000000L + fBits * 0x10000000000000L; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask); @@ -1500,7 +1499,7 @@ private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode Operand nLong = EmitSse2CvtDoubleToInt64OpF(context, nRes, scalar); Operand fpMaxValMask = scalar // 9.2233720368547760E18d (9223372036854775808) - ? X86GetScalar (context, 0x43E0000000000000L) + ? X86GetScalar(context, 0x43E0000000000000L) : X86GetAllElements(context, 0x43E0000000000000L); nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); @@ -1528,7 +1527,7 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode if (sizeF == 0) { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (op is OpCodeSimdShImm fixedOp) { @@ -1538,7 +1537,7 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode int fpScaled = 0x3F800000 + fBits * 0x800000; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask); @@ -1556,10 +1555,10 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode Operand zero = context.VectorZero(); Operand nCmp = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand fpMaxValMask = scalar // 2.14748365E9f (2147483648) - ? X86GetScalar (context, 0x4F000000) + ? X86GetScalar(context, 0x4F000000) : X86GetAllElements(context, 0x4F000000); Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes); @@ -1567,14 +1566,14 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode nRes = context.AddIntrinsic(Intrinsic.X86Subps, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand nInt2 = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes); nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); - Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nInt2, nRes); - dRes = context.AddIntrinsic(Intrinsic.X86Paddd, dRes, nInt); + Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nInt2, nRes); + dRes = context.AddIntrinsic(Intrinsic.X86Paddd, dRes, nInt); if (scalar) { @@ -1590,7 +1589,7 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode else /* if (sizeF == 1) */ { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (op is OpCodeSimdShImm fixedOp) { @@ -1600,7 +1599,7 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode long fpScaled = 0x3FF0000000000000L + fBits * 0x10000000000000L; Operand fpScaledMask = scalar - ? X86GetScalar (context, fpScaled) + ? X86GetScalar(context, fpScaled) : X86GetAllElements(context, fpScaled); nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask); @@ -1618,10 +1617,10 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode Operand zero = context.VectorZero(); Operand nCmp = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand fpMaxValMask = scalar // 9.2233720368547760E18d (9223372036854775808) - ? X86GetScalar (context, 0x43E0000000000000L) + ? X86GetScalar(context, 0x43E0000000000000L) : X86GetAllElements(context, 0x43E0000000000000L); Operand nLong = EmitSse2CvtDoubleToInt64OpF(context, nRes, scalar); @@ -1629,14 +1628,14 @@ private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode nRes = context.AddIntrinsic(Intrinsic.X86Subpd, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand nLong2 = EmitSse2CvtDoubleToInt64OpF(context, nRes, scalar); nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); - Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nLong2, nRes); - dRes = context.AddIntrinsic(Intrinsic.X86Paddq, dRes, nLong); + Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nLong2, nRes); + dRes = context.AddIntrinsic(Intrinsic.X86Paddq, dRes, nLong); if (scalar) { @@ -1656,7 +1655,7 @@ private static void EmitSse41Fcvts_Gp(ArmEmitterContext context, FPRoundingMode if (op.Size == 0) { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (isFixed) { @@ -1678,7 +1677,7 @@ private static void EmitSse41Fcvts_Gp(ArmEmitterContext context, FPRoundingMode } Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtss2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtss2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtss2si, nRes); int fpMaxVal = op.RegisterSize == RegisterSize.Int32 @@ -1703,7 +1702,7 @@ private static void EmitSse41Fcvts_Gp(ArmEmitterContext context, FPRoundingMode else /* if (op.Size == 1) */ { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (isFixed) { @@ -1725,7 +1724,7 @@ private static void EmitSse41Fcvts_Gp(ArmEmitterContext context, FPRoundingMode } Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtsd2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtsd2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtsd2si, nRes); long fpMaxVal = op.RegisterSize == RegisterSize.Int32 @@ -1758,7 +1757,7 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode if (op.Size == 0) { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (isFixed) { @@ -1782,7 +1781,7 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode Operand zero = context.VectorZero(); Operand nCmp = context.AddIntrinsic(Intrinsic.X86Cmpss, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); int fpMaxVal = op.RegisterSize == RegisterSize.Int32 ? 0x4F000000 // 2.14748365E9f (2147483648) @@ -1791,16 +1790,16 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode Operand fpMaxValMask = X86GetScalar(context, fpMaxVal); Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtss2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtss2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtss2si, nRes); nRes = context.AddIntrinsic(Intrinsic.X86Subss, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmpss, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand nIntOrLong2 = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtss2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtss2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtss2si, nRes); nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); @@ -1813,14 +1812,14 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode } Operand dRes = context.BitwiseExclusiveOr(nIntOrLong2, nInt); - dRes = context.Add(dRes, nIntOrLong); + dRes = context.Add(dRes, nIntOrLong); SetIntOrZR(context, op.Rd, dRes); } else /* if (op.Size == 1) */ { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, n, Const((int)CmpCondition.OrderedQ)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); if (isFixed) { @@ -1844,7 +1843,7 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode Operand zero = context.VectorZero(); Operand nCmp = context.AddIntrinsic(Intrinsic.X86Cmpsd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); long fpMaxVal = op.RegisterSize == RegisterSize.Int32 ? 0x41E0000000000000L // 2147483648.0000000d (2147483648) @@ -1853,16 +1852,16 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode Operand fpMaxValMask = X86GetScalar(context, fpMaxVal); Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtsd2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtsd2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtsd2si, nRes); nRes = context.AddIntrinsic(Intrinsic.X86Subsd, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmpsd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); - nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); + nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); Operand nIntOrLong2 = op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (Intrinsic.X86Cvtsd2si, nRes) + ? context.AddIntrinsicInt(Intrinsic.X86Cvtsd2si, nRes) : context.AddIntrinsicLong(Intrinsic.X86Cvtsd2si, nRes); nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); @@ -1875,7 +1874,7 @@ private static void EmitSse41Fcvtu_Gp(ArmEmitterContext context, FPRoundingMode } Operand dRes = context.BitwiseExclusiveOr(nIntOrLong2, nLong); - dRes = context.Add(dRes, nIntOrLong); + dRes = context.Add(dRes, nIntOrLong); SetIntOrZR(context, op.Rd, dRes); } diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index 33ae83df6..630e114c4 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -1,11 +1,10 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper32; @@ -115,6 +114,35 @@ public static void Vcvt_V(ArmEmitterContext context) } } + public static void Vcvt_V_Fixed(ArmEmitterContext context) + { + OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp; + + var toFixed = op.Opc == 1; + int fracBits = op.Fbits; + var unsigned = op.U; + + if (toFixed) // F32 to S32 or U32 (fixed) + { + EmitVectorUnaryOpF32(context, (op1) => + { + var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits))); + MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)); + + return context.Call(info, scaledValue); + }); + } + else // S32 or U32 (fixed) to F32 + { + EmitVectorUnaryOpI32(context, (op1) => + { + var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1); + + return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits))); + }, !unsigned); + } + } + public static void Vcvt_FD(ArmEmitterContext context) { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; @@ -165,7 +193,7 @@ public static void Vcvt_FI(ArmEmitterContext context) { Operand m = GetVecA32(op.Vm >> 1); - Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize); + Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true); Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble; @@ -175,7 +203,7 @@ public static void Vcvt_FI(ArmEmitterContext context) } else { - InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS); + InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false); } } else if (!roundWithFpscr && Optimizations.UseSse41) @@ -217,33 +245,22 @@ private static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRoun string name = nameof(Math.Round); MethodInfo info = (op.Size & 1) == 0 - ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) - : typeof(Math). GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); + ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) + : typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); return context.Call(info, n, Const((int)roundMode)); } private static FPRoundingMode RMToRoundMode(int rm) { - FPRoundingMode roundMode; - switch (rm) - { - case 0b00: - roundMode = FPRoundingMode.ToNearestAway; - break; - case 0b01: - roundMode = FPRoundingMode.ToNearest; - break; - case 0b10: - roundMode = FPRoundingMode.TowardsPlusInfinity; - break; - case 0b11: - roundMode = FPRoundingMode.TowardsMinusInfinity; - break; - default: - throw new ArgumentOutOfRangeException(nameof(rm)); - } - return roundMode; + return rm switch + { + 0b00 => FPRoundingMode.ToNearestAway, + 0b01 => FPRoundingMode.ToNearest, + 0b10 => FPRoundingMode.TowardsPlusInfinity, + 0b11 => FPRoundingMode.TowardsMinusInfinity, + _ => throw new ArgumentOutOfRangeException(nameof(rm)), + }; } // VCVTA/M/N/P (floating-point). @@ -260,28 +277,68 @@ public static void Vcvt_RM(ArmEmitterContext context) if (Optimizations.UseAdvSimd) { - if (unsigned) + bool doubleSize = floatSize == OperandType.FP64; + + if (doubleSize) { - inst = rm switch { - 0b00 => Intrinsic.Arm64FcvtauS, - 0b01 => Intrinsic.Arm64FcvtnuS, - 0b10 => Intrinsic.Arm64FcvtpuS, - 0b11 => Intrinsic.Arm64FcvtmuS, - _ => throw new ArgumentOutOfRangeException(nameof(rm)) - }; + Operand m = GetVecA32(op.Vm >> 1); + + Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true); + + if (unsigned) + { + inst = rm switch + { + 0b00 => Intrinsic.Arm64FcvtauGp, + 0b01 => Intrinsic.Arm64FcvtnuGp, + 0b10 => Intrinsic.Arm64FcvtpuGp, + 0b11 => Intrinsic.Arm64FcvtmuGp, + _ => throw new InvalidOperationException($"{nameof(rm)} contains an invalid value: {rm}"), + }; + } + else + { + inst = rm switch + { + 0b00 => Intrinsic.Arm64FcvtasGp, + 0b01 => Intrinsic.Arm64FcvtnsGp, + 0b10 => Intrinsic.Arm64FcvtpsGp, + 0b11 => Intrinsic.Arm64FcvtmsGp, + _ => throw new InvalidOperationException($"{nameof(rm)} contains an invalid value: {rm}"), + }; + } + + Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert); + + InsertScalar(context, op.Vd, asInteger); } else { - inst = rm switch { - 0b00 => Intrinsic.Arm64FcvtasS, - 0b01 => Intrinsic.Arm64FcvtnsS, - 0b10 => Intrinsic.Arm64FcvtpsS, - 0b11 => Intrinsic.Arm64FcvtmsS, - _ => throw new ArgumentOutOfRangeException(nameof(rm)) - }; - } + if (unsigned) + { + inst = rm switch + { + 0b00 => Intrinsic.Arm64FcvtauS, + 0b01 => Intrinsic.Arm64FcvtnuS, + 0b10 => Intrinsic.Arm64FcvtpuS, + 0b11 => Intrinsic.Arm64FcvtmuS, + _ => throw new InvalidOperationException($"{nameof(rm)} contains an invalid value: {rm}"), + }; + } + else + { + inst = rm switch + { + 0b00 => Intrinsic.Arm64FcvtasS, + 0b01 => Intrinsic.Arm64FcvtnsS, + 0b10 => Intrinsic.Arm64FcvtpsS, + 0b11 => Intrinsic.Arm64FcvtmsS, + _ => throw new InvalidOperationException($"{nameof(rm)} contains an invalid value: {rm}"), + }; + } - InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); + InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); + } } else if (Optimizations.UseSse41) { @@ -396,12 +453,13 @@ public static void Vrint_RM(ArmEmitterContext context) if (Optimizations.UseAdvSimd) { - Intrinsic inst = rm switch { + Intrinsic inst = rm switch + { 0b00 => Intrinsic.Arm64FrintaS, 0b01 => Intrinsic.Arm64FrintnS, 0b10 => Intrinsic.Arm64FrintpS, 0b11 => Intrinsic.Arm64FrintmS, - _ => throw new ArgumentOutOfRangeException(nameof(rm)) + _ => throw new InvalidOperationException($"{nameof(rm)} contains an invalid value: {rm}"), }; InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHash.cs b/src/ARMeilleure/Instructions/InstEmitSimdHash.cs index 4fb048eed..aee12d7dc 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHash.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHash.cs @@ -8,7 +8,7 @@ namespace ARMeilleure.Instructions { static partial class InstEmit { -#region "Sha1" + #region "Sha1" public static void Sha1c_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -89,9 +89,9 @@ public static void Sha1su1_V(ArmEmitterContext context) context.Copy(GetVec(op.Rd), res); } -#endregion + #endregion -#region "Sha256" + #region "Sha256" public static void Sha256h_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -142,6 +142,6 @@ public static void Sha256su1_V(ArmEmitterContext context) context.Copy(GetVec(op.Rd), res); } -#endregion + #endregion } } diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHash32.cs b/src/ARMeilleure/Instructions/InstEmitSimdHash32.cs index 51334608d..c2bb951ab 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHash32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHash32.cs @@ -8,7 +8,7 @@ namespace ARMeilleure.Instructions { static partial class InstEmit32 { -#region "Sha256" + #region "Sha256" public static void Sha256h_V(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; @@ -59,6 +59,6 @@ public static void Sha256su1_V(ArmEmitterContext context) context.Copy(GetVecA32(op.Qd), res); } -#endregion + #endregion } } diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHashHelper.cs b/src/ARMeilleure/Instructions/InstEmitSimdHashHelper.cs index 23e4948d9..a672b159f 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHashHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHashHelper.cs @@ -18,9 +18,9 @@ public static Operand EmitSha256h(ArmEmitterContext context, Operand x, Operand Operand round2 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src1, src2, w); Operand round4 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src2, round2, w2); - + Operand res = context.AddIntrinsic(Intrinsic.X86Shufps, round4, round2, Const(part2 ? 0x11 : 0xbb)); - + return res; } @@ -53,4 +53,4 @@ public static Operand EmitSha256su1(ArmEmitterContext context, Operand x, Operan return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), x, y, z); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs index c44c9b4d9..abd0d9acc 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs @@ -6,7 +6,6 @@ using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -18,39 +17,39 @@ namespace ARMeilleure.Instructions static class InstEmitSimdHelper { -#region "Masks" + #region "Masks" public static readonly long[] EvenMasks = new long[] { 14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0, // B 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, // H - 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0 // S + 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0, // S }; public static readonly long[] OddMasks = new long[] { 15L << 56 | 13L << 48 | 11L << 40 | 09L << 32 | 07L << 24 | 05L << 16 | 03L << 8 | 01L << 0, // B 15L << 56 | 14L << 48 | 11L << 40 | 10L << 32 | 07L << 24 | 06L << 16 | 03L << 8 | 02L << 0, // H - 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0 // S + 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0, // S }; - public static readonly long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0; + public const long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0; public static ulong X86GetGf2p8LogicalShiftLeft(int shift) { ulong identity = (0b00000001UL << 56) | (0b00000010UL << 48) | (0b00000100UL << 40) | (0b00001000UL << 32) | - (0b00010000UL << 24) | (0b00100000UL << 16) | (0b01000000UL << 8) | (0b10000000UL << 0); + (0b00010000UL << 24) | (0b00100000UL << 16) | (0b01000000UL << 8) | (0b10000000UL << 0); return shift >= 0 ? identity >> (shift * 8) : identity << (-shift * 8); } -#endregion + #endregion -#region "X86 SSE Intrinsics" + #region "X86 SSE Intrinsics" public static readonly Intrinsic[] X86PaddInstruction = new Intrinsic[] { Intrinsic.X86Paddb, Intrinsic.X86Paddw, Intrinsic.X86Paddd, - Intrinsic.X86Paddq + Intrinsic.X86Paddq, }; public static readonly Intrinsic[] X86PcmpeqInstruction = new Intrinsic[] @@ -58,7 +57,7 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) Intrinsic.X86Pcmpeqb, Intrinsic.X86Pcmpeqw, Intrinsic.X86Pcmpeqd, - Intrinsic.X86Pcmpeqq + Intrinsic.X86Pcmpeqq, }; public static readonly Intrinsic[] X86PcmpgtInstruction = new Intrinsic[] @@ -66,49 +65,49 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) Intrinsic.X86Pcmpgtb, Intrinsic.X86Pcmpgtw, Intrinsic.X86Pcmpgtd, - Intrinsic.X86Pcmpgtq + Intrinsic.X86Pcmpgtq, }; public static readonly Intrinsic[] X86PmaxsInstruction = new Intrinsic[] { Intrinsic.X86Pmaxsb, Intrinsic.X86Pmaxsw, - Intrinsic.X86Pmaxsd + Intrinsic.X86Pmaxsd, }; public static readonly Intrinsic[] X86PmaxuInstruction = new Intrinsic[] { Intrinsic.X86Pmaxub, Intrinsic.X86Pmaxuw, - Intrinsic.X86Pmaxud + Intrinsic.X86Pmaxud, }; public static readonly Intrinsic[] X86PminsInstruction = new Intrinsic[] { Intrinsic.X86Pminsb, Intrinsic.X86Pminsw, - Intrinsic.X86Pminsd + Intrinsic.X86Pminsd, }; public static readonly Intrinsic[] X86PminuInstruction = new Intrinsic[] { Intrinsic.X86Pminub, Intrinsic.X86Pminuw, - Intrinsic.X86Pminud + Intrinsic.X86Pminud, }; public static readonly Intrinsic[] X86PmovsxInstruction = new Intrinsic[] { Intrinsic.X86Pmovsxbw, Intrinsic.X86Pmovsxwd, - Intrinsic.X86Pmovsxdq + Intrinsic.X86Pmovsxdq, }; public static readonly Intrinsic[] X86PmovzxInstruction = new Intrinsic[] { Intrinsic.X86Pmovzxbw, Intrinsic.X86Pmovzxwd, - Intrinsic.X86Pmovzxdq + Intrinsic.X86Pmovzxdq, }; public static readonly Intrinsic[] X86PsllInstruction = new Intrinsic[] @@ -116,14 +115,14 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) 0, Intrinsic.X86Psllw, Intrinsic.X86Pslld, - Intrinsic.X86Psllq + Intrinsic.X86Psllq, }; public static readonly Intrinsic[] X86PsraInstruction = new Intrinsic[] { 0, Intrinsic.X86Psraw, - Intrinsic.X86Psrad + Intrinsic.X86Psrad, }; public static readonly Intrinsic[] X86PsrlInstruction = new Intrinsic[] @@ -131,7 +130,7 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) 0, Intrinsic.X86Psrlw, Intrinsic.X86Psrld, - Intrinsic.X86Psrlq + Intrinsic.X86Psrlq, }; public static readonly Intrinsic[] X86PsubInstruction = new Intrinsic[] @@ -139,7 +138,7 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) Intrinsic.X86Psubb, Intrinsic.X86Psubw, Intrinsic.X86Psubd, - Intrinsic.X86Psubq + Intrinsic.X86Psubq, }; public static readonly Intrinsic[] X86PunpckhInstruction = new Intrinsic[] @@ -147,7 +146,7 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) Intrinsic.X86Punpckhbw, Intrinsic.X86Punpckhwd, Intrinsic.X86Punpckhdq, - Intrinsic.X86Punpckhqdq + Intrinsic.X86Punpckhqdq, }; public static readonly Intrinsic[] X86PunpcklInstruction = new Intrinsic[] @@ -155,9 +154,9 @@ public static ulong X86GetGf2p8LogicalShiftLeft(int shift) Intrinsic.X86Punpcklbw, Intrinsic.X86Punpcklwd, Intrinsic.X86Punpckldq, - Intrinsic.X86Punpcklqdq + Intrinsic.X86Punpcklqdq, }; -#endregion + #endregion public static void EnterArmFpMode(EmitterContext context, Func getFpFlag) { @@ -310,15 +309,16 @@ public static Operand X86GetElements(ArmEmitterContext context, ulong e1, ulong public static int X86GetRoundControl(FPRoundingMode roundMode) { - switch (roundMode) + return roundMode switch { - case FPRoundingMode.ToNearest: return 8 | 0; // even - case FPRoundingMode.TowardsPlusInfinity: return 8 | 2; - case FPRoundingMode.TowardsMinusInfinity: return 8 | 1; - case FPRoundingMode.TowardsZero: return 8 | 3; - } - - throw new ArgumentException($"Invalid rounding mode \"{roundMode}\"."); +#pragma warning disable IDE0055 // Disable formatting + FPRoundingMode.ToNearest => 8 | 0, // even + FPRoundingMode.TowardsPlusInfinity => 8 | 2, + FPRoundingMode.TowardsMinusInfinity => 8 | 1, + FPRoundingMode.TowardsZero => 8 | 3, + _ => throw new ArgumentException($"Invalid rounding mode \"{roundMode}\"."), +#pragma warning restore IDE0055 + }; } public static Operand EmitSse41RoundToNearestWithTiesToAwayOpF(ArmEmitterContext context, Operand n, bool scalar) @@ -334,11 +334,11 @@ public static Operand EmitSse41RoundToNearestWithTiesToAwayOpF(ArmEmitterContext if ((op.Size & 1) == 0) { Operand signMask = scalar ? X86GetScalar(context, int.MinValue) : X86GetAllElements(context, int.MinValue); - signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy); + signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy); // 0x3EFFFFFF == BitConverter.SingleToInt32Bits(0.5f) - 1 Operand valueMask = scalar ? X86GetScalar(context, 0x3EFFFFFF) : X86GetAllElements(context, 0x3EFFFFFF); - valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask); + valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask); nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addss : Intrinsic.X86Addps, nCopy, valueMask); @@ -347,11 +347,11 @@ public static Operand EmitSse41RoundToNearestWithTiesToAwayOpF(ArmEmitterContext else { Operand signMask = scalar ? X86GetScalar(context, long.MinValue) : X86GetAllElements(context, long.MinValue); - signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy); + signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy); // 0x3FDFFFFFFFFFFFFFL == BitConverter.DoubleToInt64Bits(0.5d) - 1L Operand valueMask = scalar ? X86GetScalar(context, 0x3FDFFFFFFFFFFFFFL) : X86GetAllElements(context, 0x3FDFFFFFFFFFFFFFL); - valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask); + valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask); nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addsd : Intrinsic.X86Addpd, nCopy, valueMask); @@ -461,7 +461,7 @@ public static Operand EmitUnaryMathCall(ArmEmitterContext context, string name, MethodInfo info = (op.Size & 1) == 0 ? typeof(MathF).GetMethod(name, new Type[] { typeof(float) }) - : typeof(Math). GetMethod(name, new Type[] { typeof(double) }); + : typeof(Math).GetMethod(name, new Type[] { typeof(double) }); return context.Call(info, n); } @@ -473,8 +473,8 @@ public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRound string name = nameof(Math.Round); MethodInfo info = (op.Size & 1) == 0 - ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) - : typeof(Math). GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); + ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) + : typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); return context.Call(info, n, Const((int)roundMode)); } @@ -482,7 +482,7 @@ public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRound public static Operand EmitGetRoundingMode(ArmEmitterContext context) { Operand rMode = context.ShiftLeft(GetFpFlag(FPState.RMode1Flag), Const(1)); - rMode = context.BitwiseOr(rMode, GetFpFlag(FPState.RMode0Flag)); + rMode = context.BitwiseOr(rMode, GetFpFlag(FPState.RMode0Flag)); return rMode; } @@ -1015,8 +1015,8 @@ private static void EmitVectorWidenRmBinaryOp(ArmEmitterContext context, Func2I for (int index = 0; index < elems; index++) { - Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signed); - Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed); + Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signed); + Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed); res = EmitVectorInsert(context, res, emit(ne, me), index, op.Size + 1); } @@ -1077,9 +1077,9 @@ private static void EmitVectorWidenRnRmTernaryOp(ArmEmitterContext context, Func for (int index = 0; index < elems; index++) { - Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed); - Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed); - Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed); + Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed); + Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed); + Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed); res = EmitVectorInsert(context, res, emit(de, ne, me), index, op.Size + 1); } @@ -1143,8 +1143,8 @@ private static void EmitVectorWidenTernaryOpByElem(ArmEmitterContext context, Fu for (int index = 0; index < elems; index++) { - Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed); - Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed); + Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed); + Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed); res = EmitVectorInsert(context, res, emit(de, ne, me), index, op.Size + 1); } @@ -1174,13 +1174,13 @@ private static void EmitVectorPairwiseOp(ArmEmitterContext context, Func2I emit, { int pairIndex = index << 1; - Operand n0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed); + Operand n0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed); Operand n1 = EmitVectorExtract(context, op.Rn, pairIndex + 1, op.Size, signed); - Operand m0 = EmitVectorExtract(context, op.Rm, pairIndex, op.Size, signed); + Operand m0 = EmitVectorExtract(context, op.Rm, pairIndex, op.Size, signed); Operand m1 = EmitVectorExtract(context, op.Rm, pairIndex + 1, op.Size, signed); - res = EmitVectorInsert(context, res, emit(n0, n1), index, op.Size); + res = EmitVectorInsert(context, res, emit(n0, n1), index, op.Size); res = EmitVectorInsert(context, res, emit(m0, m1), pairs + index, op.Size); } @@ -1197,11 +1197,11 @@ public static void EmitSsse3VectorPairwiseOp(ArmEmitterContext context, Intrinsi if (op.RegisterSize == RegisterSize.Simd64) { Operand zeroEvenMask = X86GetElements(context, ZeroMask, EvenMasks[op.Size]); - Operand zeroOddMask = X86GetElements(context, ZeroMask, OddMasks [op.Size]); + Operand zeroOddMask = X86GetElements(context, ZeroMask, OddMasks[op.Size]); Operand mN = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m); // m:n - Operand left = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroEvenMask); // 0:even from m:n + Operand left = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroEvenMask); // 0:even from m:n Operand right = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroOddMask); // 0:odd from m:n context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[op.Size], left, right)); @@ -1213,14 +1213,14 @@ public static void EmitSsse3VectorPairwiseOp(ArmEmitterContext context, Intrinsi Operand oddEvenN = context.AddIntrinsic(Intrinsic.X86Pshufb, n, oddEvenMask); // odd:even from n Operand oddEvenM = context.AddIntrinsic(Intrinsic.X86Pshufb, m, oddEvenMask); // odd:even from m - Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, oddEvenN, oddEvenM); + Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, oddEvenN, oddEvenM); Operand right = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, oddEvenN, oddEvenM); context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[op.Size], left, right)); } else { - Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m); + Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m); Operand right = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, n, m); context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[3], left, right)); @@ -1299,17 +1299,17 @@ public static void EmitSse2VectorAcrossVectorOpF(ArmEmitterContext context, Func Debug.Assert((op.Size & 1) == 0 && op.RegisterSize == RegisterSize.Simd128); - const int sm0 = 0 << 6 | 0 << 4 | 0 << 2 | 0 << 0; - const int sm1 = 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0; - const int sm2 = 2 << 6 | 2 << 4 | 2 << 2 | 2 << 0; - const int sm3 = 3 << 6 | 3 << 4 | 3 << 2 | 3 << 0; + const int SM0 = 0 << 6 | 0 << 4 | 0 << 2 | 0 << 0; + const int SM1 = 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0; + const int SM2 = 2 << 6 | 2 << 4 | 2 << 2 | 2 << 0; + const int SM3 = 3 << 6 | 3 << 4 | 3 << 2 | 3 << 0; Operand nCopy = context.Copy(GetVec(op.Rn)); - Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm0)); - Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm1)); - Operand part2 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm2)); - Operand part3 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm3)); + Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM0)); + Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM1)); + Operand part2 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM2)); + Operand part3 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM3)); Operand res = emit(emit(part0, part1), emit(part2, part3)); @@ -1340,13 +1340,13 @@ public static void EmitSse2ScalarPairwiseOpF(ArmEmitterContext context, Func2I e if ((op.Size & 1) == 0) { - const int sm0 = 2 << 6 | 2 << 4 | 2 << 2 | 0 << 0; - const int sm1 = 2 << 6 | 2 << 4 | 2 << 2 | 1 << 0; + const int SM0 = 2 << 6 | 2 << 4 | 2 << 2 | 0 << 0; + const int SM1 = 2 << 6 | 2 << 4 | 2 << 2 | 1 << 0; Operand zeroN = context.VectorZeroUpper64(n); - op0 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(sm0)); - op1 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(sm1)); + op0 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(SM0)); + op1 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(SM1)); } else /* if ((op.Size & 1) == 1) */ { @@ -1381,7 +1381,7 @@ public static void EmitVectorPairwiseOpF(ArmEmitterContext context, Func2I emit) Operand m0 = context.VectorExtract(type, GetVec(op.Rm), pairIndex); Operand m1 = context.VectorExtract(type, GetVec(op.Rm), pairIndex + 1); - res = context.VectorInsert(res, emit(n0, n1), index); + res = context.VectorInsert(res, emit(n0, n1), index); res = context.VectorInsert(res, emit(m0, m1), pairs + index); } @@ -1412,11 +1412,11 @@ public static void EmitSse2VectorPairwiseOpF(ArmEmitterContext context, Func2I e } else /* if (op.RegisterSize == RegisterSize.Simd128) */ { - const int sm0 = 2 << 6 | 0 << 4 | 2 << 2 | 0 << 0; - const int sm1 = 3 << 6 | 1 << 4 | 3 << 2 | 1 << 0; + const int SM0 = 2 << 6 | 0 << 4 | 2 << 2 | 0 << 0; + const int SM1 = 3 << 6 | 1 << 4 | 3 << 2 | 1 << 0; - Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(sm0)); - Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(sm1)); + Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(SM0)); + Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(SM1)); context.Copy(GetVec(op.Rd), emit(part0, part1)); } @@ -1433,18 +1433,18 @@ public static void EmitSse2VectorPairwiseOpF(ArmEmitterContext context, Func2I e public enum CmpCondition { // Legacy Sse. - Equal = 0, // Ordered, non-signaling. - LessThan = 1, // Ordered, signaling. - LessThanOrEqual = 2, // Ordered, signaling. - UnorderedQ = 3, // Non-signaling. - NotLessThan = 5, // Unordered, signaling. + Equal = 0, // Ordered, non-signaling. + LessThan = 1, // Ordered, signaling. + LessThanOrEqual = 2, // Ordered, signaling. + UnorderedQ = 3, // Non-signaling. + NotLessThan = 5, // Unordered, signaling. NotLessThanOrEqual = 6, // Unordered, signaling. - OrderedQ = 7, // Non-signaling. + OrderedQ = 7, // Non-signaling. // Vex. GreaterThanOrEqual = 13, // Ordered, signaling. - GreaterThan = 14, // Ordered, signaling. - OrderedS = 23 // Signaling. + GreaterThan = 14, // Ordered, signaling. + OrderedS = 23, // Signaling. } [Flags] @@ -1459,7 +1459,7 @@ public enum SaturatingFlags Add = 1 << 3, Sub = 1 << 4, - Accumulate = 1 << 5 + Accumulate = 1 << 5, } public static void EmitScalarSaturatingUnaryOpSx(ArmEmitterContext context, Func1I emit) @@ -1579,7 +1579,7 @@ public static void EmitSaturatingBinaryOp(ArmEmitterContext context, Func2I emit { Operand de; Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, !signed); - Operand me = EmitVectorExtract(context, op.Rd, index, op.Size, signed); + Operand me = EmitVectorExtract(context, op.Rd, index, op.Size, signed); if (op.Size <= 2) { @@ -1627,7 +1627,7 @@ public static void EmitSaturatingBinaryOp(ArmEmitterContext context, Func2I emit [Flags] public enum SaturatingNarrowFlags { - Scalar = 1 << 0, + Scalar = 1 << 0, SignedSrc = 1 << 1, SignedDst = 1 << 2, @@ -1637,14 +1637,14 @@ public enum SaturatingNarrowFlags VectorSxSx = SignedSrc | SignedDst, VectorSxZx = SignedSrc, - VectorZxZx = 0 + VectorZxZx = 0, } public static void EmitSaturatingNarrowOp(ArmEmitterContext context, SaturatingNarrowFlags flags) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; - bool scalar = (flags & SaturatingNarrowFlags.Scalar) != 0; + bool scalar = (flags & SaturatingNarrowFlags.Scalar) != 0; bool signedSrc = (flags & SaturatingNarrowFlags.SignedSrc) != 0; bool signedDst = (flags & SaturatingNarrowFlags.SignedDst) != 0; @@ -2034,18 +2034,30 @@ public static Operand EmitVectorExtract(ArmEmitterContext context, int reg, int { switch (size) { - case 0: res = context.SignExtend8 (OperandType.I64, res); break; - case 1: res = context.SignExtend16(OperandType.I64, res); break; - case 2: res = context.SignExtend32(OperandType.I64, res); break; + case 0: + res = context.SignExtend8(OperandType.I64, res); + break; + case 1: + res = context.SignExtend16(OperandType.I64, res); + break; + case 2: + res = context.SignExtend32(OperandType.I64, res); + break; } } else { switch (size) { - case 0: res = context.ZeroExtend8 (OperandType.I64, res); break; - case 1: res = context.ZeroExtend16(OperandType.I64, res); break; - case 2: res = context.ZeroExtend32(OperandType.I64, res); break; + case 0: + res = context.ZeroExtend8(OperandType.I64, res); + break; + case 1: + res = context.ZeroExtend16(OperandType.I64, res); + break; + case 2: + res = context.ZeroExtend32(OperandType.I64, res); + break; } } @@ -2063,10 +2075,18 @@ public static Operand EmitVectorInsert(ArmEmitterContext context, Operand vector switch (size) { - case 0: vector = context.VectorInsert8 (vector, value, index); break; - case 1: vector = context.VectorInsert16(vector, value, index); break; - case 2: vector = context.VectorInsert (vector, value, index); break; - case 3: vector = context.VectorInsert (vector, value, index); break; + case 0: + vector = context.VectorInsert8(vector, value, index); + break; + case 1: + vector = context.VectorInsert16(vector, value, index); + break; + case 2: + vector = context.VectorInsert(vector, value, index); + break; + case 3: + vector = context.VectorInsert(vector, value, index); + break; } return vector; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs index 36d27d425..c1c59b87b 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -19,18 +18,13 @@ static class InstEmitSimdHelper32 { public static (int, int) GetQuadwordAndSubindex(int index, RegisterSize size) { - switch (size) + return size switch { - case RegisterSize.Simd128: - return (index >> 1, 0); - case RegisterSize.Simd64: - case RegisterSize.Int64: - return (index >> 1, index & 1); - case RegisterSize.Int32: - return (index >> 2, index & 3); - } - - throw new ArgumentException("Unrecognized Vector Register Size."); + RegisterSize.Simd128 => (index >> 1, 0), + RegisterSize.Simd64 or RegisterSize.Int64 => (index >> 1, index & 1), + RegisterSize.Int32 => (index >> 2, index & 3), + _ => throw new ArgumentException("Unrecognized Vector Register Size."), + }; } public static Operand ExtractScalar(ArmEmitterContext context, OperandType type, int reg) @@ -327,7 +321,7 @@ public static void EmitVectorBinaryWideOpI32(ArmEmitterContext context, Func2I e for (int index = 0; index < elems; index++) { Operand ne = EmitVectorExtract32(context, op.Qn, op.In + index, op.Size + 1, signed); - Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed); + Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed); if (op.Size == 2) { @@ -380,8 +374,8 @@ public static void EmitVectorTernaryLongOpI32(ArmEmitterContext context, Func3I for (int index = 0; index < elems; index++) { Operand de = EmitVectorExtract32(context, op.Qd, op.Id + index, op.Size + 1, signed); - Operand ne = EmitVectorExtract32(context, op.Qn, op.In + index, op.Size, signed); - Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed); + Operand ne = EmitVectorExtract32(context, op.Qn, op.In + index, op.Size, signed); + Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed); if (op.Size == 2) { @@ -778,7 +772,10 @@ public static Operand EmitSwapScalar(ArmEmitterContext context, Operand target, { // Index into 0, 0 into index. This swap happens at the start of an A32 scalar op if required. int index = reg & (doubleWidth ? 1 : 3); - if (index == 0) return target; + if (index == 0) + { + return target; + } if (doubleWidth) { @@ -974,7 +971,7 @@ public static void EmitScalarBinaryOpF32(ArmEmitterContext context, Intrinsic in Intrinsic inst = (op.Size & 1) != 0 ? inst64 : inst32; - EmitScalarBinaryOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m)); + EmitScalarBinaryOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m)); } public static void EmitScalarTernaryOpSimd32(ArmEmitterContext context, Func3I scalarFunc) @@ -1195,7 +1192,7 @@ public static Operand EmitSoftFloatCallDefaultFpscr(ArmEmitterContext context, s : typeof(SoftFloat64).GetMethod(name); Array.Resize(ref callArgs, callArgs.Length + 1); - callArgs[callArgs.Length - 1] = Const(1); + callArgs[^1] = Const(1); context.ExitArmFpMode(); context.StoreToContext(); @@ -1245,16 +1242,24 @@ public static Operand EmitVectorExtract32(ArmEmitterContext context, int reg, in { switch (size) { - case 0: res = context.SignExtend8(OperandType.I32, res); break; - case 1: res = context.SignExtend16(OperandType.I32, res); break; + case 0: + res = context.SignExtend8(OperandType.I32, res); + break; + case 1: + res = context.SignExtend16(OperandType.I32, res); + break; } } else { switch (size) { - case 0: res = context.ZeroExtend8(OperandType.I32, res); break; - case 1: res = context.ZeroExtend16(OperandType.I32, res); break; + case 0: + res = context.ZeroExtend8(OperandType.I32, res); + break; + case 1: + res = context.ZeroExtend16(OperandType.I32, res); + break; } } diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs index 98236be6d..568c07122 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs @@ -1,11 +1,9 @@ - using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -74,7 +72,10 @@ public static Operand EmitScalarInsert(ArmEmitterContext context, Operand target public static Operand EmitExtractScalar(ArmEmitterContext context, Operand target, int reg, bool doubleWidth) { int index = reg & (doubleWidth ? 1 : 3); - if (index == 0) return target; // Element is already at index 0, so just return the vector directly. + if (index == 0) + { + return target; // Element is already at index 0, so just return the vector directly. + } if (doubleWidth) { @@ -192,11 +193,10 @@ public static void EmitVectorTernaryOpF32(ArmEmitterContext context, Intrinsic i EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m)); } - public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc) + public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize) { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; - bool doubleSize = (op.Size & 1) != 0; int shift = doubleSize ? 1 : 2; Operand m = GetVecA32(op.Vm >> shift); Operand d = GetVecA32(op.Vd >> shift); @@ -215,8 +215,13 @@ public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic ins { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; - inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; - EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m)); + EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0); + } + + public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize) + { + inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; + EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize); } public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc) @@ -245,7 +250,7 @@ public static void EmitScalarBinaryOpF32(ArmEmitterContext context, Intrinsic in OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp; inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; - EmitScalarBinaryOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m)); + EmitScalarBinaryOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m)); } public static void EmitScalarTernaryOpSimd32(ArmEmitterContext context, Func3I scalarFunc) @@ -332,16 +337,17 @@ public static void EmitCmpOpF32(ArmEmitterContext context, CmpCondition cond, bo CmpCondition.GreaterThanOrEqual => Intrinsic.Arm64FcmgeVz, CmpCondition.LessThan => Intrinsic.Arm64FcmltVz, CmpCondition.LessThanOrEqual => Intrinsic.Arm64FcmleVz, - _ => throw new InvalidOperationException() + _ => throw new InvalidOperationException(), }; } - else { + else + { inst = cond switch { CmpCondition.Equal => Intrinsic.Arm64FcmeqV, CmpCondition.GreaterThan => Intrinsic.Arm64FcmgtV, CmpCondition.GreaterThanOrEqual => Intrinsic.Arm64FcmgeV, - _ => throw new InvalidOperationException() + _ => throw new InvalidOperationException(), }; } @@ -363,4 +369,4 @@ public static void EmitCmpOpF32(ArmEmitterContext context, CmpCondition cond, bo } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelperArm64.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelperArm64.cs index f0d242ae2..70dfc0fbd 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelperArm64.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelperArm64.cs @@ -50,7 +50,7 @@ public static void EmitScalarUnaryOpFToGp(ArmEmitterContext context, Intrinsic i } SetIntOrZR(context, op.Rd, op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (inst, n) + ? context.AddIntrinsicInt(inst, n) : context.AddIntrinsicLong(inst, n)); } @@ -288,7 +288,7 @@ public static void EmitScalarConvertBinaryOpFToGp(ArmEmitterContext context, Int } SetIntOrZR(context, op.Rd, op.RegisterSize == RegisterSize.Int32 - ? context.AddIntrinsicInt (inst, n, Const(fBits)) + ? context.AddIntrinsicInt(inst, n, Const(fBits)) : context.AddIntrinsicLong(inst, n, Const(fBits))); } @@ -695,7 +695,7 @@ public static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; - bool cmpWithZero = !(op is OpCodeSimdFcond) ? op.Bit3 : false; + bool cmpWithZero = op is not OpCodeSimdFcond && op.Bit3; Intrinsic inst = signalNaNs ? Intrinsic.Arm64FcmpeS : Intrinsic.Arm64FcmpS; @@ -717,4 +717,4 @@ public static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs) SetFlag(context, PState.NFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const(31)), one)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitSimdLogical.cs b/src/ARMeilleure/Instructions/InstEmitSimdLogical.cs index 2bf531e6c..ace8e4c54 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdLogical.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdLogical.cs @@ -3,7 +3,6 @@ using ARMeilleure.Translation; using System; using System.Diagnostics; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -80,10 +79,11 @@ public static void Bic_Vi(ArmEmitterContext context) int eSize = 8 << op.Size; Operand d = GetVec(op.Rd); - Operand imm = eSize switch { + Operand imm = eSize switch + { 16 => X86GetAllElements(context, (short)~op.Immediate), 32 => X86GetAllElements(context, (int)~op.Immediate), - _ => throw new InvalidOperationException($"Invalid element size {eSize}.") + _ => throw new InvalidOperationException($"Invalid element size {eSize}."), }; Operand res = context.AddIntrinsic(Intrinsic.X86Pand, d, imm); @@ -380,10 +380,11 @@ public static void Orr_Vi(ArmEmitterContext context) int eSize = 8 << op.Size; Operand d = GetVec(op.Rd); - Operand imm = eSize switch { + Operand imm = eSize switch + { 16 => X86GetAllElements(context, (short)op.Immediate), 32 => X86GetAllElements(context, (int)op.Immediate), - _ => throw new InvalidOperationException($"Invalid element size {eSize}.") + _ => throw new InvalidOperationException($"Invalid element size {eSize}."), }; Operand res = context.AddIntrinsic(Intrinsic.X86Por, d, imm); @@ -407,17 +408,17 @@ public static void Rbit_V(ArmEmitterContext context) if (Optimizations.UseGfni) { - const long bitMatrix = + const long BitMatrix = (0b10000000L << 56) | (0b01000000L << 48) | (0b00100000L << 40) | (0b00010000L << 32) | (0b00001000L << 24) | (0b00000100L << 16) | - (0b00000010L << 8) | - (0b00000001L << 0); + (0b00000010L << 8) | + (0b00000001L << 0); - Operand vBitMatrix = X86GetAllElements(context, bitMatrix); + Operand vBitMatrix = X86GetAllElements(context, BitMatrix); Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, GetVec(op.Rn), vBitMatrix, Const(0)); @@ -451,13 +452,13 @@ private static Operand EmitReverseBits8Op(ArmEmitterContext context, Operand op) Debug.Assert(op.Type == OperandType.I64); Operand val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xaaul)), Const(1)), - context.ShiftLeft (context.BitwiseAnd(op, Const(0x55ul)), Const(1))); + context.ShiftLeft(context.BitwiseAnd(op, Const(0x55ul)), Const(1))); val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xccul)), Const(2)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x33ul)), Const(2))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x33ul)), Const(2))); return context.BitwiseOr(context.ShiftRightUI(val, Const(4)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x0ful)), Const(4))); + context.ShiftLeft(context.BitwiseAnd(val, Const(0x0ful)), Const(4))); } public static void Rev16_V(ArmEmitterContext context) @@ -468,12 +469,12 @@ public static void Rev16_V(ArmEmitterContext context) Operand n = GetVec(op.Rn); - const long maskE0 = 06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0; - const long maskE1 = 14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0; + const long MaskE0 = 06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0; + const long MaskE1 = 14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0; - Operand mask = X86GetScalar(context, maskE0); + Operand mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask); @@ -502,21 +503,21 @@ public static void Rev32_V(ArmEmitterContext context) if (op.Size == 0) { - const long maskE0 = 04L << 56 | 05L << 48 | 06L << 40 | 07L << 32 | 00L << 24 | 01L << 16 | 02L << 8 | 03L << 0; - const long maskE1 = 12L << 56 | 13L << 48 | 14L << 40 | 15L << 32 | 08L << 24 | 09L << 16 | 10L << 8 | 11L << 0; + const long MaskE0 = 04L << 56 | 05L << 48 | 06L << 40 | 07L << 32 | 00L << 24 | 01L << 16 | 02L << 8 | 03L << 0; + const long MaskE1 = 12L << 56 | 13L << 48 | 14L << 40 | 15L << 32 | 08L << 24 | 09L << 16 | 10L << 8 | 11L << 0; - mask = X86GetScalar(context, maskE0); + mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); } else /* if (op.Size == 1) */ { - const long maskE0 = 05L << 56 | 04L << 48 | 07L << 40 | 06L << 32 | 01L << 24 | 00L << 16 | 03L << 8 | 02L << 0; - const long maskE1 = 13L << 56 | 12L << 48 | 15L << 40 | 14L << 32 | 09L << 24 | 08L << 16 | 11L << 8 | 10L << 0; + const long MaskE0 = 05L << 56 | 04L << 48 | 07L << 40 | 06L << 32 | 01L << 24 | 00L << 16 | 03L << 8 | 02L << 0; + const long MaskE1 = 13L << 56 | 12L << 48 | 15L << 40 | 14L << 32 | 09L << 24 | 08L << 16 | 11L << 8 | 10L << 0; - mask = X86GetScalar(context, maskE0); + mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); } Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask); @@ -546,30 +547,30 @@ public static void Rev64_V(ArmEmitterContext context) if (op.Size == 0) { - const long maskE0 = 00L << 56 | 01L << 48 | 02L << 40 | 03L << 32 | 04L << 24 | 05L << 16 | 06L << 8 | 07L << 0; - const long maskE1 = 08L << 56 | 09L << 48 | 10L << 40 | 11L << 32 | 12L << 24 | 13L << 16 | 14L << 8 | 15L << 0; + const long MaskE0 = 00L << 56 | 01L << 48 | 02L << 40 | 03L << 32 | 04L << 24 | 05L << 16 | 06L << 8 | 07L << 0; + const long MaskE1 = 08L << 56 | 09L << 48 | 10L << 40 | 11L << 32 | 12L << 24 | 13L << 16 | 14L << 8 | 15L << 0; - mask = X86GetScalar(context, maskE0); + mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); } else if (op.Size == 1) { - const long maskE0 = 01L << 56 | 00L << 48 | 03L << 40 | 02L << 32 | 05L << 24 | 04L << 16 | 07L << 8 | 06L << 0; - const long maskE1 = 09L << 56 | 08L << 48 | 11L << 40 | 10L << 32 | 13L << 24 | 12L << 16 | 15L << 8 | 14L << 0; + const long MaskE0 = 01L << 56 | 00L << 48 | 03L << 40 | 02L << 32 | 05L << 24 | 04L << 16 | 07L << 8 | 06L << 0; + const long MaskE1 = 09L << 56 | 08L << 48 | 11L << 40 | 10L << 32 | 13L << 24 | 12L << 16 | 15L << 8 | 14L << 0; - mask = X86GetScalar(context, maskE0); + mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); } else /* if (op.Size == 2) */ { - const long maskE0 = 03L << 56 | 02L << 48 | 01L << 40 | 00L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0; - const long maskE1 = 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 15L << 24 | 14L << 16 | 13L << 8 | 12L << 0; + const long MaskE0 = 03L << 56 | 02L << 48 | 01L << 40 | 00L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0; + const long MaskE1 = 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 15L << 24 | 14L << 16 | 13L << 8 | 12L << 0; - mask = X86GetScalar(context, maskE0); + mask = X86GetScalar(context, MaskE0); - mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); + mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3); } Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs b/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs index 68ef4ed17..26d093447 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; @@ -52,9 +52,15 @@ public static void Vbic_II(ArmEmitterContext context) // Replicate fields to fill the 64-bits, if size is < 64-bits. switch (op.Size) { - case 0: immediate *= 0x0101010101010101L; break; - case 1: immediate *= 0x0001000100010001L; break; - case 2: immediate *= 0x0000000100000001L; break; + case 0: + immediate *= 0x0101010101010101L; + break; + case 1: + immediate *= 0x0001000100010001L; + break; + case 2: + immediate *= 0x0000000100000001L; + break; } Operand imm = Const(immediate); @@ -199,9 +205,15 @@ public static void Vorr_II(ArmEmitterContext context) // Replicate fields to fill the 64-bits, if size is < 64-bits. switch (op.Size) { - case 0: immediate *= 0x0101010101010101L; break; - case 1: immediate *= 0x0001000100010001L; break; - case 2: immediate *= 0x0000000100000001L; break; + case 0: + immediate *= 0x0101010101010101L; + break; + case 1: + immediate *= 0x0001000100010001L; + break; + case 2: + immediate *= 0x0000000100000001L; + break; } Operand imm = Const(immediate); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMemory.cs b/src/ARMeilleure/Instructions/InstEmitSimdMemory.cs index 9b19872af..dedf0fa05 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMemory.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMemory.cs @@ -40,6 +40,7 @@ private static void EmitSimdMemMs(ArmEmitterContext context, bool isLoad) long offset = 0; +#pragma warning disable IDE0055 // Disable formatting for (int rep = 0; rep < op.Reps; rep++) for (int elem = 0; elem < op.Elems; elem++) for (int sElem = 0; sElem < op.SElems; sElem++) @@ -66,6 +67,7 @@ private static void EmitSimdMemMs(ArmEmitterContext context, bool isLoad) offset += 1 << op.Size; } +#pragma warning restore IDE0055 if (op.WBack) { @@ -157,4 +159,4 @@ private static void EmitSimdMemWBack(ArmEmitterContext context, long offset) context.Copy(n, context.Add(n, m)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs b/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs index b774bd061..35c6dd328 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMove.cs b/src/ARMeilleure/Instructions/InstEmitSimdMove.cs index b58a32f69..85c98fe3a 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMove.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMove.cs @@ -3,7 +3,6 @@ using ARMeilleure.Translation; using System.Collections.Generic; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -12,19 +11,19 @@ namespace ARMeilleure.Instructions { static partial class InstEmit { -#region "Masks" + #region "Masks" private static readonly long[] _masksE0_Uzp = new long[] { 13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0, - 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0 + 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0, }; private static readonly long[] _masksE1_Uzp = new long[] { 15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0, - 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0 + 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0, }; -#endregion + #endregion public static void Dup_Gp(ArmEmitterContext context) { @@ -36,9 +35,17 @@ public static void Dup_Gp(ArmEmitterContext context) { switch (op.Size) { - case 0: n = context.ZeroExtend8 (n.Type, n); n = context.Multiply(n, Const(n.Type, 0x01010101)); break; - case 1: n = context.ZeroExtend16(n.Type, n); n = context.Multiply(n, Const(n.Type, 0x00010001)); break; - case 2: n = context.ZeroExtend32(n.Type, n); break; + case 0: + n = context.ZeroExtend8(n.Type, n); + n = context.Multiply(n, Const(n.Type, 0x01010101)); + break; + case 1: + n = context.ZeroExtend16(n.Type, n); + n = context.Multiply(n, Const(n.Type, 0x00010001)); + break; + case 2: + n = context.ZeroExtend32(n.Type, n); + break; } Operand res = context.VectorInsert(context.VectorZero(), n, 0); @@ -209,7 +216,7 @@ public static void Fcsel_S(ArmEmitterContext context) OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp; Operand lblTrue = Label(); - Operand lblEnd = Label(); + Operand lblEnd = Label(); Operand isTrue = InstEmitFlowHelper.GetCondTrue(context, op.Cond); @@ -353,7 +360,7 @@ public static void Ins_V(ArmEmitterContext context) { OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp; - Operand d = GetVec(op.Rd); + Operand d = GetVec(op.Rd); Operand ne = EmitVectorExtractZx(context, op.Rn, op.SrcIndex, op.Size); context.Copy(d, EmitVectorInsert(context, d, ne, op.DstIndex, op.Size)); @@ -497,8 +504,12 @@ private static void EmitSse2VectorMoviMvniOp(ArmEmitterContext context, bool not switch (op.Size) { - case 0: imm *= 0x01010101; break; - case 1: imm *= 0x00010001; break; + case 0: + imm *= 0x01010101; + break; + case 1: + imm *= 0x00010001; + break; } if (not) @@ -543,7 +554,7 @@ private static void EmitTableVectorLookup(ArmEmitterContext context, bool isTbl) Operand n = GetVec(op.Rn); Operand mMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, m, mask); - mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, m); + mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, m); res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mMask); } @@ -557,7 +568,7 @@ private static void EmitTableVectorLookup(ArmEmitterContext context, bool isTbl) Operand mSubMask = context.AddIntrinsic(Intrinsic.X86Psubb, m, idxMask); Operand mMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, mSubMask, mask); - mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, mSubMask); + mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, mSubMask); Operand res2 = context.AddIntrinsic(Intrinsic.X86Pshufb, ni, mMask); @@ -566,7 +577,7 @@ private static void EmitTableVectorLookup(ArmEmitterContext context, bool isTbl) if (!isTbl) { - Operand idxMask = X86GetAllElements(context, (0x1010101010101010L * op.Size) - 0x0101010101010101L); + Operand idxMask = X86GetAllElements(context, (0x1010101010101010L * op.Size) - 0x0101010101010101L); Operand zeroMask = context.VectorZero(); Operand mPosMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, m, idxMask); @@ -590,7 +601,7 @@ private static void EmitTableVectorLookup(ArmEmitterContext context, bool isTbl) { Operand d = GetVec(op.Rd); - List args = new List(); + List args = new(); if (!isTbl) { @@ -612,20 +623,36 @@ private static void EmitTableVectorLookup(ArmEmitterContext context, bool isTbl) { switch (op.Size) { - case 1: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)); break; - case 2: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)); break; - case 3: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)); break; - case 4: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)); break; + case 1: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)); + break; + case 2: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)); + break; + case 3: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)); + break; + case 4: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)); + break; } } else { switch (op.Size) { - case 1: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)); break; - case 2: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)); break; - case 3: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)); break; - case 4: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)); break; + case 1: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)); + break; + case 2: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)); + break; + case 3: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)); + break; + case 4: + info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)); + break; } } @@ -644,7 +671,7 @@ private static void EmitVectorTranspose(ArmEmitterContext context, int part) if (op.Size < 3) { long maskE0 = EvenMasks[op.Size]; - long maskE1 = OddMasks [op.Size]; + long maskE1 = OddMasks[op.Size]; mask = X86GetScalar(context, maskE0); @@ -691,7 +718,7 @@ private static void EmitVectorTranspose(ArmEmitterContext context, int part) Operand ne = EmitVectorExtractZx(context, op.Rn, pairIndex + part, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, pairIndex + part, op.Size); - res = EmitVectorInsert(context, res, ne, pairIndex, op.Size); + res = EmitVectorInsert(context, res, ne, pairIndex, op.Size); res = EmitVectorInsert(context, res, me, pairIndex + 1, op.Size); } @@ -712,7 +739,7 @@ private static void EmitVectorUnzip(ArmEmitterContext context, int part) if (op.Size < 3) { long maskE0 = EvenMasks[op.Size]; - long maskE1 = OddMasks [op.Size]; + long maskE1 = OddMasks[op.Size]; mask = X86GetScalar(context, maskE0); @@ -784,7 +811,7 @@ private static void EmitVectorUnzip(ArmEmitterContext context, int part) Operand ne = EmitVectorExtractZx(context, op.Rn, idx + part, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, idx + part, op.Size); - res = EmitVectorInsert(context, res, ne, index, op.Size); + res = EmitVectorInsert(context, res, ne, index, op.Size); res = EmitVectorInsert(context, res, me, pairs + index, op.Size); } @@ -839,7 +866,7 @@ private static void EmitVectorZip(ArmEmitterContext context, int part) Operand ne = EmitVectorExtractZx(context, op.Rn, baseIndex + index, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, baseIndex + index, op.Size); - res = EmitVectorInsert(context, res, ne, pairIndex, op.Size); + res = EmitVectorInsert(context, res, ne, pairIndex, op.Size); res = EmitVectorInsert(context, res, me, pairIndex + 1, op.Size); } diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs b/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs index b8b91b31d..9fa740997 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs @@ -1,8 +1,7 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper32; @@ -17,13 +16,13 @@ static partial class InstEmit32 private static readonly long[] _masksE0_Uzp = new long[] { 13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0, - 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0 + 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0, }; private static readonly long[] _masksE1_Uzp = new long[] { 15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0, - 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0 + 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0, }; #endregion @@ -220,7 +219,7 @@ public static void Vtbl(ArmEmitterContext context) for (int index = 1; index < length; index++) { int newVn = (op.Vn + index) & 0x1F; - (int qn, int ind) = GetQuadwordAndSubindex(newVn, op.RegisterSize); + (int qn, _) = GetQuadwordAndSubindex(newVn, op.RegisterSize); Operand ni = EmitMoveDoubleWordToSide(context, GetVecA32(qn), newVn, 0); Operand idxMask = X86GetAllElements(context, 0x0808080808080808L * index); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdShift.cs b/src/ARMeilleure/Instructions/InstEmitSimdShift.cs index 19e41119b..be0670645 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdShift.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdShift.cs @@ -6,7 +6,6 @@ using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -17,12 +16,12 @@ namespace ARMeilleure.Instructions static partial class InstEmit { -#region "Masks" + #region "Masks" private static readonly long[] _masks_SliSri = new long[] // Replication masks. { - 0x0101010101010101L, 0x0001000100010001L, 0x0000000100000001L, 0x0000000000000001L + 0x0101010101010101L, 0x0001000100010001L, 0x0000000100000001L, 0x0000000000000001L, }; -#endregion + #endregion public static void Rshrn_V(ArmEmitterContext context) { @@ -51,9 +50,15 @@ public static void Rshrn_V(ArmEmitterContext context) switch (op.Size + 1) { - case 1: mask = X86GetAllElements(context, (int)roundConst * 0x00010001); break; - case 2: mask = X86GetAllElements(context, (int)roundConst); break; - case 3: mask = X86GetAllElements(context, roundConst); break; + case 1: + mask = X86GetAllElements(context, (int)roundConst * 0x00010001); + break; + case 2: + mask = X86GetAllElements(context, (int)roundConst); + break; + case 3: + mask = X86GetAllElements(context, roundConst); + break; } Intrinsic addInst = X86PaddInstruction[op.Size + 1]; @@ -1174,14 +1179,14 @@ private enum ShrImmFlags Scalar = 1 << 0, Signed = 1 << 1, - Round = 1 << 2, + Round = 1 << 2, Accumulate = 1 << 3, ScalarSx = Scalar | Signed, ScalarZx = Scalar, VectorSx = Signed, - VectorZx = 0 + VectorZx = 0, } private static void EmitScalarShrImmOpSx(ArmEmitterContext context, ShrImmFlags flags) @@ -1210,9 +1215,9 @@ private static void EmitShrImmOp(ArmEmitterContext context, ShrImmFlags flags) Operand res = context.VectorZero(); - bool scalar = (flags & ShrImmFlags.Scalar) != 0; - bool signed = (flags & ShrImmFlags.Signed) != 0; - bool round = (flags & ShrImmFlags.Round) != 0; + bool scalar = (flags & ShrImmFlags.Scalar) != 0; + bool signed = (flags & ShrImmFlags.Signed) != 0; + bool round = (flags & ShrImmFlags.Round) != 0; bool accumulate = (flags & ShrImmFlags.Accumulate) != 0; int shift = GetImmShr(op); @@ -1288,7 +1293,7 @@ private static void EmitVectorShrImmNarrowOpZx(ArmEmitterContext context, bool r [Flags] private enum ShrImmSaturatingNarrowFlags { - Scalar = 1 << 0, + Scalar = 1 << 0, SignedSrc = 1 << 1, SignedDst = 1 << 2, @@ -1300,7 +1305,7 @@ private enum ShrImmSaturatingNarrowFlags VectorSxSx = SignedSrc | SignedDst, VectorSxZx = SignedSrc, - VectorZxZx = 0 + VectorZxZx = 0, } private static void EmitRoundShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrImmSaturatingNarrowFlags flags) @@ -1312,10 +1317,10 @@ private static void EmitShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrI { OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp; - bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; + bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; bool signedSrc = (flags & ShrImmSaturatingNarrowFlags.SignedSrc) != 0; bool signedDst = (flags & ShrImmSaturatingNarrowFlags.SignedDst) != 0; - bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0; + bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0; int shift = GetImmShr(op); @@ -1585,7 +1590,7 @@ private enum ShlRegFlags Scalar = 1 << 0, Signed = 1 << 1, Round = 1 << 2, - Saturating = 1 << 3 + Saturating = 1 << 3, } private static void EmitShlRegOp(ArmEmitterContext context, ShlRegFlags flags = ShlRegFlags.None) diff --git a/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs index 9ac680884..e40600a47 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -1,11 +1,10 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper32; @@ -291,7 +290,7 @@ private enum ShrImmSaturatingNarrowFlags VectorSxSx = SignedSrc | SignedDst, VectorSxZx = SignedSrc, - VectorZxZx = 0 + VectorZxZx = 0, } private static void EmitRoundShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrImmSaturatingNarrowFlags flags) @@ -303,10 +302,10 @@ private static void EmitShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrI { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; - bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; + bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; bool signedSrc = (flags & ShrImmSaturatingNarrowFlags.SignedSrc) != 0; bool signedDst = (flags & ShrImmSaturatingNarrowFlags.SignedDst) != 0; - bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0; + bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0; if (scalar) { diff --git a/src/ARMeilleure/Instructions/InstEmitSystem.cs b/src/ARMeilleure/Instructions/InstEmitSystem.cs index f84829aa1..8c430fc23 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem.cs @@ -28,18 +28,39 @@ public static void Mrs(ArmEmitterContext context) switch (GetPackedId(op)) { - case 0b11_011_0000_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)); break; - case 0b11_011_0000_0000_111: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)); break; - case 0b11_011_0100_0010_000: EmitGetNzcv(context); return; - case 0b11_011_0100_0100_000: EmitGetFpcr(context); return; - case 0b11_011_0100_0100_001: EmitGetFpsr(context); return; - case 0b11_011_1101_0000_010: EmitGetTpidrEl0(context); return; - case 0b11_011_1101_0000_011: EmitGetTpidrroEl0(context); return; - case 0b11_011_1110_0000_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; - case 0b11_011_1110_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; - case 0b11_011_1110_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)); break; - - default: throw new NotImplementedException($"Unknown MRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); + case 0b11_011_0000_0000_001: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)); + break; + case 0b11_011_0000_0000_111: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)); + break; + case 0b11_011_0100_0010_000: + EmitGetNzcv(context); + return; + case 0b11_011_0100_0100_000: + EmitGetFpcr(context); + return; + case 0b11_011_0100_0100_001: + EmitGetFpsr(context); + return; + case 0b11_011_1101_0000_010: + EmitGetTpidrEl0(context); + return; + case 0b11_011_1101_0000_011: + EmitGetTpidrroEl0(context); + return; + case 0b11_011_1110_0000_000: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); + break; + case 0b11_011_1110_0000_001: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); + break; + case 0b11_011_1110_0000_010: + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)); + break; + + default: + throw new NotImplementedException($"Unknown MRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } SetIntOrZR(context, op.Rt, context.Call(info)); @@ -51,12 +72,21 @@ public static void Msr(ArmEmitterContext context) switch (GetPackedId(op)) { - case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; - case 0b11_011_0100_0100_000: EmitSetFpcr(context); return; - case 0b11_011_0100_0100_001: EmitSetFpsr(context); return; - case 0b11_011_1101_0000_010: EmitSetTpidrEl0(context); return; - - default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); + case 0b11_011_0100_0010_000: + EmitSetNzcv(context); + return; + case 0b11_011_0100_0100_000: + EmitSetFpcr(context); + return; + case 0b11_011_0100_0100_001: + EmitSetFpsr(context); + return; + case 0b11_011_1101_0000_010: + EmitSetTpidrEl0(context); + return; + + default: + throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } } @@ -75,19 +105,19 @@ public static void Sys(ArmEmitterContext context) switch (GetPackedId(op)) { case 0b11_011_0111_0100_001: - { - // DC ZVA - Operand t = GetIntOrZR(context, op.Rt); - - for (long offset = 0; offset < DczSizeInBytes; offset += 8) { - Operand address = context.Add(t, Const(offset)); + // DC ZVA + Operand t = GetIntOrZR(context, op.Rt); - InstEmitMemoryHelper.EmitStore(context, address, RegisterConsts.ZeroIndex, 3); - } + for (long offset = 0; offset < DczSizeInBytes; offset += 8) + { + Operand address = context.Add(t, Const(offset)); - break; - } + InstEmitMemoryHelper.EmitStore(context, address, RegisterConsts.ZeroIndex, 3); + } + + break; + } // No-op case 0b11_011_0111_1110_001: // DC CIVAC @@ -104,7 +134,7 @@ private static int GetPackedId(OpCodeSystem op) { int id; - id = op.Op2 << 0; + id = op.Op2 << 0; id |= op.CRm << 3; id |= op.CRn << 7; id |= op.Op1 << 11; @@ -188,7 +218,7 @@ private static void EmitSetNzcv(ArmEmitterContext context) OpCodeSystem op = (OpCodeSystem)context.CurrOp; Operand nzcv = GetIntOrZR(context, op.Rt); - nzcv = context.ConvertI64ToI32(nzcv); + nzcv = context.ConvertI64ToI32(nzcv); SetFlag(context, PState.VFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.VFlag)), Const(1))); SetFlag(context, PState.CFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.CFlag)), Const(1))); @@ -201,7 +231,7 @@ private static void EmitSetFpcr(ArmEmitterContext context) OpCodeSystem op = (OpCodeSystem)context.CurrOp; Operand fpcr = GetIntOrZR(context, op.Rt); - fpcr = context.ConvertI64ToI32(fpcr); + fpcr = context.ConvertI64ToI32(fpcr); for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) { @@ -221,7 +251,7 @@ private static void EmitSetFpsr(ArmEmitterContext context) context.ClearQcFlagIfModified(); Operand fpsr = GetIntOrZR(context, op.Rt); - fpsr = context.ConvertI64ToI32(fpsr); + fpsr = context.ConvertI64ToI32(fpsr); for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) { diff --git a/src/ARMeilleure/Instructions/InstEmitSystem32.cs b/src/ARMeilleure/Instructions/InstEmitSystem32.cs index f2732c998..74d6169c6 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -1,10 +1,9 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Reflection; - using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -34,7 +33,8 @@ public static void Mcr(ArmEmitterContext context) switch (op.Opc2) { case 2: - EmitSetTpidrEl0(context); return; + EmitSetTpidrEl0(context); + return; default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); @@ -83,17 +83,13 @@ public static void Mrc(ArmEmitterContext context) throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); } - switch (op.Opc2) + result = op.Opc2 switch { - case 2: - result = EmitGetTpidrEl0(context); break; - - case 3: - result = EmitGetTpidrroEl0(context); break; - - default: - throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); - } + 2 => EmitGetTpidrEl0(context), + 3 => EmitGetTpidrroEl0(context), + _ => throw new NotImplementedException( + $"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."), + }; break; @@ -126,27 +122,16 @@ public static void Mrrc(ArmEmitterContext context) } int opc = op.MrrcOp; - - MethodInfo info; - - switch (op.CRm) + MethodInfo info = op.CRm switch { - case 14: // Timer. - switch (opc) - { - case 0: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; - - default: - throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); - } - - break; - - default: - throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X} at 0x{op.Address:X}."); - } - + // Timer. + 14 => opc switch + { + 0 => typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)), + _ => throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."), + }, + _ => throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X} at 0x{op.Address:X}."), + }; Operand result = context.Call(info); SetIntA32(context, op.Rt, context.ConvertI64ToI32(result)); @@ -235,7 +220,8 @@ public static void Vmrs(ArmEmitterContext context) case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - EmitGetFpscr(context); return; + EmitGetFpscr(context); + return; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 @@ -258,7 +244,8 @@ public static void Vmsr(ArmEmitterContext context) case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - EmitSetFpscr(context); return; + EmitSetFpscr(context); + return; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 diff --git a/src/ARMeilleure/Instructions/InstName.cs b/src/ARMeilleure/Instructions/InstName.cs index fd71d92e6..32ae38dad 100644 --- a/src/ARMeilleure/Instructions/InstName.cs +++ b/src/ARMeilleure/Instructions/InstName.cs @@ -228,6 +228,7 @@ enum InstName Fmaxnmp_S, Fmaxnmp_V, Fmaxnmv_V, + Fmaxp_S, Fmaxp_V, Fmaxv_V, Fmin_S, @@ -237,6 +238,7 @@ enum InstName Fminnmp_S, Fminnmp_V, Fminnmv_V, + Fminp_S, Fminp_V, Fminv_V, Fmla_Se, diff --git a/src/ARMeilleure/Instructions/NativeInterface.cs b/src/ARMeilleure/Instructions/NativeInterface.cs index 2c35387a6..d1b2e353c 100644 --- a/src/ARMeilleure/Instructions/NativeInterface.cs +++ b/src/ARMeilleure/Instructions/NativeInterface.cs @@ -64,12 +64,12 @@ public static void Undefined(ulong address, int opCode) #region "System registers" public static ulong GetCtrEl0() { - return (ulong)GetContext().CtrEl0; + return GetContext().CtrEl0; } public static ulong GetDczidEl0() { - return (ulong)GetContext().DczidEl0; + return GetContext().DczidEl0; } public static ulong GetCntfrqEl0() @@ -192,4 +192,4 @@ public static IMemoryManager GetMemoryManager() return Context.Memory; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Instructions/SoftFallback.cs b/src/ARMeilleure/Instructions/SoftFallback.cs index 06d76a67c..c4fe677bf 100644 --- a/src/ARMeilleure/Instructions/SoftFallback.cs +++ b/src/ARMeilleure/Instructions/SoftFallback.cs @@ -5,7 +5,7 @@ namespace ARMeilleure.Instructions { static class SoftFallback { -#region "ShrImm64" + #region "ShrImm64" public static long SignedShrImm64(long value, long roundConst, int shift) { if (roundConst == 0L) @@ -89,12 +89,15 @@ public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift) } } } -#endregion + #endregion -#region "Saturation" + #region "Saturation" public static int SatF32ToS32(float value) { - if (float.IsNaN(value)) return 0; + if (float.IsNaN(value)) + { + return 0; + } return value >= int.MaxValue ? int.MaxValue : value <= int.MinValue ? int.MinValue : (int)value; @@ -102,7 +105,10 @@ public static int SatF32ToS32(float value) public static long SatF32ToS64(float value) { - if (float.IsNaN(value)) return 0; + if (float.IsNaN(value)) + { + return 0; + } return value >= long.MaxValue ? long.MaxValue : value <= long.MinValue ? long.MinValue : (long)value; @@ -110,7 +116,10 @@ public static long SatF32ToS64(float value) public static uint SatF32ToU32(float value) { - if (float.IsNaN(value)) return 0; + if (float.IsNaN(value)) + { + return 0; + } return value >= uint.MaxValue ? uint.MaxValue : value <= uint.MinValue ? uint.MinValue : (uint)value; @@ -118,7 +127,10 @@ public static uint SatF32ToU32(float value) public static ulong SatF32ToU64(float value) { - if (float.IsNaN(value)) return 0; + if (float.IsNaN(value)) + { + return 0; + } return value >= ulong.MaxValue ? ulong.MaxValue : value <= ulong.MinValue ? ulong.MinValue : (ulong)value; @@ -126,7 +138,10 @@ public static ulong SatF32ToU64(float value) public static int SatF64ToS32(double value) { - if (double.IsNaN(value)) return 0; + if (double.IsNaN(value)) + { + return 0; + } return value >= int.MaxValue ? int.MaxValue : value <= int.MinValue ? int.MinValue : (int)value; @@ -134,7 +149,10 @@ public static int SatF64ToS32(double value) public static long SatF64ToS64(double value) { - if (double.IsNaN(value)) return 0; + if (double.IsNaN(value)) + { + return 0; + } return value >= long.MaxValue ? long.MaxValue : value <= long.MinValue ? long.MinValue : (long)value; @@ -142,7 +160,10 @@ public static long SatF64ToS64(double value) public static uint SatF64ToU32(double value) { - if (double.IsNaN(value)) return 0; + if (double.IsNaN(value)) + { + return 0; + } return value >= uint.MaxValue ? uint.MaxValue : value <= uint.MinValue ? uint.MinValue : (uint)value; @@ -150,14 +171,17 @@ public static uint SatF64ToU32(double value) public static ulong SatF64ToU64(double value) { - if (double.IsNaN(value)) return 0; + if (double.IsNaN(value)) + { + return 0; + } return value >= ulong.MaxValue ? ulong.MaxValue : value <= ulong.MinValue ? ulong.MinValue : (ulong)value; } -#endregion + #endregion -#region "Count" + #region "Count" public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). { value ^= value >> 1; @@ -197,9 +221,9 @@ public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 3 return (ulong)count; } -#endregion + #endregion -#region "Table" + #region "Table" public static V128 Tbl1(V128 vector, int bytes, V128 tb0) { return TblOrTbx(default, vector, bytes, tb0); @@ -270,21 +294,21 @@ private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params V128[] tb return new V128(res); } -#endregion + #endregion -#region "Crc32" - private const uint Crc32RevPoly = 0xedb88320; + #region "Crc32" + private const uint Crc32RevPoly = 0xedb88320; private const uint Crc32cRevPoly = 0x82f63b78; - public static uint Crc32b(uint crc, byte value) => Crc32 (crc, Crc32RevPoly, value); + public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value); public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value); - public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value); - public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value); + public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value); + public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value); - public static uint Crc32cb(uint crc, byte value) => Crc32 (crc, Crc32cRevPoly, value); + public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value); public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value); - public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value); - public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value); + public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value); + public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value); private static uint Crc32h(uint crc, uint poly, ushort val) { @@ -331,9 +355,9 @@ private static uint Crc32(uint crc, uint poly, byte val) return crc; } -#endregion + #endregion -#region "Aes" + #region "Aes" public static V128 Decrypt(V128 value, V128 roundKey) { return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey)); @@ -353,9 +377,9 @@ public static V128 MixColumns(V128 value) { return CryptoHelper.AesMixColumns(value); } -#endregion + #endregion -#region "Sha1" + #region "Sha1" public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk) { for (int e = 0; e <= 3; e++) @@ -426,7 +450,7 @@ public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11) ulong t2 = w4_7.Extract(0); ulong t1 = w0_3.Extract(1); - V128 result = new V128(t1, t2); + V128 result = new(t1, t2); return result ^ (w0_3 ^ w8_11); } @@ -472,9 +496,9 @@ private static uint Rol(this uint value, int count) { return (value << count) | (value >> (32 - count)); } -#endregion + #endregion -#region "Sha256" + #region "Sha256" public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk) { return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true); @@ -487,7 +511,7 @@ public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk) public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7) { - V128 result = new V128(); + V128 result = new(); for (int e = 0; e <= 3; e++) { @@ -505,7 +529,7 @@ public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7) public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15) { - V128 result = new V128(); + V128 result = new(); ulong t1 = w12_15.Extract(1); @@ -602,13 +626,13 @@ private static uint ULongPart(this ulong value, int part) ? (uint)(value & 0xFFFFFFFFUL) : (uint)(value >> 32); } -#endregion + #endregion public static V128 PolynomialMult64_128(ulong op1, ulong op2) { V128 result = V128.Zero; - V128 op2_128 = new V128(op2, 0); + V128 op2_128 = new(op2, 0); for (int i = 0; i < 64; i++) { diff --git a/src/ARMeilleure/Instructions/SoftFloat.cs b/src/ARMeilleure/Instructions/SoftFloat.cs index 9e3db68d9..a67349e6e 100644 --- a/src/ARMeilleure/Instructions/SoftFloat.cs +++ b/src/ARMeilleure/Instructions/SoftFloat.cs @@ -8,7 +8,7 @@ static class SoftFloat { static SoftFloat() { - RecipEstimateTable = BuildRecipEstimateTable(); + RecipEstimateTable = BuildRecipEstimateTable(); RecipSqrtEstimateTable = BuildRecipSqrtEstimateTable(); } @@ -63,7 +63,7 @@ private static byte[] BuildRecipSqrtEstimateTable() while (src * (aux + 1u) * (aux + 1u) < (1u << 28)) { - aux = aux + 1u; + aux++; } uint dst = (aux + 1u) >> 1; @@ -133,8 +133,8 @@ public static double FPUnpackCv( { sign = (~(uint)valueBits & 0x8000u) == 0u; - uint exp16 = ((uint)valueBits & 0x7C00u) >> 10; - uint frac16 = (uint)valueBits & 0x03FFu; + uint exp16 = ((uint)valueBits & 0x7C00u) >> 10; + uint frac16 = (uint)valueBits & 0x03FFu; double real; @@ -175,22 +175,22 @@ public static double FPUnpackCv( public static ushort FPRoundCv(double real, ExecutionContext context) { - const int minimumExp = -14; + const int MinimumExp = -14; - const int e = 5; - const int f = 10; + const int E = 5; + const int F = 10; - bool sign; + bool sign; double mantissa; if (real < 0d) { - sign = true; + sign = true; mantissa = -real; } else { - sign = false; + sign = false; mantissa = real; } @@ -208,15 +208,15 @@ public static ushort FPRoundCv(double real, ExecutionContext context) exponent++; } - uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0); + uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0); if (biasedExp == 0u) { - mantissa /= Math.Pow(2d, minimumExp - exponent); + mantissa /= Math.Pow(2d, MinimumExp - exponent); } - uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f)); - double error = mantissa * Math.Pow(2d, f) - (double)intMant; + uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F)); + double error = mantissa * Math.Pow(2d, F) - (double)intMant; if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0)) { @@ -228,38 +228,40 @@ public static ushort FPRoundCv(double real, ExecutionContext context) switch (context.Fpcr.GetRoundingMode()) { - default: case FPRoundingMode.ToNearest: - roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); + roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); overflowToInf = true; break; case FPRoundingMode.TowardsPlusInfinity: - roundUp = (error != 0d && !sign); + roundUp = (error != 0d && !sign); overflowToInf = !sign; break; case FPRoundingMode.TowardsMinusInfinity: - roundUp = (error != 0d && sign); + roundUp = (error != 0d && sign); overflowToInf = sign; break; case FPRoundingMode.TowardsZero: - roundUp = false; + roundUp = false; overflowToInf = false; break; + + default: + throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.GetRoundingMode()}\"."); } if (roundUp) { intMant++; - if (intMant == 1u << f) + if (intMant == 1u << F) { biasedExp = 1u; } - if (intMant == 1u << (f + 1)) + if (intMant == 1u << (F + 1)) { biasedExp++; intMant >>= 1; @@ -270,7 +272,7 @@ public static ushort FPRoundCv(double real, ExecutionContext context) if ((context.Fpcr & FPCR.Ahp) == 0) { - if (biasedExp >= (1u << e) - 1u) + if (biasedExp >= (1u << E) - 1u) { resultBits = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign); @@ -285,7 +287,7 @@ public static ushort FPRoundCv(double real, ExecutionContext context) } else { - if (biasedExp >= 1u << e) + if (biasedExp >= 1u << E) { resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu); @@ -352,22 +354,22 @@ public static float FPConvert(ushort valueBits) private static float FPRoundCv(double real, ExecutionContext context) { - const int minimumExp = -126; + const int MinimumExp = -126; - const int e = 8; - const int f = 23; + const int E = 8; + const int F = 23; - bool sign; + bool sign; double mantissa; if (real < 0d) { - sign = true; + sign = true; mantissa = -real; } else { - sign = false; + sign = false; mantissa = real; } @@ -385,22 +387,22 @@ private static float FPRoundCv(double real, ExecutionContext context) exponent++; } - if ((context.Fpcr & FPCR.Fz) != 0 && exponent < minimumExp) + if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp) { context.Fpsr |= FPSR.Ufc; return SoftFloat32.FPZero(sign); } - uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0); + uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0); if (biasedExp == 0u) { - mantissa /= Math.Pow(2d, minimumExp - exponent); + mantissa /= Math.Pow(2d, MinimumExp - exponent); } - uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f)); - double error = mantissa * Math.Pow(2d, f) - (double)intMant; + uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F)); + double error = mantissa * Math.Pow(2d, F) - (double)intMant; if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0)) { @@ -412,38 +414,40 @@ private static float FPRoundCv(double real, ExecutionContext context) switch (context.Fpcr.GetRoundingMode()) { - default: case FPRoundingMode.ToNearest: - roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); + roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); overflowToInf = true; break; case FPRoundingMode.TowardsPlusInfinity: - roundUp = (error != 0d && !sign); + roundUp = (error != 0d && !sign); overflowToInf = !sign; break; case FPRoundingMode.TowardsMinusInfinity: - roundUp = (error != 0d && sign); + roundUp = (error != 0d && sign); overflowToInf = sign; break; case FPRoundingMode.TowardsZero: - roundUp = false; + roundUp = false; overflowToInf = false; break; + + default: + throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.GetRoundingMode()}\"."); } if (roundUp) { intMant++; - if (intMant == 1u << f) + if (intMant == 1u << F) { biasedExp = 1u; } - if (intMant == 1u << (f + 1)) + if (intMant == 1u << (F + 1)) { biasedExp++; intMant >>= 1; @@ -452,7 +456,7 @@ private static float FPRoundCv(double real, ExecutionContext context) float result; - if (biasedExp >= (1u << e) - 1u) + if (biasedExp >= (1u << E) - 1u) { result = overflowToInf ? SoftFloat32.FPInfinity(sign) : SoftFloat32.FPMaxNormal(sign); @@ -525,22 +529,22 @@ public static double FPConvert(ushort valueBits) private static double FPRoundCv(double real, ExecutionContext context) { - const int minimumExp = -1022; + const int MinimumExp = -1022; - const int e = 11; - const int f = 52; + const int E = 11; + const int F = 52; - bool sign; + bool sign; double mantissa; if (real < 0d) { - sign = true; + sign = true; mantissa = -real; } else { - sign = false; + sign = false; mantissa = real; } @@ -558,22 +562,22 @@ private static double FPRoundCv(double real, ExecutionContext context) exponent++; } - if ((context.Fpcr & FPCR.Fz) != 0 && exponent < minimumExp) + if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp) { context.Fpsr |= FPSR.Ufc; return SoftFloat64.FPZero(sign); } - uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0); + uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0); if (biasedExp == 0u) { - mantissa /= Math.Pow(2d, minimumExp - exponent); + mantissa /= Math.Pow(2d, MinimumExp - exponent); } - ulong intMant = (ulong)Math.Floor(mantissa * Math.Pow(2d, f)); - double error = mantissa * Math.Pow(2d, f) - (double)intMant; + ulong intMant = (ulong)Math.Floor(mantissa * Math.Pow(2d, F)); + double error = mantissa * Math.Pow(2d, F) - (double)intMant; if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0)) { @@ -585,38 +589,40 @@ private static double FPRoundCv(double real, ExecutionContext context) switch (context.Fpcr.GetRoundingMode()) { - default: case FPRoundingMode.ToNearest: - roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); + roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u)); overflowToInf = true; break; case FPRoundingMode.TowardsPlusInfinity: - roundUp = (error != 0d && !sign); + roundUp = (error != 0d && !sign); overflowToInf = !sign; break; case FPRoundingMode.TowardsMinusInfinity: - roundUp = (error != 0d && sign); + roundUp = (error != 0d && sign); overflowToInf = sign; break; case FPRoundingMode.TowardsZero: - roundUp = false; + roundUp = false; overflowToInf = false; break; + + default: + throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.GetRoundingMode()}\"."); } if (roundUp) { intMant++; - if (intMant == 1ul << f) + if (intMant == 1ul << F) { biasedExp = 1u; } - if (intMant == 1ul << (f + 1)) + if (intMant == 1ul << (F + 1)) { biasedExp++; intMant >>= 1; @@ -625,7 +631,7 @@ private static double FPRoundCv(double real, ExecutionContext context) double result; - if (biasedExp >= (1u << e) - 1u) + if (biasedExp >= (1u << E) - 1u) { result = overflowToInf ? SoftFloat64.FPInfinity(sign) : SoftFloat64.FPMaxNormal(sign); @@ -722,8 +728,8 @@ private static double FPUnpackCv( sign = (~valueBits & 0x80000000u) == 0u; - uint exp32 = (valueBits & 0x7F800000u) >> 23; - uint frac32 = valueBits & 0x007FFFFFu; + uint exp32 = (valueBits & 0x7F800000u) >> 23; + uint frac32 = valueBits & 0x007FFFFFu; double real; @@ -792,8 +798,10 @@ public static float FPAddFpscr(float value1, float value2, bool standardFpscr) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == !sign2) { @@ -834,8 +842,8 @@ public static int FPCompare(float value1, float value2, bool signalNaNs) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); int result; @@ -989,8 +997,10 @@ public static float FPDiv(float value1, float value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && inf2) || (zero1 && zero2)) { @@ -1226,8 +1236,10 @@ public static float FPMulFpscr(float value1, float value2, bool standardFpscr) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -1270,11 +1282,13 @@ public static float FPMulAddFpscr(float valueA, float value1, float value2, bool FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; valueA = valueA.FPUnpack(out FPType typeA, out bool signA, out uint addend, context, fpcr); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; float result = FPProcessNaNs3(typeA, type1, type2, addend, op1, op2, out bool done, context, fpcr); @@ -1287,10 +1301,11 @@ public static float FPMulAddFpscr(float valueA, float value1, float value2, bool if (!done) { - bool infA = typeA == FPType.Infinity; bool zeroA = typeA == FPType.Zero; + bool infA = typeA == FPType.Infinity; + bool zeroA = typeA == FPType.Zero; - bool signP = sign1 ^ sign2; - bool infP = inf1 || inf2; + bool signP = sign1 ^ sign2; + bool infP = inf1 || inf2; bool zeroP = zero1 || zero2; if ((inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP)) @@ -1353,8 +1368,10 @@ public static float FPMulX(float value1, float value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -1429,21 +1446,18 @@ public static float FPRecipEstimateFpscr(float value, bool standardFpscr) } else if (MathF.Abs(value) < MathF.Pow(2f, -128)) { - bool overflowToInf; - - switch (fpcr.GetRoundingMode()) + var overflowToInf = fpcr.GetRoundingMode() switch { - default: - case FPRoundingMode.ToNearest: overflowToInf = true; break; - case FPRoundingMode.TowardsPlusInfinity: overflowToInf = !sign; break; - case FPRoundingMode.TowardsMinusInfinity: overflowToInf = sign; break; - case FPRoundingMode.TowardsZero: overflowToInf = false; break; - } - + FPRoundingMode.ToNearest => true, + FPRoundingMode.TowardsPlusInfinity => !sign, + FPRoundingMode.TowardsMinusInfinity => sign, + FPRoundingMode.TowardsZero => false, + _ => throw new ArgumentException($"Invalid rounding mode \"{fpcr.GetRoundingMode()}\"."), + }; result = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign); SoftFloat.FPProcessException(FPException.Overflow, context, fpcr); - SoftFloat.FPProcessException(FPException.Inexact, context, fpcr); + SoftFloat.FPProcessException(FPException.Inexact, context, fpcr); } else if ((fpcr & FPCR.Fz) != 0 && (MathF.Abs(value) >= MathF.Pow(2f, 126))) { @@ -1499,15 +1513,17 @@ public static float FPRecipStep(float value1, float value2) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.StandardFpcrValue; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out uint op2, context, fpcr); float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; float product; @@ -1540,8 +1556,10 @@ public static float FPRecipStepFused(float value1, float value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -1672,8 +1690,10 @@ public static float FPHalvedSub(float value1, float value2, ExecutionContext con if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == sign2) { @@ -1714,15 +1734,17 @@ public static float FPRSqrtStep(float value1, float value2) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.StandardFpcrValue; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out uint op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out uint op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out uint op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out uint op2, context, fpcr); float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; float product; @@ -1755,8 +1777,10 @@ public static float FPRSqrtStepFused(float value1, float value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -1841,8 +1865,10 @@ public static float FPSubFpscr(float value1, float value2, bool standardFpscr) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == sign2) { @@ -1939,7 +1965,7 @@ private static float FPUnpack( { if ((valueBits & 0x007FFFFFu) == 0u || (fpcr & FPCR.Fz) != 0) { - type = FPType.Zero; + type = FPType.Zero; value = FPZero(sign); if ((valueBits & 0x007FFFFFu) != 0u) @@ -1960,7 +1986,7 @@ private static float FPUnpack( } else { - type = (~valueBits & 0x00400000u) == 0u ? FPType.QNaN : FPType.SNaN; + type = (~valueBits & 0x00400000u) == 0u ? FPType.QNaN : FPType.SNaN; value = FPZero(sign); } } @@ -2134,8 +2160,8 @@ private static double FPUnpackCv( sign = (~valueBits & 0x8000000000000000ul) == 0u; - ulong exp64 = (valueBits & 0x7FF0000000000000ul) >> 52; - ulong frac64 = valueBits & 0x000FFFFFFFFFFFFFul; + ulong exp64 = (valueBits & 0x7FF0000000000000ul) >> 52; + ulong frac64 = valueBits & 0x000FFFFFFFFFFFFFul; double real; @@ -2204,8 +2230,10 @@ public static double FPAddFpscr(double value1, double value2, bool standardFpscr if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == !sign2) { @@ -2246,8 +2274,8 @@ public static int FPCompare(double value1, double value2, bool signalNaNs) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.Fpcr; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out _, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out _, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr); int result; @@ -2401,8 +2429,10 @@ public static double FPDiv(double value1, double value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && inf2) || (zero1 && zero2)) { @@ -2638,8 +2668,10 @@ public static double FPMulFpscr(double value1, double value2, bool standardFpscr if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -2682,11 +2714,13 @@ public static double FPMulAddFpscr(double valueA, double value1, double value2, FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; valueA = valueA.FPUnpack(out FPType typeA, out bool signA, out ulong addend, context, fpcr); - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; double result = FPProcessNaNs3(typeA, type1, type2, addend, op1, op2, out bool done, context, fpcr); @@ -2699,10 +2733,11 @@ public static double FPMulAddFpscr(double valueA, double value1, double value2, if (!done) { - bool infA = typeA == FPType.Infinity; bool zeroA = typeA == FPType.Zero; + bool infA = typeA == FPType.Infinity; + bool zeroA = typeA == FPType.Zero; - bool signP = sign1 ^ sign2; - bool infP = inf1 || inf2; + bool signP = sign1 ^ sign2; + bool infP = inf1 || inf2; bool zeroP = zero1 || zero2; if ((inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP)) @@ -2765,8 +2800,10 @@ public static double FPMulX(double value1, double value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -2841,21 +2878,18 @@ public static double FPRecipEstimateFpscr(double value, bool standardFpscr) } else if (Math.Abs(value) < Math.Pow(2d, -1024)) { - bool overflowToInf; - - switch (fpcr.GetRoundingMode()) + var overflowToInf = fpcr.GetRoundingMode() switch { - default: - case FPRoundingMode.ToNearest: overflowToInf = true; break; - case FPRoundingMode.TowardsPlusInfinity: overflowToInf = !sign; break; - case FPRoundingMode.TowardsMinusInfinity: overflowToInf = sign; break; - case FPRoundingMode.TowardsZero: overflowToInf = false; break; - } - + FPRoundingMode.ToNearest => true, + FPRoundingMode.TowardsPlusInfinity => !sign, + FPRoundingMode.TowardsMinusInfinity => sign, + FPRoundingMode.TowardsZero => false, + _ => throw new ArgumentException($"Invalid rounding mode \"{fpcr.GetRoundingMode()}\"."), + }; result = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign); SoftFloat.FPProcessException(FPException.Overflow, context, fpcr); - SoftFloat.FPProcessException(FPException.Inexact, context, fpcr); + SoftFloat.FPProcessException(FPException.Inexact, context, fpcr); } else if ((fpcr & FPCR.Fz) != 0 && (Math.Abs(value) >= Math.Pow(2d, 1022))) { @@ -2911,15 +2945,17 @@ public static double FPRecipStep(double value1, double value2) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.StandardFpcrValue; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out ulong op2, context, fpcr); double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; double product; @@ -2952,8 +2988,10 @@ public static double FPRecipStepFused(double value1, double value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -3084,8 +3122,10 @@ public static double FPHalvedSub(double value1, double value2, ExecutionContext if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == sign2) { @@ -3126,15 +3166,17 @@ public static double FPRSqrtStep(double value1, double value2) ExecutionContext context = NativeInterface.GetContext(); FPCR fpcr = context.StandardFpcrValue; - value1 = value1.FPUnpack(out FPType type1, out bool sign1, out ulong op1, context, fpcr); - value2 = value2.FPUnpack(out FPType type2, out bool sign2, out ulong op2, context, fpcr); + value1 = value1.FPUnpack(out FPType type1, out _, out ulong op1, context, fpcr); + value2 = value2.FPUnpack(out FPType type2, out _, out ulong op2, context, fpcr); double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, context, fpcr); if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; double product; @@ -3167,8 +3209,10 @@ public static double FPRSqrtStepFused(double value1, double value2) if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if ((inf1 && zero2) || (zero1 && inf2)) { @@ -3253,8 +3297,10 @@ public static double FPSubFpscr(double value1, double value2, bool standardFpscr if (!done) { - bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero; - bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero; + bool inf1 = type1 == FPType.Infinity; + bool zero1 = type1 == FPType.Zero; + bool inf2 = type2 == FPType.Infinity; + bool zero2 = type2 == FPType.Zero; if (inf1 && inf2 && sign1 == sign2) { @@ -3351,7 +3397,7 @@ private static double FPUnpack( { if ((valueBits & 0x000FFFFFFFFFFFFFul) == 0ul || (fpcr & FPCR.Fz) != 0) { - type = FPType.Zero; + type = FPType.Zero; value = FPZero(sign); if ((valueBits & 0x000FFFFFFFFFFFFFul) != 0ul) @@ -3372,7 +3418,7 @@ private static double FPUnpack( } else { - type = (~valueBits & 0x0008000000000000ul) == 0ul ? FPType.QNaN : FPType.SNaN; + type = (~valueBits & 0x0008000000000000ul) == 0ul ? FPType.QNaN : FPType.SNaN; value = FPZero(sign); } } diff --git a/src/ARMeilleure/IntermediateRepresentation/BasicBlock.cs b/src/ARMeilleure/IntermediateRepresentation/BasicBlock.cs index 07bd8b672..810461d7c 100644 --- a/src/ARMeilleure/IntermediateRepresentation/BasicBlock.cs +++ b/src/ARMeilleure/IntermediateRepresentation/BasicBlock.cs @@ -10,7 +10,7 @@ class BasicBlock : IEquatable, IIntrusiveListNode private int _succCount; private BasicBlock _succ0; - private BasicBlock _succ1; + private readonly BasicBlock _succ1; private HashSet _domFrontiers; public int Index { get; set; } @@ -27,10 +27,7 @@ public HashSet DominanceFrontiers { get { - if (_domFrontiers == null) - { - _domFrontiers = new HashSet(); - } + _domFrontiers ??= new HashSet(); return _domFrontiers; } @@ -108,7 +105,7 @@ public void SetSuccessor(int index, BasicBlock block) oldBlock.Predecessors.Remove(this); block.Predecessors.Add(this); - + oldBlock = block; } @@ -156,4 +153,4 @@ public override int GetHashCode() return base.GetHashCode(); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs b/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs index 96cfee35a..e4f7ae809 100644 --- a/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs +++ b/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs @@ -1,8 +1,8 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { enum BasicBlockFrequency { Default, - Cold + Cold, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/Comparison.cs b/src/ARMeilleure/IntermediateRepresentation/Comparison.cs index 628ce1051..3d6a9d818 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Comparison.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Comparison.cs @@ -1,17 +1,17 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { enum Comparison { - Equal = 0, - NotEqual = 1, - Greater = 2, - LessOrEqual = 3, - GreaterUI = 4, - LessOrEqualUI = 5, - GreaterOrEqual = 6, - Less = 7, - GreaterOrEqualUI = 8, - LessUI = 9 + Equal = 0, + NotEqual = 1, + Greater = 2, + LessOrEqual = 3, + GreaterUI = 4, + LessOrEqualUI = 5, + GreaterOrEqual = 6, + Less = 7, + GreaterOrEqualUI = 8, + LessUI = 9, } static class ComparisonExtensions diff --git a/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs b/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs index caa9b83fe..05be8a5ae 100644 --- a/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs +++ b/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { interface IIntrusiveListNode { diff --git a/src/ARMeilleure/IntermediateRepresentation/Instruction.cs b/src/ARMeilleure/IntermediateRepresentation/Instruction.cs index b55fe1dac..9bae8d1fb 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Instruction.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Instruction.cs @@ -67,6 +67,6 @@ enum Instruction : ushort Phi, Spill, SpillArg, - StoreToContext + StoreToContext, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs b/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs index f5a776fa2..b9cab6674 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs @@ -1,5 +1,10 @@ +using System; +using System.Diagnostics.CodeAnalysis; + namespace ARMeilleure.IntermediateRepresentation { + [Flags] + [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")] enum Intrinsic : ushort { // X86 (SSE and AVX) @@ -631,6 +636,6 @@ enum Intrinsic : ushort Arm64VByte = 0 << Arm64VSizeShift, Arm64VHWord = 1 << Arm64VSizeShift, Arm64VWord = 2 << Arm64VSizeShift, - Arm64VDWord = 3 << Arm64VSizeShift + Arm64VDWord = 3 << Arm64VSizeShift, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs b/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs index 184df87c8..8d300075d 100644 --- a/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs +++ b/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs b/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs index 07d2633b4..9b3df8ca4 100644 --- a/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs +++ b/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs @@ -4,11 +4,11 @@ namespace ARMeilleure.IntermediateRepresentation { - unsafe struct MemoryOperand + readonly unsafe struct MemoryOperand { private struct Data { -#pragma warning disable CS0649 +#pragma warning disable CS0649 // Field is never assigned to public byte Kind; public byte Type; #pragma warning restore CS0649 @@ -18,7 +18,7 @@ private struct Data public int Displacement; } - private Data* _data; + private readonly Data* _data; public MemoryOperand(Operand operand) { @@ -30,13 +30,13 @@ public MemoryOperand(Operand operand) public Operand BaseAddress { get => _data->BaseAddress; - set => _data->BaseAddress = value; + set => _data->BaseAddress = value; } public Operand Index { get => _data->Index; - set => _data->Index = value; + set => _data->Index = value; } public Multiplier Scale @@ -51,4 +51,4 @@ public int Displacement set => _data->Displacement = value; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/Multiplier.cs b/src/ARMeilleure/IntermediateRepresentation/Multiplier.cs index d6bc7d994..6bcdda014 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Multiplier.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Multiplier.cs @@ -6,6 +6,6 @@ enum Multiplier x2 = 1, x4 = 2, x8 = 3, - x16 = 4 + x16 = 4, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/Operand.cs b/src/ARMeilleure/IntermediateRepresentation/Operand.cs index 9e8de3ba4..89aefacb1 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Operand.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Operand.cs @@ -27,25 +27,25 @@ internal struct Data private Data* _data; - public OperandKind Kind + public readonly OperandKind Kind { get => (OperandKind)_data->Kind; private set => _data->Kind = (byte)value; } - public OperandType Type + public readonly OperandType Type { get => (OperandType)_data->Type; private set => _data->Type = (byte)value; } - public ulong Value + public readonly ulong Value { get => _data->Value; private set => _data->Value = value; } - public Symbol Symbol + public readonly Symbol Symbol { get { @@ -69,7 +69,7 @@ private set } } - public ReadOnlySpan Assignments + public readonly ReadOnlySpan Assignments { get { @@ -79,7 +79,7 @@ public ReadOnlySpan Assignments } } - public ReadOnlySpan Uses + public readonly ReadOnlySpan Uses { get { @@ -89,13 +89,13 @@ public ReadOnlySpan Uses } } - public int UsesCount => (int)_data->UsesCount; - public int AssignmentsCount => _data->AssignmentsCount; + public readonly int UsesCount => (int)_data->UsesCount; + public readonly int AssignmentsCount => _data->AssignmentsCount; - public bool Relocatable => Symbol.Type != SymbolType.None; + public readonly bool Relocatable => Symbol.Type != SymbolType.None; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Register GetRegister() + public readonly Register GetRegister() { Debug.Assert(Kind == OperandKind.Register); @@ -103,52 +103,52 @@ public Register GetRegister() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MemoryOperand GetMemory() + public readonly MemoryOperand GetMemory() { Debug.Assert(Kind == OperandKind.Memory); return new MemoryOperand(this); } - public int GetLocalNumber() + public readonly int GetLocalNumber() { Debug.Assert(Kind == OperandKind.LocalVariable); return (int)Value; } - public byte AsByte() + public readonly byte AsByte() { return (byte)Value; } - public short AsInt16() + public readonly short AsInt16() { return (short)Value; } - public int AsInt32() + public readonly int AsInt32() { return (int)Value; } - public long AsInt64() + public readonly long AsInt64() { return (long)Value; } - public float AsFloat() + public readonly float AsFloat() { return BitConverter.Int32BitsToSingle((int)Value); } - public double AsDouble() + public readonly double AsDouble() { return BitConverter.Int64BitsToDouble((long)Value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal ref ulong GetValueUnsafe() + internal readonly ref ulong GetValueUnsafe() { return ref _data->Value; } @@ -163,7 +163,7 @@ internal void NumberLocal(int number) Value = (ulong)number; } - public void AddAssignment(Operation operation) + public readonly void AddAssignment(Operation operation) { if (Kind == OperandKind.LocalVariable) { @@ -187,7 +187,7 @@ public void AddAssignment(Operation operation) } } - public void RemoveAssignment(Operation operation) + public readonly void RemoveAssignment(Operation operation) { if (Kind == OperandKind.LocalVariable) { @@ -211,7 +211,7 @@ public void RemoveAssignment(Operation operation) } } - public void AddUse(Operation operation) + public readonly void AddUse(Operation operation) { if (Kind == OperandKind.LocalVariable) { @@ -235,7 +235,7 @@ public void AddUse(Operation operation) } } - public void RemoveUse(Operation operation) + public readonly void RemoveUse(Operation operation) { if (Kind == OperandKind.LocalVariable) { @@ -259,7 +259,7 @@ public void RemoveUse(Operation operation) } } - public Span GetUses(ref Span buffer) + public readonly Span GetUses(ref Span buffer) { ReadOnlySpan uses = Uses; @@ -270,7 +270,7 @@ public Span GetUses(ref Span buffer) uses.CopyTo(buffer); - return buffer.Slice(0, uses.Length); + return buffer[..uses.Length]; } private static void New(ref T* data, ref ushort count, ref ushort capacity, ushort initialCapacity) where T : unmanaged @@ -360,7 +360,7 @@ private static void Remove(in T item, ref T* data, ref ushort count) where T { if (i + 1 < count) { - span.Slice(i + 1).CopyTo(span.Slice(i)); + span[(i + 1)..].CopyTo(span[i..]); } count--; @@ -380,7 +380,7 @@ private static void Remove(in T item, ref T* data, ref uint count) where T : { if (i + 1 < count) { - span.Slice(i + 1).CopyTo(span.Slice(i)); + span[(i + 1)..].CopyTo(span[i..]); } count--; @@ -390,17 +390,17 @@ private static void Remove(in T item, ref T* data, ref uint count) where T : } } - public override int GetHashCode() + public readonly override int GetHashCode() { return ((ulong)_data).GetHashCode(); } - public bool Equals(Operand operand) + public readonly bool Equals(Operand operand) { return operand._data == _data; } - public override bool Equals(object obj) + public readonly override bool Equals(object obj) { return obj is Operand operand && Equals(operand); } @@ -453,8 +453,10 @@ private static Operand Make(OperandKind kind, OperandType type, ulong value, Sym // Look in the next InternTableProbeLength slots for a match. for (uint i = 0; i < InternTableProbeLength; i++) { - Operand interned = new(); - interned._data = &InternTable[(hash + i) % InternTableSize]; + Operand interned = new() + { + _data = &InternTable[(hash + i) % InternTableSize], + }; // If slot matches the allocation request then return that slot. if (interned.Kind == kind && interned.Type == type && interned.Value == value && interned.Symbol == symbol) @@ -479,11 +481,13 @@ private static Operand Make(OperandKind kind, OperandType type, ulong value, Sym *data = default; - Operand result = new(); - result._data = data; - result.Value = value; - result.Kind = kind; - result.Type = type; + Operand result = new() + { + _data = data, + Value = value, + Kind = kind, + Type = type, + }; if (kind != OperandKind.Memory) { @@ -591,4 +595,4 @@ public static Operand MemoryOp( } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/OperandKind.cs b/src/ARMeilleure/IntermediateRepresentation/OperandKind.cs index adb835614..2b973f006 100644 --- a/src/ARMeilleure/IntermediateRepresentation/OperandKind.cs +++ b/src/ARMeilleure/IntermediateRepresentation/OperandKind.cs @@ -8,6 +8,6 @@ enum OperandKind LocalVariable, Memory, Register, - Undefined + Undefined, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/OperandType.cs b/src/ARMeilleure/IntermediateRepresentation/OperandType.cs index 81b22cf56..67ebdcde4 100644 --- a/src/ARMeilleure/IntermediateRepresentation/OperandType.cs +++ b/src/ARMeilleure/IntermediateRepresentation/OperandType.cs @@ -9,7 +9,7 @@ enum OperandType I64, FP32, FP64, - V128 + V128, } static class OperandTypeExtensions @@ -22,44 +22,41 @@ public static bool IsInteger(this OperandType type) public static RegisterType ToRegisterType(this OperandType type) { - switch (type) + return type switch { - case OperandType.FP32: return RegisterType.Vector; - case OperandType.FP64: return RegisterType.Vector; - case OperandType.I32: return RegisterType.Integer; - case OperandType.I64: return RegisterType.Integer; - case OperandType.V128: return RegisterType.Vector; - } - - throw new InvalidOperationException($"Invalid operand type \"{type}\"."); + OperandType.FP32 => RegisterType.Vector, + OperandType.FP64 => RegisterType.Vector, + OperandType.I32 => RegisterType.Integer, + OperandType.I64 => RegisterType.Integer, + OperandType.V128 => RegisterType.Vector, + _ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."), + }; } public static int GetSizeInBytes(this OperandType type) { - switch (type) + return type switch { - case OperandType.FP32: return 4; - case OperandType.FP64: return 8; - case OperandType.I32: return 4; - case OperandType.I64: return 8; - case OperandType.V128: return 16; - } - - throw new InvalidOperationException($"Invalid operand type \"{type}\"."); + OperandType.FP32 => 4, + OperandType.FP64 => 8, + OperandType.I32 => 4, + OperandType.I64 => 8, + OperandType.V128 => 16, + _ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."), + }; } public static int GetSizeInBytesLog2(this OperandType type) { - switch (type) + return type switch { - case OperandType.FP32: return 2; - case OperandType.FP64: return 3; - case OperandType.I32: return 2; - case OperandType.I64: return 3; - case OperandType.V128: return 4; - } - - throw new InvalidOperationException($"Invalid operand type \"{type}\"."); + OperandType.FP32 => 2, + OperandType.FP64 => 3, + OperandType.I32 => 2, + OperandType.I64 => 3, + OperandType.V128 => 4, + _ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."), + }; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/Operation.cs b/src/ARMeilleure/IntermediateRepresentation/Operation.cs index c71e143c3..bc3a71b31 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Operation.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Operation.cs @@ -20,60 +20,60 @@ internal struct Data private Data* _data; - public Instruction Instruction + public readonly Instruction Instruction { get => (Instruction)_data->Instruction; private set => _data->Instruction = (ushort)value; } - public Intrinsic Intrinsic + public readonly Intrinsic Intrinsic { get => (Intrinsic)_data->Intrinsic; private set => _data->Intrinsic = (ushort)value; } - public Operation ListPrevious + public readonly Operation ListPrevious { get => _data->ListPrevious; set => _data->ListPrevious = value; } - public Operation ListNext + public readonly Operation ListNext { get => _data->ListNext; set => _data->ListNext = value; } - public Operand Destination + public readonly Operand Destination { get => _data->DestinationsCount != 0 ? GetDestination(0) : default; set => SetDestination(value); } - public int DestinationsCount => _data->DestinationsCount; - public int SourcesCount => _data->SourcesCount; + public readonly int DestinationsCount => _data->DestinationsCount; + public readonly int SourcesCount => _data->SourcesCount; - internal Span DestinationsUnsafe => new(_data->Destinations, _data->DestinationsCount); - internal Span SourcesUnsafe => new(_data->Sources, _data->SourcesCount); + internal readonly Span DestinationsUnsafe => new(_data->Destinations, _data->DestinationsCount); + internal readonly Span SourcesUnsafe => new(_data->Sources, _data->SourcesCount); - public PhiOperation AsPhi() + public readonly PhiOperation AsPhi() { Debug.Assert(Instruction == Instruction.Phi); return new PhiOperation(this); } - public Operand GetDestination(int index) + public readonly Operand GetDestination(int index) { return DestinationsUnsafe[index]; } - public Operand GetSource(int index) + public readonly Operand GetSource(int index) { return SourcesUnsafe[index]; } - public void SetDestination(int index, Operand dest) + public readonly void SetDestination(int index, Operand dest) { ref Operand curDest = ref DestinationsUnsafe[index]; @@ -83,7 +83,7 @@ public void SetDestination(int index, Operand dest) curDest = dest; } - public void SetSource(int index, Operand src) + public readonly void SetSource(int index, Operand src) { ref Operand curSrc = ref SourcesUnsafe[index]; @@ -93,7 +93,7 @@ public void SetSource(int index, Operand src) curSrc = src; } - private void RemoveOldDestinations() + private readonly void RemoveOldDestinations() { for (int i = 0; i < _data->DestinationsCount; i++) { @@ -101,7 +101,7 @@ private void RemoveOldDestinations() } } - public void SetDestination(Operand dest) + public readonly void SetDestination(Operand dest) { RemoveOldDestinations(); @@ -119,7 +119,7 @@ public void SetDestination(Operand dest) } } - public void SetDestinations(Operand[] dests) + public readonly void SetDestinations(Operand[] dests) { RemoveOldDestinations(); @@ -135,7 +135,7 @@ public void SetDestinations(Operand[] dests) } } - private void RemoveOldSources() + private readonly void RemoveOldSources() { for (int index = 0; index < _data->SourcesCount; index++) { @@ -143,7 +143,7 @@ private void RemoveOldSources() } } - public void SetSource(Operand src) + public readonly void SetSource(Operand src) { RemoveOldSources(); @@ -161,7 +161,7 @@ public void SetSource(Operand src) } } - public void SetSources(Operand[] srcs) + public readonly void SetSources(Operand[] srcs) { RemoveOldSources(); @@ -184,7 +184,7 @@ public void TurnIntoCopy(Operand source) SetSource(source); } - private void AddAssignment(Operand op) + private readonly void AddAssignment(Operand op) { if (op != default) { @@ -192,7 +192,7 @@ private void AddAssignment(Operand op) } } - private void RemoveAssignment(Operand op) + private readonly void RemoveAssignment(Operand op) { if (op != default) { @@ -200,7 +200,7 @@ private void RemoveAssignment(Operand op) } } - private void AddUse(Operand op) + private readonly void AddUse(Operand op) { if (op != default) { @@ -208,7 +208,7 @@ private void AddUse(Operand op) } } - private void RemoveUse(Operand op) + private readonly void RemoveUse(Operand op) { if (op != default) { @@ -216,17 +216,17 @@ private void RemoveUse(Operand op) } } - public bool Equals(Operation operation) + public readonly bool Equals(Operation operation) { return operation._data == _data; } - public override bool Equals(object obj) + public readonly override bool Equals(object obj) { return obj is Operation operation && Equals(operation); } - public override int GetHashCode() + public readonly override int GetHashCode() { return HashCode.Combine((IntPtr)_data); } @@ -267,9 +267,11 @@ private static Operation Make(Instruction inst, int destCount, int srcCount) Data* data = Allocators.Operations.Allocate(); *data = default; - Operation result = new(); - result._data = data; - result.Instruction = inst; + Operation result = new() + { + _data = data, + Instruction = inst, + }; EnsureCapacity(ref result._data->Destinations, ref result._data->DestinationsCount, destCount); EnsureCapacity(ref result._data->Sources, ref result._data->SourcesCount, srcCount); @@ -373,4 +375,4 @@ public static Operation PhiOperation(Operand dest, int srcCount) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs b/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs index d2a3cf218..672c280fa 100644 --- a/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs +++ b/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Translation; +using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.IntermediateRepresentation diff --git a/src/ARMeilleure/IntermediateRepresentation/Register.cs b/src/ARMeilleure/IntermediateRepresentation/Register.cs index 241e4d13d..208f94be1 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Register.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Register.cs @@ -11,7 +11,7 @@ namespace ARMeilleure.IntermediateRepresentation public Register(int index, RegisterType type) { Index = index; - Type = type; + Type = type; } public override int GetHashCode() @@ -37,7 +37,7 @@ public override bool Equals(object obj) public bool Equals(Register other) { return other.Index == Index && - other.Type == Type; + other.Type == Type; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/IntermediateRepresentation/RegisterType.cs b/src/ARMeilleure/IntermediateRepresentation/RegisterType.cs index 88ac6c124..2b4c9068c 100644 --- a/src/ARMeilleure/IntermediateRepresentation/RegisterType.cs +++ b/src/ARMeilleure/IntermediateRepresentation/RegisterType.cs @@ -5,6 +5,6 @@ enum RegisterType Integer, Vector, Flag, - FpFlag + FpFlag, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Memory/IJitMemoryAllocator.cs b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs index 19b696b0a..ff64bf13e 100644 --- a/src/ARMeilleure/Memory/IJitMemoryAllocator.cs +++ b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs @@ -1,10 +1,8 @@ -namespace ARMeilleure.Memory +namespace ARMeilleure.Memory { public interface IJitMemoryAllocator { IJitMemoryBlock Allocate(ulong size); IJitMemoryBlock Reserve(ulong size); - - ulong GetPageSize(); } } diff --git a/src/ARMeilleure/Memory/IJitMemoryBlock.cs b/src/ARMeilleure/Memory/IJitMemoryBlock.cs index 670f2862d..c103fe8d1 100644 --- a/src/ARMeilleure/Memory/IJitMemoryBlock.cs +++ b/src/ARMeilleure/Memory/IJitMemoryBlock.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Memory { @@ -6,8 +6,9 @@ public interface IJitMemoryBlock : IDisposable { IntPtr Pointer { get; } - bool Commit(ulong offset, ulong size); + void Commit(ulong offset, ulong size); + void MapAsRw(ulong offset, ulong size); void MapAsRx(ulong offset, ulong size); void MapAsRwx(ulong offset, ulong size); } diff --git a/src/ARMeilleure/Memory/IMemoryManager.cs b/src/ARMeilleure/Memory/IMemoryManager.cs index 5eb1fadd6..952cd2b4f 100644 --- a/src/ARMeilleure/Memory/IMemoryManager.cs +++ b/src/ARMeilleure/Memory/IMemoryManager.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Memory { @@ -74,4 +74,4 @@ public interface IMemoryManager /// Optional ID of the handles that should not be signalled void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Memory/MemoryManagerType.cs b/src/ARMeilleure/Memory/MemoryManagerType.cs index ce84ccaf3..b1cdbb069 100644 --- a/src/ARMeilleure/Memory/MemoryManagerType.cs +++ b/src/ARMeilleure/Memory/MemoryManagerType.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Memory +namespace ARMeilleure.Memory { /// /// Indicates the type of a memory manager and the method it uses for memory mapping @@ -28,10 +28,10 @@ public enum MemoryManagerType /// Same as the host mapped memory manager type, but without masking the address within the address space. /// Allows invalid access from JIT code to the rest of the program, but is faster. /// - HostMappedUnsafe + HostMappedUnsafe, } - static class MemoryManagerTypeExtensions + public static class MemoryManagerTypeExtensions { public static bool IsHostMapped(this MemoryManagerType type) { diff --git a/src/ARMeilleure/Memory/ReservedRegion.cs b/src/ARMeilleure/Memory/ReservedRegion.cs index 2197afad9..3870d4c84 100644 --- a/src/ARMeilleure/Memory/ReservedRegion.cs +++ b/src/ARMeilleure/Memory/ReservedRegion.cs @@ -1,8 +1,8 @@ -using System; +using System; namespace ARMeilleure.Memory { - class ReservedRegion + public class ReservedRegion { public const int DefaultGranularity = 65536; // Mapping granularity in Windows. diff --git a/src/ARMeilleure/Native/JitSupportDarwin.cs b/src/ARMeilleure/Native/JitSupportDarwin.cs index 7d6a8634a..339460397 100644 --- a/src/ARMeilleure/Native/JitSupportDarwin.cs +++ b/src/ARMeilleure/Native/JitSupportDarwin.cs @@ -5,7 +5,7 @@ namespace ARMeilleure.Native { [SupportedOSPlatform("macos")] - public static partial class JitSupportDarwin + static partial class JitSupportDarwin { [LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")] public static partial void Copy(IntPtr dst, IntPtr src, ulong n); diff --git a/src/ARMeilleure/Optimizations.cs b/src/ARMeilleure/Optimizations.cs index a84a4dc4f..8fe478e47 100644 --- a/src/ARMeilleure/Optimizations.cs +++ b/src/ARMeilleure/Optimizations.cs @@ -1,5 +1,3 @@ -using System.Runtime.Intrinsics.Arm; - namespace ARMeilleure { using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities; @@ -9,30 +7,31 @@ public static class Optimizations { public static bool FastFP { get; set; } = true; - public static bool AllowLcqInFunctionTable { get; set; } = true; + public static bool AllowLcqInFunctionTable { get; set; } = true; public static bool UseUnmanagedDispatchLoop { get; set; } = true; - public static bool UseAdvSimdIfAvailable { get; set; } = true; + public static bool UseAdvSimdIfAvailable { get; set; } = true; + public static bool UseArm64AesIfAvailable { get; set; } = true; public static bool UseArm64PmullIfAvailable { get; set; } = true; - public static bool UseSseIfAvailable { get; set; } = true; - public static bool UseSse2IfAvailable { get; set; } = true; - public static bool UseSse3IfAvailable { get; set; } = true; - public static bool UseSsse3IfAvailable { get; set; } = true; - public static bool UseSse41IfAvailable { get; set; } = true; - public static bool UseSse42IfAvailable { get; set; } = true; - public static bool UsePopCntIfAvailable { get; set; } = true; - public static bool UseAvxIfAvailable { get; set; } = true; - public static bool UseAvx512FIfAvailable { get; set; } = true; - public static bool UseAvx512VlIfAvailable { get; set; } = true; - public static bool UseAvx512BwIfAvailable { get; set; } = true; - public static bool UseAvx512DqIfAvailable { get; set; } = true; - public static bool UseF16cIfAvailable { get; set; } = true; - public static bool UseFmaIfAvailable { get; set; } = true; - public static bool UseAesniIfAvailable { get; set; } = true; + public static bool UseSseIfAvailable { get; set; } = true; + public static bool UseSse2IfAvailable { get; set; } = true; + public static bool UseSse3IfAvailable { get; set; } = true; + public static bool UseSsse3IfAvailable { get; set; } = true; + public static bool UseSse41IfAvailable { get; set; } = true; + public static bool UseSse42IfAvailable { get; set; } = true; + public static bool UsePopCntIfAvailable { get; set; } = true; + public static bool UseAvxIfAvailable { get; set; } = true; + public static bool UseAvx512FIfAvailable { get; set; } = true; + public static bool UseAvx512VlIfAvailable { get; set; } = true; + public static bool UseAvx512BwIfAvailable { get; set; } = true; + public static bool UseAvx512DqIfAvailable { get; set; } = true; + public static bool UseF16cIfAvailable { get; set; } = true; + public static bool UseFmaIfAvailable { get; set; } = true; + public static bool UseAesniIfAvailable { get; set; } = true; public static bool UsePclmulqdqIfAvailable { get; set; } = true; - public static bool UseShaIfAvailable { get; set; } = true; - public static bool UseGfniIfAvailable { get; set; } = true; + public static bool UseShaIfAvailable { get; set; } = true; + public static bool UseGfniIfAvailable { get; set; } = true; public static bool ForceLegacySse { @@ -40,7 +39,9 @@ public static bool ForceLegacySse set => X86HardwareCapabilities.ForceLegacySse = value; } +#pragma warning disable IDE0055 // Disable formatting internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd; + internal static bool UseArm64Aes => UseArm64AesIfAvailable && Arm64HardwareCapabilities.SupportsAes; internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull; internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse; @@ -61,6 +62,7 @@ public static bool ForceLegacySse internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && X86HardwareCapabilities.SupportsPclmulqdq; internal static bool UseSha => UseShaIfAvailable && X86HardwareCapabilities.SupportsSha; internal static bool UseGfni => UseGfniIfAvailable && X86HardwareCapabilities.SupportsGfni; +#pragma warning restore IDE0055 internal static bool UseAvx512Ortho => UseAvx512F && UseAvx512Vl; internal static bool UseAvx512OrthoFloat => UseAvx512Ortho && UseAvx512Dq; diff --git a/src/ARMeilleure/Signal/NativeSignalHandler.cs b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs similarity index 57% rename from src/ARMeilleure/Signal/NativeSignalHandler.cs rename to src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs index cddeb8174..c5e708e16 100644 --- a/src/ARMeilleure/Signal/NativeSignalHandler.cs +++ b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs @@ -1,64 +1,14 @@ -using ARMeilleure.IntermediateRepresentation; -using ARMeilleure.Memory; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using ARMeilleure.Translation.Cache; using System; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.Signal { - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SignalHandlerRange - { - public int IsActive; - public nuint RangeAddress; - public nuint RangeEndAddress; - public IntPtr ActionPointer; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SignalHandlerConfig + public static class NativeSignalHandlerGenerator { - /// - /// The byte offset of the faulting address in the SigInfo or ExceptionRecord struct. - /// - public int StructAddressOffset; - - /// - /// The byte offset of the write flag in the SigInfo or ExceptionRecord struct. - /// - public int StructWriteOffset; - - /// - /// The sigaction handler that was registered before this one. (unix only) - /// - public nuint UnixOldSigaction; - - /// - /// The type of the previous sigaction. True for the 3 argument variant. (unix only) - /// - public int UnixOldSigaction3Arg; - - public SignalHandlerRange Range0; - public SignalHandlerRange Range1; - public SignalHandlerRange Range2; - public SignalHandlerRange Range3; - public SignalHandlerRange Range4; - public SignalHandlerRange Range5; - public SignalHandlerRange Range6; - public SignalHandlerRange Range7; - } - - public static class NativeSignalHandler - { - private delegate void UnixExceptionHandler(int sig, IntPtr info, IntPtr ucontext); - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - private delegate int VectoredExceptionHandler(IntPtr exceptionInfo); - - private const int MaxTrackedRanges = 8; + public const int MaxTrackedRanges = 8; private const int StructAddressOffset = 0; private const int StructWriteOffset = 4; @@ -71,119 +21,10 @@ public static class NativeSignalHandler private const uint EXCEPTION_ACCESS_VIOLATION = 0xc0000005; - private static ulong _pageSize; - private static ulong _pageMask; - - private static IntPtr _handlerConfig; - private static IntPtr _signalHandlerPtr; - private static IntPtr _signalHandlerHandle; - - private static readonly object _lock = new object(); - private static bool _initialized; - - static NativeSignalHandler() - { - _handlerConfig = Marshal.AllocHGlobal(Unsafe.SizeOf()); - ref SignalHandlerConfig config = ref GetConfigRef(); - - config = new SignalHandlerConfig(); - } - - public static void Initialize(IJitMemoryAllocator allocator) - { - JitCache.Initialize(allocator); - } - - public static void InitializeSignalHandler(ulong pageSize, Func customSignalHandlerFactory = null) - { - if (_initialized) return; - - lock (_lock) - { - if (_initialized) return; - - _pageSize = pageSize; - _pageMask = pageSize - 1; - - ref SignalHandlerConfig config = ref GetConfigRef(); - - if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) - { - _signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateUnixSignalHandler(_handlerConfig)); - - if (customSignalHandlerFactory != null) - { - _signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr); - } - - var old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); - - config.UnixOldSigaction = (nuint)(ulong)old.sa_handler; - config.UnixOldSigaction3Arg = old.sa_flags & 4; - } - else - { - config.StructAddressOffset = 40; // ExceptionInformation1 - config.StructWriteOffset = 32; // ExceptionInformation0 - - _signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateWindowsSignalHandler(_handlerConfig)); - - if (customSignalHandlerFactory != null) - { - _signalHandlerPtr = customSignalHandlerFactory(IntPtr.Zero, _signalHandlerPtr); - } - - _signalHandlerHandle = WindowsSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); - } - - _initialized = true; - } - } - - private static unsafe ref SignalHandlerConfig GetConfigRef() - { - return ref Unsafe.AsRef((void*)_handlerConfig); - } - - public static unsafe bool AddTrackedRegion(nuint address, nuint endAddress, IntPtr action) - { - var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0; - - for (int i = 0; i < MaxTrackedRanges; i++) - { - if (ranges[i].IsActive == 0) - { - ranges[i].RangeAddress = address; - ranges[i].RangeEndAddress = endAddress; - ranges[i].ActionPointer = action; - ranges[i].IsActive = 1; - - return true; - } - } - - return false; - } - - public static unsafe bool RemoveTrackedRegion(nuint address) + private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite, int rangeStructSize, ulong pageSize) { - var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0; - - for (int i = 0; i < MaxTrackedRanges; i++) - { - if (ranges[i].IsActive == 1 && ranges[i].RangeAddress == address) - { - ranges[i].IsActive = 0; + ulong pageMask = pageSize - 1; - return true; - } - } - - return false; - } - - private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite) - { Operand inRegionLocal = context.AllocateLocal(OperandType.I32); context.Copy(inRegionLocal, Const(0)); @@ -191,7 +32,7 @@ private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr sig for (int i = 0; i < MaxTrackedRanges; i++) { - ulong rangeBaseOffset = (ulong)(RangeOffset + i * Unsafe.SizeOf()); + ulong rangeBaseOffset = (ulong)(RangeOffset + i * rangeStructSize); Operand nextLabel = Label(); @@ -205,13 +46,12 @@ private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr sig // Is the fault address within this tracked region? Operand inRange = context.BitwiseAnd( context.ICompare(faultAddress, rangeAddress, Comparison.GreaterOrEqualUI), - context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI) - ); + context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI)); // Only call tracking if in range. context.BranchIfFalse(nextLabel, inRange, BasicBlockFrequency.Cold); - Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~_pageMask)); + Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~pageMask)); // Call the tracking action, with the pointer's relative offset to the base address. Operand trackingActionPtr = context.Load(OperandType.I64, Const((ulong)signalStructPtr + rangeBaseOffset + 20)); @@ -222,7 +62,7 @@ private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr sig // Tracking action should be non-null to call it, otherwise assume false return. context.BranchIfFalse(skipActionLabel, trackingActionPtr); - Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(_pageSize), isWrite); + Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(pageSize), isWrite); context.Copy(inRegionLocal, result); context.MarkLabel(skipActionLabel); @@ -255,20 +95,19 @@ private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand uco { if (OperatingSystem.IsMacOS()) { - const ulong mcontextOffset = 48; // uc_mcontext - Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(mcontextOffset))); + const ulong McontextOffset = 48; // uc_mcontext + Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(McontextOffset))); if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) { - const ulong esrOffset = 8; // __es.__esr - Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(esrOffset))); + const ulong EsrOffset = 8; // __es.__esr + Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(EsrOffset))); return context.BitwiseAnd(esr, Const(0x40ul)); } - - if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + else if (RuntimeInformation.ProcessArchitecture == Architecture.X64) { - const ulong errOffset = 4; // __es.__err - Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(errOffset))); + const ulong ErrOffset = 4; // __es.__err + Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(ErrOffset))); return context.BitwiseAnd(err, Const(2ul)); } } @@ -281,10 +120,10 @@ private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand uco Operand loopLabel = Label(); Operand successLabel = Label(); - const ulong auxOffset = 464; // uc_mcontext.__reserved - const uint esrMagic = 0x45535201; + const ulong AuxOffset = 464; // uc_mcontext.__reserved + const uint EsrMagic = 0x45535201; - context.Copy(auxPtr, context.Add(ucontextPtr, Const(auxOffset))); + context.Copy(auxPtr, context.Add(ucontextPtr, Const(AuxOffset))); context.MarkLabel(loopLabel); @@ -293,7 +132,7 @@ private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand uco // _aarch64_ctx::size Operand size = context.Load(OperandType.I32, context.Add(auxPtr, Const(4ul))); - context.BranchIf(successLabel, magic, Const(esrMagic), Comparison.Equal); + context.BranchIf(successLabel, magic, Const(EsrMagic), Comparison.Equal); context.Copy(auxPtr, context.Add(auxPtr, context.ZeroExtend32(OperandType.I64, size))); @@ -305,11 +144,10 @@ private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand uco Operand esr = context.Load(OperandType.I64, context.Add(auxPtr, Const(8ul))); return context.BitwiseAnd(esr, Const(0x40ul)); } - - if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + else if (RuntimeInformation.ProcessArchitecture == Architecture.X64) { - const int errOffset = 192; // uc_mcontext.gregs[REG_ERR] - Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(errOffset))); + const int ErrOffset = 192; // uc_mcontext.gregs[REG_ERR] + Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(ErrOffset))); return context.BitwiseAnd(err, Const(2ul)); } } @@ -317,9 +155,9 @@ private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand uco throw new PlatformNotSupportedException(); } - private static UnixExceptionHandler GenerateUnixSignalHandler(IntPtr signalStructPtr) + public static byte[] GenerateUnixSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize) { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); // (int sig, SigInfo* sigInfo, void* ucontext) Operand sigInfoPtr = context.LoadArgument(OperandType.I64, 1); @@ -330,7 +168,7 @@ private static UnixExceptionHandler GenerateUnixSignalHandler(IntPtr signalStruc Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1. - Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite); + Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize); Operand endLabel = Label(); @@ -362,12 +200,12 @@ private static UnixExceptionHandler GenerateUnixSignalHandler(IntPtr signalStruc OperandType[] argTypes = new OperandType[] { OperandType.I32, OperandType.I64, OperandType.I64 }; - return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map(); + return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; } - private static VectoredExceptionHandler GenerateWindowsSignalHandler(IntPtr signalStructPtr) + public static byte[] GenerateWindowsSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize) { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); // (ExceptionPointers* exceptionInfo) Operand exceptionInfoPtr = context.LoadArgument(OperandType.I64, 0); @@ -394,7 +232,7 @@ private static VectoredExceptionHandler GenerateWindowsSignalHandler(IntPtr sign Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1. - Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite); + Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize); Operand endLabel = Label(); @@ -416,7 +254,7 @@ private static VectoredExceptionHandler GenerateWindowsSignalHandler(IntPtr sign OperandType[] argTypes = new OperandType[] { OperandType.I64 }; - return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map(); + return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; } } } diff --git a/src/ARMeilleure/Signal/TestMethods.cs b/src/ARMeilleure/Signal/TestMethods.cs index e2ecad242..0a8b3f5ff 100644 --- a/src/ARMeilleure/Signal/TestMethods.cs +++ b/src/ARMeilleure/Signal/TestMethods.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; using System.Runtime.InteropServices; @@ -20,7 +20,7 @@ public static class TestMethods public static DebugPartialUnmap GenerateDebugPartialUnmap() { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context); @@ -37,7 +37,7 @@ public static DebugPartialUnmap GenerateDebugPartialUnmap() public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrReserve(IntPtr structPtr) { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1)); @@ -54,7 +54,7 @@ public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrRe public static DebugNativeWriteLoop GenerateDebugNativeWriteLoop() { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); // Loop a write to the target address until "running" is false. diff --git a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs index 941e36e58..3bf6a4498 100644 --- a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs +++ b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs @@ -1,8 +1,8 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using Ryujinx.Common.Memory.PartialUnmaps; using System; - +using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.Signal @@ -10,8 +10,28 @@ namespace ARMeilleure.Signal /// /// Methods to handle signals caused by partial unmaps. See the structs for C# implementations of the methods. /// - internal static class WindowsPartialUnmapHandler + internal static partial class WindowsPartialUnmapHandler { + [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] + private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); + + [LibraryImport("kernel32.dll", SetLastError = true)] + private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); + + private static IntPtr _getCurrentThreadIdPtr; + + public static IntPtr GetCurrentThreadIdFunc() + { + if (_getCurrentThreadIdPtr == IntPtr.Zero) + { + IntPtr handle = LoadLibrary("kernel32.dll"); + + _getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId"); + } + + return _getCurrentThreadIdPtr; + } + public static Operand EmitRetryFromAccessViolation(EmitterContext context) { IntPtr partialRemapStatePtr = PartialUnmapState.GlobalState; @@ -20,7 +40,7 @@ public static Operand EmitRetryFromAccessViolation(EmitterContext context) // Get the lock first. EmitNativeReaderLockAcquire(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset)); - IntPtr getCurrentThreadId = WindowsSignalHandlerRegistration.GetCurrentThreadIdFunc(); + IntPtr getCurrentThreadId = GetCurrentThreadIdFunc(); Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32); Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0)); @@ -137,15 +157,6 @@ private static Operand EmitThreadLocalMapIntGetValuePtr(EmitterContext context, return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset)); } - private static void EmitThreadLocalMapIntRelease(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand index) - { - Operand offset = context.Multiply(index, Const(sizeof(int))); - Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap.ThreadIdsOffset)); - Operand idPtr = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset)); - - context.CompareAndSwap(idPtr, threadId, Const(0)); - } - private static void EmitAtomicAddI32(EmitterContext context, Operand ptr, Operand additive) { Operand loop = Label(); diff --git a/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs b/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs deleted file mode 100644 index 3219e015d..000000000 --- a/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace ARMeilleure.Signal -{ - unsafe partial class WindowsSignalHandlerRegistration - { - [LibraryImport("kernel32.dll")] - private static partial IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler); - - [LibraryImport("kernel32.dll")] - private static partial ulong RemoveVectoredExceptionHandler(IntPtr handle); - - [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] - private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); - - [LibraryImport("kernel32.dll", SetLastError = true)] - private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); - - private static IntPtr _getCurrentThreadIdPtr; - - public static IntPtr RegisterExceptionHandler(IntPtr action) - { - return AddVectoredExceptionHandler(1, action); - } - - public static bool RemoveExceptionHandler(IntPtr handle) - { - return RemoveVectoredExceptionHandler(handle) != 0; - } - - public static IntPtr GetCurrentThreadIdFunc() - { - if (_getCurrentThreadIdPtr == IntPtr.Zero) - { - IntPtr handle = LoadLibrary("kernel32.dll"); - - _getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId"); - } - - return _getCurrentThreadIdPtr; - } - } -} diff --git a/src/ARMeilleure/State/Aarch32Mode.cs b/src/ARMeilleure/State/Aarch32Mode.cs index 395e288aa..add1cd26f 100644 --- a/src/ARMeilleure/State/Aarch32Mode.cs +++ b/src/ARMeilleure/State/Aarch32Mode.cs @@ -2,14 +2,14 @@ namespace ARMeilleure.State { enum Aarch32Mode { - User = 0b10000, - Fiq = 0b10001, - Irq = 0b10010, + User = 0b10000, + Fiq = 0b10001, + Irq = 0b10010, Supervisor = 0b10011, - Monitor = 0b10110, - Abort = 0b10111, + Monitor = 0b10110, + Abort = 0b10111, Hypervisor = 0b11010, - Undefined = 0b11011, - System = 0b11111 + Undefined = 0b11011, + System = 0b11111, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/ExceptionCallback.cs b/src/ARMeilleure/State/ExceptionCallback.cs index 38d6eef78..2a4e9656a 100644 --- a/src/ARMeilleure/State/ExceptionCallback.cs +++ b/src/ARMeilleure/State/ExceptionCallback.cs @@ -2,4 +2,4 @@ namespace ARMeilleure.State { public delegate void ExceptionCallbackNoArgs(ExecutionContext context); public delegate void ExceptionCallback(ExecutionContext context, ulong address, int id); -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/ExecutionContext.cs b/src/ARMeilleure/State/ExecutionContext.cs index 859fb3a5d..ce10a591c 100644 --- a/src/ARMeilleure/State/ExecutionContext.cs +++ b/src/ARMeilleure/State/ExecutionContext.cs @@ -7,7 +7,7 @@ public class ExecutionContext { private const int MinCountForCheck = 4000; - private NativeContext _nativeContext; + private readonly NativeContext _nativeContext; internal IntPtr NativeContextPtr => _nativeContext.BasePtr; @@ -17,8 +17,10 @@ public class ExecutionContext public ulong Pc => _nativeContext.GetPc(); +#pragma warning disable CA1822 // Mark member as static public uint CtrEl0 => 0x8444c004; public uint DczidEl0 => 0x00000004; +#pragma warning restore CA1822 public ulong CntfrqEl0 => _counter.Frequency; public ulong CntpctEl0 => _counter.Counter; @@ -170,4 +172,4 @@ public void Dispose() _nativeContext.Dispose(); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/ExecutionMode.cs b/src/ARMeilleure/State/ExecutionMode.cs index 29154a255..e1fb722bd 100644 --- a/src/ARMeilleure/State/ExecutionMode.cs +++ b/src/ARMeilleure/State/ExecutionMode.cs @@ -1,9 +1,9 @@ namespace ARMeilleure.State { - enum ExecutionMode : int + enum ExecutionMode { Aarch32Arm = 0, Aarch32Thumb = 1, - Aarch64 = 2 + Aarch64 = 2, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/FPCR.cs b/src/ARMeilleure/State/FPCR.cs index 6f707de7d..427300add 100644 --- a/src/ARMeilleure/State/FPCR.cs +++ b/src/ARMeilleure/State/FPCR.cs @@ -13,10 +13,10 @@ public enum FPCR : uint Ide = 1u << 15, RMode0 = 1u << 22, RMode1 = 1u << 23, - Fz = 1u << 24, - Dn = 1u << 25, + Fz = 1u << 24, + Dn = 1u << 25, Ahp = 1u << 26, - Mask = Ahp | Dn | Fz | RMode1 | RMode0 | Ide | Ixe | Ufe | Ofe | Dze | Ioe // 0x07C09F00u + Mask = Ahp | Dn | Fz | RMode1 | RMode0 | Ide | Ixe | Ufe | Ofe | Dze | Ioe, // 0x07C09F00u } } diff --git a/src/ARMeilleure/State/FPException.cs b/src/ARMeilleure/State/FPException.cs index e24e07af1..5b13659ab 100644 --- a/src/ARMeilleure/State/FPException.cs +++ b/src/ARMeilleure/State/FPException.cs @@ -2,11 +2,11 @@ namespace ARMeilleure.State { enum FPException { - InvalidOp = 0, + InvalidOp = 0, DivideByZero = 1, - Overflow = 2, - Underflow = 3, - Inexact = 4, - InputDenorm = 7 + Overflow = 2, + Underflow = 3, + Inexact = 4, + InputDenorm = 7, } } diff --git a/src/ARMeilleure/State/FPRoundingMode.cs b/src/ARMeilleure/State/FPRoundingMode.cs index 8d757a151..0913175e7 100644 --- a/src/ARMeilleure/State/FPRoundingMode.cs +++ b/src/ARMeilleure/State/FPRoundingMode.cs @@ -2,10 +2,10 @@ namespace ARMeilleure.State { public enum FPRoundingMode { - ToNearest = 0, // With ties to even. - TowardsPlusInfinity = 1, + ToNearest = 0, // With ties to even. + TowardsPlusInfinity = 1, TowardsMinusInfinity = 2, - TowardsZero = 3, - ToNearestAway = 4 // With ties to away. + TowardsZero = 3, + ToNearestAway = 4, // With ties to away. } } diff --git a/src/ARMeilleure/State/FPSCR.cs b/src/ARMeilleure/State/FPSCR.cs index d6d2fc26a..65a060ebd 100644 --- a/src/ARMeilleure/State/FPSCR.cs +++ b/src/ARMeilleure/State/FPSCR.cs @@ -10,6 +10,6 @@ public enum FPSCR : uint Z = 1u << 30, N = 1u << 31, - Mask = N | Z | C | V | FPSR.Mask | FPCR.Mask // 0xFFC09F9Fu + Mask = N | Z | C | V | FPSR.Mask | FPCR.Mask, // 0xFFC09F9Fu } } diff --git a/src/ARMeilleure/State/FPSR.cs b/src/ARMeilleure/State/FPSR.cs index 5e66d5ce1..915b2fb31 100644 --- a/src/ARMeilleure/State/FPSR.cs +++ b/src/ARMeilleure/State/FPSR.cs @@ -13,6 +13,6 @@ public enum FPSR : uint Idc = 1u << 7, Qc = 1u << 27, - Mask = Qc | Idc | Ixc | Ufc | Ofc | Dzc | Ioc // 0x0800009Fu + Mask = Qc | Idc | Ixc | Ufc | Ofc | Dzc | Ioc, // 0x0800009Fu } } diff --git a/src/ARMeilleure/State/FPState.cs b/src/ARMeilleure/State/FPState.cs index fa6ab9d46..e76f48240 100644 --- a/src/ARMeilleure/State/FPState.cs +++ b/src/ARMeilleure/State/FPState.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.State +namespace ARMeilleure.State { public enum FPState { @@ -26,6 +26,6 @@ public enum FPState RMode1Flag = 23, FzFlag = 24, DnFlag = 25, - AhpFlag = 26 + AhpFlag = 26, } } diff --git a/src/ARMeilleure/State/FPType.cs b/src/ARMeilleure/State/FPType.cs index 84e0db8da..367082ffc 100644 --- a/src/ARMeilleure/State/FPType.cs +++ b/src/ARMeilleure/State/FPType.cs @@ -6,6 +6,6 @@ enum FPType Zero, Infinity, QNaN, - SNaN + SNaN, } } diff --git a/src/ARMeilleure/State/ICounter.cs b/src/ARMeilleure/State/ICounter.cs index 93e721ea3..7aa1cce73 100644 --- a/src/ARMeilleure/State/ICounter.cs +++ b/src/ARMeilleure/State/ICounter.cs @@ -15,4 +15,4 @@ public interface ICounter /// ulong Counter { get; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/NativeContext.cs b/src/ARMeilleure/State/NativeContext.cs index 3189bdd8a..5403042ea 100644 --- a/src/ARMeilleure/State/NativeContext.cs +++ b/src/ARMeilleure/State/NativeContext.cs @@ -23,7 +23,7 @@ private unsafe struct NativeCtxStorage public int Running; } - private static NativeCtxStorage _dummyStorage = new NativeCtxStorage(); + private static NativeCtxStorage _dummyStorage = new(); private readonly IJitMemoryBlock _block; @@ -266,4 +266,4 @@ private static int StorageOffset(ref NativeCtxStorage storage, ref T target) public void Dispose() => _block.Dispose(); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/PState.cs b/src/ARMeilleure/State/PState.cs index 9a80bc570..d4ddc8656 100644 --- a/src/ARMeilleure/State/PState.cs +++ b/src/ARMeilleure/State/PState.cs @@ -12,6 +12,6 @@ public enum PState VFlag = 28, CFlag = 29, ZFlag = 30, - NFlag = 31 + NFlag = 31, } } diff --git a/src/ARMeilleure/State/RegisterAlias.cs b/src/ARMeilleure/State/RegisterAlias.cs index 7ebfa2753..a95740891 100644 --- a/src/ARMeilleure/State/RegisterAlias.cs +++ b/src/ARMeilleure/State/RegisterAlias.cs @@ -2,13 +2,13 @@ namespace ARMeilleure.State { static class RegisterAlias { - public const int R8Usr = 8; - public const int R9Usr = 9; + public const int R8Usr = 8; + public const int R9Usr = 9; public const int R10Usr = 10; public const int R11Usr = 11; public const int R12Usr = 12; - public const int SpUsr = 13; - public const int LrUsr = 14; + public const int SpUsr = 13; + public const int LrUsr = 14; public const int SpHyp = 15; @@ -24,13 +24,13 @@ static class RegisterAlias public const int LrUnd = 22; public const int SpUnd = 23; - public const int R8Fiq = 24; - public const int R9Fiq = 25; + public const int R8Fiq = 24; + public const int R9Fiq = 25; public const int R10Fiq = 26; public const int R11Fiq = 27; public const int R12Fiq = 28; - public const int SpFiq = 29; - public const int LrFiq = 30; + public const int SpFiq = 29; + public const int LrFiq = 30; public const int Aarch32Sp = 13; public const int Aarch32Lr = 14; @@ -39,4 +39,4 @@ static class RegisterAlias public const int Lr = 30; public const int Zr = 31; } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/RegisterConsts.cs b/src/ARMeilleure/State/RegisterConsts.cs index d62940808..b43f8d646 100644 --- a/src/ARMeilleure/State/RegisterConsts.cs +++ b/src/ARMeilleure/State/RegisterConsts.cs @@ -2,14 +2,14 @@ namespace ARMeilleure.State { static class RegisterConsts { - public const int IntRegsCount = 32; - public const int VecRegsCount = 32; - public const int FlagsCount = 32; - public const int FpFlagsCount = 32; + public const int IntRegsCount = 32; + public const int VecRegsCount = 32; + public const int FlagsCount = 32; + public const int FpFlagsCount = 32; public const int IntAndVecRegsCount = IntRegsCount + VecRegsCount; - public const int FpFlagsOffset = IntRegsCount + VecRegsCount + FlagsCount; - public const int TotalCount = IntRegsCount + VecRegsCount + FlagsCount + FpFlagsCount; + public const int FpFlagsOffset = IntRegsCount + VecRegsCount + FlagsCount; + public const int TotalCount = IntRegsCount + VecRegsCount + FlagsCount + FpFlagsCount; public const int ZeroIndex = 31; } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/State/V128.cs b/src/ARMeilleure/State/V128.cs index 3fa9f9a99..cbcaddfc2 100644 --- a/src/ARMeilleure/State/V128.cs +++ b/src/ARMeilleure/State/V128.cs @@ -13,13 +13,13 @@ public struct V128 : IEquatable // _e0 & _e1 could be marked as readonly, however they are not readonly because we modify them through the Unsafe // APIs. This also means that one should be careful when changing the layout of this struct. - private ulong _e0; - private ulong _e1; + private readonly ulong _e0; + private readonly ulong _e1; /// /// Gets a new with all bits set to zero. /// - public static V128 Zero => new V128(0, 0); + public static V128 Zero => new(0, 0); /// /// Initializes a new instance of the struct with the specified value @@ -55,9 +55,9 @@ public V128(float value) : this(value, 0, 0, 0) { } /// Element 3 public V128(float e0, float e1, float e2, float e3) { - _e0 = (ulong)(uint)BitConverter.SingleToInt32Bits(e0) << 0; + _e0 = (ulong)(uint)BitConverter.SingleToInt32Bits(e0) << 0; _e0 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e1) << 32; - _e1 = (ulong)(uint)BitConverter.SingleToInt32Bits(e2) << 0; + _e1 = (ulong)(uint)BitConverter.SingleToInt32Bits(e2) << 0; _e1 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e3) << 32; } @@ -98,9 +98,9 @@ public V128(int e0, int e1, int e2, int e3) : this((uint)e0, (uint)e1, (uint)e2, /// Element 3 public V128(uint e0, uint e1, uint e2, uint e3) { - _e0 = (ulong)e0 << 0; + _e0 = (ulong)e0 << 0; _e0 |= (ulong)e1 << 32; - _e1 = (ulong)e2 << 0; + _e1 = (ulong)e2 << 0; _e1 |= (ulong)e3 << 32; } @@ -137,7 +137,9 @@ public T As() where T : unmanaged public T Extract(int index) where T : unmanaged { if ((uint)index >= GetElementCount()) + { ThrowIndexOutOfRange(); + } // Performs: // return *((*T)this + index); @@ -156,7 +158,9 @@ public T Extract(int index) where T : unmanaged public void Insert(int index, T value) where T : unmanaged { if ((uint)index >= GetElementCount()) + { ThrowIndexOutOfRange(); + } // Performs: // *((*T)this + index) = value; @@ -167,13 +171,13 @@ public void Insert(int index, T value) where T : unmanaged /// Returns a new array which represents the . /// /// A new array which represents the - public byte[] ToArray() + public readonly byte[] ToArray() { - byte[] data = new byte[16]; + byte[] data = new byte[16]; Span span = data; BitConverter.TryWriteBytes(span, _e0); - BitConverter.TryWriteBytes(span.Slice(8), _e1); + BitConverter.TryWriteBytes(span[8..], _e1); return data; } @@ -225,7 +229,7 @@ public byte[] ToArray() /// /// Target /// Result of not operation - public static V128 operator ~(V128 x) => new V128(~x._e0, ~x._e1); + public static V128 operator ~(V128 x) => new(~x._e0, ~x._e1); /// /// Performs a bitwise and on the specified instances. @@ -233,7 +237,7 @@ public byte[] ToArray() /// First instance /// Second instance /// Result of and operation - public static V128 operator &(V128 x, V128 y) => new V128(x._e0 & y._e0, x._e1 & y._e1); + public static V128 operator &(V128 x, V128 y) => new(x._e0 & y._e0, x._e1 & y._e1); /// /// Performs a bitwise or on the specified instances. @@ -241,7 +245,7 @@ public byte[] ToArray() /// First instance /// Second instance /// Result of or operation - public static V128 operator |(V128 x, V128 y) => new V128(x._e0 | y._e0, x._e1 | y._e1); + public static V128 operator |(V128 x, V128 y) => new(x._e0 | y._e0, x._e1 | y._e1); /// /// Performs a bitwise exlusive or on the specified instances. @@ -249,7 +253,7 @@ public byte[] ToArray() /// First instance /// Second instance /// Result of exclusive or operation - public static V128 operator ^(V128 x, V128 y) => new V128(x._e0 ^ y._e0, x._e1 ^ y._e1); + public static V128 operator ^(V128 x, V128 y) => new(x._e0 ^ y._e0, x._e1 ^ y._e1); /// /// Determines if the specified instances are equal. @@ -272,7 +276,7 @@ public byte[] ToArray() /// /// Other instance /// true if equal; otherwise false - public bool Equals(V128 other) + public readonly bool Equals(V128 other) { return other._e0 == _e0 && other._e1 == _e1; } @@ -282,24 +286,24 @@ public bool Equals(V128 other) /// /// Other instance /// true if equal; otherwise false - public override bool Equals(object obj) + public readonly override bool Equals(object obj) { return obj is V128 vector && Equals(vector); } /// - public override int GetHashCode() + public readonly override int GetHashCode() { return HashCode.Combine(_e0, _e1); } /// - public override string ToString() + public readonly override string ToString() { return $"0x{_e1:X16}{_e0:X16}"; } - private uint GetElementCount() where T : unmanaged + private static uint GetElementCount() where T : unmanaged { return (uint)(Unsafe.SizeOf() / Unsafe.SizeOf()); } @@ -309,4 +313,4 @@ private static void ThrowIndexOutOfRange() throw new ArgumentOutOfRangeException("index"); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Statistics.cs b/src/ARMeilleure/Statistics.cs index fbc647082..2f873bcfa 100644 --- a/src/ARMeilleure/Statistics.cs +++ b/src/ARMeilleure/Statistics.cs @@ -1,4 +1,6 @@ +#if M_PROFILE using System; +#endif using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -11,12 +13,12 @@ public static class Statistics { private const int ReportMaxFunctions = 100; -#pragma warning disable CS0169 +#if M_PROFILE [ThreadStatic] private static Stopwatch _executionTimer; -#pragma warning restore CS0169 +#endif - private static ConcurrentDictionary _ticksPerFunction; + private static readonly ConcurrentDictionary _ticksPerFunction; static Statistics() { @@ -47,7 +49,7 @@ internal static void StopTimer(ulong funcAddr) long ticks = _executionTimer.ElapsedTicks; - _ticksPerFunction.AddOrUpdate(funcAddr, ticks, (key, oldTicks) => oldTicks + ticks); + TicksPerFunction.AddOrUpdate(funcAddr, ticks, (key, oldTicks) => oldTicks + ticks); #endif } @@ -69,7 +71,7 @@ public static string GetReport() { int count = 0; - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new(); sb.AppendLine(" Function address | Time"); sb.AppendLine("--------------------------"); @@ -91,4 +93,4 @@ public static string GetReport() return sb.ToString(); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/ArmEmitterContext.cs b/src/ARMeilleure/Translation/ArmEmitterContext.cs index 565d2aada..e24074739 100644 --- a/src/ARMeilleure/Translation/ArmEmitterContext.cs +++ b/src/ARMeilleure/Translation/ArmEmitterContext.cs @@ -55,7 +55,7 @@ public Block CurrBlock public Aarch32Mode Mode { get; } private int _ifThenBlockStateIndex = 0; - private Condition[] _ifThenBlockState = { }; + private Condition[] _ifThenBlockState = Array.Empty(); public bool IsInIfThenBlock => _ifThenBlockStateIndex < _ifThenBlockState.Length; public Condition CurrentIfThenBlockCond => _ifThenBlockState[_ifThenBlockStateIndex]; @@ -96,7 +96,7 @@ public override Operand Call(MethodInfo info, params Operand[] callArgs) OperandType returnType = GetOperandType(info.ReturnType); - Symbol symbol = new Symbol(SymbolType.DelegateTable, (ulong)index); + Symbol symbol = new(SymbolType.DelegateTable, (ulong)index); Symbols.Add((ulong)funcPtr.ToInt64(), info.Name); @@ -219,6 +219,7 @@ public Operand TryGetComparisonResult(Condition condition) { switch (condition) { +#pragma warning disable IDE0055 // Disable formatting case Condition.Eq: return ICompareEqual (n, m); case Condition.Ne: return ICompareNotEqual (n, m); case Condition.GeUn: return ICompareGreaterOrEqualUI(n, m); @@ -229,6 +230,7 @@ public Operand TryGetComparisonResult(Condition condition) case Condition.Lt: return ICompareLess (n, m); case Condition.Gt: return ICompareGreater (n, m); case Condition.Le: return ICompareLessOrEqual (n, m); +#pragma warning restore IDE0055 } } else if (cmpName == InstName.Adds && _optOpLastCompare is IOpCodeAluImm op) @@ -253,12 +255,14 @@ public Operand TryGetComparisonResult(Condition condition) switch (condition) { +#pragma warning disable IDE0055 // Disable formatting case Condition.Eq: return ICompareEqual (n, m); case Condition.Ne: return ICompareNotEqual (n, m); case Condition.Ge: return ICompareGreaterOrEqual(n, m); case Condition.Lt: return ICompareLess (n, m); case Condition.Gt: return ICompareGreater (n, m); case Condition.Le: return ICompareLessOrEqual (n, m); +#pragma warning restore IDE0055 } } @@ -279,4 +283,4 @@ public void AdvanceIfThenBlockState() } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Cache/CacheEntry.cs b/src/ARMeilleure/Translation/Cache/CacheEntry.cs index dc5503b18..25b06f781 100644 --- a/src/ARMeilleure/Translation/Cache/CacheEntry.cs +++ b/src/ARMeilleure/Translation/Cache/CacheEntry.cs @@ -7,14 +7,14 @@ namespace ARMeilleure.Translation.Cache readonly struct CacheEntry : IComparable { public int Offset { get; } - public int Size { get; } + public int Size { get; } public UnwindInfo UnwindInfo { get; } public CacheEntry(int offset, int size, UnwindInfo unwindInfo) { - Offset = offset; - Size = size; + Offset = offset; + Size = size; UnwindInfo = unwindInfo; } @@ -23,4 +23,4 @@ public int CompareTo([AllowNull] CacheEntry other) return Offset.CompareTo(other.Offset); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs index 4c22de40e..f36bf7a3d 100644 --- a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs +++ b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -23,7 +23,7 @@ public int CompareTo([AllowNull] MemoryBlock other) } } - private readonly List _blocks = new List(); + private readonly List _blocks = new(); public CacheMemoryAllocator(int capacity) { diff --git a/src/ARMeilleure/Translation/Cache/JitCache.cs b/src/ARMeilleure/Translation/Cache/JitCache.cs index f496a8e9c..e2b5e2d10 100644 --- a/src/ARMeilleure/Translation/Cache/JitCache.cs +++ b/src/ARMeilleure/Translation/Cache/JitCache.cs @@ -2,17 +2,19 @@ using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.Memory; using ARMeilleure.Native; +using Ryujinx.Memory; using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace ARMeilleure.Translation.Cache { - static class JitCache + static partial class JitCache { - private const int PageSize = 4 * 1024; - private const int PageMask = PageSize - 1; + private static readonly int _pageSize = (int)MemoryBlock.GetPageSize(); + private static readonly int _pageMask = _pageSize - 1; private const int CodeAlignment = 4; // Bytes. private const int CacheSize = 2047 * 1024 * 1024; @@ -22,27 +24,41 @@ static class JitCache private static CacheMemoryAllocator _cacheAllocator; - private static readonly List _cacheEntries = new List(); + private static readonly List _cacheEntries = new(); - private static readonly object _lock = new object(); + private static readonly object _lock = new(); private static bool _initialized; + [SupportedOSPlatform("windows")] + [LibraryImport("kernel32.dll", SetLastError = true)] + public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize); + public static void Initialize(IJitMemoryAllocator allocator) { - if (_initialized) return; + if (_initialized) + { + return; + } lock (_lock) { - if (_initialized) return; + if (_initialized) + { + return; + } _jitRegion = new ReservedRegion(allocator, CacheSize); - _jitCacheInvalidator = new JitCacheInvalidation(allocator); + + if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) + { + _jitCacheInvalidator = new JitCacheInvalidation(allocator); + } _cacheAllocator = new CacheMemoryAllocator(CacheSize); if (OperatingSystem.IsWindows()) { - JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(PageSize)); + JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(_pageSize)); } _initialized = true; @@ -65,7 +81,7 @@ public static IntPtr Map(CompiledFunction func) { unsafe { - fixed (byte *codePtr = code) + fixed (byte* codePtr = code) { JitSupportDarwin.Copy(funcPtr, (IntPtr)codePtr, (ulong)code.Length); } @@ -77,7 +93,14 @@ public static IntPtr Map(CompiledFunction func) Marshal.Copy(code, 0, funcPtr, code.Length); ReprotectAsExecutable(funcOffset, code.Length); - _jitCacheInvalidator.Invalidate(funcPtr, (ulong)code.Length); + if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length); + } + else + { + _jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length); + } } Add(funcOffset, code.Length, func.UnwindInfo); @@ -94,12 +117,11 @@ public static void Unmap(IntPtr pointer) int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64()); - bool result = TryFind(funcOffset, out CacheEntry entry); - Debug.Assert(result); - - _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); - - Remove(funcOffset); + if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset) + { + _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); + _cacheEntries.RemoveAt(entryIndex); + } } } @@ -107,8 +129,8 @@ private static void ReprotectAsWritable(int offset, int size) { int endOffs = offset + size; - int regionStart = offset & ~PageMask; - int regionEnd = (endOffs + PageMask) & ~PageMask; + int regionStart = offset & ~_pageMask; + int regionEnd = (endOffs + _pageMask) & ~_pageMask; _jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart)); } @@ -117,8 +139,8 @@ private static void ReprotectAsExecutable(int offset, int size) { int endOffs = offset + size; - int regionStart = offset & ~PageMask; - int regionEnd = (endOffs + PageMask) & ~PageMask; + int regionStart = offset & ~_pageMask; + int regionEnd = (endOffs + _pageMask) & ~_pageMask; _jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart)); } @@ -146,7 +168,7 @@ private static int AlignCodeSize(int codeSize) private static void Add(int offset, int size, UnwindInfo unwindInfo) { - CacheEntry entry = new CacheEntry(offset, size, unwindInfo); + CacheEntry entry = new(offset, size, unwindInfo); int index = _cacheEntries.BinarySearch(entry); @@ -158,22 +180,7 @@ private static void Add(int offset, int size, UnwindInfo unwindInfo) _cacheEntries.Insert(index, entry); } - private static void Remove(int offset) - { - int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default)); - - if (index < 0) - { - index = ~index - 1; - } - - if (index >= 0) - { - _cacheEntries.RemoveAt(index); - } - } - - public static bool TryFind(int offset, out CacheEntry entry) + public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex) { lock (_lock) { @@ -187,12 +194,14 @@ public static bool TryFind(int offset, out CacheEntry entry) if (index >= 0) { entry = _cacheEntries[index]; + entryIndex = index; return true; } } entry = default; + entryIndex = 0; return false; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs b/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs index ec2ae73bb..3aa2e19f1 100644 --- a/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs +++ b/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs @@ -6,7 +6,7 @@ namespace ARMeilleure.Translation.Cache { class JitCacheInvalidation { - private static int[] _invalidationCode = new int[] + private static readonly int[] _invalidationCode = new int[] { unchecked((int)0xd53b0022), // mrs x2, ctr_el0 unchecked((int)0xd3504c44), // ubfx x4, x2, #16, #4 @@ -40,15 +40,15 @@ class JitCacheInvalidation private delegate void InvalidateCache(ulong start, ulong end); - private InvalidateCache _invalidateCache; - private ReservedRegion _invalidateCacheCodeRegion; + private readonly InvalidateCache _invalidateCache; + private readonly ReservedRegion _invalidateCacheCodeRegion; private readonly bool _needsInvalidation; public JitCacheInvalidation(IJitMemoryAllocator allocator) { - // On macOS, a different path is used to write to the JIT cache, which does the invalidation. - if (!OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + // On macOS and Windows, a different path is used to write to the JIT cache, which does the invalidation. + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) { ulong size = (ulong)_invalidationCode.Length * sizeof(int); ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1; @@ -76,4 +76,4 @@ public void Invalidate(IntPtr basePointer, ulong size) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Cache/JitUnwindWindows.cs b/src/ARMeilleure/Translation/Cache/JitUnwindWindows.cs index 77727bf16..3957a7559 100644 --- a/src/ARMeilleure/Translation/Cache/JitUnwindWindows.cs +++ b/src/ARMeilleure/Translation/Cache/JitUnwindWindows.cs @@ -29,15 +29,15 @@ private struct UnwindInfo private enum UnwindOp { - PushNonvol = 0, - AllocLarge = 1, - AllocSmall = 2, - SetFpreg = 3, - SaveNonvol = 4, + PushNonvol = 0, + AllocLarge = 1, + AllocSmall = 2, + SetFpreg = 3, + SaveNonvol = 4, SaveNonvolFar = 5, - SaveXmm128 = 8, + SaveXmm128 = 8, SaveXmm128Far = 9, - PushMachframe = 10 + PushMachframe = 10, } private unsafe delegate RuntimeFunction* GetRuntimeFunctionCallback(ulong controlPc, IntPtr context); @@ -95,7 +95,7 @@ public static void InstallFunctionTableHandler(IntPtr codeCachePointer, uint cod { int offset = (int)((long)controlPc - context.ToInt64()); - if (!JitCache.TryFind(offset, out CacheEntry funcEntry)) + if (!JitCache.TryFind(offset, out CacheEntry funcEntry, out _)) { return null; // Not found. } @@ -111,72 +111,73 @@ public static void InstallFunctionTableHandler(IntPtr codeCachePointer, uint cod switch (entry.PseudoOp) { case UnwindPseudoOp.SaveXmm128: - { - int stackOffset = entry.StackOffsetOrAllocSize; - - Debug.Assert(stackOffset % 16 == 0); - - if (stackOffset <= 0xFFFF0) - { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.SaveXmm128, entry.PrologOffset, entry.RegIndex); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset / 16); - } - else { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.SaveXmm128Far, entry.PrologOffset, entry.RegIndex); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 0); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 16); + int stackOffset = entry.StackOffsetOrAllocSize; + + Debug.Assert(stackOffset % 16 == 0); + + if (stackOffset <= 0xFFFF0) + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.SaveXmm128, entry.PrologOffset, entry.RegIndex); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset / 16); + } + else + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.SaveXmm128Far, entry.PrologOffset, entry.RegIndex); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 0); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 16); + } + + break; } - break; - } - case UnwindPseudoOp.AllocStack: - { - int allocSize = entry.StackOffsetOrAllocSize; - - Debug.Assert(allocSize % 8 == 0); - - if (allocSize <= 128) { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocSmall, entry.PrologOffset, (allocSize / 8) - 1); - } - else if (allocSize <= 0x7FFF8) - { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocLarge, entry.PrologOffset, 0); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize / 8); - } - else - { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocLarge, entry.PrologOffset, 1); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 0); - _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 16); + int allocSize = entry.StackOffsetOrAllocSize; + + Debug.Assert(allocSize % 8 == 0); + + if (allocSize <= 128) + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocSmall, entry.PrologOffset, (allocSize / 8) - 1); + } + else if (allocSize <= 0x7FFF8) + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocLarge, entry.PrologOffset, 0); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize / 8); + } + else + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.AllocLarge, entry.PrologOffset, 1); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 0); + _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 16); + } + + break; } - break; - } - case UnwindPseudoOp.PushReg: - { - _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.PushNonvol, entry.PrologOffset, entry.RegIndex); + { + _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOp.PushNonvol, entry.PrologOffset, entry.RegIndex); - break; - } + break; + } - default: throw new NotImplementedException($"({nameof(entry.PseudoOp)} = {entry.PseudoOp})"); + default: + throw new NotImplementedException($"({nameof(entry.PseudoOp)} = {entry.PseudoOp})"); } } Debug.Assert(codeIndex <= MaxUnwindCodesArraySize); - _unwindInfo->VersionAndFlags = 1; // Flags: The function has no handler. - _unwindInfo->SizeOfProlog = (byte)unwindInfo.PrologSize; + _unwindInfo->VersionAndFlags = 1; // Flags: The function has no handler. + _unwindInfo->SizeOfProlog = (byte)unwindInfo.PrologSize; _unwindInfo->CountOfUnwindCodes = (byte)codeIndex; - _unwindInfo->FrameRegister = 0; + _unwindInfo->FrameRegister = 0; _runtimeFunction->BeginAddress = (uint)funcEntry.Offset; - _runtimeFunction->EndAddress = (uint)(funcEntry.Offset + funcEntry.Size); - _runtimeFunction->UnwindData = (uint)_sizeOfRuntimeFunction; + _runtimeFunction->EndAddress = (uint)(funcEntry.Offset + funcEntry.Size); + _runtimeFunction->UnwindData = (uint)_sizeOfRuntimeFunction; return _runtimeFunction; } @@ -186,4 +187,4 @@ private static ushort PackUnwindOp(UnwindOp op, int prologOffset, int opInfo) return (ushort)(prologOffset | ((int)op << 8) | (opInfo << 12)); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Compiler.cs b/src/ARMeilleure/Translation/Compiler.cs index d4aa5cd96..293e63496 100644 --- a/src/ARMeilleure/Translation/Compiler.cs +++ b/src/ARMeilleure/Translation/Compiler.cs @@ -11,10 +11,10 @@ static class Compiler { public static CompiledFunction Compile( ControlFlowGraph cfg, - OperandType[] argTypes, - OperandType retType, - CompilerOptions options, - Architecture target) + OperandType[] argTypes, + OperandType retType, + CompilerOptions options, + Architecture target) { CompilerContext cctx = new(cfg, argTypes, retType, options); @@ -65,4 +65,4 @@ public static CompiledFunction Compile( } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/CompilerContext.cs b/src/ARMeilleure/Translation/CompilerContext.cs index 510dec58f..5b10686b3 100644 --- a/src/ARMeilleure/Translation/CompilerContext.cs +++ b/src/ARMeilleure/Translation/CompilerContext.cs @@ -6,21 +6,21 @@ readonly struct CompilerContext { public ControlFlowGraph Cfg { get; } - public OperandType[] FuncArgTypes { get; } - public OperandType FuncReturnType { get; } + public OperandType[] FuncArgTypes { get; } + public OperandType FuncReturnType { get; } public CompilerOptions Options { get; } public CompilerContext( ControlFlowGraph cfg, - OperandType[] funcArgTypes, - OperandType funcReturnType, - CompilerOptions options) + OperandType[] funcArgTypes, + OperandType funcReturnType, + CompilerOptions options) { - Cfg = cfg; - FuncArgTypes = funcArgTypes; + Cfg = cfg; + FuncArgTypes = funcArgTypes; FuncReturnType = funcReturnType; - Options = options; + Options = options; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/CompilerOptions.cs b/src/ARMeilleure/Translation/CompilerOptions.cs index 0a07ed4ab..d454de7f2 100644 --- a/src/ARMeilleure/Translation/CompilerOptions.cs +++ b/src/ARMeilleure/Translation/CompilerOptions.cs @@ -5,13 +5,13 @@ namespace ARMeilleure.Translation [Flags] enum CompilerOptions { - None = 0, - SsaForm = 1 << 0, - Optimize = 1 << 1, - Lsra = 1 << 2, + None = 0, + SsaForm = 1 << 0, + Optimize = 1 << 1, + Lsra = 1 << 2, Relocatable = 1 << 3, MediumCq = SsaForm | Optimize, - HighCq = SsaForm | Optimize | Lsra + HighCq = SsaForm | Optimize | Lsra, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/ControlFlowGraph.cs b/src/ARMeilleure/Translation/ControlFlowGraph.cs index c935f1521..3ead49c93 100644 --- a/src/ARMeilleure/Translation/ControlFlowGraph.cs +++ b/src/ARMeilleure/Translation/ControlFlowGraph.cs @@ -130,7 +130,7 @@ private void RemoveUnreachableBlocks(IntrusiveList blocks) public BasicBlock SplitEdge(BasicBlock predecessor, BasicBlock successor) { - BasicBlock splitBlock = new BasicBlock(Blocks.Count); + BasicBlock splitBlock = new(Blocks.Count); for (int i = 0; i < predecessor.SuccessorsCount; i++) { @@ -152,4 +152,4 @@ public BasicBlock SplitEdge(BasicBlock predecessor, BasicBlock successor) return splitBlock; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/DelegateHelper.cs b/src/ARMeilleure/Translation/DelegateHelper.cs deleted file mode 100644 index 43a39bab0..000000000 --- a/src/ARMeilleure/Translation/DelegateHelper.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; - -namespace ARMeilleure.Translation -{ - static class DelegateHelper - { - private const string DelegateTypesAssemblyName = "JitDelegateTypes"; - - private static readonly ModuleBuilder _modBuilder; - - private static readonly Dictionary _delegateTypesCache; - - static DelegateHelper() - { - AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(DelegateTypesAssemblyName), AssemblyBuilderAccess.Run); - - _modBuilder = asmBuilder.DefineDynamicModule(DelegateTypesAssemblyName); - - _delegateTypesCache = new Dictionary(); - } - - public static Delegate GetDelegate(MethodInfo info) - { - ArgumentNullException.ThrowIfNull(info); - - Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray(); - Type returnType = info.ReturnType; - - Type delegateType = GetDelegateType(parameters, returnType); - - return Delegate.CreateDelegate(delegateType, info); - } - - private static Type GetDelegateType(Type[] parameters, Type returnType) - { - string key = GetFunctionSignatureKey(parameters, returnType); - - if (!_delegateTypesCache.TryGetValue(key, out Type delegateType)) - { - delegateType = MakeDelegateType(parameters, returnType, key); - - _delegateTypesCache.TryAdd(key, delegateType); - } - - return delegateType; - } - - private static string GetFunctionSignatureKey(Type[] parameters, Type returnType) - { - string sig = GetTypeName(returnType); - - foreach (Type type in parameters) - { - sig += '_' + GetTypeName(type); - } - - return sig; - } - - private static string GetTypeName(Type type) - { - return type.FullName.Replace(".", string.Empty); - } - - private const MethodAttributes CtorAttributes = - MethodAttributes.RTSpecialName | - MethodAttributes.HideBySig | - MethodAttributes.Public; - - private const TypeAttributes DelegateTypeAttributes = - TypeAttributes.Class | - TypeAttributes.Public | - TypeAttributes.Sealed | - TypeAttributes.AnsiClass | - TypeAttributes.AutoClass; - - private const MethodImplAttributes ImplAttributes = - MethodImplAttributes.Runtime | - MethodImplAttributes.Managed; - - private const MethodAttributes InvokeAttributes = - MethodAttributes.Public | - MethodAttributes.HideBySig | - MethodAttributes.NewSlot | - MethodAttributes.Virtual; - - private static readonly Type[] _delegateCtorSignature = { typeof(object), typeof(IntPtr) }; - - private static Type MakeDelegateType(Type[] parameters, Type returnType, string name) - { - TypeBuilder builder = _modBuilder.DefineType(name, DelegateTypeAttributes, typeof(MulticastDelegate)); - - builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _delegateCtorSignature).SetImplementationFlags(ImplAttributes); - - builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes); - - return builder.CreateTypeInfo(); - } - } -} diff --git a/src/ARMeilleure/Translation/DelegateInfo.cs b/src/ARMeilleure/Translation/DelegateInfo.cs index 36320ac31..27479a003 100644 --- a/src/ARMeilleure/Translation/DelegateInfo.cs +++ b/src/ARMeilleure/Translation/DelegateInfo.cs @@ -5,7 +5,9 @@ namespace ARMeilleure.Translation { class DelegateInfo { +#pragma warning disable IDE0052 // Remove unread private member private readonly Delegate _dlg; // Ensure that this delegate will not be garbage collected. +#pragma warning restore IDE0052 public IntPtr FuncPtr { get; } diff --git a/src/ARMeilleure/Translation/Delegates.cs b/src/ARMeilleure/Translation/Delegates.cs index 55f1e5145..63db789df 100644 --- a/src/ARMeilleure/Translation/Delegates.cs +++ b/src/ARMeilleure/Translation/Delegates.cs @@ -1,4 +1,5 @@ using ARMeilleure.Instructions; +using ARMeilleure.State; using System; using System.Collections.Generic; using System.Reflection; @@ -63,11 +64,9 @@ public static int GetDelegateIndex(MethodInfo info) return index; } - private static void SetDelegateInfo(MethodInfo info) + private static void SetDelegateInfo(Delegate dlg) { - string key = GetKey(info); - - Delegate dlg = DelegateHelper.GetDelegate(info); + string key = GetKey(dlg.Method); _delegates.Add(key, new DelegateInfo(dlg)); // ArgumentException (key). } @@ -83,179 +82,354 @@ static Delegates() { _delegates = new SortedList(); - SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Abs), new Type[] { typeof(double) })); - SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Ceiling), new Type[] { typeof(double) })); - SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Floor), new Type[] { typeof(double) })); - SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Round), new Type[] { typeof(double), typeof(MidpointRounding) })); - SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Truncate), new Type[] { typeof(double) })); - - SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Abs), new Type[] { typeof(float) })); - SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Ceiling), new Type[] { typeof(float) })); - SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Floor), new Type[] { typeof(float) })); - SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Round), new Type[] { typeof(float), typeof(MidpointRounding) })); - SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Truncate), new Type[] { typeof(float) })); - - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128))); - - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64))); - - SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert))); - SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert))); - - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only. - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt))); - SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub))); - - SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert))); - - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only. - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt))); - SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub))); - - SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert))); + SetDelegateInfo(new MathAbs(Math.Abs)); + SetDelegateInfo(new MathCeiling(Math.Ceiling)); + SetDelegateInfo(new MathFloor(Math.Floor)); + SetDelegateInfo(new MathRound(Math.Round)); + SetDelegateInfo(new MathTruncate(Math.Truncate)); + + SetDelegateInfo(new MathFAbs(MathF.Abs)); + SetDelegateInfo(new MathFCeiling(MathF.Ceiling)); + SetDelegateInfo(new MathFFloor(MathF.Floor)); + SetDelegateInfo(new MathFRound(MathF.Round)); + SetDelegateInfo(new MathFTruncate(MathF.Truncate)); + + SetDelegateInfo(new NativeInterfaceBreak(NativeInterface.Break)); + SetDelegateInfo(new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization)); + SetDelegateInfo(new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit)); + SetDelegateInfo(new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0)); + SetDelegateInfo(new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0)); + SetDelegateInfo(new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0)); + SetDelegateInfo(new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0)); + SetDelegateInfo(new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0)); + SetDelegateInfo(new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress)); + SetDelegateInfo(new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine)); + SetDelegateInfo(new NativeInterfaceReadByte(NativeInterface.ReadByte)); + SetDelegateInfo(new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16)); + SetDelegateInfo(new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32)); + SetDelegateInfo(new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64)); + SetDelegateInfo(new NativeInterfaceReadVector128(NativeInterface.ReadVector128)); + SetDelegateInfo(new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking)); + SetDelegateInfo(new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall)); + SetDelegateInfo(new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess)); + SetDelegateInfo(new NativeInterfaceUndefined(NativeInterface.Undefined)); + SetDelegateInfo(new NativeInterfaceWriteByte(NativeInterface.WriteByte)); + SetDelegateInfo(new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16)); + SetDelegateInfo(new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32)); + SetDelegateInfo(new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64)); + SetDelegateInfo(new NativeInterfaceWriteVector128(NativeInterface.WriteVector128)); + + SetDelegateInfo(new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns)); + SetDelegateInfo(new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros)); + SetDelegateInfo(new SoftFallbackCrc32b(SoftFallback.Crc32b)); + SetDelegateInfo(new SoftFallbackCrc32cb(SoftFallback.Crc32cb)); + SetDelegateInfo(new SoftFallbackCrc32ch(SoftFallback.Crc32ch)); + SetDelegateInfo(new SoftFallbackCrc32cw(SoftFallback.Crc32cw)); + SetDelegateInfo(new SoftFallbackCrc32cx(SoftFallback.Crc32cx)); + SetDelegateInfo(new SoftFallbackCrc32h(SoftFallback.Crc32h)); + SetDelegateInfo(new SoftFallbackCrc32w(SoftFallback.Crc32w)); + SetDelegateInfo(new SoftFallbackCrc32x(SoftFallback.Crc32x)); + SetDelegateInfo(new SoftFallbackDecrypt(SoftFallback.Decrypt)); + SetDelegateInfo(new SoftFallbackEncrypt(SoftFallback.Encrypt)); + SetDelegateInfo(new SoftFallbackFixedRotate(SoftFallback.FixedRotate)); + SetDelegateInfo(new SoftFallbackHashChoose(SoftFallback.HashChoose)); + SetDelegateInfo(new SoftFallbackHashLower(SoftFallback.HashLower)); + SetDelegateInfo(new SoftFallbackHashMajority(SoftFallback.HashMajority)); + SetDelegateInfo(new SoftFallbackHashParity(SoftFallback.HashParity)); + SetDelegateInfo(new SoftFallbackHashUpper(SoftFallback.HashUpper)); + SetDelegateInfo(new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns)); + SetDelegateInfo(new SoftFallbackMixColumns(SoftFallback.MixColumns)); + SetDelegateInfo(new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128)); + SetDelegateInfo(new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32)); + SetDelegateInfo(new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64)); + SetDelegateInfo(new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32)); + SetDelegateInfo(new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64)); + SetDelegateInfo(new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32)); + SetDelegateInfo(new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64)); + SetDelegateInfo(new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32)); + SetDelegateInfo(new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64)); + SetDelegateInfo(new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1)); + SetDelegateInfo(new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2)); + SetDelegateInfo(new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1)); + SetDelegateInfo(new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2)); + SetDelegateInfo(new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64)); + SetDelegateInfo(new SoftFallbackTbl1(SoftFallback.Tbl1)); + SetDelegateInfo(new SoftFallbackTbl2(SoftFallback.Tbl2)); + SetDelegateInfo(new SoftFallbackTbl3(SoftFallback.Tbl3)); + SetDelegateInfo(new SoftFallbackTbl4(SoftFallback.Tbl4)); + SetDelegateInfo(new SoftFallbackTbx1(SoftFallback.Tbx1)); + SetDelegateInfo(new SoftFallbackTbx2(SoftFallback.Tbx2)); + SetDelegateInfo(new SoftFallbackTbx3(SoftFallback.Tbx3)); + SetDelegateInfo(new SoftFallbackTbx4(SoftFallback.Tbx4)); + SetDelegateInfo(new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64)); + + SetDelegateInfo(new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert)); + SetDelegateInfo(new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert)); + + SetDelegateInfo(new SoftFloat32FPAdd(SoftFloat32.FPAdd)); + SetDelegateInfo(new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPCompare(SoftFloat32.FPCompare)); + SetDelegateInfo(new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ)); + SetDelegateInfo(new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE)); + SetDelegateInfo(new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT)); + SetDelegateInfo(new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE)); + SetDelegateInfo(new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT)); + SetDelegateInfo(new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPDiv(SoftFloat32.FPDiv)); + SetDelegateInfo(new SoftFloat32FPMax(SoftFloat32.FPMax)); + SetDelegateInfo(new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum)); + SetDelegateInfo(new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMin(SoftFloat32.FPMin)); + SetDelegateInfo(new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMinNum(SoftFloat32.FPMinNum)); + SetDelegateInfo(new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMul(SoftFloat32.FPMul)); + SetDelegateInfo(new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd)); + SetDelegateInfo(new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMulSub(SoftFloat32.FPMulSub)); + SetDelegateInfo(new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPMulX(SoftFloat32.FPMulX)); + SetDelegateInfo(new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd)); + SetDelegateInfo(new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub)); + SetDelegateInfo(new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate)); + SetDelegateInfo(new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep)); // A32 only. + SetDelegateInfo(new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused)); + SetDelegateInfo(new SoftFloat32FPRecpX(SoftFloat32.FPRecpX)); + SetDelegateInfo(new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate)); + SetDelegateInfo(new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep)); // A32 only. + SetDelegateInfo(new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused)); + SetDelegateInfo(new SoftFloat32FPSqrt(SoftFloat32.FPSqrt)); + SetDelegateInfo(new SoftFloat32FPSub(SoftFloat32.FPSub)); + + SetDelegateInfo(new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert)); + + SetDelegateInfo(new SoftFloat64FPAdd(SoftFloat64.FPAdd)); + SetDelegateInfo(new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPCompare(SoftFloat64.FPCompare)); + SetDelegateInfo(new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ)); + SetDelegateInfo(new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE)); + SetDelegateInfo(new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT)); + SetDelegateInfo(new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE)); + SetDelegateInfo(new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT)); + SetDelegateInfo(new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPDiv(SoftFloat64.FPDiv)); + SetDelegateInfo(new SoftFloat64FPMax(SoftFloat64.FPMax)); + SetDelegateInfo(new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum)); + SetDelegateInfo(new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMin(SoftFloat64.FPMin)); + SetDelegateInfo(new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMinNum(SoftFloat64.FPMinNum)); + SetDelegateInfo(new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMul(SoftFloat64.FPMul)); + SetDelegateInfo(new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd)); + SetDelegateInfo(new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMulSub(SoftFloat64.FPMulSub)); + SetDelegateInfo(new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPMulX(SoftFloat64.FPMulX)); + SetDelegateInfo(new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd)); + SetDelegateInfo(new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub)); + SetDelegateInfo(new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate)); + SetDelegateInfo(new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep)); // A32 only. + SetDelegateInfo(new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused)); + SetDelegateInfo(new SoftFloat64FPRecpX(SoftFloat64.FPRecpX)); + SetDelegateInfo(new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate)); + SetDelegateInfo(new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr)); // A32 only. + SetDelegateInfo(new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep)); // A32 only. + SetDelegateInfo(new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused)); + SetDelegateInfo(new SoftFloat64FPSqrt(SoftFloat64.FPSqrt)); + SetDelegateInfo(new SoftFloat64FPSub(SoftFloat64.FPSub)); + + SetDelegateInfo(new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert)); } + + private delegate double MathAbs(double value); + private delegate double MathCeiling(double a); + private delegate double MathFloor(double d); + private delegate double MathRound(double value, MidpointRounding mode); + private delegate double MathTruncate(double d); + + private delegate float MathFAbs(float x); + private delegate float MathFCeiling(float x); + private delegate float MathFFloor(float x); + private delegate float MathFRound(float x, MidpointRounding mode); + private delegate float MathFTruncate(float x); + + private delegate void NativeInterfaceBreak(ulong address, int imm); + private delegate bool NativeInterfaceCheckSynchronization(); + private delegate void NativeInterfaceEnqueueForRejit(ulong address); + private delegate ulong NativeInterfaceGetCntfrqEl0(); + private delegate ulong NativeInterfaceGetCntpctEl0(); + private delegate ulong NativeInterfaceGetCntvctEl0(); + private delegate ulong NativeInterfaceGetCtrEl0(); + private delegate ulong NativeInterfaceGetDczidEl0(); + private delegate ulong NativeInterfaceGetFunctionAddress(ulong address); + private delegate void NativeInterfaceInvalidateCacheLine(ulong address); + private delegate byte NativeInterfaceReadByte(ulong address); + private delegate ushort NativeInterfaceReadUInt16(ulong address); + private delegate uint NativeInterfaceReadUInt32(ulong address); + private delegate ulong NativeInterfaceReadUInt64(ulong address); + private delegate V128 NativeInterfaceReadVector128(ulong address); + private delegate void NativeInterfaceSignalMemoryTracking(ulong address, ulong size, bool write); + private delegate void NativeInterfaceSupervisorCall(ulong address, int imm); + private delegate void NativeInterfaceThrowInvalidMemoryAccess(ulong address); + private delegate void NativeInterfaceUndefined(ulong address, int opCode); + private delegate void NativeInterfaceWriteByte(ulong address, byte value); + private delegate void NativeInterfaceWriteUInt16(ulong address, ushort value); + private delegate void NativeInterfaceWriteUInt32(ulong address, uint value); + private delegate void NativeInterfaceWriteUInt64(ulong address, ulong value); + private delegate void NativeInterfaceWriteVector128(ulong address, V128 value); + + private delegate ulong SoftFallbackCountLeadingSigns(ulong value, int size); + private delegate ulong SoftFallbackCountLeadingZeros(ulong value, int size); + private delegate uint SoftFallbackCrc32b(uint crc, byte value); + private delegate uint SoftFallbackCrc32cb(uint crc, byte value); + private delegate uint SoftFallbackCrc32ch(uint crc, ushort value); + private delegate uint SoftFallbackCrc32cw(uint crc, uint value); + private delegate uint SoftFallbackCrc32cx(uint crc, ulong value); + private delegate uint SoftFallbackCrc32h(uint crc, ushort value); + private delegate uint SoftFallbackCrc32w(uint crc, uint value); + private delegate uint SoftFallbackCrc32x(uint crc, ulong value); + private delegate V128 SoftFallbackDecrypt(V128 value, V128 roundKey); + private delegate V128 SoftFallbackEncrypt(V128 value, V128 roundKey); + private delegate uint SoftFallbackFixedRotate(uint hash_e); + private delegate V128 SoftFallbackHashChoose(V128 hash_abcd, uint hash_e, V128 wk); + private delegate V128 SoftFallbackHashLower(V128 hash_abcd, V128 hash_efgh, V128 wk); + private delegate V128 SoftFallbackHashMajority(V128 hash_abcd, uint hash_e, V128 wk); + private delegate V128 SoftFallbackHashParity(V128 hash_abcd, uint hash_e, V128 wk); + private delegate V128 SoftFallbackHashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk); + private delegate V128 SoftFallbackInverseMixColumns(V128 value); + private delegate V128 SoftFallbackMixColumns(V128 value); + private delegate V128 SoftFallbackPolynomialMult64_128(ulong op1, ulong op2); + private delegate int SoftFallbackSatF32ToS32(float value); + private delegate long SoftFallbackSatF32ToS64(float value); + private delegate uint SoftFallbackSatF32ToU32(float value); + private delegate ulong SoftFallbackSatF32ToU64(float value); + private delegate int SoftFallbackSatF64ToS32(double value); + private delegate long SoftFallbackSatF64ToS64(double value); + private delegate uint SoftFallbackSatF64ToU32(double value); + private delegate ulong SoftFallbackSatF64ToU64(double value); + private delegate V128 SoftFallbackSha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11); + private delegate V128 SoftFallbackSha1SchedulePart2(V128 tw0_3, V128 w12_15); + private delegate V128 SoftFallbackSha256SchedulePart1(V128 w0_3, V128 w4_7); + private delegate V128 SoftFallbackSha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15); + private delegate long SoftFallbackSignedShrImm64(long value, long roundConst, int shift); + private delegate V128 SoftFallbackTbl1(V128 vector, int bytes, V128 tb0); + private delegate V128 SoftFallbackTbl2(V128 vector, int bytes, V128 tb0, V128 tb1); + private delegate V128 SoftFallbackTbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2); + private delegate V128 SoftFallbackTbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3); + private delegate V128 SoftFallbackTbx1(V128 dest, V128 vector, int bytes, V128 tb0); + private delegate V128 SoftFallbackTbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1); + private delegate V128 SoftFallbackTbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2); + private delegate V128 SoftFallbackTbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3); + private delegate ulong SoftFallbackUnsignedShrImm64(ulong value, long roundConst, int shift); + + private delegate float SoftFloat16_32FPConvert(ushort valueBits); + + private delegate double SoftFloat16_64FPConvert(ushort valueBits); + + private delegate float SoftFloat32FPAdd(float value1, float value2); + private delegate float SoftFloat32FPAddFpscr(float value1, float value2, bool standardFpscr); + private delegate int SoftFloat32FPCompare(float value1, float value2, bool signalNaNs); + private delegate float SoftFloat32FPCompareEQ(float value1, float value2); + private delegate float SoftFloat32FPCompareEQFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPCompareGE(float value1, float value2); + private delegate float SoftFloat32FPCompareGEFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPCompareGT(float value1, float value2); + private delegate float SoftFloat32FPCompareGTFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPCompareLE(float value1, float value2); + private delegate float SoftFloat32FPCompareLEFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPCompareLT(float value1, float value2); + private delegate float SoftFloat32FPCompareLTFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPDiv(float value1, float value2); + private delegate float SoftFloat32FPMax(float value1, float value2); + private delegate float SoftFloat32FPMaxFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMaxNum(float value1, float value2); + private delegate float SoftFloat32FPMaxNumFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMin(float value1, float value2); + private delegate float SoftFloat32FPMinFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMinNum(float value1, float value2); + private delegate float SoftFloat32FPMinNumFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMul(float value1, float value2); + private delegate float SoftFloat32FPMulFpscr(float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMulAdd(float valueA, float value1, float value2); + private delegate float SoftFloat32FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMulSub(float valueA, float value1, float value2); + private delegate float SoftFloat32FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr); + private delegate float SoftFloat32FPMulX(float value1, float value2); + private delegate float SoftFloat32FPNegMulAdd(float valueA, float value1, float value2); + private delegate float SoftFloat32FPNegMulSub(float valueA, float value1, float value2); + private delegate float SoftFloat32FPRecipEstimate(float value); + private delegate float SoftFloat32FPRecipEstimateFpscr(float value, bool standardFpscr); + private delegate float SoftFloat32FPRecipStep(float value1, float value2); + private delegate float SoftFloat32FPRecipStepFused(float value1, float value2); + private delegate float SoftFloat32FPRecpX(float value); + private delegate float SoftFloat32FPRSqrtEstimate(float value); + private delegate float SoftFloat32FPRSqrtEstimateFpscr(float value, bool standardFpscr); + private delegate float SoftFloat32FPRSqrtStep(float value1, float value2); + private delegate float SoftFloat32FPRSqrtStepFused(float value1, float value2); + private delegate float SoftFloat32FPSqrt(float value); + private delegate float SoftFloat32FPSub(float value1, float value2); + + private delegate ushort SoftFloat32_16FPConvert(float value); + + private delegate double SoftFloat64FPAdd(double value1, double value2); + private delegate double SoftFloat64FPAddFpscr(double value1, double value2, bool standardFpscr); + private delegate int SoftFloat64FPCompare(double value1, double value2, bool signalNaNs); + private delegate double SoftFloat64FPCompareEQ(double value1, double value2); + private delegate double SoftFloat64FPCompareEQFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPCompareGE(double value1, double value2); + private delegate double SoftFloat64FPCompareGEFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPCompareGT(double value1, double value2); + private delegate double SoftFloat64FPCompareGTFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPCompareLE(double value1, double value2); + private delegate double SoftFloat64FPCompareLEFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPCompareLT(double value1, double value2); + private delegate double SoftFloat64FPCompareLTFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPDiv(double value1, double value2); + private delegate double SoftFloat64FPMax(double value1, double value2); + private delegate double SoftFloat64FPMaxFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMaxNum(double value1, double value2); + private delegate double SoftFloat64FPMaxNumFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMin(double value1, double value2); + private delegate double SoftFloat64FPMinFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMinNum(double value1, double value2); + private delegate double SoftFloat64FPMinNumFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMul(double value1, double value2); + private delegate double SoftFloat64FPMulFpscr(double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMulAdd(double valueA, double value1, double value2); + private delegate double SoftFloat64FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMulSub(double valueA, double value1, double value2); + private delegate double SoftFloat64FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr); + private delegate double SoftFloat64FPMulX(double value1, double value2); + private delegate double SoftFloat64FPNegMulAdd(double valueA, double value1, double value2); + private delegate double SoftFloat64FPNegMulSub(double valueA, double value1, double value2); + private delegate double SoftFloat64FPRecipEstimate(double value); + private delegate double SoftFloat64FPRecipEstimateFpscr(double value, bool standardFpscr); + private delegate double SoftFloat64FPRecipStep(double value1, double value2); + private delegate double SoftFloat64FPRecipStepFused(double value1, double value2); + private delegate double SoftFloat64FPRecpX(double value); + private delegate double SoftFloat64FPRSqrtEstimate(double value); + private delegate double SoftFloat64FPRSqrtEstimateFpscr(double value, bool standardFpscr); + private delegate double SoftFloat64FPRSqrtStep(double value1, double value2); + private delegate double SoftFloat64FPRSqrtStepFused(double value1, double value2); + private delegate double SoftFloat64FPSqrt(double value); + private delegate double SoftFloat64FPSub(double value1, double value2); + + private delegate ushort SoftFloat64_16FPConvert(double value); } } diff --git a/src/ARMeilleure/Translation/DispatcherFunction.cs b/src/ARMeilleure/Translation/DispatcherFunction.cs index 7d5a3388e..649fa0f50 100644 --- a/src/ARMeilleure/Translation/DispatcherFunction.cs +++ b/src/ARMeilleure/Translation/DispatcherFunction.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Translation { diff --git a/src/ARMeilleure/Translation/Dominance.cs b/src/ARMeilleure/Translation/Dominance.cs index b9b961d15..e2185bd85 100644 --- a/src/ARMeilleure/Translation/Dominance.cs +++ b/src/ARMeilleure/Translation/Dominance.cs @@ -29,7 +29,7 @@ BasicBlock Intersect(BasicBlock block1, BasicBlock block2) cfg.Entry.ImmediateDominator = cfg.Entry; - Debug.Assert(cfg.Entry == cfg.PostOrderBlocks[cfg.PostOrderBlocks.Length - 1]); + Debug.Assert(cfg.Entry == cfg.PostOrderBlocks[^1]); bool modified; @@ -92,4 +92,4 @@ public static void FindDominanceFrontiers(ControlFlowGraph cfg) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/EmitterContext.cs b/src/ARMeilleure/Translation/EmitterContext.cs index 8fcb4deec..88bfe1335 100644 --- a/src/ARMeilleure/Translation/EmitterContext.cs +++ b/src/ARMeilleure/Translation/EmitterContext.cs @@ -108,9 +108,9 @@ public virtual Operand Call(MethodInfo info, params Operand[] callArgs) protected static OperandType GetOperandType(Type type) { - if (type == typeof(bool) || type == typeof(byte) || - type == typeof(char) || type == typeof(short) || - type == typeof(int) || type == typeof(sbyte) || + if (type == typeof(bool) || type == typeof(byte) || + type == typeof(char) || type == typeof(short) || + type == typeof(int) || type == typeof(sbyte) || type == typeof(ushort) || type == typeof(uint)) { return OperandType.I32; @@ -635,7 +635,7 @@ public void MarkLabel(Operand label, BasicBlockFrequency nextFreq = default) private void NewNextBlock() { - BasicBlock block = new BasicBlock(_irBlocks.Count); + BasicBlock block = new(_irBlocks.Count); _irBlocks.AddLast(block); diff --git a/src/ARMeilleure/Translation/GuestFunction.cs b/src/ARMeilleure/Translation/GuestFunction.cs index ac131a0d1..6414d6bd0 100644 --- a/src/ARMeilleure/Translation/GuestFunction.cs +++ b/src/ARMeilleure/Translation/GuestFunction.cs @@ -3,4 +3,4 @@ namespace ARMeilleure.Translation { delegate ulong GuestFunction(IntPtr nativeContextPtr); -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/IntervalTree.cs b/src/ARMeilleure/Translation/IntervalTree.cs index 9af01bea0..a5f9b5d5e 100644 --- a/src/ARMeilleure/Translation/IntervalTree.cs +++ b/src/ARMeilleure/Translation/IntervalTree.cs @@ -6,15 +6,15 @@ namespace ARMeilleure.Translation /// /// An Augmented Interval Tree based off of the "TreeDictionary"'s Red-Black Tree. Allows fast overlap checking of ranges. /// - /// Key - /// Value - class IntervalTree where K : IComparable + /// Key + /// Value + public class IntervalTree where TK : IComparable { private const int ArrayGrowthSize = 32; private const bool Black = true; private const bool Red = false; - private IntervalTreeNode _root = null; + private IntervalTreeNode _root = null; private int _count = 0; public int Count => _count; @@ -27,9 +27,9 @@ class IntervalTree where K : IComparable /// Key of the node value to get /// Value with the given /// True if the key is on the dictionary, false otherwise - public bool TryGet(K key, out V value) + public bool TryGet(TK key, out TV value) { - IntervalTreeNode node = GetNode(key); + IntervalTreeNode node = GetNode(key); if (node == null) { @@ -49,7 +49,7 @@ public bool TryGet(K key, out V value) /// Overlaps array to place results in /// Index to start writing results into the array. Defaults to 0 /// Number of intervals found - public int Get(K start, K end, ref K[] overlaps, int overlapCount = 0) + public int Get(TK start, TK end, ref TK[] overlaps, int overlapCount = 0) { GetKeys(_root, start, end, ref overlaps, ref overlapCount); @@ -65,11 +65,11 @@ public int Get(K start, K end, ref K[] overlaps, int overlapCount = 0) /// Optional factory used to create a new value if is already on the tree /// is null /// True if the value was added, false if the start key was already in the dictionary - public bool AddOrUpdate(K start, K end, V value, Func updateFactoryCallback) + public bool AddOrUpdate(TK start, TK end, TV value, Func updateFactoryCallback) { ArgumentNullException.ThrowIfNull(value); - return BSTInsert(start, end, value, updateFactoryCallback, out IntervalTreeNode node); + return BSTInsert(start, end, value, updateFactoryCallback, out _); } /// @@ -80,11 +80,11 @@ public bool AddOrUpdate(K start, K end, V value, Func updateFactoryCall /// Value to add /// is null /// if is not yet on the tree, or the existing value otherwise - public V GetOrAdd(K start, K end, V value) + public TV GetOrAdd(TK start, TK end, TV value) { ArgumentNullException.ThrowIfNull(value); - BSTInsert(start, end, value, null, out IntervalTreeNode node); + BSTInsert(start, end, value, null, out IntervalTreeNode node); return node.Value; } @@ -93,7 +93,7 @@ public V GetOrAdd(K start, K end, V value) /// /// Key of the node to remove /// Number of deleted values - public int Remove(K key) + public int Remove(TK key) { int removed = Delete(key); @@ -106,9 +106,9 @@ public int Remove(K key) /// Adds all the nodes in the dictionary into . /// /// A list of all values sorted by Key Order - public List AsList() + public List AsList() { - List list = new List(); + List list = new(); AddToList(_root, list); @@ -124,7 +124,7 @@ public List AsList() /// /// The node to search for values within /// The list to add values to - private void AddToList(IntervalTreeNode node, List list) + private void AddToList(IntervalTreeNode node, List list) { if (node == null) { @@ -144,11 +144,11 @@ private void AddToList(IntervalTreeNode node, List list) /// Key of the node to get /// is null /// Node reference in the tree - private IntervalTreeNode GetNode(K key) + private IntervalTreeNode GetNode(TK key) { ArgumentNullException.ThrowIfNull(key); - IntervalTreeNode node = _root; + IntervalTreeNode node = _root; while (node != null) { int cmp = key.CompareTo(node.Start); @@ -175,7 +175,7 @@ private IntervalTreeNode GetNode(K key) /// End of the range /// Overlaps array to place results in /// Overlaps count to update - private void GetKeys(IntervalTreeNode node, K start, K end, ref K[] overlaps, ref int overlapCount) + private void GetKeys(IntervalTreeNode node, TK start, TK end, ref TK[] overlaps, ref int overlapCount) { if (node == null || start.CompareTo(node.Max) >= 0) { @@ -189,7 +189,7 @@ private void GetKeys(IntervalTreeNode node, K start, K end, ref K[] overla { if (start.CompareTo(node.End) < 0) { - if (overlaps.Length >= overlapCount) + if (overlaps.Length <= overlapCount) { Array.Resize(ref overlaps, overlapCount + ArrayGrowthSize); } @@ -206,10 +206,10 @@ private void GetKeys(IntervalTreeNode node, K start, K end, ref K[] overla /// This should only be called if the max increases - not for rebalancing or removals. /// /// The node to start propagating from - private void PropagateIncrease(IntervalTreeNode node) + private static void PropagateIncrease(IntervalTreeNode node) { - K max = node.Max; - IntervalTreeNode ptr = node; + TK max = node.Max; + IntervalTreeNode ptr = node; while ((ptr = ptr.Parent) != null) { @@ -229,13 +229,13 @@ private void PropagateIncrease(IntervalTreeNode node) /// This fully recalculates the max value from all children when there is potential for it to decrease. /// /// The node to start propagating from - private void PropagateFull(IntervalTreeNode node) + private static void PropagateFull(IntervalTreeNode node) { - IntervalTreeNode ptr = node; + IntervalTreeNode ptr = node; do { - K max = ptr.End; + TK max = ptr.End; if (ptr.Left != null && ptr.Left.Max.CompareTo(max) > 0) { @@ -263,10 +263,10 @@ private void PropagateFull(IntervalTreeNode node) /// Optional factory used to create a new value if is already on the tree /// Node that was inserted or modified /// True if was not yet on the tree, false otherwise - private bool BSTInsert(K start, K end, V value, Func updateFactoryCallback, out IntervalTreeNode outNode) + private bool BSTInsert(TK start, TK end, TV value, Func updateFactoryCallback, out IntervalTreeNode outNode) { - IntervalTreeNode parent = null; - IntervalTreeNode node = _root; + IntervalTreeNode parent = null; + IntervalTreeNode node = _root; while (node != null) { @@ -311,7 +311,7 @@ private bool BSTInsert(K start, K end, V value, Func updateFactoryCallb return false; } } - IntervalTreeNode newNode = new IntervalTreeNode(start, end, value, parent); + IntervalTreeNode newNode = new(start, end, value, parent); if (newNode.Parent == null) { _root = newNode; @@ -337,16 +337,16 @@ private bool BSTInsert(K start, K end, V value, Func updateFactoryCallb /// /// Key to search for /// Number of deleted values - private int Delete(K key) + private int Delete(TK key) { - IntervalTreeNode nodeToDelete = GetNode(key); + IntervalTreeNode nodeToDelete = GetNode(key); if (nodeToDelete == null) { return 0; } - IntervalTreeNode replacementNode; + IntervalTreeNode replacementNode; if (LeftOf(nodeToDelete) == null || RightOf(nodeToDelete) == null) { @@ -357,7 +357,7 @@ private int Delete(K key) replacementNode = PredecessorOf(nodeToDelete); } - IntervalTreeNode tmp = LeftOf(replacementNode) ?? RightOf(replacementNode); + IntervalTreeNode tmp = LeftOf(replacementNode) ?? RightOf(replacementNode); if (tmp != null) { @@ -400,9 +400,9 @@ private int Delete(K key) /// /// Root Node /// Node with the maximum key in the tree of - private static IntervalTreeNode Maximum(IntervalTreeNode node) + private static IntervalTreeNode Maximum(IntervalTreeNode node) { - IntervalTreeNode tmp = node; + IntervalTreeNode tmp = node; while (tmp.Right != null) { tmp = tmp.Right; @@ -416,13 +416,13 @@ private static IntervalTreeNode Maximum(IntervalTreeNode node) /// /// Node to find the predecessor of /// Predecessor of - private static IntervalTreeNode PredecessorOf(IntervalTreeNode node) + private static IntervalTreeNode PredecessorOf(IntervalTreeNode node) { if (node.Left != null) { return Maximum(node.Left); } - IntervalTreeNode parent = node.Parent; + IntervalTreeNode parent = node.Parent; while (parent != null && node == parent.Left) { node = parent; @@ -435,15 +435,15 @@ private static IntervalTreeNode PredecessorOf(IntervalTreeNode node) #region Private Methods (RBL) - private void RestoreBalanceAfterRemoval(IntervalTreeNode balanceNode) + private void RestoreBalanceAfterRemoval(IntervalTreeNode balanceNode) { - IntervalTreeNode ptr = balanceNode; + IntervalTreeNode ptr = balanceNode; while (ptr != _root && ColorOf(ptr) == Black) { if (ptr == LeftOf(ParentOf(ptr))) { - IntervalTreeNode sibling = RightOf(ParentOf(ptr)); + IntervalTreeNode sibling = RightOf(ParentOf(ptr)); if (ColorOf(sibling) == Red) { @@ -475,7 +475,7 @@ private void RestoreBalanceAfterRemoval(IntervalTreeNode balanceNode) } else { - IntervalTreeNode sibling = LeftOf(ParentOf(ptr)); + IntervalTreeNode sibling = LeftOf(ParentOf(ptr)); if (ColorOf(sibling) == Red) { @@ -509,14 +509,14 @@ private void RestoreBalanceAfterRemoval(IntervalTreeNode balanceNode) SetColor(ptr, Black); } - private void RestoreBalanceAfterInsertion(IntervalTreeNode balanceNode) + private void RestoreBalanceAfterInsertion(IntervalTreeNode balanceNode) { SetColor(balanceNode, Red); while (balanceNode != null && balanceNode != _root && ColorOf(ParentOf(balanceNode)) == Red) { if (ParentOf(balanceNode) == LeftOf(ParentOf(ParentOf(balanceNode)))) { - IntervalTreeNode sibling = RightOf(ParentOf(ParentOf(balanceNode))); + IntervalTreeNode sibling = RightOf(ParentOf(ParentOf(balanceNode))); if (ColorOf(sibling) == Red) { @@ -539,7 +539,7 @@ private void RestoreBalanceAfterInsertion(IntervalTreeNode balanceNode) } else { - IntervalTreeNode sibling = LeftOf(ParentOf(ParentOf(balanceNode))); + IntervalTreeNode sibling = LeftOf(ParentOf(ParentOf(balanceNode))); if (ColorOf(sibling) == Red) { @@ -564,17 +564,17 @@ private void RestoreBalanceAfterInsertion(IntervalTreeNode balanceNode) SetColor(_root, Black); } - private void RotateLeft(IntervalTreeNode node) + private void RotateLeft(IntervalTreeNode node) { if (node != null) { - IntervalTreeNode right = RightOf(node); + IntervalTreeNode right = RightOf(node); node.Right = LeftOf(right); if (node.Right != null) { node.Right.Parent = node; } - IntervalTreeNode nodeParent = ParentOf(node); + IntervalTreeNode nodeParent = ParentOf(node); right.Parent = nodeParent; if (nodeParent == null) { @@ -595,17 +595,17 @@ private void RotateLeft(IntervalTreeNode node) } } - private void RotateRight(IntervalTreeNode node) + private void RotateRight(IntervalTreeNode node) { if (node != null) { - IntervalTreeNode left = LeftOf(node); + IntervalTreeNode left = LeftOf(node); node.Left = RightOf(left); if (node.Left != null) { node.Left.Parent = node; } - IntervalTreeNode nodeParent = ParentOf(node); + IntervalTreeNode nodeParent = ParentOf(node); left.Parent = nodeParent; if (nodeParent == null) { @@ -637,7 +637,7 @@ private void RotateRight(IntervalTreeNode node) /// /// Node /// The boolean color of , or black if null - private static bool ColorOf(IntervalTreeNode node) + private static bool ColorOf(IntervalTreeNode node) { return node == null || node.Color; } @@ -649,7 +649,7 @@ private static bool ColorOf(IntervalTreeNode node) /// /// Node to set the color of /// Color (Boolean) - private static void SetColor(IntervalTreeNode node, bool color) + private static void SetColor(IntervalTreeNode node, bool color) { if (node != null) { @@ -662,7 +662,7 @@ private static void SetColor(IntervalTreeNode node, bool color) /// /// Node to retrieve the left child from /// Left child of - private static IntervalTreeNode LeftOf(IntervalTreeNode node) + private static IntervalTreeNode LeftOf(IntervalTreeNode node) { return node?.Left; } @@ -672,7 +672,7 @@ private static IntervalTreeNode LeftOf(IntervalTreeNode node) /// /// Node to retrieve the right child from /// Right child of - private static IntervalTreeNode RightOf(IntervalTreeNode node) + private static IntervalTreeNode RightOf(IntervalTreeNode node) { return node?.Right; } @@ -682,14 +682,14 @@ private static IntervalTreeNode RightOf(IntervalTreeNode node) /// /// Node to retrieve the parent from /// Parent of - private static IntervalTreeNode ParentOf(IntervalTreeNode node) + private static IntervalTreeNode ParentOf(IntervalTreeNode node) { return node?.Parent; } #endregion - public bool ContainsKey(K key) + public bool ContainsKey(TK key) { return GetNode(key) != null; } @@ -704,36 +704,36 @@ public void Clear() /// /// Represents a node in the IntervalTree which contains start and end keys of type K, and a value of generic type V. /// - /// Key type of the node - /// Value type of the node - class IntervalTreeNode + /// Key type of the node + /// Value type of the node + class IntervalTreeNode { public bool Color = true; - public IntervalTreeNode Left = null; - public IntervalTreeNode Right = null; - public IntervalTreeNode Parent = null; + public IntervalTreeNode Left = null; + public IntervalTreeNode Right = null; + public IntervalTreeNode Parent = null; /// /// The start of the range. /// - public K Start; + public TK Start; /// /// The end of the range. /// - public K End; + public TK End; /// /// The maximum end value of this node and all its children. /// - public K Max; + public TK Max; /// /// Value stored on this node. /// - public V Value; + public TV Value; - public IntervalTreeNode(K start, K end, V value, IntervalTreeNode parent) + public IntervalTreeNode(TK start, TK end, TV value, IntervalTreeNode parent) { Start = start; End = end; diff --git a/src/ARMeilleure/Translation/PTC/EncodingCache.cs b/src/ARMeilleure/Translation/PTC/EncodingCache.cs index 90d40c475..d9b38ace7 100644 --- a/src/ARMeilleure/Translation/PTC/EncodingCache.cs +++ b/src/ARMeilleure/Translation/PTC/EncodingCache.cs @@ -6,4 +6,4 @@ static class EncodingCache { public static readonly Encoding UTF8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/PTC/IPtcLoadState.cs b/src/ARMeilleure/Translation/PTC/IPtcLoadState.cs index 1b11ac0b5..efff45a9f 100644 --- a/src/ARMeilleure/Translation/PTC/IPtcLoadState.cs +++ b/src/ARMeilleure/Translation/PTC/IPtcLoadState.cs @@ -7,4 +7,4 @@ public interface IPtcLoadState event Action PtcStateChanged; void Continue(); } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs index ea4e715b5..6f6dfcadf 100644 --- a/src/ARMeilleure/Translation/PTC/Ptc.cs +++ b/src/ARMeilleure/Translation/PTC/Ptc.cs @@ -17,20 +17,19 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; - using static ARMeilleure.Translation.PTC.PtcFormatter; namespace ARMeilleure.Translation.PTC { - using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities; - using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities; + using Arm64HardwareCapabilities = CodeGen.Arm64.HardwareCapabilities; + using X86HardwareCapabilities = CodeGen.X86.HardwareCapabilities; class Ptc : IPtcLoadState { private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 4661; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 5518; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1"; @@ -187,8 +186,8 @@ private void PreLoad() string fileNameActual = $"{CachePathActual}.cache"; string fileNameBackup = $"{CachePathBackup}.cache"; - FileInfo fileInfoActual = new FileInfo(fileNameActual); - FileInfo fileInfoBackup = new FileInfo(fileNameBackup); + FileInfo fileInfoActual = new(fileNameActual); + FileInfo fileInfoBackup = new(fileNameBackup); if (fileInfoActual.Exists && fileInfoActual.Length != 0L) { @@ -275,104 +274,102 @@ private unsafe bool Load(string fileName, bool isBackup) { intPtr = Marshal.AllocHGlobal(new IntPtr(outerHeader.UncompressedStreamSize)); - using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite)) + using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite); + try { - try - { - deflateStream.CopyTo(stream); - } - catch - { - InvalidateCompressedStream(compressedStream); + deflateStream.CopyTo(stream); + } + catch + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - Debug.Assert(stream.Position == stream.Length); + Debug.Assert(stream.Position == stream.Length); - stream.Seek(0L, SeekOrigin.Begin); + stream.Seek(0L, SeekOrigin.Begin); - InnerHeader innerHeader = DeserializeStructure(stream); + InnerHeader innerHeader = DeserializeStructure(stream); - if (!innerHeader.IsHeaderValid()) - { - InvalidateCompressedStream(compressedStream); + if (!innerHeader.IsHeaderValid()) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - if (innerHeader.Magic != _innerHeaderMagic) - { - InvalidateCompressedStream(compressedStream); + if (innerHeader.Magic != _innerHeaderMagic) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - ReadOnlySpan infosBytes = new(stream.PositionPointer, innerHeader.InfosLength); - stream.Seek(innerHeader.InfosLength, SeekOrigin.Current); + ReadOnlySpan infosBytes = new(stream.PositionPointer, innerHeader.InfosLength); + stream.Seek(innerHeader.InfosLength, SeekOrigin.Current); - Hash128 infosHash = XXHash128.ComputeHash(infosBytes); + Hash128 infosHash = XXHash128.ComputeHash(infosBytes); - if (innerHeader.InfosHash != infosHash) - { - InvalidateCompressedStream(compressedStream); + if (innerHeader.InfosHash != infosHash) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - ReadOnlySpan codesBytes = (int)innerHeader.CodesLength > 0 ? new(stream.PositionPointer, (int)innerHeader.CodesLength) : ReadOnlySpan.Empty; - stream.Seek(innerHeader.CodesLength, SeekOrigin.Current); + ReadOnlySpan codesBytes = (int)innerHeader.CodesLength > 0 ? new(stream.PositionPointer, (int)innerHeader.CodesLength) : ReadOnlySpan.Empty; + stream.Seek(innerHeader.CodesLength, SeekOrigin.Current); - Hash128 codesHash = XXHash128.ComputeHash(codesBytes); + Hash128 codesHash = XXHash128.ComputeHash(codesBytes); - if (innerHeader.CodesHash != codesHash) - { - InvalidateCompressedStream(compressedStream); + if (innerHeader.CodesHash != codesHash) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - ReadOnlySpan relocsBytes = new(stream.PositionPointer, innerHeader.RelocsLength); - stream.Seek(innerHeader.RelocsLength, SeekOrigin.Current); + ReadOnlySpan relocsBytes = new(stream.PositionPointer, innerHeader.RelocsLength); + stream.Seek(innerHeader.RelocsLength, SeekOrigin.Current); - Hash128 relocsHash = XXHash128.ComputeHash(relocsBytes); + Hash128 relocsHash = XXHash128.ComputeHash(relocsBytes); - if (innerHeader.RelocsHash != relocsHash) - { - InvalidateCompressedStream(compressedStream); + if (innerHeader.RelocsHash != relocsHash) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - ReadOnlySpan unwindInfosBytes = new(stream.PositionPointer, innerHeader.UnwindInfosLength); - stream.Seek(innerHeader.UnwindInfosLength, SeekOrigin.Current); + ReadOnlySpan unwindInfosBytes = new(stream.PositionPointer, innerHeader.UnwindInfosLength); + stream.Seek(innerHeader.UnwindInfosLength, SeekOrigin.Current); - Hash128 unwindInfosHash = XXHash128.ComputeHash(unwindInfosBytes); + Hash128 unwindInfosHash = XXHash128.ComputeHash(unwindInfosBytes); - if (innerHeader.UnwindInfosHash != unwindInfosHash) - { - InvalidateCompressedStream(compressedStream); + if (innerHeader.UnwindInfosHash != unwindInfosHash) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - Debug.Assert(stream.Position == stream.Length); + Debug.Assert(stream.Position == stream.Length); - stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); + stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); - _infosStream.Write(infosBytes); - stream.Seek(innerHeader.InfosLength, SeekOrigin.Current); + _infosStream.Write(infosBytes); + stream.Seek(innerHeader.InfosLength, SeekOrigin.Current); - _codesList.ReadFrom(stream); + _codesList.ReadFrom(stream); - _relocsStream.Write(relocsBytes); - stream.Seek(innerHeader.RelocsLength, SeekOrigin.Current); + _relocsStream.Write(relocsBytes); + stream.Seek(innerHeader.RelocsLength, SeekOrigin.Current); - _unwindInfosStream.Write(unwindInfosBytes); - stream.Seek(innerHeader.UnwindInfosLength, SeekOrigin.Current); + _unwindInfosStream.Write(unwindInfosBytes); + stream.Seek(innerHeader.UnwindInfosLength, SeekOrigin.Current); - Debug.Assert(stream.Position == stream.Length); - } + Debug.Assert(stream.Position == stream.Length); } finally { @@ -390,7 +387,7 @@ private unsafe bool Load(string fileName, bool isBackup) return true; } - private void InvalidateCompressedStream(FileStream compressedStream) + private static void InvalidateCompressedStream(FileStream compressedStream) { compressedStream.SetLength(0L); } @@ -404,7 +401,7 @@ private void PreSave() string fileNameActual = $"{CachePathActual}.cache"; string fileNameBackup = $"{CachePathBackup}.cache"; - FileInfo fileInfoActual = new FileInfo(fileNameActual); + FileInfo fileInfoActual = new(fileNameActual); if (fileInfoActual.Exists && fileInfoActual.Length != 0L) { @@ -427,32 +424,34 @@ private unsafe void Save(string fileName) { int translatedFuncsCount; - InnerHeader innerHeader = new InnerHeader(); - - innerHeader.Magic = _innerHeaderMagic; - - innerHeader.InfosLength = (int)_infosStream.Length; - innerHeader.CodesLength = _codesList.Length(); - innerHeader.RelocsLength = (int)_relocsStream.Length; - innerHeader.UnwindInfosLength = (int)_unwindInfosStream.Length; + InnerHeader innerHeader = new() + { + Magic = _innerHeaderMagic, - OuterHeader outerHeader = new OuterHeader(); + InfosLength = (int)_infosStream.Length, + CodesLength = _codesList.Length(), + RelocsLength = (int)_relocsStream.Length, + UnwindInfosLength = (int)_unwindInfosStream.Length, + }; - outerHeader.Magic = _outerHeaderMagic; + OuterHeader outerHeader = new() + { + Magic = _outerHeaderMagic, - outerHeader.CacheFileVersion = InternalVersion; - outerHeader.Endianness = GetEndianness(); - outerHeader.FeatureInfo = GetFeatureInfo(); - outerHeader.MemoryManagerMode = GetMemoryManagerMode(); - outerHeader.OSPlatform = GetOSPlatform(); - outerHeader.Architecture = (uint)RuntimeInformation.ProcessArchitecture; + CacheFileVersion = InternalVersion, + Endianness = GetEndianness(), + FeatureInfo = GetFeatureInfo(), + MemoryManagerMode = GetMemoryManagerMode(), + OSPlatform = GetOSPlatform(), + Architecture = (uint)RuntimeInformation.ProcessArchitecture, - outerHeader.UncompressedStreamSize = + UncompressedStreamSize = (long)Unsafe.SizeOf() + innerHeader.InfosLength + innerHeader.CodesLength + innerHeader.RelocsLength + - innerHeader.UnwindInfosLength; + innerHeader.UnwindInfosLength, + }; outerHeader.SetHeaderHash(); @@ -462,58 +461,54 @@ private unsafe void Save(string fileName) { intPtr = Marshal.AllocHGlobal(new IntPtr(outerHeader.UncompressedStreamSize)); - using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite)) - { - stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); + using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite); + stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); - ReadOnlySpan infosBytes = new(stream.PositionPointer, innerHeader.InfosLength); - _infosStream.WriteTo(stream); + ReadOnlySpan infosBytes = new(stream.PositionPointer, innerHeader.InfosLength); + _infosStream.WriteTo(stream); - ReadOnlySpan codesBytes = (int)innerHeader.CodesLength > 0 ? new(stream.PositionPointer, (int)innerHeader.CodesLength) : ReadOnlySpan.Empty; - _codesList.WriteTo(stream); + ReadOnlySpan codesBytes = (int)innerHeader.CodesLength > 0 ? new(stream.PositionPointer, (int)innerHeader.CodesLength) : ReadOnlySpan.Empty; + _codesList.WriteTo(stream); - ReadOnlySpan relocsBytes = new(stream.PositionPointer, innerHeader.RelocsLength); - _relocsStream.WriteTo(stream); + ReadOnlySpan relocsBytes = new(stream.PositionPointer, innerHeader.RelocsLength); + _relocsStream.WriteTo(stream); - ReadOnlySpan unwindInfosBytes = new(stream.PositionPointer, innerHeader.UnwindInfosLength); - _unwindInfosStream.WriteTo(stream); + ReadOnlySpan unwindInfosBytes = new(stream.PositionPointer, innerHeader.UnwindInfosLength); + _unwindInfosStream.WriteTo(stream); - Debug.Assert(stream.Position == stream.Length); + Debug.Assert(stream.Position == stream.Length); - innerHeader.InfosHash = XXHash128.ComputeHash(infosBytes); - innerHeader.CodesHash = XXHash128.ComputeHash(codesBytes); - innerHeader.RelocsHash = XXHash128.ComputeHash(relocsBytes); - innerHeader.UnwindInfosHash = XXHash128.ComputeHash(unwindInfosBytes); + innerHeader.InfosHash = XXHash128.ComputeHash(infosBytes); + innerHeader.CodesHash = XXHash128.ComputeHash(codesBytes); + innerHeader.RelocsHash = XXHash128.ComputeHash(relocsBytes); + innerHeader.UnwindInfosHash = XXHash128.ComputeHash(unwindInfosBytes); - innerHeader.SetHeaderHash(); + innerHeader.SetHeaderHash(); - stream.Seek(0L, SeekOrigin.Begin); - SerializeStructure(stream, innerHeader); + stream.Seek(0L, SeekOrigin.Begin); + SerializeStructure(stream, innerHeader); - translatedFuncsCount = GetEntriesCount(); + translatedFuncsCount = GetEntriesCount(); - ResetCarriersIfNeeded(); + ResetCarriersIfNeeded(); - using (FileStream compressedStream = new(fileName, FileMode.OpenOrCreate)) - using (DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true)) - { - try - { - SerializeStructure(compressedStream, outerHeader); + using FileStream compressedStream = new(fileName, FileMode.OpenOrCreate); + using DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true); + try + { + SerializeStructure(compressedStream, outerHeader); - stream.Seek(0L, SeekOrigin.Begin); - stream.CopyTo(deflateStream); - } - catch - { - compressedStream.Position = 0L; - } + stream.Seek(0L, SeekOrigin.Begin); + stream.CopyTo(deflateStream); + } + catch + { + compressedStream.Position = 0L; + } - if (compressedStream.Position < compressedStream.Length) - { - compressedStream.SetLength(compressedStream.Position); - } - } + if (compressedStream.Position < compressedStream.Length) + { + compressedStream.SetLength(compressedStream.Position); } } finally @@ -647,7 +642,7 @@ private byte[] ReadCode(int index, int codeLength) return _codesList[index]; } - private RelocEntry[] GetRelocEntries(BinaryReader relocsReader, int relocEntriesCount) + private static RelocEntry[] GetRelocEntries(BinaryReader relocsReader, int relocEntriesCount) { RelocEntry[] relocEntries = new RelocEntry[relocEntriesCount]; @@ -663,7 +658,7 @@ private RelocEntry[] GetRelocEntries(BinaryReader relocsReader, int relocEntries return relocEntries; } - private void PatchCode(Translator translator, Span code, RelocEntry[] relocEntries, out Counter callCounter) + private static void PatchCode(Translator translator, Span code, RelocEntry[] relocEntries, out Counter callCounter) { callCounter = null; @@ -678,7 +673,10 @@ private void PatchCode(Translator translator, Span code, RelocEntry[] relo if (translator.FunctionTable.IsValid(guestAddress)) { - unsafe { imm = (IntPtr)Unsafe.AsPointer(ref translator.FunctionTable.GetValue(guestAddress)); } + unsafe + { + imm = (IntPtr)Unsafe.AsPointer(ref translator.FunctionTable.GetValue(guestAddress)); + } } } else if (symbol.Type == SymbolType.DelegateTable) @@ -696,12 +694,12 @@ private void PatchCode(Translator translator, Span code, RelocEntry[] relo } else if (symbol == CountTableSymbol) { - if (callCounter == null) + callCounter ??= new Counter(translator.CountTable); + + unsafe { - callCounter = new Counter(translator.CountTable); + imm = (IntPtr)Unsafe.AsPointer(ref callCounter.Value); } - - unsafe { imm = (IntPtr)Unsafe.AsPointer(ref callCounter.Value); } } else if (symbol == DispatchStubSymbol) { @@ -717,7 +715,7 @@ private void PatchCode(Translator translator, Span code, RelocEntry[] relo } } - private UnwindInfo ReadUnwindInfo(BinaryReader unwindInfosReader) + private static UnwindInfo ReadUnwindInfo(BinaryReader unwindInfosReader) { int pushEntriesLength = unwindInfosReader.ReadInt32(); @@ -738,7 +736,7 @@ private UnwindInfo ReadUnwindInfo(BinaryReader unwindInfosReader) return new UnwindInfo(pushEntries, prologueSize); } - private TranslatedFunction FastTranslate( + private static TranslatedFunction FastTranslate( byte[] code, Counter callCounter, ulong guestSize, @@ -809,13 +807,13 @@ public void MakeAndSaveTranslations(Translator translator) PtcStateChanged?.Invoke(PtcLoadingState.Start, _translateCount, _translateTotalCount); - using AutoResetEvent progressReportEvent = new AutoResetEvent(false); + using AutoResetEvent progressReportEvent = new(false); - Thread progressReportThread = new Thread(ReportProgress) + Thread progressReportThread = new(ReportProgress) { Name = "Ptc.ProgressReporter", Priority = ThreadPriority.Lowest, - IsBackground = true + IsBackground = true, }; progressReportThread.Start(progressReportEvent); @@ -845,12 +843,14 @@ void TranslateFuncs() } } - List threads = new List(); + List threads = new(); for (int i = 0; i < degreeOfParallelism; i++) { - Thread thread = new Thread(TranslateFuncs); - thread.IsBackground = true; + Thread thread = new(TranslateFuncs) + { + IsBackground = true, + }; threads.Add(thread); } @@ -871,14 +871,16 @@ void TranslateFuncs() Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s"); - Thread preSaveThread = new Thread(PreSave); - preSaveThread.IsBackground = true; + Thread preSaveThread = new(PreSave) + { + IsBackground = true, + }; preSaveThread.Start(); } private void ReportProgress(object state) { - const int refreshRate = 50; // ms. + const int RefreshRate = 50; // ms. AutoResetEvent endEvent = (AutoResetEvent)state; @@ -894,7 +896,7 @@ private void ReportProgress(object state) count = newCount; } } - while (!endEvent.WaitOne(refreshRate)); + while (!endEvent.WaitOne(RefreshRate)); } public static Hash128 ComputeHash(IMemoryManager memory, ulong address, ulong guestSize) @@ -910,15 +912,16 @@ public void WriteCompiledFunction(ulong address, ulong guestSize, Hash128 hash, RelocInfo relocInfo = compiledFunc.RelocInfo; UnwindInfo unwindInfo = compiledFunc.UnwindInfo; - InfoEntry infoEntry = new InfoEntry(); - - infoEntry.Address = address; - infoEntry.GuestSize = guestSize; - infoEntry.Hash = hash; - infoEntry.HighCq = highCq; - infoEntry.Stubbed = false; - infoEntry.CodeLength = code.Length; - infoEntry.RelocEntriesCount = relocInfo.Entries.Length; + InfoEntry infoEntry = new() + { + Address = address, + GuestSize = guestSize, + Hash = hash, + HighCq = highCq, + Stubbed = false, + CodeLength = code.Length, + RelocEntriesCount = relocInfo.Entries.Length, + }; SerializeStructure(_infosStream, infoEntry); @@ -996,10 +999,12 @@ private static uint GetOSPlatform() { uint osPlatform = 0u; +#pragma warning disable IDE0055 // Disable formatting osPlatform |= (OperatingSystem.IsFreeBSD() ? 1u : 0u) << 0; osPlatform |= (OperatingSystem.IsLinux() ? 1u : 0u) << 1; osPlatform |= (OperatingSystem.IsMacOS() ? 1u : 0u) << 2; osPlatform |= (OperatingSystem.IsWindows() ? 1u : 0u) << 3; +#pragma warning restore IDE0055 return osPlatform; } @@ -1025,14 +1030,14 @@ public void SetHeaderHash() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())); + HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]); } public bool IsHeaderValid() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())) == HeaderHash; + return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]) == HeaderHash; } } @@ -1060,14 +1065,14 @@ public void SetHeaderHash() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())); + HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]); } public bool IsHeaderValid() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())) == HeaderHash; + return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]) == HeaderHash; } } diff --git a/src/ARMeilleure/Translation/PTC/PtcFormatter.cs b/src/ARMeilleure/Translation/PTC/PtcFormatter.cs index 2f7a9c21f..60953dcd9 100644 --- a/src/ARMeilleure/Translation/PTC/PtcFormatter.cs +++ b/src/ARMeilleure/Translation/PTC/PtcFormatter.cs @@ -27,6 +27,26 @@ public static Dictionary DeserializeDictionary(Strea return dictionary; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Dictionary DeserializeAndUpdateDictionary(Stream stream, Func valueFunc, Func updateFunc) where TKey : struct + { + Dictionary dictionary = new(); + + int count = DeserializeStructure(stream); + + for (int i = 0; i < count; i++) + { + TKey key = DeserializeStructure(stream); + TValue value = valueFunc(stream); + + (key, value) = updateFunc(key, value); + + dictionary.Add(key, value); + } + + return dictionary; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List DeserializeList(Stream stream) where T : struct { @@ -47,7 +67,7 @@ public static List DeserializeList(Stream stream) where T : struct [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T DeserializeStructure(Stream stream) where T : struct { - T structure = default(T); + T structure = default; Span spanT = MemoryMarshal.CreateSpan(ref structure, 1); int bytesCount = stream.Read(MemoryMarshal.AsBytes(spanT)); @@ -176,4 +196,4 @@ public static void WriteTo(this List list, Stream stream) where T : stru } #endregion } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/PTC/PtcLoadingState.cs b/src/ARMeilleure/Translation/PTC/PtcLoadingState.cs index 526cf91fb..587be7939 100644 --- a/src/ARMeilleure/Translation/PTC/PtcLoadingState.cs +++ b/src/ARMeilleure/Translation/PTC/PtcLoadingState.cs @@ -4,6 +4,6 @@ public enum PtcLoadingState { Start, Loading, - Loaded + Loaded, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs index 391e29c76..0fe78edab 100644 --- a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs +++ b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs @@ -9,11 +9,13 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; - +using System.Timers; using static ARMeilleure.Translation.PTC.PtcFormatter; +using Timer = System.Timers.Timer; namespace ARMeilleure.Translation.PTC { @@ -21,7 +23,11 @@ class PtcProfiler { private const string OuterHeaderMagicString = "Pohd\0\0\0\0"; - private const uint InternalVersion = 1866; //! Not to be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 5518; //! Not to be incremented manually for each change to the ARMeilleure project. + + private static readonly uint[] _migrateInternalVersions = { + 1866, + }; private const int SaveInterval = 30; // Seconds. @@ -29,7 +35,7 @@ class PtcProfiler private readonly Ptc _ptc; - private readonly System.Timers.Timer _timer; + private readonly Timer _timer; private readonly ulong _outerHeaderMagic; @@ -46,13 +52,13 @@ class PtcProfiler public bool Enabled { get; private set; } public ulong StaticCodeStart { get; set; } - public ulong StaticCodeSize { get; set; } + public ulong StaticCodeSize { get; set; } public PtcProfiler(Ptc ptc) { _ptc = ptc; - _timer = new System.Timers.Timer((double)SaveInterval * 1000d); + _timer = new Timer(SaveInterval * 1000d); _timer.Elapsed += PreSave; _outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan()); @@ -129,8 +135,8 @@ public void PreLoad() string fileNameActual = $"{_ptc.CachePathActual}.info"; string fileNameBackup = $"{_ptc.CachePathBackup}.info"; - FileInfo fileInfoActual = new FileInfo(fileNameActual); - FileInfo fileInfoBackup = new FileInfo(fileNameBackup); + FileInfo fileInfoActual = new(fileNameActual); + FileInfo fileInfoBackup = new(fileNameBackup); if (fileInfoActual.Exists && fileInfoActual.Length != 0L) { @@ -169,7 +175,7 @@ private bool Load(string fileName, bool isBackup) return false; } - if (outerHeader.InfoFileVersion != InternalVersion) + if (outerHeader.InfoFileVersion != InternalVersion && !_migrateInternalVersions.Contains(outerHeader.InfoFileVersion)) { InvalidateCompressedStream(compressedStream); @@ -183,42 +189,52 @@ private bool Load(string fileName, bool isBackup) return false; } - using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) + using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); + Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); + + try + { + deflateStream.CopyTo(stream); + } + catch { - Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); + InvalidateCompressedStream(compressedStream); - try - { - deflateStream.CopyTo(stream); - } - catch - { - InvalidateCompressedStream(compressedStream); + return false; + } - return false; - } + Debug.Assert(stream.Position == stream.Length); - Debug.Assert(stream.Position == stream.Length); + stream.Seek(0L, SeekOrigin.Begin); - stream.Seek(0L, SeekOrigin.Begin); + Hash128 expectedHash = DeserializeStructure(stream); - Hash128 expectedHash = DeserializeStructure(stream); + Hash128 actualHash = XXHash128.ComputeHash(GetReadOnlySpan(stream)); - Hash128 actualHash = XXHash128.ComputeHash(GetReadOnlySpan(stream)); + if (actualHash != expectedHash) + { + InvalidateCompressedStream(compressedStream); - if (actualHash != expectedHash) - { - InvalidateCompressedStream(compressedStream); + return false; + } + switch (outerHeader.InfoFileVersion) + { + case InternalVersion: + ProfiledFuncs = Deserialize(stream); + break; + case 1866: + ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile)); + break; + default: + Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache."); + InvalidateCompressedStream(compressedStream); return false; - } - - ProfiledFuncs = Deserialize(stream); + } - Debug.Assert(stream.Position == stream.Length); + Debug.Assert(stream.Position == stream.Length); - _lastHash = actualHash; - } + _lastHash = actualHash; } long fileSize = new FileInfo(fileName).Length; @@ -228,29 +244,34 @@ private bool Load(string fileName, bool isBackup) return true; } - private static Dictionary Deserialize(Stream stream) + private static Dictionary Deserialize(Stream stream, Func migrateEntryFunc = null) { - return DeserializeDictionary(stream, (stream) => DeserializeStructure(stream)); + if (migrateEntryFunc != null) + { + return DeserializeAndUpdateDictionary(stream, DeserializeStructure, migrateEntryFunc); + } + + return DeserializeDictionary(stream, DeserializeStructure); } - private ReadOnlySpan GetReadOnlySpan(MemoryStream memoryStream) + private static ReadOnlySpan GetReadOnlySpan(MemoryStream memoryStream) { return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position); } - private void InvalidateCompressedStream(FileStream compressedStream) + private static void InvalidateCompressedStream(FileStream compressedStream) { compressedStream.SetLength(0L); } - private void PreSave(object source, System.Timers.ElapsedEventArgs e) + private void PreSave(object source, ElapsedEventArgs e) { _waitEvent.Reset(); string fileNameActual = $"{_ptc.CachePathActual}.info"; string fileNameBackup = $"{_ptc.CachePathBackup}.info"; - FileInfo fileInfoActual = new FileInfo(fileNameActual); + FileInfo fileInfoActual = new(fileNameActual); if (fileInfoActual.Exists && fileInfoActual.Length != 0L) { @@ -266,12 +287,13 @@ private void Save(string fileName) { int profiledFuncsCount; - OuterHeader outerHeader = new OuterHeader(); - - outerHeader.Magic = _outerHeaderMagic; + OuterHeader outerHeader = new() + { + Magic = _outerHeaderMagic, - outerHeader.InfoFileVersion = InternalVersion; - outerHeader.Endianness = Ptc.GetEndianness(); + InfoFileVersion = InternalVersion, + Endianness = Ptc.GetEndianness(), + }; outerHeader.SetHeaderHash(); @@ -279,7 +301,7 @@ private void Save(string fileName) { Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); - stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); + stream.Seek(Unsafe.SizeOf(), SeekOrigin.Begin); lock (_lock) { @@ -290,7 +312,7 @@ private void Save(string fileName) Debug.Assert(stream.Position == stream.Length); - stream.Seek((long)Unsafe.SizeOf(), SeekOrigin.Begin); + stream.Seek(Unsafe.SizeOf(), SeekOrigin.Begin); Hash128 hash = XXHash128.ComputeHash(GetReadOnlySpan(stream)); stream.Seek(0L, SeekOrigin.Begin); @@ -301,28 +323,26 @@ private void Save(string fileName) return; } - using (FileStream compressedStream = new(fileName, FileMode.OpenOrCreate)) - using (DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true)) + using FileStream compressedStream = new(fileName, FileMode.OpenOrCreate); + using DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true); + try { - try - { - SerializeStructure(compressedStream, outerHeader); + SerializeStructure(compressedStream, outerHeader); - stream.WriteTo(deflateStream); + stream.WriteTo(deflateStream); - _lastHash = hash; - } - catch - { - compressedStream.Position = 0L; + _lastHash = hash; + } + catch + { + compressedStream.Position = 0L; - _lastHash = default; - } + _lastHash = default; + } - if (compressedStream.Position < compressedStream.Length) - { - compressedStream.SetLength(compressedStream.Position); - } + if (compressedStream.Position < compressedStream.Length) + { + compressedStream.SetLength(compressedStream.Position); } } @@ -334,9 +354,9 @@ private void Save(string fileName) } } - private void Serialize(Stream stream, Dictionary profiledFuncs) + private static void Serialize(Stream stream, Dictionary profiledFuncs) { - SerializeDictionary(stream, profiledFuncs, (stream, structure) => SerializeStructure(stream, structure)); + SerializeDictionary(stream, profiledFuncs, SerializeStructure); } [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 29*/)] @@ -354,14 +374,14 @@ public void SetHeaderHash() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())); + HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]); } public bool IsHeaderValid() { Span spanHeader = MemoryMarshal.CreateSpan(ref this, 1); - return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf() - Unsafe.SizeOf())) == HeaderHash; + return XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader)[..(Unsafe.SizeOf() - Unsafe.SizeOf())]) == HeaderHash; } } @@ -418,4 +438,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/PTC/PtcState.cs b/src/ARMeilleure/Translation/PTC/PtcState.cs index ca4f41080..f6692e870 100644 --- a/src/ARMeilleure/Translation/PTC/PtcState.cs +++ b/src/ARMeilleure/Translation/PTC/PtcState.cs @@ -5,6 +5,6 @@ enum PtcState Enabled, Continuing, Closing, - Disabled + Disabled, } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/RegisterToLocal.cs b/src/ARMeilleure/Translation/RegisterToLocal.cs index abb9b373c..91372eb00 100644 --- a/src/ARMeilleure/Translation/RegisterToLocal.cs +++ b/src/ARMeilleure/Translation/RegisterToLocal.cs @@ -9,7 +9,7 @@ static class RegisterToLocal { public static void Rename(ControlFlowGraph cfg) { - Dictionary registerToLocalMap = new Dictionary(); + Dictionary registerToLocalMap = new(); Operand GetLocal(Operand op) { @@ -49,4 +49,4 @@ Operand GetLocal(Operand op) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/RegisterUsage.cs b/src/ARMeilleure/Translation/RegisterUsage.cs index 3ec0a7b4f..c8c250626 100644 --- a/src/ARMeilleure/Translation/RegisterUsage.cs +++ b/src/ARMeilleure/Translation/RegisterUsage.cs @@ -12,7 +12,7 @@ namespace ARMeilleure.Translation static class RegisterUsage { private const int RegsCount = 32; - private const int RegsMask = RegsCount - 1; + private const int RegsMask = RegsCount - 1; private readonly struct RegisterMask : IEquatable { @@ -90,7 +90,7 @@ public override int GetHashCode() public static void RunPass(ControlFlowGraph cfg, ExecutionMode mode) { // Compute local register inputs and outputs used inside blocks. - RegisterMask[] localInputs = new RegisterMask[cfg.Blocks.Count]; + RegisterMask[] localInputs = new RegisterMask[cfg.Blocks.Count]; RegisterMask[] localOutputs = new RegisterMask[cfg.Blocks.Count]; for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) @@ -119,7 +119,7 @@ public static void RunPass(ControlFlowGraph cfg, ExecutionMode mode) // Compute global register inputs and outputs used across blocks. RegisterMask[] globalCmnOutputs = new RegisterMask[cfg.Blocks.Count]; - RegisterMask[] globalInputs = new RegisterMask[cfg.Blocks.Count]; + RegisterMask[] globalInputs = new RegisterMask[cfg.Blocks.Count]; RegisterMask[] globalOutputs = new RegisterMask[cfg.Blocks.Count]; bool modified; @@ -286,10 +286,12 @@ private static RegisterMask GetMask(Register register) switch (register.Type) { +#pragma warning disable IDE0055 // Disable formatting case RegisterType.Flag: intMask = (1L << RegsCount) << register.Index; break; case RegisterType.Integer: intMask = 1L << register.Index; break; case RegisterType.FpFlag: vecMask = (1L << RegsCount) << register.Index; break; case RegisterType.Vector: vecMask = 1L << register.Index; break; +#pragma warning restore IDE0055 } return new RegisterMask(intMask, vecMask); @@ -373,15 +375,14 @@ private static Operand GetRegFromBit(int bit, RegisterType baseType, ExecutionMo private static OperandType GetOperandType(RegisterType type, ExecutionMode mode) { - switch (type) + return type switch { - case RegisterType.Flag: return OperandType.I32; - case RegisterType.FpFlag: return OperandType.I32; - case RegisterType.Integer: return (mode == ExecutionMode.Aarch64) ? OperandType.I64 : OperandType.I32; - case RegisterType.Vector: return OperandType.V128; - } - - throw new ArgumentException($"Invalid register type \"{type}\"."); + RegisterType.Flag => OperandType.I32, + RegisterType.FpFlag => OperandType.I32, + RegisterType.Integer => (mode == ExecutionMode.Aarch64) ? OperandType.I64 : OperandType.I32, + RegisterType.Vector => OperandType.V128, + _ => throw new ArgumentException($"Invalid register type \"{type}\"."), + }; } private static bool EndsWithReturn(BasicBlock block) @@ -391,4 +392,4 @@ private static bool EndsWithReturn(BasicBlock block) return last != default && last.Instruction == Instruction.Return; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/SsaConstruction.cs b/src/ARMeilleure/Translation/SsaConstruction.cs index 2b6efc113..cddcfcd4f 100644 --- a/src/ARMeilleure/Translation/SsaConstruction.cs +++ b/src/ARMeilleure/Translation/SsaConstruction.cs @@ -180,7 +180,7 @@ private static Operand FindDefOnPred(DefMap[] globalDefs, BasicBlock current, Op } previous = current; - current = current.ImmediateDominator; + current = current.ImmediateDominator; } while (previous != current); @@ -286,4 +286,4 @@ private static int GetId(Operand operand) return key; } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/SsaDeconstruction.cs b/src/ARMeilleure/Translation/SsaDeconstruction.cs index cd6bcca1f..68af54e5d 100644 --- a/src/ARMeilleure/Translation/SsaDeconstruction.cs +++ b/src/ARMeilleure/Translation/SsaDeconstruction.cs @@ -45,4 +45,4 @@ public static void Deconstruct(ControlFlowGraph cfg) } } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/TranslatedFunction.cs b/src/ARMeilleure/Translation/TranslatedFunction.cs index f007883ef..1446c254a 100644 --- a/src/ARMeilleure/Translation/TranslatedFunction.cs +++ b/src/ARMeilleure/Translation/TranslatedFunction.cs @@ -31,4 +31,4 @@ public ulong Execute(WrapperFunction dispatcher, State.ExecutionContext context) return dispatcher(context.NativeContextPtr, (ulong)FuncPointer); } } -} \ No newline at end of file +} diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index f349c5ebf..014b12035 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -22,24 +22,24 @@ namespace ARMeilleure.Translation { public class Translator { - private static readonly AddressTable.Level[] Levels64Bit = + private static readonly AddressTable.Level[] _levels64Bit = new AddressTable.Level[] { new(31, 17), new(23, 8), new(15, 8), new( 7, 8), - new( 2, 5) + new( 2, 5), }; - private static readonly AddressTable.Level[] Levels32Bit = + private static readonly AddressTable.Level[] _levels32Bit = new AddressTable.Level[] { new(31, 17), new(23, 8), new(15, 8), new( 7, 8), - new( 1, 6) + new( 1, 6), }; private readonly IJitMemoryAllocator _allocator; @@ -54,11 +54,9 @@ public class Translator internal TranslatorQueue Queue { get; } internal IMemoryManager Memory { get; } + private Thread[] _backgroundTranslationThreads; private volatile int _threadCount; - // FIXME: Remove this once the init logic of the emulator will be redone. - public static readonly ManualResetEvent IsReadyForTranslation = new(false); - public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for64Bits) { _allocator = allocator; @@ -74,15 +72,10 @@ public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for CountTable = new EntryTable(); Functions = new TranslatorCache(); - FunctionTable = new AddressTable(for64Bits ? Levels64Bit : Levels32Bit); - Stubs = new TranslatorStubs(this); + FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit); + Stubs = new TranslatorStubs(FunctionTable); FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub; - - if (memory.Type.IsHostMapped()) - { - NativeSignalHandler.InitializeSignalHandler(allocator.GetPageSize()); - } } public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled) @@ -104,8 +97,6 @@ public void Execute(State.ExecutionContext context, ulong address) { if (Interlocked.Increment(ref _threadCount) == 1) { - IsReadyForTranslation.WaitOne(); - if (_ptc.State == PtcState.Enabled) { Debug.Assert(Functions.Count == 0); @@ -125,20 +116,24 @@ public void Execute(State.ExecutionContext context, ulong address) // TODO: Use physical cores rather than logical. This only really makes sense for processors with // hyperthreading. Requires OS specific code. int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3); - int threadCount = Math.Min(4, unboundedThreadCount); + int threadCount = Math.Min(4, unboundedThreadCount); + + Thread[] backgroundTranslationThreads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { bool last = i != 0 && i == unboundedThreadCount - 1; - Thread backgroundTranslatorThread = new Thread(BackgroundTranslate) + backgroundTranslationThreads[i] = new(BackgroundTranslate) { Name = "CPU.BackgroundTranslatorThread." + i, - Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal + Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal, }; - backgroundTranslatorThread.Start(); + backgroundTranslationThreads[i].Start(); } + + Interlocked.Exchange(ref _backgroundTranslationThreads, backgroundTranslationThreads); } Statistics.InitializeTimer(); @@ -162,9 +157,20 @@ public void Execute(State.ExecutionContext context, ulong address) if (Interlocked.Decrement(ref _threadCount) == 0) { + Queue.Dispose(); + + Thread[] backgroundTranslationThreads = Interlocked.Exchange(ref _backgroundTranslationThreads, null); + + if (backgroundTranslationThreads != null) + { + foreach (Thread thread in backgroundTranslationThreads) + { + thread.Join(); + } + } + ClearJitCache(); - Queue.Dispose(); Stubs.Dispose(); FunctionTable.Dispose(); CountTable.Dispose(); diff --git a/src/ARMeilleure/Translation/TranslatorCache.cs b/src/ARMeilleure/Translation/TranslatorCache.cs index 11286381b..99ca58dc6 100644 --- a/src/ARMeilleure/Translation/TranslatorCache.cs +++ b/src/ARMeilleure/Translation/TranslatorCache.cs @@ -7,14 +7,14 @@ namespace ARMeilleure.Translation internal class TranslatorCache { private readonly IntervalTree _tree; - private readonly ReaderWriterLock _treeLock; + private readonly ReaderWriterLockSlim _treeLock; public int Count => _tree.Count; public TranslatorCache() { _tree = new IntervalTree(); - _treeLock = new ReaderWriterLock(); + _treeLock = new ReaderWriterLockSlim(); } public bool TryAdd(ulong address, ulong size, T value) @@ -24,70 +24,70 @@ public bool TryAdd(ulong address, ulong size, T value) public bool AddOrUpdate(ulong address, ulong size, T value, Func updateFactoryCallback) { - _treeLock.AcquireWriterLock(Timeout.Infinite); + _treeLock.EnterWriteLock(); bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback); - _treeLock.ReleaseWriterLock(); + _treeLock.ExitWriteLock(); return result; } public T GetOrAdd(ulong address, ulong size, T value) { - _treeLock.AcquireWriterLock(Timeout.Infinite); + _treeLock.EnterWriteLock(); value = _tree.GetOrAdd(address, address + size, value); - _treeLock.ReleaseWriterLock(); + _treeLock.ExitWriteLock(); return value; } public bool Remove(ulong address) { - _treeLock.AcquireWriterLock(Timeout.Infinite); + _treeLock.EnterWriteLock(); bool removed = _tree.Remove(address) != 0; - _treeLock.ReleaseWriterLock(); + _treeLock.ExitWriteLock(); return removed; } public void Clear() { - _treeLock.AcquireWriterLock(Timeout.Infinite); + _treeLock.EnterWriteLock(); _tree.Clear(); - _treeLock.ReleaseWriterLock(); + _treeLock.ExitWriteLock(); } public bool ContainsKey(ulong address) { - _treeLock.AcquireReaderLock(Timeout.Infinite); + _treeLock.EnterReadLock(); bool result = _tree.ContainsKey(address); - _treeLock.ReleaseReaderLock(); + _treeLock.ExitReadLock(); return result; } public bool TryGetValue(ulong address, out T value) { - _treeLock.AcquireReaderLock(Timeout.Infinite); + _treeLock.EnterReadLock(); bool result = _tree.TryGet(address, out value); - _treeLock.ReleaseReaderLock(); + _treeLock.ExitReadLock(); return result; } public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps) { - _treeLock.AcquireReaderLock(Timeout.Infinite); + _treeLock.EnterReadLock(); int count = _tree.Get(address, address + size, ref overlaps); - _treeLock.ReleaseReaderLock(); + _treeLock.ExitReadLock(); return count; } public List AsList() { - _treeLock.AcquireReaderLock(Timeout.Infinite); + _treeLock.EnterReadLock(); List list = _tree.AsList(); - _treeLock.ReleaseReaderLock(); + _treeLock.ExitReadLock(); return list; } diff --git a/src/ARMeilleure/Translation/TranslatorQueue.cs b/src/ARMeilleure/Translation/TranslatorQueue.cs index fc0aa64f2..cee2f9080 100644 --- a/src/ARMeilleure/Translation/TranslatorQueue.cs +++ b/src/ARMeilleure/Translation/TranslatorQueue.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Diagnostics; +using ARMeilleure.Diagnostics; using ARMeilleure.State; using System; using System.Collections.Generic; diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs index 69648df44..d80823a8b 100644 --- a/src/ARMeilleure/Translation/TranslatorStubs.cs +++ b/src/ARMeilleure/Translation/TranslatorStubs.cs @@ -1,4 +1,5 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Common; +using ARMeilleure.Instructions; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation.Cache; @@ -14,11 +15,11 @@ namespace ARMeilleure.Translation /// class TranslatorStubs : IDisposable { - private static readonly Lazy _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true); + private readonly Lazy _slowDispatchStub; private bool _disposed; - private readonly Translator _translator; + private readonly AddressTable _functionTable; private readonly Lazy _dispatchStub; private readonly Lazy _dispatchLoop; private readonly Lazy _contextWrapper; @@ -83,13 +84,14 @@ public WrapperFunction ContextWrapper /// Initializes a new instance of the class with the specified /// instance. /// - /// instance to use + /// Function table used to store pointers to the functions that the guest code will call /// is null - public TranslatorStubs(Translator translator) + public TranslatorStubs(AddressTable functionTable) { - ArgumentNullException.ThrowIfNull(translator); + ArgumentNullException.ThrowIfNull(functionTable); - _translator = translator; + _functionTable = functionTable; + _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true); _dispatchStub = new(GenerateDispatchStub, isThreadSafe: true); _dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true); _contextWrapper = new(GenerateContextWrapper, isThreadSafe: true); @@ -151,15 +153,15 @@ private IntPtr GenerateDispatchStub() context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()))); // Check if guest address is within range of the AddressTable. - Operand masked = context.BitwiseAnd(guestAddress, Const(~_translator.FunctionTable.Mask)); + Operand masked = context.BitwiseAnd(guestAddress, Const(~_functionTable.Mask)); context.BranchIfTrue(lblFallback, masked); Operand index = default; - Operand page = Const((long)_translator.FunctionTable.Base); + Operand page = Const((long)_functionTable.Base); - for (int i = 0; i < _translator.FunctionTable.Levels.Length; i++) + for (int i = 0; i < _functionTable.Levels.Length; i++) { - ref var level = ref _translator.FunctionTable.Levels[i]; + ref var level = ref _functionTable.Levels[i]; // level.Mask is not used directly because it is more often bigger than 32-bits, so it will not // be encoded as an immediate on x86's bitwise and operation. @@ -167,7 +169,7 @@ private IntPtr GenerateDispatchStub() index = context.BitwiseAnd(context.ShiftRightUI(guestAddress, Const(level.Index)), mask); - if (i < _translator.FunctionTable.Levels.Length - 1) + if (i < _functionTable.Levels.Length - 1) { page = context.Load(OperandType.I64, context.Add(page, context.ShiftLeft(index, Const(3)))); context.BranchIfFalse(lblFallback, page); @@ -196,7 +198,7 @@ private IntPtr GenerateDispatchStub() /// Generates a . /// /// Generated - private static IntPtr GenerateSlowDispatchStub() + private IntPtr GenerateSlowDispatchStub() { var context = new EmitterContext(); @@ -205,8 +207,7 @@ private static IntPtr GenerateSlowDispatchStub() Operand guestAddress = context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()))); - MethodInfo getFuncAddress = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)); - Operand hostAddress = context.Call(getFuncAddress, guestAddress); + Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); context.Tailcall(hostAddress, nativeContext); var cfg = context.GetControlFlowGraph(); @@ -224,7 +225,7 @@ private static IntPtr GenerateSlowDispatchStub() /// Emitter context for the method /// Pointer to the native context /// True if entering guest code, false otherwise - private void EmitSyncFpContext(EmitterContext context, Operand nativeContext, bool enter) + private static void EmitSyncFpContext(EmitterContext context, Operand nativeContext, bool enter) { if (enter) { diff --git a/src/ARMeilleure/Translation/TranslatorTestMethods.cs b/src/ARMeilleure/Translation/TranslatorTestMethods.cs index ab96019a6..8cc7a3cf8 100644 --- a/src/ARMeilleure/Translation/TranslatorTestMethods.cs +++ b/src/ARMeilleure/Translation/TranslatorTestMethods.cs @@ -1,7 +1,6 @@ -using ARMeilleure.CodeGen.X86; +using ARMeilleure.CodeGen.X86; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; -using ARMeilleure.Translation; using System; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -62,7 +61,7 @@ private static Operand FpBitsToInt(EmitterContext context, Operand fp) public static FpFlagsPInvokeTest GenerateFpFlagsPInvokeTest() { - EmitterContext context = new EmitterContext(); + EmitterContext context = new(); Operand methodAddress = context.Copy(context.LoadArgument(OperandType.I64, 0)); @@ -110,7 +109,7 @@ public static FpFlagsPInvokeTest GenerateFpFlagsPInvokeTest() context.MarkLabel(correct2Label); - // Call a managed method. This method should not change Fz state. + // Call a managed method. This method should not change Fz state. context.Call(methodAddress, OperandType.None); diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs index 050b52a9f..bd7a9c25c 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.OpenAL +namespace Ryujinx.Audio.Backends.OpenAL { class OpenALAudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs index 0c793f248..744a4bc56 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs @@ -1,4 +1,4 @@ -using OpenTK.Audio.OpenAL; +using OpenTK.Audio.OpenAL; using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Memory; @@ -18,7 +18,7 @@ public class OpenALHardwareDeviceDriver : IHardwareDeviceDriver private readonly ManualResetEvent _pauseEvent; private readonly ConcurrentDictionary _sessions; private bool _stillRunning; - private Thread _updaterThread; + private readonly Thread _updaterThread; public OpenALHardwareDeviceDriver() { @@ -31,7 +31,7 @@ public OpenALHardwareDeviceDriver() _stillRunning = true; _updaterThread = new Thread(Update) { - Name = "HardwareDeviceDriver.OpenAL" + Name = "HardwareDeviceDriver.OpenAL", }; _updaterThread.Start(); @@ -73,7 +73,7 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem throw new ArgumentException($"{channelCount}"); } - OpenALHardwareDeviceSession session = new OpenALHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); + OpenALHardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); _sessions.TryAdd(session, 0); @@ -123,6 +123,7 @@ private void Update() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs index ac3319e0d..a52821616 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using OpenTK.Audio.OpenAL; +using OpenTK.Audio.OpenAL; using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Common; using Ryujinx.Memory; @@ -10,14 +10,14 @@ namespace Ryujinx.Audio.Backends.OpenAL { class OpenALHardwareDeviceSession : HardwareDeviceSessionOutputBase { - private OpenALHardwareDeviceDriver _driver; - private int _sourceId; - private ALFormat _targetFormat; + private readonly OpenALHardwareDeviceDriver _driver; + private readonly int _sourceId; + private readonly ALFormat _targetFormat; private bool _isActive; - private Queue _queuedBuffers; + private readonly Queue _queuedBuffers; private ulong _playedSampleCount; - private object _lock = new object(); + private readonly object _lock = new(); public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount) { @@ -32,23 +32,17 @@ public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMe private ALFormat GetALFormat() { - switch (RequestedSampleFormat) + return RequestedSampleFormat switch { - case SampleFormat.PcmInt16: - switch (RequestedChannelCount) - { - case 1: - return ALFormat.Mono16; - case 2: - return ALFormat.Stereo16; - case 6: - return ALFormat.Multi51Chn16Ext; - default: - throw new NotImplementedException($"Unsupported channel config {RequestedChannelCount}"); - } - default: - throw new NotImplementedException($"Unsupported sample format {RequestedSampleFormat}"); - } + SampleFormat.PcmInt16 => RequestedChannelCount switch + { + 1 => ALFormat.Mono16, + 2 => ALFormat.Stereo16, + 6 => ALFormat.Multi51Chn16Ext, + _ => throw new NotImplementedException($"Unsupported channel config {RequestedChannelCount}"), + }, + _ => throw new NotImplementedException($"Unsupported sample format {RequestedSampleFormat}"), + }; } public override void PrepareToClose() { } @@ -69,11 +63,11 @@ public override void QueueBuffer(AudioBuffer buffer) { lock (_lock) { - OpenALAudioBuffer driverBuffer = new OpenALAudioBuffer + OpenALAudioBuffer driverBuffer = new() { DriverIdentifier = buffer.DataPointer, BufferId = AL.GenBuffer(), - SampleCount = GetSampleCount(buffer) + SampleCount = GetSampleCount(buffer), }; AL.BufferData(driverBuffer.BufferId, _targetFormat, buffer.Data, (int)RequestedSampleRate); diff --git a/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj b/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj index 115a37601..b5fd8f9e7 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj +++ b/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj @@ -1,11 +1,11 @@ - net7.0 + net8.0 - + diff --git a/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj b/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj index 525f1f5b6..dd18e70a1 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj +++ b/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 true diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs index 71ef414a9..a390c5467 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SDL2 +namespace Ryujinx.Audio.Backends.SDL2 { class SDL2AudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs index b190b4c83..b83e63dbc 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs @@ -1,12 +1,12 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Common.Logging; using Ryujinx.Memory; using Ryujinx.SDL2.Common; using System; using System.Collections.Concurrent; +using System.Runtime.InteropServices; using System.Threading; - using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; using static SDL2.SDL; @@ -18,6 +18,15 @@ public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver private readonly ManualResetEvent _pauseEvent; private readonly ConcurrentDictionary _sessions; + private readonly bool _supportSurroundConfiguration; + + // TODO: Add this to SDL2-CS + // NOTE: We use a DllImport here because of marshaling issue for spec. +#pragma warning disable SYSLIB1054 + [DllImport("SDL2")] + private static extern int SDL_GetDefaultAudioInfo(IntPtr name, out SDL_AudioSpec spec, int isCapture); +#pragma warning restore SYSLIB1054 + public SDL2HardwareDeviceDriver() { _updateRequiredEvent = new ManualResetEvent(false); @@ -25,6 +34,20 @@ public SDL2HardwareDeviceDriver() _sessions = new ConcurrentDictionary(); SDL2Driver.Instance.Initialize(); + + int res = SDL_GetDefaultAudioInfo(IntPtr.Zero, out var spec, 0); + + if (res != 0) + { + Logger.Error?.Print(LogClass.Application, + $"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\""); + + _supportSurroundConfiguration = true; + } + else + { + _supportSurroundConfiguration = spec.channels >= 6; + } } public static bool IsSupported => IsSupportedInternal(); @@ -68,7 +91,7 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem throw new NotImplementedException("Input direction is currently not implemented on SDL2 backend!"); } - SDL2HardwareDeviceSession session = new SDL2HardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); + SDL2HardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); _sessions.TryAdd(session, 0); @@ -87,7 +110,7 @@ private static SDL_AudioSpec GetSDL2Spec(SampleFormat requestedSampleFormat, uin channels = (byte)requestedChannelCount, format = GetSDL2Format(requestedSampleFormat), freq = (int)requestedSampleRate, - samples = (ushort)sampleCount + samples = (ushort)sampleCount, }; } @@ -113,8 +136,7 @@ internal static uint OpenStream(SampleFormat requestedSampleFormat, uint request if (device == 0) { - Logger.Error?.Print(LogClass.Application, - $"SDL2 open audio device initialization failed with error \"{SDL_GetError()}\""); + Logger.Error?.Print(LogClass.Application, $"SDL2 open audio device initialization failed with error \"{SDL_GetError()}\""); return 0; } @@ -134,6 +156,7 @@ internal static uint OpenStream(SampleFormat requestedSampleFormat, uint request public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -164,6 +187,11 @@ public bool SupportsSampleFormat(SampleFormat sampleFormat) public bool SupportsChannelCount(uint channelCount) { + if (channelCount == 6) + { + return _supportSurroundConfiguration; + } + return true; } diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs index 14310b934..7a683f4ed 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.Common; +using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Common; using Ryujinx.Common.Logging; using Ryujinx.Memory; @@ -12,19 +12,19 @@ namespace Ryujinx.Audio.Backends.SDL2 { class SDL2HardwareDeviceSession : HardwareDeviceSessionOutputBase { - private SDL2HardwareDeviceDriver _driver; - private ConcurrentQueue _queuedBuffers; - private DynamicRingBuffer _ringBuffer; + private readonly SDL2HardwareDeviceDriver _driver; + private readonly ConcurrentQueue _queuedBuffers; + private readonly DynamicRingBuffer _ringBuffer; private ulong _playedSampleCount; - private ManualResetEvent _updateRequiredEvent; + private readonly ManualResetEvent _updateRequiredEvent; private uint _outputStream; private bool _hasSetupError; - private SDL_AudioCallback _callbackDelegate; - private int _bytesPerFrame; + private readonly SDL_AudioCallback _callbackDelegate; + private readonly int _bytesPerFrame; private uint _sampleCount; private bool _started; private float _volume; - private ushort _nativeSampleFormat; + private readonly ushort _nativeSampleFormat; public SDL2HardwareDeviceSession(SDL2HardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount) { @@ -72,7 +72,7 @@ private void EnsureAudioStreamSetup(AudioBuffer buffer) private unsafe void Update(IntPtr userdata, IntPtr stream, int streamLength) { - Span streamSpan = new Span((void*)stream, streamLength); + Span streamSpan = new((void*)stream, streamLength); int maxFrameCount = (int)GetSampleCount(streamLength); int bufferedFrames = _ringBuffer.Length / _bytesPerFrame; @@ -82,7 +82,7 @@ private unsafe void Update(IntPtr userdata, IntPtr stream, int streamLength) if (frameCount == 0) { // SDL2 left the responsibility to the user to clear the buffer. - streamSpan.Fill(0); + streamSpan.Clear(); return; } @@ -96,7 +96,7 @@ private unsafe void Update(IntPtr userdata, IntPtr stream, int streamLength) IntPtr pStreamSrc = (IntPtr)p; // Zero the dest buffer - streamSpan.Fill(0); + streamSpan.Clear(); // Apply volume to written data SDL_MixAudioFormat(stream, pStreamSrc, _nativeSampleFormat, (uint)samples.Length, (int)(_volume * SDL_MIX_MAXVOLUME)); @@ -151,7 +151,7 @@ public override void QueueBuffer(AudioBuffer buffer) if (_outputStream != 0) { - SDL2AudioBuffer driverBuffer = new SDL2AudioBuffer(buffer.DataPointer, GetSampleCount(buffer)); + SDL2AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer)); _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length); diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs index 9c3e686df..7fdb1fc04 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -10,19 +10,19 @@ public static partial class SoundIo private const string LibraryName = "libsoundio"; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public unsafe delegate void OnDeviceChangeNativeDelegate(IntPtr ctx); + public delegate void OnDeviceChangeNativeDelegate(IntPtr ctx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public unsafe delegate void OnBackendDisconnectedDelegate(IntPtr ctx, SoundIoError err); + public delegate void OnBackendDisconnectedDelegate(IntPtr ctx, SoundIoError err); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public unsafe delegate void OnEventsSignalDelegate(IntPtr ctx); + public delegate void OnEventsSignalDelegate(IntPtr ctx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public unsafe delegate void EmitRtPrioWarningDelegate(); + public delegate void EmitRtPrioWarningDelegate(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public unsafe delegate void JackCallbackDelegate(IntPtr msg); + public delegate void JackCallbackDelegate(IntPtr msg); [StructLayout(LayoutKind.Sequential)] public struct SoundIoStruct @@ -110,69 +110,69 @@ public struct SoundIoChannelArea } [LibraryImport(LibraryName)] - public static partial IntPtr soundio_create(); + internal static partial IntPtr soundio_create(); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_connect(IntPtr ctx); + internal static partial SoundIoError soundio_connect(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial void soundio_disconnect(IntPtr ctx); + internal static partial void soundio_disconnect(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial void soundio_flush_events(IntPtr ctx); + internal static partial void soundio_flush_events(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial int soundio_output_device_count(IntPtr ctx); + internal static partial int soundio_output_device_count(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial int soundio_default_output_device_index(IntPtr ctx); + internal static partial int soundio_default_output_device_index(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial IntPtr soundio_get_output_device(IntPtr ctx, int index); + internal static partial IntPtr soundio_get_output_device(IntPtr ctx, int index); [LibraryImport(LibraryName)] [return: MarshalAs(UnmanagedType.Bool)] - public static partial bool soundio_device_supports_format(IntPtr devCtx, SoundIoFormat format); + internal static partial bool soundio_device_supports_format(IntPtr devCtx, SoundIoFormat format); [LibraryImport(LibraryName)] [return: MarshalAs(UnmanagedType.Bool)] - public static partial bool soundio_device_supports_layout(IntPtr devCtx, IntPtr layout); + internal static partial bool soundio_device_supports_layout(IntPtr devCtx, IntPtr layout); [LibraryImport(LibraryName)] [return: MarshalAs(UnmanagedType.Bool)] - public static partial bool soundio_device_supports_sample_rate(IntPtr devCtx, int sampleRate); + internal static partial bool soundio_device_supports_sample_rate(IntPtr devCtx, int sampleRate); [LibraryImport(LibraryName)] - public static partial IntPtr soundio_outstream_create(IntPtr devCtx); + internal static partial IntPtr soundio_outstream_create(IntPtr devCtx); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_open(IntPtr outStreamCtx); + internal static partial SoundIoError soundio_outstream_open(IntPtr outStreamCtx); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_start(IntPtr outStreamCtx); + internal static partial SoundIoError soundio_outstream_start(IntPtr outStreamCtx); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_begin_write(IntPtr outStreamCtx, IntPtr areas, IntPtr frameCount); + internal static partial SoundIoError soundio_outstream_begin_write(IntPtr outStreamCtx, IntPtr areas, IntPtr frameCount); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_end_write(IntPtr outStreamCtx); + internal static partial SoundIoError soundio_outstream_end_write(IntPtr outStreamCtx); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_pause(IntPtr devCtx, [MarshalAs(UnmanagedType.Bool)] bool pause); + internal static partial SoundIoError soundio_outstream_pause(IntPtr devCtx, [MarshalAs(UnmanagedType.Bool)] bool pause); [LibraryImport(LibraryName)] - public static partial SoundIoError soundio_outstream_set_volume(IntPtr devCtx, double volume); + internal static partial SoundIoError soundio_outstream_set_volume(IntPtr devCtx, double volume); [LibraryImport(LibraryName)] - public static partial void soundio_outstream_destroy(IntPtr streamCtx); + internal static partial void soundio_outstream_destroy(IntPtr streamCtx); [LibraryImport(LibraryName)] - public static partial void soundio_destroy(IntPtr ctx); + internal static partial void soundio_destroy(IntPtr ctx); [LibraryImport(LibraryName)] - public static partial IntPtr soundio_channel_layout_get_default(int channelCount); + internal static partial IntPtr soundio_channel_layout_get_default(int channelCount); [LibraryImport(LibraryName)] - public static partial IntPtr soundio_strerror(SoundIoError err); + internal static partial IntPtr soundio_strerror(SoundIoError err); } } diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs index 92f8ea375..d91eca488 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs @@ -1,6 +1,6 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { - public enum SoundIoBackend : int + public enum SoundIoBackend { None = 0, Jack = 1, @@ -8,6 +8,6 @@ public enum SoundIoBackend : int Alsa = 3, CoreAudio = 4, Wasapi = 5, - Dummy = 6 + Dummy = 6, } } diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs index 70346e0bf..c1a14e1ea 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoChannelId { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs index 3744c2e64..f2e91fcd7 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs @@ -1,5 +1,4 @@ -using System; -using System.Reflection.Metadata; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs index a0689d6d6..58bdce394 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs @@ -1,8 +1,8 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoDeviceAim { SoundIoDeviceAimInput = 0, - SoundIoDeviceAimOutput = 1 + SoundIoDeviceAimOutput = 1, } } diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs index 42bcc6e3b..7923e9b17 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs index 9e33fa194..64329450c 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoError { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs index a033356e8..1a33472da 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs index 0eee97804..7e8c22a9f 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoFormat { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs index 2e432b311..4148ea0dd 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj index 9f242dbe2..1d92d9d2e 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj +++ b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj @@ -1,9 +1,9 @@ - net7.0 + net8.0 true - win10-x64;linux-x64;osx-x64 + win-x64;osx-x64;linux-x64 @@ -15,11 +15,11 @@ PreserveNewest libsoundio.dll - + PreserveNewest libsoundio.dylib - + PreserveNewest libsoundio.so diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs index 7f32b9533..e1a62de75 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo +namespace Ryujinx.Audio.Backends.SoundIo { class SoundIoAudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs index 02da27769..ff0392882 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.SoundIo.Native; +using Ryujinx.Audio.Backends.SoundIo.Native; using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Memory; @@ -141,7 +141,7 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem throw new NotImplementedException("Input direction is currently not implemented on SoundIO backend!"); } - SoundIoHardwareDeviceSession session = new SoundIoHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); + SoundIoHardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); _sessions.TryAdd(session, 0); @@ -162,7 +162,7 @@ public static SoundIoFormat GetSoundIoFormat(SampleFormat format) SampleFormat.PcmInt24 => SoundIoFormat.S24LE, SampleFormat.PcmInt32 => SoundIoFormat.S32LE, SampleFormat.PcmFloat => SoundIoFormat.Float32LE, - _ => throw new ArgumentException ($"Unsupported sample format {format}"), + _ => throw new ArgumentException($"Unsupported sample format {format}"), }; } @@ -202,6 +202,8 @@ internal void FlushContextEvents() public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs index 96d9ce970..123cfd27a 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.Common; +using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Backends.SoundIo.Native; using Ryujinx.Audio.Common; using Ryujinx.Memory; @@ -12,12 +12,12 @@ namespace Ryujinx.Audio.Backends.SoundIo { class SoundIoHardwareDeviceSession : HardwareDeviceSessionOutputBase { - private SoundIoHardwareDeviceDriver _driver; - private ConcurrentQueue _queuedBuffers; + private readonly SoundIoHardwareDeviceDriver _driver; + private readonly ConcurrentQueue _queuedBuffers; private SoundIoOutStreamContext _outputStream; - private DynamicRingBuffer _ringBuffer; + private readonly DynamicRingBuffer _ringBuffer; private ulong _playedSampleCount; - private ManualResetEvent _updateRequiredEvent; + private readonly ManualResetEvent _updateRequiredEvent; private int _disposeState; public SoundIoHardwareDeviceSession(SoundIoHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount) @@ -54,7 +54,7 @@ public override void PrepareToClose() { } public override void QueueBuffer(AudioBuffer buffer) { - SoundIoAudioBuffer driverBuffer = new SoundIoAudioBuffer(buffer.DataPointer, GetSampleCount(buffer)); + SoundIoAudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer)); _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length); @@ -81,7 +81,7 @@ public override void Stop() _driver.FlushContextEvents(); } - public override void UnregisterBuffer(AudioBuffer buffer) {} + public override void UnregisterBuffer(AudioBuffer buffer) { } public override bool WasBufferFullyConsumed(AudioBuffer buffer) { diff --git a/src/Ryujinx.Audio/AudioManager.cs b/src/Ryujinx.Audio/AudioManager.cs index c37ca4a3d..370d3d098 100644 --- a/src/Ryujinx.Audio/AudioManager.cs +++ b/src/Ryujinx.Audio/AudioManager.cs @@ -11,22 +11,22 @@ public class AudioManager : IDisposable /// /// Lock used to control the waiters registration. /// - private object _lock = new object(); + private readonly object _lock = new(); /// /// Events signaled when the driver played audio buffers. /// - private ManualResetEvent[] _updateRequiredEvents; + private readonly ManualResetEvent[] _updateRequiredEvents; /// /// Action to execute when the driver played audio buffers. /// - private Action[] _actions; + private readonly Action[] _actions; /// /// The worker thread in charge of handling sessions update. /// - private Thread _workerThread; + private readonly Thread _workerThread; private bool _isRunning; @@ -44,7 +44,7 @@ public AudioManager() _workerThread = new Thread(Update) { - Name = "AudioManager.Worker" + Name = "AudioManager.Worker", }; } @@ -115,6 +115,7 @@ public void StopUpdates() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -129,4 +130,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Common/BackendHelper.cs b/src/Ryujinx.Audio/Backends/Common/BackendHelper.cs index 30db340fa..124d8364f 100644 --- a/src/Ryujinx.Audio/Backends/Common/BackendHelper.cs +++ b/src/Ryujinx.Audio/Backends/Common/BackendHelper.cs @@ -23,4 +23,4 @@ public static int GetSampleCount(SampleFormat format, int channelCount, int buff return bufferSize / GetSampleSize(format) / channelCount; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs index 9bf20d4b5..05dd2162a 100644 --- a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs +++ b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs @@ -10,7 +10,7 @@ public class DynamicRingBuffer { private const int RingBufferAlignment = 2048; - private object _lock = new object(); + private readonly object _lock = new(); private byte[] _buffer; private int _size; @@ -163,4 +163,4 @@ public int Read(T[] buffer, int index, int count) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs b/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs index 6fb3bee02..5599c0827 100644 --- a/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs +++ b/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs @@ -66,14 +66,11 @@ public virtual bool RegisterBuffer(AudioBuffer buffer, byte[] samples) return false; } - if (buffer.Data == null) - { - buffer.Data = samples; - } + buffer.Data ??= samples; return true; } public virtual void UnregisterBuffer(AudioBuffer buffer) { } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs index 22919f1e1..3f3806c3e 100644 --- a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs @@ -6,14 +6,13 @@ using Ryujinx.Memory; using System; using System.Threading; - using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; namespace Ryujinx.Audio.Backends.CompatLayer { public class CompatLayerHardwareDeviceDriver : IHardwareDeviceDriver { - private IHardwareDeviceDriver _realDriver; + private readonly IHardwareDeviceDriver _realDriver; public static bool IsSupported => true; @@ -24,6 +23,7 @@ public CompatLayerHardwareDeviceDriver(IHardwareDeviceDriver realDevice) public void Dispose() { + GC.SuppressFinalize(this); _realDriver.Dispose(); } @@ -49,7 +49,7 @@ private uint SelectHardwareChannelCount(uint targetChannelCount) 6 => SelectHardwareChannelCount(2), 2 => SelectHardwareChannelCount(1), 1 => throw new ArgumentException("No valid channel configuration found!"), - _ => throw new ArgumentException($"Invalid targetChannelCount {targetChannelCount}") + _ => throw new ArgumentException($"Invalid targetChannelCount {targetChannelCount}"), }; } @@ -110,7 +110,7 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem { Logger.Warning?.Print(LogClass.Audio, "The selected audio backend doesn't support audio input, fallback to dummy..."); - return new DummyHardwareDeviceSessionInput(this, memoryManager, sampleFormat, sampleRate, channelCount); + return new DummyHardwareDeviceSessionInput(this, memoryManager); } throw new NotImplementedException(); @@ -138,12 +138,12 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem if (direction == Direction.Input) { - Logger.Warning?.Print(LogClass.Audio, $"The selected audio backend doesn't support the requested audio input configuration, fallback to dummy..."); + Logger.Warning?.Print(LogClass.Audio, "The selected audio backend doesn't support the requested audio input configuration, fallback to dummy..."); // TODO: We currently don't support audio input upsampling/downsampling, implement this. realSession.Dispose(); - return new DummyHardwareDeviceSessionInput(this, memoryManager, sampleFormat, sampleRate, channelCount); + return new DummyHardwareDeviceSessionInput(this, memoryManager); } // It must be a HardwareDeviceSessionOutputBase. @@ -183,4 +183,4 @@ public bool SupportsDirection(Direction direction) return direction == Direction.Input || direction == Direction.Output; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs index f22a7a690..a9acabec9 100644 --- a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs @@ -8,9 +8,9 @@ namespace Ryujinx.Audio.Backends.CompatLayer { class CompatLayerHardwareDeviceSession : HardwareDeviceSessionOutputBase { - private HardwareDeviceSessionOutputBase _realSession; - private SampleFormat _userSampleFormat; - private uint _userChannelCount; + private readonly HardwareDeviceSessionOutputBase _realSession; + private readonly SampleFormat _userSampleFormat; + private readonly uint _userChannelCount; public CompatLayerHardwareDeviceSession(HardwareDeviceSessionOutputBase realSession, SampleFormat userSampleFormat, uint userChannelCount) : base(realSession.MemoryManager, realSession.RequestedSampleFormat, realSession.RequestedSampleRate, userChannelCount) { @@ -116,11 +116,11 @@ public override bool RegisterBuffer(AudioBuffer buffer, byte[] samples) samples = MemoryMarshal.Cast(samplesPCM16).ToArray(); } - AudioBuffer fakeBuffer = new AudioBuffer + AudioBuffer fakeBuffer = new() { BufferTag = buffer.BufferTag, DataPointer = buffer.DataPointer, - DataSize = (ulong)samples.Length + DataSize = (ulong)samples.Length, }; bool result = _realSession.RegisterBuffer(fakeBuffer, samples); @@ -159,4 +159,4 @@ public override bool WasBufferFullyConsumed(AudioBuffer buffer) return _realSession.WasBufferFullyConsumed(buffer); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs b/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs index 6959c1588..7a5ea0deb 100644 --- a/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs +++ b/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs @@ -31,18 +31,18 @@ private struct ChannelStereoFormatPCM16 private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One); private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One); - private static readonly int[] DefaultSurroundToStereoCoefficients = new int[4] + private static readonly long[] _defaultSurroundToStereoCoefficients = new long[4] { RawQ15One, Minus3dBInQ15, Minus12dBInQ15, - Minus3dBInQ15 + Minus3dBInQ15, }; - private static readonly int[] DefaultStereoToMonoCoefficients = new int[2] + private static readonly long[] _defaultStereoToMonoCoefficients = new long[2] { Minus6dBInQ15, - Minus6dBInQ15 + Minus6dBInQ15, }; private const int SurroundChannelCount = 6; @@ -62,19 +62,23 @@ private static ReadOnlySpan GetStereoBuffer(ReadOnlySp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short DownMixStereoToMono(ReadOnlySpan coefficients, short left, short right) + private static short DownMixStereoToMono(ReadOnlySpan coefficients, short left, short right) { - return (short)((left * coefficients[0] + right * coefficients[1]) >> Q15Bits); + return (short)Math.Clamp((left * coefficients[0] + right * coefficients[1]) >> Q15Bits, short.MinValue, short.MaxValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short DownMixSurroundToStereo(ReadOnlySpan coefficients, short back, short lfe, short center, short front) + private static short DownMixSurroundToStereo(ReadOnlySpan coefficients, short back, short lfe, short center, short front) { - return (short)((coefficients[3] * back + coefficients[2] * lfe + coefficients[1] * center + coefficients[0] * front + RawQ15HalfOne) >> Q15Bits); + return (short)Math.Clamp( + (coefficients[3] * back + + coefficients[2] * lfe + + coefficients[1] * center + + coefficients[0] * front + RawQ15HalfOne) >> Q15Bits, short.MinValue, short.MaxValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short[] DownMixSurroundToStereo(ReadOnlySpan coefficients, ReadOnlySpan data) + private static short[] DownMixSurroundToStereo(ReadOnlySpan coefficients, ReadOnlySpan data) { int samplePerChannelCount = data.Length / SurroundChannelCount; @@ -94,7 +98,7 @@ private static short[] DownMixSurroundToStereo(ReadOnlySpan coefficients, R } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short[] DownMixStereoToMono(ReadOnlySpan coefficients, ReadOnlySpan data) + private static short[] DownMixStereoToMono(ReadOnlySpan coefficients, ReadOnlySpan data) { int samplePerChannelCount = data.Length / StereoChannelCount; @@ -114,12 +118,12 @@ private static short[] DownMixStereoToMono(ReadOnlySpan coefficients, ReadO public static short[] DownMixStereoToMono(ReadOnlySpan data) { - return DownMixStereoToMono(DefaultStereoToMonoCoefficients, data); + return DownMixStereoToMono(_defaultStereoToMonoCoefficients, data); } public static short[] DownMixSurroundToStereo(ReadOnlySpan data) { - return DownMixSurroundToStereo(DefaultSurroundToStereoCoefficients, data); + return DownMixSurroundToStereo(_defaultSurroundToStereoCoefficients, data); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs index 641640f0e..bac21c448 100644 --- a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs @@ -1,16 +1,16 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Memory; +using System; using System.Threading; - using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; namespace Ryujinx.Audio.Backends.Dummy { public class DummyHardwareDeviceDriver : IHardwareDeviceDriver { - private ManualResetEvent _updateRequiredEvent; - private ManualResetEvent _pauseEvent; + private readonly ManualResetEvent _updateRequiredEvent; + private readonly ManualResetEvent _pauseEvent; public static bool IsSupported => true; @@ -36,10 +36,8 @@ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMem { return new DummyHardwareDeviceSessionOutput(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); } - else - { - return new DummyHardwareDeviceSessionInput(this, memoryManager, sampleFormat, sampleRate, channelCount); - } + + return new DummyHardwareDeviceSessionInput(this, memoryManager); } public ManualResetEvent GetUpdateRequiredEvent() @@ -54,6 +52,7 @@ public ManualResetEvent GetPauseEvent() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -86,4 +85,4 @@ public bool SupportsChannelCount(uint channelCount) return channelCount == 1 || channelCount == 2 || channelCount == 6; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionInput.cs b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionInput.cs index 845713a19..f51a63393 100644 --- a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionInput.cs +++ b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionInput.cs @@ -8,10 +8,10 @@ namespace Ryujinx.Audio.Backends.Dummy class DummyHardwareDeviceSessionInput : IHardwareDeviceSession { private float _volume; - private IHardwareDeviceDriver _manager; - private IVirtualMemoryManager _memoryManager; + private readonly IHardwareDeviceDriver _manager; + private readonly IVirtualMemoryManager _memoryManager; - public DummyHardwareDeviceSessionInput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) + public DummyHardwareDeviceSessionInput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager) { _volume = 1.0f; _manager = manager; @@ -64,4 +64,4 @@ public bool WasBufferFullyConsumed(AudioBuffer buffer) return true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs index 8e2c949ec..1c248faaa 100644 --- a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs +++ b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs @@ -9,7 +9,7 @@ namespace Ryujinx.Audio.Backends.Dummy internal class DummyHardwareDeviceSessionOutput : HardwareDeviceSessionOutputBase { private float _volume; - private IHardwareDeviceDriver _manager; + private readonly IHardwareDeviceDriver _manager; private ulong _playedSampleCount; @@ -59,4 +59,4 @@ public override bool WasBufferFullyConsumed(AudioBuffer buffer) return true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioBuffer.cs b/src/Ryujinx.Audio/Common/AudioBuffer.cs index b79401b77..87a7d5f32 100644 --- a/src/Ryujinx.Audio/Common/AudioBuffer.cs +++ b/src/Ryujinx.Audio/Common/AudioBuffer.cs @@ -34,4 +34,4 @@ public class AudioBuffer /// public byte[] Data; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioDeviceSession.cs b/src/Ryujinx.Audio/Common/AudioDeviceSession.cs index 0191f7ccd..a0e04c80d 100644 --- a/src/Ryujinx.Audio/Common/AudioDeviceSession.cs +++ b/src/Ryujinx.Audio/Common/AudioDeviceSession.cs @@ -23,7 +23,7 @@ class AudioDeviceSession : IDisposable /// /// Array of all buffers currently used or released. /// - private AudioBuffer[] _buffers; + private readonly AudioBuffer[] _buffers; /// /// The server index inside (appended but not queued to device driver). @@ -58,17 +58,17 @@ class AudioDeviceSession : IDisposable /// /// The released buffer event. /// - private IWritableEvent _bufferEvent; + private readonly IWritableEvent _bufferEvent; /// /// The session on the device driver. /// - private IHardwareDeviceSession _hardwareDeviceSession; + private readonly IHardwareDeviceSession _hardwareDeviceSession; /// /// Max number of buffers that can be registered to the device driver at a time. /// - private uint _bufferRegisteredLimit; + private readonly uint _bufferRegisteredLimit; /// /// Create a new . @@ -311,9 +311,9 @@ public bool AppendBuffer(AudioBuffer buffer) return false; } - public bool AppendUacBuffer(AudioBuffer buffer, uint handle) + public static bool AppendUacBuffer(AudioBuffer buffer, uint handle) { - // NOTE: On hardware, there is another RegisterBuffer method taking an handle. + // NOTE: On hardware, there is another RegisterBuffer method taking a handle. // This variant of the call always return false (stubbed?) as a result this logic will never succeed. return false; @@ -425,10 +425,8 @@ public ulong GetPlayedSampleCount() { return 0; } - else - { - return _hardwareDeviceSession.GetPlayedSampleCount(); - } + + return _hardwareDeviceSession.GetPlayedSampleCount(); } /// @@ -515,4 +513,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioDeviceState.cs b/src/Ryujinx.Audio/Common/AudioDeviceState.cs index b3f968da2..8705e802e 100644 --- a/src/Ryujinx.Audio/Common/AudioDeviceState.cs +++ b/src/Ryujinx.Audio/Common/AudioDeviceState.cs @@ -13,6 +13,6 @@ public enum AudioDeviceState : uint /// /// The audio device is stopped. /// - Stopped + Stopped, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioInputConfiguration.cs b/src/Ryujinx.Audio/Common/AudioInputConfiguration.cs index d3cfdd47b..078c3a394 100644 --- a/src/Ryujinx.Audio/Common/AudioInputConfiguration.cs +++ b/src/Ryujinx.Audio/Common/AudioInputConfiguration.cs @@ -24,6 +24,6 @@ public struct AudioInputConfiguration /// /// Reserved/unused. /// - private ushort _reserved; + private readonly ushort _reserved; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioOutputConfiguration.cs b/src/Ryujinx.Audio/Common/AudioOutputConfiguration.cs index e17e17576..594f12250 100644 --- a/src/Ryujinx.Audio/Common/AudioOutputConfiguration.cs +++ b/src/Ryujinx.Audio/Common/AudioOutputConfiguration.cs @@ -34,4 +34,4 @@ public struct AudioOutputConfiguration /// public AudioDeviceState AudioOutState; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/AudioUserBuffer.cs b/src/Ryujinx.Audio/Common/AudioUserBuffer.cs index 50ab67fa3..bb71165ff 100644 --- a/src/Ryujinx.Audio/Common/AudioUserBuffer.cs +++ b/src/Ryujinx.Audio/Common/AudioUserBuffer.cs @@ -33,4 +33,4 @@ public struct AudioUserBuffer /// public ulong DataOffset; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Common/SampleFormat.cs b/src/Ryujinx.Audio/Common/SampleFormat.cs index 901410a24..39e525e87 100644 --- a/src/Ryujinx.Audio/Common/SampleFormat.cs +++ b/src/Ryujinx.Audio/Common/SampleFormat.cs @@ -38,6 +38,6 @@ public enum SampleFormat : byte /// /// ADPCM sample format. (Also known as GC-ADPCM) /// - Adpcm = 6 + Adpcm = 6, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Constants.cs b/src/Ryujinx.Audio/Constants.cs index 7d2ffa57b..eb5b39013 100644 --- a/src/Ryujinx.Audio/Constants.cs +++ b/src/Ryujinx.Audio/Constants.cs @@ -164,7 +164,7 @@ public static class Constants /// /// The default coefficients used for standard 5.1 surround to stereo downmixing. /// - public static float[] DefaultSurroundToStereoCoefficients = new float[4] + public static readonly float[] DefaultSurroundToStereoCoefficients = new float[4] { 1.0f, 0.707f, @@ -172,4 +172,4 @@ public static class Constants 0.707f, }; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Input/AudioInputManager.cs b/src/Ryujinx.Audio/Input/AudioInputManager.cs index ac012c4a9..4d1796c96 100644 --- a/src/Ryujinx.Audio/Input/AudioInputManager.cs +++ b/src/Ryujinx.Audio/Input/AudioInputManager.cs @@ -14,17 +14,17 @@ namespace Ryujinx.Audio.Input /// public class AudioInputManager : IDisposable { - private object _lock = new object(); + private readonly object _lock = new(); /// /// Lock used for session allocation. /// - private object _sessionLock = new object(); + private readonly object _sessionLock = new(); /// /// The session ids allocation table. /// - private int[] _sessionIds; + private readonly int[] _sessionIds; /// /// The device driver. @@ -39,7 +39,7 @@ public class AudioInputManager : IDisposable /// /// The session instances. /// - private AudioInputSystem[] _sessions; + private readonly AudioInputSystem[] _sessions; /// /// The count of active sessions. @@ -166,6 +166,7 @@ internal void Unregister(AudioInputSystem input) /// /// If true, filter disconnected devices /// The list of all audio inputs name +#pragma warning disable CA1822 // Mark member as static public string[] ListAudioIns(bool filtered) { if (filtered) @@ -173,8 +174,9 @@ public string[] ListAudioIns(bool filtered) // TODO: Detect if the driver supports audio input } - return new string[] { Constants.DefaultDeviceInputName }; + return new[] { Constants.DefaultDeviceInputName }; } +#pragma warning restore CA1822 /// /// Open a new . @@ -205,7 +207,7 @@ public ResultCode OpenAudioIn(out string outputDeviceName, IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Input, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount); - AudioInputSystem audioIn = new AudioInputSystem(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]); + AudioInputSystem audioIn = new(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]); ResultCode result = audioIn.Initialize(inputDeviceName, sampleFormat, ref parameter, sessionId); @@ -238,6 +240,8 @@ public ResultCode OpenAudioIn(out string outputDeviceName, public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -263,4 +267,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Input/AudioInputSystem.cs b/src/Ryujinx.Audio/Input/AudioInputSystem.cs index b3ca0fd68..34623b34f 100644 --- a/src/Ryujinx.Audio/Input/AudioInputSystem.cs +++ b/src/Ryujinx.Audio/Input/AudioInputSystem.cs @@ -18,7 +18,7 @@ public class AudioInputSystem : IDisposable /// /// The session the . /// - private AudioDeviceSession _session; + private readonly AudioDeviceSession _session; /// /// The target device name of the . @@ -43,12 +43,12 @@ public class AudioInputSystem : IDisposable /// /// The owning this. /// - private AudioInputManager _manager; + private readonly AudioInputManager _manager; /// /// The lock of the parent. /// - private object _parentLock; + private readonly object _parentLock; /// /// The dispose state. @@ -90,11 +90,13 @@ private static ResultCode IsConfigurationValid(ref AudioInputConfiguration confi { return ResultCode.DeviceNotFound; } - else if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) + + if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) { return ResultCode.UnsupportedSampleRate; } - else if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) + + if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) { return ResultCode.UnsupportedChannelConfiguration; } @@ -185,11 +187,11 @@ public ResultCode AppendBuffer(ulong bufferTag, ref AudioUserBuffer userBuffer) { lock (_parentLock) { - AudioBuffer buffer = new AudioBuffer + AudioBuffer buffer = new() { BufferTag = bufferTag, DataPointer = userBuffer.Data, - DataSize = userBuffer.DataSize + DataSize = userBuffer.DataSize, }; if (_session.AppendBuffer(buffer)) @@ -213,14 +215,14 @@ public ResultCode AppendUacBuffer(ulong bufferTag, ref AudioUserBuffer userBuffe { lock (_parentLock) { - AudioBuffer buffer = new AudioBuffer + AudioBuffer buffer = new() { BufferTag = bufferTag, DataPointer = userBuffer.Data, - DataSize = userBuffer.DataSize + DataSize = userBuffer.DataSize, }; - if (_session.AppendUacBuffer(buffer, handle)) + if (AudioDeviceSession.AppendUacBuffer(buffer, handle)) { return ResultCode.Success; } @@ -373,6 +375,8 @@ public bool FlushBuffers() public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -389,4 +393,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs b/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs index 552f1ab24..576954b96 100644 --- a/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs +++ b/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs @@ -6,12 +6,12 @@ namespace Ryujinx.Audio.Integration { public class HardwareDeviceImpl : IHardwareDevice { - private IHardwareDeviceSession _session; - private uint _channelCount; - private uint _sampleRate; + private readonly IHardwareDeviceSession _session; + private readonly uint _channelCount; + private readonly uint _sampleRate; private uint _currentBufferTag; - private byte[] _buffer; + private readonly byte[] _buffer; public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate, float volume) { @@ -36,7 +36,7 @@ public void AppendBuffer(ReadOnlySpan data, uint channelCount) DataSize = (ulong)_buffer.Length, }); - _currentBufferTag = _currentBufferTag % 4; + _currentBufferTag %= 4; } public void SetVolume(float volume) @@ -61,6 +61,7 @@ public uint GetSampleRate() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -72,4 +73,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Integration/IHardwareDevice.cs b/src/Ryujinx.Audio/Integration/IHardwareDevice.cs index 300de8c5d..f9ade9dbc 100644 --- a/src/Ryujinx.Audio/Integration/IHardwareDevice.cs +++ b/src/Ryujinx.Audio/Integration/IHardwareDevice.cs @@ -52,4 +52,4 @@ public bool NeedDownmixing() return channelCount != Constants.ChannelCountMax; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs index 4ed179519..9c812fb9a 100644 --- a/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs @@ -13,7 +13,7 @@ public interface IHardwareDeviceDriver : IDisposable public enum Direction { Input, - Output + Output, } IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume = 1f); @@ -33,4 +33,4 @@ IHardwareDeviceDriver GetRealDeviceDriver() return this; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Integration/IHardwareDeviceSession.cs b/src/Ryujinx.Audio/Integration/IHardwareDeviceSession.cs index 400daec00..f29c109cb 100644 --- a/src/Ryujinx.Audio/Integration/IHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio/Integration/IHardwareDeviceSession.cs @@ -25,4 +25,4 @@ public interface IHardwareDeviceSession : IDisposable void PrepareToClose(); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Integration/IWritableEvent.cs b/src/Ryujinx.Audio/Integration/IWritableEvent.cs index 9a12e3d28..a3b3bc0bc 100644 --- a/src/Ryujinx.Audio/Integration/IWritableEvent.cs +++ b/src/Ryujinx.Audio/Integration/IWritableEvent.cs @@ -15,4 +15,4 @@ public interface IWritableEvent /// void Clear(); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Output/AudioOutputManager.cs b/src/Ryujinx.Audio/Output/AudioOutputManager.cs index 8c21f76a1..5232357bb 100644 --- a/src/Ryujinx.Audio/Output/AudioOutputManager.cs +++ b/src/Ryujinx.Audio/Output/AudioOutputManager.cs @@ -14,17 +14,17 @@ namespace Ryujinx.Audio.Output /// public class AudioOutputManager : IDisposable { - private object _lock = new object(); + private readonly object _lock = new(); /// /// Lock used for session allocation. /// - private object _sessionLock = new object(); + private readonly object _sessionLock = new(); /// /// The session ids allocation table. /// - private int[] _sessionIds; + private readonly int[] _sessionIds; /// /// The device driver. @@ -39,7 +39,7 @@ public class AudioOutputManager : IDisposable /// /// The session instances. /// - private AudioOutputSystem[] _sessions; + private readonly AudioOutputSystem[] _sessions; /// /// The count of active sessions. @@ -165,10 +165,12 @@ internal void Unregister(AudioOutputSystem output) /// Get the list of all audio outputs name. /// /// The list of all audio outputs name +#pragma warning disable CA1822 // Mark member as static public string[] ListAudioOuts() { - return new string[] { Constants.DefaultDeviceOutputName }; + return new[] { Constants.DefaultDeviceOutputName }; } +#pragma warning restore CA1822 /// /// Open a new . @@ -182,6 +184,7 @@ public string[] ListAudioOuts() /// The user configuration /// The applet resource user id of the application /// The process handle of the application + /// The volume level to request /// A reporting an error or a success public ResultCode OpenAudioOut(out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, @@ -200,7 +203,7 @@ public ResultCode OpenAudioOut(out string outputDeviceName, IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount, volume); - AudioOutputSystem audioOut = new AudioOutputSystem(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]); + AudioOutputSystem audioOut = new(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]); ResultCode result = audioOut.Initialize(inputDeviceName, sampleFormat, ref parameter, sessionId); @@ -268,6 +271,8 @@ public float GetVolume() public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -293,4 +298,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Output/AudioOutputSystem.cs b/src/Ryujinx.Audio/Output/AudioOutputSystem.cs index 93df87aab..f9b9bdcf1 100644 --- a/src/Ryujinx.Audio/Output/AudioOutputSystem.cs +++ b/src/Ryujinx.Audio/Output/AudioOutputSystem.cs @@ -18,7 +18,7 @@ public class AudioOutputSystem : IDisposable /// /// The session the . /// - private AudioDeviceSession _session; + private readonly AudioDeviceSession _session; /// /// The target device name of the . @@ -43,12 +43,12 @@ public class AudioOutputSystem : IDisposable /// /// The owning this. /// - private AudioOutputManager _manager; + private readonly AudioOutputManager _manager; /// /// THe lock of the parent. /// - private object _parentLock; + private readonly object _parentLock; /// /// The dispose state. @@ -90,11 +90,13 @@ private static ResultCode IsConfigurationValid(ref AudioInputConfiguration confi { return ResultCode.DeviceNotFound; } - else if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) + + if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) { return ResultCode.UnsupportedSampleRate; } - else if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) + + if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) { return ResultCode.UnsupportedChannelConfiguration; } @@ -185,11 +187,11 @@ public ResultCode AppendBuffer(ulong bufferTag, ref AudioUserBuffer userBuffer) { lock (_parentLock) { - AudioBuffer buffer = new AudioBuffer + AudioBuffer buffer = new() { BufferTag = bufferTag, DataPointer = userBuffer.Data, - DataSize = userBuffer.DataSize + DataSize = userBuffer.DataSize, }; if (_session.AppendBuffer(buffer)) @@ -346,6 +348,8 @@ public bool FlushBuffers() public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -362,4 +366,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/AuxiliaryBufferAddresses.cs b/src/Ryujinx.Audio/Renderer/Common/AuxiliaryBufferAddresses.cs index 966474052..b7b97d5d8 100644 --- a/src/Ryujinx.Audio/Renderer/Common/AuxiliaryBufferAddresses.cs +++ b/src/Ryujinx.Audio/Renderer/Common/AuxiliaryBufferAddresses.cs @@ -10,4 +10,4 @@ public struct AuxiliaryBufferAddresses public ulong ReturnBufferInfo; public ulong ReturnBufferInfoBase; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs index 270f84d5b..b0963c935 100644 --- a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs @@ -16,7 +16,7 @@ public struct BehaviourParameter /// /// Reserved/padding. /// - private uint _padding; + private readonly uint _padding; /// /// The flags given controlling behaviour of the audio renderer @@ -38,7 +38,7 @@ public struct ErrorInfo /// /// Reserved/padding. /// - private uint _padding; + private readonly uint _padding; /// /// Extra information given with the @@ -47,4 +47,4 @@ public struct ErrorInfo public ulong ExtraErrorInfo; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/EdgeMatrix.cs b/src/Ryujinx.Audio/Renderer/Common/EdgeMatrix.cs index 24a9350fc..3beb62399 100644 --- a/src/Ryujinx.Audio/Renderer/Common/EdgeMatrix.cs +++ b/src/Ryujinx.Audio/Renderer/Common/EdgeMatrix.cs @@ -147,4 +147,4 @@ public int GetNodeCount() return _nodeCount; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/EffectType.cs b/src/Ryujinx.Audio/Renderer/Common/EffectType.cs index 7128db4ce..7c8713b12 100644 --- a/src/Ryujinx.Audio/Renderer/Common/EffectType.cs +++ b/src/Ryujinx.Audio/Renderer/Common/EffectType.cs @@ -55,4 +55,4 @@ public enum EffectType : byte /// Compressor, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/MemoryPoolUserState.cs b/src/Ryujinx.Audio/Renderer/Common/MemoryPoolUserState.cs index 590731c3b..6d835879c 100644 --- a/src/Ryujinx.Audio/Renderer/Common/MemoryPoolUserState.cs +++ b/src/Ryujinx.Audio/Renderer/Common/MemoryPoolUserState.cs @@ -38,6 +38,6 @@ public enum MemoryPoolUserState : uint /// /// The memory pool is released. (client side only) /// - Released = 6 + Released = 6, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/NodeIdHelper.cs b/src/Ryujinx.Audio/Renderer/Common/NodeIdHelper.cs index a999e3ad1..76fba54b6 100644 --- a/src/Ryujinx.Audio/Renderer/Common/NodeIdHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Common/NodeIdHelper.cs @@ -25,4 +25,4 @@ public static int GetBase(int nodeId) return (nodeId >> 16) & 0xFFF; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/NodeIdType.cs b/src/Ryujinx.Audio/Renderer/Common/NodeIdType.cs index 69b58f6bc..b226da14f 100644 --- a/src/Ryujinx.Audio/Renderer/Common/NodeIdType.cs +++ b/src/Ryujinx.Audio/Renderer/Common/NodeIdType.cs @@ -28,6 +28,6 @@ public enum NodeIdType : byte /// /// Performance monitoring related node id (performance commands) /// - Performance = 15 + Performance = 15, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/NodeStates.cs b/src/Ryujinx.Audio/Renderer/Common/NodeStates.cs index 45748d606..75290a741 100644 --- a/src/Ryujinx.Audio/Renderer/Common/NodeStates.cs +++ b/src/Ryujinx.Audio/Renderer/Common/NodeStates.cs @@ -53,17 +53,17 @@ public static int CalcBufferSize(int nodeCount) } private int _nodeCount; - private EdgeMatrix _discovered; - private EdgeMatrix _finished; + private readonly EdgeMatrix _discovered; + private readonly EdgeMatrix _finished; private Memory _resultArray; - private Stack _stack; + private readonly Stack _stack; private int _tsortResultIndex; private enum NodeState : byte { Unknown, Discovered, - Finished + Finished, } public NodeStates() @@ -88,16 +88,16 @@ public void Initialize(Memory nodeStatesWorkBuffer, int nodeCount) int edgeMatrixWorkBufferSize = EdgeMatrix.GetWorkBufferSize(nodeCount); - _discovered.Initialize(nodeStatesWorkBuffer.Slice(0, edgeMatrixWorkBufferSize), nodeCount); + _discovered.Initialize(nodeStatesWorkBuffer[..edgeMatrixWorkBufferSize], nodeCount); _finished.Initialize(nodeStatesWorkBuffer.Slice(edgeMatrixWorkBufferSize, edgeMatrixWorkBufferSize), nodeCount); - nodeStatesWorkBuffer = nodeStatesWorkBuffer.Slice(edgeMatrixWorkBufferSize * 2); + nodeStatesWorkBuffer = nodeStatesWorkBuffer[(edgeMatrixWorkBufferSize * 2)..]; - _resultArray = SpanMemoryManager.Cast(nodeStatesWorkBuffer.Slice(0, sizeof(int) * nodeCount)); + _resultArray = SpanMemoryManager.Cast(nodeStatesWorkBuffer[..(sizeof(int) * nodeCount)]); - nodeStatesWorkBuffer = nodeStatesWorkBuffer.Slice(sizeof(int) * nodeCount); + nodeStatesWorkBuffer = nodeStatesWorkBuffer[(sizeof(int) * nodeCount)..]; - Memory stackWorkBuffer = SpanMemoryManager.Cast(nodeStatesWorkBuffer.Slice(0, Stack.CalcBufferSize(nodeCount * nodeCount))); + Memory stackWorkBuffer = SpanMemoryManager.Cast(nodeStatesWorkBuffer[..Stack.CalcBufferSize(nodeCount * nodeCount)]); _stack.Reset(stackWorkBuffer, nodeCount * nodeCount); } @@ -120,7 +120,8 @@ private NodeState GetState(int index) return NodeState.Discovered; } - else if (_finished.Test(index)) + + if (_finished.Test(index)) { Debug.Assert(!_discovered.Test(index)); @@ -158,7 +159,7 @@ private void PushTsortResult(int index) public ReadOnlySpan GetTsortResult() { - return _resultArray.Span.Slice(0, _tsortResultIndex); + return _resultArray.Span[.._tsortResultIndex]; } public bool Sort(EdgeMatrix edgeMatrix) @@ -226,4 +227,4 @@ public bool Sort(EdgeMatrix edgeMatrix) return true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/PerformanceDetailType.cs b/src/Ryujinx.Audio/Renderer/Common/PerformanceDetailType.cs index 805d55183..bde32a709 100644 --- a/src/Ryujinx.Audio/Renderer/Common/PerformanceDetailType.cs +++ b/src/Ryujinx.Audio/Renderer/Common/PerformanceDetailType.cs @@ -15,6 +15,6 @@ public enum PerformanceDetailType : byte PcmFloat, Limiter, CaptureBuffer, - Compressor + Compressor, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/PerformanceEntryType.cs b/src/Ryujinx.Audio/Renderer/Common/PerformanceEntryType.cs index bde72aaed..e32095e62 100644 --- a/src/Ryujinx.Audio/Renderer/Common/PerformanceEntryType.cs +++ b/src/Ryujinx.Audio/Renderer/Common/PerformanceEntryType.cs @@ -6,6 +6,6 @@ public enum PerformanceEntryType : byte Voice, SubMix, FinalMix, - Sink + Sink, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/PlayState.cs b/src/Ryujinx.Audio/Renderer/Common/PlayState.cs index 4a6929e03..a83d16afb 100644 --- a/src/Ryujinx.Audio/Renderer/Common/PlayState.cs +++ b/src/Ryujinx.Audio/Renderer/Common/PlayState.cs @@ -18,6 +18,6 @@ public enum PlayState : byte /// /// The user request the voice to be paused. /// - Pause + Pause, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/ReverbEarlyMode.cs b/src/Ryujinx.Audio/Renderer/Common/ReverbEarlyMode.cs index aa7685621..c7443cc49 100644 --- a/src/Ryujinx.Audio/Renderer/Common/ReverbEarlyMode.cs +++ b/src/Ryujinx.Audio/Renderer/Common/ReverbEarlyMode.cs @@ -28,6 +28,6 @@ public enum ReverbEarlyMode : uint /// /// No early reflection. /// - Disabled + Disabled, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/ReverbLateMode.cs b/src/Ryujinx.Audio/Renderer/Common/ReverbLateMode.cs index 8aa88165a..78f91cf08 100644 --- a/src/Ryujinx.Audio/Renderer/Common/ReverbLateMode.cs +++ b/src/Ryujinx.Audio/Renderer/Common/ReverbLateMode.cs @@ -33,6 +33,6 @@ public enum ReverbLateMode : uint /// /// Max delay. (used for delay line limits) /// - Limit = NoDelay + Limit = NoDelay, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/SinkType.cs b/src/Ryujinx.Audio/Renderer/Common/SinkType.cs index 2e17201e7..5a08df4e1 100644 --- a/src/Ryujinx.Audio/Renderer/Common/SinkType.cs +++ b/src/Ryujinx.Audio/Renderer/Common/SinkType.cs @@ -18,6 +18,6 @@ public enum SinkType : byte /// /// The sink is a circular buffer. /// - CircularBuffer + CircularBuffer, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/UpdateDataHeader.cs b/src/Ryujinx.Audio/Renderer/Common/UpdateDataHeader.cs index 70dbfa947..7efe3b02b 100644 --- a/src/Ryujinx.Audio/Renderer/Common/UpdateDataHeader.cs +++ b/src/Ryujinx.Audio/Renderer/Common/UpdateDataHeader.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Memory; using System.Runtime.CompilerServices; namespace Ryujinx.Audio.Renderer.Common @@ -19,7 +20,9 @@ public struct UpdateDataHeader public uint Unknown24; public uint RenderInfoSize; - private unsafe fixed int _reserved[4]; +#pragma warning disable IDE0051, CS0169 // Remove unused field + private Array4 _reserved; +#pragma warning restore IDE0051, CS0169 public uint TotalSize; @@ -30,4 +33,4 @@ public void Initialize(int revision) TotalSize = (uint)Unsafe.SizeOf(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs b/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs index f52c2f4c4..608381af1 100644 --- a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs +++ b/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs @@ -101,4 +101,4 @@ public void MarkEndOfBufferWaveBufferProcessing(ref WaveBuffer waveBuffer, ref i } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/WaveBuffer.cs b/src/Ryujinx.Audio/Renderer/Common/WaveBuffer.cs index 0d00e8384..5109d3fa0 100644 --- a/src/Ryujinx.Audio/Renderer/Common/WaveBuffer.cs +++ b/src/Ryujinx.Audio/Renderer/Common/WaveBuffer.cs @@ -1,5 +1,4 @@ using System.Runtime.InteropServices; - using DspAddr = System.UInt64; namespace Ryujinx.Audio.Renderer.Common @@ -77,6 +76,6 @@ public struct WaveBuffer /// /// Padding/Reserved. /// - private ushort _padding; + private readonly ushort _padding; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Common/WorkBufferAllocator.cs b/src/Ryujinx.Audio/Renderer/Common/WorkBufferAllocator.cs index f35dbec7f..54673f2f6 100644 --- a/src/Ryujinx.Audio/Renderer/Common/WorkBufferAllocator.cs +++ b/src/Ryujinx.Audio/Renderer/Common/WorkBufferAllocator.cs @@ -23,7 +23,7 @@ public Memory Allocate(ulong size, int align) if (size != 0) { - ulong alignedOffset = BitUtils.AlignUp(Offset, (ulong)align); + ulong alignedOffset = BitUtils.AlignUp(Offset, (ulong)align); if (alignedOffset + size <= (ulong)BackingMemory.Length) { @@ -32,7 +32,7 @@ public Memory Allocate(ulong size, int align) Offset = alignedOffset + size; // Clear the memory to be sure that is does not contain any garbage. - result.Span.Fill(0); + result.Span.Clear(); return result; } @@ -55,7 +55,7 @@ public Memory Allocate(ulong count, int align) where T : unmanaged public static ulong GetTargetSize(ulong currentSize, ulong count, int align) where T : unmanaged { - return BitUtils.AlignUp(currentSize, (ulong)align) + (ulong)Unsafe.SizeOf() * count; + return BitUtils.AlignUp(currentSize, (ulong)align) + (ulong)Unsafe.SizeOf() * count; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Device/VirtualDevice.cs b/src/Ryujinx.Audio/Renderer/Device/VirtualDevice.cs index 2fa030a8f..91956fda6 100644 --- a/src/Ryujinx.Audio/Renderer/Device/VirtualDevice.cs +++ b/src/Ryujinx.Audio/Renderer/Device/VirtualDevice.cs @@ -12,11 +12,11 @@ public class VirtualDevice /// public static readonly VirtualDevice[] Devices = new VirtualDevice[5] { - new VirtualDevice("AudioStereoJackOutput", 2, true), - new VirtualDevice("AudioBuiltInSpeakerOutput", 2, false), - new VirtualDevice("AudioTvOutput", 6, false), - new VirtualDevice("AudioUsbDeviceOutput", 2, true), - new VirtualDevice("AudioExternalOutput", 6, true), + new("AudioStereoJackOutput", 2, true), + new("AudioBuiltInSpeakerOutput", 2, false), + new("AudioTvOutput", 6, false), + new("AudioUsbDeviceOutput", 2, true), + new("AudioExternalOutput", 6, true), }; /// @@ -45,7 +45,7 @@ public class VirtualDevice /// The name of the . /// The count of channels supported by the . /// Indicate if the is provided by an external interface. - private VirtualDevice(string name, uint channelCount, bool isExternalOutput) + public VirtualDevice(string name, uint channelCount, bool isExternalOutput) { Name = name; ChannelCount = channelCount; @@ -86,4 +86,4 @@ public string GetOutputDeviceName() return Name; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSession.cs b/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSession.cs index db35d26d2..09fa71eda 100644 --- a/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSession.cs +++ b/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSession.cs @@ -24,4 +24,4 @@ public VirtualDeviceSession(VirtualDevice virtualDevice) Device = virtualDevice; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSessionRegistry.cs b/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSessionRegistry.cs index 927e45add..4ad70619e 100644 --- a/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSessionRegistry.cs +++ b/src/Ryujinx.Audio/Renderer/Device/VirtualDeviceSessionRegistry.cs @@ -1,3 +1,4 @@ +using Ryujinx.Audio.Integration; using System.Collections.Generic; namespace Ryujinx.Audio.Renderer.Device @@ -10,19 +11,37 @@ public class VirtualDeviceSessionRegistry /// /// The session registry, used to store the sessions of a given AppletResourceId. /// - private Dictionary _sessionsRegistry = new Dictionary(); + private readonly Dictionary _sessionsRegistry = new(); /// /// The default . /// /// This is used when the USB device is the default one on older revision. +#pragma warning disable CA1822 // Mark member as static public VirtualDevice DefaultDevice => VirtualDevice.Devices[0]; +#pragma warning restore CA1822 /// /// The current active . /// // TODO: make this configurable - public VirtualDevice ActiveDevice = VirtualDevice.Devices[2]; + public VirtualDevice ActiveDevice { get; } + + public VirtualDeviceSessionRegistry(IHardwareDeviceDriver driver) + { + uint channelCount; + + if (driver.GetRealDeviceDriver().SupportsChannelCount(6)) + { + channelCount = 6; + } + else + { + channelCount = 2; + } + + ActiveDevice = new VirtualDevice("AudioTvOutput", channelCount, false); + } /// /// Get the associated from an AppletResourceId. @@ -59,4 +78,4 @@ private static VirtualDeviceSession[] CreateSessionsFromBehaviourContext() return virtualDeviceSession; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/AdpcmHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/AdpcmHelper.cs index 2680dcb1e..5cb4509ff 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/AdpcmHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/AdpcmHelper.cs @@ -12,7 +12,9 @@ public static class AdpcmHelper private const int SamplesPerFrame = 14; private const int NibblesPerFrame = SamplesPerFrame + 2; private const int BytesPerFrame = 8; +#pragma warning disable IDE0051 // Remove unused private member private const int BitsPerFrame = BytesPerFrame * 8; +#pragma warning restore IDE0051 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint GetAdpcmDataSize(int sampleCount) @@ -64,10 +66,14 @@ public static int GetNibblesFromSampleCount(int sampleCount) private static short Saturate(int value) { if (value > short.MaxValue) + { value = short.MaxValue; + } if (value < short.MinValue) + { value = short.MinValue; + } return (short)value; } @@ -109,7 +115,7 @@ public static int Decode(Span output, ReadOnlySpan input, int start ReadOnlySpan targetInput; - targetInput = input.Slice(nibbles / 2); + targetInput = input[(nibbles / 2)..]; while (remaining > 0) { @@ -213,4 +219,4 @@ public static int Decode(Span output, ReadOnlySpan input, int start return decodedCount; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs b/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs index 7bd0443c2..9c885b2cf 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs @@ -18,7 +18,7 @@ private enum MailboxMessage : uint Start, Stop, RenderStart, - RenderEnd + RenderEnd, } private class RendererSession @@ -36,7 +36,7 @@ private class RendererSession private long _lastTime; private long _playbackEnds; - private ManualResetEvent _event; + private readonly ManualResetEvent _event; private ManualResetEvent _pauseEvent; @@ -45,6 +45,7 @@ public AudioProcessor() _event = new ManualResetEvent(false); } +#pragma warning disable IDE0051 // Remove unused private member private static uint GetHardwareChannelCount(IHardwareDeviceDriver deviceDriver) { // Get the real device driver (In case the compat layer is on top of it). @@ -54,20 +55,17 @@ private static uint GetHardwareChannelCount(IHardwareDeviceDriver deviceDriver) { return 6; } - else - { - // NOTE: We default to stereo as this will get downmixed to mono by the compat layer if it's not compatible. - return 2; - } + + // NOTE: We default to stereo as this will get downmixed to mono by the compat layer if it's not compatible. + return 2; } +#pragma warning restore IDE0051 public void Start(IHardwareDeviceDriver deviceDriver, float volume) { OutputDevices = new IHardwareDevice[Constants.AudioRendererSessionCountMax]; - // TODO: Before enabling this, we need up-mixing from stereo to 5.1. - // uint channelCount = GetHardwareChannelCount(deviceDriver); - uint channelCount = 2; + uint channelCount = GetHardwareChannelCount(deviceDriver); for (int i = 0; i < OutputDevices.Length; i++) { @@ -112,7 +110,7 @@ public void Send(int sessionId, CommandList commands, int renderingLimit, ulong { CommandList = commands, RenderingLimit = renderingLimit, - AppletResourceId = appletResourceId + AppletResourceId = appletResourceId, }; } @@ -173,7 +171,7 @@ private void StartThread() { _workerThread = new Thread(Work) { - Name = "AudioProcessor.Worker" + Name = "AudioProcessor.Worker", }; _workerThread.Start(); @@ -262,6 +260,7 @@ public void SetVolume(float volume) public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -273,4 +272,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs index 98460ff1a..1a51a1fbd 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs @@ -80,4 +80,4 @@ public static void ProcessBiquadFilter(ReadOnlySpan param } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs index 1fe6069f7..51a12b4e7 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs @@ -1,7 +1,9 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Server.Voice; using System; using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter; +using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer; namespace Ryujinx.Audio.Renderer.Dsp.Command { @@ -29,7 +31,7 @@ public class AdpcmDataSourceCommandVersion1 : ICommand public DecodingBehaviour DecodingBehaviour { get; } - public AdpcmDataSourceCommandVersion1(ref Server.Voice.VoiceState serverState, Memory state, ushort outputBufferIndex, int nodeId) + public AdpcmDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -57,7 +59,7 @@ public void Process(CommandList context) { Span outputBuffer = context.GetBuffer(OutputBufferIndex); - DataSourceHelper.WaveBufferInformation info = new DataSourceHelper.WaveBufferInformation + DataSourceHelper.WaveBufferInformation info = new() { SourceSampleRate = SampleRate, SampleFormat = SampleFormat.Adpcm, @@ -72,4 +74,4 @@ public void Process(CommandList context) DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs index 5c3c0324b..73d66dcf4 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs @@ -31,9 +31,18 @@ public class AuxiliaryBufferCommand : ICommand public bool IsEffectEnabled { get; } - public AuxiliaryBufferCommand(uint bufferOffset, byte inputBufferOffset, byte outputBufferOffset, - ref AuxiliaryBufferAddresses sendBufferInfo, bool isEnabled, uint countMax, - CpuAddress outputBuffer, CpuAddress inputBuffer, uint updateCount, uint writeOffset, int nodeId) + public AuxiliaryBufferCommand( + uint bufferOffset, + byte inputBufferOffset, + byte outputBufferOffset, + ref AuxiliaryBufferAddresses sendBufferInfo, + bool isEnabled, + uint countMax, + CpuAddress outputBuffer, + CpuAddress inputBuffer, + uint updateCount, + uint writeOffset, + int nodeId) { Enabled = true; NodeId = nodeId; @@ -155,7 +164,7 @@ public void Process(CommandList context) if (readResult != context.SampleCount) { - outputBuffer.Slice((int)readResult, (int)context.SampleCount - (int)readResult).Fill(0); + outputBuffer[(int)readResult..(int)context.SampleCount].Clear(); } } else @@ -170,4 +179,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs index b994c1cb9..ac1e581f6 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs @@ -21,7 +21,14 @@ public class BiquadFilterCommand : ICommand private BiquadFilterParameter _parameter; - public BiquadFilterCommand(int baseIndex, ref BiquadFilterParameter filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId) + public BiquadFilterCommand( + int baseIndex, + ref BiquadFilterParameter filter, + Memory biquadFilterStateMemory, + int inputBufferOffset, + int outputBufferOffset, + bool needInitialization, + int nodeId) { _parameter = filter; BiquadFilterState = biquadFilterStateMemory; @@ -48,4 +55,4 @@ public void Process(CommandList context) BiquadFilterHelper.ProcessBiquadFilter(ref _parameter, ref state, outputBuffer, inputBuffer, context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs index da1cb2546..01bff1e7d 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs @@ -133,4 +133,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs index e50637eb3..59ef70932 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs @@ -43,7 +43,7 @@ public CircularBufferSinkCommand(uint bufferOffset, ref CircularBufferParameter public void Process(CommandList context) { - const int targetChannelCount = 2; + const int TargetChannelCount = 2; ulong currentOffset = CurrentOffset; @@ -59,10 +59,10 @@ public void Process(CommandList context) for (int y = 0; y < context.SampleCount; y++) { - context.MemoryManager.Write(targetOffset + (ulong)y * targetChannelCount, PcmHelper.Saturate(inputBuffer[y])); + context.MemoryManager.Write(targetOffset + (ulong)y * TargetChannelCount, PcmHelper.Saturate(inputBuffer[y])); } - currentOffset += context.SampleCount * targetChannelCount; + currentOffset += context.SampleCount * TargetChannelCount; if (currentOffset >= CircularBufferSize) { @@ -73,4 +73,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs index 9e653e804..f0f85b0b2 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs @@ -21,4 +21,4 @@ public void Process(CommandList context) context.ClearBuffers(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs index 2cbed9c2b..3fe106ddf 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs @@ -71,13 +71,13 @@ public unsafe IntPtr GetBufferPointer(int index) return (IntPtr)((float*)_buffersMemoryHandle.Pointer + index * _sampleCount); } - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(index), index, null); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void ClearBuffer(int index) { - Unsafe.InitBlock((void*)GetBufferPointer(index), 0, SampleCount); + Unsafe.InitBlock((void*)GetBufferPointer(index), 0, SampleCount * sizeof(float)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -89,7 +89,7 @@ public unsafe void ClearBuffers() [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void CopyBuffer(int outputBufferIndex, int inputBufferIndex) { - Unsafe.CopyBlock((void*)GetBufferPointer(outputBufferIndex), (void*)GetBufferPointer(inputBufferIndex), SampleCount); + Unsafe.CopyBlock((void*)GetBufferPointer(outputBufferIndex), (void*)GetBufferPointer(inputBufferIndex), SampleCount * sizeof(float)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -149,7 +149,8 @@ public void Process(IHardwareDevice outputDevice) public void Dispose() { + GC.SuppressFinalize(this); _buffersMemoryHandle.Dispose(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs index 9ce181b17..098a04a04 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs @@ -32,6 +32,6 @@ public enum CommandType : byte LimiterVersion2, GroupedBiquadFilter, CaptureBuffer, - Compressor + Compressor, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs index 34231e614..09f415d20 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs @@ -1,6 +1,7 @@ -using Ryujinx.Audio.Renderer.Dsp.Effect; +using Ryujinx.Audio.Renderer.Dsp.Effect; using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using System; using System.Diagnostics; @@ -51,11 +52,11 @@ public void Process(CommandList context) if (IsEffectEnabled) { - if (_parameter.Status == Server.Effect.UsageState.Invalid) + if (_parameter.Status == UsageState.Invalid) { state = new CompressorState(ref _parameter); } - else if (_parameter.Status == Server.Effect.UsageState.New) + else if (_parameter.Status == UsageState.New) { state.UpdateParameter(ref _parameter); } @@ -93,18 +94,18 @@ private unsafe void ProcessCompressor(CommandList context, ref CompressorState s float newMean = inputMovingAverage.Update(FloatingPointHelper.MeanSquare(channelInput), _parameter.InputGain); float y = FloatingPointHelper.Log10(newMean) * 10.0f; - float z = 0.0f; + float z = 1.0f; - bool unknown10OutOfRange = false; + bool unknown10OutOfRange = y >= state.Unknown10; if (newMean < 1.0e-10f) { - z = 1.0f; + y = -100.0f; - unknown10OutOfRange = state.Unknown10 < -100.0f; + unknown10OutOfRange = state.Unknown10 <= -100.0f; } - if (y >= state.Unknown10 || unknown10OutOfRange) + if (unknown10OutOfRange) { float tmpGain; @@ -117,7 +118,7 @@ private unsafe void ProcessCompressor(CommandList context, ref CompressorState s tmpGain = (y - state.Unknown10) * ((y - state.Unknown10) * -state.CompressorGainReduction); } - z = FloatingPointHelper.DecibelToLinearExtended(tmpGain); + z = FloatingPointHelper.DecibelToLinear(tmpGain); } float unknown4New = z; diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs index 7237fddf6..3f6aa8390 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs @@ -27,4 +27,4 @@ public void Process(CommandList context) context.CopyBuffer(OutputBufferIndex, InputBufferIndex); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs index c1503b6a0..e82d403bf 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs @@ -1,7 +1,9 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Server.Voice; using System; using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter; +using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer; namespace Ryujinx.Audio.Renderer.Dsp.Command { @@ -37,7 +39,7 @@ public class DataSourceVersion2Command : ICommand public SampleRateConversionQuality SrcQuality { get; } - public DataSourceVersion2Command(ref Server.Voice.VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public DataSourceVersion2Command(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -72,24 +74,20 @@ public DataSourceVersion2Command(ref Server.Voice.VoiceState serverState, Memory private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat) { - switch (sampleFormat) + return sampleFormat switch { - case SampleFormat.Adpcm: - return CommandType.AdpcmDataSourceVersion2; - case SampleFormat.PcmInt16: - return CommandType.PcmInt16DataSourceVersion2; - case SampleFormat.PcmFloat: - return CommandType.PcmFloatDataSourceVersion2; - default: - throw new NotImplementedException($"{sampleFormat}"); - } + SampleFormat.Adpcm => CommandType.AdpcmDataSourceVersion2, + SampleFormat.PcmInt16 => CommandType.PcmInt16DataSourceVersion2, + SampleFormat.PcmFloat => CommandType.PcmFloatDataSourceVersion2, + _ => throw new NotImplementedException($"{sampleFormat}"), + }; } public void Process(CommandList context) { Span outputBuffer = context.GetBuffer(OutputBufferIndex); - DataSourceHelper.WaveBufferInformation info = new DataSourceHelper.WaveBufferInformation + DataSourceHelper.WaveBufferInformation info = new() { SourceSampleRate = SampleRate, SampleFormat = SampleFormat, @@ -99,10 +97,10 @@ public void Process(CommandList context) ExtraParameterSize = ExtraParameterSize, ChannelIndex = (int)ChannelIndex, ChannelCount = (int)ChannelCount, - SrcQuality = SrcQuality + SrcQuality = SrcQuality, }; DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs index cb5678c7b..6fa3777f4 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs @@ -49,14 +49,14 @@ public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - const ushort channelCount = 2; + const ushort ChannelCount = 2; float delayFeedbackBaseGain = state.DelayFeedbackBaseGain; float delayFeedbackCrossGain = state.DelayFeedbackCrossGain; @@ -87,18 +87,18 @@ private unsafe void ProcessDelayStereo(ref DelayState state, Span output float dryGain = FixedPointHelper.ToFloat(Parameter.DryGain, FixedPointPrecision); float outGain = FixedPointHelper.ToFloat(Parameter.OutGain, FixedPointPrecision); - Matrix2x2 delayFeedback = new Matrix2x2(delayFeedbackBaseGain, delayFeedbackCrossGain, - delayFeedbackCrossGain, delayFeedbackBaseGain); + Matrix2x2 delayFeedback = new(delayFeedbackBaseGain, delayFeedbackCrossGain, + delayFeedbackCrossGain, delayFeedbackBaseGain); for (int i = 0; i < sampleCount; i++) { - Vector2 channelInput = new Vector2 + Vector2 channelInput = new() { X = *((float*)inputBuffers[0] + i) * 64, Y = *((float*)inputBuffers[1] + i) * 64, }; - Vector2 delayLineValues = new Vector2() + Vector2 delayLineValues = new() { X = state.DelayLines[0].Read(), Y = state.DelayLines[1].Read(), @@ -106,7 +106,7 @@ private unsafe void ProcessDelayStereo(ref DelayState state, Span output Vector2 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain; - state.UpdateLowPassFilter(ref Unsafe.As(ref temp), channelCount); + state.UpdateLowPassFilter(ref Unsafe.As(ref temp), ChannelCount); *((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64; *((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64; @@ -116,7 +116,7 @@ private unsafe void ProcessDelayStereo(ref DelayState state, Span output [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private unsafe void ProcessDelayQuadraphonic(ref DelayState state, Span outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - const ushort channelCount = 4; + const ushort ChannelCount = 4; float delayFeedbackBaseGain = state.DelayFeedbackBaseGain; float delayFeedbackCrossGain = state.DelayFeedbackCrossGain; @@ -124,33 +124,33 @@ private unsafe void ProcessDelayQuadraphonic(ref DelayState state, Span float dryGain = FixedPointHelper.ToFloat(Parameter.DryGain, FixedPointPrecision); float outGain = FixedPointHelper.ToFloat(Parameter.OutGain, FixedPointPrecision); - Matrix4x4 delayFeedback = new Matrix4x4(delayFeedbackBaseGain, delayFeedbackCrossGain, delayFeedbackCrossGain, 0.0f, - delayFeedbackCrossGain, delayFeedbackBaseGain, 0.0f, delayFeedbackCrossGain, - delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, - 0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain); + Matrix4x4 delayFeedback = new(delayFeedbackBaseGain, delayFeedbackCrossGain, delayFeedbackCrossGain, 0.0f, + delayFeedbackCrossGain, delayFeedbackBaseGain, 0.0f, delayFeedbackCrossGain, + delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, + 0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain); for (int i = 0; i < sampleCount; i++) { - Vector4 channelInput = new Vector4 + Vector4 channelInput = new() { X = *((float*)inputBuffers[0] + i) * 64, Y = *((float*)inputBuffers[1] + i) * 64, Z = *((float*)inputBuffers[2] + i) * 64, - W = *((float*)inputBuffers[3] + i) * 64 + W = *((float*)inputBuffers[3] + i) * 64, }; - Vector4 delayLineValues = new Vector4() + Vector4 delayLineValues = new() { X = state.DelayLines[0].Read(), Y = state.DelayLines[1].Read(), Z = state.DelayLines[2].Read(), - W = state.DelayLines[3].Read() + W = state.DelayLines[3].Read(), }; Vector4 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain; - state.UpdateLowPassFilter(ref Unsafe.As(ref temp), channelCount); + state.UpdateLowPassFilter(ref Unsafe.As(ref temp), ChannelCount); *((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64; *((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64; @@ -162,7 +162,7 @@ private unsafe void ProcessDelayQuadraphonic(ref DelayState state, Span [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private unsafe void ProcessDelaySurround(ref DelayState state, Span outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - const ushort channelCount = 6; + const ushort ChannelCount = 6; float feedbackGain = FixedPointHelper.ToFloat(Parameter.FeedbackGain, FixedPointPrecision); float delayFeedbackBaseGain = state.DelayFeedbackBaseGain; @@ -171,38 +171,38 @@ private unsafe void ProcessDelaySurround(ref DelayState state, Span outp float dryGain = FixedPointHelper.ToFloat(Parameter.DryGain, FixedPointPrecision); float outGain = FixedPointHelper.ToFloat(Parameter.OutGain, FixedPointPrecision); - Matrix6x6 delayFeedback = new Matrix6x6(delayFeedbackBaseGain, 0.0f, delayFeedbackCrossGain, 0.0f, delayFeedbackCrossGain, 0.0f, - 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, 0.0f, 0.0f, delayFeedbackCrossGain, - delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, feedbackGain, 0.0f, 0.0f, - delayFeedbackCrossGain, 0.0f, 0.0f, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, - 0.0f, delayFeedbackCrossGain, 0.0f, 0.0f, delayFeedbackCrossGain, delayFeedbackBaseGain); + Matrix6x6 delayFeedback = new(delayFeedbackBaseGain, 0.0f, delayFeedbackCrossGain, 0.0f, delayFeedbackCrossGain, 0.0f, + 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, 0.0f, 0.0f, delayFeedbackCrossGain, + delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, feedbackGain, 0.0f, 0.0f, + delayFeedbackCrossGain, 0.0f, 0.0f, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, + 0.0f, delayFeedbackCrossGain, 0.0f, 0.0f, delayFeedbackCrossGain, delayFeedbackBaseGain); for (int i = 0; i < sampleCount; i++) { - Vector6 channelInput = new Vector6 + Vector6 channelInput = new() { X = *((float*)inputBuffers[0] + i) * 64, Y = *((float*)inputBuffers[1] + i) * 64, Z = *((float*)inputBuffers[2] + i) * 64, W = *((float*)inputBuffers[3] + i) * 64, V = *((float*)inputBuffers[4] + i) * 64, - U = *((float*)inputBuffers[5] + i) * 64 + U = *((float*)inputBuffers[5] + i) * 64, }; - Vector6 delayLineValues = new Vector6 + Vector6 delayLineValues = new() { X = state.DelayLines[0].Read(), Y = state.DelayLines[1].Read(), Z = state.DelayLines[2].Read(), W = state.DelayLines[3].Read(), V = state.DelayLines[4].Read(), - U = state.DelayLines[5].Read() + U = state.DelayLines[5].Read(), }; Vector6 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain; - state.UpdateLowPassFilter(ref Unsafe.As(ref temp), channelCount); + state.UpdateLowPassFilter(ref Unsafe.As(ref temp), ChannelCount); *((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64; *((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64; @@ -277,4 +277,4 @@ public void Process(CommandList context) ProcessDelay(context, ref state); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs index 1dba56e6c..ff38f38ca 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs @@ -55,17 +55,15 @@ private unsafe float ProcessDepopMix(float* buffer, float depopValue, uint sampl return -depopValue; } - else - { - for (int i = 0; i < sampleCount; i++) - { - depopValue = FloatingPointHelper.MultiplyRoundDown(Decay, depopValue); - buffer[i] += depopValue; - } + for (int i = 0; i < sampleCount; i++) + { + depopValue = FloatingPointHelper.MultiplyRoundDown(Decay, depopValue); - return depopValue; + buffer[i] += depopValue; } + + return depopValue; } public void Process(CommandList context) @@ -89,4 +87,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs index d02f7c121..c64bbdc57 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs @@ -54,4 +54,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs index 9c88a4e7f..19afc66f4 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs @@ -65,21 +65,33 @@ public void Process(CommandList context) int channelCount = (int)device.GetChannelCount(); uint bufferCount = Math.Min(device.GetChannelCount(), InputCount); - const int sampleCount = Constants.TargetSampleCount; + const int SampleCount = Constants.TargetSampleCount; - short[] outputBuffer = new short[bufferCount * sampleCount]; + uint inputCount; + + // In case of upmixing to 5.1, we allocate the right amount. + if (bufferCount != channelCount && channelCount == 6) + { + inputCount = (uint)channelCount; + } + else + { + inputCount = bufferCount; + } + + short[] outputBuffer = new short[inputCount * SampleCount]; for (int i = 0; i < bufferCount; i++) { - ReadOnlySpan inputBuffer = GetBuffer(InputBufferIndices[i], sampleCount); + ReadOnlySpan inputBuffer = GetBuffer(InputBufferIndices[i], SampleCount); - for (int j = 0; j < sampleCount; j++) + for (int j = 0; j < SampleCount; j++) { outputBuffer[i + j * channelCount] = PcmHelper.Saturate(inputBuffer[j]); } } - device.AppendBuffer(outputBuffer, InputCount); + device.AppendBuffer(outputBuffer, inputCount); } else { @@ -88,4 +100,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs index 79cefcc53..8997b0dbd 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs @@ -65,4 +65,4 @@ public void Process(CommandList context) context.ClearBuffer(OutputBufferIndices[5]); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/GroupedBiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/GroupedBiquadFilterCommand.cs index b190cc10d..7af851bdc 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/GroupedBiquadFilterCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/GroupedBiquadFilterCommand.cs @@ -14,11 +14,11 @@ public class GroupedBiquadFilterCommand : ICommand public uint EstimatedProcessingTime { get; set; } - private BiquadFilterParameter[] _parameters; - private Memory _biquadFilterStates; - private int _inputBufferIndex; - private int _outputBufferIndex; - private bool[] _isInitialized; + private readonly BiquadFilterParameter[] _parameters; + private readonly Memory _biquadFilterStates; + private readonly int _inputBufferIndex; + private readonly int _outputBufferIndex; + private readonly bool[] _isInitialized; public GroupedBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId) { @@ -59,4 +59,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/ICommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/ICommand.cs index d281e6e9f..34a62c58d 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/ICommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/ICommand.cs @@ -17,4 +17,4 @@ public bool ShouldMeter() return false; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs index a464ad704..3ba0b5884 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs @@ -1,5 +1,6 @@ using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using System; using System.Diagnostics; @@ -50,13 +51,13 @@ public void Process(CommandList context) if (IsEffectEnabled) { - if (Parameter.Status == Server.Effect.UsageState.Invalid) + if (Parameter.Status == UsageState.Invalid) { state = new LimiterState(ref _parameter, WorkBuffer); } - else if (Parameter.Status == Server.Effect.UsageState.New) + else if (Parameter.Status == UsageState.New) { - state.UpdateParameter(ref _parameter); + LimiterState.UpdateParameter(ref _parameter); } } @@ -141,4 +142,4 @@ private unsafe void ProcessLimiter(CommandList context, ref LimiterState state) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs index 950de97b8..f6e1654dd 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs @@ -1,6 +1,7 @@ using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Parameter.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using System; using System.Diagnostics; using System.Runtime.InteropServices; @@ -27,7 +28,14 @@ public class LimiterCommandVersion2 : ICommand private LimiterParameter _parameter; - public LimiterCommandVersion2(uint bufferOffset, LimiterParameter parameter, Memory state, Memory resultState, bool isEnabled, ulong workBuffer, int nodeId) + public LimiterCommandVersion2( + uint bufferOffset, + LimiterParameter parameter, + Memory state, + Memory resultState, + bool isEnabled, + ulong workBuffer, + int nodeId) { Enabled = true; NodeId = nodeId; @@ -54,13 +62,13 @@ public void Process(CommandList context) if (IsEffectEnabled) { - if (Parameter.Status == Server.Effect.UsageState.Invalid) + if (Parameter.Status == UsageState.Invalid) { state = new LimiterState(ref _parameter, WorkBuffer); } - else if (Parameter.Status == Server.Effect.UsageState.New) + else if (Parameter.Status == UsageState.New) { - state.UpdateParameter(ref _parameter); + LimiterState.UpdateParameter(ref _parameter); } } @@ -160,4 +168,4 @@ private unsafe void ProcessLimiter(CommandList context, ref LimiterState state) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs index 2616bda57..c701f80eb 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs @@ -134,4 +134,4 @@ public void Process(CommandList context) ProcessMix(outputBuffer, inputBuffer); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs index 76a1aba25..f77a233e1 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs @@ -65,4 +65,4 @@ public void Process(CommandList context) State.Span[0].LastSamples[LastSampleIndex] = ProcessMixRamp(outputBuffer, inputBuffer, (int)context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs index e348e3588..3c7dd63b2 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs @@ -48,7 +48,7 @@ public MixRampGroupedCommand(uint mixBufferCount, uint inputBufferIndex, uint ou } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private float ProcessMixRampGrouped(Span outputBuffer, ReadOnlySpan inputBuffer, float volume0, float volume1, int sampleCount) + private static float ProcessMixRampGrouped(Span outputBuffer, ReadOnlySpan inputBuffer, float volume0, float volume1, int sampleCount) { float ramp = (volume1 - volume0) / sampleCount; float volume = volume0; @@ -88,4 +88,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs index 7cec7d2ab..585edc058 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs @@ -1,7 +1,9 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Server.Voice; using System; using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter; +using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer; namespace Ryujinx.Audio.Renderer.Dsp.Command { @@ -28,7 +30,7 @@ public class PcmFloatDataSourceCommandVersion1 : ICommand public Memory State { get; } public DecodingBehaviour DecodingBehaviour { get; } - public PcmFloatDataSourceCommandVersion1(ref Server.Voice.VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public PcmFloatDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -56,7 +58,7 @@ public void Process(CommandList context) { Span outputBuffer = context.GetBuffer(OutputBufferIndex); - DataSourceHelper.WaveBufferInformation info = new DataSourceHelper.WaveBufferInformation + DataSourceHelper.WaveBufferInformation info = new() { SourceSampleRate = SampleRate, SampleFormat = SampleFormat.PcmFloat, @@ -71,4 +73,4 @@ public void Process(CommandList context) DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs index dfe9814fe..6f01219f3 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs @@ -1,7 +1,9 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Server.Voice; using System; using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter; +using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer; namespace Ryujinx.Audio.Renderer.Dsp.Command { @@ -28,7 +30,7 @@ public class PcmInt16DataSourceCommandVersion1 : ICommand public Memory State { get; } public DecodingBehaviour DecodingBehaviour { get; } - public PcmInt16DataSourceCommandVersion1(ref Server.Voice.VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public PcmInt16DataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -56,7 +58,7 @@ public void Process(CommandList context) { Span outputBuffer = context.GetBuffer(OutputBufferIndex); - DataSourceHelper.WaveBufferInformation info = new DataSourceHelper.WaveBufferInformation + DataSourceHelper.WaveBufferInformation info = new() { SourceSampleRate = SampleRate, SampleFormat = SampleFormat.PcmInt16, @@ -71,4 +73,4 @@ public void Process(CommandList context) DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs index d3e3f8056..d3d2ee306 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs @@ -8,7 +8,7 @@ public enum Type { Invalid, Start, - End + End, } public bool Enabled { get; set; } @@ -44,4 +44,4 @@ public void Process(CommandList context) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs index eeb645673..8cdd4843b 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs @@ -9,21 +9,21 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public class Reverb3dCommand : ICommand { - private static readonly int[] OutputEarlyIndicesTableMono = new int[20] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableMono = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; - private static readonly int[] TargetOutputFeedbackIndicesTableMono = new int[1] { 0 }; + private static readonly int[] _outputEarlyIndicesTableMono = new int[20] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableMono = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + private static readonly int[] _targetOutputFeedbackIndicesTableMono = new int[1] { 0 }; - private static readonly int[] OutputEarlyIndicesTableStereo = new int[20] { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableStereo = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; - private static readonly int[] TargetOutputFeedbackIndicesTableStereo = new int[2] { 0, 1 }; + private static readonly int[] _outputEarlyIndicesTableStereo = new int[20] { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + private static readonly int[] _targetOutputFeedbackIndicesTableStereo = new int[2] { 0, 1 }; - private static readonly int[] OutputEarlyIndicesTableQuadraphonic = new int[20] { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableQuadraphonic = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; - private static readonly int[] TargetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; + private static readonly int[] _outputEarlyIndicesTableQuadraphonic = new int[20] { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; - private static readonly int[] OutputEarlyIndicesTableSurround = new int[40] { 4, 5, 0, 5, 0, 5, 1, 5, 1, 5, 1, 5, 1, 5, 2, 5, 2, 5, 2, 5, 1, 5, 1, 5, 1, 5, 0, 5, 0, 5, 0, 5, 0, 5, 3, 5, 3, 5, 3, 5 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableSurround = new int[40] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19 }; - private static readonly int[] TargetOutputFeedbackIndicesTableSurround = new int[6] { 0, 1, 2, 3, -1, 3 }; + private static readonly int[] _outputEarlyIndicesTableSurround = new int[40] { 4, 5, 0, 5, 0, 5, 1, 5, 1, 5, 1, 5, 1, 5, 2, 5, 2, 5, 2, 5, 1, 5, 1, 5, 1, 5, 0, 5, 0, 5, 0, 5, 0, 5, 3, 5, 3, 5, 3, 5 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = new int[40] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19 }; + private static readonly int[] _targetOutputFeedbackIndicesTableSurround = new int[6] { 0, 1, 2, 3, -1, 3 }; public bool Enabled { get; set; } @@ -66,37 +66,37 @@ public Reverb3dCommand(uint bufferOffset, Reverb3dParameter parameter, Memory outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, OutputEarlyIndicesTableMono, TargetEarlyDelayLineIndicesTableMono, TargetOutputFeedbackIndicesTableMono); + ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, _outputEarlyIndicesTableMono, _targetEarlyDelayLineIndicesTableMono, _targetOutputFeedbackIndicesTableMono); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverb3dStereo(ref Reverb3dState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, OutputEarlyIndicesTableStereo, TargetEarlyDelayLineIndicesTableStereo, TargetOutputFeedbackIndicesTableStereo); + ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, _outputEarlyIndicesTableStereo, _targetEarlyDelayLineIndicesTableStereo, _targetOutputFeedbackIndicesTableStereo); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverb3dQuadraphonic(ref Reverb3dState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, OutputEarlyIndicesTableQuadraphonic, TargetEarlyDelayLineIndicesTableQuadraphonic, TargetOutputFeedbackIndicesTableQuadraphonic); + ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, _outputEarlyIndicesTableQuadraphonic, _targetEarlyDelayLineIndicesTableQuadraphonic, _targetOutputFeedbackIndicesTableQuadraphonic); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverb3dSurround(ref Reverb3dState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, OutputEarlyIndicesTableSurround, TargetEarlyDelayLineIndicesTableSurround, TargetOutputFeedbackIndicesTableSurround); + ProcessReverb3dGeneric(ref state, outputBuffers, inputBuffers, sampleCount, _outputEarlyIndicesTableSurround, _targetEarlyDelayLineIndicesTableSurround, _targetOutputFeedbackIndicesTableSurround); } private unsafe void ProcessReverb3dGeneric(ref Reverb3dState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount, ReadOnlySpan outputEarlyIndicesTable, ReadOnlySpan targetEarlyDelayLineIndicesTable, ReadOnlySpan targetOutputFeedbackIndicesTable) { - const int delayLineSampleIndexOffset = 1; + const int DelayLineSampleIndexOffset = 1; bool isMono = Parameter.ChannelCount == 1; bool isSurround = Parameter.ChannelCount == 6; @@ -109,16 +109,16 @@ private unsafe void ProcessReverb3dGeneric(ref Reverb3dState state, ReadOnlySpan for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { - outputValues.Fill(0); + outputValues.Clear(); - float tapOut = state.PreDelayLine.TapUnsafe(state.ReflectionDelayTime, delayLineSampleIndexOffset); + float tapOut = state.PreDelayLine.TapUnsafe(state.ReflectionDelayTime, DelayLineSampleIndexOffset); for (int i = 0; i < targetEarlyDelayLineIndicesTable.Length; i++) { int earlyDelayIndex = targetEarlyDelayLineIndicesTable[i]; - int outputIndex = outputEarlyIndicesTable[i]; + int outputIndex = outputEarlyIndicesTable[earlyDelayIndex]; - float tempTapOut = state.PreDelayLine.TapUnsafe(state.EarlyDelayTime[earlyDelayIndex], delayLineSampleIndexOffset); + float tempTapOut = state.PreDelayLine.TapUnsafe(state.EarlyDelayTime[earlyDelayIndex], DelayLineSampleIndexOffset); outputValues[outputIndex] += tempTapOut * state.EarlyGain[earlyDelayIndex]; } @@ -251,4 +251,4 @@ public void Process(CommandList context) ProcessReverb3d(context, ref state); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs index 0a32a065d..874eb8e8b 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs @@ -1,5 +1,6 @@ using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using System; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -8,25 +9,25 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public class ReverbCommand : ICommand { - private static readonly int[] OutputEarlyIndicesTableMono = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableMono = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - private static readonly int[] OutputIndicesTableMono = new int[4] { 0, 0, 0, 0 }; - private static readonly int[] TargetOutputFeedbackIndicesTableMono = new int[4] { 0, 1, 2, 3 }; - - private static readonly int[] OutputEarlyIndicesTableStereo = new int[10] { 0, 0, 1, 1, 0, 1, 0, 0, 1, 1 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableStereo = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - private static readonly int[] OutputIndicesTableStereo = new int[4] { 0, 0, 1, 1 }; - private static readonly int[] TargetOutputFeedbackIndicesTableStereo = new int[4] { 2, 0, 3, 1 }; - - private static readonly int[] OutputEarlyIndicesTableQuadraphonic = new int[10] { 0, 0, 1, 1, 0, 1, 2, 2, 3, 3 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableQuadraphonic = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - private static readonly int[] OutputIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; - private static readonly int[] TargetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; - - private static readonly int[] OutputEarlyIndicesTableSurround = new int[20] { 0, 5, 0, 5, 1, 5, 1, 5, 4, 5, 4, 5, 2, 5, 2, 5, 3, 5, 3, 5 }; - private static readonly int[] TargetEarlyDelayLineIndicesTableSurround = new int[20] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9 }; - private static readonly int[] OutputIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, 4, 5 }; - private static readonly int[] TargetOutputFeedbackIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, -1, 3 }; + private static readonly int[] _outputEarlyIndicesTableMono = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableMono = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + private static readonly int[] _outputIndicesTableMono = new int[4] { 0, 0, 0, 0 }; + private static readonly int[] _targetOutputFeedbackIndicesTableMono = new int[4] { 0, 1, 2, 3 }; + + private static readonly int[] _outputEarlyIndicesTableStereo = new int[10] { 0, 0, 1, 1, 0, 1, 0, 0, 1, 1 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + private static readonly int[] _outputIndicesTableStereo = new int[4] { 0, 0, 1, 1 }; + private static readonly int[] _targetOutputFeedbackIndicesTableStereo = new int[4] { 2, 0, 3, 1 }; + + private static readonly int[] _outputEarlyIndicesTableQuadraphonic = new int[10] { 0, 0, 1, 1, 0, 1, 2, 2, 3, 3 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + private static readonly int[] _outputIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; + private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; + + private static readonly int[] _outputEarlyIndicesTableSurround = new int[20] { 0, 5, 0, 5, 1, 5, 1, 5, 4, 5, 4, 5, 2, 5, 2, 5, 3, 5, 3, 5 }; + private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = new int[20] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9 }; + private static readonly int[] _outputIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, 4, 5 }; + private static readonly int[] _targetOutputFeedbackIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, -1, 3 }; public bool Enabled { get; set; } @@ -71,60 +72,64 @@ public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverbGeneric(ref state, - outputBuffers, - inputBuffers, - sampleCount, - OutputEarlyIndicesTableMono, - TargetEarlyDelayLineIndicesTableMono, - TargetOutputFeedbackIndicesTableMono, - OutputIndicesTableMono); + ProcessReverbGeneric( + ref state, + outputBuffers, + inputBuffers, + sampleCount, + _outputEarlyIndicesTableMono, + _targetEarlyDelayLineIndicesTableMono, + _targetOutputFeedbackIndicesTableMono, + _outputIndicesTableMono); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverbStereo(ref ReverbState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverbGeneric(ref state, - outputBuffers, - inputBuffers, - sampleCount, - OutputEarlyIndicesTableStereo, - TargetEarlyDelayLineIndicesTableStereo, - TargetOutputFeedbackIndicesTableStereo, - OutputIndicesTableStereo); + ProcessReverbGeneric( + ref state, + outputBuffers, + inputBuffers, + sampleCount, + _outputEarlyIndicesTableStereo, + _targetEarlyDelayLineIndicesTableStereo, + _targetOutputFeedbackIndicesTableStereo, + _outputIndicesTableStereo); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverbQuadraphonic(ref ReverbState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverbGeneric(ref state, - outputBuffers, - inputBuffers, - sampleCount, - OutputEarlyIndicesTableQuadraphonic, - TargetEarlyDelayLineIndicesTableQuadraphonic, - TargetOutputFeedbackIndicesTableQuadraphonic, - OutputIndicesTableQuadraphonic); + ProcessReverbGeneric( + ref state, + outputBuffers, + inputBuffers, + sampleCount, + _outputEarlyIndicesTableQuadraphonic, + _targetEarlyDelayLineIndicesTableQuadraphonic, + _targetOutputFeedbackIndicesTableQuadraphonic, + _outputIndicesTableQuadraphonic); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ProcessReverbSurround(ref ReverbState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount) { - ProcessReverbGeneric(ref state, - outputBuffers, - inputBuffers, - sampleCount, - OutputEarlyIndicesTableSurround, - TargetEarlyDelayLineIndicesTableSurround, - TargetOutputFeedbackIndicesTableSurround, - OutputIndicesTableSurround); + ProcessReverbGeneric( + ref state, + outputBuffers, + inputBuffers, + sampleCount, + _outputEarlyIndicesTableSurround, + _targetEarlyDelayLineIndicesTableSurround, + _targetOutputFeedbackIndicesTableSurround, + _outputIndicesTableSurround); } private unsafe void ProcessReverbGeneric(ref ReverbState state, ReadOnlySpan outputBuffers, ReadOnlySpan inputBuffers, uint sampleCount, ReadOnlySpan outputEarlyIndicesTable, ReadOnlySpan targetEarlyDelayLineIndicesTable, ReadOnlySpan targetOutputFeedbackIndicesTable, ReadOnlySpan outputIndicesTable) @@ -143,7 +148,7 @@ private unsafe void ProcessReverbGeneric(ref ReverbState state, ReadOnlySpan outputBuffer, ref WaveBufferInformation info, Span wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount) { - const int tempBufferSize = 0x3F00; + const int TempBufferSize = 0x3F00; - Span tempBuffer = stackalloc short[tempBufferSize]; + Span tempBuffer = stackalloc short[TempBufferSize]; float sampleRateRatio = (float)info.SourceSampleRate / targetSampleRate * info.Pitch; @@ -60,11 +60,11 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< int totalNeededSize = (int)MathF.Truncate(fraction + sampleRateRatio * sampleCount); - if (totalNeededSize + pitchMaxLength <= tempBufferSize && totalNeededSize >= 0) + if (totalNeededSize + pitchMaxLength <= TempBufferSize && totalNeededSize >= 0) { int sourceSampleCountToProcess = sampleCount; - int maxSampleCountPerIteration = Math.Min((int)MathF.Truncate((tempBufferSize - fraction) / sampleRateRatio), sampleCount); + int maxSampleCountPerIteration = Math.Min((int)MathF.Truncate((TempBufferSize - fraction) / sampleRateRatio), sampleCount); bool isStarving = false; @@ -76,7 +76,7 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< if (!info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion)) { - voiceState.Pitch.AsSpan().Slice(0, pitchMaxLength).CopyTo(tempBuffer); + voiceState.Pitch.AsSpan()[..pitchMaxLength].CopyTo(tempBuffer); tempBufferIndex += pitchMaxLength; } @@ -107,7 +107,7 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< voiceState.LoopContext = memoryManager.Read(waveBuffer.Context); } - Span tempSpan = tempBuffer.Slice(tempBufferIndex + y); + Span tempSpan = tempBuffer[(tempBufferIndex + y)..]; int decodedSampleCount = -1; @@ -168,7 +168,7 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< decodedSampleCount = PcmHelper.Decode(tempSpan, waveBufferPcmFloat, targetSampleStartOffset, targetSampleEndOffset, info.ChannelIndex, info.ChannelCount); break; default: - Logger.Error?.Print(LogClass.AudioRenderer, $"Unsupported sample format " + info.SampleFormat); + Logger.Error?.Print(LogClass.AudioRenderer, "Unsupported sample format " + info.SampleFormat); break; } @@ -220,7 +220,7 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< } } - Span outputSpanInt = MemoryMarshal.Cast(outputBuffer.Slice(i)); + Span outputSpanInt = MemoryMarshal.Cast(outputBuffer[i..]); if (info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion)) { @@ -231,9 +231,9 @@ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span< } else { - Span tempSpan = tempBuffer.Slice(tempBufferIndex + y); + Span tempSpan = tempBuffer[(tempBufferIndex + y)..]; - tempSpan.Slice(0, sampleCountToDecode - y).Fill(0); + tempSpan[..(sampleCountToDecode - y)].Clear(); ToFloat(outputBuffer, outputSpanInt, sampleCountToProcess); @@ -430,9 +430,9 @@ public static void ToInt(Span output, ReadOnlySpan input, int sample } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RemapLegacyChannelEffectMappingToChannelResourceMapping(bool isSupported, Span bufferIndices) + public static void RemapLegacyChannelEffectMappingToChannelResourceMapping(bool isSupported, Span bufferIndices, uint channelCount) { - if (!isSupported && bufferIndices.Length == 6) + if (!isSupported && channelCount == 6) { ushort backLeft = bufferIndices[2]; ushort backRight = bufferIndices[3]; @@ -447,9 +447,9 @@ public static void RemapLegacyChannelEffectMappingToChannelResourceMapping(bool } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RemapChannelResourceMappingToLegacy(bool isSupported, Span bufferIndices) + public static void RemapChannelResourceMappingToLegacy(bool isSupported, Span bufferIndices, uint channelCount) { - if (isSupported && bufferIndices.Length == 6) + if (isSupported && channelCount == 6) { ushort frontCenter = bufferIndices[2]; ushort lowFrequency = bufferIndices[3]; @@ -463,4 +463,4 @@ public static void RemapChannelResourceMappingToLegacy(bool isSupported, Span inputs) foreach (float input in inputs) { - res += (input * input); + float normInput = input * (1f / 32768f); + res += normInput * normInput; } res /= inputs.Length; @@ -81,19 +82,6 @@ public static float DecibelToLinear(float db) return MathF.Pow(10.0f, db / 20.0f); } - /// - /// Map decibel to linear in [0, 2] range. - /// - /// The decibel value to convert - /// Converted linear value in [0, 2] range - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float DecibelToLinearExtended(float db) - { - float tmp = MathF.Log2(DecibelToLinear(db)); - - return MathF.Truncate(tmp) + MathF.Pow(2.0f, tmp - MathF.Truncate(tmp)); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float DegreesToRadians(float degrees) { @@ -112,4 +100,4 @@ public static float Sin(float value) return MathF.Sin(DegreesToRadians(value)); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs index 0233a8d71..8134e6b77 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs @@ -1,5 +1,4 @@ using System; -using System.Numerics; using System.Runtime.CompilerServices; namespace Ryujinx.Audio.Renderer.Dsp @@ -21,6 +20,11 @@ public static ulong GetBufferOffset(int startSampleOffset, int offset, int ch [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetBufferSize(int startSampleOffset, int endSampleOffset, int offset, int count) where T : unmanaged { + if (endSampleOffset < startSampleOffset) + { + return 0; + } + return GetCountToDecode(startSampleOffset, endSampleOffset, offset, count) * Unsafe.SizeOf(); } @@ -62,7 +66,7 @@ public static void ConvertSampleToPcm32(Span output, ReadOnlySpan in { for (int i = 0; i < input.Length; i++) { - output[i] = ((int)input[i]) << 16; + output[i] = input[i] << 16; } } @@ -127,4 +131,4 @@ public static short Saturate(float value) return (short)value; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs index 7873c4d27..e44e9f41e 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -11,8 +10,7 @@ namespace Ryujinx.Audio.Renderer.Dsp public static class ResamplerHelper { #region "Default Quality Lookup Tables" - private static short[] _normalCurveLut0 = new short[] - { + private static readonly short[] _normalCurveLut0 = { 6600, 19426, 6722, 3, 6479, 19424, 6845, 9, 6359, 19419, 6968, 15, 6239, 19412, 7093, 22, 6121, 19403, 7219, 28, 6004, 19391, 7345, 34, 5888, 19377, 7472, 41, 5773, 19361, 7600, 48, 5659, 19342, 7728, 55, 5546, 19321, 7857, 62, 5434, 19298, 7987, 69, 5323, 19273, 8118, 77, @@ -44,11 +42,10 @@ public static class ResamplerHelper 109, 8646, 19148, 4890, 101, 8513, 19183, 4997, 92, 8381, 19215, 5104, 84, 8249, 19245, 5213, 77, 8118, 19273, 5323, 69, 7987, 19298, 5434, 62, 7857, 19321, 5546, 55, 7728, 19342, 5659, 48, 7600, 19361, 5773, 41, 7472, 19377, 5888, 34, 7345, 19391, 6004, 28, 7219, 19403, 6121, - 22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600 + 22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600, }; - private static short[] _normalCurveLut1 = new short[] - { + private static readonly short[] _normalCurveLut1 = { -68, 32639, 69, -5, -200, 32630, 212, -15, -328, 32613, 359, -26, -450, 32586, 512, -36, -568, 32551, 669, -47, -680, 32507, 832, -58, -788, 32454, 1000, -69, -891, 32393, 1174, -80, -990, 32323, 1352, -92, -1084, 32244, 1536, -103, -1173, 32157, 1724, -115, -1258, 32061, 1919, -128, @@ -80,11 +77,10 @@ public static class ResamplerHelper -180, 2747, 31593, -1554, -167, 2532, 31723, -1486, -153, 2322, 31844, -1414, -140, 2118, 31956, -1338, -128, 1919, 32061, -1258, -115, 1724, 32157, -1173, -103, 1536, 32244, -1084, -92, 1352, 32323, -990, -80, 1174, 32393, -891, -69, 1000, 32454, -788, -58, 832, 32507, -680, -47, 669, 32551, -568, - -36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68 + -36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68, }; - private static short[] _normalCurveLut2 = new short[] - { + private static readonly short[] _normalCurveLut2 = { 3195, 26287, 3329, -32, 3064, 26281, 3467, -34, 2936, 26270, 3608, -38, 2811, 26253, 3751, -42, 2688, 26230, 3897, -46, 2568, 26202, 4046, -50, 2451, 26169, 4199, -54, 2338, 26130, 4354, -58, 2227, 26085, 4512, -63, 2120, 26035, 4673, -67, 2015, 25980, 4837, -72, 1912, 25919, 5004, -76, @@ -116,13 +112,12 @@ public static class ResamplerHelper -98, 5701, 25621, 1531, -92, 5522, 25704, 1622, -87, 5347, 25780, 1716, -81, 5174, 25852, 1813, -76, 5004, 25919, 1912, -72, 4837, 25980, 2015, -67, 4673, 26035, 2120, -63, 4512, 26085, 2227, -58, 4354, 26130, 2338, -54, 4199, 26169, 2451, -50, 4046, 26202, 2568, -46, 3897, 26230, 2688, - -42, 3751, 26253, 2811, -38, 3608, 26270, 2936, -34, 3467, 26281, 3064, -32, 3329, 26287, 3195 + -42, 3751, 26253, 2811, -38, 3608, 26270, 2936, -34, 3467, 26281, 3064, -32, 3329, 26287, 3195, }; #endregion #region "High Quality Lookup Tables" - private static short[] _highCurveLut0 = new short[] - { + private static readonly short[] _highCurveLut0 = { -582, -23, 8740, 16386, 8833, 8, -590, 0, -573, -54, 8647, 16385, 8925, 40, -598, -1, -565, -84, 8555, 16383, 9018, 72, -606, -1, -557, -113, 8462, 16379, 9110, 105, -614, -2, -549, -142, 8370, 16375, 9203, 139, -622, -2, -541, -170, 8277, 16369, 9295, 173, -630, -3, @@ -189,8 +184,7 @@ public static class ResamplerHelper -1, -598, 40, 8925, 16385, 8647, -54, -573, 0, -590, 8, 8833, 16386, 8740, -23, -582, }; - private static short[] _highCurveLut1 = new short[] - { + private static readonly short[] _highCurveLut1 = { -12, 47, -134, 32767, 81, -16, 2, 0, -26, 108, -345, 32760, 301, -79, 17, -1, -40, 168, -552, 32745, 526, -144, 32, -2, -53, 226, -753, 32723, 755, -210, 47, -3, -66, 284, -950, 32694, 989, -277, 63, -5, -78, 340, -1143, 32658, 1226, -346, 79, -6, @@ -257,8 +251,7 @@ public static class ResamplerHelper -1, 17, -79, 301, 32760, -345, 108, -26, 0, 2, -16, 81, 32767, -134, 47, -12, }; - private static short[] _highCurveLut2 = new short[] - { + private static readonly short[] _highCurveLut2 = { 418, -2538, 6118, 24615, 6298, -2563, 417, 0, 420, -2512, 5939, 24611, 6479, -2588, 415, 1, 421, -2485, 5761, 24605, 6662, -2612, 412, 2, 422, -2458, 5585, 24595, 6846, -2635, 409, 3, 423, -2430, 5410, 24582, 7030, -2658, 406, 4, 423, -2402, 5236, 24565, 7216, -2680, 403, 5, @@ -326,13 +319,13 @@ public static class ResamplerHelper }; #endregion - private static float[] _normalCurveLut0F; - private static float[] _normalCurveLut1F; - private static float[] _normalCurveLut2F; + private static readonly float[] _normalCurveLut0F; + private static readonly float[] _normalCurveLut1F; + private static readonly float[] _normalCurveLut2F; - private static float[] _highCurveLut0F; - private static float[] _highCurveLut1F; - private static float[] _highCurveLut2F; + private static readonly float[] _highCurveLut0F; + private static readonly float[] _highCurveLut1F; + private static readonly float[] _highCurveLut2F; static ResamplerHelper() { @@ -373,7 +366,8 @@ private static ReadOnlySpan GetDefaultParameter(float ratio) { return _normalCurveLut1F; } - else if (ratio > 1.333313f) + + if (ratio > 1.333313f) { return _normalCurveLut0F; } @@ -514,7 +508,8 @@ private static ReadOnlySpan GetHighParameter(float ratio) { return _highCurveLut1F; } - else if (ratio > 1.333313f) + + if (ratio > 1.333313f) { return _highCurveLut0F; } @@ -601,4 +596,4 @@ public static void ResampleLowQuality(Span outputBuffer, ReadOnlySpan GetFdnDelayTimesByLateMode(ReverbLateMode lateMode) + private static ReadOnlySpan GetFdnDelayTimesByLateMode(ReverbLateMode lateMode) { - return FdnDelayTimes.AsSpan((int)lateMode * 4, 4); + return _fdnDelayTimes.AsSpan((int)lateMode * 4, 4); } - private ReadOnlySpan GetDecayDelayTimesByLateMode(ReverbLateMode lateMode) + private static ReadOnlySpan GetDecayDelayTimesByLateMode(ReverbLateMode lateMode) { - return DecayDelayTimes.AsSpan((int)lateMode * 4, 4); + return _decayDelayTimes.AsSpan((int)lateMode * 4, 4); } public ReverbState(ref ReverbParameter parameter, ulong workBuffer, bool isLongSizePreDelaySupported) @@ -148,8 +148,8 @@ public void UpdateParameter(ref ReverbParameter parameter) for (int i = 0; i < 10; i++) { - EarlyDelayTime[i] = Math.Min(IDelayLine.GetSampleCount(sampleRate, EarlyDelayTimes[i] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax) + 1; - EarlyGain[i] = EarlyGainBase[i] * earlyGain; + EarlyDelayTime[i] = Math.Min(IDelayLine.GetSampleCount(sampleRate, _earlyDelayTimes[i] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax) + 1; + EarlyGain[i] = _earlyGainBase[i] * earlyGain; } if (parameter.ChannelCount == 2) @@ -158,7 +158,7 @@ public void UpdateParameter(ref ReverbParameter parameter) EarlyGain[5] = EarlyGain[5] * 0.5f; } - PreDelayLineDelayTime = Math.Min(IDelayLine.GetSampleCount(sampleRate, PreDelayTimes[(int)parameter.EarlyMode] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax); + PreDelayLineDelayTime = Math.Min(IDelayLine.GetSampleCount(sampleRate, _preDelayTimes[(int)parameter.EarlyMode] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax); ReadOnlySpan fdnDelayTimes = GetFdnDelayTimesByLateMode(parameter.LateMode); ReadOnlySpan decayDelayTimes = GetDecayDelayTimesByLateMode(parameter.LateMode); @@ -201,4 +201,4 @@ public void UpdateParameter(ref ReverbParameter parameter) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs index 6cdab5a7b..5732cdb21 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs @@ -13,11 +13,11 @@ public class UpsamplerHelper private const int FilterBankLength = 20; // Bank0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; private const int Bank0CenterIndex = 9; - private static readonly Array20 Bank1 = PrecomputeFilterBank(1.0f / 6.0f); - private static readonly Array20 Bank2 = PrecomputeFilterBank(2.0f / 6.0f); - private static readonly Array20 Bank3 = PrecomputeFilterBank(3.0f / 6.0f); - private static readonly Array20 Bank4 = PrecomputeFilterBank(4.0f / 6.0f); - private static readonly Array20 Bank5 = PrecomputeFilterBank(5.0f / 6.0f); + private static readonly Array20 _bank1 = PrecomputeFilterBank(1.0f / 6.0f); + private static readonly Array20 _bank2 = PrecomputeFilterBank(2.0f / 6.0f); + private static readonly Array20 _bank3 = PrecomputeFilterBank(3.0f / 6.0f); + private static readonly Array20 _bank4 = PrecomputeFilterBank(4.0f / 6.0f); + private static readonly Array20 _bank5 = PrecomputeFilterBank(5.0f / 6.0f); private static Array20 PrecomputeFilterBank(float offset) { @@ -32,14 +32,14 @@ float Sinc(float x) float BlackmanWindow(float x) { - const float a = 0.18f; - const float a0 = 0.5f - 0.5f * a; - const float a1 = -0.5f; - const float a2 = 0.5f * a; - return a0 + a1 * MathF.Cos(2 * MathF.PI * x) + a2 * MathF.Cos(4 * MathF.PI * x); + const float A = 0.18f; + const float A0 = 0.5f - 0.5f * A; + const float A1 = -0.5f; + const float A2 = 0.5f * A; + return A0 + A1 * MathF.Cos(2 * MathF.PI * x) + A2 * MathF.Cos(4 * MathF.PI * x); } - - Array20 result = new Array20(); + + Array20 result = new(); for (int i = 0; i < FilterBankLength; i++) { @@ -58,10 +58,10 @@ public static void Upsample(Span outputBuffer, ReadOnlySpan inputB { state.Scale = inputSampleCount switch { - 40 => 6.0f, - 80 => 3.0f, + 40 => 6.0f, + 80 => 3.0f, 160 => 1.5f, - _ => throw new ArgumentOutOfRangeException() + _ => throw new ArgumentOutOfRangeException(nameof(inputSampleCount), inputSampleCount, null), }; state.Initialized = true; } @@ -105,14 +105,14 @@ float DoFilterBank(ref UpsamplerBufferState state, in Array20 bank) [MethodImpl(MethodImplOptions.AggressiveInlining)] void NextInput(ref UpsamplerBufferState state, float input) { - state.History.AsSpan().Slice(1).CopyTo(state.History.AsSpan()); + state.History.AsSpan()[1..].CopyTo(state.History.AsSpan()); state.History[HistoryLength - 1] = input; } int inputBufferIndex = 0; switch (state.Scale) - { + { case 6.0f: for (int i = 0; i < outputSampleCount; i++) { @@ -123,19 +123,19 @@ void NextInput(ref UpsamplerBufferState state, float input) outputBuffer[i] = state.History[Bank0CenterIndex]; break; case 1: - outputBuffer[i] = DoFilterBank(ref state, Bank1); + outputBuffer[i] = DoFilterBank(ref state, _bank1); break; case 2: - outputBuffer[i] = DoFilterBank(ref state, Bank2); + outputBuffer[i] = DoFilterBank(ref state, _bank2); break; case 3: - outputBuffer[i] = DoFilterBank(ref state, Bank3); + outputBuffer[i] = DoFilterBank(ref state, _bank3); break; case 4: - outputBuffer[i] = DoFilterBank(ref state, Bank4); + outputBuffer[i] = DoFilterBank(ref state, _bank4); break; case 5: - outputBuffer[i] = DoFilterBank(ref state, Bank5); + outputBuffer[i] = DoFilterBank(ref state, _bank5); break; } @@ -152,10 +152,10 @@ void NextInput(ref UpsamplerBufferState state, float input) outputBuffer[i] = state.History[Bank0CenterIndex]; break; case 1: - outputBuffer[i] = DoFilterBank(ref state, Bank2); + outputBuffer[i] = DoFilterBank(ref state, _bank2); break; case 2: - outputBuffer[i] = DoFilterBank(ref state, Bank4); + outputBuffer[i] = DoFilterBank(ref state, _bank4); break; } @@ -173,11 +173,11 @@ void NextInput(ref UpsamplerBufferState state, float input) outputBuffer[i] = state.History[Bank0CenterIndex]; break; case 1: - outputBuffer[i] = DoFilterBank(ref state, Bank4); + outputBuffer[i] = DoFilterBank(ref state, _bank4); break; case 2: NextInput(ref state, inputBuffer[inputBufferIndex++]); - outputBuffer[i] = DoFilterBank(ref state, Bank2); + outputBuffer[i] = DoFilterBank(ref state, _bank2); break; } @@ -185,8 +185,8 @@ void NextInput(ref UpsamplerBufferState state, float input) } break; default: - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(state), state.Scale, null); } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs index 359cd4c02..491a05c86 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs @@ -60,7 +60,7 @@ public struct AudioRendererConfiguration /// /// Reserved/unused /// - private byte _reserved; + private readonly byte _reserved; /// /// The target rendering device. @@ -96,4 +96,4 @@ public struct AudioRendererConfiguration /// public int Revision; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BehaviourErrorInfoOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/BehaviourErrorInfoOutStatus.cs index aba7dcd61..5a0565dc6 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/BehaviourErrorInfoOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/BehaviourErrorInfoOutStatus.cs @@ -27,4 +27,4 @@ public struct BehaviourErrorInfoOutStatus /// private unsafe fixed uint _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs index ef86015fe..f1492b0b1 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs @@ -18,7 +18,7 @@ public struct BiquadFilterParameter /// /// Reserved/padding. /// - private byte _reserved; + private readonly byte _reserved; /// /// Biquad filter numerator (b0, b1, b2). @@ -31,4 +31,4 @@ public struct BiquadFilterParameter /// a0 = 1 public Array2 Denominator; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs index 36f286775..65f265a32 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs @@ -81,4 +81,4 @@ public struct AuxiliaryBufferParameter /// This is unused. public uint MixBufferSampleCount; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs index 73e0e9bbc..b12a941a5 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs @@ -41,4 +41,4 @@ public struct BiquadFilterEffectParameter /// public UsageState Status; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs index b03559eba..49b70e501 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs @@ -29,4 +29,4 @@ public struct BufferMixParameter /// public uint MixesCount; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs index 0be376088..b403f1370 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using Ryujinx.Common.Memory; using System.Runtime.InteropServices; @@ -98,7 +98,7 @@ public struct CompressorParameter /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountValid() + public readonly bool IsChannelCountValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCount); } @@ -107,7 +107,7 @@ public bool IsChannelCountValid() /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountMaxValid() + public readonly bool IsChannelCountMaxValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCountMax); } diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs index 72332c170..99c97d9d9 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs @@ -84,7 +84,7 @@ public struct DelayParameter /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountValid() + public readonly bool IsChannelCountValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCount); } @@ -93,9 +93,9 @@ public bool IsChannelCountValid() /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountMaxValid() + public readonly bool IsChannelCountMaxValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCountMax); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterParameter.cs index 0bce94a27..23ccb8c88 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterParameter.cs @@ -115,13 +115,13 @@ public struct LimiterParameter /// /// Reserved/padding. /// - private byte _reserved; + private readonly byte _reserved; /// /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountValid() + public readonly bool IsChannelCountValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCount); } @@ -130,9 +130,9 @@ public bool IsChannelCountValid() /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountMaxValid() + public readonly bool IsChannelCountMaxValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCountMax); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterStatistics.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterStatistics.cs index f353f18d1..97e2f39fc 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterStatistics.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/LimiterStatistics.cs @@ -24,8 +24,8 @@ public struct LimiterStatistics /// public void Reset() { - InputMax.AsSpan().Fill(0.0f); + InputMax.AsSpan().Clear(); CompressionGainMin.AsSpan().Fill(1.0f); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs index c78ce5951..d2cd78707 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs @@ -33,7 +33,7 @@ public struct Reverb3dParameter /// /// Reserved/unused. /// - private uint _reserved; + private readonly uint _reserved; /// /// The target sample rate. @@ -110,7 +110,7 @@ public struct Reverb3dParameter /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountValid() + public readonly bool IsChannelCountValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCount); } @@ -119,9 +119,9 @@ public bool IsChannelCountValid() /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountMaxValid() + public readonly bool IsChannelCountMaxValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCountMax); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs index baf049fbd..51ab156d2 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs @@ -102,7 +102,7 @@ public struct ReverbParameter /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountValid() + public readonly bool IsChannelCountValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCount); } @@ -111,9 +111,9 @@ public bool IsChannelCountValid() /// Check if the is valid. /// /// Returns true if the is valid. - public bool IsChannelCountMaxValid() + public readonly bool IsChannelCountMaxValid() { return EffectInParameterVersion1.IsChannelCountValid(ChannelCountMax); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion1.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion1.cs index e5419f70a..46686e3b4 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion1.cs @@ -31,7 +31,7 @@ public struct EffectInParameterVersion1 : IEffectInParameter /// /// Reserved/padding. /// - private byte _reserved1; + private readonly byte _reserved1; /// /// The target mix id of the effect. @@ -58,7 +58,7 @@ public struct EffectInParameterVersion1 : IEffectInParameter /// /// Reserved/padding. /// - private uint _reserved2; + private readonly uint _reserved2; /// /// Specific data storage. @@ -70,19 +70,19 @@ private struct SpecificDataStruct { } public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart); - EffectType IEffectInParameter.Type => Type; + readonly EffectType IEffectInParameter.Type => Type; - bool IEffectInParameter.IsNew => IsNew; + readonly bool IEffectInParameter.IsNew => IsNew; - bool IEffectInParameter.IsEnabled => IsEnabled; + readonly bool IEffectInParameter.IsEnabled => IsEnabled; - int IEffectInParameter.MixId => MixId; + readonly int IEffectInParameter.MixId => MixId; - ulong IEffectInParameter.BufferBase => BufferBase; + readonly ulong IEffectInParameter.BufferBase => BufferBase; - ulong IEffectInParameter.BufferSize => BufferSize; + readonly ulong IEffectInParameter.BufferSize => BufferSize; - uint IEffectInParameter.ProcessingOrder => ProcessingOrder; + readonly uint IEffectInParameter.ProcessingOrder => ProcessingOrder; /// /// Check if the given channel count is valid. @@ -94,4 +94,4 @@ public static bool IsChannelCountValid(int channelCount) return channelCount == 1 || channelCount == 2 || channelCount == 4 || channelCount == 6; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion2.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion2.cs index 250012d16..3854c7148 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion2.cs @@ -31,7 +31,7 @@ public struct EffectInParameterVersion2 : IEffectInParameter /// /// Reserved/padding. /// - private byte _reserved1; + private readonly byte _reserved1; /// /// The target mix id of the effect. @@ -58,7 +58,7 @@ public struct EffectInParameterVersion2 : IEffectInParameter /// /// Reserved/padding. /// - private uint _reserved2; + private readonly uint _reserved2; /// /// Specific data storage. @@ -70,19 +70,19 @@ private struct SpecificDataStruct { } public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart); - EffectType IEffectInParameter.Type => Type; + readonly EffectType IEffectInParameter.Type => Type; - bool IEffectInParameter.IsNew => IsNew; + readonly bool IEffectInParameter.IsNew => IsNew; - bool IEffectInParameter.IsEnabled => IsEnabled; + readonly bool IEffectInParameter.IsEnabled => IsEnabled; - int IEffectInParameter.MixId => MixId; + readonly int IEffectInParameter.MixId => MixId; - ulong IEffectInParameter.BufferBase => BufferBase; + readonly ulong IEffectInParameter.BufferBase => BufferBase; - ulong IEffectInParameter.BufferSize => BufferSize; + readonly ulong IEffectInParameter.BufferSize => BufferSize; - uint IEffectInParameter.ProcessingOrder => ProcessingOrder; + readonly uint IEffectInParameter.ProcessingOrder => ProcessingOrder; /// /// Check if the given channel count is valid. @@ -94,4 +94,4 @@ public static bool IsChannelCountValid(int channelCount) return channelCount == 1 || channelCount == 2 || channelCount == 4 || channelCount == 6; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion1.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion1.cs index 5e6a33ace..3c3e95538 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion1.cs @@ -18,6 +18,6 @@ public struct EffectOutStatusVersion1 : IEffectOutStatus /// private unsafe fixed byte _reserved[15]; - EffectState IEffectOutStatus.State { get => State; set => State = value; } + EffectState IEffectOutStatus.State { readonly get => State; set => State = value; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion2.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion2.cs index f2c9768b3..ee058d3ae 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectOutStatusVersion2.cs @@ -23,6 +23,6 @@ public struct EffectOutStatusVersion2 : IEffectOutStatus /// public EffectResultState ResultState; - EffectState IEffectOutStatus.State { get => State; set => State = value; } + EffectState IEffectOutStatus.State { readonly get => State; set => State = value; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectResultState.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectResultState.cs index bd96c22bf..b3a4bae12 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectResultState.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectResultState.cs @@ -23,4 +23,4 @@ private struct SpecificDataStruct { } /// public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectState.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectState.cs index 911ba6d84..c4d06f122 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectState.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectState.cs @@ -13,6 +13,6 @@ public enum EffectState : byte /// /// The effect is disabled. /// - Disabled = 4 + Disabled = 4, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/IEffectInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/IEffectInParameter.cs index bdd1ca45e..703c3e6db 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/IEffectInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/IEffectInParameter.cs @@ -50,4 +50,4 @@ public interface IEffectInParameter /// Span SpecificData { get; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/IEffectOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/IEffectOutStatus.cs index a5addbcb7..74d132209 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/IEffectOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/IEffectOutStatus.cs @@ -10,4 +10,4 @@ public interface IEffectOutStatus /// EffectState State { get; set; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs index 242e3843c..602508589 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs @@ -30,4 +30,4 @@ public struct MemoryPoolInParameter /// private unsafe fixed uint _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs index 29a6e261f..a78937d01 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs @@ -19,4 +19,4 @@ public struct MemoryPoolOutStatus /// private unsafe fixed uint _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdate.cs b/src/Ryujinx.Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdate.cs index c0954cda0..733b5ad76 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdate.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdate.cs @@ -24,4 +24,4 @@ public struct MixInParameterDirtyOnlyUpdate /// private unsafe fixed byte _reserved[24]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/MixParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/MixParameter.cs index 5b9a969a0..2eec04a21 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/MixParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/MixParameter.cs @@ -41,7 +41,7 @@ public struct MixParameter /// /// Reserved/padding. /// - private ushort _reserved1; + private readonly ushort _reserved1; /// /// The id of the mix. @@ -61,7 +61,7 @@ public struct MixParameter /// /// Reserved/padding. /// - private ulong _reserved2; + private readonly ulong _reserved2; /// /// Mix buffer volumes storage. @@ -81,7 +81,7 @@ public struct MixParameter /// /// Reserved/padding. /// - private uint _reserved3; + private readonly uint _reserved3; [StructLayout(LayoutKind.Sequential, Size = 4 * Constants.MixBufferCountMax * Constants.MixBufferCountMax, Pack = 1)] private struct MixVolumeArray { } @@ -92,4 +92,4 @@ private struct MixVolumeArray { } /// Used when no splitter id is specified. public Span MixBufferVolume => SpanHelpers.AsSpan(ref _mixBufferVolumeArray); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceInParameter.cs index 0f9a3aa3e..806f7fa89 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceInParameter.cs @@ -18,4 +18,4 @@ public struct PerformanceInParameter /// private unsafe fixed uint _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceOutStatus.cs index 64bbe080a..839d6eb6b 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Performance/PerformanceOutStatus.cs @@ -18,4 +18,4 @@ public struct PerformanceOutStatus /// private unsafe fixed uint _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs index a42ea833f..c97ce2965 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs @@ -16,6 +16,6 @@ public struct RendererInfoOutStatus /// /// Reserved/Unused. /// - private ulong _reserved; + private readonly ulong _reserved; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Sink/CircularBufferParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Sink/CircularBufferParameter.cs index 7c02d65ff..0d4b276ef 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Sink/CircularBufferParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Sink/CircularBufferParameter.cs @@ -2,7 +2,6 @@ using Ryujinx.Audio.Renderer.Common; using Ryujinx.Common.Memory; using System.Runtime.InteropServices; - using CpuAddress = System.UInt64; namespace Ryujinx.Audio.Renderer.Parameter.Sink @@ -41,7 +40,7 @@ public struct CircularBufferParameter /// /// The target . /// - /// Only is supported. + /// Only is supported. public SampleFormat SampleFormat; /// @@ -57,6 +56,6 @@ public struct CircularBufferParameter /// /// Reserved/padding. /// - private ushort _reserved2; + private readonly ushort _reserved2; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs index abeadaccf..652d02a63 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs @@ -19,7 +19,7 @@ public struct DeviceParameter /// /// Reserved/padding. /// - private byte _padding; + private readonly byte _padding; /// /// The total count of channels to output to the device. @@ -34,7 +34,7 @@ public struct DeviceParameter /// /// Reserved/padding. /// - private byte _reserved; + private readonly byte _reserved; /// /// Set to true if the user controls Surround to Stereo downmixing coefficients. @@ -55,4 +55,4 @@ private struct DeviceNameStruct { } /// public Span DeviceName => SpanHelpers.AsSpan(ref _deviceName); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs index 1ee4eb532..3c1ac09c0 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs @@ -25,7 +25,7 @@ public struct SinkInParameter /// /// Reserved/padding. /// - private ushort _reserved1; + private readonly ushort _reserved1; /// /// The node id of the sink. @@ -50,4 +50,4 @@ private struct SpecificDataStruct { } /// public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs index 426b861ca..dd0f867b5 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs @@ -16,11 +16,11 @@ public struct SinkOutStatus /// /// Reserved/padding. /// - private uint _padding; + private readonly uint _padding; /// /// Reserved/padding. /// private unsafe fixed ulong _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameter.cs index 96c43092b..b74b67be0 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameter.cs @@ -59,9 +59,9 @@ private struct MixArray { } /// Check if the magic is valid. /// /// Returns true if the magic is valid. - public bool IsMagicValid() + public readonly bool IsMagicValid() { return Magic == ValidMagic; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs index 0220497de..2567b15a8 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs @@ -38,9 +38,9 @@ public struct SplitterInParameter /// Check if the magic is valid. /// /// Returns true if the magic is valid. - public bool IsMagicValid() + public readonly bool IsMagicValid() { return Magic == ValidMagic; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameterHeader.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameterHeader.cs index dbae17a9a..10fa866e7 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameterHeader.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterInParameterHeader.cs @@ -37,9 +37,9 @@ public struct SplitterInParameterHeader /// Check if the magic is valid. /// /// Returns true if the magic is valid. - public bool IsMagicValid() + public readonly bool IsMagicValid() { return Magic == ValidMagic; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceChannelResourceInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceChannelResourceInParameter.cs index 6a863237d..6cff1a251 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceChannelResourceInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceChannelResourceInParameter.cs @@ -25,4 +25,4 @@ public struct VoiceChannelResourceInParameter [MarshalAs(UnmanagedType.I1)] public bool IsUsed; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs index c4b4ba312..f33d82aa0 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs @@ -94,7 +94,7 @@ public struct VoiceInParameter /// /// Reserved/unused. /// - private uint _reserved1; + private readonly uint _reserved1; /// /// User state address required by the data source. @@ -143,7 +143,7 @@ public struct VoiceInParameter /// /// Reserved/unused. /// - private ushort _reserved2; + private readonly ushort _reserved2; /// /// Change the behaviour of the voice. @@ -222,7 +222,7 @@ public struct WaveBufferInternal /// /// Reserved/unused. /// - private byte _reserved; + private readonly byte _reserved; /// /// If set to anything other than 0, specifies how many times to loop the wavebuffer. @@ -260,12 +260,12 @@ public struct WaveBufferInternal /// The PCM sample type /// Returns true if the sample offset are in range of the size. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsSampleOffsetInRangeForPcm() where T : unmanaged + private readonly bool IsSampleOffsetInRangeForPcm() where T : unmanaged { uint dataTypeSize = (uint)Unsafe.SizeOf(); - return StartSampleOffset * dataTypeSize <= Size && - EndSampleOffset * dataTypeSize <= Size; + return (ulong)StartSampleOffset * dataTypeSize <= Size && + (ulong)EndSampleOffset * dataTypeSize <= Size; } /// @@ -273,27 +273,15 @@ private bool IsSampleOffsetInRangeForPcm() where T : unmanaged /// /// The target /// Returns true if the sample offset are in range of the size. - public bool IsSampleOffsetValid(SampleFormat format) + public readonly bool IsSampleOffsetValid(SampleFormat format) { - bool result; - - switch (format) + return format switch { - case SampleFormat.PcmInt16: - result = IsSampleOffsetInRangeForPcm(); - break; - case SampleFormat.PcmFloat: - result = IsSampleOffsetInRangeForPcm(); - break; - case SampleFormat.Adpcm: - result = AdpcmHelper.GetAdpcmDataSize((int)StartSampleOffset) <= Size && - AdpcmHelper.GetAdpcmDataSize((int)EndSampleOffset) <= Size; - break; - default: - throw new NotImplementedException($"{format} not implemented!"); - } - - return result; + SampleFormat.PcmInt16 => IsSampleOffsetInRangeForPcm(), + SampleFormat.PcmFloat => IsSampleOffsetInRangeForPcm(), + SampleFormat.Adpcm => AdpcmHelper.GetAdpcmDataSize((int)StartSampleOffset) <= Size && AdpcmHelper.GetAdpcmDataSize((int)EndSampleOffset) <= Size, + _ => throw new NotImplementedException($"{format} not implemented!"), + }; } } @@ -316,7 +304,7 @@ public enum DecodingBehaviour : ushort /// /// Skip pitch and Sample Rate Conversion (SRC). /// - SkipPitchAndSampleRateConversion = 2 + SkipPitchAndSampleRateConversion = 2, } /// @@ -338,7 +326,7 @@ public enum SampleRateConversionQuality : byte /// /// Resample interpolating 1 samples per output sample. /// - Low + Low, } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs index be9d35849..a7c749835 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs @@ -32,4 +32,4 @@ public struct VoiceOutStatus /// private unsafe fixed byte _reserved[3]; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs index 53570243d..7bb8ae5ba 100644 --- a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs +++ b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs @@ -19,31 +19,31 @@ using System.Buffers; using System.Diagnostics; using System.Threading; - using CpuAddress = System.UInt64; namespace Ryujinx.Audio.Renderer.Server { public class AudioRenderSystem : IDisposable { - private object _lock = new object(); + private readonly object _lock = new(); private AudioRendererRenderingDevice _renderingDevice; private AudioRendererExecutionMode _executionMode; - private IWritableEvent _systemEvent; - private ManualResetEvent _terminationEvent; + private readonly IWritableEvent _systemEvent; private MemoryPoolState _dspMemoryPoolState; - private VoiceContext _voiceContext; - private MixContext _mixContext; - private SinkContext _sinkContext; - private SplitterContext _splitterContext; - private EffectContext _effectContext; + private readonly VoiceContext _voiceContext; + private readonly MixContext _mixContext; + private readonly SinkContext _sinkContext; + private readonly SplitterContext _splitterContext; + private readonly EffectContext _effectContext; private PerformanceManager _performanceManager; private UpsamplerManager _upsamplerManager; private bool _isActive; private BehaviourContext _behaviourContext; +#pragma warning disable IDE0052 // Remove unread private member private ulong _totalElapsedTicksUpdating; private ulong _totalElapsedTicks; +#pragma warning restore IDE0052 private int _sessionId; private Memory _memoryPools; @@ -76,14 +76,13 @@ public class AudioRenderSystem : IDisposable private ulong _elapsedFrameCount; private ulong _renderingStartTick; - private AudioRendererManager _manager; + private readonly AudioRendererManager _manager; private int _disposeState; public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent) { _manager = manager; - _terminationEvent = new ManualResetEvent(false); _dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp); _voiceContext = new VoiceContext(); _mixContext = new MixContext(); @@ -145,12 +144,12 @@ public ResultCode Initialize( WorkBufferAllocator workBufferAllocator; - workBufferMemory.Span.Fill(0); + workBufferMemory.Span.Clear(); _workBufferMemoryPin = workBufferMemory.Pin(); workBufferAllocator = new WorkBufferAllocator(workBufferMemory); - PoolMapper poolMapper = new PoolMapper(processHandle, false); + PoolMapper poolMapper = new(processHandle, false); poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize); _mixBuffer = workBufferAllocator.Allocate(_sampleCount * (_voiceChannelCountMax + _mixBufferCount), 0x10); @@ -246,9 +245,9 @@ public ResultCode Initialize( foreach (ref MixState mix in mixes.Span) { - mix = new MixState(effectProcessingOrderArray.Slice(0, (int)parameter.EffectCount), ref _behaviourContext); + mix = new MixState(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourContext); - effectProcessingOrderArray = effectProcessingOrderArray.Slice((int)parameter.EffectCount); + effectProcessingOrderArray = effectProcessingOrderArray[(int)parameter.EffectCount..]; } } @@ -343,26 +342,15 @@ public ResultCode Initialize( _elapsedFrameCount = 0; _voiceDropParameter = 1.0f; - switch (_behaviourContext.GetCommandProcessingTimeEstimatorVersion()) + _commandProcessingTimeEstimator = _behaviourContext.GetCommandProcessingTimeEstimatorVersion() switch { - case 1: - _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount); - break; - case 2: - _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount); - break; - case 3: - _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount); - break; - case 4: - _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount); - break; - case 5: - _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount); - break; - default: - throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}."); - } + 1 => new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount), + 2 => new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount), + 3 => new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount), + 4 => new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount), + 5 => new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount), + _ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}."), + }; return ResultCode.Success; } @@ -387,11 +375,6 @@ public void Stop() _isActive = false; } - if (_executionMode == AudioRendererExecutionMode.Auto) - { - _terminationEvent.WaitOne(); - } - Logger.Info?.Print(LogClass.AudioRenderer, $"Stopped renderer id {_sessionId}"); } @@ -409,9 +392,9 @@ public ResultCode Update(Memory output, Memory performanceOutput, Re { ulong updateStartTicks = GetSystemTicks(); - output.Span.Fill(0); + output.Span.Clear(); - StateUpdater stateUpdater = new StateUpdater(input, output, _processHandle, _behaviourContext); + StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourContext); ResultCode result; @@ -616,9 +599,9 @@ private void GenerateCommandList(out CommandList commandList) _renderingStartTick = 0; } - CommandBuffer commandBuffer = new CommandBuffer(commandList, _commandProcessingTimeEstimator); + CommandBuffer commandBuffer = new(commandList, _commandProcessingTimeEstimator); - CommandGenerator commandGenerator = new CommandGenerator(commandBuffer, GetContext(), _voiceContext, _mixContext, _effectContext, _sinkContext, _splitterContext, _performanceManager); + CommandGenerator commandGenerator = new(commandBuffer, GetContext(), _voiceContext, _mixContext, _effectContext, _sinkContext, _splitterContext, _performanceManager); _voiceContext.Sort(); commandGenerator.GenerateVoices(); @@ -668,8 +651,6 @@ public void SendCommands() { if (_isActive) { - _terminationEvent.Reset(); - if (!_manager.Processor.HasRemainingCommands(_sessionId)) { GenerateCommandList(out CommandList commands); @@ -686,10 +667,6 @@ public void SendCommands() _isDspRunningBehind = true; } } - else - { - _terminationEvent.Set(); - } } } @@ -744,7 +721,7 @@ private RendererSystemContext GetContext() DepopBuffer = _depopBuffer, MixBufferCount = GetMixBufferCount(), SessionId = _sessionId, - UpsamplerManager = _upsamplerManager + UpsamplerManager = _upsamplerManager, }; } @@ -755,7 +732,7 @@ public int GetSessionId() public static ulong GetWorkBufferSize(ref AudioRendererConfiguration parameter) { - BehaviourContext behaviourContext = new BehaviourContext(); + BehaviourContext behaviourContext = new(); behaviourContext.SetUserRevision(parameter.Revision); @@ -826,6 +803,8 @@ public ResultCode QuerySystemEvent(out IWritableEvent systemEvent) public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -841,7 +820,7 @@ protected virtual void Dispose(bool disposing) Stop(); } - PoolMapper mapper = new PoolMapper(_processHandle, false); + PoolMapper mapper = new(_processHandle, false); mapper.Unmap(ref _dspMemoryPoolState); PoolMapper.ClearUsageState(_memoryPools); @@ -857,7 +836,6 @@ protected virtual void Dispose(bool disposing) } _manager.Unregister(this); - _terminationEvent.Dispose(); _workBufferMemoryPin.Dispose(); if (MemoryManager is IRefCounted rc) @@ -890,4 +868,4 @@ public ResultCode ExecuteAudioRendererRendering() return ResultCode.UnsupportedOperation; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs index 4de0ad166..0dbbd26c8 100644 --- a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs +++ b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs @@ -19,17 +19,17 @@ public class AudioRendererManager : IDisposable /// /// Lock used for session allocation. /// - private object _sessionLock = new object(); + private readonly object _sessionLock = new(); /// /// Lock used to control the running state. /// - private object _audioProcessorLock = new object(); + private readonly object _audioProcessorLock = new(); /// /// The session ids allocation table. /// - private int[] _sessionIds; + private readonly int[] _sessionIds; /// /// The events linked to each session. @@ -39,7 +39,7 @@ public class AudioRendererManager : IDisposable /// /// The sessions instances. /// - private AudioRenderSystem[] _sessions; + private readonly AudioRenderSystem[] _sessions; /// /// The count of active sessions. @@ -186,7 +186,7 @@ private void StartLocked(float volume) _workerThread = new Thread(SendCommands) { - Name = "AudioRendererManager.Worker" + Name = "AudioRendererManager.Worker", }; _workerThread.Start(); @@ -317,7 +317,7 @@ public ResultCode OpenAudioRenderer( { int sessionId = AcquireSessionId(); - AudioRenderSystem audioRenderer = new AudioRenderSystem(this, _sessionsSystemEvent[sessionId]); + AudioRenderSystem audioRenderer = new(this, _sessionsSystemEvent[sessionId]); // TODO: Eventually, we should try to use the guest supplied work buffer instead of allocating // our own. However, it was causing problems on some applications that would unmap the memory @@ -367,6 +367,8 @@ public void SetVolume(float volume) public void Dispose() { + GC.SuppressFinalize(this); + if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0) { Dispose(true); @@ -402,4 +404,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs index 821947a98..3297b5d9f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs @@ -125,7 +125,7 @@ public class BehaviourContext /// /// Error storage. /// - private ErrorInfo[] _errorInfos; + private readonly ErrorInfo[] _errorInfos; /// /// Current position in the array. @@ -254,7 +254,8 @@ public float GetAudioRendererProcessingTimeLimit() { return 0.80f; } - else if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision4)) + + if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision4)) { return 0.75f; } @@ -299,10 +300,8 @@ public uint GetPerformanceMetricsDataFormat() { return 2; } - else - { - return 1; - } + + return 1; } /// @@ -436,7 +435,7 @@ public void CopyErrorInfo(Span errorInfos, out uint errorCount) errorInfos[i] = new ErrorInfo { ErrorCode = 0, - ExtraErrorInfo = 0 + ExtraErrorInfo = 0, }; } } @@ -450,4 +449,4 @@ public void ClearError() _errorIndex = 0; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs index 905cb2054..f4174a913 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs @@ -20,7 +20,7 @@ public class CommandBuffer /// /// The command processing time estimator in use. /// - private ICommandProcessingTimeEstimator _commandProcessingTimeEstimator; + private readonly ICommandProcessingTimeEstimator _commandProcessingTimeEstimator; /// /// The estimated total processing time. @@ -61,7 +61,7 @@ private void AddCommand(ICommand command) /// The node id associated to this command. public void GenerateClearMixBuffer(int nodeId) { - ClearMixBufferCommand command = new ClearMixBufferCommand(nodeId); + ClearMixBufferCommand command = new(nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -79,7 +79,7 @@ public void GenerateClearMixBuffer(int nodeId) /// Set to true if the voice was playing previously. public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying) { - DepopPrepareCommand command = new DepopPrepareCommand(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying); + DepopPrepareCommand command = new(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -94,7 +94,7 @@ public void GenerateDepopPrepare(Memory state, Memory d /// The node id associated to this command. public void GeneratePerformance(ref PerformanceEntryAddresses performanceEntryAddresses, PerformanceCommand.Type type, int nodeId) { - PerformanceCommand command = new PerformanceCommand(ref performanceEntryAddresses, type, nodeId); + PerformanceCommand command = new(ref performanceEntryAddresses, type, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -110,7 +110,7 @@ public void GeneratePerformance(ref PerformanceEntryAddresses performanceEntryAd /// The node id associated to this command. public void GenerateVolumeRamp(float previousVolume, float volume, uint bufferIndex, int nodeId) { - VolumeRampCommand command = new VolumeRampCommand(previousVolume, volume, bufferIndex, nodeId); + VolumeRampCommand command = new(previousVolume, volume, bufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -127,7 +127,7 @@ public void GenerateVolumeRamp(float previousVolume, float volume, uint bufferIn /// The node id associated to this command. public void GenerateDataSourceVersion2(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - DataSourceVersion2Command command = new DataSourceVersion2Command(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); + DataSourceVersion2Command command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -144,7 +144,7 @@ public void GenerateDataSourceVersion2(ref VoiceState voiceState, MemoryThe node id associated to this command. public void GeneratePcmInt16DataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - PcmInt16DataSourceCommandVersion1 command = new PcmInt16DataSourceCommandVersion1(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); + PcmInt16DataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -161,7 +161,7 @@ public void GeneratePcmInt16DataSourceVersion1(ref VoiceState voiceState, Memory /// The node id associated to this command. public void GeneratePcmFloatDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - PcmFloatDataSourceCommandVersion1 command = new PcmFloatDataSourceCommandVersion1(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); + PcmFloatDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -177,7 +177,7 @@ public void GeneratePcmFloatDataSourceVersion1(ref VoiceState voiceState, Memory /// The node id associated to this command. public void GenerateAdpcmDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, int nodeId) { - AdpcmDataSourceCommandVersion1 command = new AdpcmDataSourceCommandVersion1(ref voiceState, state, outputBufferIndex, nodeId); + AdpcmDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -196,7 +196,7 @@ public void GenerateAdpcmDataSourceVersion1(ref VoiceState voiceState, MemoryThe node id associated to this command. public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId) { - BiquadFilterCommand command = new BiquadFilterCommand(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId); + BiquadFilterCommand command = new(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -215,7 +215,7 @@ public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter filter /// The node id associated to this command. public void GenerateGroupedBiquadFilter(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId) { - GroupedBiquadFilterCommand command = new GroupedBiquadFilterCommand(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId); + GroupedBiquadFilterCommand command = new(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -234,7 +234,7 @@ public void GenerateGroupedBiquadFilter(int baseIndex, ReadOnlySpanThe node id associated to this command. public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, Span previousVolume, Span volume, Memory state, int nodeId) { - MixRampGroupedCommand command = new MixRampGroupedCommand(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId); + MixRampGroupedCommand command = new(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -253,7 +253,7 @@ public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, u /// The node id associated to this command. public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId) { - MixRampCommand command = new MixRampCommand(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId); + MixRampCommand command = new(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -270,7 +270,7 @@ public void GenerateMixRamp(float previousVolume, float volume, uint inputBuffer /// The target sample rate in use. public void GenerateDepopForMixBuffersCommand(Memory depopBuffer, uint bufferOffset, uint bufferCount, int nodeId, uint sampleRate) { - DepopForMixBuffersCommand command = new DepopForMixBuffersCommand(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate); + DepopForMixBuffersCommand command = new(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -285,7 +285,7 @@ public void GenerateDepopForMixBuffersCommand(Memory depopBuffer, uint bu /// The node id associated to this command. public void GenerateCopyMixBuffer(uint inputBufferIndex, uint outputBufferIndex, int nodeId) { - CopyMixBufferCommand command = new CopyMixBufferCommand(inputBufferIndex, outputBufferIndex, nodeId); + CopyMixBufferCommand command = new(inputBufferIndex, outputBufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -301,7 +301,7 @@ public void GenerateCopyMixBuffer(uint inputBufferIndex, uint outputBufferIndex, /// The mix volume. public void GenerateMix(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume) { - MixCommand command = new MixCommand(inputBufferIndex, outputBufferIndex, nodeId, volume); + MixCommand command = new(inputBufferIndex, outputBufferIndex, nodeId, volume); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -323,7 +323,7 @@ public void GenerateReverbEffect(uint bufferOffset, ReverbParameter parameter, M { if (parameter.IsChannelCountValid()) { - ReverbCommand command = new ReverbCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported); + ReverbCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -345,7 +345,7 @@ public void GenerateReverb3dEffect(uint bufferOffset, Reverb3dParameter paramete { if (parameter.IsChannelCountValid()) { - Reverb3dCommand command = new Reverb3dCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); + Reverb3dCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -368,7 +368,7 @@ public void GenerateDelayEffect(uint bufferOffset, DelayParameter parameter, Mem { if (parameter.IsChannelCountValid()) { - DelayCommand command = new DelayCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); + DelayCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -389,7 +389,7 @@ public void GenerateLimiterEffectVersion1(uint bufferOffset, LimiterParameter pa { if (parameter.IsChannelCountValid()) { - LimiterCommandVersion1 command = new LimiterCommandVersion1(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId); + LimiterCommandVersion1 command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -411,7 +411,7 @@ public void GenerateLimiterEffectVersion2(uint bufferOffset, LimiterParameter pa { if (parameter.IsChannelCountValid()) { - LimiterCommandVersion2 command = new LimiterCommandVersion2(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId); + LimiterCommandVersion2 command = new(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -437,7 +437,7 @@ public void GenerateAuxEffect(uint bufferOffset, byte inputBufferOffset, byte ou { if (state.SendBufferInfoBase != 0 && state.ReturnBufferInfoBase != 0) { - AuxiliaryBufferCommand command = new AuxiliaryBufferCommand(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId); + AuxiliaryBufferCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -461,7 +461,7 @@ public void GenerateCaptureEffect(uint bufferOffset, byte inputBufferOffset, ulo { if (sendBufferInfo != 0) { - CaptureBufferCommand command = new CaptureBufferCommand(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId); + CaptureBufferCommand command = new(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -473,7 +473,7 @@ public void GenerateCompressorEffect(uint bufferOffset, CompressorParameter para { if (parameter.IsChannelCountValid()) { - CompressorCommand command = new CompressorCommand(bufferOffset, parameter, state, isEnabled, nodeId); + CompressorCommand command = new(bufferOffset, parameter, state, isEnabled, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -489,7 +489,7 @@ public void GenerateCompressorEffect(uint bufferOffset, CompressorParameter para /// The node id associated to this command. public void GenerateVolume(float volume, uint bufferOffset, int nodeId) { - VolumeCommand command = new VolumeCommand(volume, bufferOffset, nodeId); + VolumeCommand command = new(volume, bufferOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -504,7 +504,7 @@ public void GenerateVolume(float volume, uint bufferOffset, int nodeId) /// The node id associated to this command. public void GenerateCircularBuffer(uint bufferOffset, CircularBufferSink sink, int nodeId) { - CircularBufferSinkCommand command = new CircularBufferSinkCommand(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId); + CircularBufferSinkCommand command = new(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -521,7 +521,7 @@ public void GenerateCircularBuffer(uint bufferOffset, CircularBufferSink sink, i /// The node id associated to this command. public void GenerateDownMixSurroundToStereo(uint bufferOffset, Span inputBufferOffset, Span outputBufferOffset, float[] downMixParameter, int nodeId) { - DownMixSurroundToStereoCommand command = new DownMixSurroundToStereoCommand(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId); + DownMixSurroundToStereoCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -541,7 +541,7 @@ public void GenerateDownMixSurroundToStereo(uint bufferOffset, Span inputB /// The node id associated to this command. public void GenerateUpsample(uint bufferOffset, UpsamplerState upsampler, uint inputCount, Span inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId) { - UpsampleCommand command = new UpsampleCommand(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId); + UpsampleCommand command = new(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -558,11 +558,11 @@ public void GenerateUpsample(uint bufferOffset, UpsamplerState upsampler, uint i /// The node id associated to this command. public void GenerateDeviceSink(uint bufferOffset, DeviceSink sink, int sessionId, Memory buffer, int nodeId) { - DeviceSinkCommand command = new DeviceSinkCommand(bufferOffset, sink, sessionId, buffer, nodeId); + DeviceSinkCommand command = new(bufferOffset, sink, sessionId, buffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); AddCommand(command); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs index afc1e39b7..ae8f699f3 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs @@ -17,14 +17,14 @@ namespace Ryujinx.Audio.Renderer.Server { public class CommandGenerator { - private CommandBuffer _commandBuffer; - private RendererSystemContext _rendererContext; - private VoiceContext _voiceContext; - private MixContext _mixContext; - private EffectContext _effectContext; - private SinkContext _sinkContext; - private SplitterContext _splitterContext; - private PerformanceManager _performanceManager; + private readonly CommandBuffer _commandBuffer; + private readonly RendererSystemContext _rendererContext; + private readonly VoiceContext _voiceContext; + private readonly MixContext _mixContext; + private readonly EffectContext _effectContext; + private readonly SinkContext _sinkContext; + private readonly SplitterContext _splitterContext; + private readonly PerformanceManager _performanceManager; public CommandGenerator(CommandBuffer commandBuffer, RendererSystemContext rendererContext, VoiceContext voiceContext, MixContext mixContext, EffectContext effectContext, SinkContext sinkContext, SplitterContext splitterContext, PerformanceManager performanceManager) { @@ -138,7 +138,7 @@ private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory biquadStateRawMemory = SpanMemoryManager.Cast(state).Slice(VoiceUpdateState.BiquadStateOffset, VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount); + Memory biquadStateRawMemory = SpanMemoryManager.Cast(state)[..(VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount)]; Memory stateMemory = SpanMemoryManager.Cast(biquadStateRawMemory); _commandBuffer.GenerateGroupedBiquadFilter(baseIndex, voiceState.BiquadFilters.AsSpan(), stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId); @@ -151,7 +151,7 @@ private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory biquadStateRawMemory = SpanMemoryManager.Cast(state).Slice(VoiceUpdateState.BiquadStateOffset, VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount); + Memory biquadStateRawMemory = SpanMemoryManager.Cast(state)[..(VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount)]; Memory stateMemory = SpanMemoryManager.Cast(biquadStateRawMemory); @@ -224,7 +224,7 @@ private void GenerateVoice(ref VoiceState voiceState) bool performanceInitialized = false; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); if (_performanceManager != null && _performanceManager.IsTargetNodeId(nodeId) && _performanceManager.GetNextEntry(out performanceEntry, dataSourceDetailType, PerformanceEntryType.Voice, nodeId)) { @@ -371,7 +371,7 @@ public void GenerateVoices() { int nodeId = sortedState.NodeId; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); bool performanceInitialized = false; @@ -502,9 +502,11 @@ private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect ef bool needInitialization = effect.Parameter.Status == UsageState.Invalid || (effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourContext.IsBiquadFilterEffectStateClearBugFixed()); - BiquadFilterParameter parameter = new BiquadFilterParameter(); + BiquadFilterParameter parameter = new() + { + Enable = true, + }; - parameter.Enable = true; effect.Parameter.Denominator.AsSpan().CopyTo(parameter.Denominator.AsSpan()); effect.Parameter.Numerator.AsSpan().CopyTo(parameter.Numerator.AsSpan()); @@ -623,7 +625,7 @@ private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect) bool isFinalMix = mix.MixId == Constants.FinalMixId; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); bool performanceInitialized = false; @@ -789,7 +791,7 @@ private void GenerateSubMix(ref MixState subMix) GenerateEffects(ref subMix); - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); int nodeId = subMix.NodeId; @@ -820,7 +822,7 @@ public void GenerateSubMixes() { int nodeId = sortedState.NodeId; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); bool performanceInitialized = false; @@ -853,7 +855,7 @@ private void GenerateFinalMix() GenerateEffects(ref finalMix); - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); int nodeId = finalMix.NodeId; @@ -901,7 +903,7 @@ public void GenerateFinalMixes() { int nodeId = _mixContext.GetFinalState().NodeId; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); bool performanceInitialized = false; @@ -977,7 +979,7 @@ private void GenerateSink(BaseSink sink, ref MixState finalMix) { bool performanceInitialized = false; - PerformanceEntryAddresses performanceEntry = new PerformanceEntryAddresses(); + PerformanceEntryAddresses performanceEntry = new(); if (_performanceManager != null && _performanceManager.GetNextEntry(out performanceEntry, PerformanceEntryType.Sink, sink.NodeId)) { @@ -1025,4 +1027,4 @@ public void GenerateSinks() } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs index 63dc9ca96..d95e9aa71 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs @@ -8,8 +8,8 @@ namespace Ryujinx.Audio.Renderer.Server /// public class CommandProcessingTimeEstimatorVersion1 : ICommandProcessingTimeEstimator { - private uint _sampleCount; - private uint _bufferCount; + private readonly uint _sampleCount; + private readonly uint _bufferCount; public CommandProcessingTimeEstimatorVersion1(uint sampleCount, uint bufferCount) { @@ -185,4 +185,4 @@ public uint Estimate(CompressorCommand command) return 0; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs index 7ee491cd6..929aaf383 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs @@ -9,8 +9,8 @@ namespace Ryujinx.Audio.Renderer.Server /// public class CommandProcessingTimeEstimatorVersion2 : ICommandProcessingTimeEstimator { - private uint _sampleCount; - private uint _bufferCount; + private readonly uint _sampleCount; + private readonly uint _bufferCount; public CommandProcessingTimeEstimatorVersion2(uint sampleCount, uint bufferCount) { @@ -60,7 +60,7 @@ public uint Estimate(BiquadFilterCommand command) public uint Estimate(MixRampGroupedCommand command) { - const float costPerSample = 7.245f; + const float CostPerSample = 7.245f; Debug.Assert(_sampleCount == 160 || _sampleCount == 240); @@ -74,7 +74,7 @@ public uint Estimate(MixRampGroupedCommand command) } } - return (uint)(_sampleCount * costPerSample * volumeCount); + return (uint)(_sampleCount * CostPerSample * volumeCount); } public uint Estimate(MixRampCommand command) @@ -189,71 +189,47 @@ public uint Estimate(DelayCommand command) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)41636.0f; - case 2: - return (uint)97861.0f; - case 4: - return (uint)192520.0f; - case 6: - return (uint)301760.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)41636.0f, + 2 => (uint)97861.0f, + 4 => (uint)192520.0f, + 6 => (uint)301760.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)578.53f; - case 2: - return (uint)663.06f; - case 4: - return (uint)703.98f; - case 6: - return (uint)760.03f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)578.53f, + 2 => (uint)663.06f, + 4 => (uint)703.98f, + 6 => (uint)760.03f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)8770.3f; - case 2: - return (uint)25741.0f; - case 4: - return (uint)47551.0f; - case 6: - return (uint)81629.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)8770.3f, + 2 => (uint)25741.0f, + 4 => (uint)47551.0f, + 6 => (uint)81629.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)521.28f; - case 2: - return (uint)585.4f; - case 4: - return (uint)629.88f; - case 6: - return (uint)713.57f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)521.28f, + 2 => (uint)585.4f, + 4 => (uint)629.88f, + 6 => (uint)713.57f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public uint Estimate(ReverbCommand command) @@ -264,71 +240,47 @@ public uint Estimate(ReverbCommand command) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)97192.0f; - case 2: - return (uint)103280.0f; - case 4: - return (uint)109580.0f; - case 6: - return (uint)115070.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)97192.0f, + 2 => (uint)103280.0f, + 4 => (uint)109580.0f, + 6 => (uint)115070.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)492.01f; - case 2: - return (uint)554.46f; - case 4: - return (uint)595.86f; - case 6: - return (uint)656.62f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)492.01f, + 2 => (uint)554.46f, + 4 => (uint)595.86f, + 6 => (uint)656.62f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)136460.0f; - case 2: - return (uint)145750.0f; - case 4: - return (uint)154800.0f; - case 6: - return (uint)161970.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)136460.0f, + 2 => (uint)145750.0f, + 4 => (uint)154800.0f, + 6 => (uint)161970.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)495.79f; - case 2: - return (uint)527.16f; - case 4: - return (uint)598.75f; - case 6: - return (uint)666.03f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)495.79f, + 2 => (uint)527.16f, + 4 => (uint)598.75f, + 6 => (uint)666.03f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public uint Estimate(Reverb3dCommand command) @@ -339,70 +291,46 @@ public uint Estimate(Reverb3dCommand command) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)138840.0f; - case 2: - return (uint)135430.0f; - case 4: - return (uint)199180.0f; - case 6: - return (uint)247350.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)138840.0f, + 2 => (uint)135430.0f, + 4 => (uint)199180.0f, + 6 => (uint)247350.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)718.7f; - case 2: - return (uint)751.3f; - case 4: - return (uint)797.46f; - case 6: - return (uint)867.43f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)718.7f, + 2 => (uint)751.3f, + 4 => (uint)797.46f, + 6 => (uint)867.43f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)199950.0f; - case 2: - return (uint)195200.0f; - case 4: - return (uint)290580.0f; - case 6: - return (uint)363490.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)199950.0f, + 2 => (uint)195200.0f, + 4 => (uint)290580.0f, + 6 => (uint)363490.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)534.24f; - case 2: - return (uint)570.87f; - case 4: - return (uint)660.93f; - case 6: - return (uint)694.6f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)534.24f, + 2 => (uint)570.87f, + 4 => (uint)660.93f, + 6 => (uint)694.6f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public uint Estimate(AuxiliaryBufferCommand command) @@ -549,4 +477,4 @@ public uint Estimate(CompressorCommand command) return 0; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs index b79ca1369..8ae4bc059 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs @@ -12,20 +12,20 @@ namespace Ryujinx.Audio.Renderer.Server /// public class CommandProcessingTimeEstimatorVersion3 : ICommandProcessingTimeEstimator { - protected uint _sampleCount; - protected uint _bufferCount; + protected uint SampleCount; + protected uint BufferCount; public CommandProcessingTimeEstimatorVersion3(uint sampleCount, uint bufferCount) { - _sampleCount = sampleCount; - _bufferCount = bufferCount; + SampleCount = sampleCount; + BufferCount = bufferCount; } public uint Estimate(PerformanceCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)498.17f; } @@ -35,24 +35,24 @@ public uint Estimate(PerformanceCommand command) public uint Estimate(ClearMixBufferCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); float costPerBuffer = 440.68f; float baseCost = 0; - if (_sampleCount == 160) + if (SampleCount == 160) { costPerBuffer = 266.65f; } - return (uint)(baseCost + costPerBuffer * _bufferCount); + return (uint)(baseCost + costPerBuffer * BufferCount); } public uint Estimate(BiquadFilterCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)4173.2f; } @@ -64,9 +64,9 @@ public uint Estimate(MixRampGroupedCommand command) { float costPerSample = 6.4434f; - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { costPerSample = 6.708f; } @@ -81,14 +81,14 @@ public uint Estimate(MixRampGroupedCommand command) } } - return (uint)(_sampleCount * costPerSample * volumeCount); + return (uint)(SampleCount * costPerSample * volumeCount); } public uint Estimate(MixRampCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)1968.7f; } @@ -103,9 +103,9 @@ public uint Estimate(DepopPrepareCommand command) public uint Estimate(VolumeRampCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)1425.3f; } @@ -115,41 +115,41 @@ public uint Estimate(VolumeRampCommand command) public uint Estimate(PcmInt16DataSourceCommandVersion1 command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); float costPerSample = 710.143f; float baseCost = 7853.286f; - if (_sampleCount == 160) + if (SampleCount == 160) { costPerSample = 427.52f; baseCost = 6329.442f; } - return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f)))); + return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f)))); } public uint Estimate(AdpcmDataSourceCommandVersion1 command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); float costPerSample = 3564.1f; float baseCost = 9736.702f; - if (_sampleCount == 160) + if (SampleCount == 160) { costPerSample = 2125.6f; baseCost = 7913.808f; } - return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f)))); + return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f)))); } public uint Estimate(DepopForMixBuffersCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)739.64f; } @@ -159,9 +159,9 @@ public uint Estimate(DepopForMixBuffersCommand command) public uint Estimate(CopyMixBufferCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)842.59f; } @@ -171,9 +171,9 @@ public uint Estimate(CopyMixBufferCommand command) public uint Estimate(MixCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)1402.8f; } @@ -183,231 +183,159 @@ public uint Estimate(MixCommand command) public virtual uint Estimate(DelayCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)8929.04f; - case 2: - return (uint)25500.75f; - case 4: - return (uint)47759.62f; - case 6: - return (uint)82203.07f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)8929.04f, + 2 => (uint)25500.75f, + 4 => (uint)47759.62f, + 6 => (uint)82203.07f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)1295.20f; - case 2: - return (uint)1213.60f; - case 4: - return (uint)942.03f; - case 6: - return (uint)1001.55f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)1295.20f, + 2 => (uint)1213.60f, + 4 => (uint)942.03f, + 6 => (uint)1001.55f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)11941.05f; - case 2: - return (uint)37197.37f; - case 4: - return (uint)69749.84f; - case 6: - return (uint)120042.40f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)997.67f; - case 2: - return (uint)977.63f; - case 4: - return (uint)792.30f; - case 6: - return (uint)875.43f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)11941.05f, + 2 => (uint)37197.37f, + 4 => (uint)69749.84f, + 6 => (uint)120042.40f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; + } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)997.67f, + 2 => (uint)977.63f, + 4 => (uint)792.30f, + 6 => (uint)875.43f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public virtual uint Estimate(ReverbCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)81475.05f; - case 2: - return (uint)84975.0f; - case 4: - return (uint)91625.15f; - case 6: - return (uint)95332.27f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)81475.05f, + 2 => (uint)84975.0f, + 4 => (uint)91625.15f, + 6 => (uint)95332.27f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)536.30f; - case 2: - return (uint)588.70f; - case 4: - return (uint)643.70f; - case 6: - return (uint)706.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)536.30f, + 2 => (uint)588.70f, + 4 => (uint)643.70f, + 6 => (uint)706.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)120174.47f; - case 2: - return (uint)25262.22f; - case 4: - return (uint)135751.23f; - case 6: - return (uint)141129.23f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)617.64f; - case 2: - return (uint)659.54f; - case 4: - return (uint)711.43f; - case 6: - return (uint)778.07f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)120174.47f, + 2 => (uint)25262.22f, + 4 => (uint)135751.23f, + 6 => (uint)141129.23f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; + } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)617.64f, + 2 => (uint)659.54f, + 4 => (uint)711.43f, + 6 => (uint)778.07f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public virtual uint Estimate(Reverb3dCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)116754.0f; - case 2: - return (uint)125912.05f; - case 4: - return (uint)146336.03f; - case 6: - return (uint)165812.66f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)116754.0f, + 2 => (uint)125912.05f, + 4 => (uint)146336.03f, + 6 => (uint)165812.66f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)734.0f; - case 2: - return (uint)766.62f; - case 4: - return (uint)797.46f; - case 6: - return (uint)867.43f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)734.0f, + 2 => (uint)766.62f, + 4 => (uint)797.46f, + 6 => (uint)867.43f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)170292.34f; - case 2: - return (uint)183875.63f; - case 4: - return (uint)214696.19f; - case 6: - return (uint)243846.77f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)508.47f; - case 2: - return (uint)582.45f; - case 4: - return (uint)626.42f; - case 6: - return (uint)682.47f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)170292.34f, + 2 => (uint)183875.63f, + 4 => (uint)214696.19f, + 6 => (uint)243846.77f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; + } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)508.47f, + 2 => (uint)582.45f, + 4 => (uint)626.42f, + 6 => (uint)682.47f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public uint Estimate(AuxiliaryBufferCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { @@ -427,9 +355,9 @@ public uint Estimate(AuxiliaryBufferCommand command) public uint Estimate(VolumeCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)1311.1f; } @@ -439,12 +367,12 @@ public uint Estimate(VolumeCommand command) public uint Estimate(CircularBufferSinkCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); float costPerBuffer = 770.26f; float baseCost = 0f; - if (_sampleCount == 160) + if (SampleCount == 160) { costPerBuffer = 531.07f; } @@ -454,9 +382,9 @@ public uint Estimate(CircularBufferSinkCommand command) public uint Estimate(DownMixSurroundToStereoCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)9949.7f; } @@ -466,9 +394,9 @@ public uint Estimate(DownMixSurroundToStereoCommand command) public uint Estimate(UpsampleCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)312990.0f; } @@ -478,12 +406,12 @@ public uint Estimate(UpsampleCommand command) public uint Estimate(DeviceSinkCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); Debug.Assert(command.InputCount == 2 || command.InputCount == 6); if (command.InputCount == 2) { - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)8980.0f; } @@ -491,7 +419,7 @@ public uint Estimate(DeviceSinkCommand command) return (uint)9221.9f; } - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)9177.9f; } @@ -501,27 +429,27 @@ public uint Estimate(DeviceSinkCommand command) public uint Estimate(PcmFloatDataSourceCommandVersion1 command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); float costPerSample = 3490.9f; float baseCost = 10090.9f; - if (_sampleCount == 160) + if (SampleCount == 160) { costPerSample = 2310.4f; baseCost = 7845.25f; } - return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f)))); + return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f)))); } public uint Estimate(DataSourceVersion2Command command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - (float baseCost, float costPerSample) = GetCostByFormat(_sampleCount, command.SampleFormat, command.SrcQuality); + (float baseCost, float costPerSample) = GetCostByFormat(SampleCount, command.SampleFormat, command.SrcQuality); - return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f) - 1.0f))); + return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f) - 1.0f))); } private static (float, float) GetCostByFormat(uint sampleCount, SampleFormat format, SampleRateConversionQuality quality) @@ -618,124 +546,90 @@ private static (float, float) GetCostByFormat(uint sampleCount, SampleFormat for private uint EstimateLimiterCommandCommon(LimiterParameter parameter, bool enabled) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (enabled) { - switch (parameter.ChannelCount) + return parameter.ChannelCount switch { - case 1: - return (uint)21392.0f; - case 2: - return (uint)26829.0f; - case 4: - return (uint)32405.0f; - case 6: - return (uint)52219.0f; - default: - throw new NotImplementedException($"{parameter.ChannelCount}"); - } + 1 => (uint)21392.0f, + 2 => (uint)26829.0f, + 4 => (uint)32405.0f, + 6 => (uint)52219.0f, + _ => throw new NotImplementedException($"{parameter.ChannelCount}"), + }; } - else + + return parameter.ChannelCount switch { - switch (parameter.ChannelCount) - { - case 1: - return (uint)897.0f; - case 2: - return (uint)931.55f; - case 4: - return (uint)975.39f; - case 6: - return (uint)1016.8f; - default: - throw new NotImplementedException($"{parameter.ChannelCount}"); - } - } + 1 => (uint)897.0f, + 2 => (uint)931.55f, + 4 => (uint)975.39f, + 6 => (uint)1016.8f, + _ => throw new NotImplementedException($"{parameter.ChannelCount}"), + }; } if (enabled) { - switch (parameter.ChannelCount) + return parameter.ChannelCount switch { - case 1: - return (uint)30556.0f; - case 2: - return (uint)39011.0f; - case 4: - return (uint)48270.0f; - case 6: - return (uint)76712.0f; - default: - throw new NotImplementedException($"{parameter.ChannelCount}"); - } - } - else - { - switch (parameter.ChannelCount) - { - case 1: - return (uint)874.43f; - case 2: - return (uint)921.55f; - case 4: - return (uint)945.26f; - case 6: - return (uint)992.26f; - default: - throw new NotImplementedException($"{parameter.ChannelCount}"); - } - } + 1 => (uint)30556.0f, + 2 => (uint)39011.0f, + 4 => (uint)48270.0f, + 6 => (uint)76712.0f, + _ => throw new NotImplementedException($"{parameter.ChannelCount}"), + }; + } + + return parameter.ChannelCount switch + { + 1 => (uint)874.43f, + 2 => (uint)921.55f, + 4 => (uint)945.26f, + 6 => (uint)992.26f, + _ => throw new NotImplementedException($"{parameter.ChannelCount}"), + }; } public uint Estimate(LimiterCommandVersion1 command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled); } public uint Estimate(LimiterCommandVersion2 command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); if (!command.Parameter.StatisticsEnabled || !command.IsEffectEnabled) { return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled); } - if (_sampleCount == 160) + if (SampleCount == 160) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return (uint)23309.0f; - case 2: - return (uint)29954.0f; - case 4: - return (uint)35807.0f; - case 6: - return (uint)58340.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)33526.0f; - case 2: - return (uint)43549.0f; - case 4: - return (uint)52190.0f; - case 6: - return (uint)85527.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => (uint)23309.0f, + 2 => (uint)29954.0f, + 4 => (uint)35807.0f, + 6 => (uint)58340.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; + } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)33526.0f, + 2 => (uint)43549.0f, + 4 => (uint)52190.0f, + 6 => (uint)85527.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public virtual uint Estimate(GroupedBiquadFilterCommand command) @@ -753,4 +647,4 @@ public virtual uint Estimate(CompressorCommand command) return 0; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion4.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion4.cs index c60d8ebcb..25bc67cd9 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion4.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion4.cs @@ -12,9 +12,9 @@ public CommandProcessingTimeEstimatorVersion4(uint sampleCount, uint bufferCount public override uint Estimate(GroupedBiquadFilterCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { return (uint)7424.5f; } @@ -24,9 +24,9 @@ public override uint Estimate(GroupedBiquadFilterCommand command) public override uint Estimate(CaptureBufferCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { @@ -44,4 +44,4 @@ public override uint Estimate(CaptureBufferCommand command) return (uint)435.2f; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs index 2ed7e6a5b..7135c1c4f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs @@ -13,298 +13,202 @@ public CommandProcessingTimeEstimatorVersion5(uint sampleCount, uint bufferCount public override uint Estimate(DelayCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return 8929; - case 2: - return 25501; - case 4: - return 47760; - case 6: - return 82203; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)1295.20f; - case 2: - return (uint)1213.60f; - case 4: - return (uint)942.03f; - case 6: - return (uint)1001.6f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => 8929, + 2 => 25501, + 4 => 47760, + 6 => 82203, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)1295.20f, + 2 => (uint)1213.60f, + 4 => (uint)942.03f, + 6 => (uint)1001.6f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return 11941; - case 2: - return 37197; - case 4: - return 69750; - case 6: - return 12004; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + return command.Parameter.ChannelCount switch + { + 1 => 11941, + 2 => 37197, + 4 => 69750, + 6 => 12004, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)997.67f; - case 2: - return (uint)977.63f; - case 4: - return (uint)792.31f; - case 6: - return (uint)875.43f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)997.67f, + 2 => (uint)977.63f, + 4 => (uint)792.31f, + 6 => (uint)875.43f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public override uint Estimate(ReverbCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return 81475; - case 2: - return 84975; - case 4: - return 91625; - case 6: - return 95332; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)536.30f; - case 2: - return (uint)588.80f; - case 4: - return (uint)643.70f; - case 6: - return (uint)706.0f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => 81475, + 2 => 84975, + 4 => 91625, + 6 => 95332, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)536.30f, + 2 => (uint)588.80f, + 4 => (uint)643.70f, + 6 => (uint)706.0f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return 120170; - case 2: - return 125260; - case 4: - return 135750; - case 6: - return 141130; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + return command.Parameter.ChannelCount switch + { + 1 => 120170, + 2 => 125260, + 4 => 135750, + 6 => 141130, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)617.64f; - case 2: - return (uint)659.54f; - case 4: - return (uint)711.44f; - case 6: - return (uint)778.07f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)617.64f, + 2 => (uint)659.54f, + 4 => (uint)711.44f, + 6 => (uint)778.07f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public override uint Estimate(Reverb3dCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return 116750; - case 2: - return 125910; - case 4: - return 146340; - case 6: - return 165810; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) - { - case 1: - return 735; - case 2: - return (uint)766.62f; - case 4: - return (uint)834.07f; - case 6: - return (uint)875.44f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => 116750, + 2 => 125910, + 4 => 146340, + 6 => 165810, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } + + return command.Parameter.ChannelCount switch + { + 1 => 735, + 2 => (uint)766.62f, + 4 => (uint)834.07f, + 6 => (uint)875.44f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return 170290; - case 2: - return 183880; - case 4: - return 214700; - case 6: - return 243850; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + return command.Parameter.ChannelCount switch + { + 1 => 170290, + 2 => 183880, + 4 => 214700, + 6 => 243850, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)508.47f; - case 2: - return (uint)582.45f; - case 4: - return (uint)626.42f; - case 6: - return (uint)682.47f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)508.47f, + 2 => (uint)582.45f, + 4 => (uint)626.42f, + 6 => (uint)682.47f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } public override uint Estimate(CompressorCommand command) { - Debug.Assert(_sampleCount == 160 || _sampleCount == 240); + Debug.Assert(SampleCount == 160 || SampleCount == 240); - if (_sampleCount == 160) + if (SampleCount == 160) { if (command.Enabled) { - switch (command.Parameter.ChannelCount) + return command.Parameter.ChannelCount switch { - case 1: - return 34431; - case 2: - return 44253; - case 4: - return 63827; - case 6: - return 83361; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } - else - { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)630.12f; - case 2: - return (uint)638.27f; - case 4: - return (uint)705.86f; - case 6: - return (uint)782.02f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + 1 => 34431, + 2 => 44253, + 4 => 63827, + 6 => 83361, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } + + return command.Parameter.ChannelCount switch + { + 1 => (uint)630.12f, + 2 => (uint)638.27f, + 4 => (uint)705.86f, + 6 => (uint)782.02f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } if (command.Enabled) { - switch (command.Parameter.ChannelCount) - { - case 1: - return 51095; - case 2: - return 65693; - case 4: - return 95383; - case 6: - return 124510; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } + return command.Parameter.ChannelCount switch + { + 1 => 51095, + 2 => 65693, + 4 => 95383, + 6 => 124510, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } - else + + return command.Parameter.ChannelCount switch { - switch (command.Parameter.ChannelCount) - { - case 1: - return (uint)840.14f; - case 2: - return (uint)826.1f; - case 4: - return (uint)901.88f; - case 6: - return (uint)965.29f; - default: - throw new NotImplementedException($"{command.Parameter.ChannelCount}"); - } - } + 1 => (uint)840.14f, + 2 => (uint)826.1f, + 4 => (uint)901.88f, + 6 => (uint)965.29f, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs index 164065271..57ca266f4 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs @@ -58,7 +58,7 @@ public void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T pa { ulong bufferSize = (ulong)Unsafe.SizeOf() * Parameter.BufferStorageSize + (ulong)Unsafe.SizeOf(); - bool sendBufferUnmapped = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[0], Parameter.SendBufferInfoAddress, bufferSize); + bool sendBufferUnmapped = !mapper.TryAttachBuffer(out _, ref WorkBuffers[0], Parameter.SendBufferInfoAddress, bufferSize); bool returnBufferUnmapped = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[1], Parameter.ReturnBufferInfoAddress, bufferSize); BufferUnmapped = sendBufferUnmapped && returnBufferUnmapped; @@ -82,4 +82,4 @@ public override void UpdateForCommandGeneration() UpdateUsageStateForCommandGeneration(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs index 825b3bf76..a9716db2a 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs @@ -244,29 +244,19 @@ public void StoreStatus(ref T outStatus, bool isAudioRendererActive) where T /// The associated to the of this effect. public PerformanceDetailType GetPerformanceDetailType() { - switch (Type) + return Type switch { - case EffectType.BiquadFilter: - return PerformanceDetailType.BiquadFilter; - case EffectType.AuxiliaryBuffer: - return PerformanceDetailType.Aux; - case EffectType.Delay: - return PerformanceDetailType.Delay; - case EffectType.Reverb: - return PerformanceDetailType.Reverb; - case EffectType.Reverb3d: - return PerformanceDetailType.Reverb3d; - case EffectType.BufferMix: - return PerformanceDetailType.Mix; - case EffectType.Limiter: - return PerformanceDetailType.Limiter; - case EffectType.CaptureBuffer: - return PerformanceDetailType.CaptureBuffer; - case EffectType.Compressor: - return PerformanceDetailType.Compressor; - default: - throw new NotImplementedException($"{Type}"); - } + EffectType.BiquadFilter => PerformanceDetailType.BiquadFilter, + EffectType.AuxiliaryBuffer => PerformanceDetailType.Aux, + EffectType.Delay => PerformanceDetailType.Delay, + EffectType.Reverb => PerformanceDetailType.Reverb, + EffectType.Reverb3d => PerformanceDetailType.Reverb3d, + EffectType.BufferMix => PerformanceDetailType.Mix, + EffectType.Limiter => PerformanceDetailType.Limiter, + EffectType.CaptureBuffer => PerformanceDetailType.CaptureBuffer, + EffectType.Compressor => PerformanceDetailType.Compressor, + _ => throw new NotImplementedException($"{Type}"), + }; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs index de91046dc..b987f7c85 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs @@ -64,4 +64,4 @@ public override void UpdateForCommandGeneration() Parameter.Status = UsageState.Enabled; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs index 82c0a055a..d6cb9cfa3 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs @@ -46,4 +46,4 @@ public override void UpdateForCommandGeneration() UpdateUsageStateForCommandGeneration(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/CaptureBufferEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/CaptureBufferEffect.cs index c445798d4..5be4b4ed5 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/CaptureBufferEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/CaptureBufferEffect.cs @@ -79,4 +79,4 @@ public override void UpdateForCommandGeneration() UpdateUsageStateForCommandGeneration(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs index 32162abcd..826c32cb0 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Common; using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Parameter.Effect; diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs index 3f5d70bcf..43cabb7db 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs @@ -90,4 +90,4 @@ public override void UpdateForCommandGeneration() Parameter.Status = UsageState.Enabled; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs index bfb6528b4..619f31100 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs @@ -120,4 +120,4 @@ public void UpdateResultStateForCommandGeneration() } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs index 6e17ef3d1..3e2f7326d 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs @@ -92,4 +92,4 @@ public override void UpdateResultState(ref EffectResultState destState, ref Effe destState = srcState; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs index 473fddb84..f9d7f4943 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs @@ -89,4 +89,4 @@ public override void UpdateForCommandGeneration() Parameter.ParameterStatus = UsageState.Enabled; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs index e1543fd17..6fdf8fc23 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs @@ -92,4 +92,4 @@ public override void UpdateForCommandGeneration() Parameter.Status = UsageState.Enabled; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/UsageState.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/UsageState.cs index 8648aa2ca..da7172244 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/UsageState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/UsageState.cs @@ -23,6 +23,6 @@ public enum UsageState : byte /// /// The effect is disabled. /// - Disabled + Disabled, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs index 4872ddb3a..27b22363a 100644 --- a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs +++ b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs @@ -37,4 +37,4 @@ public interface ICommandProcessingTimeEstimator uint Estimate(CaptureBufferCommand command); uint Estimate(CompressorCommand command); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs index 5fd6b2b92..a7ec4cf51 100644 --- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs +++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs @@ -27,9 +27,9 @@ public struct AddressInfo /// public DspAddress ForceMappedDspAddress; - private unsafe ref MemoryPoolState MemoryPoolState => ref *_memoryPools; + private readonly unsafe ref MemoryPoolState MemoryPoolState => ref *_memoryPools; - public unsafe bool HasMemoryPoolState => (IntPtr)_memoryPools != IntPtr.Zero; + public readonly unsafe bool HasMemoryPoolState => (IntPtr)_memoryPools != IntPtr.Zero; /// /// Create an new empty . @@ -55,7 +55,7 @@ public static AddressInfo Create(CpuAddress cpuAddress, ulong size) CpuAddress = cpuAddress, _memoryPools = MemoryPoolState.Null, Size = size, - ForceMappedDspAddress = 0 + ForceMappedDspAddress = 0, }; } } @@ -105,7 +105,7 @@ public unsafe void SetupMemoryPool(MemoryPoolState* memoryPoolState) /// Check if the is mapped. /// /// Returns true if the is mapped. - public bool HasMappedMemoryPool() + public readonly bool HasMappedMemoryPool() { return HasMemoryPoolState && MemoryPoolState.IsMapped(); } @@ -115,7 +115,7 @@ public bool HasMappedMemoryPool() /// /// If true, mark the as used. /// Returns the DSP address associated to the . - public DspAddress GetReference(bool markUsed) + public readonly DspAddress GetReference(bool markUsed) { if (!HasMappedMemoryPool()) { @@ -130,4 +130,4 @@ public DspAddress GetReference(bool markUsed) return MemoryPoolState.Translate(CpuAddress, Size); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs index 69466bab5..91bd5dbf5 100644 --- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs @@ -26,7 +26,7 @@ public enum LocationType : uint /// /// located on the DSP side for system use. /// - Dsp + Dsp, } /// @@ -69,7 +69,7 @@ public static MemoryPoolState Create(LocationType location) CpuAddress = 0, DspAddress = 0, Size = 0, - Location = location + Location = location, }; } @@ -90,7 +90,7 @@ public void SetCpuAddress(CpuAddress cpuAddress, ulong size) /// The . /// The size. /// True if the is contained inside the . - public bool Contains(CpuAddress targetCpuAddress, ulong size) + public readonly bool Contains(CpuAddress targetCpuAddress, ulong size) { if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress) { @@ -106,7 +106,7 @@ public bool Contains(CpuAddress targetCpuAddress, ulong size) /// The . /// The size. /// the target DSP address. - public DspAddress Translate(CpuAddress targetCpuAddress, ulong size) + public readonly DspAddress Translate(CpuAddress targetCpuAddress, ulong size) { if (Contains(targetCpuAddress, size) && IsMapped()) { @@ -122,9 +122,9 @@ public DspAddress Translate(CpuAddress targetCpuAddress, ulong size) /// Is the mapped on the DSP? /// /// Returns true if the is mapped on the DSP. - public bool IsMapped() + public readonly bool IsMapped() { return DspAddress != 0; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs index 6c79da157..391b80f8d 100644 --- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs +++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs @@ -40,23 +40,23 @@ public enum UpdateResult : uint /// /// unmapping failed. /// - UnmapError = 3 + UnmapError = 3, } /// /// The handle of the process owning the CPU memory manipulated. /// - private uint _processHandle; + private readonly uint _processHandle; /// /// The that will be manipulated. /// - private Memory _memoryPools; + private readonly Memory _memoryPools; /// /// If set to true, this will try to force map memory pool even if their state are considered invalid. /// - private bool _isForceMapEnabled; + private readonly bool _isForceMapEnabled; /// /// Create a new used for system mapping. @@ -125,7 +125,8 @@ public uint GetProcessHandle(ref MemoryPoolState memoryPool) { return CurrentProcessPseudoHandle; } - else if (memoryPool.Location == MemoryPoolState.LocationType.Dsp) + + if (memoryPool.Location == MemoryPoolState.LocationType.Dsp) { return _processHandle; } @@ -234,13 +235,11 @@ public bool TryAttachBuffer(out ErrorInfo errorInfo, ref AddressInfo addressInfo return true; } - else - { - errorInfo.ErrorCode = ResultCode.InvalidAddressInfo; - errorInfo.ExtraErrorInfo = addressInfo.CpuAddress; - return _isForceMapEnabled; - } + errorInfo.ErrorCode = ResultCode.InvalidAddressInfo; + errorInfo.ExtraErrorInfo = addressInfo.CpuAddress; + + return _isForceMapEnabled; } /// @@ -256,19 +255,19 @@ public UpdateResult Update(ref MemoryPoolState memoryPool, ref MemoryPoolInParam MemoryPoolUserState outputState; - const uint pageSize = 0x1000; + const uint PageSize = 0x1000; if (inputState != MemoryPoolUserState.RequestAttach && inputState != MemoryPoolUserState.RequestDetach) { return UpdateResult.Success; } - if (inParameter.CpuAddress == 0 || (inParameter.CpuAddress % pageSize) != 0) + if (inParameter.CpuAddress == 0 || (inParameter.CpuAddress % PageSize) != 0) { return UpdateResult.InvalidParameter; } - if (inParameter.Size == 0 || (inParameter.Size % pageSize) != 0) + if (inParameter.Size == 0 || (inParameter.Size % PageSize) != 0) { return UpdateResult.InvalidParameter; } @@ -363,4 +362,4 @@ public static void ClearUsageState(Memory memoryPool) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs index cda6f737c..8991ceaf9 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs @@ -206,7 +206,7 @@ public void Sort() { UpdateDistancesFromFinalMix(); - int[] sortedMixesTemp = _sortedMixes.Slice(0, (int)GetCount()).ToArray(); + int[] sortedMixesTemp = _sortedMixes[..(int)GetCount()].ToArray(); Array.Sort(sortedMixesTemp, (a, b) => { @@ -248,12 +248,10 @@ public bool Sort(SplitterContext splitterContext) return isValid; } - else - { - UpdateMixBufferOffset(); - return true; - } + UpdateMixBufferOffset(); + + return true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs index 146e67811..88ae44831 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using static Ryujinx.Audio.Constants; namespace Ryujinx.Audio.Renderer.Server.Mix @@ -66,7 +65,7 @@ public struct MixState /// /// The effect processing order storage. /// - private IntPtr _effectProcessingOrderArrayPointer; + private readonly IntPtr _effectProcessingOrderArrayPointer; /// /// The max element count that can be found in the effect processing order storage. @@ -120,7 +119,7 @@ public float GetMixBufferVolume(int sourceIndex, int destinationIndex) /// /// The array used to order effects associated to this mix. /// - public Span EffectProcessingOrderArray + public readonly Span EffectProcessingOrderArray { get { @@ -175,7 +174,7 @@ public void ClearDistanceFromFinalMix() /// /// Clear the to its default state. /// - public void ClearEffectProcessingOrder() + public readonly void ClearEffectProcessingOrder() { EffectProcessingOrderArray.Fill(-1); } @@ -184,7 +183,7 @@ public void ClearEffectProcessingOrder() /// Return true if the mix has any destinations. /// /// True if the mix has any destinations. - public bool HasAnyDestination() + public readonly bool HasAnyDestination() { return DestinationMixId != UnusedMixId || DestinationSplitterId != UnusedSplitterId; } @@ -310,4 +309,4 @@ public bool Update(EdgeMatrix edgeMatrix, ref MixParameter parameter, EffectCont return isDirty; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceDetailEntry.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceDetailEntry.cs index dbe59cb0d..ffabf4676 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceDetailEntry.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceDetailEntry.cs @@ -49,4 +49,4 @@ public interface IPerformanceDetailEntry /// The type to use. void SetDetailType(PerformanceDetailType detailType); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceEntry.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceEntry.cs index 9888a4cc1..a0178187b 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceEntry.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceEntry.cs @@ -43,4 +43,4 @@ public interface IPerformanceEntry /// The type to use. void SetEntryType(PerformanceEntryType type); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceHeader.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceHeader.cs index 21876b4b4..deacd8ccc 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceHeader.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/IPerformanceHeader.cs @@ -77,4 +77,4 @@ public interface IPerformanceHeader /// The total count of detailed entries in this frame. void SetEntryDetailCount(int entryDetailCount); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion1.cs index 22704c0d1..a4024607c 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion1.cs @@ -34,22 +34,22 @@ public struct PerformanceDetailVersion1 : IPerformanceDetailEntry /// public PerformanceEntryType EntryType; - public int GetProcessingTime() + public readonly int GetProcessingTime() { return ProcessingTime; } - public int GetProcessingTimeOffset() + public readonly int GetProcessingTimeOffset() { return 8; } - public int GetStartTime() + public readonly int GetStartTime() { return StartTime; } - public int GetStartTimeOffset() + public readonly int GetStartTimeOffset() { return 4; } @@ -69,4 +69,4 @@ public void SetNodeId(int nodeId) NodeId = nodeId; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion2.cs index 05ecda9b6..f10e2937e 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceDetailVersion2.cs @@ -34,22 +34,22 @@ public struct PerformanceDetailVersion2 : IPerformanceDetailEntry /// public PerformanceEntryType EntryType; - public int GetProcessingTime() + public readonly int GetProcessingTime() { return ProcessingTime; } - public int GetProcessingTimeOffset() + public readonly int GetProcessingTimeOffset() { return 8; } - public int GetStartTime() + public readonly int GetStartTime() { return StartTime; } - public int GetStartTimeOffset() + public readonly int GetStartTimeOffset() { return 4; } @@ -69,4 +69,4 @@ public void SetNodeId(int nodeId) NodeId = nodeId; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs index 1b8d8668a..d24b96a27 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs @@ -53,4 +53,4 @@ public void SetProcessingTime(ulong endTimeNano) BaseMemory.Span[(int)ProcessingTimeOffset / 4] = (int)(endTimeNano / 1000) - BaseMemory.Span[(int)StartTimeOffset / 4]; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion1.cs index fa2d32164..2c407670f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion1.cs @@ -29,22 +29,22 @@ public struct PerformanceEntryVersion1 : IPerformanceEntry /// public PerformanceEntryType EntryType; - public int GetProcessingTime() + public readonly int GetProcessingTime() { return ProcessingTime; } - public int GetProcessingTimeOffset() + public readonly int GetProcessingTimeOffset() { return 8; } - public int GetStartTime() + public readonly int GetStartTime() { return StartTime; } - public int GetStartTimeOffset() + public readonly int GetStartTimeOffset() { return 4; } @@ -59,4 +59,4 @@ public void SetNodeId(int nodeId) NodeId = nodeId; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion2.cs index 49d4b3ce0..eb96a3141 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryVersion2.cs @@ -29,22 +29,22 @@ public struct PerformanceEntryVersion2 : IPerformanceEntry /// public PerformanceEntryType EntryType; - public int GetProcessingTime() + public readonly int GetProcessingTime() { return ProcessingTime; } - public int GetProcessingTimeOffset() + public readonly int GetProcessingTimeOffset() { return 8; } - public int GetStartTime() + public readonly int GetStartTime() { return StartTime; } - public int GetStartTimeOffset() + public readonly int GetStartTimeOffset() { return 4; } @@ -59,4 +59,4 @@ public void SetNodeId(int nodeId) NodeId = nodeId; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion1.cs index 5fe6bff06..5aeb703c5 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion1.cs @@ -38,22 +38,22 @@ public struct PerformanceFrameHeaderVersion1 : IPerformanceHeader /// public uint VoiceDropCount; - public int GetEntryCount() + public readonly int GetEntryCount() { return EntryCount; } - public int GetEntryCountOffset() + public readonly int GetEntryCountOffset() { return 4; } - public int GetEntryDetailCount() + public readonly int GetEntryDetailCount() { return EntryDetailCount; } - public void SetDspRunningBehind(bool isRunningBehind) + public readonly void SetDspRunningBehind(bool isRunningBehind) { // NOTE: Not present in version 1 } @@ -68,7 +68,7 @@ public void SetEntryDetailCount(int entryDetailCount) EntryDetailCount = entryDetailCount; } - public void SetIndex(uint index) + public readonly void SetIndex(uint index) { // NOTE: Not present in version 1 } @@ -83,7 +83,7 @@ public void SetNextOffset(int nextOffset) NextOffset = nextOffset; } - public void SetStartRenderingTicks(ulong startTicks) + public readonly void SetStartRenderingTicks(ulong startTicks) { // NOTE: not present in version 1 } @@ -98,4 +98,4 @@ public void SetVoiceDropCount(uint voiceCount) VoiceDropCount = voiceCount; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion2.cs index a18229686..d6e0ffc8b 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceFrameHeaderVersion2.cs @@ -54,17 +54,17 @@ public struct PerformanceFrameHeaderVersion2 : IPerformanceHeader [MarshalAs(UnmanagedType.I1)] public bool IsDspRunningBehind; - public int GetEntryCount() + public readonly int GetEntryCount() { return EntryCount; } - public int GetEntryCountOffset() + public readonly int GetEntryCountOffset() { return 4; } - public int GetEntryDetailCount() + public readonly int GetEntryDetailCount() { return EntryDetailCount; } @@ -114,4 +114,4 @@ public void SetVoiceDropCount(uint voiceCount) VoiceDropCount = voiceCount; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs index f996441c0..0a035916c 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs @@ -22,11 +22,12 @@ public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref Audio PerformanceEntryVersion2, PerformanceDetailVersion2>.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter); } - else if (version == 1) + + if (version == 1) { return (ulong)PerformanceManagerGeneric.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter); + PerformanceEntryVersion1, + PerformanceDetailVersion1>.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter); } throw new NotImplementedException($"Unknown Performance metrics data format version {version}"); @@ -90,17 +91,12 @@ public static PerformanceManager Create(Memory performanceBuffer, ref Audi { uint version = behaviourContext.GetPerformanceMetricsDataFormat(); - switch (version) + return version switch { - case 1: - return new PerformanceManagerGeneric(performanceBuffer, - ref parameter); - case 2: - return new PerformanceManagerGeneric(performanceBuffer, - ref parameter); - default: - throw new NotImplementedException($"Unknown Performance metrics data format version {version}"); - } + 1 => new PerformanceManagerGeneric(performanceBuffer, ref parameter), + 2 => new PerformanceManagerGeneric(performanceBuffer, ref parameter), + _ => throw new NotImplementedException($"Unknown Performance metrics data format version {version}"), + }; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs index 18e77391d..5a70a1bcf 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs @@ -25,20 +25,20 @@ public class PerformanceManagerGeneric : Performa /// private const int MaxFrameDetailCount = 100; - private Memory _buffer; - private Memory _historyBuffer; + private readonly Memory _buffer; + private readonly Memory _historyBuffer; - private Memory CurrentBuffer => _buffer.Slice(0, _frameSize); - private Memory CurrentBufferData => CurrentBuffer.Slice(Unsafe.SizeOf()); + private Memory CurrentBuffer => _buffer[.._frameSize]; + private Memory CurrentBufferData => CurrentBuffer[Unsafe.SizeOf()..]; private ref THeader CurrentHeader => ref MemoryMarshal.Cast(CurrentBuffer.Span)[0]; - private Span Entries => MemoryMarshal.Cast(CurrentBufferData.Span.Slice(0, GetEntriesSize())); + private Span Entries => MemoryMarshal.Cast(CurrentBufferData.Span[..GetEntriesSize()]); private Span EntriesDetail => MemoryMarshal.Cast(CurrentBufferData.Span.Slice(GetEntriesSize(), GetEntriesDetailSize())); - private int _frameSize; - private int _availableFrameCount; - private int _entryCountPerFrame; + private readonly int _frameSize; + private readonly int _availableFrameCount; + private readonly int _entryCountPerFrame; private int _detailTarget; private int _entryIndex; private int _entryDetailIndex; @@ -56,7 +56,7 @@ public PerformanceManagerGeneric(Memory buffer, ref AudioRendererConfigura _historyFrameIndex = 0; - _historyBuffer = _buffer.Slice(_frameSize); + _historyBuffer = _buffer[_frameSize..]; SetupNewHeader(); } @@ -130,7 +130,7 @@ public override uint CopyHistories(Span performanceOutput) Span inputEntries = GetEntriesFromBuffer(_historyBuffer.Span, _indexHistoryRead); Span inputEntriesDetail = GetEntriesDetailFromBuffer(_historyBuffer.Span, _indexHistoryRead); - Span targetSpan = performanceOutput.Slice(nextOffset); + Span targetSpan = performanceOutput[nextOffset..]; // NOTE: We check for the space for two headers for the final blank header. int requiredSpace = Unsafe.SizeOf() + Unsafe.SizeOf() * inputHeader.GetEntryCount() @@ -146,7 +146,7 @@ public override uint CopyHistories(Span performanceOutput) nextOffset += Unsafe.SizeOf(); - Span outputEntries = MemoryMarshal.Cast(performanceOutput.Slice(nextOffset)); + Span outputEntries = MemoryMarshal.Cast(performanceOutput[nextOffset..]); int totalProcessingTime = 0; @@ -168,7 +168,7 @@ public override uint CopyHistories(Span performanceOutput) } } - Span outputEntriesDetail = MemoryMarshal.Cast(performanceOutput.Slice(nextOffset)); + Span outputEntriesDetail = MemoryMarshal.Cast(performanceOutput[nextOffset..]); int effectiveEntryDetailCount = 0; @@ -198,7 +198,7 @@ public override uint CopyHistories(Span performanceOutput) if (nextOffset < performanceOutput.Length && (performanceOutput.Length - nextOffset) >= Unsafe.SizeOf()) { - ref THeader outputHeader = ref MemoryMarshal.Cast(performanceOutput.Slice(nextOffset))[0]; + ref THeader outputHeader = ref MemoryMarshal.Cast(performanceOutput[nextOffset..])[0]; outputHeader = default; } @@ -208,9 +208,11 @@ public override uint CopyHistories(Span performanceOutput) public override bool GetNextEntry(out PerformanceEntryAddresses performanceEntry, PerformanceEntryType entryType, int nodeId) { - performanceEntry = new PerformanceEntryAddresses(); - performanceEntry.BaseMemory = SpanMemoryManager.Cast(CurrentBuffer); - performanceEntry.EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(); + performanceEntry = new PerformanceEntryAddresses + { + BaseMemory = SpanMemoryManager.Cast(CurrentBuffer), + EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(), + }; uint baseEntryOffset = (uint)(Unsafe.SizeOf() + Unsafe.SizeOf() * _entryIndex); @@ -237,9 +239,11 @@ public override bool GetNextEntry(out PerformanceEntryAddresses performanceEntry return false; } - performanceEntry = new PerformanceEntryAddresses(); - performanceEntry.BaseMemory = SpanMemoryManager.Cast(CurrentBuffer); - performanceEntry.EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(); + performanceEntry = new PerformanceEntryAddresses + { + BaseMemory = SpanMemoryManager.Cast(CurrentBuffer), + EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(), + }; uint baseEntryOffset = (uint)(Unsafe.SizeOf() + GetEntriesSize() + Unsafe.SizeOf() * _entryDetailIndex); @@ -301,4 +305,4 @@ public override void TapFrame(bool dspRunningBehind, uint voiceDropCount, ulong } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs index 164567806..090850018 100644 --- a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs @@ -45,4 +45,4 @@ public sealed class RendererSystemContext /// public Memory DepopBuffer; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/BaseSink.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/BaseSink.cs index f7b639975..d36c5e260 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Sink/BaseSink.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Sink/BaseSink.cs @@ -99,4 +99,4 @@ public virtual void Update(out ErrorInfo errorInfo, ref SinkInParameter paramete errorInfo = new ErrorInfo(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/CircularBufferSink.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/CircularBufferSink.cs index 722d8c4b4..097757988 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Sink/CircularBufferSink.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Sink/CircularBufferSink.cs @@ -106,4 +106,4 @@ public override void CleanUp() base.CleanUp(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs index de345d3ad..e03fe11d4 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs @@ -72,4 +72,4 @@ public override void Update(out BehaviourParameter.ErrorInfo errorInfo, ref Sink outStatus = new SinkOutStatus(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/SinkContext.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/SinkContext.cs index b57d39908..951984d8c 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Sink/SinkContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Sink/SinkContext.cs @@ -53,4 +53,4 @@ public ref BaseSink GetSink(int id) return ref _sinks[id]; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs index 91877cdda..e408692ab 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs @@ -101,10 +101,8 @@ public static ulong GetWorkBufferSize(ulong size, ref BehaviourContext behaviour return size; } - else - { - return size; - } + + return size; } /// @@ -164,10 +162,10 @@ private void UpdateState(scoped ref SplitterInParameterHeader inputHeader, ref R { ref SplitterState splitter = ref GetState(parameter.Id); - splitter.Update(this, ref parameter, input.Slice(Unsafe.SizeOf())); + splitter.Update(this, ref parameter, input[Unsafe.SizeOf()..]); } - input = input.Slice(0x1C + (int)parameter.DestinationCount * 4); + input = input[(0x1C + parameter.DestinationCount * 4)..]; } } } @@ -194,7 +192,7 @@ private void UpdateData(scoped ref SplitterInParameterHeader inputHeader, ref Re destination.Update(parameter); } - input = input.Slice(Unsafe.SizeOf()); + input = input[Unsafe.SizeOf()..]; } } } @@ -229,12 +227,10 @@ public bool Update(ReadOnlySpan input, out int consumedSize) return true; } - else - { - consumedSize = 0; - return false; - } + consumedSize = 0; + + return false; } /// @@ -300,4 +296,4 @@ public void UpdateInternalState() } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs index c074e4a72..1faf7921f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs @@ -65,7 +65,7 @@ private struct MixArray { } /// /// Get the of the next element or if not present. /// - public Span Next + public readonly Span Next { get { @@ -138,7 +138,7 @@ public void MarkAsNeedToUpdateInternalState() /// Return true if the is used and has a destination. /// /// True if the is used and has a destination. - public bool IsConfigured() + public readonly bool IsConfigured() { return IsUsed && DestinationId != Constants.UnusedMixId; } @@ -160,8 +160,8 @@ public float GetMixVolume(int destinationIndex) /// public void ClearVolumes() { - MixBufferVolume.Fill(0); - PreviousMixBufferVolume.Fill(0); + MixBufferVolume.Clear(); + PreviousMixBufferVolume.Clear(); } /// @@ -190,4 +190,4 @@ public void Unlink() } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs index 15a0c6ba4..e08ee9ea7 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs @@ -43,7 +43,7 @@ public struct SplitterState /// /// Span to the first element of the linked list of . /// - public Span Destinations + public readonly Span Destinations { get { @@ -63,7 +63,7 @@ public SplitterState(int id) : this() Id = id; } - public Span GetData(int index) + public readonly Span GetData(int index) { int i = 0; @@ -95,7 +95,7 @@ public void ClearNewConnectionFlag() /// Utility function to apply a given to all . /// /// The action to execute on each elements. - private void ForEachDestination(SpanAction action) + private readonly void ForEachDestination(SpanAction action) { Span temp = Destinations; @@ -183,7 +183,7 @@ public void SetDestination(ref SplitterDestination newValue) /// /// Update the internal state of this instance. /// - public void UpdateInternalState() + public readonly void UpdateInternalState() { ForEachDestination((destination, _) => destination[0].UpdateInternalState()); } @@ -218,4 +218,4 @@ public static void InitializeSplitters(Span splitters) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs index 5cf539c6d..22eebc7cc 100644 --- a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs +++ b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs @@ -22,15 +22,15 @@ namespace Ryujinx.Audio.Renderer.Server public class StateUpdater { private readonly ReadOnlyMemory _inputOrigin; - private ReadOnlyMemory _outputOrigin; + private readonly ReadOnlyMemory _outputOrigin; private ReadOnlyMemory _input; private Memory _output; - private uint _processHandle; + private readonly uint _processHandle; private BehaviourContext _behaviourContext; private UpdateDataHeader _inputHeader; - private Memory _outputHeader; + private readonly Memory _outputHeader; private ref UpdateDataHeader OutputHeader => ref _outputHeader.Span[0]; @@ -45,9 +45,9 @@ public StateUpdater(ReadOnlyMemory input, Memory output, uint proces _inputHeader = SpanIOHelper.Read(ref _input); - _outputHeader = SpanMemoryManager.Cast(_output.Slice(0, Unsafe.SizeOf())); + _outputHeader = SpanMemoryManager.Cast(_output[..Unsafe.SizeOf()]); OutputHeader.Initialize(_behaviourContext.UserRevision); - _output = _output.Slice(Unsafe.SizeOf()); + _output = _output[Unsafe.SizeOf()..]; } public ResultCode UpdateBehaviourContext() @@ -72,7 +72,7 @@ public ResultCode UpdateBehaviourContext() public ResultCode UpdateMemoryPools(Span memoryPools) { - PoolMapper mapper = new PoolMapper(_processHandle, _behaviourContext.IsMemoryPoolForceMappingEnabled()); + PoolMapper mapper = new(_processHandle, _behaviourContext.IsMemoryPoolForceMappingEnabled()); if (memoryPools.Length * Unsafe.SizeOf() != _inputHeader.MemoryPoolsSize) { @@ -136,11 +136,11 @@ public ResultCode UpdateVoices(VoiceContext context, Memory mem int initialOutputSize = _output.Length; - ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Slice(0, (int)_inputHeader.VoicesSize).Span); + ReadOnlySpan parameters = MemoryMarshal.Cast(_input[..(int)_inputHeader.VoicesSize].Span); - _input = _input.Slice((int)_inputHeader.VoicesSize); + _input = _input[(int)_inputHeader.VoicesSize..]; - PoolMapper mapper = new PoolMapper(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); + PoolMapper mapper = new(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); // First make everything not in use. for (int i = 0; i < context.GetCount(); i++) @@ -151,7 +151,7 @@ public ResultCode UpdateVoices(VoiceContext context, Memory mem } Memory[] voiceUpdateStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax); - + Span> voiceUpdateStates = voiceUpdateStatesArray.AsSpan(0, Constants.VoiceChannelCountMax); // Start processing @@ -218,42 +218,20 @@ private static void ResetEffect(ref BaseEffect effect, ref T parameter, PoolM { effect.ForceUnmapBuffers(mapper); - switch (parameter.Type) - { - case EffectType.Invalid: - effect = new BaseEffect(); - break; - case EffectType.BufferMix: - effect = new BufferMixEffect(); - break; - case EffectType.AuxiliaryBuffer: - effect = new AuxiliaryBufferEffect(); - break; - case EffectType.Delay: - effect = new DelayEffect(); - break; - case EffectType.Reverb: - effect = new ReverbEffect(); - break; - case EffectType.Reverb3d: - effect = new Reverb3dEffect(); - break; - case EffectType.BiquadFilter: - effect = new BiquadFilterEffect(); - break; - case EffectType.Limiter: - effect = new LimiterEffect(); - break; - case EffectType.CaptureBuffer: - effect = new CaptureBufferEffect(); - break; - case EffectType.Compressor: - effect = new CompressorEffect(); - break; - - default: - throw new NotImplementedException($"EffectType {parameter.Type} not implemented!"); - } + effect = parameter.Type switch + { + EffectType.Invalid => new BaseEffect(), + EffectType.BufferMix => new BufferMixEffect(), + EffectType.AuxiliaryBuffer => new AuxiliaryBufferEffect(), + EffectType.Delay => new DelayEffect(), + EffectType.Reverb => new ReverbEffect(), + EffectType.Reverb3d => new Reverb3dEffect(), + EffectType.BiquadFilter => new BiquadFilterEffect(), + EffectType.Limiter => new LimiterEffect(), + EffectType.CaptureBuffer => new CaptureBufferEffect(), + EffectType.Compressor => new CompressorEffect(), + _ => throw new NotImplementedException($"EffectType {parameter.Type} not implemented!"), + }; } public ResultCode UpdateEffects(EffectContext context, bool isAudioRendererActive, Memory memoryPools) @@ -262,10 +240,8 @@ public ResultCode UpdateEffects(EffectContext context, bool isAudioRendererActiv { return UpdateEffectsVersion2(context, isAudioRendererActive, memoryPools); } - else - { - return UpdateEffectsVersion1(context, isAudioRendererActive, memoryPools); - } + + return UpdateEffectsVersion1(context, isAudioRendererActive, memoryPools); } public ResultCode UpdateEffectsVersion2(EffectContext context, bool isAudioRendererActive, Memory memoryPools) @@ -277,11 +253,11 @@ public ResultCode UpdateEffectsVersion2(EffectContext context, bool isAudioRende int initialOutputSize = _output.Length; - ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Slice(0, (int)_inputHeader.EffectsSize).Span); + ReadOnlySpan parameters = MemoryMarshal.Cast(_input[..(int)_inputHeader.EffectsSize].Span); - _input = _input.Slice((int)_inputHeader.EffectsSize); + _input = _input[(int)_inputHeader.EffectsSize..]; - PoolMapper mapper = new PoolMapper(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); + PoolMapper mapper = new(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); for (int i = 0; i < context.GetCount(); i++) { @@ -333,11 +309,11 @@ public ResultCode UpdateEffectsVersion1(EffectContext context, bool isAudioRende int initialOutputSize = _output.Length; - ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Slice(0, (int)_inputHeader.EffectsSize).Span); + ReadOnlySpan parameters = MemoryMarshal.Cast(_input[..(int)_inputHeader.EffectsSize].Span); - _input = _input.Slice((int)_inputHeader.EffectsSize); + _input = _input[(int)_inputHeader.EffectsSize..]; - PoolMapper mapper = new PoolMapper(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); + PoolMapper mapper = new(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); for (int i = 0; i < context.GetCount(); i++) { @@ -376,17 +352,15 @@ public ResultCode UpdateSplitter(SplitterContext context) { if (context.Update(_input.Span, out int consumedSize)) { - _input = _input.Slice(consumedSize); + _input = _input[consumedSize..]; return ResultCode.Success; } - else - { - return ResultCode.InvalidUpdateInfo; - } + + return ResultCode.InvalidUpdateInfo; } - private bool CheckMixParametersValidity(MixContext mixContext, uint mixBufferCount, uint inputMixCount, ReadOnlySpan parameters) + private static bool CheckMixParametersValidity(MixContext mixContext, uint mixBufferCount, uint inputMixCount, ReadOnlySpan parameters) { uint maxMixStateCount = mixContext.GetCount(); uint totalRequiredMixBufferCount = 0; @@ -439,12 +413,12 @@ public ResultCode UpdateMixes(MixContext mixContext, uint mixBufferCount, Effect if (_behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported()) { - _input = _input.Slice(Unsafe.SizeOf()); + _input = _input[Unsafe.SizeOf()..]; } - ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Span.Slice(0, (int)inputMixSize)); + ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Span[..(int)inputMixSize]); - _input = _input.Slice((int)inputMixSize); + _input = _input[(int)inputMixSize..]; if (CheckMixParametersValidity(mixContext, mixBufferCount, mixCount, parameters)) { @@ -506,25 +480,18 @@ private static void ResetSink(ref BaseSink sink, ref SinkInParameter parameter) { sink.CleanUp(); - switch (parameter.Type) - { - case SinkType.Invalid: - sink = new BaseSink(); - break; - case SinkType.CircularBuffer: - sink = new CircularBufferSink(); - break; - case SinkType.Device: - sink = new DeviceSink(); - break; - default: - throw new NotImplementedException($"SinkType {parameter.Type} not implemented!"); - } + sink = parameter.Type switch + { + SinkType.Invalid => new BaseSink(), + SinkType.CircularBuffer => new CircularBufferSink(), + SinkType.Device => new DeviceSink(), + _ => throw new NotImplementedException($"SinkType {parameter.Type} not implemented!"), + }; } public ResultCode UpdateSinks(SinkContext context, Memory memoryPools) { - PoolMapper mapper = new PoolMapper(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); + PoolMapper mapper = new(_processHandle, memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.SinksSize) { @@ -533,9 +500,9 @@ public ResultCode UpdateSinks(SinkContext context, Memory memor int initialOutputSize = _output.Length; - ReadOnlySpan parameters = MemoryMarshal.Cast(_input.Slice(0, (int)_inputHeader.SinksSize).Span); + ReadOnlySpan parameters = MemoryMarshal.Cast(_input[..(int)_inputHeader.SinksSize].Span); - _input = _input.Slice((int)_inputHeader.SinksSize); + _input = _input[(int)_inputHeader.SinksSize..]; for (int i = 0; i < context.GetCount(); i++) { @@ -640,4 +607,4 @@ public ResultCode CheckConsumedSize() return ResultCode.Success; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererExecutionMode.cs b/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererExecutionMode.cs index 5d82ce0b6..0db61c5e6 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererExecutionMode.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererExecutionMode.cs @@ -14,6 +14,6 @@ public enum AudioRendererExecutionMode : byte /// Audio renderer operation needs to be done manually via ExecuteAudioRenderer. /// /// This is not supported on the DSP and is as such stubbed. - Manual + Manual, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererRenderingDevice.cs b/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererRenderingDevice.cs index 5ad27b0b1..fd9e231cf 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererRenderingDevice.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Types/AudioRendererRenderingDevice.cs @@ -19,6 +19,6 @@ public enum AudioRendererRenderingDevice : byte /// /// Only supports . /// - Cpu + Cpu, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs index 25cc34a8f..46aae05ab 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs @@ -34,6 +34,6 @@ public enum PlayState /// /// The user can resume to the state. /// - Paused + Paused, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerBufferState.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerBufferState.cs index a45fa8e5b..a3c442a45 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerBufferState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerBufferState.cs @@ -11,4 +11,4 @@ public struct UpsamplerBufferState public bool Initialized; public int Phase; } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs index b37988fed..dbc2c9b3f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs @@ -11,22 +11,22 @@ public class UpsamplerManager /// /// Work buffer for upsampler. /// - private Memory _upSamplerWorkBuffer; + private readonly Memory _upSamplerWorkBuffer; /// /// Global lock of the object. /// - private object Lock = new object(); + private readonly object _lock = new(); /// /// The upsamplers instances. /// - private UpsamplerState[] _upsamplers; + private readonly UpsamplerState[] _upsamplers; /// /// The count of upsamplers. /// - private uint _count; + private readonly uint _count; /// /// Create a new . @@ -49,7 +49,7 @@ public UpsamplerState Allocate() { int workBufferOffset = 0; - lock (Lock) + lock (_lock) { for (int i = 0; i < _count; i++) { @@ -73,7 +73,7 @@ public UpsamplerState Allocate() /// The index of the to free. public void Free(int index) { - lock (Lock) + lock (_lock) { Debug.Assert(_upsamplers[index] != null); @@ -81,4 +81,4 @@ public void Free(int index) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs index e508f35b4..39a58c91a 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs @@ -20,12 +20,12 @@ public class UpsamplerState /// /// The index of the . (used to free it) /// - private int _index; + private readonly int _index; /// /// The . /// - private UpsamplerManager _manager; + private readonly UpsamplerManager _manager; /// /// The source sample count. @@ -65,4 +65,4 @@ public void Release() _manager.Free(_index); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceChannelResource.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceChannelResource.cs index 939d92944..e3d5f797d 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceChannelResource.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceChannelResource.cs @@ -37,4 +37,4 @@ public void UpdateState() Mix.AsSpan().CopyTo(PreviousMix.AsSpan()); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs index 1c57b71be..7ce7143ed 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs @@ -126,7 +126,7 @@ public void Sort() _sortedVoices.Span[i] = i; } - int[] sortedVoicesTemp = _sortedVoices.Slice(0, (int)GetCount()).ToArray(); + int[] sortedVoicesTemp = _sortedVoices[..(int)GetCount()].ToArray(); Array.Sort(sortedVoicesTemp, (a, b) => { @@ -146,4 +146,4 @@ public void Sort() sortedVoicesTemp.AsSpan().CopyTo(_sortedVoices.Span); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs index 0bf53c544..225f7d31b 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs @@ -1,5 +1,6 @@ using Ryujinx.Audio.Common; using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Server.MemoryPool; using Ryujinx.Common.Memory; @@ -9,6 +10,7 @@ using System.Runtime.InteropServices; using static Ryujinx.Audio.Renderer.Common.BehaviourParameter; using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter; +using PlayState = Ryujinx.Audio.Renderer.Server.Types.PlayState; namespace Ryujinx.Audio.Renderer.Server.Voice { @@ -65,12 +67,12 @@ public struct VoiceState /// /// The current voice . /// - public Types.PlayState PlayState; + public PlayState PlayState; /// /// The previous voice . /// - public Types.PlayState PreviousPlayState; + public PlayState PreviousPlayState; /// /// The priority of the voice. @@ -192,7 +194,7 @@ public void Initialize() DataSourceStateUnmapped = false; BufferInfoUnmapped = false; FlushWaveBufferCount = 0; - PlayState = Types.PlayState.Stopped; + PlayState = PlayState.Stopped; Priority = Constants.VoiceLowestPriority; Id = 0; NodeId = 0; @@ -202,7 +204,7 @@ public void Initialize() Pitch = 0.0f; Volume = 0.0f; PreviousVolume = 0.0f; - BiquadFilters.AsSpan().Fill(new BiquadFilterParameter()); + BiquadFilters.AsSpan().Clear(); WaveBuffersCount = 0; WaveBuffersIndex = 0; MixId = Constants.UnusedMixId; @@ -233,7 +235,7 @@ private void InitializeWaveBuffers() /// Check if the voice needs to be skipped. /// /// Returns true if the voice needs to be skipped. - public bool ShouldSkip() + public readonly bool ShouldSkip() { return !InUse || WaveBuffersCount == 0 || DataSourceStateUnmapped || BufferInfoUnmapped || VoiceDropFlag; } @@ -242,7 +244,7 @@ public bool ShouldSkip() /// Return true if the mix has any destinations. /// /// True if the mix has any destinations. - public bool HasAnyDestination() + public readonly bool HasAnyDestination() { return MixId != Constants.UnusedMixId || SplitterId != Constants.UnusedSplitterId; } @@ -252,7 +254,7 @@ public bool HasAnyDestination() /// /// The user parameter. /// Return true, if the server voice information needs to be updated. - private bool ShouldUpdateParameters(ref VoiceInParameter parameter) + private readonly bool ShouldUpdateParameters(ref VoiceInParameter parameter) { if (DataSourceStateAddressInfo.CpuAddress == parameter.DataSourceStateAddress) { @@ -338,31 +340,31 @@ public void UpdateParameters(out ErrorInfo outErrorInfo, ref VoiceInParameter pa /// Update the internal play state from user play state. /// /// The target user play state. - public void UpdatePlayState(PlayState userPlayState) + public void UpdatePlayState(Common.PlayState userPlayState) { - Types.PlayState oldServerPlayState = PlayState; + PlayState oldServerPlayState = PlayState; PreviousPlayState = oldServerPlayState; - Types.PlayState newServerPlayState; + PlayState newServerPlayState; switch (userPlayState) { case Common.PlayState.Start: - newServerPlayState = Types.PlayState.Started; + newServerPlayState = PlayState.Started; break; case Common.PlayState.Stop: - if (oldServerPlayState == Types.PlayState.Stopped) + if (oldServerPlayState == PlayState.Stopped) { return; } - newServerPlayState = Types.PlayState.Stopping; + newServerPlayState = PlayState.Stopping; break; case Common.PlayState.Pause: - newServerPlayState = Types.PlayState.Paused; + newServerPlayState = PlayState.Paused; break; default: @@ -434,7 +436,7 @@ public void UpdateWaveBuffers(out ErrorInfo[] errorInfos, ref VoiceInParameter p for (int i = 0; i < parameter.ChannelCount; i++) { - voiceUpdateStates[i].Span[0].IsWaveBufferValid.Fill(false); + voiceUpdateStates[i].Span[0].IsWaveBufferValid.Clear(); } } @@ -530,7 +532,7 @@ private void ResetResources(VoiceContext context) Memory dspSharedState = context.GetUpdateStateForDsp(channelResourceId); - MemoryMarshal.Cast(dspSharedState.Span).Fill(0); + MemoryMarshal.Cast(dspSharedState.Span).Clear(); voiceChannelResource.UpdateState(); } @@ -579,7 +581,7 @@ public bool UpdateParametersForCommandGeneration(Memory[] voic switch (PlayState) { - case Types.PlayState.Started: + case PlayState.Started: for (int i = 0; i < WaveBuffers.Length; i++) { ref WaveBuffer wavebuffer = ref WaveBuffers[i]; @@ -611,7 +613,7 @@ public bool UpdateParametersForCommandGeneration(Memory[] voic return false; - case Types.PlayState.Stopping: + case PlayState.Stopping: for (int i = 0; i < WaveBuffers.Length; i++) { ref WaveBuffer wavebuffer = ref WaveBuffers[i]; @@ -638,18 +640,18 @@ public bool UpdateParametersForCommandGeneration(Memory[] voic voiceUpdateState.Offset = 0; voiceUpdateState.PlayedSampleCount = 0; - voiceUpdateState.Pitch.AsSpan().Fill(0); + voiceUpdateState.Pitch.AsSpan().Clear(); voiceUpdateState.Fraction = 0; - voiceUpdateState.LoopContext = new Dsp.State.AdpcmLoopContext(); + voiceUpdateState.LoopContext = new AdpcmLoopContext(); } - PlayState = Types.PlayState.Stopped; - WasPlaying = PreviousPlayState == Types.PlayState.Started; + PlayState = PlayState.Stopped; + WasPlaying = PreviousPlayState == PlayState.Started; return WasPlaying; - case Types.PlayState.Stopped: - case Types.PlayState.Paused: + case PlayState.Stopped: + case PlayState.Paused: foreach (ref WaveBuffer wavebuffer in WaveBuffers.AsSpan()) { wavebuffer.BufferAddressInfo.GetReference(true); @@ -664,7 +666,7 @@ public bool UpdateParametersForCommandGeneration(Memory[] voic } } - WasPlaying = PreviousPlayState == Types.PlayState.Started; + WasPlaying = PreviousPlayState == PlayState.Started; return WasPlaying; default: @@ -696,4 +698,4 @@ public bool UpdateForCommandGeneration(VoiceContext context) return UpdateParametersForCommandGeneration(voiceUpdateStates); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/WaveBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/WaveBuffer.cs index 4bf7dd280..a9946ba44 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Voice/WaveBuffer.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Voice/WaveBuffer.cs @@ -71,10 +71,11 @@ public struct WaveBuffer /// A new for use by the . public Common.WaveBuffer ToCommon(int version) { - Common.WaveBuffer waveBuffer = new Common.WaveBuffer(); - - waveBuffer.Buffer = BufferAddressInfo.GetReference(true); - waveBuffer.BufferSize = (uint)BufferAddressInfo.Size; + Common.WaveBuffer waveBuffer = new() + { + Buffer = BufferAddressInfo.GetReference(true), + BufferSize = (uint)BufferAddressInfo.Size, + }; if (ContextAddressInfo.CpuAddress != 0) { @@ -101,4 +102,4 @@ public Common.WaveBuffer ToCommon(int version) return waveBuffer; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/AudioProcessorMemoryManager.cs b/src/Ryujinx.Audio/Renderer/Utils/AudioProcessorMemoryManager.cs index 973f0672a..8ebf20340 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/AudioProcessorMemoryManager.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/AudioProcessorMemoryManager.cs @@ -54,4 +54,4 @@ public static void InvalidateDataCache(CpuAddress address, ulong size) { } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/BitArray.cs b/src/Ryujinx.Audio/Renderer/Utils/BitArray.cs index 8b1054771..8fd0baeae 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/BitArray.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/BitArray.cs @@ -11,7 +11,7 @@ public class BitArray /// /// The backing storage of the . /// - private Memory _storage; + private readonly Memory _storage; /// /// Create a new from . @@ -97,7 +97,7 @@ private void Set(int index, bool value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Reset() { - _storage.Span.Fill(0); + _storage.Span.Clear(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs b/src/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs index d49313ea1..bc2313ccf 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.Runtime.InteropServices; -using System.Text; namespace Ryujinx.Audio.Renderer.Utils { @@ -12,8 +11,8 @@ namespace Ryujinx.Audio.Renderer.Utils public class FileHardwareDevice : IHardwareDevice { private FileStream _stream; - private uint _channelCount; - private uint _sampleRate; + private readonly uint _channelCount; + private readonly uint _sampleRate; private const int HeaderSize = 44; @@ -82,6 +81,7 @@ public uint GetSampleRate() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -96,4 +96,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/Mailbox.cs b/src/Ryujinx.Audio/Renderer/Utils/Mailbox.cs index 35c71ae36..26907af91 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/Mailbox.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/Mailbox.cs @@ -9,8 +9,8 @@ namespace Ryujinx.Audio.Renderer.Utils /// The target unmanaged type used public class Mailbox : IDisposable where T : unmanaged { - private BlockingCollection _messageQueue; - private BlockingCollection _responseQueue; + private readonly BlockingCollection _messageQueue; + private readonly BlockingCollection _responseQueue; public Mailbox() { @@ -40,6 +40,7 @@ public T ReceiveResponse() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -52,4 +53,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix2x2.cs b/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix2x2.cs index 5b513aff3..7a6edab19 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix2x2.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix2x2.cs @@ -68,4 +68,4 @@ public Matrix2x2(float m11, float m12, return m; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix6x6.cs b/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix6x6.cs index 415a81fdf..ff0123026 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix6x6.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/Math/Matrix6x6.cs @@ -94,4 +94,4 @@ public Matrix6x6(float m11, float m12, float m13, float m14, float m15, float m1 M66 = m66; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/Math/MatrixHelper.cs b/src/Ryujinx.Audio/Renderer/Utils/Math/MatrixHelper.cs index 209a81c46..7b4b7ad1d 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/Math/MatrixHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/Math/MatrixHelper.cs @@ -28,7 +28,7 @@ public static Vector4 Transform(ref Vector4 value1, ref Matrix4x4 value2) X = value2.M11 * value1.X + value2.M12 * value1.Y + value2.M13 * value1.Z + value2.M14 * value1.W, Y = value2.M21 * value1.X + value2.M22 * value1.Y + value2.M23 * value1.Z + value2.M24 * value1.W, Z = value2.M31 * value1.X + value2.M32 * value1.Y + value2.M33 * value1.Z + value2.M34 * value1.W, - W = value2.M41 * value1.X + value2.M42 * value1.Y + value2.M43 * value1.Z + value2.M44 * value1.W + W = value2.M41 * value1.X + value2.M42 * value1.Y + value2.M43 * value1.Z + value2.M44 * value1.W, }; } @@ -42,4 +42,4 @@ public static Vector2 Transform(ref Vector2 value1, ref Matrix2x2 value2) }; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/Math/Vector6.cs b/src/Ryujinx.Audio/Renderer/Utils/Math/Vector6.cs index 81bcb6982..303c5e9d0 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/Math/Vector6.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/Math/Vector6.cs @@ -53,4 +53,4 @@ public Vector6(float x, float y, float z, float w, float v, float u) return left * new Vector6(right); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/SpanIOHelper.cs b/src/Ryujinx.Audio/Renderer/Utils/SpanIOHelper.cs index 103fb6a04..abbb6ea6c 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/SpanIOHelper.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/SpanIOHelper.cs @@ -22,12 +22,12 @@ public static void Write(ref Memory backingMemory, ref T data) where T if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - MemoryMarshal.Write(backingMemory.Span.Slice(0, size), ref data); + MemoryMarshal.Write(backingMemory.Span[..size], in data); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; } /// @@ -42,12 +42,12 @@ public static void Write(ref Span backingMemory, ref T data) where T : if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - MemoryMarshal.Write(backingMemory.Slice(0, size), ref data); + MemoryMarshal.Write(backingMemory[..size], in data); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; } /// @@ -62,12 +62,12 @@ public static Span GetWriteRef(ref Memory backingMemory) where T : u if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - Span result = MemoryMarshal.Cast(backingMemory.Span.Slice(0, size)); + Span result = MemoryMarshal.Cast(backingMemory.Span[..size]); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; return result; } @@ -84,12 +84,12 @@ public static Span GetWriteRef(ref Span backingMemory) where T : unm if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - Span result = MemoryMarshal.Cast(backingMemory.Slice(0, size)); + Span result = MemoryMarshal.Cast(backingMemory[..size]); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; return result; } @@ -106,12 +106,12 @@ public static T Read(ref ReadOnlyMemory backingMemory) where T : unmana if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - T result = MemoryMarshal.Read(backingMemory.Span.Slice(0, size)); + T result = MemoryMarshal.Read(backingMemory.Span[..size]); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; return result; } @@ -128,12 +128,12 @@ public static T Read(ref ReadOnlySpan backingMemory) where T : unmanage if (size > backingMemory.Length) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(backingMemory), backingMemory.Length, null); } - T result = MemoryMarshal.Read(backingMemory.Slice(0, size)); + T result = MemoryMarshal.Read(backingMemory[..size]); - backingMemory = backingMemory.Slice(size); + backingMemory = backingMemory[size..]; return result; } @@ -168,4 +168,4 @@ public static ref T GetFromMemory(Memory memory, int id, uint count) where return ref GetMemory(memory, id, count).Span[0]; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/SpanMemoryManager.cs b/src/Ryujinx.Audio/Renderer/Utils/SpanMemoryManager.cs index 2c48da6aa..b6bafbe0f 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/SpanMemoryManager.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/SpanMemoryManager.cs @@ -19,7 +19,7 @@ public SpanMemoryManager(Span span) } } - public override Span GetSpan() => new Span(_pointer, _length); + public override Span GetSpan() => new(_pointer, _length); public override MemoryHandle Pin(int elementIndex = 0) { @@ -40,4 +40,4 @@ public static Memory Cast(Memory memory) where TFrom : unmanage return new SpanMemoryManager(MemoryMarshal.Cast(memory.Span)).Memory; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs b/src/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs index 183960789..32d50e12f 100644 --- a/src/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs +++ b/src/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs @@ -5,8 +5,8 @@ namespace Ryujinx.Audio.Renderer.Utils { public class SplitterHardwareDevice : IHardwareDevice { - private IHardwareDevice _baseDevice; - private IHardwareDevice _secondaryDevice; + private readonly IHardwareDevice _baseDevice; + private readonly IHardwareDevice _secondaryDevice; public SplitterHardwareDevice(IHardwareDevice baseDevice, IHardwareDevice secondaryDevice) { @@ -43,6 +43,7 @@ public uint GetSampleRate() public void Dispose() { + GC.SuppressFinalize(this); Dispose(true); } @@ -55,4 +56,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/ResultCode.cs b/src/Ryujinx.Audio/ResultCode.cs index 1d05ac65e..eab27c16d 100644 --- a/src/Ryujinx.Audio/ResultCode.cs +++ b/src/Ryujinx.Audio/ResultCode.cs @@ -19,4 +19,4 @@ public enum ResultCode UnsupportedOperation = (513 << ErrorCodeShift) | ModuleId, InvalidExecutionContextOperation = (514 << ErrorCodeShift) | ModuleId, } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Audio/Ryujinx.Audio.csproj b/src/Ryujinx.Audio/Ryujinx.Audio.csproj index 4a159eb5c..fc20f4ec4 100644 --- a/src/Ryujinx.Audio/Ryujinx.Audio.csproj +++ b/src/Ryujinx.Audio/Ryujinx.Audio.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 true diff --git a/src/Ryujinx.Ava/App.axaml b/src/Ryujinx.Ava/App.axaml index 72bc0deee..eab318b7b 100644 --- a/src/Ryujinx.Ava/App.axaml +++ b/src/Ryujinx.Ava/App.axaml @@ -3,7 +3,15 @@ xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sty="using:FluentAvalonia.Styling"> + + + + + + + + \ No newline at end of file diff --git a/src/Ryujinx.Ava/App.axaml.cs b/src/Ryujinx.Ava/App.axaml.cs index e36cbfdd6..c1a3ab3e2 100644 --- a/src/Ryujinx.Ava/App.axaml.cs +++ b/src/Ryujinx.Ava/App.axaml.cs @@ -3,9 +3,7 @@ using Avalonia.Markup.Xaml; using Avalonia.Styling; using Avalonia.Threading; -using FluentAvalonia.Styling; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Windows; using Ryujinx.Common; @@ -25,6 +23,11 @@ public override void Initialize() Name = $"Ryujinx {Program.Version}"; AvaloniaXamlLoader.Load(this); + + if (OperatingSystem.IsMacOS()) + { + Process.Start("/usr/bin/defaults", "write org.ryujinx.Ryujinx ApplePressAndHoldEnabled -bool false"); + } } public override void OnFrameworkInitializationCompleted() @@ -67,7 +70,7 @@ private void ShowRestartDialog() if (result == UserResult.Yes) { - var path = Process.GetCurrentProcess().MainModule.FileName; + var path = Environment.ProcessPath; var proc = Process.Start(path, CommandLineState.Arguments); desktop.Shutdown(); Environment.Exit(0); @@ -90,8 +93,6 @@ private void ApplyConfiguredTheme() string themePath = ConfigurationState.Instance.Ui.CustomThemePath; bool enableCustomTheme = ConfigurationState.Instance.Ui.EnableCustomTheme; - const string BaseStyleUrl = "avares://Ryujinx.Ava/Assets/Styles/Base{0}.xaml"; - if (string.IsNullOrWhiteSpace(baseStyle)) { ConfigurationState.Instance.Ui.BaseStyle.Value = "Dark"; @@ -99,31 +100,12 @@ private void ApplyConfiguredTheme() baseStyle = ConfigurationState.Instance.Ui.BaseStyle; } - var theme = AvaloniaLocator.Current.GetService(); - - theme.RequestedTheme = baseStyle; - - var currentStyles = this.Styles; - - // Remove all styles except the base style. - if (currentStyles.Count > 1) + RequestedThemeVariant = baseStyle switch { - currentStyles.RemoveRange(1, currentStyles.Count - 1); - } - - IStyle newStyles = null; - - // Load requested style, and fallback to Dark theme if loading failed. - try - { - newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, baseStyle), UriKind.Absolute)); - } - catch (XamlLoadException) - { - newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, "Dark"), UriKind.Absolute)); - } - - currentStyles.Add(newStyles); + "Light" => ThemeVariant.Light, + "Dark" => ThemeVariant.Dark, + _ => ThemeVariant.Default, + }; if (enableCustomTheme) { @@ -134,7 +116,7 @@ private void ApplyConfiguredTheme() var themeContent = File.ReadAllText(themePath); var customStyle = AvaloniaRuntimeXamlLoader.Parse(themeContent); - currentStyles.Add(customStyle); + Styles.Add(customStyle); } catch (Exception ex) { @@ -151,4 +133,4 @@ private void ApplyConfiguredTheme() } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs index e11a954d8..e434deb0a 100644 --- a/src/Ryujinx.Ava/AppHost.cs +++ b/src/Ryujinx.Ava/AppHost.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Translation; +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; @@ -19,6 +19,7 @@ using Ryujinx.Ava.UI.Windows; using Ryujinx.Common; using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; using Ryujinx.Common.SystemInterop; using Ryujinx.Graphics.GAL; @@ -26,15 +27,18 @@ using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; +using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; 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 SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; @@ -47,10 +51,13 @@ using System.Threading; using System.Threading.Tasks; using static Ryujinx.Ava.UI.Helpers.Win32NativeInterop; +using AntiAliasing = Ryujinx.Common.Configuration.AntiAliasing; using Image = SixLabors.ImageSharp.Image; using InputManager = Ryujinx.Input.HLE.InputManager; +using IRenderer = Ryujinx.Graphics.GAL.IRenderer; using Key = Ryujinx.Input.Key; using MouseButton = Ryujinx.Input.MouseButton; +using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter; using Size = Avalonia.Size; using Switch = Ryujinx.HLE.Switch; @@ -58,45 +65,47 @@ namespace Ryujinx.Ava { internal class AppHost { - private const int CursorHideIdleTime = 5; // Hide Cursor seconds. + private const int CursorHideIdleTime = 5; // Hide Cursor seconds. private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping. - private const int TargetFps = 60; - private const float VolumeDelta = 0.05f; + private const int TargetFps = 60; + private const float VolumeDelta = 0.05f; - private static readonly Cursor InvisibleCursor = new(StandardCursorType.None); - private readonly IntPtr InvisibleCursorWin; - private readonly IntPtr DefaultCursorWin; + private static readonly Cursor _invisibleCursor = new(StandardCursorType.None); + private readonly IntPtr _invisibleCursorWin; + private readonly IntPtr _defaultCursorWin; - private readonly long _ticksPerFrame; + private readonly long _ticksPerFrame; private readonly Stopwatch _chrono; - private long _ticks; + private long _ticks; - private readonly AccountManager _accountManager; + private readonly AccountManager _accountManager; private readonly UserChannelPersistence _userChannelPersistence; - private readonly InputManager _inputManager; + private readonly InputManager _inputManager; private readonly MainWindowViewModel _viewModel; - private readonly IKeyboard _keyboardInterface; - private readonly TopLevel _topLevel; - public RendererHost _rendererHost; + private readonly IKeyboard _keyboardInterface; + private readonly TopLevel _topLevel; + public RendererHost RendererHost; private readonly GraphicsDebugLevel _glLogLevel; - private float _newVolume; - private KeyboardHotkeyState _prevHotkeyState; + private float _newVolume; + private KeyboardHotkeyState _prevHotkeyState; private long _lastCursorMoveTime; - private bool _isCursorInRenderer; + private bool _isCursorInRenderer = true; private bool _isStopped; private bool _isActive; private bool _renderingStarted; - private IRenderer _renderer; - private readonly Thread _renderingThread; + private readonly ManualResetEvent _gpuDoneEvent; + + private IRenderer _renderer; + private readonly Thread _renderingThread; private readonly CancellationTokenSource _gpuCancellationTokenSource; private WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution; - private bool _dialogShown; + private bool _dialogShown; private readonly bool _isFirmwareTitle; private readonly object _lockObject = new(); @@ -104,114 +113,128 @@ internal class AppHost public event EventHandler AppExit; public event EventHandler StatusUpdatedEvent; - public VirtualFileSystem VirtualFileSystem { get; } - public ContentManager ContentManager { get; } - public NpadManager NpadManager { get; } + public VirtualFileSystem VirtualFileSystem { get; } + public ContentManager ContentManager { get; } + public NpadManager NpadManager { get; } public TouchScreenManager TouchScreenManager { get; } - public Switch Device { get; set; } + public Switch Device { get; set; } - public int Width { get; private set; } - public int Height { get; private set; } - public string ApplicationPath { get; private set; } - public bool ScreenshotRequested { get; set; } + public int Width { get; private set; } + public int Height { get; private set; } + public string ApplicationPath { get; private set; } + public bool ScreenshotRequested { get; set; } public AppHost( - RendererHost renderer, - InputManager inputManager, - string applicationPath, - VirtualFileSystem virtualFileSystem, - ContentManager contentManager, - AccountManager accountManager, + RendererHost renderer, + InputManager inputManager, + string applicationPath, + VirtualFileSystem virtualFileSystem, + ContentManager contentManager, + AccountManager accountManager, UserChannelPersistence userChannelPersistence, - MainWindowViewModel viewmodel, - TopLevel topLevel) + MainWindowViewModel viewmodel, + TopLevel topLevel) { - _viewModel = viewmodel; - _inputManager = inputManager; - _accountManager = accountManager; + _viewModel = viewmodel; + _inputManager = inputManager; + _accountManager = accountManager; _userChannelPersistence = userChannelPersistence; - _renderingThread = new Thread(RenderLoop, 1 * 1024 * 1024) { Name = "GUI.RenderThread" }; - _lastCursorMoveTime = Stopwatch.GetTimestamp(); - _glLogLevel = ConfigurationState.Instance.Logger.GraphicsDebugLevel; - _topLevel = topLevel; + _renderingThread = new Thread(RenderLoop) { Name = "GUI.RenderThread" }; + _lastCursorMoveTime = Stopwatch.GetTimestamp(); + _glLogLevel = ConfigurationState.Instance.Logger.GraphicsDebugLevel; + _topLevel = topLevel; _inputManager.SetMouseDriver(new AvaloniaMouseDriver(_topLevel, renderer)); _keyboardInterface = (IKeyboard)_inputManager.KeyboardDriver.GetGamepad("0"); - NpadManager = _inputManager.CreateNpadManager(); + NpadManager = _inputManager.CreateNpadManager(); TouchScreenManager = _inputManager.CreateTouchScreenManager(); - ApplicationPath = applicationPath; - VirtualFileSystem = virtualFileSystem; - ContentManager = contentManager; + ApplicationPath = applicationPath; + VirtualFileSystem = virtualFileSystem; + ContentManager = contentManager; - _rendererHost = renderer; + RendererHost = renderer; - _chrono = new Stopwatch(); + _chrono = new Stopwatch(); _ticksPerFrame = Stopwatch.Frequency / TargetFps; if (ApplicationPath.StartsWith("@SystemContent")) { - ApplicationPath = _viewModel.VirtualFileSystem.SwitchPathToSystemPath(ApplicationPath); + ApplicationPath = VirtualFileSystem.SwitchPathToSystemPath(ApplicationPath); _isFirmwareTitle = true; } ConfigurationState.Instance.HideCursor.Event += HideCursorState_Changed; - _topLevel.PointerMoved += TopLevel_PointerMoved; + _topLevel.PointerMoved += TopLevel_PointerEnteredOrMoved; + _topLevel.PointerEntered += TopLevel_PointerEnteredOrMoved; + _topLevel.PointerExited += TopLevel_PointerExited; if (OperatingSystem.IsWindows()) { - InvisibleCursorWin = CreateEmptyCursor(); - DefaultCursorWin = CreateArrowCursor(); + _invisibleCursorWin = CreateEmptyCursor(); + _defaultCursorWin = CreateArrowCursor(); } ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState; - ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState; - ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState; - ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; - ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState; - ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; - ConfigurationState.Instance.Graphics.AntiAliasing.Event += UpdateAntiAliasing; - ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter; - ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel; - - ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState; + ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState; + ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState; + ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; + ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState; + ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; + ConfigurationState.Instance.Graphics.AntiAliasing.Event += UpdateAntiAliasing; + ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter; + ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel; + ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event += UpdateColorSpacePassthrough; + + ConfigurationState.Instance.System.EnableInternetAccess.Event += UpdateEnableInternetAccessState; + ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState; + ConfigurationState.Instance.Multiplayer.Mode.Event += UpdateMultiplayerModeState; _gpuCancellationTokenSource = new CancellationTokenSource(); + _gpuDoneEvent = new ManualResetEvent(false); } - private void TopLevel_PointerMoved(object sender, PointerEventArgs e) + private void TopLevel_PointerEnteredOrMoved(object sender, PointerEventArgs e) { if (sender is MainWindow window) { _lastCursorMoveTime = Stopwatch.GetTimestamp(); - if (_rendererHost.EmbeddedWindow.TransformedBounds != null) - { - var point = e.GetCurrentPoint(window).Position; - var bounds = _rendererHost.EmbeddedWindow.TransformedBounds.Value.Clip; + var point = e.GetCurrentPoint(window).Position; + var bounds = RendererHost.EmbeddedWindow.Bounds; - _isCursorInRenderer = point.X >= bounds.X && - point.X <= bounds.Width + bounds.X && - point.Y >= bounds.Y && - point.Y <= bounds.Height + bounds.Y; - } + _isCursorInRenderer = point.X >= bounds.X && + point.X <= bounds.Width + bounds.X && + point.Y >= bounds.Y && + point.Y <= bounds.Height + bounds.Y; } } + + private void TopLevel_PointerExited(object sender, PointerEventArgs e) + { + _isCursorInRenderer = false; + } + 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); } - private void UpdateScalingFilter(object sender, ReactiveEventArgs e) + 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); } + private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs e) + { + _renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value); + } + private void ShowCursor() { Dispatcher.UIThread.Post(() => @@ -220,7 +243,7 @@ private void ShowCursor() if (OperatingSystem.IsWindows()) { - SetCursor(DefaultCursorWin); + SetCursor(_defaultCursorWin); } }); } @@ -229,11 +252,11 @@ private void HideCursor() { Dispatcher.UIThread.Post(() => { - _viewModel.Cursor = InvisibleCursor; + _viewModel.Cursor = _invisibleCursor; if (OperatingSystem.IsWindows()) { - SetCursor(InvisibleCursorWin); + SetCursor(_invisibleCursorWin); } }); } @@ -242,7 +265,7 @@ private void SetRendererWindowSize(Size size) { if (_renderer != null) { - double scale = _topLevel.PlatformImpl.RenderScaling; + double scale = _topLevel.RenderScaling; _renderer.Window?.SetSize((int)(size.Width * scale), (int)(size.Height * scale)); } @@ -257,12 +280,12 @@ private void Renderer_ScreenCaptured(object sender, ScreenCaptureImageInfo e) lock (_lockObject) { DateTime currentTime = DateTime.Now; - string filename = $"ryujinx_capture_{currentTime.Year}-{currentTime.Month:D2}-{currentTime.Day:D2}_{currentTime.Hour:D2}-{currentTime.Minute:D2}-{currentTime.Second:D2}.png"; + string filename = $"ryujinx_capture_{currentTime.Year}-{currentTime.Month:D2}-{currentTime.Day:D2}_{currentTime.Hour:D2}-{currentTime.Minute:D2}-{currentTime.Second:D2}.png"; string directory = AppDataManager.Mode switch { - AppDataManager.LaunchMode.Portable => Path.Combine(AppDataManager.BaseDirPath, "screenshots"), - _ => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Ryujinx") + AppDataManager.LaunchMode.Portable or AppDataManager.LaunchMode.Custom => Path.Combine(AppDataManager.BaseDirPath, "screenshots"), + _ => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Ryujinx"), }; string path = Path.Combine(directory, filename); @@ -291,9 +314,9 @@ private void Renderer_ScreenCaptured(object sender, ScreenCaptureImageInfo e) image.Mutate(x => x.Flip(FlipMode.Vertical)); } - image.SaveAsPng(path, new PngEncoder() + image.SaveAsPng(path, new PngEncoder { - ColorType = PngColorType.Rgb + ColorType = PngColorType.Rgb, }); image.Dispose(); @@ -322,21 +345,14 @@ public void Start() _viewModel.IsGameRunning = true; - var activeProcess = Device.Processes.ActiveApplication; - - string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; - string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; - string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; - string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; - Dispatcher.UIThread.InvokeAsync(() => { - _viewModel.Title = $"Ryujinx {Program.Version} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version); }); - _viewModel.SetUIProgressHandlers(Device); + _viewModel.SetUiProgressHandlers(Device); - _rendererHost.SizeChanged += Window_SizeChanged; + RendererHost.BoundsChanged += Window_BoundsChanged; _isActive = true; @@ -365,7 +381,7 @@ private void UpdateAspectRatioState(object sender, ReactiveEventArgs e) + private void UpdateAntiAliasing(object sender, ReactiveEventArgs e) { _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)e.NewValue); } @@ -385,11 +401,21 @@ private void UpdateAudioVolumeState(object sender, ReactiveEventArgs e) }); } + private void UpdateEnableInternetAccessState(object sender, ReactiveEventArgs e) + { + Device.Configuration.EnableInternetAccess = e.NewValue; + } + private void UpdateLanInterfaceIdState(object sender, ReactiveEventArgs e) { Device.Configuration.MultiplayerLanInterfaceId = e.NewValue; } + private void UpdateMultiplayerModeState(object sender, ReactiveEventArgs e) + { + Device.Configuration.MultiplayerMode = e.NewValue; + } + public void Stop() { _isActive = false; @@ -405,7 +431,7 @@ private void Exit() } _isStopped = true; - _isActive = false; + _isActive = false; } public void DisposeContext() @@ -414,10 +440,10 @@ public void DisposeContext() _isActive = false; - if (_renderingThread.IsAlive) - { - _renderingThread.Join(); - } + // NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose. + // We only need to wait for all commands submitted during the main gpu loop to be processed. + _gpuDoneEvent.WaitOne(); + _gpuDoneEvent.Dispose(); DisplaySleep.Restore(); @@ -434,18 +460,21 @@ private void Dispose() { if (Device.Processes != null) { - _viewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText); + MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText); } ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState; - ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState; - ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState; - ConfigurationState.Instance.System.AudioVolume.Event -= UpdateAudioVolumeState; - ConfigurationState.Instance.Graphics.ScalingFilter.Event -= UpdateScalingFilter; - ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event -= UpdateScalingFilterLevel; - ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAntiAliasing; - - _topLevel.PointerMoved -= TopLevel_PointerMoved; + ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState; + ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState; + ConfigurationState.Instance.System.AudioVolume.Event -= UpdateAudioVolumeState; + ConfigurationState.Instance.Graphics.ScalingFilter.Event -= UpdateScalingFilter; + ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event -= UpdateScalingFilterLevel; + ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAntiAliasing; + ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event -= UpdateColorSpacePassthrough; + + _topLevel.PointerMoved -= TopLevel_PointerEnteredOrMoved; + _topLevel.PointerEntered -= TopLevel_PointerEnteredOrMoved; + _topLevel.PointerExited -= TopLevel_PointerExited; _gpuCancellationTokenSource.Cancel(); _gpuCancellationTokenSource.Dispose(); @@ -461,11 +490,20 @@ public void DisposeGpu() _windowsMultimediaTimerResolution = null; } - (_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(); + if (RendererHost.EmbeddedWindow is EmbeddedWindowOpenGL openGlWindow) + { + // Try to bind the OpenGL context before calling the shutdown event. + openGlWindow.MakeCurrent(false, false); - Device.DisposeGpu(); + Device.DisposeGpu(); - (_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null); + // Unbind context and destroy everything. + openGlWindow.MakeCurrent(true, false); + } + else + { + Device.DisposeGpu(); + } } private void HideCursorState_Changed(object sender, ReactiveEventArgs state) @@ -483,7 +521,7 @@ public async Task LoadGuestApplication() SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); - if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { if (!SetupValidator.CanStartApplication(ContentManager, ApplicationPath, out UserError userError)) { @@ -501,7 +539,7 @@ public async Task LoadGuestApplication() if (result != UserResult.Yes) { - await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + await UserErrorDialog.ShowUserErrorDialog(userError); Device.Dispose(); return false; @@ -510,7 +548,7 @@ public async Task LoadGuestApplication() if (!SetupValidator.TryFixStartApplication(ContentManager, ApplicationPath, userError, out _)) { - await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + await UserErrorDialog.ShowUserErrorDialog(userError); Device.Dispose(); return false; @@ -533,7 +571,7 @@ await ContentDialogHelper.CreateInfoDialog( } else { - await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + await UserErrorDialog.ShowUserErrorDialog(userError); Device.Dispose(); return false; @@ -668,9 +706,9 @@ await ContentDialogHelper.CreateInfoDialog( DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, Device.Processes.ActiveApplication.Name); - _viewModel.ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => + ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => { - appMetadata.LastPlayed = DateTime.UtcNow.ToString(); + appMetadata.UpdatePreGame(); }); return true; @@ -681,6 +719,8 @@ internal void Resume() Device?.System.TogglePauseEmulation(false); _viewModel.IsPaused = false; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version); + Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } internal void Pause() @@ -688,6 +728,8 @@ internal void Pause() Device?.System.TogglePauseEmulation(true); _viewModel.IsPaused = true; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, LocaleManager.Instance[LocaleKeys.Paused]); + Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } private void InitializeSwitchInstance() @@ -701,7 +743,8 @@ private void InitializeSwitchInstance() if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.Vulkan) { renderer = new VulkanRenderer( - (_rendererHost.EmbeddedWindow as EmbeddedWindowVulkan).CreateSurface, + Vk.GetApi(), + (RendererHost.EmbeddedWindow as EmbeddedWindowVulkan).CreateSurface, VulkanHelper.GetRequiredInstanceExtensions, ConfigurationState.Instance.Graphics.PreferredGpu.Value); } @@ -712,18 +755,18 @@ private void InitializeSwitchInstance() BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading; - var isGALthreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); - if (isGALthreaded) + var isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); + if (isGALThreaded) { renderer = new ThreadedRenderer(renderer); } - Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALthreaded}"); + Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}"); // Initialize Configuration. - var memoryConfiguration = ConfigurationState.Instance.System.ExpandRam.Value ? HLE.MemoryConfiguration.MemoryConfiguration6GiB : HLE.MemoryConfiguration.MemoryConfiguration4GiB; + var memoryConfiguration = ConfigurationState.Instance.System.ExpandRam.Value ? MemoryConfiguration.MemoryConfiguration6GiB : MemoryConfiguration.MemoryConfiguration4GiB; - HLE.HLEConfiguration configuration = new(VirtualFileSystem, + HLEConfiguration configuration = new(VirtualFileSystem, _viewModel.LibHacHorizonManager, ContentManager, _accountManager, @@ -747,19 +790,20 @@ private void InitializeSwitchInstance() ConfigurationState.Instance.Graphics.AspectRatio, ConfigurationState.Instance.System.AudioVolume, ConfigurationState.Instance.System.UseHypervisor, - ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value); + ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value, + ConfigurationState.Instance.Multiplayer.Mode); Device = new Switch(configuration); } private static IHardwareDeviceDriver InitializeAudio() { - var availableBackends = new List() + var availableBackends = new List { AudioBackend.SDL2, AudioBackend.SoundIo, AudioBackend.OpenAl, - AudioBackend.Dummy + AudioBackend.Dummy, }; AudioBackend preferredBackend = ConfigurationState.Instance.System.AudioBackend.Value; @@ -780,12 +824,10 @@ private static IHardwareDeviceDriver InitializeAudio() { return new T(); } - else - { - Logger.Warning?.Print(LogClass.Audio, $"{backend} is not supported, falling back to {nextBackend}."); - return null; - } + Logger.Warning?.Print(LogClass.Audio, $"{backend} is not supported, falling back to {nextBackend}."); + + return null; } IHardwareDeviceDriver deviceDriver = null; @@ -793,14 +835,14 @@ private static IHardwareDeviceDriver InitializeAudio() for (int i = 0; i < availableBackends.Count; i++) { AudioBackend currentBackend = availableBackends[i]; - AudioBackend nextBackend = i + 1 < availableBackends.Count ? availableBackends[i + 1] : AudioBackend.Dummy; + AudioBackend nextBackend = i + 1 < availableBackends.Count ? availableBackends[i + 1] : AudioBackend.Dummy; deviceDriver = currentBackend switch { - AudioBackend.SDL2 => InitializeAudioBackend(AudioBackend.SDL2, nextBackend), + AudioBackend.SDL2 => InitializeAudioBackend(AudioBackend.SDL2, nextBackend), AudioBackend.SoundIo => InitializeAudioBackend(AudioBackend.SoundIo, nextBackend), - AudioBackend.OpenAl => InitializeAudioBackend(AudioBackend.OpenAl, nextBackend), - _ => new DummyHardwareDeviceDriver() + AudioBackend.OpenAl => InitializeAudioBackend(AudioBackend.OpenAl, nextBackend), + _ => new DummyHardwareDeviceDriver(), }; if (deviceDriver != null) @@ -815,9 +857,9 @@ private static IHardwareDeviceDriver InitializeAudio() return deviceDriver; } - private void Window_SizeChanged(object sender, Size e) + private void Window_BoundsChanged(object sender, Size e) { - Width = (int)e.Width; + Width = (int)e.Width; Height = (int)e.Height; SetRendererWindowSize(e); @@ -853,18 +895,19 @@ private void RenderLoop() _renderer.ScreenCaptured += Renderer_ScreenCaptured; - (_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.InitializeBackgroundContext(_renderer); + (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.InitializeBackgroundContext(_renderer); 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); - Width = (int)_rendererHost.Bounds.Width; - Height = (int)_rendererHost.Bounds.Height; + Width = (int)RendererHost.Bounds.Width; + Height = (int)RendererHost.Bounds.Height; - _renderer.Window.SetSize((int)(Width * _topLevel.PlatformImpl.RenderScaling), (int)(Height * _topLevel.PlatformImpl.RenderScaling)); + _renderer.Window.SetSize((int)(Width * _topLevel.RenderScaling), (int)(Height * _topLevel.RenderScaling)); _chrono.Start(); @@ -872,7 +915,6 @@ private void RenderLoop() { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); _renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync); @@ -897,7 +939,7 @@ private void RenderLoop() _viewModel.SwitchToRenderer(false); } - Device.PresentFrame(() => (_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers()); + Device.PresentFrame(() => (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers()); } if (_ticks >= _ticksPerFrame) @@ -905,9 +947,17 @@ private void RenderLoop() UpdateStatus(); } } + + // Make sure all commands in the run loop are fully executed before leaving the loop. + if (Device.Gpu.Renderer is ThreadedRenderer threaded) + { + threaded.FlushThreadedCommands(); + } + + _gpuDoneEvent.Set(); }); - (_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null); + (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true); } public void UpdateStatus() @@ -1021,7 +1071,7 @@ private bool UpdateFrame() ScreenshotRequested = true; break; case KeyboardHotkeyState.ShowUi: - _viewModel.ShowMenuAndStatusBar = true; + _viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar; break; case KeyboardHotkeyState.Pause: if (_viewModel.IsPaused) @@ -1036,10 +1086,11 @@ private bool UpdateFrame() case KeyboardHotkeyState.ToggleMute: if (Device.IsAudioMuted()) { - Device.SetVolume(ConfigurationState.Instance.System.AudioVolume); + Device.SetVolume(_viewModel.VolumeBeforeMute); } else { + _viewModel.VolumeBeforeMute = Device.GetVolume(); Device.SetVolume(0); } @@ -1141,4 +1192,4 @@ private KeyboardHotkeyState GetHotkeyState() return state; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg new file mode 100644 index 000000000..cf78cf120 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg new file mode 100644 index 000000000..8097762df --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg new file mode 100644 index 000000000..adb6e1e18 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg new file mode 100644 index 000000000..53eef82c2 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/de_DE.json b/src/Ryujinx.Ava/Assets/Locales/de_DE.json index 8bf00d7ed..7cdcdf5a2 100644 --- a/src/Ryujinx.Ava/Assets/Locales/de_DE.json +++ b/src/Ryujinx.Ava/Assets/Locales/de_DE.json @@ -1,12 +1,13 @@ { "Language": "Deutsch", - "MenuBarFileOpenApplet": "Applet öffnen", - "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Öffnet das Mii Editor Applet im Standalone Modus", + "MenuBarFileOpenApplet": "Öffne Anwendung", + "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Öffnet das Mii-Editor-Applet im Standalone-Modus", "SettingsTabInputDirectMouseAccess": "Direkter Mauszugriff", "SettingsTabSystemMemoryManagerMode": "Speichermanagermodus:", "SettingsTabSystemMemoryManagerModeSoftware": "Software", "SettingsTabSystemMemoryManagerModeHost": "Host (schnell)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host ungeprüft (am schnellsten, unsicher)", + "SettingsTabSystemUseHypervisor": "Hypervisor verwenden", "MenuBarFile": "_Datei", "MenuBarFileOpenFromFile": "_Datei öffnen", "MenuBarFileOpenUnpacked": "_Entpacktes Spiel öffnen", @@ -18,14 +19,17 @@ "MenuBarOptionsStartGamesInFullscreen": "Spiele im Vollbildmodus starten", "MenuBarOptionsStopEmulation": "Emulation beenden", "MenuBarOptionsSettings": "_Einstellungen", - "MenuBarOptionsManageUserProfiles": "_Profilverwaltung", + "MenuBarOptionsManageUserProfiles": "_Benutzerprofile verwalten", "MenuBarActions": "_Aktionen", - "MenuBarOptionsSimulateWakeUpMessage": "Aufwachnachricht", - "MenuBarActionsScanAmiibo": "Scanne ein Amiibo", + "MenuBarOptionsSimulateWakeUpMessage": "Aufwachnachricht simulieren", + "MenuBarActionsScanAmiibo": "Amiibo scannen", "MenuBarTools": "_Werkzeuge", "MenuBarToolsInstallFirmware": "Firmware installieren", - "MenuBarFileToolsInstallFirmwareFromFile": "Installiere Firmware von einer XCI oder einer ZIP Datei", - "MenuBarFileToolsInstallFirmwareFromDirectory": "Installiere Firmware aus einem Verzeichnis", + "MenuBarFileToolsInstallFirmwareFromFile": "Firmware von einer XCI- oder einer ZIP-Datei installieren", + "MenuBarFileToolsInstallFirmwareFromDirectory": "Firmware aus einem Verzeichnis installieren", + "MenuBarToolsManageFileTypes": "Dateitypen verwalten", + "MenuBarToolsInstallFileTypes": "Dateitypen installieren", + "MenuBarToolsUninstallFileTypes": "Dateitypen deinstallieren", "MenuBarHelp": "Hilfe", "MenuBarHelpCheckForUpdates": "Nach Updates suchen", "MenuBarHelpAbout": "Über Ryujinx", @@ -45,8 +49,8 @@ "GameListContextMenuOpenDeviceSaveDirectory": "Benutzer-Geräte-Verzeichnis öffnen", "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "Öffnet das Verzeichnis, welches den Geräte-Spielstände beinhaltet", "GameListContextMenuOpenBcatSaveDirectory": "Benutzer-BCAT-Vezeichnis öffnen", - "GameListContextMenuOpenBcatSaveDirectoryToolTip": "Öffnet das Verzeichnis, welches den BCAT Cache des Spiels beinhaltet", - "GameListContextMenuManageTitleUpdates": "Verwalten von Spiel Updates", + "GameListContextMenuOpenBcatSaveDirectoryToolTip": "Öffnet das Verzeichnis, welches den BCAT-Cache des Spiels beinhaltet", + "GameListContextMenuManageTitleUpdates": "Verwalte Spiel-Updates", "GameListContextMenuManageTitleUpdatesToolTip": "Öffnet den Spiel-Update-Manager", "GameListContextMenuManageDlc": "Verwalten von DLC", "GameListContextMenuManageDlcToolTip": "Öffnet den DLC-Manager", @@ -56,10 +60,10 @@ "GameListContextMenuCacheManagementPurgePptc": "PPTC als ungültig markieren", "GameListContextMenuCacheManagementPurgePptcToolTip": "Markiert den PPTC als ungültig, sodass dieser beim nächsten Spielstart neu erstellt wird", "GameListContextMenuCacheManagementPurgeShaderCache": "Shader Cache löschen", - "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Löscht den Shader Cache der Anwendung", - "GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC Verzeichnis öffnen", - "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Öffnet das Verzeichnis, das den PPTC Cache der Anwendung beinhaltet", - "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader Cache Verzeichnis öffnen", + "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Löscht den Shader-Cache der Anwendung", + "GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC-Verzeichnis öffnen", + "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Öffnet das Verzeichnis, das den PPTC-Cache der Anwendung beinhaltet", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader-Cache-Verzeichnis öffnen", "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Öffnet das Verzeichnis, das den Shader Cache der Anwendung beinhaltet", "GameListContextMenuExtractData": "Daten extrahieren", "GameListContextMenuExtractDataExeFS": "ExeFS", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Extrahiert das Logo aus der aktuellen Anwendungskonfiguration (einschließlich Updates)", "StatusBarGamesLoaded": "{0}/{1} Spiele geladen", "StatusBarSystemVersion": "Systemversion: {0}", + "LinuxVmMaxMapCountDialogTitle": "Niedriges Limit für Speicherzuordnungen erkannt", + "LinuxVmMaxMapCountDialogTextPrimary": "Möchtest Du den Wert von vm.max_map_count auf {0} erhöhen", + "LinuxVmMaxMapCountDialogTextSecondary": "Einige Spiele könnten versuchen, mehr Speicherzuordnungen zu erstellen, als derzeit erlaubt. Ryujinx wird abstürzen, sobald dieses Limit überschritten wird.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Ja, bis zum nächsten Neustart", + "LinuxVmMaxMapCountDialogButtonPersistent": "Ja, permanent", + "LinuxVmMaxMapCountWarningTextPrimary": "Maximale Anzahl an Speicherzuordnungen ist niedriger als empfohlen.", + "LinuxVmMaxMapCountWarningTextSecondary": "Der aktuelle Wert von vm.max_map_count ({0}) ist kleiner als {1}. Einige Spiele könnten versuchen, mehr Speicherzuordnungen zu erstellen, als derzeit erlaubt. Ryujinx wird abstürzen, sobald dieses Limit überschritten wird.\n\nDu kannst das Limit entweder manuell erhöhen oder pkexec installieren, damit Ryujinx Dir dabei hilft.", "Settings": "Einstellungen", - "SettingsTabGeneral": "Allgemein", + "SettingsTabGeneral": "Oberfläche", "SettingsTabGeneralGeneral": "Allgemein", - "SettingsTabGeneralEnableDiscordRichPresence": "Aktiviere Discord Rich Presence", + "SettingsTabGeneralEnableDiscordRichPresence": "Aktiviere die Statusanzeige für Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Beim Start nach Updates suchen", - "SettingsTabGeneralShowConfirmExitDialog": "Zeige den \"Beenden bestätigen\" Dialog", + "SettingsTabGeneralShowConfirmExitDialog": "Zeige den \"Beenden bestätigen\"-Dialog", + "SettingsTabGeneralHideCursor": "Mauszeiger ausblenden", + "SettingsTabGeneralHideCursorNever": "Niemals", "SettingsTabGeneralHideCursorOnIdle": "Mauszeiger bei Inaktivität ausblenden", + "SettingsTabGeneralHideCursorAlways": "Immer", "SettingsTabGeneralGameDirectories": "Spielverzeichnisse", "SettingsTabGeneralAdd": "Hinzufügen", "SettingsTabGeneralRemove": "Entfernen", @@ -108,10 +122,10 @@ "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Lateinamerikanisches Spanisch", "SettingsTabSystemSystemLanguageSimplifiedChinese": "Vereinfachtes Chinesisch", "SettingsTabSystemSystemLanguageTraditionalChinese": "Traditionelles Chinesisch", - "SettingsTabSystemSystemTimeZone": "System Zeitzone:", - "SettingsTabSystemSystemTime": "System Zeit:", + "SettingsTabSystemSystemTimeZone": "System-Zeitzone:", + "SettingsTabSystemSystemTime": "Systemzeit:", "SettingsTabSystemEnableVsync": "VSync", - "SettingsTabSystemEnablePptc": "PPTC Cache (Profiled Persistent Translation Cache)", + "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnableFsIntegrityChecks": "FS Integritätsprüfung", "SettingsTabSystemAudioBackend": "Audio-Backend:", "SettingsTabSystemAudioBackendDummy": "Ohne Funktion", @@ -124,7 +138,7 @@ "SettingsTabSystemIgnoreMissingServices": "Ignoriere fehlende Dienste", "SettingsTabGraphics": "Grafik", "SettingsTabGraphicsAPI": "Grafik-API", - "SettingsTabGraphicsEnableShaderCache": "Shader Cache", + "SettingsTabGraphicsEnableShaderCache": "Shader-Cache aktivieren", "SettingsTabGraphicsAnisotropicFiltering": "Anisotrope Filterung:", "SettingsTabGraphicsAnisotropicFilteringAuto": "Auto", "SettingsTabGraphicsAnisotropicFiltering2x": "2x", @@ -143,12 +157,12 @@ "SettingsTabGraphicsAspectRatio16x10": "16:10", "SettingsTabGraphicsAspectRatio21x9": "21:9", "SettingsTabGraphicsAspectRatio32x9": "32:9", - "SettingsTabGraphicsAspectRatioStretch": "Dehnen, um sich an das Fenster anzupassen", + "SettingsTabGraphicsAspectRatioStretch": "An Fenster anpassen", "SettingsTabGraphicsDeveloperOptions": "Optionen für Entwickler", - "SettingsTabGraphicsShaderDumpPath": "Grafik-Shader Dump Pfad:", + "SettingsTabGraphicsShaderDumpPath": "Grafik-Shader-Dump-Pfad:", "SettingsTabLogging": "Logs", "SettingsTabLoggingLogging": "Logs", - "SettingsTabLoggingEnableLoggingToFile": "Aktiviere Erstellung von Log-Datei", + "SettingsTabLoggingEnableLoggingToFile": "Protokollierung in Datei aktivieren", "SettingsTabLoggingEnableStubLogs": "Aktiviere Stub-Logs", "SettingsTabLoggingEnableInfoLogs": "Aktiviere Info-Logs", "SettingsTabLoggingEnableWarningLogs": "Aktiviere Warn-Logs", @@ -157,15 +171,16 @@ "SettingsTabLoggingEnableGuestLogs": "Aktiviere Gast-Logs", "SettingsTabLoggingEnableFsAccessLogs": "Aktiviere Fs Zugriff-Logs", "SettingsTabLoggingFsGlobalAccessLogMode": "Fs Globaler Zugriff-Log-Modus:", - "SettingsTabLoggingDeveloperOptions": "Entwickleroptionen (WARNUNG: Beeinträchtigt die Leistung)", - "SettingsTabLoggingGraphicsBackendLogLevel": "Graphics Backend Log Level:", + "SettingsTabLoggingDeveloperOptions": "Entwickleroptionen", + "SettingsTabLoggingDeveloperOptionsNote": "ACHTUNG: Wird die Leistung reduzieren", + "SettingsTabLoggingGraphicsBackendLogLevel": "Protokollstufe des Grafik-Backends:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Keine", "SettingsTabLoggingGraphicsBackendLogLevelError": "Fehler", "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "Verlangsamungen", "SettingsTabLoggingGraphicsBackendLogLevelAll": "Alle", "SettingsTabLoggingEnableDebugLogs": "Aktiviere Debug-Log", "SettingsTabInput": "Eingabe", - "SettingsTabInputEnableDockedMode": "Docked Modus", + "SettingsTabInputEnableDockedMode": "Angedockter Modus", "SettingsTabInputDirectKeyboardAccess": "Direkter Tastaturzugriff", "SettingsButtonSave": "Speichern", "SettingsButtonClose": "Schließen", @@ -185,12 +200,12 @@ "ControllerSettingsInputDevice": "Eingabegerät", "ControllerSettingsRefresh": "Aktualisieren", "ControllerSettingsDeviceDisabled": "Deaktiviert", - "ControllerSettingsControllerType": "Controller Typ", + "ControllerSettingsControllerType": "Controller-Typ", "ControllerSettingsControllerTypeHandheld": "Handheld", "ControllerSettingsControllerTypeProController": "Pro Controller", - "ControllerSettingsControllerTypeJoyConPair": "Joy-Con Paar", - "ControllerSettingsControllerTypeJoyConLeft": "Joy-Con Links", - "ControllerSettingsControllerTypeJoyConRight": "Joy-Con Rechts", + "ControllerSettingsControllerTypeJoyConPair": "Joy-Con-Paar", + "ControllerSettingsControllerTypeJoyConLeft": "Linker Joy-Con", + "ControllerSettingsControllerTypeJoyConRight": "Rechter Joy-Con", "ControllerSettingsProfile": "Profil", "ControllerSettingsProfileDefault": "Standard", "ControllerSettingsLoad": "Laden", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Runter", "ControllerSettingsDPadLeft": "Links", "ControllerSettingsDPadRight": "Rechts", + "ControllerSettingsStickButton": "Button", + "ControllerSettingsStickUp": "Hoch", + "ControllerSettingsStickDown": "Runter", + "ControllerSettingsStickLeft": "Links", + "ControllerSettingsStickRight": "Rechts", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "X-Achse invertieren", + "ControllerSettingsStickInvertYAxis": "Y-Achse invertieren", + "ControllerSettingsStickDeadzone": "Deadzone:", "ControllerSettingsLStick": "Linker Analogstick", - "ControllerSettingsLStickButton": "L3", - "ControllerSettingsLStickUp": "Hoch", - "ControllerSettingsLStickDown": "Runter", - "ControllerSettingsLStickLeft": "Links", - "ControllerSettingsLStickRight": "Rechts", - "ControllerSettingsLStickStick": "Analogstick", - "ControllerSettingsLStickInvertXAxis": "X-Achse invertieren", - "ControllerSettingsLStickInvertYAxis": "Y-Achse invertieren", - "ControllerSettingsLStickDeadzone": "Deadzone:", "ControllerSettingsRStick": "Rechter Analogstick", - "ControllerSettingsRStickButton": "R3", - "ControllerSettingsRStickUp": "Hoch", - "ControllerSettingsRStickDown": "Runter", - "ControllerSettingsRStickLeft": "Links", - "ControllerSettingsRStickRight": "Rechts", - "ControllerSettingsRStickStick": "Analogstick", - "ControllerSettingsRStickInvertXAxis": "X-Achse invertieren", - "ControllerSettingsRStickInvertYAxis": "Y-Achse invertieren", - "ControllerSettingsRStickDeadzone": "Deadzone:", "ControllerSettingsTriggersLeft": "Linker Trigger", "ControllerSettingsTriggersRight": "Rechter Trigger", "ControllerSettingsTriggersButtonsLeft": "Linke Schultertaste", @@ -247,12 +253,12 @@ "ControllerSettingsTriggerThreshold": "Empfindlichkeit:", "ControllerSettingsMotion": "Bewegung", "ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook kompatible Bewegungssteuerung", - "ControllerSettingsMotionControllerSlot": "Kontroller Slot:", - "ControllerSettingsMotionMirrorInput": "Spiegele Eingabe", - "ControllerSettingsMotionRightJoyConSlot": "Rechter Joy-Con Slot:", + "ControllerSettingsMotionControllerSlot": "Controller-Slot:", + "ControllerSettingsMotionMirrorInput": "Eingabe spiegeln", + "ControllerSettingsMotionRightJoyConSlot": "Rechter Joy-Con-Slot:", "ControllerSettingsMotionServerHost": "Server Host:", - "ControllerSettingsMotionGyroSensitivity": "Gyro Empfindlichkeit:", - "ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:", + "ControllerSettingsMotionGyroSensitivity": "Gyro-Empfindlichkeit:", + "ControllerSettingsMotionGyroDeadzone": "Gyro-Deadzone:", "ControllerSettingsSave": "Speichern", "ControllerSettingsClose": "Schließen", "UserProfilesSelectedUserProfile": "Ausgewähltes Profil:", @@ -262,26 +268,28 @@ "UserProfilesAddNewProfile": "Neues Profil", "UserProfilesDelete": "Löschen", "UserProfilesClose": "Schließen", + "ProfileNameSelectionWatermark": "Wähle einen Spitznamen", "ProfileImageSelectionTitle": "Auswahl des Profilbildes", "ProfileImageSelectionHeader": "Wähle ein Profilbild aus", "ProfileImageSelectionNote": "Es kann ein eigenes Profilbild importiert werden oder ein Avatar aus der System-Firmware", "ProfileImageSelectionImportImage": "Bilddatei importieren", - "ProfileImageSelectionSelectAvatar": "Firmware Avatar auswählen", - "InputDialogTitle": "Eingabe Dialog", + "ProfileImageSelectionSelectAvatar": "Firmware-Avatar auswählen", + "InputDialogTitle": "Eingabe-Dialog", "InputDialogOk": "OK", "InputDialogCancel": "Abbrechen", "InputDialogAddNewProfileTitle": "Wähle den Profilnamen", "InputDialogAddNewProfileHeader": "Bitte gebe einen Profilnamen ein", "InputDialogAddNewProfileSubtext": "(Maximale Länge: {0})", "AvatarChoose": "Bestätigen", - "AvatarSetBackgroundColor": "Hintergrundfarbe einstellen", + "AvatarSetBackgroundColor": "Hintergrundfarbe auswählen", "AvatarClose": "Schließen", "ControllerSettingsLoadProfileToolTip": "Lädt ein Profil", "ControllerSettingsAddProfileToolTip": "Fügt ein Profil hinzu", "ControllerSettingsRemoveProfileToolTip": "Entfernt ein Profil", "ControllerSettingsSaveProfileToolTip": "Speichert ein Profil", "MenuBarFileToolsTakeScreenshot": "Screenshot aufnehmen", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "Oberfläche ausblenden", + "GameListContextMenuRunApplication": "Anwendung ausführen", "GameListContextMenuToggleFavorite": "Als Favoriten hinzufügen/entfernen", "GameListContextMenuToggleFavoriteToolTip": "Aktiviert den Favoriten-Status des Spiels", "SettingsTabGeneralTheme": "Design", @@ -296,7 +304,7 @@ "ControllerSettingsRumbleStrongMultiplier": "Starker Vibrations-Multiplikator", "ControllerSettingsRumbleWeakMultiplier": "Schwacher Vibrations-Multiplikator", "DialogMessageSaveNotAvailableMessage": "Es existieren keine Speicherdaten für {0} [{1:x16}]", - "DialogMessageSaveNotAvailableCreateSaveMessage": "Soll Ryujinx Speicherdaten für dieses Spiel erstellen?", + "DialogMessageSaveNotAvailableCreateSaveMessage": "Sollen Speicherdaten für dieses Spiel erstellt werden?", "DialogConfirmationTitle": "Ryujinx - Bestätigung", "DialogUpdaterTitle": "Ryujinx - Updater", "DialogErrorTitle": "Ryujinx - Fehler", @@ -306,26 +314,26 @@ "DialogExitMessage": "Ryujinx wirklich schließen?", "DialogExitSubMessage": "Alle nicht gespeicherten Daten gehen verloren!", "DialogMessageCreateSaveErrorMessage": "Es ist ein Fehler bei der Erstellung der angegebenen Speicherdaten aufgetreten: {0}", - "DialogMessageFindSaveErrorMessage": "Es ist ein Fehler beim Auffinden der angegebenen Speicherdaten aufgetreten: {0}", + "DialogMessageFindSaveErrorMessage": "Es ist ein Fehler beim Suchen der angegebenen Speicherdaten aufgetreten: {0}", "FolderDialogExtractTitle": "Wähle den Ordner, in welchen die Dateien entpackt werden sollen", "DialogNcaExtractionMessage": "Extrahiert {0} abschnitt von {1}...", "DialogNcaExtractionTitle": "Ryujinx - NCA-Abschnitt-Extraktor", "DialogNcaExtractionMainNcaNotFoundErrorMessage": "Extraktion fehlgeschlagen. Der Hauptheader der NCA war in der ausgewählten Datei nicht vorhanden.", "DialogNcaExtractionCheckLogErrorMessage": "Extraktion fehlgeschlagen. Überprüfe die Logs für weitere Informationen.", "DialogNcaExtractionSuccessMessage": "Extraktion erfolgreich abgeschlossen.", - "DialogUpdaterConvertFailedMessage": "Die Konvertierung der aktuellen Ryujinx Version ist fehlgeschlagen.", + "DialogUpdaterConvertFailedMessage": "Die Konvertierung der aktuellen Ryujinx-Version ist fehlgeschlagen.", "DialogUpdaterCancelUpdateMessage": "Download wird abgebrochen!", "DialogUpdaterAlreadyOnLatestVersionMessage": "Es wird bereits die aktuellste Version von Ryujinx benutzt", - "DialogUpdaterFailedToGetVersionMessage": "An error has occurred when trying to get release information from GitHub Release. This can be caused if a new release is being compiled by GitHub Actions. Try again in a few minutes.", - "DialogUpdaterConvertFailedGithubMessage": "Failed to convert the received Ryujinx version from Github Release.", - "DialogUpdaterDownloadingMessage": "Update wird Heruntergeladen...", + "DialogUpdaterFailedToGetVersionMessage": "Beim Versuch, Veröffentlichungs-Info von GitHub Release zu erhalten, ist ein Fehler aufgetreten. Dies kann aufgrund einer neuen Veröffentlichung, die gerade von GitHub Actions kompiliert wird, verursacht werden.", + "DialogUpdaterConvertFailedGithubMessage": "Fehler beim Konvertieren der erhaltenen Ryujinx-Version von GitHub Release.", + "DialogUpdaterDownloadingMessage": "Update wird heruntergeladen...", "DialogUpdaterExtractionMessage": "Update wird entpackt...", "DialogUpdaterRenamingMessage": "Update wird umbenannt...", "DialogUpdaterAddingFilesMessage": "Update wird hinzugefügt...", "DialogUpdaterCompleteMessage": "Update abgeschlossen!", "DialogUpdaterRestartMessage": "Ryujinx jetzt neu starten?", "DialogUpdaterArchNotSupportedMessage": "Eine nicht unterstützte Systemarchitektur wird benutzt!", - "DialogUpdaterArchNotSupportedSubMessage": "Nur x64 Systeme werden unterstützt!", + "DialogUpdaterArchNotSupportedSubMessage": "Nur 64-Bit-Systeme werden unterstützt!", "DialogUpdaterNoInternetMessage": "Es besteht keine Verbindung mit dem Internet!", "DialogUpdaterNoInternetSubMessage": "Bitte vergewissern, dass eine funktionierende Internetverbindung existiert!", "DialogUpdaterDirtyBuildMessage": "Inoffizielle Versionen von Ryujinx können nicht aktualisiert werden", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Es wurde keine installierte Firmware gefunden, aber Ryujinx konnte die Firmware {0} aus dem bereitgestellten Spiel installieren.\nRyujinx wird nun gestartet.", "DialogFirmwareNoFirmwareInstalledMessage": "Keine Firmware installiert", "DialogFirmwareInstalledMessage": "Firmware {0} wurde installiert", + "DialogInstallFileTypesSuccessMessage": "Dateitypen erfolgreich installiert!", + "DialogInstallFileTypesErrorMessage": "Dateitypen konnten nicht installiert werden.", + "DialogUninstallFileTypesSuccessMessage": "Dateitypen erfolgreich deinstalliert!", + "DialogUninstallFileTypesErrorMessage": "Deinstallation der Dateitypen fehlgeschlagen.", "DialogOpenSettingsWindowLabel": "Fenster-Einstellungen öffnen", "DialogControllerAppletTitle": "Controller-Applet", "DialogMessageDialogErrorExceptionMessage": "Fehler bei der Anzeige des Meldungs-Dialogs: {0}", @@ -345,7 +357,7 @@ "DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogInfoMessage": "\nWeitere Informationen zur Behebung dieses Fehlers können in unserem Setup-Guide gefunden werden.", "DialogUserErrorDialogTitle": "Ryujinx Fehler ({0})", - "DialogAmiiboApiTitle": "Amiibo API", + "DialogAmiiboApiTitle": "Amiibo-API", "DialogAmiiboApiFailFetchMessage": "Beim Abrufen von Informationen aus der API ist ein Fehler aufgetreten.", "DialogAmiiboApiConnectErrorMessage": "Verbindung zum Amiibo API Server kann nicht hergestellt werden. Der Dienst ist möglicherweise nicht verfügbar oder es existiert keine Internetverbindung.", "DialogProfileInvalidProfileErrorMessage": "Das Profil {0} ist mit dem aktuellen Eingabekonfigurationssystem nicht kompatibel.", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Systemversion {0} wurde erfolgreich installiert.", "DialogUserProfileDeletionWarningMessage": "Es können keine anderen Profile geöffnet werden, wenn das ausgewählte Profil gelöscht wird.", "DialogUserProfileDeletionConfirmMessage": "Möchtest du das ausgewählte Profil löschen?", + "DialogUserProfileUnsavedChangesTitle": "Warnung - Nicht gespeicherte Änderungen", + "DialogUserProfileUnsavedChangesMessage": "Sie haben Änderungen an diesem Nutzerprofil vorgenommen, die nicht gespeichert wurden.", + "DialogUserProfileUnsavedChangesSubMessage": "Möchten Sie Ihre Änderungen wirklich verwerfen?", "DialogControllerSettingsModifiedConfirmMessage": "Die aktuellen Controller-Einstellungen wurden aktualisiert.", "DialogControllerSettingsModifiedConfirmSubMessage": "Controller-Einstellungen speichern?", "DialogLoadNcaErrorMessage": "{0}. Fehlerhafte Datei: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Alle aktivieren", "DlcManagerDisableAllButton": "Alle deaktivieren", "MenuBarOptionsChangeLanguage": "Sprache ändern", + "MenuBarShowFileTypes": "Dateitypen anzeigen", "CommonSort": "Sortieren", "CommonShowNames": "Spiel-Namen anzeigen", "CommonFavorite": "Favoriten", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Verwendung einer Software-Seitentabelle für die Adressumsetzung. Höchste Genauigkeit, aber langsamste Leistung.", "MemoryManagerHostTooltip": "Direkte Zuordnung von Speicher im Host-Adressraum. Viel schnellere JIT-Kompilierung und Ausführung.", "MemoryManagerUnsafeTooltip": "Direkte Zuordnung des Speichers, aber keine Maskierung der Adresse innerhalb des Gastadressraums vor dem Zugriff. Schneller, aber auf Kosten der Sicherheit. Die Gastanwendung kann von überall in Ryujinx auf den Speicher zugreifen, daher sollte in diesem Modus nur Programme ausgeführt werden denen vertraut wird.", + "UseHypervisorTooltip": "Verwende Hypervisor anstelle von JIT. Verbessert die Leistung stark, falls vorhanden, kann jedoch in seinem aktuellen Zustand instabil sein.", "DRamTooltip": "Erhöht den Arbeitsspeicher des emulierten Systems von 4 GiB auf 6 GiB.\n\nDies ist nur für Texturenpakete mit höherer Auflösung oder Mods mit 4K-Auflösung nützlich. Diese Option verbessert NICHT die Leistung.\n\nIm Zweifelsfall AUS lassen.", "IgnoreMissingServicesTooltip": "Durch diese Option werden nicht implementierte Dienste der Switch-Firmware ignoriert. Dies kann dabei helfen, Abstürze beim Starten bestimmter Spiele zu umgehen.\n\nIm Zweifelsfall AUS lassen.", "GraphicsBackendThreadingTooltip": "Führt Grafik-Backend Befehle auf einem zweiten Thread aus.\n\nDies beschleunigt die Shader-Kompilierung, reduziert Stottern und verbessert die Leistung auf GPU-Treibern ohne eigene Multithreading-Unterstützung. Geringfügig bessere Leistung bei Treibern mit Multithreading.\n\nIm Zweifelsfall auf AUTO stellen.", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Muss mindestens {0} Zeichen lang sein", "SwkbdMinRangeCharacters": "Muss {0}-{1} Zeichen lang sein", "SoftwareKeyboard": "Software-Tastatur", + "SoftwareKeyboardModeNumbersOnly": "Nur Zahlen", + "SoftwareKeyboardModeAlphabet": "Keine CJK-Zeichen", + "SoftwareKeyboardModeASCII": "Nur ASCII-Text", "DialogControllerAppletMessagePlayerRange": "Die Anwendung benötigt {0} Spieler mit:\n\nTYPEN: {1}\n\nSPIELER: {2}\n\n{3}Bitte öffne die Einstellungen und rekonfiguriere die Controller Einstellungen oder drücke auf schließen.", "DialogControllerAppletMessage": "Die Anwendung benötigt genau {0} Speieler mit:\n\nTYPEN: {1}\n\nSPIELER: {2}\n\n{3}Bitte öffne die Einstellungen und rekonfiguriere die Controller Einstellungen oder drücke auf schließen.", "DialogControllerAppletDockModeSet": "Der 'Docked Modus' ist ausgewählt. Handheld ist ebenfalls ungültig.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Spiel-DLC verwalten", "UpdateWindowTitle": "Spiel-Updates verwalten", "CheatWindowHeading": "Cheats verfügbar für {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "DLC verfügbar für {0} [{1}]", "UserProfilesEditProfile": "Profil bearbeiten", "Cancel": "Abbrechen", @@ -598,7 +619,9 @@ "SettingsTabHotkeysVolumeUpHotkey": "Lautstärke erhöhen:", "SettingsTabHotkeysVolumeDownHotkey": "Lautstärke verringern:", "SettingsEnableMacroHLE": "HLE Makros aktivieren", - "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", + "SettingsEnableMacroHLETooltip": "High-Level-Emulation von GPU-Makrocode.\n\nVerbessert die Leistung, kann aber in einigen Spielen zu Grafikfehlern führen.\n\nBei Unsicherheit AKTIVIEREN.", + "SettingsEnableColorSpacePassthrough": "Farbraum Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Weist das Vulkan-Backend an, Farbinformationen ohne Angabe eines Farbraums weiterzuleiten. Für Benutzer mit Wide-Gamut-Displays kann dies zu lebendigeren Farben führen, allerdings auf Kosten der Farbkorrektheit.", "VolumeShort": "Vol", "UserProfilesManageSaves": "Speicherstände verwalten", "DeleteUserSave": "Möchtest du den Spielerstand für dieses Spiel löschen?", @@ -610,5 +633,24 @@ "Search": "Suche", "UserProfilesRecoverLostAccounts": "Konto wiederherstellen", "Recover": "Wiederherstellen", - "UserProfilesRecoverHeading": "Speicherstände wurden für die folgenden Konten gefunden" -} + "UserProfilesRecoverHeading": "Speicherstände wurden für die folgenden Konten gefunden", + "UserProfilesRecoverEmptyList": "Keine Profile zum Wiederherstellen", + "GraphicsAATooltip": "Wendet Anti-Aliasing auf das Spiel-Rendering an", + "GraphicsAALabel": "Antialiasing:", + "GraphicsScalingFilterLabel": "Skalierungsfilter:", + "GraphicsScalingFilterTooltip": "Ermöglicht Framebuffer-Skalierung", + "GraphicsScalingFilterLevelLabel": "Stufe", + "GraphicsScalingFilterLevelTooltip": "Skalierungsfilter-Stufe festlegen", + "SmaaLow": "SMAA Niedrig", + "SmaaMedium": "SMAA Mittel", + "SmaaHigh": "SMAA Hoch", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Nutzer bearbeiten", + "UserEditorTitleCreate": "Nutzer erstellen", + "SettingsTabNetworkInterface": "Netzwerkschnittstelle:", + "NetworkInterfaceTooltip": "Die Netzwerkschnittstelle, die für LAN-Funktionen verwendet wird", + "NetworkInterfaceDefault": "Standard", + "PackagingShaders": "Verpackt Shader", + "AboutChangelogButton": "Changelog in GitHub öffnen", + "AboutChangelogButtonTooltipMessage": "Klicke hier, um das Changelog für diese Version in Ihrem Standardbrowser zu öffnen." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/el_GR.json b/src/Ryujinx.Ava/Assets/Locales/el_GR.json index de8897368..59f50ad92 100644 --- a/src/Ryujinx.Ava/Assets/Locales/el_GR.json +++ b/src/Ryujinx.Ava/Assets/Locales/el_GR.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "Λογισμικό", "SettingsTabSystemMemoryManagerModeHost": "Υπολογιστής (γρήγορο)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Χωρίς Ελέγχους (γρηγορότερο, μη ασφαλές)", + "SettingsTabSystemUseHypervisor": "Χρήση Hypervisor", "MenuBarFile": "_Αρχείο", "MenuBarFileOpenFromFile": "_Φόρτωση Αρχείου Εφαρμογής", "MenuBarFileOpenUnpacked": "Φόρτωση Απακετάριστου _Παιχνιδιού", @@ -22,10 +23,13 @@ "MenuBarActions": "_Δράσεις", "MenuBarOptionsSimulateWakeUpMessage": "Προσομοίωση Μηνύματος Αφύπνισης", "MenuBarActionsScanAmiibo": "Σάρωση Amiibo", - "MenuBarTools": "Εργα_λεία", + "MenuBarTools": "_Εργαλεία", "MenuBarToolsInstallFirmware": "Εγκατάσταση Firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Εγκατάσταση Firmware από XCI ή ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Εγκατάσταση Firmware από τοποθεσία", + "MenuBarToolsManageFileTypes": "Διαχείριση τύπων αρχείων", + "MenuBarToolsInstallFileTypes": "Εγκαταστήσετε τύπους αρχείων.", + "MenuBarToolsUninstallFileTypes": "Απεγκαταστήσετε τύπους αρχείων", "MenuBarHelp": "Βοήθεια", "MenuBarHelpCheckForUpdates": "Έλεγχος για Ενημερώσεις", "MenuBarHelpAbout": "Σχετικά με", @@ -38,7 +42,7 @@ "GameListHeaderTimePlayed": "Χρόνος", "GameListHeaderLastPlayed": "Παίχτηκε", "GameListHeaderFileExtension": "Κατάληξη", - "GameListHeaderFileSize": "Μέγεθος", + "GameListHeaderFileSize": "Μέγεθος Αρχείου", "GameListHeaderPath": "Τοποθεσία", "GameListContextMenuOpenUserSaveDirectory": "Άνοιγμα Τοποθεσίας Αποθήκευσης Χρήστη", "GameListContextMenuOpenUserSaveDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την Αποθήκευση Χρήστη της εφαρμογής", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Εξαγωγή της ενότητας Logo από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)", "StatusBarGamesLoaded": "{0}/{1} Φορτωμένα Παιχνίδια", "StatusBarSystemVersion": "Έκδοση Συστήματος: {0}", + "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", + "LinuxVmMaxMapCountDialogTextPrimary": "Would you like to increase the value of vm.max_map_count to {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Yes, until the next restart", + "LinuxVmMaxMapCountDialogButtonPersistent": "Yes, permanently", + "LinuxVmMaxMapCountWarningTextPrimary": "Max amount of memory mappings is lower than recommended.", + "LinuxVmMaxMapCountWarningTextSecondary": "The current value of vm.max_map_count ({0}) is lower than {1}. Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.\n\nYou might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.", "Settings": "Ρυθμίσεις", "SettingsTabGeneral": "Εμφάνιση", "SettingsTabGeneralGeneral": "Γενικά", "SettingsTabGeneralEnableDiscordRichPresence": "Ενεργοποίηση Εμπλουτισμένης Παρουσίας Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Έλεγχος για Ενημερώσεις στην Εκκίνηση", "SettingsTabGeneralShowConfirmExitDialog": "Εμφάνιση διαλόγου \"Επιβεβαίωση Εξόδου\".", + "SettingsTabGeneralHideCursor": "Απόκρυψη Κέρσορα:", + "SettingsTabGeneralHideCursorNever": "Ποτέ", "SettingsTabGeneralHideCursorOnIdle": "Απόκρυψη Δρομέα στην Αδράνεια", + "SettingsTabGeneralHideCursorAlways": "Πάντα", "SettingsTabGeneralGameDirectories": "Τοποθεσίες παιχνιδιών", "SettingsTabGeneralAdd": "Προσθήκη", "SettingsTabGeneralRemove": "Αφαίρεση", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Ενεργοποίηση Καταγραφής Πρόσβασης FS", "SettingsTabLoggingFsGlobalAccessLogMode": "Λειτουργία Καταγραφής Καθολικής Πρόσβασης FS:", "SettingsTabLoggingDeveloperOptions": "Επιλογές Προγραμματιστή (ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η απόδοση Θα μειωθεί)", + "SettingsTabLoggingDeveloperOptionsNote": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Θα μειώσει την απόδοση", "SettingsTabLoggingGraphicsBackendLogLevel": "Επίπεδο Καταγραφής Διεπαφής Γραφικών:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Κανένα", "SettingsTabLoggingGraphicsBackendLogLevelError": "Σφάλμα", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Κάτω", "ControllerSettingsDPadLeft": "Αριστερά", "ControllerSettingsDPadRight": "Δεξιά", + "ControllerSettingsStickButton": "Κουμπί", + "ControllerSettingsStickUp": "Πάνω", + "ControllerSettingsStickDown": "Κάτω", + "ControllerSettingsStickLeft": "Αριστερά", + "ControllerSettingsStickRight": "Δεξιά", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "Invert Stick X", + "ControllerSettingsStickInvertYAxis": "Invert Stick Y", + "ControllerSettingsStickDeadzone": "Deadzone:", "ControllerSettingsLStick": "Αριστερός Μοχλός", - "ControllerSettingsLStickButton": "Κουμπί", - "ControllerSettingsLStickUp": "Πάνω", - "ControllerSettingsLStickDown": "Κάτω", - "ControllerSettingsLStickLeft": "Αριστερά", - "ControllerSettingsLStickRight": "Δεξιά", - "ControllerSettingsLStickStick": "Μοχλός", - "ControllerSettingsLStickInvertXAxis": "Αντιστροφή Μοχλού X", - "ControllerSettingsLStickInvertYAxis": "Αντιστροφή Μοχλού Y", - "ControllerSettingsLStickDeadzone": "Νεκρή Ζώνη:", "ControllerSettingsRStick": "Δεξιός Μοχλός", - "ControllerSettingsRStickButton": "Κουμπί", - "ControllerSettingsRStickUp": "Πάνω", - "ControllerSettingsRStickDown": "Κάτω", - "ControllerSettingsRStickLeft": "Αριστερά", - "ControllerSettingsRStickRight": "Δεξιά", - "ControllerSettingsRStickStick": "Μοχλός", - "ControllerSettingsRStickInvertXAxis": "Αντιστροφή Μοχλού X", - "ControllerSettingsRStickInvertYAxis": "Αντιστροφή Μοχλού Y", - "ControllerSettingsRStickDeadzone": "Νεκρή Ζώνη:", "ControllerSettingsTriggersLeft": "Αριστερή Σκανδάλη", "ControllerSettingsTriggersRight": "Δεξιά Σκανδάλη", "ControllerSettingsTriggersButtonsLeft": "Αριστερά Κουμπιά Σκανδάλης", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Προσθήκη Νέου Προφίλ", "UserProfilesDelete": "Διαγράφω", "UserProfilesClose": "Κλείσιμο", + "ProfileNameSelectionWatermark": "Επιλέξτε ψευδώνυμο", "ProfileImageSelectionTitle": "Επιλογή Εικόνας Προφίλ", "ProfileImageSelectionHeader": "Επιλέξτε μία Εικόνα Προφίλ", "ProfileImageSelectionNote": "Μπορείτε να εισαγάγετε μία προσαρμοσμένη εικόνα προφίλ ή να επιλέξετε ένα avatar από το Firmware", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Αποθήκευση Προφίλ", "MenuBarFileToolsTakeScreenshot": "Λήψη Στιγμιότυπου", "MenuBarFileToolsHideUi": "Απόκρυψη UI", + "GameListContextMenuRunApplication": "Run Application", "GameListContextMenuToggleFavorite": "Εναλλαγή Αγαπημένου", "GameListContextMenuToggleFavoriteToolTip": "Εναλλαγή της Κατάστασης Αγαπημένο του Παιχνιδιού", "SettingsTabGeneralTheme": "Θέμα", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Δεν βρέθηκε εγκατεστημένο Firmware, αλλά το Ryujinx μπόρεσε να εγκαταστήσει το Firmware {0} από το παρεχόμενο παιχνίδι.\nΟ εξομοιωτής θα ξεκινήσει τώρα.", "DialogFirmwareNoFirmwareInstalledMessage": "Δεν έχει εγκατασταθεί Firmware", "DialogFirmwareInstalledMessage": "Το Firmware {0} εγκαταστάθηκε", + "DialogInstallFileTypesSuccessMessage": "Επιτυχής εγκατάσταση τύπων αρχείων!", + "DialogInstallFileTypesErrorMessage": "Απέτυχε η εγκατάσταση τύπων αρχείων.", + "DialogUninstallFileTypesSuccessMessage": "Επιτυχής απεγκατάσταση τύπων αρχείων!", + "DialogUninstallFileTypesErrorMessage": "Αποτυχία απεγκατάστασης τύπων αρχείων.", "DialogOpenSettingsWindowLabel": "Άνοιγμα Παραθύρου Ρυθμίσεων", "DialogControllerAppletTitle": "Applet Χειρισμού", "DialogMessageDialogErrorExceptionMessage": "Σφάλμα εμφάνισης του διαλόγου Μηνυμάτων: {0}", @@ -345,7 +357,7 @@ "DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogInfoMessage": "\nΓια πληροφορίες σχετικά με τον τρόπο διόρθωσης του σφάλματος, ακολουθήστε τον Οδηγό Εγκατάστασης.", "DialogUserErrorDialogTitle": "Σφάλμα Ryujinx ({0})", - "DialogAmiiboApiTitle": "Amiibo API", + "DialogAmiiboApiTitle": "API για Amiibo.", "DialogAmiiboApiFailFetchMessage": "Παρουσιάστηκε σφάλμα κατά την ανάκτηση πληροφοριών από το API.", "DialogAmiiboApiConnectErrorMessage": "Δεν είναι δυνατή η σύνδεση με τον διακομιστή Amiibo API. Η υπηρεσία μπορεί να είναι εκτός λειτουργίας ή μπορεί να χρειαστεί να επαληθεύσετε ότι έχετε ενεργή σύνδεσή στο Διαδίκτυο.", "DialogProfileInvalidProfileErrorMessage": "Το προφίλ {0} δεν είναι συμβατό με το τρέχον σύστημα χειρισμού.", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Η έκδοση συστήματος {0} εγκαταστάθηκε με επιτυχία.", "DialogUserProfileDeletionWarningMessage": "Δεν θα υπάρχουν άλλα προφίλ εάν διαγραφεί το επιλεγμένο", "DialogUserProfileDeletionConfirmMessage": "Θέλετε να διαγράψετε το επιλεγμένο προφίλ", + "DialogUserProfileUnsavedChangesTitle": "Προσοχή - Μην Αποθηκευμένες Αλλαγές.", + "DialogUserProfileUnsavedChangesMessage": "Έχετε κάνει αλλαγές σε αυτό το προφίλ χρήστη που δεν έχουν αποθηκευτεί.", + "DialogUserProfileUnsavedChangesSubMessage": "Θέλετε να απορρίψετε τις αλλαγές σας;", "DialogControllerSettingsModifiedConfirmMessage": "Οι τρέχουσες ρυθμίσεις χειρισμού έχουν ενημερωθεί.", "DialogControllerSettingsModifiedConfirmSubMessage": "Θέλετε να αποθηκεύσετε;", "DialogLoadNcaErrorMessage": "{0}. Σφάλμα Αρχείου: {1}", @@ -386,7 +401,7 @@ "CommonAuto": "Αυτόματο", "CommonOff": "Ανενεργό", "CommonOn": "Ενεργό", - "InputDialogYes": "Ναί", + "InputDialogYes": "Ναι", "InputDialogNo": "Όχι", "DialogProfileInvalidProfileNameErrorMessage": "Το όνομα αρχείου περιέχει μη έγκυρους χαρακτήρες. Παρακαλώ προσπαθήστε ξανά.", "MenuBarOptionsPauseEmulation": "Παύση", @@ -408,7 +423,7 @@ "AmiiboScanButtonLabel": "Σαρώστε το", "AmiiboOptionsShowAllLabel": "Εμφάνιση όλων των Amiibo", "AmiiboOptionsUsRandomTagLabel": "Hack: Χρησιμοποιήστε τυχαίο αναγνωριστικό UUID", - "DlcManagerTableHeadingEnabledLabel": "Ενεργοποιήθηκε", + "DlcManagerTableHeadingEnabledLabel": "Ενεργοποιημένο", "DlcManagerTableHeadingTitleIdLabel": "Αναγνωριστικό τίτλου", "DlcManagerTableHeadingContainerPathLabel": "Τοποθεσία DLC", "DlcManagerTableHeadingFullPathLabel": "Πλήρης τοποθεσία", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Ενεργοποίηση Όλων", "DlcManagerDisableAllButton": "Απενεργοποίηση Όλων", "MenuBarOptionsChangeLanguage": "Αλλαξε γλώσσα", + "MenuBarShowFileTypes": "Εμφάνιση Τύπων Αρχείων", "CommonSort": "Κατάταξη", "CommonShowNames": "Εμφάνιση ονομάτων", "CommonFavorite": "Αγαπημένα", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Χρησιμοποιήστε έναν πίνακα σελίδων λογισμικού για τη μετάφραση διευθύνσεων. Υψηλότερη ακρίβεια αλλά πιο αργή απόδοση.", "MemoryManagerHostTooltip": "Απευθείας αντιστοίχιση της μνήμης στον χώρο διευθύνσεων υπολογιστή υποδοχής. Πολύ πιο γρήγορη μεταγλώττιση και εκτέλεση JIT.", "MemoryManagerUnsafeTooltip": "Απευθείας χαρτογράφηση της μνήμης, αλλά μην καλύπτετε τη διεύθυνση εντός του χώρου διευθύνσεων επισκέπτη πριν από την πρόσβαση. Πιο γρήγορα, αλλά με κόστος ασφάλειας. Η εφαρμογή μπορεί να έχει πρόσβαση στη μνήμη από οπουδήποτε στο Ryujinx, επομένως εκτελείτε μόνο προγράμματα που εμπιστεύεστε με αυτήν τη λειτουργία.", + "UseHypervisorTooltip": "Χρησιμοποιήστε Hypervisor αντί για JIT. Βελτιώνει σημαντικά την απόδοση όταν διατίθεται, αλλά μπορεί να είναι ασταθής στην τρέχουσα κατάστασή του.", "DRamTooltip": "Επεκτείνει την ποσότητα της μνήμης στο εξομοιούμενο σύστημα από 4 GiB σε 6 GiB", "IgnoreMissingServicesTooltip": "Ενεργοποίηση ή απενεργοποίηση της αγνοώησης για υπηρεσίες που λείπουν", "GraphicsBackendThreadingTooltip": "Ενεργοποίηση Πολυνηματικής Επεξεργασίας Γραφικών", @@ -499,116 +516,141 @@ "DialogUpdaterFlatpakNotSupportedMessage": "Παρακαλούμε ενημερώστε το Ryujinx μέσω FlatHub.", "UpdaterDisabledWarningTitle": "Ο Διαχειριστής Ενημερώσεων Είναι Απενεργοποιημένος!", "GameListContextMenuOpenSdModsDirectory": "Άνοιγμα Της Τοποθεσίας Των Atmosphere Mods", - "GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.", - "ControllerSettingsRotate90": "Rotate 90° Clockwise", - "IconSize": "Icon Size", - "IconSizeTooltip": "Change the size of game icons", - "MenuBarOptionsShowConsole": "Show Console", - "ShaderCachePurgeError": "Error purging shader cache at {0}: {1}", - "UserErrorNoKeys": "Keys not found", - "UserErrorNoFirmware": "Firmware not found", - "UserErrorFirmwareParsingFailed": "Firmware parsing error", - "UserErrorApplicationNotFound": "Application not found", - "UserErrorUnknown": "Unknown error", - "UserErrorUndefined": "Undefined error", - "UserErrorNoKeysDescription": "Ryujinx was unable to find your 'prod.keys' file", - "UserErrorNoFirmwareDescription": "Ryujinx was unable to find any firmwares installed", - "UserErrorFirmwareParsingFailedDescription": "Ryujinx was unable to parse the provided firmware. This is usually caused by outdated keys.", - "UserErrorApplicationNotFoundDescription": "Ryujinx couldn't find a valid application at the given path.", - "UserErrorUnknownDescription": "An unknown error occured!", - "UserErrorUndefinedDescription": "An undefined error occured! This shouldn't happen, please contact a dev!", - "OpenSetupGuideMessage": "Open the Setup Guide", - "NoUpdate": "No Update", + "GameListContextMenuOpenSdModsDirectoryToolTip": "Ανοίγει τον εναλλακτικό SD card Atmosphere κατάλογο που περιέχει Mods για το Application. Χρήσιμο για mods τα οποία συσκευάστηκαν για την πραγματική κονσόλα.", + "ControllerSettingsRotate90": "Περιστροφή 90° Δεξιόστροφα", + "IconSize": "Μέγεθος Εικονιδίου", + "IconSizeTooltip": "Αλλάξτε μέγεθος εικονιδίων των παιχνιδιών", + "MenuBarOptionsShowConsole": "Εμφάνιση Κονσόλας", + "ShaderCachePurgeError": "Σφάλμα κατά την εκκαθάριση του shader cache στο {0}: {1}", + "UserErrorNoKeys": "Τα κλειδιά δεν βρέθηκαν", + "UserErrorNoFirmware": "Το firmware δε βρέθηκε", + "UserErrorFirmwareParsingFailed": "Σφάλμα ανάλυσης firmware", + "UserErrorApplicationNotFound": "Η εφαρμογή δε βρέθηκε", + "UserErrorUnknown": "Άγνωστο σφάλμα", + "UserErrorUndefined": "Αόριστο σφάλμα", + "UserErrorNoKeysDescription": "Το Ryujinx δεν κατάφερε να εντοπίσει το αρχείο 'prod.keys'", + "UserErrorNoFirmwareDescription": "Το Ryujinx δεν κατάφερε να εντοπίσει κανένα εγκατεστημένο firmware", + "UserErrorFirmwareParsingFailedDescription": "Το Ryujinx δεν κατάφερε να αναλύσει το συγκεκριμένο firmware. Αυτό συνήθως οφείλετε σε ξεπερασμένα/παλιά κλειδιά.", + "UserErrorApplicationNotFoundDescription": "Το Ryujinx δεν κατάφερε να εντοπίσει έγκυρη εφαρμογή στη συγκεκριμένη διαδρομή.", + "UserErrorUnknownDescription": "Παρουσιάστηκε άγνωστο σφάλμα.", + "UserErrorUndefinedDescription": "Παρουσιάστηκε ένα άγνωστο σφάλμα! Αυτό δεν πρέπει να συμβεί, παρακαλώ επικοινωνήστε με έναν προγραμματιστή!", + "OpenSetupGuideMessage": "Ανοίξτε τον Οδηγό Εγκατάστασης.", + "NoUpdate": "Καμία Eνημέρωση", "TitleUpdateVersionLabel": "Version {0} - {1}", - "RyujinxInfo": "Ryujinx - Info", - "RyujinxConfirm": "Ryujinx - Confirmation", - "FileDialogAllTypes": "All types", - "Never": "Never", - "SwkbdMinCharacters": "Must be at least {0} characters long", - "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long", - "SoftwareKeyboard": "Software Keyboard", - "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n", - "UpdaterRenaming": "Renaming Old Files...", - "UpdaterRenameFailed": "Updater was unable to rename file: {0}", - "UpdaterAddingFiles": "Adding New Files...", - "UpdaterExtracting": "Extracting Update...", - "UpdaterDownloading": "Downloading Update...", - "Game": "Game", - "Docked": "Docked", - "Handheld": "Handheld", - "ConnectionError": "Connection Error.", - "AboutPageDeveloperListMore": "{0} and more...", - "ApiError": "API Error.", - "LoadingHeading": "Loading {0}", - "CompilingPPTC": "Compiling PTC", - "CompilingShaders": "Compiling Shaders", - "AllKeyboards": "All keyboards", - "OpenFileDialogTitle": "Select a supported file to open", - "OpenFolderDialogTitle": "Select a folder with an unpacked game", - "AllSupportedFormats": "All Supported Formats", - "RyujinxUpdater": "Ryujinx Updater", - "SettingsTabHotkeys": "Keyboard Hotkeys", - "SettingsTabHotkeysHotkeys": "Keyboard Hotkeys", - "SettingsTabHotkeysToggleVsyncHotkey": "Toggle VSync:", - "SettingsTabHotkeysScreenshotHotkey": "Screenshot:", - "SettingsTabHotkeysShowUiHotkey": "Show UI:", - "SettingsTabHotkeysPauseHotkey": "Pause:", - "SettingsTabHotkeysToggleMuteHotkey": "Mute:", - "ControllerMotionTitle": "Motion Control Settings", - "ControllerRumbleTitle": "Rumble Settings", - "SettingsSelectThemeFileDialogTitle": "Select Theme File", - "SettingsXamlThemeFile": "Xaml Theme File", - "AvatarWindowTitle": "Manage Accounts - Avatar", + "RyujinxInfo": "Ryujinx - Πληροφορίες", + "RyujinxConfirm": "Ryujinx - Επιβεβαίωση", + "FileDialogAllTypes": "Όλοι οι τύποι", + "Never": "Ποτέ", + "SwkbdMinCharacters": "Πρέπει να έχει μήκος τουλάχιστον {0} χαρακτήρες", + "SwkbdMinRangeCharacters": "Πρέπει να έχει μήκος {0}-{1} χαρακτήρες", + "SoftwareKeyboard": "Εικονικό Πληκτρολόγιο", + "SoftwareKeyboardModeNumbersOnly": "Must be numbers only", + "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", + "SoftwareKeyboardModeASCII": "Must be ASCII text only", + "DialogControllerAppletMessagePlayerRange": "Η εφαρμογή ζητά {0} παίκτη(ες) με:\n\nΤΥΠΟΥΣ: {1}\n\nΠΑΙΚΤΕΣ: {2}\n\n{3}Παρακαλώ ανοίξτε τις ρυθμίσεις και αλλάξτε τις ρυθμίσεις εισαγωγής τώρα ή πατήστε Κλείσιμο.", + "DialogControllerAppletMessage": "Η εφαρμογή ζητά ακριβώς {0} παίκτη(ες) με:\n\nΤΥΠΟΥΣ: {1}\n\nΠΑΙΚΤΕΣ: {2}\n\n{3}Παρακαλώ ανοίξτε τις ρυθμίσεις και αλλάξτε τις Ρυθμίσεις εισαγωγής τώρα ή πατήστε Κλείσιμο.", + "DialogControllerAppletDockModeSet": "Η κατάσταση Docked ενεργοποιήθηκε. Το συσκευή παλάμης είναι επίσης μην αποδεκτό.", + "UpdaterRenaming": "Μετονομασία Παλαιών Αρχείων...", + "UpdaterRenameFailed": "Δεν ήταν δυνατή η μετονομασία του αρχείου: {0}", + "UpdaterAddingFiles": "Προσθήκη Νέων Αρχείων...", + "UpdaterExtracting": "Εξαγωγή Ενημέρωσης...", + "UpdaterDownloading": "Λήψη Ενημέρωσης...", + "Game": "Παιχνίδι", + "Docked": "Προσκολλημένο", + "Handheld": "Χειροκίνητο", + "ConnectionError": "Σφάλμα Σύνδεσης.", + "AboutPageDeveloperListMore": "{0} και περισσότερα...", + "ApiError": "Σφάλμα API.", + "LoadingHeading": "Φόρτωση {0}", + "CompilingPPTC": "Μεταγλώττιση του PTC", + "CompilingShaders": "Σύνταξη των Shaders", + "AllKeyboards": "Όλα τα πληκτρολόγια", + "OpenFileDialogTitle": "Επιλέξτε ένα υποστηριζόμενο αρχείο για άνοιγμα", + "OpenFolderDialogTitle": "Επιλέξτε ένα φάκελο με ένα αποσυμπιεσμένο παιχνίδι", + "AllSupportedFormats": "Όλες Οι Υποστηριζόμενες Μορφές", + "RyujinxUpdater": "Ryujinx Ενημερωτής", + "SettingsTabHotkeys": "Συντομεύσεις Πληκτρολογίου", + "SettingsTabHotkeysHotkeys": "Συντομεύσεις Πληκτρολογίου", + "SettingsTabHotkeysToggleVsyncHotkey": "Εναλλαγή VSync:", + "SettingsTabHotkeysScreenshotHotkey": "Στιγμιότυπο Οθόνης:", + "SettingsTabHotkeysShowUiHotkey": "Εμφάνιση Διεπαφής Χρήστη:", + "SettingsTabHotkeysPauseHotkey": "Παύση:", + "SettingsTabHotkeysToggleMuteHotkey": "Σίγαση:", + "ControllerMotionTitle": "Ρυθμίσεις Ελέγχου Κίνησης", + "ControllerRumbleTitle": "Ρυθμίσεις Δόνησης", + "SettingsSelectThemeFileDialogTitle": "Επιλογή Αρχείου Θέματος", + "SettingsXamlThemeFile": "Αρχείο Θέματος Xaml", + "AvatarWindowTitle": "Διαχείριση Λογαριασμών - Avatar", "Amiibo": "Amiibo", - "Unknown": "Unknown", - "Usage": "Usage", - "Writable": "Writable", - "SelectDlcDialogTitle": "Select DLC files", - "SelectUpdateDialogTitle": "Select update files", - "UserProfileWindowTitle": "User Profiles Manager", - "CheatWindowTitle": "Cheats Manager", + "Unknown": "Άγνωστο", + "Usage": "Χρήση", + "Writable": "Εγγράψιμο", + "SelectDlcDialogTitle": "Επιλογή αρχείων DLC", + "SelectUpdateDialogTitle": "Επιλογή αρχείων ενημέρωσης", + "UserProfileWindowTitle": "Διαχειριστής Προφίλ Χρήστη", + "CheatWindowTitle": "Διαχειριστής των Cheats", "DlcWindowTitle": "Downloadable Content Manager", - "UpdateWindowTitle": "Title Update Manager", - "CheatWindowHeading": "Cheats Available for {0} [{1}]", + "UpdateWindowTitle": "Διαχειριστής Ενημερώσεων Τίτλου", + "CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", - "UserProfilesEditProfile": "Edit Selected", - "Cancel": "Cancel", - "Save": "Save", - "Discard": "Discard", - "UserProfilesSetProfileImage": "Set Profile Image", - "UserProfileEmptyNameError": "Name is required", - "UserProfileNoImageError": "Profile image must be set", + "UserProfilesEditProfile": "Επεξεργασία Επιλεγμένων", + "Cancel": "Ακύρωση", + "Save": "Αποθήκευση", + "Discard": "Απόρριψη", + "UserProfilesSetProfileImage": "Ορισμός Εικόνας Προφίλ", + "UserProfileEmptyNameError": "Απαιτείται όνομα", + "UserProfileNoImageError": "Η εικόνα προφίλ πρέπει να οριστεί", "GameUpdateWindowHeading": "{0} Update(s) available for {1} ({2})", - "SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:", - "SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:", - "UserProfilesName": "Name:", + "SettingsTabHotkeysResScaleUpHotkey": "Αύξηση της ανάλυσης:", + "SettingsTabHotkeysResScaleDownHotkey": "Μείωση της ανάλυσης:", + "UserProfilesName": "Όνομα:", "UserProfilesUserId": "User Id:", - "SettingsTabGraphicsBackend": "Graphics Backend", - "SettingsTabGraphicsBackendTooltip": "Graphics Backend to use", - "SettingsEnableTextureRecompression": "Enable Texture Recompression", - "SettingsEnableTextureRecompressionTooltip": "Compresses certain textures in order to reduce VRAM usage.\n\nRecommended for use with GPUs that have less than 4GiB VRAM.\n\nLeave OFF if unsure.", - "SettingsTabGraphicsPreferredGpu": "Preferred GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "Select the graphics card that will be used with the Vulkan graphics backend.\n\nDoes not affect the GPU that OpenGL will use.\n\nSet to the GPU flagged as \"dGPU\" if unsure. If there isn't one, leave untouched.", - "SettingsAppRequiredRestartMessage": "Ryujinx Restart Required", - "SettingsGpuBackendRestartMessage": "Graphics Backend or GPU settings have been modified. This will require a restart to be applied", - "SettingsGpuBackendRestartSubMessage": "Do you want to restart now?", - "RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?", - "SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:", - "SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:", - "SettingsEnableMacroHLE": "Enable Macro HLE", - "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", - "VolumeShort": "Vol", - "UserProfilesManageSaves": "Manage Saves", - "DeleteUserSave": "Do you want to delete user save for this game?", - "IrreversibleActionNote": "This action is not reversible.", + "SettingsTabGraphicsBackend": "Σύστημα Υποστήριξης Γραφικών", + "SettingsTabGraphicsBackendTooltip": "Backend Γραφικών που θα χρησιμοποιηθεί", + "SettingsEnableTextureRecompression": "Ενεργοποίηση Επανασυμπίεσης Των Texture", + "SettingsEnableTextureRecompressionTooltip": "Συμπιέζει συγκεκριμένα texture για να μειωθεί η χρήση της VRAM.\nΣυνίσταται για χρήση σε κάρτες γραφικών με λιγότερο από 4 GiB VRAM.\nΑφήστε το Απενεργοποιημένο αν είστε αβέβαιοι.", + "SettingsTabGraphicsPreferredGpu": "Προτιμώμενη GPU", + "SettingsTabGraphicsPreferredGpuTooltip": "Επιλέξτε την κάρτα γραφικών η οποία θα χρησιμοποιηθεί από το Vulkan.\n\nΔεν επηρεάζει το OpenGL.\n\nΔιαλέξτε την GPU που διαθέτει την υπόδειξη \"dGPU\" αν δεν είστε βέβαιοι. Αν δεν υπάρχει κάποιαν, το πειράξετε", + "SettingsAppRequiredRestartMessage": "Απαιτείται Επανεκκίνηση Του Ryujinx", + "SettingsGpuBackendRestartMessage": "Οι ρυθμίσεις GPU έχουν αλλαχτεί. Θα χρειαστεί επανεκκίνηση του Ryujinx για να τεθούν σε ισχύ.", + "SettingsGpuBackendRestartSubMessage": "Θέλετε να κάνετε επανεκκίνηση τώρα;", + "RyujinxUpdaterMessage": "Θέλετε να ενημερώσετε το Ryujinx στην πιο πρόσφατη έκδοση:", + "SettingsTabHotkeysVolumeUpHotkey": "Αύξηση Έντασης:", + "SettingsTabHotkeysVolumeDownHotkey": "Μείωση Έντασης:", + "SettingsEnableMacroHLE": "Ενεργοποίηση του Macro HLE", + "SettingsEnableMacroHLETooltip": "Προσομοίωση του κώδικα GPU Macro .\n\nΒελτιώνει την απόδοση, αλλά μπορεί να προκαλέσει γραφικά προβλήματα σε μερικά παιχνίδια.\n\nΑφήστε ΕΝΕΡΓΟ αν δεν είστε σίγουροι.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", + "VolumeShort": "Έντ.", + "UserProfilesManageSaves": "Διαχείριση Των Save", + "DeleteUserSave": "Επιθυμείτε να διαγράψετε το save χρήστη για το συγκεκριμένο παιχνίδι;", + "IrreversibleActionNote": "Αυτή η ενέργεια είναι μη αναστρέψιμη.", "SaveManagerHeading": "Manage Saves for {0}", - "SaveManagerTitle": "Save Manager", - "Name": "Name", - "Size": "Size", - "Search": "Search", - "UserProfilesRecoverLostAccounts": "Recover Lost Accounts", - "Recover": "Recover", - "UserProfilesRecoverHeading": "Saves were found for the following accounts" -} + "SaveManagerTitle": "Διαχειριστής Save", + "Name": "Όνομα", + "Size": "Μέγεθος", + "Search": "Αναζήτηση", + "UserProfilesRecoverLostAccounts": "Ανάκτηση Χαμένων Λογαριασμών", + "Recover": "Ανάκτηση", + "UserProfilesRecoverHeading": "Βρέθηκαν save για τους ακόλουθους λογαριασμούς", + "UserProfilesRecoverEmptyList": "Δεν υπάρχουν προφίλ για ανάκτηση", + "GraphicsAATooltip": "Εφαρμόζει anti-aliasing στην απόδοση του παιχνιδιού", + "GraphicsAALabel": "Anti-Aliasing", + "GraphicsScalingFilterLabel": "Φίλτρο Κλιμάκωσης:", + "GraphicsScalingFilterTooltip": "Ενεργοποιεί Κλίμακα Framebuffer", + "GraphicsScalingFilterLevelLabel": "Επίπεδο", + "GraphicsScalingFilterLevelTooltip": "Ορισμός Επιπέδου Φίλτρου Κλιμάκωσης", + "SmaaLow": "Χαμηλό SMAA", + "SmaaMedium": " Μεσαίο SMAA", + "SmaaHigh": "Υψηλό SMAA", + "SmaaUltra": "Oύλτρα SMAA", + "UserEditorTitle": "Επεξεργασία Χρήστη", + "UserEditorTitleCreate": "Δημιουργία Χρήστη", + "SettingsTabNetworkInterface": "Διεπαφή Δικτύου", + "NetworkInterfaceTooltip": "Η διεπαφή δικτύου που χρησιμοποιείται για τα χαρακτηριστικά LAN", + "NetworkInterfaceDefault": "Προεπιλογή", + "PackagingShaders": "Shaders Συσκευασίας", + "AboutChangelogButton": "View Changelog on GitHub", + "AboutChangelogButtonTooltipMessage": "Click to open the changelog for this version in your default browser." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json index 617cad34f..72b5e8e3c 100644 --- a/src/Ryujinx.Ava/Assets/Locales/en_US.json +++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json @@ -14,7 +14,7 @@ "MenuBarFileOpenEmuFolder": "Open Ryujinx Folder", "MenuBarFileOpenLogsFolder": "Open Logs Folder", "MenuBarFileExit": "_Exit", - "MenuBarOptions": "Options", + "MenuBarOptions": "_Options", "MenuBarOptionsToggleFullscreen": "Toggle Fullscreen", "MenuBarOptionsStartGamesInFullscreen": "Start Games in Fullscreen Mode", "MenuBarOptionsStopEmulation": "Stop Emulation", @@ -30,7 +30,7 @@ "MenuBarToolsManageFileTypes": "Manage file types", "MenuBarToolsInstallFileTypes": "Install file types", "MenuBarToolsUninstallFileTypes": "Uninstall file types", - "MenuBarHelp": "Help", + "MenuBarHelp": "_Help", "MenuBarHelpCheckForUpdates": "Check for Updates", "MenuBarHelpAbout": "About", "MenuSearch": "Search...", @@ -72,8 +72,17 @@ "GameListContextMenuExtractDataRomFSToolTip": "Extract the RomFS section from Application's current config (including updates)", "GameListContextMenuExtractDataLogo": "Logo", "GameListContextMenuExtractDataLogoToolTip": "Extract the Logo section from Application's current config (including updates)", + "GameListContextMenuCreateShortcut": "Create Application Shortcut", + "GameListContextMenuCreateShortcutToolTip": "Create a Desktop Shortcut that launches the selected Application", "StatusBarGamesLoaded": "{0}/{1} Games Loaded", "StatusBarSystemVersion": "System Version: {0}", + "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", + "LinuxVmMaxMapCountDialogTextPrimary": "Would you like to increase the value of vm.max_map_count to {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Yes, until the next restart", + "LinuxVmMaxMapCountDialogButtonPersistent": "Yes, permanently", + "LinuxVmMaxMapCountWarningTextPrimary": "Max amount of memory mappings is lower than recommended.", + "LinuxVmMaxMapCountWarningTextSecondary": "The current value of vm.max_map_count ({0}) is lower than {1}. Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.\n\nYou might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.", "Settings": "Settings", "SettingsTabGeneral": "User Interface", "SettingsTabGeneralGeneral": "General", @@ -216,26 +225,17 @@ "ControllerSettingsDPadDown": "Down", "ControllerSettingsDPadLeft": "Left", "ControllerSettingsDPadRight": "Right", + "ControllerSettingsStickButton": "Button", + "ControllerSettingsStickUp": "Up", + "ControllerSettingsStickDown": "Down", + "ControllerSettingsStickLeft": "Left", + "ControllerSettingsStickRight": "Right", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "Invert Stick X", + "ControllerSettingsStickInvertYAxis": "Invert Stick Y", + "ControllerSettingsStickDeadzone": "Deadzone:", "ControllerSettingsLStick": "Left Stick", - "ControllerSettingsLStickButton": "Button", - "ControllerSettingsLStickUp": "Up", - "ControllerSettingsLStickDown": "Down", - "ControllerSettingsLStickLeft": "Left", - "ControllerSettingsLStickRight": "Right", - "ControllerSettingsLStickStick": "Stick", - "ControllerSettingsLStickInvertXAxis": "Invert Stick X", - "ControllerSettingsLStickInvertYAxis": "Invert Stick Y", - "ControllerSettingsLStickDeadzone": "Deadzone:", "ControllerSettingsRStick": "Right Stick", - "ControllerSettingsRStickButton": "Button", - "ControllerSettingsRStickUp": "Up", - "ControllerSettingsRStickDown": "Down", - "ControllerSettingsRStickLeft": "Left", - "ControllerSettingsRStickRight": "Right", - "ControllerSettingsRStickStick": "Stick", - "ControllerSettingsRStickInvertXAxis": "Invert Stick X", - "ControllerSettingsRStickInvertYAxis": "Invert Stick Y", - "ControllerSettingsRStickDeadzone": "Deadzone:", "ControllerSettingsTriggersLeft": "Triggers Left", "ControllerSettingsTriggersRight": "Triggers Right", "ControllerSettingsTriggersButtonsLeft": "Trigger Buttons Left", @@ -291,6 +291,7 @@ "ControllerSettingsSaveProfileToolTip": "Save Profile", "MenuBarFileToolsTakeScreenshot": "Take Screenshot", "MenuBarFileToolsHideUi": "Hide UI", + "GameListContextMenuRunApplication": "Run Application", "GameListContextMenuToggleFavorite": "Toggle Favorite", "GameListContextMenuToggleFavoriteToolTip": "Toggle Favorite status of Game", "SettingsTabGeneralTheme": "Theme", @@ -545,9 +546,13 @@ "SwkbdMinCharacters": "Must be at least {0} characters long", "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long", "SoftwareKeyboard": "Software Keyboard", - "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n", + "SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only", + "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", + "SoftwareKeyboardModeASCII": "Must be ASCII text only", + "ControllerAppletControllers": "Supported Controllers:", + "ControllerAppletPlayers": "Players:", + "ControllerAppletDescription": "Your current configuration is invalid. Open settings and reconfigure your inputs.", + "ControllerAppletDocked": "Docked mode set. Handheld control should be disabled.", "UpdaterRenaming": "Renaming Old Files...", "UpdaterRenameFailed": "Updater was unable to rename file: {0}", "UpdaterAddingFiles": "Adding New Files...", @@ -590,11 +595,13 @@ "DlcWindowTitle": "Manage Downloadable Content for {0} ({1})", "UpdateWindowTitle": "Title Update Manager", "CheatWindowHeading": "Cheats Available for {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "{0} Downloadable Content(s)", "UserProfilesEditProfile": "Edit Selected", "Cancel": "Cancel", "Save": "Save", "Discard": "Discard", + "Paused": "Paused", "UserProfilesSetProfileImage": "Set Profile Image", "UserProfileEmptyNameError": "Name is required", "UserProfileNoImageError": "Profile image must be set", @@ -617,6 +624,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:", "SettingsEnableMacroHLE": "Enable Macro HLE", "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", "VolumeShort": "Vol", "UserProfilesManageSaves": "Manage Saves", "DeleteUserSave": "Do you want to delete user save for this game?", @@ -628,7 +637,7 @@ "Search": "Search", "UserProfilesRecoverLostAccounts": "Recover Lost Accounts", "Recover": "Recover", - "UserProfilesRecoverHeading" : "Saves were found for the following accounts", + "UserProfilesRecoverHeading": "Saves were found for the following accounts", "UserProfilesRecoverEmptyList": "No profiles to recover", "GraphicsAATooltip": "Applies anti-aliasing to the game render", "GraphicsAALabel": "Anti-Aliasing:", @@ -640,9 +649,15 @@ "SmaaMedium": "SMAA Medium", "SmaaHigh": "SMAA High", "SmaaUltra": "SMAA Ultra", - "UserEditorTitle" : "Edit User", - "UserEditorTitleCreate" : "Create User", + "UserEditorTitle": "Edit User", + "UserEditorTitleCreate": "Create User", "SettingsTabNetworkInterface": "Network Interface:", - "NetworkInterfaceTooltip": "The network interface used for LAN features", - "NetworkInterfaceDefault": "Default" + "NetworkInterfaceTooltip": "The network interface used for LAN/LDN features", + "NetworkInterfaceDefault": "Default", + "PackagingShaders": "Packaging Shaders", + "AboutChangelogButton": "View Changelog on GitHub", + "AboutChangelogButtonTooltipMessage": "Click to open the changelog for this version in your default browser.", + "SettingsTabNetworkMultiplayer": "Multiplayer", + "MultiplayerMode": "Mode:", + "MultiplayerModeTooltip": "Change multiplayer mode" } diff --git a/src/Ryujinx.Ava/Assets/Locales/es_ES.json b/src/Ryujinx.Ava/Assets/Locales/es_ES.json index 13b05fc04..91bcd8f11 100644 --- a/src/Ryujinx.Ava/Assets/Locales/es_ES.json +++ b/src/Ryujinx.Ava/Assets/Locales/es_ES.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "Software", "SettingsTabSystemMemoryManagerModeHost": "Host (rápido)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host sin verificación (más rápido, inseguro)", + "SettingsTabSystemUseHypervisor": "Usar hipervisor", "MenuBarFile": "_Archivo", "MenuBarFileOpenFromFile": "_Cargar aplicación desde un archivo", "MenuBarFileOpenUnpacked": "Cargar juego _desempaquetado", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "Instalar firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware desde un archivo XCI o ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware desde una carpeta", + "MenuBarToolsManageFileTypes": "Administrar tipos de archivo", + "MenuBarToolsInstallFileTypes": "Instalar tipos de archivo", + "MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo", "MenuBarHelp": "Ayuda", "MenuBarHelpCheckForUpdates": "Buscar actualizaciones", "MenuBarHelpAbout": "Acerca de", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Extraer la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones)", "StatusBarGamesLoaded": "{0}/{1} juegos cargados", "StatusBarSystemVersion": "Versión del sistema: {0}", + "LinuxVmMaxMapCountDialogTitle": "Límite inferior para mapeos de memoria detectado", + "LinuxVmMaxMapCountDialogTextPrimary": "¿Quieres aumentar el valor de vm.max_map_count a {0}?", + "LinuxVmMaxMapCountDialogTextSecondary": "Algunos juegos podrían intentar crear más mapeos de memoria de los permitidos. Ryujinx se bloqueará tan pronto como se supere este límite.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Sí, hasta el próximo reinicio", + "LinuxVmMaxMapCountDialogButtonPersistent": "Si, permanentemente", + "LinuxVmMaxMapCountWarningTextPrimary": "La cantidad máxima de mapeos de memoria es menor de lo recomendado.", + "LinuxVmMaxMapCountWarningTextSecondary": "El valor actual de vm.max_map_count ({0}) es menor que {1}. Algunos juegos podrían intentar crear más mapeos de memoria de los permitidos actualmente. Ryujinx se bloqueará tan pronto como se supere este límite.\n\nPuede que desee aumentar manualmente el límite o instalar pkexec, lo que permite a Ryujinx ayudar con eso.", "Settings": "Configuración", "SettingsTabGeneral": "Interfaz de usuario", "SettingsTabGeneralGeneral": "General", "SettingsTabGeneralEnableDiscordRichPresence": "Habilitar estado en Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Buscar actualizaciones al iniciar", "SettingsTabGeneralShowConfirmExitDialog": "Mostrar diálogo de confirmación al cerrar", + "SettingsTabGeneralHideCursor": "Esconder el cursor:", + "SettingsTabGeneralHideCursorNever": "Nunca", "SettingsTabGeneralHideCursorOnIdle": "Ocultar cursor cuando esté inactivo", + "SettingsTabGeneralHideCursorAlways": "Siempre", "SettingsTabGeneralGameDirectories": "Carpetas de juegos", "SettingsTabGeneralAdd": "Agregar", "SettingsTabGeneralRemove": "Quitar", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Habilitar registros de Fs Access", "SettingsTabLoggingFsGlobalAccessLogMode": "Modo de registros Fs Global Access:", "SettingsTabLoggingDeveloperOptions": "Opciones de desarrollador (ADVERTENCIA: empeorarán el rendimiento)", + "SettingsTabLoggingDeveloperOptionsNote": "ADVERTENCIA: Reducirá el rendimiento", "SettingsTabLoggingGraphicsBackendLogLevel": "Nivel de registro de backend gráficos:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Nada", "SettingsTabLoggingGraphicsBackendLogLevelError": "Errores", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Abajo", "ControllerSettingsDPadLeft": "Izquierda", "ControllerSettingsDPadRight": "Derecha", + "ControllerSettingsStickButton": "Botón", + "ControllerSettingsStickUp": "Arriba", + "ControllerSettingsStickDown": "Abajo", + "ControllerSettingsStickLeft": "Izquierda", + "ControllerSettingsStickRight": "Derecha", + "ControllerSettingsStickStick": "Palanca", + "ControllerSettingsStickInvertXAxis": "Invertir eje X", + "ControllerSettingsStickInvertYAxis": "Invertir eje Y", + "ControllerSettingsStickDeadzone": "Zona muerta:", "ControllerSettingsLStick": "Palanca izquierda", - "ControllerSettingsLStickButton": "Botón (L3)", - "ControllerSettingsLStickUp": "Arriba", - "ControllerSettingsLStickDown": "Abajo", - "ControllerSettingsLStickLeft": "Izquierda", - "ControllerSettingsLStickRight": "Derecha", - "ControllerSettingsLStickStick": "Palanca", - "ControllerSettingsLStickInvertXAxis": "Invertir eje X", - "ControllerSettingsLStickInvertYAxis": "Invertir eje Y", - "ControllerSettingsLStickDeadzone": "Zona muerta:", "ControllerSettingsRStick": "Palanca derecha", - "ControllerSettingsRStickButton": "Botón (R3)", - "ControllerSettingsRStickUp": "Arriba", - "ControllerSettingsRStickDown": "Abajo", - "ControllerSettingsRStickLeft": "Izquierda", - "ControllerSettingsRStickRight": "Derecha", - "ControllerSettingsRStickStick": "Palanca", - "ControllerSettingsRStickInvertXAxis": "Invertir eje X", - "ControllerSettingsRStickInvertYAxis": "Invertir eje Y", - "ControllerSettingsRStickDeadzone": "Zona muerta:", "ControllerSettingsTriggersLeft": "Gatillos izquierdos", "ControllerSettingsTriggersRight": "Gatillos derechos", "ControllerSettingsTriggersButtonsLeft": "Botones de gatillo izquierdos", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Añadir nuevo perfil", "UserProfilesDelete": "Eliminar", "UserProfilesClose": "Cerrar", + "ProfileNameSelectionWatermark": "Escoge un apodo", "ProfileImageSelectionTitle": "Selección de imagen de perfil", "ProfileImageSelectionHeader": "Elige una imagen de perfil", "ProfileImageSelectionNote": "Puedes importar una imagen de perfil personalizada, o seleccionar un avatar del firmware de sistema", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Guardar perfil", "MenuBarFileToolsTakeScreenshot": "Captura de pantalla", "MenuBarFileToolsHideUi": "Ocultar interfaz", + "GameListContextMenuRunApplication": "Ejecutar aplicación", "GameListContextMenuToggleFavorite": "Marcar favorito", "GameListContextMenuToggleFavoriteToolTip": "Marca o desmarca el juego como favorito", "SettingsTabGeneralTheme": "Tema", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "No se encontró firmware instalado pero Ryujinx pudo instalar el firmware {0} a partir de este juego.\nA continuación, se iniciará el emulador.", "DialogFirmwareNoFirmwareInstalledMessage": "No hay firmware instalado", "DialogFirmwareInstalledMessage": "Se instaló el firmware {0}", + "DialogInstallFileTypesSuccessMessage": "¡Tipos de archivos instalados con éxito!", + "DialogInstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.", + "DialogUninstallFileTypesSuccessMessage": "¡Tipos de archivos desinstalados con éxito!", + "DialogUninstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.", "DialogOpenSettingsWindowLabel": "Abrir ventana de opciones", "DialogControllerAppletTitle": "Applet de mandos", "DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versión de sistema {0} instalada con éxito.", "DialogUserProfileDeletionWarningMessage": "Si eliminas el perfil seleccionado no quedará ningún otro perfil", "DialogUserProfileDeletionConfirmMessage": "¿Quieres eliminar el perfil seleccionado?", + "DialogUserProfileUnsavedChangesTitle": "Advertencia - Cambios sin guardar", + "DialogUserProfileUnsavedChangesMessage": "Ha realizado cambios en este perfil de usuario que no han sido guardados.", + "DialogUserProfileUnsavedChangesSubMessage": "¿Quieres descartar los cambios realizados?", "DialogControllerSettingsModifiedConfirmMessage": "Se ha actualizado la configuración del mando actual.", "DialogControllerSettingsModifiedConfirmSubMessage": "¿Guardar cambios?", "DialogLoadNcaErrorMessage": "{0}. Archivo con error: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Activar todas", "DlcManagerDisableAllButton": "Desactivar todos", "MenuBarOptionsChangeLanguage": "Cambiar idioma", + "MenuBarShowFileTypes": "Mostrar tipos de archivo", "CommonSort": "Orden", "CommonShowNames": "Mostrar nombres", "CommonFavorite": "Favorito", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Usa una tabla de paginación de software para traducir direcciones. Ofrece la precisión más exacta pero el rendimiento más lento.", "MemoryManagerHostTooltip": "Mapea la memoria directamente en la dirección de espacio del host. Compilación y ejecución JIT mucho más rápida.", "MemoryManagerUnsafeTooltip": "Mapea la memoria directamente, pero no enmascara la dirección dentro del espacio de dirección del guest antes del acceso. El modo más rápido, pero a costa de seguridad. La aplicación guest puede acceder a la memoria desde cualquier parte en Ryujinx, así que ejecuta solo programas en los que confíes cuando uses este modo.", + "UseHypervisorTooltip": "Usar Hypervisor en lugar de JIT. Mejora enormemente el rendimiento cuando está disponible, pero puede ser inestable en su estado actual.", "DRamTooltip": "Expande la memoria DRAM del sistema emulado de 4GiB a 6GiB.\n\nUtilizar solo con packs de texturas HD o mods de resolución 4K. NO mejora el rendimiento.\n\nDesactívalo si no sabes qué hacer.", "IgnoreMissingServicesTooltip": "Hack para ignorar servicios no implementados del Horizon OS. Esto puede ayudar a sobrepasar crasheos cuando inicies ciertos juegos.\n\nDesactívalo si no sabes qué hacer.", "GraphicsBackendThreadingTooltip": "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 multihilado. Rendimiento máximo ligeramente superior en controladores gráficos que soporten multihilado.\n\nSelecciona \"Auto\" si no sabes qué hacer.", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Debe tener al menos {0} caracteres", "SwkbdMinRangeCharacters": "Debe tener {0}-{1} caracteres", "SoftwareKeyboard": "Teclado de software", + "SoftwareKeyboardModeNumbersOnly": "Solo deben ser números", + "SoftwareKeyboardModeAlphabet": "Solo deben ser caracteres no CJK", + "SoftwareKeyboardModeASCII": "Solo deben ser texto ASCII", "DialogControllerAppletMessagePlayerRange": "La aplicación require {0} jugador(es) con:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Por favor abre las opciones y reconfigura los dispositivos de entrada o presiona 'Cerrar'.", "DialogControllerAppletMessage": "La aplicación require exactamente {0} jugador(es) con:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Por favor abre las opciones y reconfigura los dispositivos de entrada o presiona 'Cerrar'.", "DialogControllerAppletDockModeSet": "Modo dock/TV activo. El control portátil también es inválido.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Administrar contenido descargable", "UpdateWindowTitle": "Administrar actualizaciones", "CheatWindowHeading": "Cheats disponibles para {0} [{1}]", + "BuildId": "Id de compilación:", "DlcWindowHeading": "Contenido descargable disponible para {0} [{1}]", "UserProfilesEditProfile": "Editar selección", "Cancel": "Cancelar", @@ -586,29 +607,50 @@ "UserProfilesName": "Nombre:", "UserProfilesUserId": "Id de Usuario:", "SettingsTabGraphicsBackend": "Fondo de gráficos", - "SettingsTabGraphicsBackendTooltip": "Graphics Backend to use", - "SettingsEnableTextureRecompression": "Enable Texture Recompression", - "SettingsEnableTextureRecompressionTooltip": "Compresses certain textures in order to reduce VRAM usage.\n\nRecommended for use with GPUs that have less than 4GiB VRAM.\n\nLeave OFF if unsure.", - "SettingsTabGraphicsPreferredGpu": "Preferred GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "Select the graphics card that will be used with the Vulkan graphics backend.\n\nDoes not affect the GPU that OpenGL will use.\n\nSet to the GPU flagged as \"dGPU\" if unsure. If there isn't one, leave untouched.", - "SettingsAppRequiredRestartMessage": "Ryujinx Restart Required", - "SettingsGpuBackendRestartMessage": "Graphics Backend or GPU settings have been modified. This will require a restart to be applied", - "SettingsGpuBackendRestartSubMessage": "Do you want to restart now?", - "RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?", - "SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:", - "SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:", - "SettingsEnableMacroHLE": "Enable Macro HLE", - "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", - "VolumeShort": "Vol", - "UserProfilesManageSaves": "Manage Saves", - "DeleteUserSave": "Do you want to delete user save for this game?", - "IrreversibleActionNote": "This action is not reversible.", + "SettingsTabGraphicsBackendTooltip": "Back-end de los gráficos a utilizar", + "SettingsEnableTextureRecompression": "Activar recompresión de texturas", + "SettingsEnableTextureRecompressionTooltip": "Comprime ciertas texturas para reducir el uso de la VRAM.\n\nRecomendado para GPUs que tienen menos de 4 GB de VRAM.\n\nMantén esta opción desactivada si no estás seguro.", + "SettingsTabGraphicsPreferredGpu": "GPU preferida", + "SettingsTabGraphicsPreferredGpuTooltip": "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.", + "SettingsAppRequiredRestartMessage": "Reinicio de Ryujinx requerido.", + "SettingsGpuBackendRestartMessage": "La configuración de la GPU o del back-end de los gráficos fue modificada. Es necesario reiniciar para que se aplique.", + "SettingsGpuBackendRestartSubMessage": "¿Quieres reiniciar ahora?", + "RyujinxUpdaterMessage": "¿Quieres actualizar Ryujinx a la última versión?", + "SettingsTabHotkeysVolumeUpHotkey": "Aumentar volumen:", + "SettingsTabHotkeysVolumeDownHotkey": "Disminuir volumen:", + "SettingsEnableMacroHLE": "Activar Macros HLE", + "SettingsEnableMacroHLETooltip": "Emulación alto-nivel del código de Macros de GPU\n\nIncrementa el rendimiento, pero puede causar errores gráficos en algunos juegos.\n\nDeja esta opción activada si no estás seguro.", + "SettingsEnableColorSpacePassthrough": "Paso de espacio de color", + "SettingsEnableColorSpacePassthroughTooltip": "Dirige el backend de Vulkan a pasar a través de la información del color sin especificar un espacio de color. Para los usuarios con pantallas de gran gama, esto puede resultar en colores más vibrantes, a costa de la corrección del color.", + "VolumeShort": "Volumen", + "UserProfilesManageSaves": "Administrar mis partidas guardadas", + "DeleteUserSave": "¿Quieres borrar los datos de usuario de este juego?", + "IrreversibleActionNote": "Esta acción no es reversible.", "SaveManagerHeading": "Manage Saves for {0}", - "SaveManagerTitle": "Save Manager", - "Name": "Name", - "Size": "Size", - "Search": "Search", - "UserProfilesRecoverLostAccounts": "Recover Lost Accounts", - "Recover": "Recover", - "UserProfilesRecoverHeading": "Saves were found for the following accounts" -} + "SaveManagerTitle": "Administrador de datos de guardado.", + "Name": "Nombre", + "Size": "Tamaño", + "Search": "Buscar", + "UserProfilesRecoverLostAccounts": "Recuperar cuentas perdidas", + "Recover": "Recuperar", + "UserProfilesRecoverHeading": "Datos de guardado fueron encontrados para las siguientes cuentas", + "UserProfilesRecoverEmptyList": "No hay perfiles a recuperar", + "GraphicsAATooltip": "Aplica el suavizado de bordes al procesamiento del juego", + "GraphicsAALabel": "Suavizado de bordes:", + "GraphicsScalingFilterLabel": "Filtro de escalado:", + "GraphicsScalingFilterTooltip": "Activa el escalado de búfer de fotogramas", + "GraphicsScalingFilterLevelLabel": "Nivel", + "GraphicsScalingFilterLevelTooltip": "Establecer nivel del filtro de escalado", + "SmaaLow": "SMAA Bajo", + "SmaaMedium": "SMAA Medio", + "SmaaHigh": "SMAA Alto", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Editar usuario", + "UserEditorTitleCreate": "Crear Usuario", + "SettingsTabNetworkInterface": "Interfaz de Red", + "NetworkInterfaceTooltip": "Interfaz de red usada para las características LAN", + "NetworkInterfaceDefault": "Predeterminado", + "PackagingShaders": "Empaquetando sombreadores", + "AboutChangelogButton": "Ver registro de cambios en GitHub", + "AboutChangelogButtonTooltipMessage": "Haga clic para abrir el registro de cambios para esta versión en su navegador predeterminado." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/fr_FR.json b/src/Ryujinx.Ava/Assets/Locales/fr_FR.json index fad46751a..5bab6f7b2 100644 --- a/src/Ryujinx.Ava/Assets/Locales/fr_FR.json +++ b/src/Ryujinx.Ava/Assets/Locales/fr_FR.json @@ -1,43 +1,47 @@ { "Language": "Français", "MenuBarFileOpenApplet": "Ouvrir Applet", - "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Ouvrir l'Applet Mii Editor en mode Standalone", + "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Ouvrir l'Éditeur Applet Mii en mode autonome", "SettingsTabInputDirectMouseAccess": "Accès direct à la souris", - "SettingsTabSystemMemoryManagerMode": "Mode de gestion mémoire :", + "SettingsTabSystemMemoryManagerMode": "Mode de gestion de la mémoire :", "SettingsTabSystemMemoryManagerModeSoftware": "Logiciel", "SettingsTabSystemMemoryManagerModeHost": "Hôte (rapide)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Hôte non vérifié (plus rapide, non sécurisé)", + "SettingsTabSystemUseHypervisor": "Utiliser l'Hyperviseur", "MenuBarFile": "_Fichier", "MenuBarFileOpenFromFile": "_Charger un jeu depuis un fichier", - "MenuBarFileOpenUnpacked": "Charger un jeu _extrait", + "MenuBarFileOpenUnpacked": "Charger un jeu extrait", "MenuBarFileOpenEmuFolder": "Ouvrir le dossier Ryujinx", "MenuBarFileOpenLogsFolder": "Ouvrir le dossier des journaux", "MenuBarFileExit": "_Quitter", "MenuBarOptions": "Options", "MenuBarOptionsToggleFullscreen": "Basculer en plein écran", - "MenuBarOptionsStartGamesInFullscreen": "Démarrer le jeu en plein écran", + "MenuBarOptionsStartGamesInFullscreen": "Démarrer jeux en plein écran", "MenuBarOptionsStopEmulation": "Arrêter l'émulation", "MenuBarOptionsSettings": "_Paramètres", - "MenuBarOptionsManageUserProfiles": "_Gêrer les profils d'utilisateurs", + "MenuBarOptionsManageUserProfiles": "_Gérer les profils d'utilisateurs", "MenuBarActions": "_Actions", - "MenuBarOptionsSimulateWakeUpMessage": "Simuler une sortie de veille", + "MenuBarOptionsSimulateWakeUpMessage": "Simuler un message de réveil", "MenuBarActionsScanAmiibo": "Scanner un Amiibo", "MenuBarTools": "_Outils", "MenuBarToolsInstallFirmware": "Installer un firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Installer un firmware depuis un fichier XCI ou ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Installer un firmware depuis un dossier", + "MenuBarToolsManageFileTypes": "Gérer les types de fichiers", + "MenuBarToolsInstallFileTypes": "Installer les types de fichiers", + "MenuBarToolsUninstallFileTypes": "Désinstaller les types de fichiers", "MenuBarHelp": "Aide", "MenuBarHelpCheckForUpdates": "Vérifier les mises à jour", "MenuBarHelpAbout": "Á propos", "MenuSearch": "Rechercher...", "GameListHeaderFavorite": "Favoris", "GameListHeaderIcon": "Icône", - "GameListHeaderApplication": "Application", + "GameListHeaderApplication": "Nom", "GameListHeaderDeveloper": "Développeur", "GameListHeaderVersion": "Version", "GameListHeaderTimePlayed": "Temps de jeu", - "GameListHeaderLastPlayed": "Dernière partie", - "GameListHeaderFileExtension": "Extension du Fichier", + "GameListHeaderLastPlayed": "jouer la dernière fois", + "GameListHeaderFileExtension": "Fichier externe", "GameListHeaderFileSize": "Taille du Fichier", "GameListHeaderPath": "Chemin", "GameListContextMenuOpenUserSaveDirectory": "Ouvrir le dossier de sauvegarde utilisateur", @@ -46,8 +50,8 @@ "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "Ouvre le dossier contenant la sauvegarde console du jeu", "GameListContextMenuOpenBcatSaveDirectory": "Ouvrir le dossier de sauvegarde BCAT", "GameListContextMenuOpenBcatSaveDirectoryToolTip": "Ouvre le dossier contenant la sauvegarde BCAT du jeu", - "GameListContextMenuManageTitleUpdates": "Gérer les mises à jour", - "GameListContextMenuManageTitleUpdatesToolTip": "Ouvre la fenêtre de gestion des mises à jour", + "GameListContextMenuManageTitleUpdates": "Gérer la mise à jour des titres", + "GameListContextMenuManageTitleUpdatesToolTip": "Ouvre la fenêtre de gestion de la mise à jour des titres", "GameListContextMenuManageDlc": "Gérer les DLC", "GameListContextMenuManageDlcToolTip": "Ouvre la fenêtre de gestion des DLC", "GameListContextMenuOpenModsDirectory": "Ouvrir le dossier des Mods", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Extrait la section Logo du jeu (mise à jour incluse)", "StatusBarGamesLoaded": "{0}/{1} Jeux chargés", "StatusBarSystemVersion": "Version du Firmware: {0}", + "LinuxVmMaxMapCountDialogTitle": "Limite basse pour les mappages de mémoire détectés", + "LinuxVmMaxMapCountDialogTextPrimary": "Voulez-vous augmenter la valeur de vm.max_map_count à {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Certains jeux peuvent essayer de créer plus de mappages de mémoire que ce qui est actuellement autorisé. Ryujinx plantera dès que cette limite sera dépassée.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Oui, jusqu'au prochain redémarrage", + "LinuxVmMaxMapCountDialogButtonPersistent": "Oui, en permanence", + "LinuxVmMaxMapCountWarningTextPrimary": "La quantité maximale de mappings mémoire est inférieure à la valeur recommandée.", + "LinuxVmMaxMapCountWarningTextSecondary": "La valeur actuelle de vm.max_map_count ({0}) est inférieure à {1}. Certains jeux peuvent essayer de créer plus de mappings mémoire que ceux actuellement autorisés. Ryujinx s'écrasera dès que cette limite sera dépassée.\n\nVous pouvez soit augmenter manuellement la limite, soit installer pkexec, ce qui permet à Ryujinx de l'aider.", "Settings": "Paramètres", - "SettingsTabGeneral": "Général", + "SettingsTabGeneral": "Interface Utilisateur", "SettingsTabGeneralGeneral": "Général", - "SettingsTabGeneralEnableDiscordRichPresence": "Active Discord Rich Presence", + "SettingsTabGeneralEnableDiscordRichPresence": "Activer Discord Rich Presence", "SettingsTabGeneralCheckUpdatesOnLaunch": "Vérifier les mises à jour au démarrage", - "SettingsTabGeneralShowConfirmExitDialog": "Afficher le message de \"Confirmation de fermeture\"", + "SettingsTabGeneralShowConfirmExitDialog": "Afficher le message de \"Confirmation de sortie\"", + "SettingsTabGeneralHideCursor": "Masquer le Curseur :", + "SettingsTabGeneralHideCursorNever": "Jamais", "SettingsTabGeneralHideCursorOnIdle": "Masquer le curseur si inactif", + "SettingsTabGeneralHideCursorAlways": "Toujours", "SettingsTabGeneralGameDirectories": "Dossiers de Jeux", "SettingsTabGeneralAdd": "Ajouter", "SettingsTabGeneralRemove": "Supprimer", @@ -92,7 +106,7 @@ "SettingsTabSystemSystemRegionTaiwan": "Taïwan", "SettingsTabSystemSystemLanguage": "Langue du système:", "SettingsTabSystemSystemLanguageJapanese": "Japonais", - "SettingsTabSystemSystemLanguageAmericanEnglish": "Américain", + "SettingsTabSystemSystemLanguageAmericanEnglish": "Anglais Américain", "SettingsTabSystemSystemLanguageFrench": "Français", "SettingsTabSystemSystemLanguageGerman": "Allemand", "SettingsTabSystemSystemLanguageItalian": "Italien", @@ -103,25 +117,25 @@ "SettingsTabSystemSystemLanguagePortuguese": "Portugais", "SettingsTabSystemSystemLanguageRussian": "Russe", "SettingsTabSystemSystemLanguageTaiwanese": "Taïwanais", - "SettingsTabSystemSystemLanguageBritishEnglish": "Anglais", - "SettingsTabSystemSystemLanguageCanadianFrench": "Canadien", + "SettingsTabSystemSystemLanguageBritishEnglish": "Anglais britannique ", + "SettingsTabSystemSystemLanguageCanadianFrench": "Français Canadien", "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Espagnol latino-américain", "SettingsTabSystemSystemLanguageSimplifiedChinese": "Chinois simplifié", "SettingsTabSystemSystemLanguageTraditionalChinese": "Chinois traditionnel", - "SettingsTabSystemSystemTimeZone": "Fuseau horaire du système:", + "SettingsTabSystemSystemTimeZone": "Fuseau horaire du système :", "SettingsTabSystemSystemTime": "Heure du système:", - "SettingsTabSystemEnableVsync": "Activer la VSync", + "SettingsTabSystemEnableVsync": "Activer le VSync", "SettingsTabSystemEnablePptc": "Activer le PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnableFsIntegrityChecks": "Activer la vérification de l'intégrité du système de fichiers", - "SettingsTabSystemAudioBackend": "Bibliothèque Audio :", + "SettingsTabSystemAudioBackend": "Back-end audio", "SettingsTabSystemAudioBackendDummy": "Factice", "SettingsTabSystemAudioBackendOpenAL": "OpenAL", "SettingsTabSystemAudioBackendSoundIO": "SoundIO", "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": " (Cela peut causer des instabilités)", - "SettingsTabSystemExpandDramSize": "Augmenter la taille de la DRAM à 6GiB", - "SettingsTabSystemIgnoreMissingServices": "Ignorer les services manquant", + "SettingsTabSystemExpandDramSize": "Utiliser disposition alternative de la mémoire (développeur)", + "SettingsTabSystemIgnoreMissingServices": "Ignorer les services manquants", "SettingsTabGraphics": "Graphique", "SettingsTabGraphicsAPI": "API Graphique", "SettingsTabGraphicsEnableShaderCache": "Activer le cache des shaders", @@ -132,12 +146,12 @@ "SettingsTabGraphicsAnisotropicFiltering8x": "x8", "SettingsTabGraphicsAnisotropicFiltering16x": "x16", "SettingsTabGraphicsResolutionScale": "Échelle de résolution:", - "SettingsTabGraphicsResolutionScaleCustom": "Customisée (Non recommandée)", + "SettingsTabGraphicsResolutionScaleCustom": "Personnalisée (Non recommandée)", "SettingsTabGraphicsResolutionScaleNative": "Natif (720p/1080p)", "SettingsTabGraphicsResolutionScale2x": "x2 (1440p/2160p)", "SettingsTabGraphicsResolutionScale3x": "x3 (2160p/3240p)", "SettingsTabGraphicsResolutionScale4x": "x4 (2880p/4320p)", - "SettingsTabGraphicsAspectRatio": "Format:", + "SettingsTabGraphicsAspectRatio": "Format :", "SettingsTabGraphicsAspectRatio4x3": "4:3", "SettingsTabGraphicsAspectRatio16x9": "16:9", "SettingsTabGraphicsAspectRatio16x10": "16:10", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Activer les journaux des accès au système de fichiers", "SettingsTabLoggingFsGlobalAccessLogMode": "Niveau des journaux des accès au système de fichiers:", "SettingsTabLoggingDeveloperOptions": "Options développeur (ATTENTION: Cela peut réduire les performances)", + "SettingsTabLoggingDeveloperOptionsNote": "ATTENTION : Réduira les performances", "SettingsTabLoggingGraphicsBackendLogLevel": "Niveau du journal du backend graphique :", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Aucun", "SettingsTabLoggingGraphicsBackendLogLevelError": "Erreur", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Bas", "ControllerSettingsDPadLeft": "Gauche", "ControllerSettingsDPadRight": "Droite", + "ControllerSettingsStickButton": "Bouton", + "ControllerSettingsStickUp": "Haut", + "ControllerSettingsStickDown": "Bas", + "ControllerSettingsStickLeft": "Gauche", + "ControllerSettingsStickRight": "Droite", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "Inverser l'axe X", + "ControllerSettingsStickInvertYAxis": "Inverser l'axe Y", + "ControllerSettingsStickDeadzone": "Zone morte :", "ControllerSettingsLStick": "Joystick Gauche", - "ControllerSettingsLStickButton": "Bouton", - "ControllerSettingsLStickUp": "Haut", - "ControllerSettingsLStickDown": "Bas", - "ControllerSettingsLStickLeft": "Gauche", - "ControllerSettingsLStickRight": "Droite", - "ControllerSettingsLStickStick": "Joystick", - "ControllerSettingsLStickInvertXAxis": "Inverser l'axe X", - "ControllerSettingsLStickInvertYAxis": "Inverser l'axe Y", - "ControllerSettingsLStickDeadzone": "Zone morte:", "ControllerSettingsRStick": "Joystick Droit", - "ControllerSettingsRStickButton": "Bouton", - "ControllerSettingsRStickUp": "Haut", - "ControllerSettingsRStickDown": "Bas", - "ControllerSettingsRStickLeft": "Gauche", - "ControllerSettingsRStickRight": "Droite", - "ControllerSettingsRStickStick": "Joystick", - "ControllerSettingsRStickInvertXAxis": "Inverser l'axe X", - "ControllerSettingsRStickInvertYAxis": "Inverser l'axe Y", - "ControllerSettingsRStickDeadzone": "Zone morte:", "ControllerSettingsTriggersLeft": "Gachettes Gauche", "ControllerSettingsTriggersRight": "Gachettes Droite", "ControllerSettingsTriggersButtonsLeft": "Boutons Gachettes Gauche", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Ajouter un nouveau profil", "UserProfilesDelete": "Supprimer", "UserProfilesClose": "Fermer", + "ProfileNameSelectionWatermark": "Choisir un pseudo", "ProfileImageSelectionTitle": "Sélection de l'image du profil", "ProfileImageSelectionHeader": "Choisir l'image du profil", "ProfileImageSelectionNote": "Vous pouvez importer une image de profil personnalisée ou sélectionner un avatar à partir du firmware", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Enregistrer un profil", "MenuBarFileToolsTakeScreenshot": "Prendre une Capture d'Écran", "MenuBarFileToolsHideUi": "Masquer l'interface utilisateur", + "GameListContextMenuRunApplication": "Démarrer l'application", "GameListContextMenuToggleFavorite": "Ajouter/Retirer des favoris", "GameListContextMenuToggleFavoriteToolTip": "Activer/désactiver le statut favori du jeu", "SettingsTabGeneralTheme": "Thème", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Aucun firmware installé n'a été trouvé mais Ryujinx a pu installer le firmware {0} à partir du jeu fourni.\\nL'émulateur va maintenant démarrer.", "DialogFirmwareNoFirmwareInstalledMessage": "Aucun Firmware installé", "DialogFirmwareInstalledMessage": "Le firmware {0} a été installé", + "DialogInstallFileTypesSuccessMessage": "Types de fichiers installés avec succès!", + "DialogInstallFileTypesErrorMessage": "Échec de l'installation des types de fichiers.", + "DialogUninstallFileTypesSuccessMessage": "Types de fichiers désinstallés avec succès!", + "DialogUninstallFileTypesErrorMessage": "Échec de la désinstallation des types de fichiers.", "DialogOpenSettingsWindowLabel": "Ouvrir la fenêtre de configuration", "DialogControllerAppletTitle": "Controller Applet", "DialogMessageDialogErrorExceptionMessage": "Erreur lors de l'affichage de la boîte de dialogue : {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Version du système {0} installée avec succès.", "DialogUserProfileDeletionWarningMessage": "Il n'y aurait aucun autre profil à ouvrir si le profil sélectionné est supprimé", "DialogUserProfileDeletionConfirmMessage": "Voulez-vous supprimer le profil sélectionné ?", + "DialogUserProfileUnsavedChangesTitle": "Avertissement - Modifications non enregistrées", + "DialogUserProfileUnsavedChangesMessage": "Vous avez effectué des modifications sur ce profil d'utilisateur qui n'ont pas été enregistrées.", + "DialogUserProfileUnsavedChangesSubMessage": "Voulez-vous annuler les modifications ?", "DialogControllerSettingsModifiedConfirmMessage": "Les paramètres actuels du contrôleur ont été mis à jour.", "DialogControllerSettingsModifiedConfirmSubMessage": "Voulez-vous sauvegarder?", "DialogLoadNcaErrorMessage": "{0}. Fichier erroné : {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Activer Tout", "DlcManagerDisableAllButton": "Désactiver Tout", "MenuBarOptionsChangeLanguage": "Changer la Langue", + "MenuBarShowFileTypes": "Afficher les types de fichiers", "CommonSort": "Trier", "CommonShowNames": "Afficher les noms", "CommonFavorite": "Favoris", @@ -427,46 +443,47 @@ "AddGameDirBoxTooltip": "Entrez un répertoire de jeux à ajouter à la liste", "AddGameDirTooltip": "Ajouter un répertoire de jeux à la liste", "RemoveGameDirTooltip": "Supprimer le dossier sélectionné", - "CustomThemeCheckTooltip": "Use a custom Avalonia theme for the GUI to change the appearance of the emulator menus", + "CustomThemeCheckTooltip": "Utilisez un thème personnalisé Avalonia pour modifier l'apparence des menus de l'émulateur", "CustomThemePathTooltip": "Chemin vers le thème personnalisé de l'interface utilisateur", "CustomThemeBrowseTooltip": "Parcourir vers un thème personnalisé pour l'interface utilisateur", "DockModeToggleTooltip": "Le mode station d'accueil permet à la console émulée de se comporter comme une Nintendo Switch en mode station d'accueil, ce qui améliore la fidélité graphique dans la plupart des jeux. Inversement, la désactivation de cette option rendra la console émulée comme une console Nintendo Switch portable, réduisant la qualité graphique.\n\nConfigurer les controles du joueur 1 si vous prévoyez d'utiliser le mode station d'accueil; configurez les commandes portable si vous prévoyez d'utiliser le mode portable.\n\nLaissez ACTIVER si vous n'êtes pas sûr.", - "DirectKeyboardTooltip": "Direct keyboard access (HID) support. Provides games access to your keyboard as a text entry device.", - "DirectMouseTooltip": "Direct mouse access (HID) support. Provides games access to your mouse as a pointing device.", + "DirectKeyboardTooltip": "Prise en charge de l'accès direct au clavier (HID). Fournit aux jeux l'accès à votre clavier en tant que périphérique de saisie de texte.", + "DirectMouseTooltip": "Prise en charge de l'accès à la souris (HID). Permet aux jeux d'accéder a votre souris en tant que périphérique de pointage.", "RegionTooltip": "Changer la région du système", "LanguageTooltip": "Changer la langue du système", "TimezoneTooltip": "Changer le fuseau horaire du système", "TimeTooltip": "Changer l'heure du système", - "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference. We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.", - "PptcToggleTooltip": "Saves translated JIT functions so that they do not need to be translated every time the game loads.\n\nReduces stuttering and significantly speeds up boot times after the first boot of a game.\n\nLeave ON if unsure.", - "FsIntegrityToggleTooltip": "Checks for corrupt files when booting a game, and if corrupt files are detected, displays a hash error in the log.\n\nHas no impact on performance and is meant to help troubleshooting.\n\nLeave ON if unsure.", - "AudioBackendTooltip": "Changes the backend used to render audio.\n\nSDL2 is the preferred one, while OpenAL and SoundIO are used as fallbacks. Dummy will have no sound.\n\nSet to SDL2 if unsure.", - "MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.\n\nSet to HOST UNCHECKED if unsure.", - "MemoryManagerSoftwareTooltip": "Use a software page table for address translation. Highest accuracy but slowest performance.", - "MemoryManagerHostTooltip": "Directly map memory in the host address space. Much faster JIT compilation and execution.", - "MemoryManagerUnsafeTooltip": "Directly map memory, but do not mask the address within the guest address space before access. Faster, but at the cost of safety. The guest application can access memory from anywhere in Ryujinx, so only run programs you trust with this mode.", - "DRamTooltip": "Utilizes an alternative MemoryMode layout to mimic a Switch development model.\n\nThis is only useful for higher-resolution texture packs or 4k resolution mods. Does NOT improve performance.\n\nLeave OFF if unsure.", - "IgnoreMissingServicesTooltip": "Ignores unimplemented Horizon OS services. This may help in bypassing crashes when booting certain games.\n\nLeave OFF if unsure.", - "GraphicsBackendThreadingTooltip": "Executes graphics backend commands on a second thread.\n\nSpeeds up shader compilation, reduces stuttering, and improves performance on GPU drivers without multithreading support of their own. Slightly better performance on drivers with multithreading.\n\nSet to AUTO if unsure.", - "GalThreadingTooltip": "Executes graphics backend commands on a second thread.\n\nSpeeds up shader compilation, reduces stuttering, and improves performance on GPU drivers without multithreading support of their own. Slightly better performance on drivers with multithreading.\n\nSet to AUTO if unsure.", - "ShaderCacheToggleTooltip": "Saves a disk shader cache which reduces stuttering in subsequent runs.\n\nLeave ON if unsure.", - "ResolutionScaleTooltip": "Resolution Scale applied to applicable render targets", - "ResolutionScaleEntryTooltip": "Floating point resolution scale, such as 1.5. Non-integral scales are more likely to cause issues or crash.", - "AnisotropyTooltip": "Level of Anisotropic Filtering (set to Auto to use the value requested by the game)", + "VSyncToggleTooltip": "Synchronisation verticale de l'émulateur. Généralement un limiteur d'FPS pour la majorité des jeux, le désactiver peut accélérer les jeux pour rendre les écrans de chargement plus court, mais augemente le risque de crash lors des chargements.\n\nPeut être activer ou desactiver en jeu avec un raccourci de votre choix. Nous vous recommandons de le laisser.\n\nLaissez activer, si vous n'êtes pas sûr.", + "PptcToggleTooltip": "Sauvegarde les fonctions JIT afin qu'elles n'aient pas besoin d'être à chaque fois recompiler lorsque le jeu se charge.\n\nRéduit les lags et accélère considérablement le temps de chargement après le premier lancement d'un jeu.\n\nLaissez par défaut si vous n'êtes pas sûr.", + "FsIntegrityToggleTooltip": "Vérifie si des fichiers sont corrompus lors du lancement d'un jeu, et si des fichiers corrompus sont détectés, affiche une erreur de hachage dans la console.\n\nN'a aucun impact sur les performances et est destiné à aider le dépannage.\n\nLaissez activer en cas d'incertitude.", + "AudioBackendTooltip": "Modifie le backend utilisé pour donnée un rendu audio.\n\nSDL2 est préféré, tandis que OpenAL et SoundIO sont utilisés comme backend secondaire. Le backend Dummy (Factice) ne rends aucun son.\n\nLaissez sur SDL2 si vous n'êtes pas sûr.", + "MemoryManagerTooltip": "Change la façon dont la mémoire émulée est mappée et utiliser. Cela affecte grandement les performances du processeur.\n\nRéglez sur Host Uncheked en cas d'incertitude.", + "MemoryManagerSoftwareTooltip": "Utilisez une table logicielle pour la traduction d'adresses. La plus grande précision est fournie, mais les performances en seront impacter.", + "MemoryManagerHostTooltip": "Mappez directement la mémoire dans l'espace d'adresses de l'hôte. Compilation et exécution JIT beaucoup plus rapides.", + "MemoryManagerUnsafeTooltip": "Mapper directement la mémoire dans la carte, mais ne pas masquer l'adresse dans l'espace d'adressage du client avant l'accès. Plus rapide, mais la sécurité sera négliger. L'application peut accéder à la mémoire depuis n'importe où dans Ryujinx, donc exécutez uniquement les programmes en qui vous avez confiance avec ce mode.", + "UseHypervisorTooltip": "Utiliser l'Hyperviseur au lieu du JIT. Améliore considérablement les performances lorsqu'il est disponible, mais peut être instable dans son état actuel.", + "DRamTooltip": "Utilise une disposition alternative de la mémoire pour imiter le kit de développeur de la Switch.\n\nActiver cette option uniquement pour les packs de textures 4k ou les mods à résolution 4k.\nN'améliore pas les performances, cause des crashs dans certains jeux si activer.\n\nLaissez Désactiver en cas d'incertitude.", + "IgnoreMissingServicesTooltip": "Ignore les services Horizon OS non-intégré. Cela peut aider à contourner les plantages lors du démarrage de certains jeux.\n\nActivez-le en cas d'incertitude.", + "GraphicsBackendThreadingTooltip": "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.", + "GalThreadingTooltip": "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.", + "ShaderCacheToggleTooltip": "Enregistre un cache de shaders sur le disque dur, réduit le lag lors de multiples exécutions.\n\nLaissez Activer si vous n'êtes pas sûr.", + "ResolutionScaleTooltip": "Échelle de résolution appliquer au rendu du jeu", + "ResolutionScaleEntryTooltip": "Échelle de résolution à virgule flottante, telle que : 1.5. Les échelles non intégrales sont plus susceptibles de causer des problèmes ou des crashs.", + "AnisotropyTooltip": "Niveau de Filtrage Anisotropique (mettre sur Auto pour utiliser la valeur demandée par le jeu)", "AspectRatioTooltip": "Ratio d'aspect appliqué à la fenêtre de rendu", "ShaderDumpPathTooltip": "Chemin de copie des Shaders Graphiques", "FileLogTooltip": "Sauver le journal de la console dans un fichier journal sur le disque. Cela n'affecte pas les performances.", - "StubLogTooltip": "Prints stub log messages in the console. Does not affect performance.", - "InfoLogTooltip": "Prints info log messages in the console. Does not affect performance.", - "WarnLogTooltip": "Prints warning log messages in the console. Does not affect performance.", - "ErrorLogTooltip": "Prints error log messages in the console. Does not affect performance.", - "TraceLogTooltip": "Prints trace log messages in the console. Does not affect performance.", - "GuestLogTooltip": "Prints guest log messages in the console. Does not affect performance.", - "FileAccessLogTooltip": "Prints file access log messages in the console.", - "FSAccessLogModeTooltip": "Enables FS access log output to the console. Possible modes are 0-3", + "StubLogTooltip": "Affiche les messages de log dans la console. N'affecte pas les performances.", + "InfoLogTooltip": "Affiche les messages de log d'informations dans la console. N'affecte pas les performances.", + "WarnLogTooltip": "Affiche les messages d'avertissement dans la console. N'affecte pas les performances.", + "ErrorLogTooltip": "Affiche les messages de log d'erreur dans la console. N'affecte pas les performances.", + "TraceLogTooltip": "Affiche la trace des messages de log dans la console. N'affecte pas les performances.", + "GuestLogTooltip": "Affiche les messages de log des invités dans la console. N'affecte pas les performances.", + "FileAccessLogTooltip": "Affiche les messages de log d'accès aux fichiers dans la console.", + "FSAccessLogModeTooltip": "Active la sortie du journal d'accès FS de la console. Les modes possibles sont 0-3", "DeveloperOptionTooltip": "Utiliser avec précaution", "OpenGlLogLevel": "Nécessite l'activation des niveaux de journalisation appropriés", - "DebugLogTooltip": "Prints debug log messages in the console.\n\nOnly use this if specifically instructed by a staff member, as it will make logs difficult to read and worsen emulator performance.", + "DebugLogTooltip": "Affiche les messages de débogage dans la console.\n\nN'utilisez ceci que si un membre du personnel le demande, car cela rendra les logs difficiles à lire et réduit les performances de l'émulateur.", "LoadApplicationFileTooltip": "Ouvrir un explorateur de fichiers pour choisir un fichier compatible Switch à charger", "LoadApplicationFolderTooltip": "Ouvrir un explorateur de fichiers pour choisir une application Switch compatible et décompressée à charger", "OpenRyujinxFolderTooltip": "Ouvrir le dossier du système de fichiers Ryujinx", @@ -511,7 +528,7 @@ "UserErrorApplicationNotFound": " Application introuvable", "UserErrorUnknown": "Erreur inconnue", "UserErrorUndefined": "Erreur non définie", - "UserErrorNoKeysDescription": "Ryujinx n'a pas trouvé votre fichier 'prod.keys'", + "UserErrorNoKeysDescription": "Ryujinx n'a pas pu trouver votre fichier 'prod.keys'", "UserErrorNoFirmwareDescription": "Ryujinx n'a pas trouvé de firmwares installés", "UserErrorFirmwareParsingFailedDescription": "Ryujinx n'a pas pu analyser le firmware fourni. Cela est généralement dû à des clés obsolètes.", "UserErrorApplicationNotFoundDescription": "Ryujinx n'a pas pu trouver une application valide dans le chemin indiqué.", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Doit comporter au moins {0} caractères", "SwkbdMinRangeCharacters": "Doit contenir {0}-{1} caractères en longueur", "SoftwareKeyboard": "Clavier logiciel", + "SoftwareKeyboardModeNumbersOnly": "Doit être uniquement des chiffres", + "SoftwareKeyboardModeAlphabet": "Doit être uniquement des caractères non CJK", + "SoftwareKeyboardModeASCII": "Doit être uniquement du texte ASCII", "DialogControllerAppletMessagePlayerRange": "L'application demande {0} joueur(s) avec :\n\nTYPES : {1}\n\nJOUEURS : {2}\n\n{3}Merci d'ouvrir les Paramètres et de reconfigurer les Périphériques maintenant ou appuyez sur Fermer.", "DialogControllerAppletMessage": "L'application demande exactement {0} joueur(s) avec :\n\nTYPES : {1}\n\nJOUEURS : {2}\n\n{3}Merci d'ouvrir les Paramètres et de reconfigurer les Périphériques maintenant ou appuyez sur Fermer.", "DialogControllerAppletDockModeSet": "Mode station d'accueil défini. Le portable est également invalide.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Gestionnaire de contenus téléchargeables", "UpdateWindowTitle": "Gestionnaire de mises à jour", "CheatWindowHeading": "Cheats disponibles pour {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "{0} Contenu(s) téléchargeable(s) disponible pour {1} ({2})", "UserProfilesEditProfile": "Éditer la sélection", "Cancel": "Annuler", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Diminuer le volume :", "SettingsEnableMacroHLE": "Activer les macros HLE", "SettingsEnableMacroHLETooltip": "Émulation de haut niveau du code de Macro GPU.\n\nAméliore les performances, mais peut causer des bugs graphiques dans certains jeux.\n\nLaissez ACTIVER si vous n'êtes pas sûr.", + "SettingsEnableColorSpacePassthrough": "Traversée de l'espace colorimétrique", + "SettingsEnableColorSpacePassthroughTooltip": "Dirige l'interface graphique Vulkan pour qu'il transmette les informations de couleur sans spécifier d'espace colorimétrique. Pour les utilisateurs possédant des écrans haut de gamme, cela peut entraîner des couleurs plus vives, au détriment de l'exactitude des couleurs.", "VolumeShort": "Vol", "UserProfilesManageSaves": "Gérer les sauvegardes", "DeleteUserSave": "Voulez-vous supprimer la sauvegarde de l'utilisateur pour ce jeu?", @@ -610,5 +633,24 @@ "Search": "Rechercher", "UserProfilesRecoverLostAccounts": "Récupérer les comptes perdus", "Recover": "Récupérer", - "UserProfilesRecoverHeading": "Des sauvegardes ont été trouvées pour les comptes suivants" -} + "UserProfilesRecoverHeading": "Des sauvegardes ont été trouvées pour les comptes suivants", + "UserProfilesRecoverEmptyList": "Aucun profil à restaurer", + "GraphicsAATooltip": "Applique l'anticrénelage au rendu du jeu", + "GraphicsAALabel": "Anticrénelage :", + "GraphicsScalingFilterLabel": "Filtre de mise à l'échelle :", + "GraphicsScalingFilterTooltip": "Active la mise à l'échelle du tampon d'image", + "GraphicsScalingFilterLevelLabel": "Niveau ", + "GraphicsScalingFilterLevelTooltip": "Définir le niveau du filtre de mise à l'échelle", + "SmaaLow": "SMAA Faible", + "SmaaMedium": "SMAA moyen", + "SmaaHigh": "SMAA Élevé", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Modifier Utilisateur", + "UserEditorTitleCreate": "Créer Utilisateur", + "SettingsTabNetworkInterface": "Interface Réseau :", + "NetworkInterfaceTooltip": "Interface réseau pour les fonctionnalités LAN", + "NetworkInterfaceDefault": "Par défaut", + "PackagingShaders": "Empaquetage des Shaders", + "AboutChangelogButton": "Voir le Changelog sur GitHub", + "AboutChangelogButtonTooltipMessage": "Cliquez pour ouvrir le changelog de cette version dans votre navigateur par défaut." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/he_IL.json b/src/Ryujinx.Ava/Assets/Locales/he_IL.json new file mode 100644 index 000000000..e5caf445a --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Locales/he_IL.json @@ -0,0 +1,656 @@ +{ + "Language": "אנגלית (ארה\"ב)", + "MenuBarFileOpenApplet": "פתח יישומון", + "MenuBarFileOpenAppletOpenMiiAppletToolTip": "פתח את יישומון עורך ה- Mii במצב עצמאי", + "SettingsTabInputDirectMouseAccess": "גישה ישירה לעכבר", + "SettingsTabSystemMemoryManagerMode": "מצב מנהל זיכרון:", + "SettingsTabSystemMemoryManagerModeSoftware": "תוכנה", + "SettingsTabSystemMemoryManagerModeHost": "מארח (מהיר)", + "SettingsTabSystemMemoryManagerModeHostUnchecked": "מארח לא מבוקר (המהיר ביותר, לא בטוח)", + "SettingsTabSystemUseHypervisor": "השתמש ב Hypervisor", + "MenuBarFile": "_קובץ", + "MenuBarFileOpenFromFile": "_טען יישום מקובץ", + "MenuBarFileOpenUnpacked": "טען משחק _שאינו ארוז", + "MenuBarFileOpenEmuFolder": "פתח את תיקיית ריוג'ינקס", + "MenuBarFileOpenLogsFolder": "פתח את תיקיית קבצי הלוג", + "MenuBarFileExit": "_יציאה", + "MenuBarOptions": "הגדרות", + "MenuBarOptionsToggleFullscreen": "שנה מצב- מסך מלא", + "MenuBarOptionsStartGamesInFullscreen": "התחל משחקים במסך מלא", + "MenuBarOptionsStopEmulation": "עצור אמולציה", + "MenuBarOptionsSettings": "_הגדרות", + "MenuBarOptionsManageUserProfiles": "_נהל פרופילי משתמש", + "MenuBarActions": "_פעולות", + "MenuBarOptionsSimulateWakeUpMessage": "דמה הודעת השכמה", + "MenuBarActionsScanAmiibo": "סרוק אמיבו", + "MenuBarTools": "_כלים", + "MenuBarToolsInstallFirmware": "התקן קושחה", + "MenuBarFileToolsInstallFirmwareFromFile": "התקן קושחה מקובץ- ZIP/XCI", + "MenuBarFileToolsInstallFirmwareFromDirectory": "התקן קושחה מתוך תקייה", + "MenuBarToolsManageFileTypes": "ניהול סוגי קבצים", + "MenuBarToolsInstallFileTypes": "סוגי קבצי התקנה", + "MenuBarToolsUninstallFileTypes": "סוגי קבצי הסרה", + "MenuBarHelp": "עזרה", + "MenuBarHelpCheckForUpdates": "חפש עדכונים", + "MenuBarHelpAbout": "אודות", + "MenuSearch": "חפש...", + "GameListHeaderFavorite": "אהוב", + "GameListHeaderIcon": "סמל", + "GameListHeaderApplication": "שם", + "GameListHeaderDeveloper": "מפתח", + "GameListHeaderVersion": "גרסה", + "GameListHeaderTimePlayed": "זמן משחק", + "GameListHeaderLastPlayed": "שוחק לאחרונה", + "GameListHeaderFileExtension": "סיומת קובץ", + "GameListHeaderFileSize": "גודל הקובץ", + "GameListHeaderPath": "נתיב", + "GameListContextMenuOpenUserSaveDirectory": "פתח את תקיית השמור של המשתמש", + "GameListContextMenuOpenUserSaveDirectoryToolTip": "פותח את תקיית השמור של המשתמש ביישום הנוכחי", + "GameListContextMenuOpenDeviceSaveDirectory": "פתח את תקיית השמור של המכשיר", + "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "פותח את הספרייה המכילה את שמור המכשיר של היישום", + "GameListContextMenuOpenBcatSaveDirectory": "פתח את תקיית השמור של ה-BCAT", + "GameListContextMenuOpenBcatSaveDirectoryToolTip": "פותח את תקיית שמור ה-BCAT של היישום", + "GameListContextMenuManageTitleUpdates": "מנהל עדכוני משחקים", + "GameListContextMenuManageTitleUpdatesToolTip": "פותח את חלון מנהל עדכוני המשחקים", + "GameListContextMenuManageDlc": "מנהל הרחבות", + "GameListContextMenuManageDlcToolTip": "פותח את חלון מנהל הרחבות המשחקים", + "GameListContextMenuOpenModsDirectory": "פתח את תקיית המודים", + "GameListContextMenuOpenModsDirectoryToolTip": "פותח את התקייה המכילה את המודים של היישום", + "GameListContextMenuCacheManagement": "ניהול מטמון", + "GameListContextMenuCacheManagementPurgePptc": "הוסף PPTC לתור בנייה מחדש", + "GameListContextMenuCacheManagementPurgePptcToolTip": "גרום ל-PPTC להבנות מחדש בפתיחה הבאה של המשחק", + "GameListContextMenuCacheManagementPurgeShaderCache": "ניקוי מטמון הצללות", + "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "מוחק את מטמון ההצללות של היישום", + "GameListContextMenuCacheManagementOpenPptcDirectory": "פתח את תקיית PPTC", + "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "פותח את התקייה של מטמון ה-PPTC של האפליקציה", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "פתח את תקיית המטמון של ההצללות", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "פותח את תקיית מטמון ההצללות של היישום", + "GameListContextMenuExtractData": "חילוץ נתונים", + "GameListContextMenuExtractDataExeFS": "ExeFS", + "GameListContextMenuExtractDataExeFSToolTip": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים)", + "GameListContextMenuExtractDataRomFS": "RomFS", + "GameListContextMenuExtractDataRomFSToolTip": "חלץ את קטע ה-RomFS מתצורת היישום הנוכחית (כולל עדכונים)", + "GameListContextMenuExtractDataLogo": "Logo", + "GameListContextMenuExtractDataLogoToolTip": "חלץ את קטע ה-Logo מתצורת היישום הנוכחית (כולל עדכונים)", + "StatusBarGamesLoaded": "{1}/{0} משחקים נטענו", + "StatusBarSystemVersion": "גרסת מערכת: {0}", + "LinuxVmMaxMapCountDialogTitle": "זוהתה מגבלה נמוכה עבור מיפויי זיכרון", + "LinuxVmMaxMapCountDialogTextPrimary": "האם תרצה להגביר את הערך של vm.max_map_count ל{0}", + "LinuxVmMaxMapCountDialogTextSecondary": "משחקים מסוימים עלולים לייצר עוד מיפויי זיכרון ממה שמתאפשר. Ryujinx יקרוס ברגע שהמגבלה תחרוג.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "כן, עד האתחול הבא", + "LinuxVmMaxMapCountDialogButtonPersistent": "כן, לצמיתות", + "LinuxVmMaxMapCountWarningTextPrimary": "הכמות המירבית של מיפויי הזיכרון נמוכה מהמומלץ.", + "LinuxVmMaxMapCountWarningTextSecondary": "הערך הנוכחי של vm.max_map_count {0} נמוך מ{1}. משחקים מסוימים עלולים לייצר עוד מיפוי זיכרון ממה שמתאפשר.Ryujinx יקרוס ברגע שהמגבלה תחרוג.\n\nיתכן ותרצה להעלות את המגבלה הנוכחית או להתקין את pkexec, אשר יאפשר לRyujinx לסייע בכך.", + "Settings": "הגדרות", + "SettingsTabGeneral": "ממשק משתמש", + "SettingsTabGeneralGeneral": "כללי", + "SettingsTabGeneralEnableDiscordRichPresence": "הפעלת תצוגה עשירה בדיסקורד", + "SettingsTabGeneralCheckUpdatesOnLaunch": "בדוק אם קיימים עדכונים בהפעלה", + "SettingsTabGeneralShowConfirmExitDialog": "הראה דיאלוג \"אשר יציאה\"", + "SettingsTabGeneralHideCursor": "הסתר את הסמן", + "SettingsTabGeneralHideCursorNever": "אף פעם", + "SettingsTabGeneralHideCursorOnIdle": "במצב סרק", + "SettingsTabGeneralHideCursorAlways": "תמיד", + "SettingsTabGeneralGameDirectories": "תקיות משחקים", + "SettingsTabGeneralAdd": "הוסף", + "SettingsTabGeneralRemove": "הסר", + "SettingsTabSystem": "מערכת", + "SettingsTabSystemCore": "ליבה", + "SettingsTabSystemSystemRegion": "אזור מערכת:", + "SettingsTabSystemSystemRegionJapan": "יפן", + "SettingsTabSystemSystemRegionUSA": "ארה\"ב", + "SettingsTabSystemSystemRegionEurope": "אירופה", + "SettingsTabSystemSystemRegionAustralia": "אוסטרליה", + "SettingsTabSystemSystemRegionChina": "סין", + "SettingsTabSystemSystemRegionKorea": "קוריאה", + "SettingsTabSystemSystemRegionTaiwan": "טייוואן", + "SettingsTabSystemSystemLanguage": "שפת המערכת:", + "SettingsTabSystemSystemLanguageJapanese": "יפנית", + "SettingsTabSystemSystemLanguageAmericanEnglish": "אנגלית אמריקאית", + "SettingsTabSystemSystemLanguageFrench": "צרפתית", + "SettingsTabSystemSystemLanguageGerman": "גרמנית", + "SettingsTabSystemSystemLanguageItalian": "איטלקית", + "SettingsTabSystemSystemLanguageSpanish": "ספרדית", + "SettingsTabSystemSystemLanguageChinese": "סינית", + "SettingsTabSystemSystemLanguageKorean": "קוריאנית", + "SettingsTabSystemSystemLanguageDutch": "הולנדית", + "SettingsTabSystemSystemLanguagePortuguese": "פורטוגזית", + "SettingsTabSystemSystemLanguageRussian": "רוסית", + "SettingsTabSystemSystemLanguageTaiwanese": "טייוואנית", + "SettingsTabSystemSystemLanguageBritishEnglish": "אנגלית בריטית", + "SettingsTabSystemSystemLanguageCanadianFrench": "צרפתית קנדית", + "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "ספרדית אמריקה הלטינית", + "SettingsTabSystemSystemLanguageSimplifiedChinese": "סינית פשוטה", + "SettingsTabSystemSystemLanguageTraditionalChinese": "סינית מסורתית", + "SettingsTabSystemSystemTimeZone": "אזור זמן מערכת:", + "SettingsTabSystemSystemTime": "זמן מערכת:", + "SettingsTabSystemEnableVsync": "VSync", + "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", + "SettingsTabSystemEnableFsIntegrityChecks": "FS בדיקות תקינות", + "SettingsTabSystemAudioBackend": "אחראי שמע:", + "SettingsTabSystemAudioBackendDummy": "גולם", + "SettingsTabSystemAudioBackendOpenAL": "OpenAL", + "SettingsTabSystemAudioBackendSoundIO": "SoundIO", + "SettingsTabSystemAudioBackendSDL2": "SDL2", + "SettingsTabSystemHacks": "האצות", + "SettingsTabSystemHacksNote": "עלול לגרום לאי יציבות", + "SettingsTabSystemExpandDramSize": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)", + "SettingsTabSystemIgnoreMissingServices": "התעלם משירותים חסרים", + "SettingsTabGraphics": "גרפיקה", + "SettingsTabGraphicsAPI": "ממשק גראפי", + "SettingsTabGraphicsEnableShaderCache": "הפעל מטמון הצללות", + "SettingsTabGraphicsAnisotropicFiltering": "סינון אניסוטרופי:", + "SettingsTabGraphicsAnisotropicFilteringAuto": "אוטומטי", + "SettingsTabGraphicsAnisotropicFiltering2x": "2x", + "SettingsTabGraphicsAnisotropicFiltering4x": "4x", + "SettingsTabGraphicsAnisotropicFiltering8x": "8x", + "SettingsTabGraphicsAnisotropicFiltering16x": "16x", + "SettingsTabGraphicsResolutionScale": "קנה מידה של רזולוציה:", + "SettingsTabGraphicsResolutionScaleCustom": "מותאם אישית (לא מומלץ)", + "SettingsTabGraphicsResolutionScaleNative": "מקורי (720p/1080p)", + "SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)", + "SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)", + "SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)", + "SettingsTabGraphicsAspectRatio": "יחס גובה-רוחב:", + "SettingsTabGraphicsAspectRatio4x3": "4:3", + "SettingsTabGraphicsAspectRatio16x9": "16:9", + "SettingsTabGraphicsAspectRatio16x10": "16:10", + "SettingsTabGraphicsAspectRatio21x9": "21:9", + "SettingsTabGraphicsAspectRatio32x9": "32:9", + "SettingsTabGraphicsAspectRatioStretch": "מתח לגודל חלון", + "SettingsTabGraphicsDeveloperOptions": "אפשרויות מפתח", + "SettingsTabGraphicsShaderDumpPath": "Graphics Shader Dump Path:", + "SettingsTabLogging": "רישום", + "SettingsTabLoggingLogging": "רישום", + "SettingsTabLoggingEnableLoggingToFile": "אפשר רישום לקובץ", + "SettingsTabLoggingEnableStubLogs": "אפשר רישום בדל", + "SettingsTabLoggingEnableInfoLogs": "אפשר רישום מידע", + "SettingsTabLoggingEnableWarningLogs": "אפשר רישום אזהרות", + "SettingsTabLoggingEnableErrorLogs": "אפשר רישום שגיאות", + "SettingsTabLoggingEnableTraceLogs": "הפעל רישום מעקבי", + "SettingsTabLoggingEnableGuestLogs": "הפעל רישום מארח", + "SettingsTabLoggingEnableFsAccessLogs": "אפשר רישום גישת קבצי מערכת", + "SettingsTabLoggingFsGlobalAccessLogMode": "מצב רישום גלובלי של גישת קבצי מערכת", + "SettingsTabLoggingDeveloperOptions": "אפשרויות מפתח", + "SettingsTabLoggingDeveloperOptionsNote": "אזהרה: יפחית ביצועים", + "SettingsTabLoggingGraphicsBackendLogLevel": "רישום גרפיקת קצה אחורי:", + "SettingsTabLoggingGraphicsBackendLogLevelNone": "כלום", + "SettingsTabLoggingGraphicsBackendLogLevelError": "שגיאה", + "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "האטות", + "SettingsTabLoggingGraphicsBackendLogLevelAll": "הכל", + "SettingsTabLoggingEnableDebugLogs": "אפשר רישום ניפוי באגים", + "SettingsTabInput": "קלט", + "SettingsTabInputEnableDockedMode": "מצב עגינה", + "SettingsTabInputDirectKeyboardAccess": "גישה ישירה למקלדת", + "SettingsButtonSave": "שמירה", + "SettingsButtonClose": "סגירה", + "SettingsButtonOk": "אישור", + "SettingsButtonCancel": "ביטול", + "SettingsButtonApply": "החל", + "ControllerSettingsPlayer": "שחקן/ית", + "ControllerSettingsPlayer1": "שחקן/ית 1", + "ControllerSettingsPlayer2": "שחקן/ית 2", + "ControllerSettingsPlayer3": "שחקן/ית 3", + "ControllerSettingsPlayer4": "שחקן/ית 4", + "ControllerSettingsPlayer5": "שחקן/ית 5", + "ControllerSettingsPlayer6": "שחקן/ית 6", + "ControllerSettingsPlayer7": "שחקן/ית 7", + "ControllerSettingsPlayer8": "שחקן/ית 8", + "ControllerSettingsHandheld": "נייד", + "ControllerSettingsInputDevice": "מכשיר קלט", + "ControllerSettingsRefresh": "רענון", + "ControllerSettingsDeviceDisabled": "מושבת", + "ControllerSettingsControllerType": "סוג שלט", + "ControllerSettingsControllerTypeHandheld": "נייד", + "ControllerSettingsControllerTypeProController": "שלט פרו ", + "ControllerSettingsControllerTypeJoyConPair": "ג'ויקון הותאם", + "ControllerSettingsControllerTypeJoyConLeft": "ג'ויקון שמאלי ", + "ControllerSettingsControllerTypeJoyConRight": "ג'ויקון ימני", + "ControllerSettingsProfile": "פרופיל", + "ControllerSettingsProfileDefault": "ברירת המחדל", + "ControllerSettingsLoad": "טעינה", + "ControllerSettingsAdd": "הוספה", + "ControllerSettingsRemove": "הסר", + "ControllerSettingsButtons": "כפתורים", + "ControllerSettingsButtonA": "A", + "ControllerSettingsButtonB": "B", + "ControllerSettingsButtonX": "X", + "ControllerSettingsButtonY": "Y", + "ControllerSettingsButtonPlus": "+", + "ControllerSettingsButtonMinus": "-", + "ControllerSettingsDPad": "כפתורי כיוונים", + "ControllerSettingsDPadUp": "מעלה", + "ControllerSettingsDPadDown": "מטה", + "ControllerSettingsDPadLeft": "שמאלה", + "ControllerSettingsDPadRight": "ימינה", + "ControllerSettingsStickButton": "כפתור", + "ControllerSettingsStickUp": "למעלה", + "ControllerSettingsStickDown": "למטה", + "ControllerSettingsStickLeft": "שמאלה", + "ControllerSettingsStickRight": "ימינה", + "ControllerSettingsStickStick": "סטיק", + "ControllerSettingsStickInvertXAxis": "הפיכת הX של הסטיק", + "ControllerSettingsStickInvertYAxis": "הפיכת הY של הסטיק", + "ControllerSettingsStickDeadzone": "שטח מת:", + "ControllerSettingsLStick": "מקל שמאלי", + "ControllerSettingsRStick": "מקל ימני", + "ControllerSettingsTriggersLeft": "הדק שמאלי", + "ControllerSettingsTriggersRight": "הדק ימני", + "ControllerSettingsTriggersButtonsLeft": "כפתור הדק שמאלי", + "ControllerSettingsTriggersButtonsRight": "כפתור הדק ימני", + "ControllerSettingsTriggers": "הדקים", + "ControllerSettingsTriggerL": "L", + "ControllerSettingsTriggerR": "R", + "ControllerSettingsTriggerZL": "ZL", + "ControllerSettingsTriggerZR": "ZR", + "ControllerSettingsLeftSL": "SL", + "ControllerSettingsLeftSR": "SR", + "ControllerSettingsRightSL": "SL", + "ControllerSettingsRightSR": "SR", + "ControllerSettingsExtraButtonsLeft": "כפתורים משמאל", + "ControllerSettingsExtraButtonsRight": "כפתורים מימין", + "ControllerSettingsMisc": "שונות", + "ControllerSettingsTriggerThreshold": "סף הדק:", + "ControllerSettingsMotion": "תנועה", + "ControllerSettingsMotionUseCemuhookCompatibleMotion": "השתמש בתנועת CemuHook תואמת ", + "ControllerSettingsMotionControllerSlot": "מיקום שלט", + "ControllerSettingsMotionMirrorInput": "קלט מראה", + "ControllerSettingsMotionRightJoyConSlot": "מיקום ג'ויקון ימני", + "ControllerSettingsMotionServerHost": "מארח השרת:", + "ControllerSettingsMotionGyroSensitivity": "רגישות ג'ירוסקופ:", + "ControllerSettingsMotionGyroDeadzone": "שטח מת של הג'ירוסקופ:", + "ControllerSettingsSave": "שמירה", + "ControllerSettingsClose": "סגירה", + "UserProfilesSelectedUserProfile": "פרופיל המשתמש הנבחר:", + "UserProfilesSaveProfileName": "שמור שם פרופיל", + "UserProfilesChangeProfileImage": "שנה תמונת פרופיל", + "UserProfilesAvailableUserProfiles": "פרופילי משתמש זמינים:", + "UserProfilesAddNewProfile": "צור פרופיל", + "UserProfilesDelete": "מחיקה", + "UserProfilesClose": "סגור", + "ProfileNameSelectionWatermark": "בחרו כינוי", + "ProfileImageSelectionTitle": "בחירת תמונת פרופיל", + "ProfileImageSelectionHeader": "בחרו תמונת פרופיל", + "ProfileImageSelectionNote": "אתם יכולים לייבא תמונת פרופיל מותאמת אישית, או לבחור אווטאר מקושחת המערכת", + "ProfileImageSelectionImportImage": "ייבוא קובץ תמונה", + "ProfileImageSelectionSelectAvatar": "בחרו אוואטר קושחה", + "InputDialogTitle": "דיאלוג קלט", + "InputDialogOk": "בסדר", + "InputDialogCancel": "ביטול", + "InputDialogAddNewProfileTitle": "בחרו את שם הפרופיל", + "InputDialogAddNewProfileHeader": "אנא הזינו שם לפרופיל", + "InputDialogAddNewProfileSubtext": "(אורך מרבי: {0})", + "AvatarChoose": "בחרו דמות", + "AvatarSetBackgroundColor": "הגדר צבע רקע", + "AvatarClose": "סגור", + "ControllerSettingsLoadProfileToolTip": "טען פרופיל", + "ControllerSettingsAddProfileToolTip": "הוסף פרופיל", + "ControllerSettingsRemoveProfileToolTip": "הסר פרופיל", + "ControllerSettingsSaveProfileToolTip": "שמור פרופיל", + "MenuBarFileToolsTakeScreenshot": "צלם מסך", + "MenuBarFileToolsHideUi": "הסתר ממשק משתמש ", + "GameListContextMenuRunApplication": "הרץ יישום", + "GameListContextMenuToggleFavorite": "למתג העדפה", + "GameListContextMenuToggleFavoriteToolTip": "למתג סטטוס העדפה של משחק", + "SettingsTabGeneralTheme": "ערכת נושא", + "SettingsTabGeneralThemeCustomTheme": "נתיב ערכת נושא מותאמת אישית", + "SettingsTabGeneralThemeBaseStyle": "סגנון בסיס", + "SettingsTabGeneralThemeBaseStyleDark": "כהה", + "SettingsTabGeneralThemeBaseStyleLight": "בהיר", + "SettingsTabGeneralThemeEnableCustomTheme": "אפשר ערכת נושא מותאמת אישית", + "ButtonBrowse": "עיין", + "ControllerSettingsConfigureGeneral": "הגדר", + "ControllerSettingsRumble": "רטט", + "ControllerSettingsRumbleStrongMultiplier": "העצמת רטט חזק", + "ControllerSettingsRumbleWeakMultiplier": "מכפיל רטט חלש", + "DialogMessageSaveNotAvailableMessage": "אין שמור משחק עבור [{1:x16}] {0}", + "DialogMessageSaveNotAvailableCreateSaveMessage": "האם תרצה ליצור שמור משחק עבור המשחק הזה?", + "DialogConfirmationTitle": "ריוג'ינקס - אישור", + "DialogUpdaterTitle": "ריוג'ינקס - מעדכן", + "DialogErrorTitle": "ריוג'ינקס - שגיאה", + "DialogWarningTitle": "ריוג'ינקס - אזהרה", + "DialogExitTitle": "ריוג'ינקס - יציאה", + "DialogErrorMessage": "ריוג'ינקס נתקל בשגיאה", + "DialogExitMessage": "האם אתם בטוחים שאתם רוצים לסגור את ריוג'ינקס?", + "DialogExitSubMessage": "כל הנתונים שלא נשמרו יאבדו!", + "DialogMessageCreateSaveErrorMessage": "אירעה שגיאה ביצירת שמור המשחק שצויין: {0}", + "DialogMessageFindSaveErrorMessage": "אירעה שגיאה במציאת שמור המשחק שצויין: {0}", + "FolderDialogExtractTitle": "בחרו את התיקייה לחילוץ", + "DialogNcaExtractionMessage": "מלחץ {0} ממקטע {1}...", + "DialogNcaExtractionTitle": "ריוג'ינקס - מחלץ מקטע NCA", + "DialogNcaExtractionMainNcaNotFoundErrorMessage": "כשל בחילוץ. ה-NCA הראשי לא היה קיים בקובץ שנבחר.", + "DialogNcaExtractionCheckLogErrorMessage": "כשל בחילוץ. קרא את קובץ הרישום למידע נוסף.", + "DialogNcaExtractionSuccessMessage": "החילוץ הושלם בהצלחה.", + "DialogUpdaterConvertFailedMessage": "המרת הגרסה הנוכחית של ריוג'ינקס נכשלה.", + "DialogUpdaterCancelUpdateMessage": "מבטל עדכון!", + "DialogUpdaterAlreadyOnLatestVersionMessage": "אתם כבר משתמשים בגרסה המעודכנת ביותר של ריוג'ינקס!", + "DialogUpdaterFailedToGetVersionMessage": "אירעה שגיאה בעת ניסיון לקבל עדכונים מ-גיטהב. זה יכול להיגרם אם הגרסה המעודכנת האחרונה נוצרה על ידי פעולות של גיטהב. נסה שוב בעוד מספר דקות.", + "DialogUpdaterConvertFailedGithubMessage": "המרת גרסת ריוג'ינקס שהתקבלה מ-עדכון הגרסאות של גיטהב נכשלה.", + "DialogUpdaterDownloadingMessage": "מוריד עדכון...", + "DialogUpdaterExtractionMessage": "מחלץ עדכון...", + "DialogUpdaterRenamingMessage": "משנה את שם העדכון...", + "DialogUpdaterAddingFilesMessage": "מוסיף עדכון חדש...", + "DialogUpdaterCompleteMessage": "העדכון הושלם!", + "DialogUpdaterRestartMessage": "האם אתם רוצים להפעיל מחדש את ריוג'ינקס עכשיו?", + "DialogUpdaterArchNotSupportedMessage": "אינך מריץ ארכיטקטורת מערכת נתמכת!", + "DialogUpdaterArchNotSupportedSubMessage": "(רק מערכות x64 נתמכות!)", + "DialogUpdaterNoInternetMessage": "אתם לא מחוברים לאינטרנט!", + "DialogUpdaterNoInternetSubMessage": "אנא ודא שיש לך חיבור אינטרנט תקין!", + "DialogUpdaterDirtyBuildMessage": "אתם לא יכולים לעדכן מבנה מלוכלך של ריוג'ינקס!", + "DialogUpdaterDirtyBuildSubMessage": "אם אתם מחפשים גרסא נתמכת, אנא הורידו את ריוג'ינקס בכתובת https://ryujinx.org", + "DialogRestartRequiredMessage": "אתחול נדרש", + "DialogThemeRestartMessage": "ערכת הנושא נשמרה. יש צורך בהפעלה מחדש כדי להחיל את ערכת הנושא.", + "DialogThemeRestartSubMessage": "האם ברצונך להפעיל מחדש?", + "DialogFirmwareInstallEmbeddedMessage": "האם תרצו להתקין את הקושחה המוטמעת במשחק הזה? (קושחה {0})", + "DialogFirmwareInstallEmbeddedSuccessMessage": "לא נמצאה קושחה מותקנת אבל ריוג'ינקס הצליח להתקין קושחה {0} מהמשחק שסופק. \\nהאמולטור יופעל כעת.", + "DialogFirmwareNoFirmwareInstalledMessage": "לא מותקנת קושחה", + "DialogFirmwareInstalledMessage": "הקושחה {0} הותקנה", + "DialogInstallFileTypesSuccessMessage": "סוגי קבצים הותקנו בהצלחה!", + "DialogInstallFileTypesErrorMessage": "נכשל בהתקנת סוגי קבצים.", + "DialogUninstallFileTypesSuccessMessage": "סוגי קבצים הוסרו בהצלחה!", + "DialogUninstallFileTypesErrorMessage": "נכשל בהסרת סוגי קבצים.", + "DialogOpenSettingsWindowLabel": "פתח את חלון ההגדרות", + "DialogControllerAppletTitle": "יישומון בקר", + "DialogMessageDialogErrorExceptionMessage": "שגיאה בהצגת דיאלוג ההודעה: {0}", + "DialogSoftwareKeyboardErrorExceptionMessage": "שגיאה בהצגת תוכנת המקלדת: {0}", + "DialogErrorAppletErrorExceptionMessage": "שגיאה בהצגת דיאלוג ErrorApplet: {0}", + "DialogUserErrorDialogMessage": "{0}: {1}", + "DialogUserErrorDialogInfoMessage": "\nלמידע נוסף על איך לתקן שגיאה זו, עקוב אחר מדריך ההתקנה שלנו.", + "DialogUserErrorDialogTitle": "שגיאת Ryujinx ({0})", + "DialogAmiiboApiTitle": "ממשק תכנות אמיבו", + "DialogAmiiboApiFailFetchMessage": "אירעה שגיאה בעת שליפת מידע מהממשק.", + "DialogAmiiboApiConnectErrorMessage": "לא ניתן להתחבר לממשק שרת האמיבו. ייתכן שהשירות מושבת או שתצטרך לוודא שהחיבור לאינטרנט שלך מקוון.", + "DialogProfileInvalidProfileErrorMessage": "הפרופיל {0} אינו תואם למערכת תצורת הקלט הנוכחית.", + "DialogProfileDefaultProfileOverwriteErrorMessage": "לא ניתן להחליף את פרופיל ברירת המחדל", + "DialogProfileDeleteProfileTitle": "מוחק פרופיל", + "DialogProfileDeleteProfileMessage": "פעולה זו היא בלתי הפיכה, האם אתם בטוחים שברצונכם להמשיך?", + "DialogWarning": "אזהרה", + "DialogPPTCDeletionMessage": "אם תמשיכו אתם עומדים לגרום לבנייה מחדש של מטמון ה-PPTC עבור:\n\n{0}", + "DialogPPTCDeletionErrorMessage": "שגיאה בטיהור מטמון PPTC ב-{0}: {1}", + "DialogShaderDeletionMessage": "אם תמשיכו אתם עומדים למחוק את מטמון ההצללות עבור:\n\n{0}", + "DialogShaderDeletionErrorMessage": "שגיאה בניקוי מטמון ההצללות ב-{0}: {1}", + "DialogRyujinxErrorMessage": "ריוג'ינקס נתקלה בשגיאה", + "DialogInvalidTitleIdErrorMessage": "שגיאת ממשק משתמש: למשחק שנבחר לא קיים מזהה משחק", + "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "לא נמצאה קושחת מערכת תקפה ב-{0}.", + "DialogFirmwareInstallerFirmwareInstallTitle": "התקן קושחה {0}", + "DialogFirmwareInstallerFirmwareInstallMessage": "גירסת המערכת {0} תותקן.", + "DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nזה יחליף את גרסת המערכת הנוכחית {0}.", + "DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nהאם ברצונך להמשיך?", + "DialogFirmwareInstallerFirmwareInstallWaitMessage": "מתקין קושחה...", + "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "גרסת המערכת {0} הותקנה בהצלחה.", + "DialogUserProfileDeletionWarningMessage": "לא יהיו פרופילים אחרים שייפתחו אם הפרופיל שנבחר יימחק", + "DialogUserProfileDeletionConfirmMessage": "האם ברצונך למחוק את הפרופיל שנבחר", + "DialogUserProfileUnsavedChangesTitle": "אזהרה - שינויים לא שמורים", + "DialogUserProfileUnsavedChangesMessage": "ביצעת שינויים בפרופיל משתמש זה שלא נשמרו.", + "DialogUserProfileUnsavedChangesSubMessage": "האם ברצונך למחוק את השינויים האחרונים?", + "DialogControllerSettingsModifiedConfirmMessage": "הגדרות השלט הנוכחי עודכנו.", + "DialogControllerSettingsModifiedConfirmSubMessage": "האם ברצונך לשמור?", + "DialogLoadNcaErrorMessage": "{0}. קובץ שגוי: {1}", + "DialogDlcNoDlcErrorMessage": "הקובץ שצוין אינו מכיל DLC עבור המשחק שנבחר!", + "DialogPerformanceCheckLoggingEnabledMessage": "הפעלת רישום מעקב, אשר נועד לשמש מפתחים בלבד.", + "DialogPerformanceCheckLoggingEnabledConfirmMessage": "לביצועים מיטביים, מומלץ להשבית את רישום המעקב. האם ברצונך להשבית את רישום המעקב כעת?", + "DialogPerformanceCheckShaderDumpEnabledMessage": "הפעלת השלכת הצללה, שנועדה לשמש מפתחים בלבד.", + "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "לביצועים מיטביים, מומלץ להשבית את השלכת הצללה. האם ברצונך להשבית את השלכת הצללה עכשיו?", + "DialogLoadAppGameAlreadyLoadedMessage": "ישנו משחק שכבר רץ כעת", + "DialogLoadAppGameAlreadyLoadedSubMessage": "אנא הפסק את האמולציה או סגור את האמולטור לפני הפעלת משחק אחר.", + "DialogUpdateAddUpdateErrorMessage": "הקובץ שצוין אינו מכיל עדכון עבור המשחק שנבחר!", + "DialogSettingsBackendThreadingWarningTitle": "אזהרה - ריבוי תהליכי רקע", + "DialogSettingsBackendThreadingWarningMessage": "יש להפעיל מחדש את ריוג'ינקס לאחר שינוי אפשרות זו כדי שהיא תחול במלואה. בהתאם לפלטפורמה שלך, ייתכן שיהיה עליך להשבית ידנית את ריבוי ההליכים של ההתקן שלך בעת השימוש ב-ריוג'ינקס.", + "SettingsTabGraphicsFeaturesOptions": "אפשרויות", + "SettingsTabGraphicsBackendMultithreading": "אחראי גרפיקה רב-תהליכי:", + "CommonAuto": "אוטומטי", + "CommonOff": "כבוי", + "CommonOn": "דלוק", + "InputDialogYes": "כן", + "InputDialogNo": "לא", + "DialogProfileInvalidProfileNameErrorMessage": "שם הקובץ מכיל תווים לא חוקיים. אנא נסה שוב.", + "MenuBarOptionsPauseEmulation": "הפסק", + "MenuBarOptionsResumeEmulation": "המשך", + "AboutUrlTooltipMessage": "לחץ כדי לפתוח את אתר ריוג'ינקס בדפדפן ברירת המחדל שלך.", + "AboutDisclaimerMessage": "ריוג'ינקס אינה מזוהת עם נינטנדו,\nאו שוטפייה בכל דרך שהיא.", + "AboutAmiiboDisclaimerMessage": "ממשק אמיבו (www.amiiboapi.com) משומש בהדמיית האמיבו שלנו.", + "AboutPatreonUrlTooltipMessage": "לחץ כדי לפתוח את דף הפטראון של ריוג'ינקס בדפדפן ברירת המחדל שלך.", + "AboutGithubUrlTooltipMessage": "לחץ כדי לפתוח את דף הגיטהב של ריוג'ינקס בדפדפן ברירת המחדל שלך.", + "AboutDiscordUrlTooltipMessage": "לחץ כדי לפתוח הזמנה לשרת הדיסקורד של ריוג'ינקס בדפדפן ברירת המחדל שלך.", + "AboutTwitterUrlTooltipMessage": "לחץ כדי לפתוח את דף הטוויטר של Ryujinx בדפדפן ברירת המחדל שלך.", + "AboutRyujinxAboutTitle": "אודות:", + "AboutRyujinxAboutContent": "ריוג'ינקס הוא אמולטור עבור הנינטנדו סוויץ' (כל הזכויות שמורות).\nבבקשה תתמכו בנו בפטראון.\nקבל את כל החדשות האחרונות בטוויטר או בדיסקורד שלנו.\nמפתחים המעוניינים לתרום יכולים לקבל מידע נוסף ב-גיטהאב או ב-דיסקורד שלנו.", + "AboutRyujinxMaintainersTitle": "מתוחזק על ידי:", + "AboutRyujinxMaintainersContentTooltipMessage": "לחץ כדי לפתוח את דף התורמים בדפדפן ברירת המחדל שלך.", + "AboutRyujinxSupprtersTitle": "תמוך באמצעות Patreon", + "AmiiboSeriesLabel": "סדרת אמיבו", + "AmiiboCharacterLabel": "דמות", + "AmiiboScanButtonLabel": "סרוק את זה", + "AmiiboOptionsShowAllLabel": "הצג את כל האמיבואים", + "AmiiboOptionsUsRandomTagLabel": "האצה: השתמש בתג Uuid אקראי", + "DlcManagerTableHeadingEnabledLabel": "מאופשר", + "DlcManagerTableHeadingTitleIdLabel": "מזהה משחק", + "DlcManagerTableHeadingContainerPathLabel": "נתיב מכיל", + "DlcManagerTableHeadingFullPathLabel": "נתיב מלא", + "DlcManagerRemoveAllButton": "מחק הכל", + "DlcManagerEnableAllButton": "אפשר הכל", + "DlcManagerDisableAllButton": "השבת הכל", + "MenuBarOptionsChangeLanguage": "החלף שפה", + "MenuBarShowFileTypes": "הצג מזהה סוג קובץ", + "CommonSort": "מיין", + "CommonShowNames": "הצג שמות", + "CommonFavorite": "מועדף", + "OrderAscending": "סדר עולה", + "OrderDescending": "סדר יורד", + "SettingsTabGraphicsFeatures": "תכונות ושיפורים", + "ErrorWindowTitle": "חלון שגיאה", + "ToggleDiscordTooltip": "בחרו להציג את ריוג'ינקס או לא בפעילות הדיסקורד שלכם \"משוחק כרגע\".", + "AddGameDirBoxTooltip": "הזן תקיית משחקים כדי להוסיף לרשימה", + "AddGameDirTooltip": "הוסף תקיית משחקים לרשימה", + "RemoveGameDirTooltip": "הסר את תקיית המשחקים שנבחרה", + "CustomThemeCheckTooltip": "השתמש בעיצוב מותאם אישית של אבלוניה עבור ה-ממשק הגראפי כדי לשנות את המראה של תפריטי האמולטור", + "CustomThemePathTooltip": "נתיב לערכת נושא לממשק גראפי מותאם אישית", + "CustomThemeBrowseTooltip": "חפש עיצוב ממשק גראפי מותאם אישית", + "DockModeToggleTooltip": "מצב עגינה גורם למערכת המדומה להתנהג כ-נינטנדו סוויץ' בתחנת עגינתו. זה משפר את הנאמנות הגרפית ברוב המשחקים.\n לעומת זאת, השבתה של תכונה זו תגרום למערכת המדומה להתנהג כ- נינטנדו סוויץ' נייד, ולהפחית את איכות הגרפיקה.\n\nהגדירו את שלט שחקן 1 אם אתם מתכננים להשתמש במצב עגינה; הגדירו את פקדי כף היד אם אתם מתכננים להשתמש במצב נייד.\n\nמוטב להשאיר דלוק אם אתם לא בטוחים.", + "DirectKeyboardTooltip": "תמיכה ישירה למקלדת (HID). מספק גישה בשביל משחקים למקלדת שלך כמכשיר להזנת טקסט.", + "DirectMouseTooltip": "תמיכה ישירה לעכבר (HID). מספק גישה בשביל משחקים לעכבר שלך כהתקן הצבעה.", + "RegionTooltip": "שנה אזור מערכת", + "LanguageTooltip": "שנה שפת מערכת", + "TimezoneTooltip": "שנה את אזור הזמן של המערכת", + "TimeTooltip": "שנה זמן מערכת", + "VSyncToggleTooltip": "מדמה סנכרון אנכי של קונסולה. כלומר חסם הפריימים לרוב המשחקים; השבתה שלו עלולה לגרום למשחקים לרוץ מהר יותר או לגרום למסכי טעינה לקחת יותר זמן או להתקע.\n\nניתן לשנות מצב של תפריט זה בזמן משחק עם המקש לבחירתך. אנו ממליצים לעשות זאת אם אתם מתכננים להשבית אותו.\n\nמוטב להשאיר דלוק אם לא בטוחים.", + "PptcToggleTooltip": "שומר את פונקציות ה-JIT המתורגמות כך שלא יצטרכו לעבור תרגום שוב כאשר משחק עולה.\n\nמפחית תקיעות ומשפר מהירות עלייה של המערכת אחרי הפתיחה הראשונה של המשחק.\n\nמוטב להשאיר דלוק אם לא בטוחים.", + "FsIntegrityToggleTooltip": "בודק לקבצים שגויים כאשר משחק עולה, ואם מתגלים כאלו, מציג את מזהה השגיאה שלהם לקובץ הלוג.\n\nאין לכך השפעה על הביצועים ונועד לעזור לבדיקה וניפוי שגיאות של האמולטור.\n\nמוטב להשאיר דלוק אם לא בטוחים.", + "AudioBackendTooltip": "משנה את אחראי השמע.\n\nSDL2 הוא הנבחר, למראת שOpenAL וגם SoundIO משומשים כאפשרויות חלופיות. אפשרות הDummy לא תשמיע קול כלל.\n\nמוטב להשאיר על SDL2 אם לא בטוחים.", + "MemoryManagerTooltip": "שנה איך שזיכרון מארח מיוחד ומונגד. משפיע מאוד על ביצועי המעבד המדומה.\n\nמוטב להשאיר על מארח לא מבוקר אם לא בטוחים.", + "MemoryManagerSoftwareTooltip": "השתמש בתוכנת ה-page table בכדי להתייחס לתרגומים. דיוק מרבי לקונסולה אך המימוש הכי איטי.", + "MemoryManagerHostTooltip": "ממפה זיכרון ישירות לכתובת המארח. מהיר בהרבה ביכולות קימפול ה-JIT והריצה.", + "MemoryManagerUnsafeTooltip": "ממפה זיכרון ישירות, אך לא ממסך את הכתובת בתוך כתובת המארח לפני הגישה. מהיר, אך במחיר של הגנה. יישום המארח בעל גישה לזיכרון מכל מקום בריוג'ינקס, לכן הריצו איתו רק קבצים שאתם סומכים עליהם.", + "UseHypervisorTooltip": "השתמש ב- Hypervisor במקום JIT. משפר מאוד ביצועים כשניתן, אבל יכול להיות לא יציב במצבו הנוכחי.", + "DRamTooltip": "מנצל תצורת מצב-זיכרון חלופית לחכות את מכשיר הפיתוח של הסוויץ'.\n\nזה שימושי להחלפת חבילות מרקמים באיכותיים יותר או כאלו ברזולוציית 4k. לא משפר ביצועים.\n\nמוטב להשאיר כבוי אם לא בטוחים.", + "IgnoreMissingServicesTooltip": "מתעלם מפעולות שלא קיבלו מימוש במערכת ההפעלה Horizon OS. זה עלול לעזור לעקוף קריסות של היישום במשחקים מסויימים.\n\nמוטב להשאיר כבוי אם לא בטוחים.", + "GraphicsBackendThreadingTooltip": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", + "GalThreadingTooltip": "מריץ פקודות גראפיקה בתהליך שני נפרד.\n\nמאיץ עיבוד הצללות, מפחית תקיעות ומשפר ביצועים של דרייבר כרטיסי מסך אשר לא תומכים בהרצה רב-תהליכית.\n\nמוטב להשאיר על אוטומטי אם לא בטוחים.", + "ShaderCacheToggleTooltip": "שומר זכרון מטמון של הצללות, דבר שמפחית תקיעות בריצות מסוימות.\n\nמוטב להשאיר דלוק אם לא בטוחים.", + "ResolutionScaleTooltip": "שיפור רזולוצייה המאופשרת לעיבוד מטרות.", + "ResolutionScaleEntryTooltip": "שיפור רזולוציית נקודה צפה, כגון 1.5. הוא שיפור לא אינטגרלי הנוטה לגרום יותר בעיות או להקריס.", + "AnisotropyTooltip": "רמת סינון אניסוטרופי (מוגדר לאוטומטי כדי להשתמש בערך המבוקש על ידי המשחק)", + "AspectRatioTooltip": "יחס גובה-רוחב הוחל על חלון המעבד.", + "ShaderDumpPathTooltip": "נתיב השלכת הצללות גראפיות", + "FileLogTooltip": "שומר את רישומי שורת הפקודות לזיכרון, לא משפיע על ביצועי היישום.", + "StubLogTooltip": "מדפיס רישומים כושלים לשורת הפקודות. לא משפיע על ביצועי היישום.", + "InfoLogTooltip": "מדפיק רישומי מידע לשורת הפקודות. לא משפיע על ביצועי היישום.", + "WarnLogTooltip": "מדפיק רישומי הערות לשורת הפקודות. לא משפיע על ביצועי היישום.", + "ErrorLogTooltip": "מדפיס רישומי שגיאות לשורת הפקודות. לא משפיע על ביצועי היישום.", + "TraceLogTooltip": "מדפיק רישומי זיכרון לשורת הפקודות. לא משפיע על ביצועי היישום.", + "GuestLogTooltip": "מדפיס רישומי אורח לשורת הפקודות. לא משפיע על ביצועי היישום.", + "FileAccessLogTooltip": "מדפיס גישות לקבצי רישום לשורת הפקודות.", + "FSAccessLogModeTooltip": "מאפשר גישה לרישומי FS ליציאת שורת הפקודות. האפשרויות הינן 0-3.", + "DeveloperOptionTooltip": "השתמש בזהירות", + "OpenGlLogLevel": "דורש הפעלת רמות רישום מתאימות", + "DebugLogTooltip": "מדפיס הודעות יומן ניפוי באגים בשורת הפקודות.", + "LoadApplicationFileTooltip": "פתח סייר קבצים כדי לבחור קובץ תואם סוויץ' לטעינה", + "LoadApplicationFolderTooltip": "פתח סייר קבצים כדי לבחור יישום תואם סוויץ', לא ארוז לטעינה.", + "OpenRyujinxFolderTooltip": "פתח את תיקיית מערכת הקבצים ריוג'ינקס", + "OpenRyujinxLogsTooltip": "פותח את התיקיה שאליה נכתבים רישומים", + "ExitTooltip": "צא מריוג'ינקס", + "OpenSettingsTooltip": "פתח את חלון ההגדרות", + "OpenProfileManagerTooltip": "פתח את חלון מנהל פרופילי המשתמש", + "StopEmulationTooltip": "הפסק את הדמייה של המשחק הנוכחי וחזור למסך בחירת המשחק", + "CheckUpdatesTooltip": "בדוק אם קיימים עדכונים לריוג'ינקס", + "OpenAboutTooltip": "פתח את חלון אודות היישום", + "GridSize": "גודל רשת", + "GridSizeTooltip": "שנה את גודל המוצרים על הרשת.", + "SettingsTabSystemSystemLanguageBrazilianPortuguese": "פורטוגלית ברזילאית", + "AboutRyujinxContributorsButtonHeader": "צפה בכל התורמים", + "SettingsTabSystemAudioVolume": "עוצמת קול: ", + "AudioVolumeTooltip": "שנה עוצמת קול", + "SettingsTabSystemEnableInternetAccess": "אפשר גישה לאינטרנט בתור אורח/חיבור לאן", + "EnableInternetAccessTooltip": "מאפשר ליישומים באמולצייה להתחבר לאינטרנט.\n\nמשחקים עם חיבור לאן יכולים להתחבר אחד לשני כשאופצייה זו מופעלת והמערכות מתחברות לאותה נקודת גישה. כמו כן זה כולל שורות פקודות אמיתיות גם.\n\nאופצייה זו לא מאפשרת חיבור לשרתי נינטנדו. כשהאופצייה דלוקה היא עלולה לגרום לקריסת היישום במשחקים מסויימים שמנסים להתחבר לאינטרנט.\n\nמוטב להשאיר כבוי אם לא בטוחים.", + "GameListContextMenuManageCheatToolTip": "נהל צ'יטים", + "GameListContextMenuManageCheat": "נהל צ'יטים", + "ControllerSettingsStickRange": "טווח:", + "DialogStopEmulationTitle": "ריוג'ינקס - עצור אמולציה", + "DialogStopEmulationMessage": "האם אתם בטוחים שאתם רוצים לסגור את האמולצייה?", + "SettingsTabCpu": "מעבד", + "SettingsTabAudio": "שמע", + "SettingsTabNetwork": "רשת", + "SettingsTabNetworkConnection": "חיבור רשת", + "SettingsTabCpuCache": "מטמון מעבד", + "SettingsTabCpuMemory": "מצב מעבד", + "DialogUpdaterFlatpakNotSupportedMessage": "בבקשה עדכן את ריוג'ינקס דרך פלאטהב.", + "UpdaterDisabledWarningTitle": "מעדכן מושבת!", + "GameListContextMenuOpenSdModsDirectory": "פתח את תקיית המודים של אטמוספרה", + "GameListContextMenuOpenSdModsDirectoryToolTip": "פותח את תקיית כרטיס ה-SD החלופית של אטמוספרה המכילה את המודים של האפליקציה. שימושי עבור מודים ארוזים עבור חומרה אמיתית.", + "ControllerSettingsRotate90": "סובב 90° עם בכיוון השעון", + "IconSize": "גודל הסמל", + "IconSizeTooltip": "שנה את גודל הסמלים של משחקים", + "MenuBarOptionsShowConsole": "הצג שורת פקודות", + "ShaderCachePurgeError": "שגיאה בניקוי מטמון ההצללות ב-{0}: {1}", + "UserErrorNoKeys": "המפתחות לא נמצאו", + "UserErrorNoFirmware": "קושחה לא נמצאה", + "UserErrorFirmwareParsingFailed": "שגיאת ניתוח קושחה", + "UserErrorApplicationNotFound": "יישום לא נמצא", + "UserErrorUnknown": "שגיאה לא ידועה", + "UserErrorUndefined": "שגיאה לא מוגדרת", + "UserErrorNoKeysDescription": "ריוג'ינקס לא הצליח למצוא את קובץ ה-'prod.keys' שלך", + "UserErrorNoFirmwareDescription": "ריוג'ינקס לא הצליחה למצוא קושחה מותקנת", + "UserErrorFirmwareParsingFailedDescription": "ריוג'ינקס לא הצליחה לנתח את הקושחה שסופקה. זה נגרם בדרך כלל על ידי מפתחות לא עדכניים.", + "UserErrorApplicationNotFoundDescription": "ריוג'ינקס לא מצאה יישום תקין בנתיב הנתון", + "UserErrorUnknownDescription": "קרתה שגיאה לא ידועה!", + "UserErrorUndefinedDescription": "קרתה שגיאה לא מוגדרת! זה לא אמור לקרות, אנא צרו קשר עם מפתח!", + "OpenSetupGuideMessage": "פתח מדריך התקנה", + "NoUpdate": "אין עדכון", + "TitleUpdateVersionLabel": "גרסה {0}", + "RyujinxInfo": "ריוג'ינקס - מידע", + "RyujinxConfirm": "ריוג'ינקס - אישור", + "FileDialogAllTypes": "כל הסוגים", + "Never": "אף פעם", + "SwkbdMinCharacters": "לפחות {0} תווים", + "SwkbdMinRangeCharacters": "באורך {0}-{1} תווים", + "SoftwareKeyboard": "מקלדת וירטואלית", + "SoftwareKeyboardModeNumbersOnly": "מחויב להיות מספרי בלבד", + "SoftwareKeyboardModeAlphabet": "מחויב להיות ללא אותיות CJK", + "SoftwareKeyboardModeASCII": "מחויב להיות טקסט אסקיי", + "DialogControllerAppletMessagePlayerRange": "האפליקציה מבקשת {0} שחקנים עם:\n\nסוגים: {1}\n\nשחקנים: {2}\n\n{3}אנא פתח את ההגדרות והגדר מחדש את הקלט כעת או סגור.", + "DialogControllerAppletMessage": "האפליקציה מבקשת בדיוק {0} שחקנים עם:\n\nסוגים: {1}\n\nשחקנים: {2}\n\n{3}אנא פתח את ההגדרות והגדר מחדש את הקלט כעת או סגור.", + "DialogControllerAppletDockModeSet": "במצב עגינה. בנוסף מצב נייד לא אפשרי.\n\n", + "UpdaterRenaming": "משנה שמות של קבצים ישנים...", + "UpdaterRenameFailed": "המעדכן לא הצליח לשנות את שם הקובץ: {0}", + "UpdaterAddingFiles": "מוסיף קבצים חדשים...", + "UpdaterExtracting": "מחלץ עדכון...", + "UpdaterDownloading": "מוריד עדכון...", + "Game": "משחק", + "Docked": "בתחנת עגינה", + "Handheld": "נייד", + "ConnectionError": "שגיאת חיבור", + "AboutPageDeveloperListMore": "{0} ועוד...", + "ApiError": "שגיאת ממשק.", + "LoadingHeading": "טוען {0}", + "CompilingPPTC": "קימפול PTC", + "CompilingShaders": "קימפול הצללות", + "AllKeyboards": "כל המקלדות", + "OpenFileDialogTitle": "בחר קובץ נתמך לפתיחה", + "OpenFolderDialogTitle": "בחר תיקיה עם משחק לא ארוז", + "AllSupportedFormats": "כל הפורמטים הנתמכים", + "RyujinxUpdater": "מעדכן ריוג'ינקס", + "SettingsTabHotkeys": "מקשי קיצור במקלדת", + "SettingsTabHotkeysHotkeys": "מקשי קיצור במקלדת", + "SettingsTabHotkeysToggleVsyncHotkey": "שנה סינכרון אנכי:", + "SettingsTabHotkeysScreenshotHotkey": "צילום מסך:", + "SettingsTabHotkeysShowUiHotkey": "הצג ממשק משתמש:", + "SettingsTabHotkeysPauseHotkey": "הפסק:", + "SettingsTabHotkeysToggleMuteHotkey": "השתק:", + "ControllerMotionTitle": "הגדרות שליטת תנועות ג'ירוסקופ", + "ControllerRumbleTitle": "הגדרות רטט", + "SettingsSelectThemeFileDialogTitle": "בחרו קובץ ערכת נושא", + "SettingsXamlThemeFile": "קובץ ערכת נושא Xaml", + "AvatarWindowTitle": "ניהול חשבונות - אוואטר", + "Amiibo": "אמיבו", + "Unknown": "לא ידוע", + "Usage": "שימוש", + "Writable": "ניתן לכתיבה", + "SelectDlcDialogTitle": "בחרו קבצי הרחבות משחק", + "SelectUpdateDialogTitle": "בחרו קבצי עדכון", + "UserProfileWindowTitle": "ניהול פרופילי משתמש", + "CheatWindowTitle": "נהל צ'יטים למשחק", + "DlcWindowTitle": "נהל הרחבות משחק עבור {0} ({1})", + "UpdateWindowTitle": "נהל עדכוני משחקים", + "CheatWindowHeading": "צ'יטים זמינים עבור {0} [{1}]", + "BuildId": "מזהה בניה:", + "DlcWindowHeading": "{0} הרחבות משחק", + "UserProfilesEditProfile": "ערוך נבחר/ים", + "Cancel": "בטל", + "Save": "שמור", + "Discard": "השלך", + "UserProfilesSetProfileImage": "הגדר תמונת פרופיל", + "UserProfileEmptyNameError": "נדרש שם", + "UserProfileNoImageError": "נדרשת תמונת פרופיל", + "GameUpdateWindowHeading": "נהל עדכונים עבור {0} ({1})", + "SettingsTabHotkeysResScaleUpHotkey": "שפר רזולוציה:", + "SettingsTabHotkeysResScaleDownHotkey": "הפחת רזולוציה:", + "UserProfilesName": "שם:", + "UserProfilesUserId": "מזהה משתמש:", + "SettingsTabGraphicsBackend": "אחראי גראפיקה", + "SettingsTabGraphicsBackendTooltip": "אחראי גראפיקה לשימוש", + "SettingsEnableTextureRecompression": "אפשר דחיסה מחדש של המרקם", + "SettingsEnableTextureRecompressionTooltip": " דוחס מרקמים מסויימים להפחתת השימוש בראם הוירטואלי.\n\nמומלץ לשימוש עם כרטיס גראפי בעל פחות מ-4GiB בראם הוירטואלי.\n\nמוטב להשאיר כבוי אם אינכם בטוחים.", + "SettingsTabGraphicsPreferredGpu": "כרטיס גראפי מועדף", + "SettingsTabGraphicsPreferredGpuTooltip": "בחר את הכרטיס הגראפי שישומש עם הגראפיקה של וולקאן.\n\nדבר זה לא משפיע על הכרטיס הגראפי שישומש עם OpenGL.\n\nמוטב לבחור את ה-GPU המסומן כ-\"dGPU\" אם אינכם בטוחים, אם זו לא אופצייה, אל תשנו דבר.", + "SettingsAppRequiredRestartMessage": "ריוג'ינקס דורש אתחול מחדש", + "SettingsGpuBackendRestartMessage": "הגדרות אחראי גרפיקה או כרטיס גראפי שונו. זה ידרוש הפעלה מחדש כדי להחיל שינויים", + "SettingsGpuBackendRestartSubMessage": "האם ברצונך להפעיל מחדש כעט?", + "RyujinxUpdaterMessage": "האם ברצונך לעדכן את ריוג'ינקס לגרסא האחרונה?", + "SettingsTabHotkeysVolumeUpHotkey": "הגבר את עוצמת הקול:", + "SettingsTabHotkeysVolumeDownHotkey": "הנמך את עוצמת הקול:", + "SettingsEnableMacroHLE": "Enable Macro HLE", + "SettingsEnableMacroHLETooltip": "אמולצייה ברמה גבוהה של כרטיס גראפי עם קוד מקרו.\n\nמשפר את ביצועי היישום אך עלול לגרום לגליצ'ים חזותיים במשחקים מסויימים.\n\nמוטב להשאיר דלוק אם אינך בטוח.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", + "VolumeShort": "שמע", + "UserProfilesManageSaves": "נהל שמורים", + "DeleteUserSave": "האם ברצונך למחוק את תקיית השמור למשחק זה?", + "IrreversibleActionNote": "הפעולה הזו בלתי הפיכה.", + "SaveManagerHeading": "נהל שמורי משחק עבור {0} ({1})", + "SaveManagerTitle": "מנהל שמירות", + "Name": "שם", + "Size": "גודל", + "Search": "חפש", + "UserProfilesRecoverLostAccounts": "שחזר חשבון שאבד", + "Recover": "שחזר", + "UserProfilesRecoverHeading": "שמורים נמצאו לחשבונות הבאים", + "UserProfilesRecoverEmptyList": "אין פרופילים לשחזור", + "GraphicsAATooltip": "מחיל החלקת-עקומות על עיבוד המשחק", + "GraphicsAALabel": "החלקת-עקומות:", + "GraphicsScalingFilterLabel": "מסנן מידת איכות:", + "GraphicsScalingFilterTooltip": "אפשר מידת איכות מסוג איגור-תמונה", + "GraphicsScalingFilterLevelLabel": "רמה", + "GraphicsScalingFilterLevelTooltip": "קבע מידת איכות תמונה לפי רמת סינון", + "SmaaLow": "SMAA נמוך", + "SmaaMedium": "SMAA בינוני", + "SmaaHigh": "SMAA גבוהה", + "SmaaUltra": "SMAA אולטרה", + "UserEditorTitle": "ערוך משתמש", + "UserEditorTitleCreate": "צור משתמש", + "SettingsTabNetworkInterface": "ממשק רשת", + "NetworkInterfaceTooltip": "ממשק הרשת המשומש עבור יכולות לאן", + "NetworkInterfaceDefault": "ברירת המחדל", + "PackagingShaders": "אורז הצללות", + "AboutChangelogButton": "צפה במידע אודות שינויים בגיטהב", + "AboutChangelogButtonTooltipMessage": "לחץ כדי לפתוח את יומן השינויים עבור גרסה זו בדפדפן ברירת המחדל שלך." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/it_IT.json b/src/Ryujinx.Ava/Assets/Locales/it_IT.json index 0ae027496..5aff7a7ec 100644 --- a/src/Ryujinx.Ava/Assets/Locales/it_IT.json +++ b/src/Ryujinx.Ava/Assets/Locales/it_IT.json @@ -2,16 +2,17 @@ "Language": "Italiano", "MenuBarFileOpenApplet": "Apri Applet", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Apri l'applet Mii Editor in modalità Standalone", - "SettingsTabInputDirectMouseAccess": "Accesso diretto al mouse", + "SettingsTabInputDirectMouseAccess": "Accesso diretto mouse", "SettingsTabSystemMemoryManagerMode": "Modalità di gestione della memoria:", "SettingsTabSystemMemoryManagerModeSoftware": "Software", "SettingsTabSystemMemoryManagerModeHost": "Host (veloce)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Unchecked (più veloce, non sicura)", + "SettingsTabSystemUseHypervisor": "Usa Hypervisor", "MenuBarFile": "_File", "MenuBarFileOpenFromFile": "_Carica applicazione da un file", "MenuBarFileOpenUnpacked": "Carica _gioco estratto", "MenuBarFileOpenEmuFolder": "Apri cartella di Ryujinx", - "MenuBarFileOpenLogsFolder": "Apri cartella dei logs", + "MenuBarFileOpenLogsFolder": "Apri cartella dei Log", "MenuBarFileExit": "_Esci", "MenuBarOptions": "Opzioni", "MenuBarOptionsToggleFullscreen": "Schermo intero", @@ -26,11 +27,14 @@ "MenuBarToolsInstallFirmware": "Installa firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Installa un firmware da file XCI o ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Installa un firmare da una cartella", + "MenuBarToolsManageFileTypes": "Gestisci i tipi di file", + "MenuBarToolsInstallFileTypes": "Installa i tipi di file", + "MenuBarToolsUninstallFileTypes": "Disinstalla i tipi di file", "MenuBarHelp": "Aiuto", "MenuBarHelpCheckForUpdates": "Controlla aggiornamenti", "MenuBarHelpAbout": "Informazioni", "MenuSearch": "Cerca...", - "GameListHeaderFavorite": "Pref", + "GameListHeaderFavorite": "Preferito", "GameListHeaderIcon": "Icona", "GameListHeaderApplication": "Nome", "GameListHeaderDeveloper": "Sviluppatore", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (includendo aggiornamenti)", "StatusBarGamesLoaded": "{0}/{1} Giochi caricati", "StatusBarSystemVersion": "Versione di sistema: {0}", + "LinuxVmMaxMapCountDialogTitle": "Limite basso per le mappature di memoria rilevate", + "LinuxVmMaxMapCountDialogTextPrimary": "Vuoi aumentare il valore di vm.max_map_count a {0}?", + "LinuxVmMaxMapCountDialogTextSecondary": "Alcuni giochi potrebbero provare a creare più mappature di memoria di quanto sia attualmente consentito. Ryujinx si bloccherà non appena questo limite viene superato.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Sì, fino al prossimo riavvio", + "LinuxVmMaxMapCountDialogButtonPersistent": "Sì, in modo permanente", + "LinuxVmMaxMapCountWarningTextPrimary": "La quantità massima di mappature di memoria è inferiore a quella consigliata.", + "LinuxVmMaxMapCountWarningTextSecondary": "Il valore corrente di vm.max_map_count ({0}) è inferiore a {1}. Alcuni giochi potrebbero provare a creare più mappature di memoria di quanto sia attualmente consentito. Ryujinx si bloccherà non appena questo limite viene superato.\n\nPotresti voler aumentare manualmente il limite o installare pkexec, il che permette a Ryujinx di assisterlo.", "Settings": "Impostazioni", "SettingsTabGeneral": "Interfaccia utente", "SettingsTabGeneralGeneral": "Generali", "SettingsTabGeneralEnableDiscordRichPresence": "Attiva Discord Rich Presence", "SettingsTabGeneralCheckUpdatesOnLaunch": "Controlla aggiornamenti all'avvio", "SettingsTabGeneralShowConfirmExitDialog": "Mostra dialogo \"Conferma Uscita\"", + "SettingsTabGeneralHideCursor": "Nascondi il cursore:", + "SettingsTabGeneralHideCursorNever": "Mai", "SettingsTabGeneralHideCursorOnIdle": "Nascondi cursore inattivo", + "SettingsTabGeneralHideCursorAlways": "Sempre", "SettingsTabGeneralGameDirectories": "Cartelle dei giochi", "SettingsTabGeneralAdd": "Aggiungi", "SettingsTabGeneralRemove": "Rimuovi", @@ -89,7 +103,7 @@ "SettingsTabSystemSystemRegionAustralia": "Australia", "SettingsTabSystemSystemRegionChina": "Cina", "SettingsTabSystemSystemRegionKorea": "Corea", - "SettingsTabSystemSystemRegionTaiwan": "Tailandia", + "SettingsTabSystemSystemRegionTaiwan": "Taiwan", "SettingsTabSystemSystemLanguage": "Lingua del sistema:", "SettingsTabSystemSystemLanguageJapanese": "Giapponese", "SettingsTabSystemSystemLanguageAmericanEnglish": "Inglese americano", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Attiva Fs Access Logs", "SettingsTabLoggingFsGlobalAccessLogMode": "Modalità log accesso globale Fs:", "SettingsTabLoggingDeveloperOptions": "Opzioni da sviluppatore (AVVISO: Ridurrà le prestazioni)", + "SettingsTabLoggingDeveloperOptionsNote": "ATTENZIONE: ridurrà le prestazioni", "SettingsTabLoggingGraphicsBackendLogLevel": "Livello registro backend grafico:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Nessuno", "SettingsTabLoggingGraphicsBackendLogLevelError": "Errore", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Giù", "ControllerSettingsDPadLeft": "Sinistra", "ControllerSettingsDPadRight": "Destra", + "ControllerSettingsStickButton": "Pulsante", + "ControllerSettingsStickUp": "Su", + "ControllerSettingsStickDown": "Giù", + "ControllerSettingsStickLeft": "Sinistra", + "ControllerSettingsStickRight": "Destra", + "ControllerSettingsStickStick": "Levetta", + "ControllerSettingsStickInvertXAxis": "Inverti levetta X", + "ControllerSettingsStickInvertYAxis": "Inverti levetta Y", + "ControllerSettingsStickDeadzone": "Zona morta:", "ControllerSettingsLStick": "Stick sinistro", - "ControllerSettingsLStickButton": "Pulsante", - "ControllerSettingsLStickUp": "Su", - "ControllerSettingsLStickDown": "Giù", - "ControllerSettingsLStickLeft": "Sinistra", - "ControllerSettingsLStickRight": "Destra", - "ControllerSettingsLStickStick": "Levetta", - "ControllerSettingsLStickInvertXAxis": "Inverti stick X", - "ControllerSettingsLStickInvertYAxis": "Inverti stick Y", - "ControllerSettingsLStickDeadzone": "Zona morta:", "ControllerSettingsRStick": "Stick destro", - "ControllerSettingsRStickButton": "Pulsante", - "ControllerSettingsRStickUp": "Su", - "ControllerSettingsRStickDown": "Giù", - "ControllerSettingsRStickLeft": "Sinistra", - "ControllerSettingsRStickRight": "Destra", - "ControllerSettingsRStickStick": "Levetta", - "ControllerSettingsRStickInvertXAxis": "Inverti stick X", - "ControllerSettingsRStickInvertYAxis": "Inverti stick Y", - "ControllerSettingsRStickDeadzone": "Zona morta:", "ControllerSettingsTriggersLeft": "Grilletto sinistro", "ControllerSettingsTriggersRight": "Grilletto destro", "ControllerSettingsTriggersButtonsLeft": "Pulsante dorsale sinistro", @@ -260,8 +266,9 @@ "UserProfilesChangeProfileImage": "Cambia immagine profilo", "UserProfilesAvailableUserProfiles": "Profili utente disponibili:", "UserProfilesAddNewProfile": "Aggiungi nuovo profilo", - "UserProfilesDeleteSelectedProfile": "Elimina il profilo selezionato", + "UserProfilesDelete": "Elimina", "UserProfilesClose": "Chiudi", + "ProfileNameSelectionWatermark": "Scegli un soprannome", "ProfileImageSelectionTitle": "Selezione dell'immagine profilo", "ProfileImageSelectionHeader": "Scegli un'immagine profilo", "ProfileImageSelectionNote": "Puoi importare un'immagine profilo personalizzata o selezionare un avatar dal firmware del sistema", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Salva profilo", "MenuBarFileToolsTakeScreenshot": "Fai uno screenshot", "MenuBarFileToolsHideUi": "Nascondi UI", + "GameListContextMenuRunApplication": "Esegui applicazione", "GameListContextMenuToggleFavorite": "Preferito", "GameListContextMenuToggleFavoriteToolTip": "Segna il gioco come preferito", "SettingsTabGeneralTheme": "Tema", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Non è stato trovato alcun firmware installato, ma Ryujinx è riuscito ad installare il firmware {0} dal gioco fornito.\nL'emulatore si avvierà adesso.", "DialogFirmwareNoFirmwareInstalledMessage": "Nessun firmware installato", "DialogFirmwareInstalledMessage": "Il firmware {0} è stato installato", + "DialogInstallFileTypesSuccessMessage": "Tipi di file installati con successo!", + "DialogInstallFileTypesErrorMessage": "Impossibile installare i tipi di file.", + "DialogUninstallFileTypesSuccessMessage": "Tipi di file disinstallati con successo!", + "DialogUninstallFileTypesErrorMessage": "Disinstallazione dei tipi di file non riuscita.", "DialogOpenSettingsWindowLabel": "Apri finestra delle impostazioni", "DialogControllerAppletTitle": "Applet del controller", "DialogMessageDialogErrorExceptionMessage": "Errore nella visualizzazione del Message Dialog: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "La versione del sistema {0} è stata installata.", "DialogUserProfileDeletionWarningMessage": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato", "DialogUserProfileDeletionConfirmMessage": "Vuoi eliminare il profilo selezionato?", + "DialogUserProfileUnsavedChangesTitle": "Attenzione - Modifiche Non Salvate", + "DialogUserProfileUnsavedChangesMessage": "Hai apportato modifiche a questo profilo utente che non sono state salvate.", + "DialogUserProfileUnsavedChangesSubMessage": "Vuoi scartare le modifiche?", "DialogControllerSettingsModifiedConfirmMessage": "Le attuali impostazioni del controller sono state aggiornate.", "DialogControllerSettingsModifiedConfirmSubMessage": "Vuoi salvare?", "DialogLoadNcaErrorMessage": "{0}. File errato: {1}", @@ -409,13 +424,14 @@ "AmiiboOptionsShowAllLabel": "Mostra tutti gli amiibo", "AmiiboOptionsUsRandomTagLabel": "Hack: Usa un tag uuid casuale", "DlcManagerTableHeadingEnabledLabel": "Abilitato", - "DlcManagerTableHeadingTitleIdLabel": "Titolo ID", + "DlcManagerTableHeadingTitleIdLabel": "ID Titolo", "DlcManagerTableHeadingContainerPathLabel": "Percorso del contenitore", "DlcManagerTableHeadingFullPathLabel": "Percorso completo", "DlcManagerRemoveAllButton": "Rimuovi tutti", "DlcManagerEnableAllButton": "Abilita tutto", "DlcManagerDisableAllButton": "Disabilita tutto", "MenuBarOptionsChangeLanguage": "Cambia lingua", + "MenuBarShowFileTypes": "Mostra tipi di file", "CommonSort": "Ordina", "CommonShowNames": "Mostra nomi", "CommonFavorite": "Preferito", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Usa una software page table per la traduzione degli indirizzi. Massima precisione ma prestazioni più lente.", "MemoryManagerHostTooltip": "Mappa direttamente la memoria nello spazio degli indirizzi dell'host. Compilazione ed esecuzione JIT molto più veloce.", "MemoryManagerUnsafeTooltip": "Mappa direttamente la memoria, ma non maschera l'indirizzo all'interno dello spazio degli indirizzi guest prima dell'accesso. Più veloce, ma a costo della sicurezza. L'applicazione guest può accedere alla memoria da qualsiasi punto di Ryujinx, quindi esegui solo programmi di cui ti fidi con questa modalità.", + "UseHypervisorTooltip": "Usa Hypervisor invece di JIT. Migliora notevolmente le prestazioni quando disponibile, ma può essere instabile nel suo stato attuale.", "DRamTooltip": "Espande l'ammontare di memoria sul sistema emulato da 4GiB A 6GiB", "IgnoreMissingServicesTooltip": "Attiva o disattiva l'opzione di ignorare i servizi mancanti", "GraphicsBackendThreadingTooltip": "Attiva il Graphics Backend Multithreading", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Non può avere meno di {0} caratteri", "SwkbdMinRangeCharacters": "Può avere da {0} a {1} caratteri", "SoftwareKeyboard": "Tastiera software", + "SoftwareKeyboardModeNumbersOnly": "Deve essere solo numeri", + "SoftwareKeyboardModeAlphabet": "Deve essere solo caratteri non CJK", + "SoftwareKeyboardModeASCII": "Deve essere solo testo ASCII", "DialogControllerAppletMessagePlayerRange": "L'applicazione richiede {0} giocatori con:\n\nTIPI: {1}\n\nGIOCATORI: {2}\n\n{3}Apri le impostazioni e riconfigura l'input adesso o premi Chiudi.", "DialogControllerAppletMessage": "L'applicazione richiede esattamente {0} giocatori con:\n\nTIPI: {1}\n\nGIOCATORI: {2}\n\n{3}Apri le impostazioni e riconfigura l'input adesso o premi Chiudi.", "DialogControllerAppletDockModeSet": "Modalità TV attivata. Neanche portatile è valida.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Gestisci DLC dei giochi", "UpdateWindowTitle": "Gestisci aggiornamenti dei giochi", "CheatWindowHeading": "Cheat disponibiili per {0} [{1}]", + "BuildId": "ID Build", "DlcWindowHeading": "DLC disponibili per {0} [{1}]", "UserProfilesEditProfile": "Modifica selezionati", "Cancel": "Annulla", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Diminuire il volume:", "SettingsEnableMacroHLE": "Abilita Macro HLE", "SettingsEnableMacroHLETooltip": "Emulazione di alto livello del codice Macro GPU.\n\nMigliora le prestazioni, ma può causare anomalie grafiche in alcuni giochi.\n\nLasciare ON se non sei sicuro.", + "SettingsEnableColorSpacePassthrough": "Spazio colore passante", + "SettingsEnableColorSpacePassthroughTooltip": "Indica al backend Vulkan di passare le informazioni sul colore senza specificare uno spazio colore. Per gli utenti con schermi ad ampia gamma, questo può risultare in colori più vivaci, al costo della correttezza del colore.", "VolumeShort": "Vol", "UserProfilesManageSaves": "Gestisci i salvataggi", "DeleteUserSave": "Vuoi eliminare il salvataggio utente per questo gioco?", @@ -610,5 +633,24 @@ "Search": "Cerca", "UserProfilesRecoverLostAccounts": "Recupera il tuo account", "Recover": "Recupera", - "UserProfilesRecoverHeading": "Sono stati trovati dei salvataggi per i seguenti account" -} + "UserProfilesRecoverHeading": "Sono stati trovati dei salvataggi per i seguenti account", + "UserProfilesRecoverEmptyList": "Nessun profilo da recuperare", + "GraphicsAATooltip": "Applica anti-aliasing al rendering del gioco", + "GraphicsAALabel": "Anti-Aliasing:", + "GraphicsScalingFilterLabel": "Filtro di scala:", + "GraphicsScalingFilterTooltip": "Abilita scalatura Framebuffer", + "GraphicsScalingFilterLevelLabel": "Livello", + "GraphicsScalingFilterLevelTooltip": "Imposta livello del filtro di scala", + "SmaaLow": "SMAA Basso", + "SmaaMedium": "SMAA Medio", + "SmaaHigh": "SMAA Alto", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Modificare L'Utente", + "UserEditorTitleCreate": "Crea Un Utente", + "SettingsTabNetworkInterface": "Interfaccia di rete:", + "NetworkInterfaceTooltip": "L'interfaccia di rete utilizzata per le funzionalità LAN", + "NetworkInterfaceDefault": "Predefinito", + "PackagingShaders": "Comprimendo shader", + "AboutChangelogButton": "Visualizza changelog su GitHub", + "AboutChangelogButtonTooltipMessage": "Clicca per aprire il changelog per questa versione nel tuo browser predefinito." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/ja_JP.json b/src/Ryujinx.Ava/Assets/Locales/ja_JP.json index 581443f55..5b31c5f20 100644 --- a/src/Ryujinx.Ava/Assets/Locales/ja_JP.json +++ b/src/Ryujinx.Ava/Assets/Locales/ja_JP.json @@ -1,5 +1,5 @@ { - "Language": "日本語", + "Language": "英語 (アメリカ)", "MenuBarFileOpenApplet": "アプレットを開く", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "スタンドアロンモードで Mii エディタアプレットを開きます", "SettingsTabInputDirectMouseAccess": "マウス直接アクセス", @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "ソフトウェア", "SettingsTabSystemMemoryManagerModeHost": "ホスト (高速)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "ホスト, チェックなし (最高速, 安全でない)", + "SettingsTabSystemUseHypervisor": "ハイパーバイザーを使用", "MenuBarFile": "ファイル(_F)", "MenuBarFileOpenFromFile": "ファイルからアプリケーションをロード(_L)", "MenuBarFileOpenUnpacked": "展開されたゲームをロード", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "ファームウェアをインストール", "MenuBarFileToolsInstallFirmwareFromFile": "XCI または ZIP からファームウェアをインストール", "MenuBarFileToolsInstallFirmwareFromDirectory": "ディレクトリからファームウェアをインストール", + "MenuBarToolsManageFileTypes": "ファイル形式を管理", + "MenuBarToolsInstallFileTypes": "ファイル形式をインストール", + "MenuBarToolsUninstallFileTypes": "ファイル形式をアンインストール", "MenuBarHelp": "ヘルプ", "MenuBarHelpCheckForUpdates": "アップデートを確認", "MenuBarHelpAbout": "Ryujinx について", @@ -55,12 +59,12 @@ "GameListContextMenuCacheManagement": "キャッシュ管理", "GameListContextMenuCacheManagementPurgePptc": "PPTC を再構築", "GameListContextMenuCacheManagementPurgePptcToolTip": "次回のゲーム起動時に PPTC を再構築します", - "GameListContextMenuCacheManagementPurgeShaderCache": "シェーダキャッシュを破棄", - "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "アプリケーションのシェーダキャッシュを破棄します", + "GameListContextMenuCacheManagementPurgeShaderCache": "シェーダーキャッシュを破棄", + "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "アプリケーションのシェーダーキャッシュを破棄します", "GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC ディレクトリを開く", "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "アプリケーションの PPTC キャッシュを格納するディレクトリを開きます", - "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "シェーダキャッシュディレクトリを開く", - "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "アプリケーションのシェーダキャッシュを格納するディレクトリを開きます", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "シェーダーキャッシュディレクトリを開く", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "アプリケーションのシェーダーキャッシュを格納するディレクトリを開きます", "GameListContextMenuExtractData": "データを展開", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "現在のアプリケーション設定(アップデート含む)からロゴセクションを展開します", "StatusBarGamesLoaded": "{0}/{1} ゲーム", "StatusBarSystemVersion": "システムバージョン: {0}", + "LinuxVmMaxMapCountDialogTitle": "メモリマッピング上限値が小さすぎます", + "LinuxVmMaxMapCountDialogTextPrimary": "vm.max_map_count の値を {0}に増やしますか?", + "LinuxVmMaxMapCountDialogTextSecondary": "ゲームによっては, 現在許可されているサイズより大きなメモリマッピングを作成しようとすることがあります. この制限を超えると, Ryjinx はすぐにクラッシュします.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "はい, 次回再起動まで", + "LinuxVmMaxMapCountDialogButtonPersistent": "はい, 恒久的に", + "LinuxVmMaxMapCountWarningTextPrimary": "メモリマッピングの最大量が推奨値よりも小さいです.", + "LinuxVmMaxMapCountWarningTextSecondary": "vm.max_map_count の現在値 {0} は {1} よりも小さいです. ゲームによっては現在許可されている値よりも大きなメモリマッピングを作成しようとする場合があります. 上限を越えた場合, Ryujinx はクラッシュします.", "Settings": "設定", "SettingsTabGeneral": "ユーザインタフェース", "SettingsTabGeneralGeneral": "一般", - "SettingsTabGeneralEnableDiscordRichPresence": "Discord リッチプレゼンスを有効", - "SettingsTabGeneralCheckUpdatesOnLaunch": "起動時にアップデートを確認", - "SettingsTabGeneralShowConfirmExitDialog": "\"終了を確認\" ダイアログを表示", - "SettingsTabGeneralHideCursorOnIdle": "アイドル時にカーソルを隠す", + "SettingsTabGeneralEnableDiscordRichPresence": "Discord リッチプレゼンスを有効にする", + "SettingsTabGeneralCheckUpdatesOnLaunch": "起動時にアップデートを確認する", + "SettingsTabGeneralShowConfirmExitDialog": "\"終了を確認\" ダイアログを表示する", + "SettingsTabGeneralHideCursor": "マウスカーソルを非表示", + "SettingsTabGeneralHideCursorNever": "決して", + "SettingsTabGeneralHideCursorOnIdle": "アイドル時", + "SettingsTabGeneralHideCursorAlways": "常時", "SettingsTabGeneralGameDirectories": "ゲームディレクトリ", "SettingsTabGeneralAdd": "追加", "SettingsTabGeneralRemove": "削除", @@ -120,11 +134,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "ハック", "SettingsTabSystemHacksNote": " (挙動が不安定になる可能性があります)", - "SettingsTabSystemExpandDramSize": "DRAMサイズを6GiBに拡大", - "SettingsTabSystemIgnoreMissingServices": "未実装サービスを無視", + "SettingsTabSystemExpandDramSize": "DRAMサイズを6GiBに拡大する", + "SettingsTabSystemIgnoreMissingServices": "未実装サービスを無視する", "SettingsTabGraphics": "グラフィックス", "SettingsTabGraphicsAPI": "グラフィックスAPI", - "SettingsTabGraphicsEnableShaderCache": "シェーダキャッシュを有効", + "SettingsTabGraphicsEnableShaderCache": "シェーダーキャッシュを有効にする", "SettingsTabGraphicsAnisotropicFiltering": "異方性フィルタリング:", "SettingsTabGraphicsAnisotropicFilteringAuto": "自動", "SettingsTabGraphicsAnisotropicFiltering2x": "2x", @@ -145,25 +159,26 @@ "SettingsTabGraphicsAspectRatio32x9": "32:9", "SettingsTabGraphicsAspectRatioStretch": "ウインドウサイズに合わせる", "SettingsTabGraphicsDeveloperOptions": "開発者向けオプション", - "SettingsTabGraphicsShaderDumpPath": "グラフィックス シェーダダンプパス:", + "SettingsTabGraphicsShaderDumpPath": "グラフィックス シェーダー ダンプパス:", "SettingsTabLogging": "ロギング", "SettingsTabLoggingLogging": "ロギング", - "SettingsTabLoggingEnableLoggingToFile": "ファイルへのロギングを有効", - "SettingsTabLoggingEnableStubLogs": "Stub ログを有効", - "SettingsTabLoggingEnableInfoLogs": "Info ログを有効", - "SettingsTabLoggingEnableWarningLogs": "Warning ログを有効", - "SettingsTabLoggingEnableErrorLogs": "Error ログを有効", - "SettingsTabLoggingEnableTraceLogs": "Trace ログを有効", - "SettingsTabLoggingEnableGuestLogs": "Guest ログを有効", - "SettingsTabLoggingEnableFsAccessLogs": "Fs アクセスログを有効", + "SettingsTabLoggingEnableLoggingToFile": "ファイルへのロギングを有効にする", + "SettingsTabLoggingEnableStubLogs": "Stub ログを有効にする", + "SettingsTabLoggingEnableInfoLogs": "Info ログを有効にする", + "SettingsTabLoggingEnableWarningLogs": "Warning ログを有効にする", + "SettingsTabLoggingEnableErrorLogs": "Error ログを有効にする", + "SettingsTabLoggingEnableTraceLogs": "Trace ログを有効にする", + "SettingsTabLoggingEnableGuestLogs": "Guest ログを有効にする", + "SettingsTabLoggingEnableFsAccessLogs": "Fs アクセスログを有効にする", "SettingsTabLoggingFsGlobalAccessLogMode": "Fs グローバルアクセスログモード:", - "SettingsTabLoggingDeveloperOptions": "開発者オプション (警告: パフォーマンスが低下します)", + "SettingsTabLoggingDeveloperOptions": "開発者オプション", + "SettingsTabLoggingDeveloperOptionsNote": "警告: パフォーマンスを低下させます", "SettingsTabLoggingGraphicsBackendLogLevel": "グラフィックスバックエンド ログレベル:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "なし", "SettingsTabLoggingGraphicsBackendLogLevelError": "エラー", "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "パフォーマンス低下", "SettingsTabLoggingGraphicsBackendLogLevelAll": "すべて", - "SettingsTabLoggingEnableDebugLogs": "デバッグログを有効", + "SettingsTabLoggingEnableDebugLogs": "デバッグログを有効にする", "SettingsTabInput": "入力", "SettingsTabInputEnableDockedMode": "ドッキングモード", "SettingsTabInputDirectKeyboardAccess": "キーボード直接アクセス", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "下", "ControllerSettingsDPadLeft": "左", "ControllerSettingsDPadRight": "右", + "ControllerSettingsStickButton": "ボタン", + "ControllerSettingsStickUp": "上", + "ControllerSettingsStickDown": "下", + "ControllerSettingsStickLeft": "左", + "ControllerSettingsStickRight": "右", + "ControllerSettingsStickStick": "スティック", + "ControllerSettingsStickInvertXAxis": "X軸を反転", + "ControllerSettingsStickInvertYAxis": "Y軸を反転", + "ControllerSettingsStickDeadzone": "遊び:", "ControllerSettingsLStick": "左スティック", - "ControllerSettingsLStickButton": "ボタン", - "ControllerSettingsLStickUp": "上", - "ControllerSettingsLStickDown": "下", - "ControllerSettingsLStickLeft": "左", - "ControllerSettingsLStickRight": "右", - "ControllerSettingsLStickStick": "スティック", - "ControllerSettingsLStickInvertXAxis": "X軸を反転", - "ControllerSettingsLStickInvertYAxis": "Y軸を反転", - "ControllerSettingsLStickDeadzone": "遊び:", "ControllerSettingsRStick": "右スティック", - "ControllerSettingsRStickButton": "ボタン", - "ControllerSettingsRStickUp": "上", - "ControllerSettingsRStickDown": "下", - "ControllerSettingsRStickLeft": "左", - "ControllerSettingsRStickRight": "右", - "ControllerSettingsRStickStick": "スティック", - "ControllerSettingsRStickInvertXAxis": "X軸を反転", - "ControllerSettingsRStickInvertYAxis": "Y軸を反転", - "ControllerSettingsRStickDeadzone": "遊び:", "ControllerSettingsTriggersLeft": "左トリガー", "ControllerSettingsTriggersRight": "右トリガー", "ControllerSettingsTriggersButtonsLeft": "左トリガーボタン", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "プロファイルを作成", "UserProfilesDelete": "削除", "UserProfilesClose": "閉じる", + "ProfileNameSelectionWatermark": "ニックネームを選択", "ProfileImageSelectionTitle": "プロファイル画像選択", "ProfileImageSelectionHeader": "プロファイル画像を選択", "ProfileImageSelectionNote": "カスタム画像をインポート, またはファームウェア内のアバターを選択できます", @@ -281,7 +288,8 @@ "ControllerSettingsRemoveProfileToolTip": "プロファイルを削除", "ControllerSettingsSaveProfileToolTip": "プロファイルをセーブ", "MenuBarFileToolsTakeScreenshot": "スクリーンショットを撮影", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "UIを隠す", + "GameListContextMenuRunApplication": "アプリケーションを実行", "GameListContextMenuToggleFavorite": "お気に入りを切り替え", "GameListContextMenuToggleFavoriteToolTip": "ゲームをお気に入りに含めるかどうかを切り替えます", "SettingsTabGeneralTheme": "テーマ", @@ -289,7 +297,7 @@ "SettingsTabGeneralThemeBaseStyle": "基本スタイル", "SettingsTabGeneralThemeBaseStyleDark": "ダーク", "SettingsTabGeneralThemeBaseStyleLight": "ライト", - "SettingsTabGeneralThemeEnableCustomTheme": "カスタムテーマを有効", + "SettingsTabGeneralThemeEnableCustomTheme": "カスタムテーマを有効にする", "ButtonBrowse": "参照", "ControllerSettingsConfigureGeneral": "設定", "ControllerSettingsRumble": "振動", @@ -316,7 +324,7 @@ "DialogUpdaterConvertFailedMessage": "現在の Ryujinx バージョンの変換に失敗しました.", "DialogUpdaterCancelUpdateMessage": "アップデータをキャンセル中!", "DialogUpdaterAlreadyOnLatestVersionMessage": "最新バージョンの Ryujinx を使用中です!", - "DialogUpdaterFailedToGetVersionMessage": "An error has occurred when trying to get release information from GitHub Release. This can be caused if a new release is being compiled by GitHub Actions. Try again in a few minutes.", + "DialogUpdaterFailedToGetVersionMessage": "Github からのリリース情報取得時にエラーが発生しました. Github Actions でリリースファイルを作成中かもしれません. 後ほどもう一度試してみてください.", "DialogUpdaterConvertFailedGithubMessage": "Github から取得した Ryujinx バージョンの変換に失敗しました.", "DialogUpdaterDownloadingMessage": "アップデートをダウンロード中...", "DialogUpdaterExtractionMessage": "アップデートを展開中...", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "ファームウェアがインストールされていませんが, ゲームに含まれるファームウェア {0} をインストールできます.\\nエミュレータが開始します.", "DialogFirmwareNoFirmwareInstalledMessage": "ファームウェアがインストールされていません", "DialogFirmwareInstalledMessage": "ファームウェア {0} がインストールされました", + "DialogInstallFileTypesSuccessMessage": "ファイル形式のインストールに成功しました!", + "DialogInstallFileTypesErrorMessage": "ファイル形式のインストールに失敗しました.", + "DialogUninstallFileTypesSuccessMessage": "ファイル形式のアンインストールに成功しました!", + "DialogUninstallFileTypesErrorMessage": "ファイル形式のアンインストールに失敗しました.", "DialogOpenSettingsWindowLabel": "設定ウインドウを開く", "DialogControllerAppletTitle": "コントローラアプレット", "DialogMessageDialogErrorExceptionMessage": "メッセージダイアログ表示エラー: {0}", @@ -355,8 +367,8 @@ "DialogWarning": "警告", "DialogPPTCDeletionMessage": "次回起動時に PPTC を再構築します:\n\n{0}\n\n実行してよろしいですか?", "DialogPPTCDeletionErrorMessage": "PPTC キャッシュ破棄エラー {0}: {1}", - "DialogShaderDeletionMessage": "シェーダキャッシュを破棄しようとしています:\n\n{0}\n\n実行してよろしいですか?", - "DialogShaderDeletionErrorMessage": "シェーダキャッシュ破棄エラー {0}: {1}", + "DialogShaderDeletionMessage": "シェーダーキャッシュを破棄しようとしています:\n\n{0}\n\n実行してよろしいですか?", + "DialogShaderDeletionErrorMessage": "シェーダーキャッシュ破棄エラー {0}: {1}", "DialogRyujinxErrorMessage": "エラーが発生しました", "DialogInvalidTitleIdErrorMessage": "UI エラー: 選択されたゲームは有効なタイトル ID を保持していません", "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "{0} には有効なシステムファームウェアがありません.", @@ -368,14 +380,17 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "システムバージョン {0} が正常にインストールされました.", "DialogUserProfileDeletionWarningMessage": "選択されたプロファイルを削除すると,プロファイルがひとつも存在しなくなります", "DialogUserProfileDeletionConfirmMessage": "選択されたプロファイルを削除しますか", + "DialogUserProfileUnsavedChangesTitle": "警告 - 保存されていない変更", + "DialogUserProfileUnsavedChangesMessage": "保存されていないユーザプロファイルを変更しました.", + "DialogUserProfileUnsavedChangesSubMessage": "変更を破棄しますか?", "DialogControllerSettingsModifiedConfirmMessage": "現在のコントローラ設定が更新されました.", "DialogControllerSettingsModifiedConfirmSubMessage": "セーブしますか?", "DialogLoadNcaErrorMessage": "{0}. エラー発生ファイル: {1}", "DialogDlcNoDlcErrorMessage": "選択されたファイルはこのタイトル用の DLC ではありません!", "DialogPerformanceCheckLoggingEnabledMessage": "トレースロギングを有効にします. これは開発者のみに有用な機能です.", "DialogPerformanceCheckLoggingEnabledConfirmMessage": "パフォーマンス最適化のためには,トレースロギングを無効にすることを推奨します. トレースロギングを無効にしてよろしいですか?", - "DialogPerformanceCheckShaderDumpEnabledMessage": "シェーダダンプを有効にします. これは開発者のみに有用な機能です.", - "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "パフォーマンス最適化のためには, シェーダダンプを無効にすることを推奨します. シェーダダンプを無効にしてよろしいですか?", + "DialogPerformanceCheckShaderDumpEnabledMessage": "シェーダーダンプを有効にします. これは開発者のみに有用な機能です.", + "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "パフォーマンス最適化のためには, シェーダーダンプを無効にすることを推奨します. シェーダーダンプを無効にしてよろしいですか?", "DialogLoadAppGameAlreadyLoadedMessage": "ゲームはすでにロード済みです", "DialogLoadAppGameAlreadyLoadedSubMessage": "別のゲームを起動する前に, エミュレーションを停止またはエミュレータを閉じてください.", "DialogUpdateAddUpdateErrorMessage": "選択されたファイルはこのタイトル用のアップデートではありません!", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "すべて有効", "DlcManagerDisableAllButton": "すべて無効", "MenuBarOptionsChangeLanguage": "言語を変更", + "MenuBarShowFileTypes": "ファイル形式を表示", "CommonSort": "並べ替え", "CommonShowNames": "名称を表示", "CommonFavorite": "お気に入り", @@ -445,16 +461,17 @@ "MemoryManagerSoftwareTooltip": "アドレス変換にソフトウェアページテーブルを使用します. 非常に正確ですがパフォーマンスが大きく低下します.", "MemoryManagerHostTooltip": "ホストのアドレス空間にメモリを直接マップします.JITのコンパイルと実行速度が大きく向上します.", "MemoryManagerUnsafeTooltip": "メモリを直接マップしますが, アクセス前にゲストのアドレス空間内のアドレスをマスクしません. より高速になりますが, 安全性が犠牲になります. ゲストアプリケーションは Ryujinx のどこからでもメモリにアクセスできるので,このモードでは信頼できるプログラムだけを実行するようにしてください.", + "UseHypervisorTooltip": "JIT の代わりにハイパーバイザーを使用します. 利用可能な場合, パフォーマンスが大幅に向上しますが, 現在の状態では不安定になる可能性があります.", "DRamTooltip": "エミュレートされたシステムのメモリ容量を 4GiB から 6GiB に増加します.\n\n高解像度のテクスチャパックや 4K解像度の mod を使用する場合に有用です. パフォーマンスを改善するものではありません.\n\nよくわからない場合はオフのままにしてください.", "IgnoreMissingServicesTooltip": "未実装の Horizon OS サービスを無視します. 特定のゲームにおいて起動時のクラッシュを回避できる場合があります.\n\nよくわからない場合はオフのままにしてください.", "GraphicsBackendThreadingTooltip": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", "GalThreadingTooltip": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.", - "ShaderCacheToggleTooltip": "ディスクシェーダキャッシュをセーブし,次回以降の実行時遅延を軽減します.\n\nよくわからない場合はオンのままにしてください.", + "ShaderCacheToggleTooltip": "ディスクシェーダーキャッシュをセーブし,次回以降の実行時遅延を軽減します.\n\nよくわからない場合はオンのままにしてください.", "ResolutionScaleTooltip": "レンダリングに適用される解像度の倍率です", "ResolutionScaleEntryTooltip": "1.5 のような整数でない倍率を指定すると,問題が発生したりクラッシュしたりする場合があります.", "AnisotropyTooltip": "異方性フィルタリングのレベルです (ゲームが要求する値を使用する場合は「自動」を設定してください)", "AspectRatioTooltip": "レンダリングに適用されるアスペクト比です.", - "ShaderDumpPathTooltip": "グラフィックス シェーダダンプのパスです", + "ShaderDumpPathTooltip": "グラフィックス シェーダー ダンプのパスです", "FileLogTooltip": "コンソール出力されるログをディスク上のログファイルにセーブします. パフォーマンスには影響を与えません.", "StubLogTooltip": "stub ログメッセージをコンソールに出力します. パフォーマンスには影響を与えません.", "InfoLogTooltip": "info ログメッセージをコンソールに出力します. パフォーマンスには影響を与えません.", @@ -504,7 +521,7 @@ "IconSize": "アイコンサイズ", "IconSizeTooltip": "ゲームアイコンのサイズを変更します", "MenuBarOptionsShowConsole": "コンソールを表示", - "ShaderCachePurgeError": "シェーダキャッシュの破棄エラー {0}: {1}", + "ShaderCachePurgeError": "シェーダーキャッシュの破棄エラー {0}: {1}", "UserErrorNoKeys": "Keys がありません", "UserErrorNoFirmware": "ファームウェアがありません", "UserErrorFirmwareParsingFailed": "ファームウェアのパーズエラー", @@ -523,10 +540,13 @@ "RyujinxInfo": "Ryujinx - 情報", "RyujinxConfirm": "Ryujinx - 確認", "FileDialogAllTypes": "すべての種別", - "Never": "Never", + "Never": "決して", "SwkbdMinCharacters": "最低 {0} 文字必要です", "SwkbdMinRangeCharacters": "{0}-{1} 文字にしてください", "SoftwareKeyboard": "ソフトウェアキーボード", + "SoftwareKeyboardModeNumbersOnly": "数字のみ", + "SoftwareKeyboardModeAlphabet": "CJK文字以外のみ", + "SoftwareKeyboardModeASCII": "ASCII文字列のみ", "DialogControllerAppletMessagePlayerRange": "アプリケーションは {0} 名のプレイヤーを要求しています:\n\n種別: {1}\n\nプレイヤー: {2}\n\n{3}設定を開き各プレイヤーの入力設定を行ってから閉じるを押してください.", "DialogControllerAppletMessage": "アプリケーションは {0} 名のプレイヤーを要求しています:\n\n種別: {1}\n\nプレイヤー: {2}\n\n{3}設定を開き各プレイヤーの入力設定を行ってから閉じるを押してください.", "DialogControllerAppletDockModeSet": "ドッキングモードに設定されました. 携帯モードは無効になります.\n\n", @@ -543,7 +563,7 @@ "ApiError": "API エラー.", "LoadingHeading": "ロード中: {0}", "CompilingPPTC": "PTC をコンパイル中", - "CompilingShaders": "シェーダをコンパイル中", + "CompilingShaders": "シェーダーをコンパイル中", "AllKeyboards": "すべてのキーボード", "OpenFileDialogTitle": "開くファイルを選択", "OpenFolderDialogTitle": "展開されたゲームフォルダを選択", @@ -572,6 +592,7 @@ "DlcWindowTitle": "DLC 管理", "UpdateWindowTitle": "アップデート管理", "CheatWindowHeading": "利用可能なチート {0} [{1}]", + "BuildId": "ビルドID:", "DlcWindowHeading": "利用可能な DLC {0} [{1}]", "UserProfilesEditProfile": "編集", "Cancel": "キャンセル", @@ -587,7 +608,7 @@ "UserProfilesUserId": "ユーザID:", "SettingsTabGraphicsBackend": "グラフィックスバックエンド", "SettingsTabGraphicsBackendTooltip": "使用するグラフィックスバックエンドです", - "SettingsEnableTextureRecompression": "テクスチャの再圧縮を有効", + "SettingsEnableTextureRecompression": "テクスチャの再圧縮を有効にする", "SettingsEnableTextureRecompressionTooltip": "VRAMの使用量を削減するためテクスチャを圧縮します.\n\nGPUのVRAMが4GiB未満の場合は使用を推奨します.\n\nよくわからない場合はオフのままにしてください.", "SettingsTabGraphicsPreferredGpu": "優先使用するGPU", "SettingsTabGraphicsPreferredGpuTooltip": "Vulkanグラフィックスバックエンドで使用されるグラフィックスカードを選択します.\n\nOpenGLが使用するGPUには影響しません.\n\n不明な場合は, \"dGPU\" としてフラグが立っているGPUに設定します. ない場合はそのままにします.", @@ -597,8 +618,10 @@ "RyujinxUpdaterMessage": "Ryujinx を最新版にアップデートしますか?", "SettingsTabHotkeysVolumeUpHotkey": "音量を上げる:", "SettingsTabHotkeysVolumeDownHotkey": "音量を下げる:", - "SettingsEnableMacroHLE": "マクロの高レベルエミュレーション (HLE) を有効", + "SettingsEnableMacroHLE": "マクロの高レベルエミュレーション (HLE) を有効にする", "SettingsEnableMacroHLETooltip": "GPU マクロコードの高レベルエミュレーションです.\n\nパフォーマンスを向上させますが, 一部のゲームでグラフィックに不具合が発生する可能性があります.\n\nよくわからない場合はオンのままにしてください.", + "SettingsEnableColorSpacePassthrough": "色空間をパススルー", + "SettingsEnableColorSpacePassthroughTooltip": "Vulkan バックエンドに対して, 色空間を指定せずに色情報を渡します. 高色域ディスプレイを使用する場合, 正確ではないですがより鮮やかな色になる可能性があります.", "VolumeShort": "音量", "UserProfilesManageSaves": "セーブデータの管理", "DeleteUserSave": "このゲームのユーザセーブデータを削除しますか?", @@ -610,5 +633,24 @@ "Search": "検索", "UserProfilesRecoverLostAccounts": "アカウントの復旧", "Recover": "復旧", - "UserProfilesRecoverHeading": "以下のアカウントのセーブデータが見つかりました" -} + "UserProfilesRecoverHeading": "以下のアカウントのセーブデータが見つかりました", + "UserProfilesRecoverEmptyList": "復元するプロファイルはありません", + "GraphicsAATooltip": "ゲームのレンダリングにアンチエイリアスを適用します", + "GraphicsAALabel": "アンチエイリアス:", + "GraphicsScalingFilterLabel": "スケーリングフィルタ:", + "GraphicsScalingFilterTooltip": "フレームバッファスケーリングを有効にします", + "GraphicsScalingFilterLevelLabel": "レベル", + "GraphicsScalingFilterLevelTooltip": "スケーリングフィルタのレベルを設定", + "SmaaLow": "SMAA Low", + "SmaaMedium": "SMAA Medium", + "SmaaHigh": "SMAA High", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "ユーザを編集", + "UserEditorTitleCreate": "ユーザを作成", + "SettingsTabNetworkInterface": "ネットワークインタフェース:", + "NetworkInterfaceTooltip": "LAN機能に使用されるネットワークインタフェース", + "NetworkInterfaceDefault": "デフォルト", + "PackagingShaders": "シェーダーを構築中", + "AboutChangelogButton": "GitHub で更新履歴を表示", + "AboutChangelogButtonTooltipMessage": "クリックして, このバージョンの更新履歴をデフォルトのブラウザで開きます." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/ko_KR.json b/src/Ryujinx.Ava/Assets/Locales/ko_KR.json index adf7f61e3..cdc617222 100644 --- a/src/Ryujinx.Ava/Assets/Locales/ko_KR.json +++ b/src/Ryujinx.Ava/Assets/Locales/ko_KR.json @@ -3,10 +3,11 @@ "MenuBarFileOpenApplet": "애플릿 열기", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드에서 Mii 편집기 애플릿 열기", "SettingsTabInputDirectMouseAccess": "직접 마우스 접속", - "SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :", + "SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드:", "SettingsTabSystemMemoryManagerModeSoftware": "소프트웨어", "SettingsTabSystemMemoryManagerModeHost": "호스트 (빠름)", - "SettingsTabSystemMemoryManagerModeHostUnchecked": "호스트가 확인되지 않음 (가장 빠르나 안전하지 않음)", + "SettingsTabSystemMemoryManagerModeHostUnchecked": "호스트 확인 안함 (가장 빠르나 안전하지 않음)", + "SettingsTabSystemUseHypervisor": "하이퍼바이저 사용하기", "MenuBarFile": "_파일", "MenuBarFileOpenFromFile": "_파일에서 응용 프로그램 불러오기", "MenuBarFileOpenUnpacked": "_압축을 푼 게임 불러오기", @@ -18,15 +19,18 @@ "MenuBarOptionsStartGamesInFullscreen": "전체 화면 모드에서 게임 시작", "MenuBarOptionsStopEmulation": "에뮬레이션 중지", "MenuBarOptionsSettings": "_설정", - "MenuBarOptionsManageUserProfiles": "_사용자 프로파일 관리\n", + "MenuBarOptionsManageUserProfiles": "_사용자 프로파일 관리", "MenuBarActions": "_동작", - "MenuBarOptionsSimulateWakeUpMessage": "모닝콜 메세지 시뮬레이션\n", + "MenuBarOptionsSimulateWakeUpMessage": "깨우기 메시지 시뮬레이션", "MenuBarActionsScanAmiibo": "Amiibo 스캔", "MenuBarTools": "_도구", "MenuBarToolsInstallFirmware": "펌웨어 설치", "MenuBarFileToolsInstallFirmwareFromFile": "XCI 또는 ZIP에서 펌웨어 설치", - "MenuBarFileToolsInstallFirmwareFromDirectory": "디렉토리에서 펌웨어 설치", - "MenuBarHelp": "도움", + "MenuBarFileToolsInstallFirmwareFromDirectory": "디렉터리에서 펌웨어 설치", + "MenuBarToolsManageFileTypes": "파일 형식 관리", + "MenuBarToolsInstallFileTypes": "파일 형식 설치", + "MenuBarToolsUninstallFileTypes": "파일 형식 설치 제거", + "MenuBarHelp": "도움말", "MenuBarHelpCheckForUpdates": "업데이트 확인", "MenuBarHelpAbout": "정보", "MenuSearch": "검색...", @@ -40,49 +44,59 @@ "GameListHeaderFileExtension": "파일 확장자", "GameListHeaderFileSize": "파일 크기", "GameListHeaderPath": "경로", - "GameListContextMenuOpenUserSaveDirectory": "사용자 저장 디렉토리 열기\n", - "GameListContextMenuOpenUserSaveDirectoryToolTip": "응용 프로그램의 사용자 저장이 포함된 디렉토리 열기\n", - "GameListContextMenuOpenDeviceSaveDirectory": "사용자 장치 디렉토리 열기", - "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "응용 프로그램의 장치 저장이 포함된 디렉토리 열기\n", - "GameListContextMenuOpenBcatSaveDirectory": "사용자의 BCAT 디렉토리 열기\n", - "GameListContextMenuOpenBcatSaveDirectoryToolTip": "응용 프로그램의 BCAT 저장이 포함된 디렉토리 열기\n", - "GameListContextMenuManageTitleUpdates": "타이틀 업데이트 관리\n", + "GameListContextMenuOpenUserSaveDirectory": "사용자 저장 디렉터리 열기", + "GameListContextMenuOpenUserSaveDirectoryToolTip": "응용프로그램의 사용자 저장이 포함된 디렉터리 열기", + "GameListContextMenuOpenDeviceSaveDirectory": "사용자 장치 디렉터리 열기", + "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "응용프로그램의 장치 저장이 포함된 디렉터리 열기", + "GameListContextMenuOpenBcatSaveDirectory": "BCAT 저장 디렉터리 열기", + "GameListContextMenuOpenBcatSaveDirectoryToolTip": "응용프로그램의 BCAT 저장이 포함된 디렉터리 열기", + "GameListContextMenuManageTitleUpdates": "타이틀 업데이트 관리", "GameListContextMenuManageTitleUpdatesToolTip": "타이틀 업데이트 관리 창 열기", "GameListContextMenuManageDlc": "DLC 관리", "GameListContextMenuManageDlcToolTip": "DLC 관리 창 열기", - "GameListContextMenuOpenModsDirectory": "Mod 디렉토리 열기", - "GameListContextMenuOpenModsDirectoryToolTip": "응용 프로그램의 Mod들이 포함된 디렉터리 열기", + "GameListContextMenuOpenModsDirectory": "Mod 디렉터리 열기", + "GameListContextMenuOpenModsDirectoryToolTip": "응용프로그램의 Mod가 포함된 디렉터리 열기", "GameListContextMenuCacheManagement": "캐시 관리", "GameListContextMenuCacheManagementPurgePptc": "대기열 PPTC 재구성", - "GameListContextMenuCacheManagementPurgePptcToolTip": "다음 게임 시작 시 부팅 시 PPTC가 다시 빌드되도록 트리거\n", + "GameListContextMenuCacheManagementPurgePptcToolTip": "다음 게임 시작에서 부팅 시 PPTC가 다시 빌드하도록 트리거", "GameListContextMenuCacheManagementPurgeShaderCache": "셰이더 캐시 제거", - "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "응용 프로그램 셰이더 캐시 삭제\n", - "GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC 디렉토리 열기", - "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "응용 프로그램 PPTC 캐시가 포함된 디렉터리 열기\n", - "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "셰이더 캐시 디렉토리 열기", - "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "응용 프로그램 셰이더 캐시가 포함된 디렉터리 열기\n", + "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "응용프로그램 셰이더 캐시 삭제\n", + "GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC 디렉터리 열기", + "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "응용프로그램 PPTC 캐시가 포함된 디렉터리 열기", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "셰이더 캐시 디렉터리 열기", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "응용프로그램 셰이더 캐시가 포함된 디렉터리 열기", "GameListContextMenuExtractData": "데이터 추출", "GameListContextMenuExtractDataExeFS": "ExeFS", - "GameListContextMenuExtractDataExeFSToolTip": "애플리케이션의 현재 구성에서 ExeFS 추출 (업데이트 포함)", + "GameListContextMenuExtractDataExeFSToolTip": "응용프로그램의 현재 구성에서 ExeFS 추출 (업데이트 포함)", "GameListContextMenuExtractDataRomFS": "RomFS", - "GameListContextMenuExtractDataRomFSToolTip": "응용 프로그램의 현재 구성에서 RomFS 추출 (업데이트 포함)\n", + "GameListContextMenuExtractDataRomFSToolTip": "응용 프로그램의 현재 구성에서 RomFS 추출 (업데이트 포함)", "GameListContextMenuExtractDataLogo": "로고", - "GameListContextMenuExtractDataLogoToolTip": "응용 프로그램의 현재 구성에서 로고 섹션 추출 (업데이트 포함)\n", - "StatusBarGamesLoaded": "불러온 {0}/{1} 개의 게임", + "GameListContextMenuExtractDataLogoToolTip": "응용프로그램의 현재 구성에서 로고 섹션 추출 (업데이트 포함)", + "StatusBarGamesLoaded": "{0}/{1}개의 게임 불러옴", "StatusBarSystemVersion": "시스템 버전 : {0}", + "LinuxVmMaxMapCountDialogTitle": "감지된 메모리 매핑의 하한선", + "LinuxVmMaxMapCountDialogTextPrimary": "vm.max_map_count의 값을 {0}으로 늘리시겠습니까?", + "LinuxVmMaxMapCountDialogTextSecondary": "일부 게임은 현재 허용된 것보다 더 많은 메모리 매핑을 생성하려고 시도할 수 있습니다. 이 제한을 초과하는 즉시 Ryujinx에 문제가 발생합니다.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "예, 다음에 다시 시작할 때까지", + "LinuxVmMaxMapCountDialogButtonPersistent": "예, 영구적으로", + "LinuxVmMaxMapCountWarningTextPrimary": "메모리 매핑의 최대 용량이 권장 용량보다 적습니다.", + "LinuxVmMaxMapCountWarningTextSecondary": "vm.max_map_count({0})의 현재 값이 {1}보다 낮습니다. 일부 게임은 현재 허용된 것보다 더 많은 메모리 매핑을 생성하려고 시도할 수 있습니다. 이 제한을 초과하는 즉시 Ryujinx에 문제가 발생합니다.\n\n수동으로 제한을 늘리거나 Ryujinx의 도움을 받을 수 있는 pkexec을 설치하는 것이 좋습니다.", "Settings": "설정", "SettingsTabGeneral": "사용자 인터페이스", "SettingsTabGeneralGeneral": "일반", - "SettingsTabGeneralEnableDiscordRichPresence": "디스코드 활동 상태 활성화\n", - "SettingsTabGeneralCheckUpdatesOnLaunch": "실행 시 업데이트 확인\n", + "SettingsTabGeneralEnableDiscordRichPresence": "디스코드 활동 상태 활성화", + "SettingsTabGeneralCheckUpdatesOnLaunch": "시작 시, 업데이트 확인", "SettingsTabGeneralShowConfirmExitDialog": "\"종료 확인\" 대화 상자 표시", - "SettingsTabGeneralHideCursorOnIdle": "유휴 상태에서 커서 숨기기", - "SettingsTabGeneralGameDirectories": "게임 디렉토리", + "SettingsTabGeneralHideCursor": "마우스 커서 숨기기", + "SettingsTabGeneralHideCursorNever": "절대 안 함", + "SettingsTabGeneralHideCursorOnIdle": "유휴 상태", + "SettingsTabGeneralHideCursorAlways": "언제나", + "SettingsTabGeneralGameDirectories": "게임 디렉터리", "SettingsTabGeneralAdd": "추가", "SettingsTabGeneralRemove": "제거", "SettingsTabSystem": "시스템", "SettingsTabSystemCore": "코어", - "SettingsTabSystemSystemRegion": "시스템 지역 :", + "SettingsTabSystemSystemRegion": "시스템 지역:", "SettingsTabSystemSystemRegionJapan": "일본", "SettingsTabSystemSystemRegionUSA": "미국", "SettingsTabSystemSystemRegionEurope": "유럽", @@ -103,41 +117,41 @@ "SettingsTabSystemSystemLanguagePortuguese": "포르투갈어", "SettingsTabSystemSystemLanguageRussian": "러시아어", "SettingsTabSystemSystemLanguageTaiwanese": "대만어", - "SettingsTabSystemSystemLanguageBritishEnglish": "영어 (영국)", - "SettingsTabSystemSystemLanguageCanadianFrench": "프랑스어 (캐나다)", - "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "스페인어 (라틴 아메리카)", + "SettingsTabSystemSystemLanguageBritishEnglish": "영어(영국)", + "SettingsTabSystemSystemLanguageCanadianFrench": "프랑스어(캐나다)", + "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "스페인어(라틴 아메리카)", "SettingsTabSystemSystemLanguageSimplifiedChinese": "중국어 간체", "SettingsTabSystemSystemLanguageTraditionalChinese": "중국어 번체", - "SettingsTabSystemSystemTimeZone": "시스템 시간대 :", - "SettingsTabSystemSystemTime": "시스템 시간 :", + "SettingsTabSystemSystemTimeZone": "시스템 시간대:", + "SettingsTabSystemSystemTime": "시스템 시간:", "SettingsTabSystemEnableVsync": "수직 동기화", - "SettingsTabSystemEnablePptc": "PPTC (프로파일된 영구 번역 캐시) 활성화", - "SettingsTabSystemEnableFsIntegrityChecks": "FS 무결성 검사", - "SettingsTabSystemAudioBackend": "오디오 백엔드:", + "SettingsTabSystemEnablePptc": "PPTC(프로파일된 영구 번역 캐시)", + "SettingsTabSystemEnableFsIntegrityChecks": "파일 시스템 무결성 검사", + "SettingsTabSystemAudioBackend": "음향 후단부 :", "SettingsTabSystemAudioBackendDummy": "더미", "SettingsTabSystemAudioBackendOpenAL": "OpenAL", "SettingsTabSystemAudioBackendSoundIO": "사운드IO", "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "해킹", - "SettingsTabSystemHacksNote": " (불안정을 일으킬 수 있음)", - "SettingsTabSystemExpandDramSize": "대체 메모리 레이아웃 사용 (개발자)\n", + "SettingsTabSystemHacksNote": "불안정성을 유발할 수 있음", + "SettingsTabSystemExpandDramSize": "대체 메모리 레이아웃 사용(개발자)", "SettingsTabSystemIgnoreMissingServices": "누락된 서비스 무시", "SettingsTabGraphics": "그래픽", "SettingsTabGraphicsAPI": "그래픽 API", "SettingsTabGraphicsEnableShaderCache": "셰이더 캐시 활성화", - "SettingsTabGraphicsAnisotropicFiltering": "이방성 필터링:", + "SettingsTabGraphicsAnisotropicFiltering": "이방성 필터링 :", "SettingsTabGraphicsAnisotropicFilteringAuto": "자동", - "SettingsTabGraphicsAnisotropicFiltering2x": "2 배", - "SettingsTabGraphicsAnisotropicFiltering4x": "4 배", - "SettingsTabGraphicsAnisotropicFiltering8x": "8 배", - "SettingsTabGraphicsAnisotropicFiltering16x": "16 배", - "SettingsTabGraphicsResolutionScale": "해상도 스케일:", - "SettingsTabGraphicsResolutionScaleCustom": "사용자 지정 (권장하지 않음)", - "SettingsTabGraphicsResolutionScaleNative": "기본 (720p/1080p)", - "SettingsTabGraphicsResolutionScale2x": "2 배 (1440p/2160p)", - "SettingsTabGraphicsResolutionScale3x": "3 배 (2160p/3240p)", - "SettingsTabGraphicsResolutionScale4x": "4 배 (2880p/4320p)", - "SettingsTabGraphicsAspectRatio": "화면비:", + "SettingsTabGraphicsAnisotropicFiltering2x": "2배", + "SettingsTabGraphicsAnisotropicFiltering4x": "4배", + "SettingsTabGraphicsAnisotropicFiltering8x": "8배", + "SettingsTabGraphicsAnisotropicFiltering16x": "16배", + "SettingsTabGraphicsResolutionScale": "해상도 배율 :", + "SettingsTabGraphicsResolutionScaleCustom": "사용자 정의(권장하지 않음)", + "SettingsTabGraphicsResolutionScaleNative": "원본(720p/1080p)", + "SettingsTabGraphicsResolutionScale2x": "2배(1440p/2160p)", + "SettingsTabGraphicsResolutionScale3x": "3배(2160p/3240p)", + "SettingsTabGraphicsResolutionScale4x": "4배(2880p/4320p)", + "SettingsTabGraphicsAspectRatio": "종횡비 :", "SettingsTabGraphicsAspectRatio4x3": "4:3", "SettingsTabGraphicsAspectRatio16x9": "16:9", "SettingsTabGraphicsAspectRatio16x10": "16:10", @@ -145,10 +159,10 @@ "SettingsTabGraphicsAspectRatio32x9": "32:9", "SettingsTabGraphicsAspectRatioStretch": "창에 맞게 늘리기", "SettingsTabGraphicsDeveloperOptions": "개발자 옵션", - "SettingsTabGraphicsShaderDumpPath": "그래픽 쉐이더 덤프 경로:", - "SettingsTabLogging": "로깅", - "SettingsTabLoggingLogging": "로깅", - "SettingsTabLoggingEnableLoggingToFile": "파일에 로깅 활성화", + "SettingsTabGraphicsShaderDumpPath": "그래픽 셰이더 덤프 경로 :", + "SettingsTabLogging": "로그 기록", + "SettingsTabLoggingLogging": "로그 기록", + "SettingsTabLoggingEnableLoggingToFile": "파일에 로그 기록 활성화", "SettingsTabLoggingEnableStubLogs": "스텁 로그 활성화", "SettingsTabLoggingEnableInfoLogs": "정보 로그 활성화", "SettingsTabLoggingEnableWarningLogs": "경고 로그 활성화", @@ -156,12 +170,13 @@ "SettingsTabLoggingEnableTraceLogs": "추적 로그 활성화", "SettingsTabLoggingEnableGuestLogs": "게스트 로그 활성화", "SettingsTabLoggingEnableFsAccessLogs": "Fs 접속 로그 활성화", - "SettingsTabLoggingFsGlobalAccessLogMode": "Fs 글로벌 접속 로그 모드:", - "SettingsTabLoggingDeveloperOptions": "개발자 옵션 (경고 : 성능이 저하됨)", - "SettingsTabLoggingGraphicsBackendLogLevel": "그래픽 백엔드 로그 수준:", + "SettingsTabLoggingFsGlobalAccessLogMode": "Fs 전역 접속 로그 모드 :", + "SettingsTabLoggingDeveloperOptions": "개발자 옵션", + "SettingsTabLoggingDeveloperOptionsNote": "경고: 성능이 저하됨", + "SettingsTabLoggingGraphicsBackendLogLevel": "그래픽 후단부 로그 수준 :", "SettingsTabLoggingGraphicsBackendLogLevelNone": "없음", "SettingsTabLoggingGraphicsBackendLogLevelError": "오류", - "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "감속", + "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "느려짐", "SettingsTabLoggingGraphicsBackendLogLevelAll": "모두", "SettingsTabLoggingEnableDebugLogs": "디버그 로그 활성화", "SettingsTabInput": "입력", @@ -181,111 +196,104 @@ "ControllerSettingsPlayer6": "플레이어 6", "ControllerSettingsPlayer7": "플레이어 7", "ControllerSettingsPlayer8": "플레이어 8", - "ControllerSettingsHandheld": "휴대용", + "ControllerSettingsHandheld": "휴대 모드", "ControllerSettingsInputDevice": "입력 장치", "ControllerSettingsRefresh": "새로 고침", "ControllerSettingsDeviceDisabled": "비활성화됨", "ControllerSettingsControllerType": "컨트롤러 유형", - "ControllerSettingsControllerTypeHandheld": "휴대용", + "ControllerSettingsControllerTypeHandheld": "휴대 모드", "ControllerSettingsControllerTypeProController": "프로 컨트롤러", "ControllerSettingsControllerTypeJoyConPair": "조이콘 페어링", - "ControllerSettingsControllerTypeJoyConLeft": "왼쪽 조이콘", - "ControllerSettingsControllerTypeJoyConRight": "오른쪽 조이콘", - "ControllerSettingsProfile": "프로파일", + "ControllerSettingsControllerTypeJoyConLeft": "좌측 조이콘", + "ControllerSettingsControllerTypeJoyConRight": "우측 조이콘", + "ControllerSettingsProfile": "프로필", "ControllerSettingsProfileDefault": "기본", "ControllerSettingsLoad": "불러오기", "ControllerSettingsAdd": "추가", "ControllerSettingsRemove": "제거", "ControllerSettingsButtons": "버튼", - "ControllerSettingsButtonA": "A 버튼", - "ControllerSettingsButtonB": "B 버튼", - "ControllerSettingsButtonX": "X 버튼", - "ControllerSettingsButtonY": "Y 버튼", - "ControllerSettingsButtonPlus": "+ 버튼", - "ControllerSettingsButtonMinus": "- 버튼", + "ControllerSettingsButtonA": "A", + "ControllerSettingsButtonB": "B", + "ControllerSettingsButtonX": "X", + "ControllerSettingsButtonY": "Y", + "ControllerSettingsButtonPlus": "+", + "ControllerSettingsButtonMinus": "-", "ControllerSettingsDPad": "방향 패드", - "ControllerSettingsDPadUp": "위쪽", - "ControllerSettingsDPadDown": "아래쪽", - "ControllerSettingsDPadLeft": "왼쪽", - "ControllerSettingsDPadRight": "오른쪽", - "ControllerSettingsLStick": "왼쪽 스틱", - "ControllerSettingsLStickButton": "버튼", - "ControllerSettingsLStickUp": "위쪽", - "ControllerSettingsLStickDown": "아래쪽", - "ControllerSettingsLStickLeft": "왼쪽", - "ControllerSettingsLStickRight": "오른쪽", - "ControllerSettingsLStickStick": "스틱", - "ControllerSettingsLStickInvertXAxis": "스틱 X 축 반전", - "ControllerSettingsLStickInvertYAxis": "스틱 Y 축 반전", - "ControllerSettingsLStickDeadzone": "데드존:", - "ControllerSettingsRStick": "오른쪽 스틱", - "ControllerSettingsRStickButton": "버튼", - "ControllerSettingsRStickUp": "위쪽", - "ControllerSettingsRStickDown": "아래쪽", - "ControllerSettingsRStickLeft": "왼쪽", - "ControllerSettingsRStickRight": "오른쪽", - "ControllerSettingsRStickStick": "스틱", - "ControllerSettingsRStickInvertXAxis": "스틱 X 축 반전", - "ControllerSettingsRStickInvertYAxis": "스틱 Y 축 반전", - "ControllerSettingsRStickDeadzone": "데드존:", - "ControllerSettingsTriggersLeft": "왼쪽 트리거", - "ControllerSettingsTriggersRight": "오른쪽 트리거", - "ControllerSettingsTriggersButtonsLeft": "왼쪽 트리거 버튼", - "ControllerSettingsTriggersButtonsRight": "오른쪽 트리거 버튼", + "ControllerSettingsDPadUp": "↑", + "ControllerSettingsDPadDown": "↓", + "ControllerSettingsDPadLeft": "←", + "ControllerSettingsDPadRight": "→", + "ControllerSettingsStickButton": "버튼", + "ControllerSettingsStickUp": "↑", + "ControllerSettingsStickDown": "↓", + "ControllerSettingsStickLeft": "←", + "ControllerSettingsStickRight": "→", + "ControllerSettingsStickStick": "스틱", + "ControllerSettingsStickInvertXAxis": "스틱 X 축 반전", + "ControllerSettingsStickInvertYAxis": "스틱 Y 축 반전", + "ControllerSettingsStickDeadzone": "사각지대 :", + "ControllerSettingsLStick": "좌측 스틱", + "ControllerSettingsRStick": "우측 스틱", + "ControllerSettingsTriggersLeft": "좌측 트리거", + "ControllerSettingsTriggersRight": "우측 트리거", + "ControllerSettingsTriggersButtonsLeft": "좌측 트리거 버튼", + "ControllerSettingsTriggersButtonsRight": "우측 트리거 버튼", "ControllerSettingsTriggers": "트리거 버튼", - "ControllerSettingsTriggerL": "L 버튼", - "ControllerSettingsTriggerR": "R 버튼", - "ControllerSettingsTriggerZL": "ZL 버튼", - "ControllerSettingsTriggerZR": "ZR 버튼", - "ControllerSettingsLeftSL": "SL 버튼", - "ControllerSettingsLeftSR": "SR 버튼", - "ControllerSettingsRightSL": "SL 버튼", - "ControllerSettingsRightSR": "SR 버튼", - "ControllerSettingsExtraButtonsLeft": "왼쪽 버튼", - "ControllerSettingsExtraButtonsRight": "오른쪽 버튼", + "ControllerSettingsTriggerL": "L", + "ControllerSettingsTriggerR": "R", + "ControllerSettingsTriggerZL": "ZL", + "ControllerSettingsTriggerZR": "ZR", + "ControllerSettingsLeftSL": "SL", + "ControllerSettingsLeftSR": "SR", + "ControllerSettingsRightSL": "SL", + "ControllerSettingsRightSR": "SR", + "ControllerSettingsExtraButtonsLeft": "좌측 버튼", + "ControllerSettingsExtraButtonsRight": "우측 버튼", "ControllerSettingsMisc": "기타", "ControllerSettingsTriggerThreshold": "트리거 임계값 :", "ControllerSettingsMotion": "동작", "ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook 호환 모션 사용", - "ControllerSettingsMotionControllerSlot": "컨트롤러 슬롯:", + "ControllerSettingsMotionControllerSlot": "컨트롤러 슬롯 :", "ControllerSettingsMotionMirrorInput": "미러 입력", - "ControllerSettingsMotionRightJoyConSlot": "오른쪽 조이콘 슬롯 :", - "ControllerSettingsMotionServerHost": "서버 호스트:", - "ControllerSettingsMotionGyroSensitivity": "자이로 감도:", - "ControllerSettingsMotionGyroDeadzone": "자이로 데드존:", + "ControllerSettingsMotionRightJoyConSlot": "우측 조이콘 슬롯 :", + "ControllerSettingsMotionServerHost": "서버 호스트 :", + "ControllerSettingsMotionGyroSensitivity": "자이로 감도 :", + "ControllerSettingsMotionGyroDeadzone": "자이로 사각지대 :", "ControllerSettingsSave": "저장", "ControllerSettingsClose": "닫기", - "UserProfilesSelectedUserProfile": "선택한 사용자 프로파일:", - "UserProfilesSaveProfileName": "프로파일 이름 저장", - "UserProfilesChangeProfileImage": "프로파일 이미지 변경", - "UserProfilesAvailableUserProfiles": "사용 가능한 사용자 프로파일:", - "UserProfilesAddNewProfile": "프로파일 생성", - "UserProfilesDeleteSelectedProfile": "선택한 프로파일 삭제", + "UserProfilesSelectedUserProfile": "선택한 사용자 프로필 :", + "UserProfilesSaveProfileName": "프로필 이름 저장", + "UserProfilesChangeProfileImage": "프로필 이미지 변경", + "UserProfilesAvailableUserProfiles": "사용 가능한 사용자 프로필 :", + "UserProfilesAddNewProfile": "프로필 생성", + "UserProfilesDelete": "삭제", "UserProfilesClose": "닫기", - "ProfileImageSelectionTitle": "프로파일 이미지 선택", - "ProfileImageSelectionHeader": "프로파일 이미지 선택", - "ProfileImageSelectionNote": "사용자 지정 프로파일 이미지를 가져오거나 시스템 펌웨어에서 아바타를 선택할 수 있음\n", + "ProfileNameSelectionWatermark": "닉네임을 입력하세요", + "ProfileImageSelectionTitle": "프로필 이미지 선택", + "ProfileImageSelectionHeader": "프로필 이미지 선택", + "ProfileImageSelectionNote": "사용자 지정 프로필 이미지를 가져오거나 시스템 펌웨어에서 아바타 선택 가능", "ProfileImageSelectionImportImage": "이미지 파일 가져오기", "ProfileImageSelectionSelectAvatar": "펌웨어 아바타 선택", "InputDialogTitle": "입력 대화상자", "InputDialogOk": "확인", "InputDialogCancel": "취소", - "InputDialogAddNewProfileTitle": "프로파일 이름 선택", - "InputDialogAddNewProfileHeader": "프로파일 이름 입력", - "InputDialogAddNewProfileSubtext": "(최대 길이: {0})\n", + "InputDialogAddNewProfileTitle": "프로필 이름 선택", + "InputDialogAddNewProfileHeader": "프로필 이름 입력", + "InputDialogAddNewProfileSubtext": "(최대 길이 : {0})", "AvatarChoose": "선택", "AvatarSetBackgroundColor": "배경색 설정", "AvatarClose": "닫기", - "ControllerSettingsLoadProfileToolTip": "프로파일 불러오기", - "ControllerSettingsAddProfileToolTip": "프로파일 추가", - "ControllerSettingsRemoveProfileToolTip": "프로파일 제거", - "ControllerSettingsSaveProfileToolTip": "프로파일 저장", + "ControllerSettingsLoadProfileToolTip": "프로필 불러오기", + "ControllerSettingsAddProfileToolTip": "프로필 추가", + "ControllerSettingsRemoveProfileToolTip": "프로필 제거", + "ControllerSettingsSaveProfileToolTip": "프로필 저장", "MenuBarFileToolsTakeScreenshot": "스크린 샷 찍기", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "UI 숨기기", + "GameListContextMenuRunApplication": "응용프로그램 실행", "GameListContextMenuToggleFavorite": "즐겨찾기 전환", - "GameListContextMenuToggleFavoriteToolTip": "게임 즐겨찾기 상태 전환\n", + "GameListContextMenuToggleFavoriteToolTip": "게임 즐겨찾기 상태 전환", "SettingsTabGeneralTheme": "테마", - "SettingsTabGeneralThemeCustomTheme": "사용자 정의 테마 경로", + "SettingsTabGeneralThemeCustomTheme": "커스텀 테마 경로", "SettingsTabGeneralThemeBaseStyle": "기본 스타일", "SettingsTabGeneralThemeBaseStyleDark": "어두움", "SettingsTabGeneralThemeBaseStyleLight": "밝음", @@ -295,8 +303,8 @@ "ControllerSettingsRumble": "진동", "ControllerSettingsRumbleStrongMultiplier": "강력한 진동 증폭기", "ControllerSettingsRumbleWeakMultiplier": "약한 진동 증폭기", - "DialogMessageSaveNotAvailableMessage": "{0} [{1:x16}]에 대한 저장 데이터가 없음\n", - "DialogMessageSaveNotAvailableCreateSaveMessage": "이 게임에 대한 저장 데이터를 생성하겠습니까?\n", + "DialogMessageSaveNotAvailableMessage": "{0} [{1:x16}]에 대한 저장 데이터가 없음", + "DialogMessageSaveNotAvailableCreateSaveMessage": "이 게임에 대한 저장 데이터를 생성하겠습니까?", "DialogConfirmationTitle": "Ryujinx - 확인", "DialogUpdaterTitle": "Ryujinx - 업데이터", "DialogErrorTitle": "Ryujinx - 오류", @@ -305,60 +313,64 @@ "DialogErrorMessage": "Ryujinx 오류 발생", "DialogExitMessage": "Ryujinx를 종료하겠습니까?", "DialogExitSubMessage": "저장하지 않은 모든 데이터는 손실됩니다!", - "DialogMessageCreateSaveErrorMessage": "지정된 저장 데이터를 작성하는 중에 오류 발생: {0}\n", - "DialogMessageFindSaveErrorMessage": "지정된 저장 데이터를 찾는 중에 오류 발생: {0}\n", + "DialogMessageCreateSaveErrorMessage": "지정된 저장 데이터를 작성하는 중에 오류 발생: {0}", + "DialogMessageFindSaveErrorMessage": "지정된 저장 데이터를 찾는 중에 오류 발생: {0}", "FolderDialogExtractTitle": "추출할 폴더 선택", - "DialogNcaExtractionMessage": "{1}에서 {0} 섹션을 추출하는 중...\n", + "DialogNcaExtractionMessage": "{1}에서 {0} 섹션을 추출하는 중...", "DialogNcaExtractionTitle": "Ryujinx - NCA 섹션 추출기", - "DialogNcaExtractionMainNcaNotFoundErrorMessage": "추출 실패하였습니다. 선택한 파일에 기본 NCA가 없습니다.\n", - "DialogNcaExtractionCheckLogErrorMessage": "추출 실패하였습니다. 자세한 내용은 로그 파일을 읽으세요.\n", + "DialogNcaExtractionMainNcaNotFoundErrorMessage": "추출 실패하였습니다. 선택한 파일에 기본 NCA가 없습니다.", + "DialogNcaExtractionCheckLogErrorMessage": "추출 실패하였습니다. 자세한 내용은 로그 파일을 읽으세요.", "DialogNcaExtractionSuccessMessage": "추출이 성공적으로 완료되었습니다.", "DialogUpdaterConvertFailedMessage": "현재 Ryujinx 버전을 변환하지 못했습니다.", "DialogUpdaterCancelUpdateMessage": "업데이트 취소 중 입니다!", "DialogUpdaterAlreadyOnLatestVersionMessage": "이미 최신 버전의 Ryujinx를 사용하고 있습니다!", "DialogUpdaterFailedToGetVersionMessage": "GitHub 릴리스에서 릴리스 정보를 가져오는 중에 오류가 발생했습니다. 이는 GitHub Actions에서 새 릴리스를 컴파일하는 경우 발생할 수 있습니다. 몇 분 후에 다시 시도하세요.", - "DialogUpdaterConvertFailedGithubMessage": "Github 개정에서 받은 Ryujinx 버전을 변환하지 못했습니다.\n", - "DialogUpdaterDownloadingMessage": "업데이트 다운로드 중...\n", - "DialogUpdaterExtractionMessage": "업데이트 추출 중...\n", - "DialogUpdaterRenamingMessage": "업데이트 이름 바꾸는 중...\n", - "DialogUpdaterAddingFilesMessage": "새 업데이트 추가 중...\n", - "DialogUpdaterCompleteMessage": "업데이트 완료하였습니다!\n", + "DialogUpdaterConvertFailedGithubMessage": "Github 개정에서 받은 Ryujinx 버전을 변환하지 못했습니다.", + "DialogUpdaterDownloadingMessage": "업데이트 다운로드 중...", + "DialogUpdaterExtractionMessage": "업데이트 추출 중...", + "DialogUpdaterRenamingMessage": "업데이트 이름 바꾸는 중...", + "DialogUpdaterAddingFilesMessage": "새 업데이트 추가 중...", + "DialogUpdaterCompleteMessage": "업데이트를 완료했습니다!", "DialogUpdaterRestartMessage": "지금 Ryujinx를 다시 시작하겠습니까?", "DialogUpdaterArchNotSupportedMessage": "지원되는 시스템 아키텍처를 실행하고 있지 않습니다!", - "DialogUpdaterArchNotSupportedSubMessage": "(x64 시스템만 지원됩니다!)\n", + "DialogUpdaterArchNotSupportedSubMessage": "(64비트 시스템만 지원됩니다!)", "DialogUpdaterNoInternetMessage": "인터넷에 연결되어 있지 않습니다!", "DialogUpdaterNoInternetSubMessage": "인터넷 연결이 작동하는지 확인하세요!", "DialogUpdaterDirtyBuildMessage": "Ryujinx의 나쁜 빌드는 업데이트할 수 없습니다!\n", "DialogUpdaterDirtyBuildSubMessage": "지원되는 버전을 찾고 있다면 https://ryujinx.org/에서 Ryujinx를 다운로드하세요.", "DialogRestartRequiredMessage": "재시작 필요", "DialogThemeRestartMessage": "테마가 저장되었습니다. 테마를 적용하려면 다시 시작해야 합니다.", - "DialogThemeRestartSubMessage": "다시 시작하겠습니까?\n", + "DialogThemeRestartSubMessage": "다시 시작하겠습니까?", "DialogFirmwareInstallEmbeddedMessage": "이 게임에 내장된 펌웨어를 설치하겠습니까? (펌웨어 {0})", "DialogFirmwareInstallEmbeddedSuccessMessage": "설치된 펌웨어가 없지만 Ryujinx가 제공된 게임에서 펌웨어 {0}을(를) 설치할 수 있었습니다.\\n이제 에뮬레이터가 시작됩니다.", "DialogFirmwareNoFirmwareInstalledMessage": "설치된 펌웨어 없음", "DialogFirmwareInstalledMessage": "펌웨어 {0}이(가) 설치됨", + "DialogInstallFileTypesSuccessMessage": "파일 형식을 성공적으로 설치했습니다!", + "DialogInstallFileTypesErrorMessage": "파일 형식을 설치하지 못했습니다.", + "DialogUninstallFileTypesSuccessMessage": "파일 형식을 성공적으로 제거했습니다!", + "DialogUninstallFileTypesErrorMessage": "파일 형식을 제거하지 못했습니다.", "DialogOpenSettingsWindowLabel": "설정 창 열기", "DialogControllerAppletTitle": "컨트롤러 애플릿", - "DialogMessageDialogErrorExceptionMessage": "메시지 대화상자를 표시하는 동안 오류 발생: {0}\n", - "DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드를 표시하는 동안 오류 발생: {0}", - "DialogErrorAppletErrorExceptionMessage": "오류에플릿 대화상자를 표시하는 동안 오류 발생: {0}", + "DialogMessageDialogErrorExceptionMessage": "메시지 대화상자를 표시하는 동안 오류 발생 : {0}", + "DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드를 표시하는 동안 오류 발생 : {0}", + "DialogErrorAppletErrorExceptionMessage": "오류에플릿 대화상자를 표시하는 동안 오류 발생 : {0}", "DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogInfoMessage": "\n이 오류를 수정하는 방법에 대한 자세한 내용은 설정 가이드를 따르세요.", "DialogUserErrorDialogTitle": "Ryuijnx 오류 ({0})", "DialogAmiiboApiTitle": "Amiibo API", "DialogAmiiboApiFailFetchMessage": "API에서 정보를 가져오는 동안 오류가 발생했습니다.", - "DialogAmiiboApiConnectErrorMessage": "Amiibo API 서버에 연결할 수 없습니다. 서비스가 다운되었거나 인터넷 연결이 오프라인인지 확인해야 할 수 있습니다.", - "DialogProfileInvalidProfileErrorMessage": "{0} 프로파일은 현재 입력 구성 시스템과 호환되지 않습니다.", - "DialogProfileDefaultProfileOverwriteErrorMessage": "기본 프로파일을 덮어쓸 수 없음", - "DialogProfileDeleteProfileTitle": "프로파일 삭제", + "DialogAmiiboApiConnectErrorMessage": "Amiibo API 서버에 연결할 수 없습니다. 서비스가 다운되었거나 인터넷 연결이 온라인 상태인지 확인해야 할 수 있습니다.", + "DialogProfileInvalidProfileErrorMessage": "{0} 프로필은 현재 입력 구성 시스템과 호환되지 않습니다.", + "DialogProfileDefaultProfileOverwriteErrorMessage": "기본 프로필을 덮어쓸 수 없음", + "DialogProfileDeleteProfileTitle": "프로필 삭제", "DialogProfileDeleteProfileMessage": "이 작업은 되돌릴 수 없습니다. 계속하겠습니까?", "DialogWarning": "경고", - "DialogPPTCDeletionMessage": "다음에 부팅할 때 PPTC 재구축을 대기시키려고 합니다:\n\n{0}\n\n계속하겠습니까?", - "DialogPPTCDeletionErrorMessage": "{0}에서 PPTC 캐시 삭제 오류: {1}", - "DialogShaderDeletionMessage": "다음에 대한 셰이더 캐시를 삭제하려고 합니다:\n\n{0}\n\n계속하겠습니까?", - "DialogShaderDeletionErrorMessage": "{0}에서 셰이더 캐시 제거 오류: {1}", + "DialogPPTCDeletionMessage": "다음 부팅 시, PPTC 재구축을 대기열에 추가 :\n\n{0}\n\n계속하겠습니까?", + "DialogPPTCDeletionErrorMessage": "{0}에서 PPTC 캐시 삭제 오류 : {1}", + "DialogShaderDeletionMessage": "다음에 대한 셰이더 캐시 삭제 :\n\n{0}\n\n계속하겠습니까?", + "DialogShaderDeletionErrorMessage": "{0}에서 셰이더 캐시 제거 오류 : {1}", "DialogRyujinxErrorMessage": "Ryujinx에 오류 발생", - "DialogInvalidTitleIdErrorMessage": "UI 오류: 선택한 게임에 유효한 타이틀 ID가 없음", + "DialogInvalidTitleIdErrorMessage": "UI 오류 : 선택한 게임에 유효한 타이틀 ID가 없음", "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "{0}에서 유효한 시스템 펌웨어를 찾을 수 없습니다.", "DialogFirmwareInstallerFirmwareInstallTitle": "펌웨어 {0} 설치", "DialogFirmwareInstallerFirmwareInstallMessage": "시스템 버전 {0}이(가) 설치됩니다.", @@ -368,39 +380,42 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "시스템 버전 {0}이(가) 성공적으로 설치되었습니다.", "DialogUserProfileDeletionWarningMessage": "선택한 프로파일이 삭제되면 사용 가능한 다른 프로파일이 없음", "DialogUserProfileDeletionConfirmMessage": "선택한 프로파일을 삭제하겠습니까?", + "DialogUserProfileUnsavedChangesTitle": "경고 - 변경사항 저장되지 않음", + "DialogUserProfileUnsavedChangesMessage": "저장되지 않은 사용자 프로파일을 수정했습니다.", + "DialogUserProfileUnsavedChangesSubMessage": "변경사항을 저장하지 않으시겠습니까?", "DialogControllerSettingsModifiedConfirmMessage": "현재 컨트롤러 설정이 업데이트되었습니다.", "DialogControllerSettingsModifiedConfirmSubMessage": "저장하겠습니까?", - "DialogLoadNcaErrorMessage": "{0}입니다. 오류 발생 파일: {1}", + "DialogLoadNcaErrorMessage": "{0}. 오류 발생 파일 : {1}", "DialogDlcNoDlcErrorMessage": "지정된 파일에 선택한 타이틀에 대한 DLC가 포함되어 있지 않습니다!", - "DialogPerformanceCheckLoggingEnabledMessage": "개발자만 사용하도록 설계된 추적 로깅이 활성화되어 있습니다.", - "DialogPerformanceCheckLoggingEnabledConfirmMessage": "최적의 성능을 위해 추적 로깅을 비활성화하는 것이 좋습니다. 지금 추적 로깅을 비활성화하겠습니까?", + "DialogPerformanceCheckLoggingEnabledMessage": "개발자만 사용하도록 설계된 추적 로그 기록이 활성화되어 있습니다.", + "DialogPerformanceCheckLoggingEnabledConfirmMessage": "최적의 성능을 위해 추적 로그 생성을 비활성화하는 것이 좋습니다. 지금 추적 로그 기록을 비활성화하겠습니까?", "DialogPerformanceCheckShaderDumpEnabledMessage": "개발자만 사용하도록 설계된 셰이더 덤프를 활성화했습니다.", "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "최적의 성능을 위해 세이더 덤핑을 비활성화하는 것이 좋습니다. 지금 세이더 덤핑을 비활성화하겠습니까?", - "DialogLoadAppGameAlreadyLoadedMessage": "게임을 이미 불러 왔습니다.", + "DialogLoadAppGameAlreadyLoadedMessage": "이미 게임 불러옴", "DialogLoadAppGameAlreadyLoadedSubMessage": "다른 게임을 시작하기 전에 에뮬레이션을 중지하거나 에뮬레이터를 닫으세요.", "DialogUpdateAddUpdateErrorMessage": "지정된 파일에 선택한 제목에 대한 업데이트가 포함되어 있지 않습니다!", - "DialogSettingsBackendThreadingWarningTitle": "경고 - 백엔드 스레딩", - "DialogSettingsBackendThreadingWarningMessage": "변경 사항을 완전히 적용하려면 이 옵션을 변경한 후 Ryujinx를 다시 시작해야 합니다. 플랫폼에 따라 Ryujinx를 사용할 때 드라이버 자체의 멀티스레딩을 수동으로 비활성화해야 할 수도 있습니다.", + "DialogSettingsBackendThreadingWarningTitle": "경고 - 후단부 스레딩", + "DialogSettingsBackendThreadingWarningMessage": "변경 사항을 완전히 적용하려면 이 옵션을 변경한 후, Ryujinx를 다시 시작해야 합니다. 플랫폼에 따라 Ryujinx를 사용할 때 드라이버 자체의 멀티스레딩을 수동으로 비활성화해야 할 수도 있습니다.", "SettingsTabGraphicsFeaturesOptions": "기능", - "SettingsTabGraphicsBackendMultithreading": "그래픽 백엔드 멀티스레딩:", + "SettingsTabGraphicsBackendMultithreading": "그래픽 후단부 멀티스레딩 :", "CommonAuto": "자동", "CommonOff": "끔", "CommonOn": "켬", - "InputDialogYes": "네", + "InputDialogYes": "예", "InputDialogNo": "아니오", "DialogProfileInvalidProfileNameErrorMessage": "파일 이름에 잘못된 문자가 포함되어 있습니다. 다시 시도하세요.", "MenuBarOptionsPauseEmulation": "일시 정지", "MenuBarOptionsResumeEmulation": "다시 시작", "AboutUrlTooltipMessage": "기본 브라우저에서 Ryujinx 웹사이트를 열려면 클릭하세요.", - "AboutDisclaimerMessage": "Ryujinx는 닌텐도™,\n또는 그 파트너와 제휴하지 않습니다.", + "AboutDisclaimerMessage": "Ryujinx는 닌텐도™,\n또는 그 파트너와 제휴한 바가 없습니다.", "AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com)는\nAmiibo 에뮬레이션에 사용됩니다.", "AboutPatreonUrlTooltipMessage": "기본 브라우저에서 Ryujinx Patreon 페이지를 열려면 클릭하세요.", "AboutGithubUrlTooltipMessage": "기본 브라우저에서 Ryujinx GitHub 페이지를 열려면 클릭하세요.", "AboutDiscordUrlTooltipMessage": "기본 브라우저에서 Ryujinx 디스코드 서버에 대한 초대를 열려면 클릭하세요.", "AboutTwitterUrlTooltipMessage": "기본 브라우저에서 Ryujinx 트위터 페이지를 열려면 클릭하세요.", - "AboutRyujinxAboutTitle": "정보:", - "AboutRyujinxAboutContent": "Ryujinx는 닌텐도 스위치™용 에뮬레이터입니다.\nPatreon에서 지원해 주세요.\n모든 최신 뉴스는 트위터 또는 디스코드에서 확인하세요.\n기여에 관심이 있는 개발자는 GitHub 또는 디스코드에서 자세한 내용을 확인할 수 있습니다", - "AboutRyujinxMaintainersTitle": "유지 관리:", + "AboutRyujinxAboutTitle": "정보 :", + "AboutRyujinxAboutContent": "Ryujinx는 닌텐도 스위치™용 에뮬레이터입니다.\nPatreon에서 지원해 주세요.\n트위터나 디스코드에서 최신 소식을 받아보세요.\n기여에 참여하고자 하는 개발자는 GitHub 또는 디스코드에서 자세한 내용을 확인할 수 있습니다.", + "AboutRyujinxMaintainersTitle": "유지 관리 :", "AboutRyujinxMaintainersContentTooltipMessage": "기본 브라우저에서 기여자 페이지를 열려면 클릭하세요.", "AboutRyujinxSupprtersTitle": "Patreon에서 후원:", "AmiiboSeriesLabel": "Amiibo 시리즈", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "모두 활성화", "DlcManagerDisableAllButton": "모두 비활성화", "MenuBarOptionsChangeLanguage": "언어 변경", + "MenuBarShowFileTypes": "파일 유형 표시", "CommonSort": "정렬", "CommonShowNames": "이름 표시", "CommonFavorite": "즐겨찾기", @@ -424,13 +440,13 @@ "SettingsTabGraphicsFeatures": "기능ㆍ개선 사항", "ErrorWindowTitle": "오류 창", "ToggleDiscordTooltip": "\"현재 재생 중인\" 디스코드 활동에 Ryujinx를 표시할지 여부 선택", - "AddGameDirBoxTooltip": "목록에 추가할 게임 디렉토리 입력", - "AddGameDirTooltip": "목록에 게임 디렉토리 추가", - "RemoveGameDirTooltip": "선택한 게임 디렉토리 제거", + "AddGameDirBoxTooltip": "목록에 추가할 게임 디렉터리 입력", + "AddGameDirTooltip": "목록에 게임 디렉터리 추가", + "RemoveGameDirTooltip": "선택한 게임 디렉터리 제거", "CustomThemeCheckTooltip": "GUI에 사용자 지정 Avalonia 테마를 사용하여 에뮬레이터 메뉴의 모양 변경", "CustomThemePathTooltip": "사용자 정의 GUI 테마 경로", "CustomThemeBrowseTooltip": "사용자 정의 GUI 테마 찾아보기", - "DockModeToggleTooltip": "도킹 모드에서는 에뮬레이트된 시스템이 도킹된 닌텐도 스위치처럼 작동합니다. 이것은 대부분의 게임에서 그래픽 충실도를 향상시킵니다. 반대로 이 기능을 비활성화하면 에뮬레이트된 시스템이 휴대용 닌텐도 스위치처럼 작동하여 그래픽 품질이 저하됩니다.\n\n도킹 모드를 사용하려는 경우 플레이어 1 컨트롤을 구성하세요. 휴대용 모드를 사용하려는 경우 휴대용 컨트롤을 구성합니다.\n\n확실하지 않으면 켜 두세요.", + "DockModeToggleTooltip": "독 모드에서는 에뮬레이트된 시스템이 도킹된 닌텐도 스위치처럼 작동합니다. 이것은 대부분의 게임에서 그래픽 품질을 향상시킵니다. 반대로 이 기능을 비활성화하면 에뮬레이트된 시스템이 휴대용 닌텐도 스위치처럼 작동하여 그래픽 품질이 저하됩니다.\n\n독 모드를 사용하려는 경우 플레이어 1의 컨트롤을 구성하세요. 휴대 모드를 사용하려는 경우 휴대용 컨트롤을 구성하세요.\n\n확실하지 않으면 켜 두세요.", "DirectKeyboardTooltip": "직접 키보드 접속 (HID) 지원합니다. 텍스트 입력 장치로 키보드에 대한 게임 접속을 제공합니다.", "DirectMouseTooltip": "직접 마우스 접속 (HID) 지원합니다. 포인팅 장치로 마우스에 대한 게임 접속을 제공합니다.", "RegionTooltip": "시스템 지역 변경", @@ -441,10 +457,11 @@ "PptcToggleTooltip": "게임이 불러올 때마다 번역할 필요가 없도록 번역된 JIT 기능을 저장합니다.\n\n게임을 처음 부팅한 후 끊김 현상을 줄이고 부팅 시간을 크게 단축합니다.\n\n확실하지 않으면 켜 두세요.", "FsIntegrityToggleTooltip": "게임을 부팅할 때 손상된 파일을 확인하고 손상된 파일이 감지되면 로그에 해시 오류를 표시합니다.\n\n성능에 영향을 미치지 않으며 문제 해결에 도움이 됩니다.\n\n확실하지 않으면 켜 두세요.", "AudioBackendTooltip": "오디오를 렌더링하는 데 사용되는 백엔드를 변경합니다.\n\nSDL2가 선호되는 반면 OpenAL 및 사운드IO는 폴백으로 사용됩니다. 더미는 소리가 나지 않습니다.\n\n확실하지 않으면 SDL2로 설정하세요.", - "MemoryManagerTooltip": "게스트 메모리가 매핑되고 접속되는 방식을 변경합니다. 에뮬레이트된 CPU 성능에 크게 영향을 미칩니다.\n\n확실하지 않은 경우 호스트 확인 안함으로 설정하십시오.", + "MemoryManagerTooltip": "게스트 메모리가 매핑되고 접속되는 방식을 변경합니다. 에뮬레이트된 CPU 성능에 크게 영향을 미칩니다.\n\n확실하지 않은 경우 호스트 확인 안함으로 설정하세요.", "MemoryManagerSoftwareTooltip": "주소 변환을 위해 소프트웨어 페이지 테이블을 사용하세요. 정확도는 가장 높지만 성능은 가장 느립니다.", "MemoryManagerHostTooltip": "호스트 주소 공간의 메모리를 직접 매핑합니다. 훨씬 빠른 JIT 컴파일 및 실행합니다.", "MemoryManagerUnsafeTooltip": "메모리를 직접 매핑하지만 접속하기 전에 게스트 주소 공간 내의 주소를 마스킹하지 마십시오. 더 빠르지만 안전을 희생해야 합니다. 게스트 응용 프로그램은 Ryujinx의 어디에서나 메모리에 접속할 수 있으므로 이 모드에서는 신뢰할 수 있는 프로그램만 실행하세요.", + "UseHypervisorTooltip": "JIT 대신 하이퍼바이저를 사용합니다. 하이퍼바이저를 사용할 수 있을 때 성능을 향상시키지만, 현재 상태에서는 불안정할 수 있습니다.", "DRamTooltip": "대체 메모리모드 레이아웃을 활용하여 스위치 개발 모델을 모방합니다.\n\n고해상도 텍스처 팩 또는 4k 해상도 모드에만 유용합니다. 성능을 향상시키지 않습니다.\n\n확실하지 않으면 꺼 두세요.", "IgnoreMissingServicesTooltip": "구현되지 않은 호라이즌 OS 서비스를 무시합니다. 이것은 특정 게임을 부팅할 때 충돌을 우회하는 데 도움이 될 수 있습니다.\n\n확실하지 않으면 꺼 두세요.", "GraphicsBackendThreadingTooltip": "두 번째 스레드에서 그래픽 백엔드 명령을 실행합니다.\n\n세이더 컴파일 속도를 높이고 끊김 현상을 줄이며 자체 멀티스레딩 지원 없이 GPU 드라이버의 성능을 향상시킵니다. 멀티스레딩이 있는 드라이버에서 성능이 약간 향상되었습니다.\n\n잘 모르겠으면 자동으로 설정하세요.", @@ -452,7 +469,7 @@ "ShaderCacheToggleTooltip": "후속 실행에서 끊김 현상을 줄이는 디스크 세이더 캐시를 저장합니다.\n\n확실하지 않으면 켜 두세요.", "ResolutionScaleTooltip": "적용 가능한 렌더 타겟에 적용된 해상도 스케일", "ResolutionScaleEntryTooltip": "1.5와 같은 부동 소수점 분해능 스케일입니다. 비통합 척도는 문제나 충돌을 일으킬 가능성이 더 큽니다.", - "AnisotropyTooltip": "이방성 필터링 수준 (게임에서 요청한 값을 사용하려면 자동으로 설정)", + "AnisotropyTooltip": "비등방성 필터링 수준 (게임에서 요청한 값을 사용하려면 자동으로 설정)", "AspectRatioTooltip": "렌더러 창에 적용된 화면비입니다.", "ShaderDumpPathTooltip": "그래픽 셰이더 덤프 경로", "FileLogTooltip": "디스크의 로그 파일에 콘솔 로깅을 저장합니다. 성능에 영향을 미치지 않습니다.", @@ -468,7 +485,7 @@ "OpenGlLogLevel": "적절한 로그 수준을 활성화해야 함", "DebugLogTooltip": "콘솔에 디버그 로그 메시지를 인쇄합니다.\n\n로그를 읽기 어렵게 만들고 에뮬레이터 성능을 악화시키므로 직원이 구체적으로 지시한 경우에만 사용하세요.", "LoadApplicationFileTooltip": "파일 탐색기를 열어 불러올 스위치 호환 파일 선택", - "LoadApplicationFolderTooltip": "파일 탐색기를 열어 불러올 스위치 호환 압축 해제 애플리케이션 선택", + "LoadApplicationFolderTooltip": "파일 탐색기를 열어 불러올 스위치 호환 압축 해제 응용 프로그램 선택", "OpenRyujinxFolderTooltip": "Ryujinx 파일 시스템 폴더 열기", "OpenRyujinxLogsTooltip": "로그가 기록된 폴더 열기", "ExitTooltip": "Ryujinx 종료", @@ -478,16 +495,16 @@ "CheckUpdatesTooltip": "Ryujinx 업데이트 확인", "OpenAboutTooltip": "정보 창 열기", "GridSize": "격자 크기", - "GridSizeTooltip": "격자 항목의 크기 변경\n", - "SettingsTabSystemSystemLanguageBrazilianPortuguese": "포르투갈어 (브라질)", + "GridSizeTooltip": "격자 항목의 크기 변경", + "SettingsTabSystemSystemLanguageBrazilianPortuguese": "포르투갈어(브라질)", "AboutRyujinxContributorsButtonHeader": "모든 기여자 보기", - "SettingsTabSystemAudioVolume": "볼륨 : ", - "AudioVolumeTooltip": "오디오 볼륨 변경", + "SettingsTabSystemAudioVolume": "음량 : ", + "AudioVolumeTooltip": "음향 음량 변경", "SettingsTabSystemEnableInternetAccess": "게스트 인터넷 접속/LAN 모드", - "EnableInternetAccessTooltip": "에뮬레이션된 애플리케이션이 인터넷에 연결되도록 허용합니다.\n\nLAN 모드가 있는 게임은 이 모드가 활성화되고 시스템이 동일한 접속 포인트에 연결된 경우 서로 연결할 수 있습니다. 여기에는 실제 콘솔도 포함됩니다.\n\n닌텐도 서버에 연결할 수 없습니다. 인터넷에 연결을 시도하는 특정 게임에서 충돌이 발생할 수 있습니다.\n\n확실하지 않으면 꺼두세요.", + "EnableInternetAccessTooltip": "에뮬레이션된 응용프로그램이 인터넷에 연결되도록 허용합니다.\n\nLAN 모드가 있는 게임은 이 모드가 활성화되고 시스템이 동일한 접속 포인트에 연결된 경우 서로 연결할 수 있습니다. 여기에는 실제 콘솔도 포함됩니다.\n\n닌텐도 서버에 연결할 수 없습니다. 인터넷에 연결을 시도하는 특정 게임에서 충돌이 발생할 수 있습니다.\n\n확실하지 않으면 꺼두세요.", "GameListContextMenuManageCheatToolTip": "치트 관리", "GameListContextMenuManageCheat": "치트 관리", - "ControllerSettingsStickRange": "범위:", + "ControllerSettingsStickRange": "범위 :", "DialogStopEmulationTitle": "Ryujinx - 에뮬레이션 중지", "DialogStopEmulationMessage": "에뮬레이션을 중지하겠습니까?", "SettingsTabCpu": "CPU", @@ -495,11 +512,11 @@ "SettingsTabNetwork": "네트워크", "SettingsTabNetworkConnection": "네트워크 연결", "SettingsTabCpuCache": "CPU 캐시", - "SettingsTabCpuMemory": "CPU 메모리", + "SettingsTabCpuMemory": "CPU 모드", "DialogUpdaterFlatpakNotSupportedMessage": "FlatHub를 통해 Ryujinx를 업데이트하세요.", "UpdaterDisabledWarningTitle": "업데이터 비활성화입니다!", - "GameListContextMenuOpenSdModsDirectory": "엣모스피어 Mod 디렉토리 열기", - "GameListContextMenuOpenSdModsDirectoryToolTip": "응용 프로그램의 모드가 포함된 대체 SD 카드 Atmosphere 디렉토리를 엽니다. 실제 하드웨어용으로 패키징된 모드에 유용합니다.\n", + "GameListContextMenuOpenSdModsDirectory": "분위기 모드 디렉터리 열기", + "GameListContextMenuOpenSdModsDirectoryToolTip": "응용프로그램의 모드가 포함된 대체 SD 카드 분위기 디렉터리를 엽니다. 실제 하드웨어용으로 패키징된 모드에 유용합니다.", "ControllerSettingsRotate90": "시계 방향으로 90° 회전", "IconSize": "아이콘 크기", "IconSizeTooltip": "게임 아이콘 크기 변경", @@ -513,25 +530,28 @@ "UserErrorUndefined": "정의되지 않은 오류", "UserErrorNoKeysDescription": "Ryujinx가 'prod.keys' 파일을 찾을 수 없음", "UserErrorNoFirmwareDescription": "Ryujinx가 설치된 펌웨어를 찾을 수 없음", - "UserErrorFirmwareParsingFailedDescription": "Ryujinx가 제공된 펌웨어를 구문 분석할 수 없습니다. 일반적으로 오래된 키가 원인입니다.\n", - "UserErrorApplicationNotFoundDescription": "Ryujinx가 지정된 경로에서 유효한 응용 프로그램을 찾을 수 없습니다.\n", - "UserErrorUnknownDescription": "알 수 없는 오류가 발생했습니다!\n", - "UserErrorUndefinedDescription": "정의되지 않은 오류가 발생했습니다! 이런 일이 발생하면 안 되므로, 개발자에게 문의하세요!\n", + "UserErrorFirmwareParsingFailedDescription": "Ryujinx가 제공된 펌웨어를 구문 분석할 수 없습니다. 일반적으로 오래된 키가 원인입니다.", + "UserErrorApplicationNotFoundDescription": "Ryujinx가 지정된 경로에서 유효한 응용 프로그램을 찾을 수 없습니다.", + "UserErrorUnknownDescription": "알 수 없는 오류가 발생했습니다!", + "UserErrorUndefinedDescription": "정의되지 않은 오류가 발생했습니다! 이런 일이 발생하면 안 되므로, 개발자에게 문의하세요!", "OpenSetupGuideMessage": "설정 가이드 열기", "NoUpdate": "업데이트 없음", - "TitleUpdateVersionLabel": "버전 {0} - {1}", + "TitleUpdateVersionLabel": "버전 {0}", "RyujinxInfo": "Ryujinx - 정보", "RyujinxConfirm": "Ryujinx - 확인", "FileDialogAllTypes": "모든 유형", "Never": "절대 안 함", - "SwkbdMinCharacters": "{0} 자 이상이어야 함", - "SwkbdMinRangeCharacters": "{0}-{1} 자여야 함", + "SwkbdMinCharacters": "{0}자 이상이어야 함", + "SwkbdMinRangeCharacters": "{0}-{1}자여야 함", "SoftwareKeyboard": "소프트웨어 키보드", - "DialogControllerAppletMessagePlayerRange": "응용 프로그램은 다음을 사용하여 {0} 플레이어를 요청합니다:\n\n유형: {1}\n\n플레이어: {2}\n\n{3} 지금 설정을 열고 입력을 재구성하거나 닫기를 누르세요.\n", - "DialogControllerAppletMessage": "애플리케이션은 다음을 사용하여 정확히 {0}명의 플레이어를 요청합니다:\n\n유형: {1}\n\n플레이어: {2}\n\n{3} 지금 설정을 열고 입력을 재구성하거나 닫기를 누르세요.\n", - "DialogControllerAppletDockModeSet": "도킹 모드가 설정되었습니다. 휴대용도 유효하지 않습니다.\n\n\n", + "SoftwareKeyboardModeNumbersOnly": "숫자만 가능", + "SoftwareKeyboardModeAlphabet": "한중일 문자가 아닌 문자만 가능", + "SoftwareKeyboardModeASCII": "ASCII 텍스트만 가능", + "DialogControllerAppletMessagePlayerRange": "응용 프로그램은 다음을 사용하는 {0} 명의 플레이어를 요청합니다:\n\n유형: {1}\n\n플레이어: {2}\n\n{3} 지금 설정을 열고 입력을 재구성하거나 닫기를 누르세요.\n", + "DialogControllerAppletMessage": "응용 프로그램은 다음을 사용하는 정확히 {0}명의 플레이어를 요청합니다:\n\n유형: {1}\n\n플레이어: {2}\n\n{3} 지금 설정을 열고 입력을 재구성하거나 닫기를 누르세요.\n", + "DialogControllerAppletDockModeSet": "독 모드가 설정되었습니다. 휴대 모드도 유효하지 않습니다.", "UpdaterRenaming": "이전 파일 이름 바꾸는 중...", - "UpdaterRenameFailed": "업데이터가 파일 이름을 바꿀 수 없습니다: {0}", + "UpdaterRenameFailed": "업데이터가 파일 이름을 바꿀 수 없음: {0}", "UpdaterAddingFiles": "새로운 파일을 추가하는 중...", "UpdaterExtracting": "업데이트를 추출하는 중...", "UpdaterDownloading": "업데이트 다운로드 중...", @@ -543,7 +563,7 @@ "ApiError": "API 오류입니다.", "LoadingHeading": "{0} 로딩 중", "CompilingPPTC": "PTC 컴파일 중", - "CompilingShaders": "세이더 컴파일", + "CompilingShaders": "셰이더 컴파일 중", "AllKeyboards": "모든 키보드", "OpenFileDialogTitle": "지원되는 파일을 선택", "OpenFolderDialogTitle": "압축을 푼 게임이 있는 폴더 선택", @@ -551,11 +571,11 @@ "RyujinxUpdater": "Ryujinx 업데이터", "SettingsTabHotkeys": "키보드 단축키", "SettingsTabHotkeysHotkeys": "키보드 단축키", - "SettingsTabHotkeysToggleVsyncHotkey": "수직 동기화 전환:", - "SettingsTabHotkeysScreenshotHotkey": "스크린샷:", - "SettingsTabHotkeysShowUiHotkey": "UI 표시:", - "SettingsTabHotkeysPauseHotkey": "일시정지:", - "SettingsTabHotkeysToggleMuteHotkey": "음소거:", + "SettingsTabHotkeysToggleVsyncHotkey": "수직 동기화 전환 :", + "SettingsTabHotkeysScreenshotHotkey": "스크린샷 :", + "SettingsTabHotkeysShowUiHotkey": "UI 표시 :", + "SettingsTabHotkeysPauseHotkey": "일시 중지 :", + "SettingsTabHotkeysToggleMuteHotkey": "음 소거 :", "ControllerMotionTitle": "동작 제어 설정", "ControllerRumbleTitle": "진동 설정", "SettingsSelectThemeFileDialogTitle": "테마 파일 선택", @@ -569,46 +589,68 @@ "SelectUpdateDialogTitle": "업데이트 파일 선택", "UserProfileWindowTitle": "사용자 프로파일 관리자", "CheatWindowTitle": "치트 관리자", - "DlcWindowTitle": "다운로드 가능한 콘텐츠 관리자", + "DlcWindowTitle": "{0} ({1})의 다운로드 가능한 콘텐츠 관리", "UpdateWindowTitle": "타이틀 업데이트 관리자", "CheatWindowHeading": "{0} [{1}]에 사용할 수 있는 치트", - "DlcWindowHeading": "{1} ({2})에 사용할 수 있는 {0} 다운로드 가능한 콘텐츠", - "UserProfilesEditProfile": "선택 항목 편집", + "BuildId": "빌드ID :", + "DlcWindowHeading": "{0} 내려받기 가능한 콘텐츠", + "UserProfilesEditProfile": "선택된 항목 편집", "Cancel": "취소", "Save": "저장", "Discard": "삭제", "UserProfilesSetProfileImage": "프로파일 이미지 설정", "UserProfileEmptyNameError": "이름 필요", "UserProfileNoImageError": "프로파일 이미지를 설정해야 함", - "GameUpdateWindowHeading": "{1} ({2})에 대한 {0} 업데이트 사용 가능", - "SettingsTabHotkeysResScaleUpHotkey": "해상도 증가:", - "SettingsTabHotkeysResScaleDownHotkey": "해상도 감소:", - "UserProfilesName": "이름:", - "UserProfilesUserId": "사용자 Id:", - "SettingsTabGraphicsBackend": "그래픽 백엔드", - "SettingsTabGraphicsBackendTooltip": "사용할 그래픽 백엔드", + "GameUpdateWindowHeading": "{0} ({1})에 대한 업데이트 관리", + "SettingsTabHotkeysResScaleUpHotkey": "해상도 증가 :", + "SettingsTabHotkeysResScaleDownHotkey": "해상도 감소 :", + "UserProfilesName": "이름 :", + "UserProfilesUserId": "사용자 ID :", + "SettingsTabGraphicsBackend": "그래픽 후단부", + "SettingsTabGraphicsBackendTooltip": "사용할 그래픽 후단부", "SettingsEnableTextureRecompression": "텍스처 재압축 활성화", "SettingsEnableTextureRecompressionTooltip": "VRAM 사용량을 줄이기 위해 특정 텍스처를 압축합니다.\n\n4GiB VRAM 미만의 GPU와 함께 사용하는 것이 좋습니다.\n\n확실하지 않으면 꺼 두세요.", "SettingsTabGraphicsPreferredGpu": "선호하는 GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "Vulkan 그래픽 백엔드와 함께 사용할 그래픽 카드를 선택하세요.\n\nOpenGL이 사용할 GPU에는 영향을 미치지 않습니다.\n\n확실하지 않은 경우 \"dGPU\" 플래그가 지정된 GPU로 설정하세요. 없는 경우, 그대로 두세요.\n", - "SettingsAppRequiredRestartMessage": "Ryujinx 재시작 필요", - "SettingsGpuBackendRestartMessage": "그래픽 백엔드 또는 GPU 설정이 수정되었습니다. 적용하려면 다시 시작해야 함\n", + "SettingsTabGraphicsPreferredGpuTooltip": "Vulkan 그래픽 후단부와 함께 사용할 그래픽 카드를 선택하세요.\n\nOpenGL이 사용할 GPU에는 영향을 미치지 않습니다.\n\n확실하지 않은 경우 \"dGPU\" 플래그가 지정된 GPU로 설정하세요. 없는 경우, 그대로 두세요.", + "SettingsAppRequiredRestartMessage": "Ryujinx 다시 시작 필요", + "SettingsGpuBackendRestartMessage": "그래픽 후단부 또는 GPU 설정이 수정되었습니다. 적용하려면 다시 시작해야 합니다.", "SettingsGpuBackendRestartSubMessage": "지금 다시 시작하겠습니까?", "RyujinxUpdaterMessage": "Ryujinx를 최신 버전으로 업데이트하겠습니까?", - "SettingsTabHotkeysVolumeUpHotkey": "볼륨 증가:", - "SettingsTabHotkeysVolumeDownHotkey": "볼륨 감소:", + "SettingsTabHotkeysVolumeUpHotkey": "음량 증가 :", + "SettingsTabHotkeysVolumeDownHotkey": "음량 감소 :", "SettingsEnableMacroHLE": "매크로 HLE 활성화", "SettingsEnableMacroHLETooltip": "GPU 매크로 코드의 높은 수준 에뮬레이션입니다.\n\n성능이 향상되지만 일부 게임에서 그래픽 결함이 발생할 수 있습니다.\n\n확실하지 않으면 켜 두세요.", - "VolumeShort": "볼륨", + "SettingsEnableColorSpacePassthrough": "색 공간 통과", + "SettingsEnableColorSpacePassthroughTooltip": "색 공간을 지정하지 않고 색상 정보를 전달하도록 Vulkan 후단에 지시합니다. 와이드 가멋 디스플레이를 사용하는 사용자의 경우 색 정확도가 저하되지만 더 생생한 색상을 얻을 수 있습니다.", + "VolumeShort": "음량", "UserProfilesManageSaves": "저장 관리", "DeleteUserSave": "이 게임에 대한 사용자 저장을 삭제하겠습니까?", "IrreversibleActionNote": "이 작업은 되돌릴 수 없습니다.", - "SaveManagerHeading": "{0}의 저장 관리", + "SaveManagerHeading": "{0} ({1})의 저장 관리", "SaveManagerTitle": "저장 관리자", "Name": "이름", "Size": "크기", "Search": "검색", "UserProfilesRecoverLostAccounts": "잃어버린 계정 복구", "Recover": "복구", - "UserProfilesRecoverHeading": "다음 계정에 대한 저장 발견" -} + "UserProfilesRecoverHeading": "다음 계정에 대한 저장 발견", + "UserProfilesRecoverEmptyList": "복구할 프로파일이 없습니다", + "GraphicsAATooltip": "게임 렌더링에 안티 앨리어싱을 적용", + "GraphicsAALabel": "안티 앨리어싱:", + "GraphicsScalingFilterLabel": "스케일링 필터:", + "GraphicsScalingFilterTooltip": "프레임버퍼 스케일링 활성화", + "GraphicsScalingFilterLevelLabel": "수준", + "GraphicsScalingFilterLevelTooltip": "스케일링 필터 수준 설정", + "SmaaLow": "SMAA 낮음", + "SmaaMedium": "SMAA 중간", + "SmaaHigh": "SMAA 높음", + "SmaaUltra": "SMAA 울트라", + "UserEditorTitle": "사용자 수정", + "UserEditorTitleCreate": "사용자 생성", + "SettingsTabNetworkInterface": "네트워크 인터페이스:", + "NetworkInterfaceTooltip": "LAN 기능에 사용되는 네트워크 인터페이스", + "NetworkInterfaceDefault": "기본", + "PackagingShaders": "셰이더 패키징 중", + "AboutChangelogButton": "GitHub에서 변경 로그 보기", + "AboutChangelogButtonTooltipMessage": "기본 브라우저에서 이 버전의 변경 로그를 열려면 클릭합니다." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/pl_PL.json b/src/Ryujinx.Ava/Assets/Locales/pl_PL.json index 077ccc2d5..7edf41e84 100644 --- a/src/Ryujinx.Ava/Assets/Locales/pl_PL.json +++ b/src/Ryujinx.Ava/Assets/Locales/pl_PL.json @@ -1,12 +1,13 @@ { - "Language": "Polski", + "Language": "Angielski (USA)", "MenuBarFileOpenApplet": "Otwórz Aplet", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Otwórz aplet Mii Editor w trybie Indywidualnym", "SettingsTabInputDirectMouseAccess": "Bezpośredni Dostęp do Myszy", "SettingsTabSystemMemoryManagerMode": "Tryb Menedżera Pamięci:", - "SettingsTabSystemMemoryManagerModeSoftware": "Oprogramowania", + "SettingsTabSystemMemoryManagerModeSoftware": "Oprogramowanie", "SettingsTabSystemMemoryManagerModeHost": "Host (szybko)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Niesprawdzony (najszybciej, niebezpiecznie)", + "SettingsTabSystemUseHypervisor": "Użyj Hiperwizora", "MenuBarFile": "_Plik", "MenuBarFileOpenFromFile": "_Załaduj Aplikację z Pliku", "MenuBarFileOpenUnpacked": "Załaduj _Rozpakowaną Grę", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "Zainstaluj Firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Zainstaluj Firmware z XCI lub ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Zainstaluj Firmware z Katalogu", + "MenuBarToolsManageFileTypes": "Zarządzaj rodzajem plików", + "MenuBarToolsInstallFileTypes": "Instalacja typów plików", + "MenuBarToolsUninstallFileTypes": "Odinstaluj rodzaje plików", "MenuBarHelp": "Pomoc", "MenuBarHelpCheckForUpdates": "Sprawdź Aktualizacje", "MenuBarHelpAbout": "O Aplikacji", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Wyodrębnij sekcję Logo z bieżącej konfiguracji aplikacji (w tym aktualizacje)", "StatusBarGamesLoaded": "{0}/{1} Załadowane Gry", "StatusBarSystemVersion": "Wersja Systemu: {0}", + "LinuxVmMaxMapCountDialogTitle": "Wykryto niski limit dla mapowania pamięci", + "LinuxVmMaxMapCountDialogTextPrimary": "Czy chciałbyś zwiększyć wartość vm.max_map_count do {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "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.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Tak, do następnego ponownego uruchomienia", + "LinuxVmMaxMapCountDialogButtonPersistent": "Tak, permanentnie ", + "LinuxVmMaxMapCountWarningTextPrimary": "Maksymalna ilość mapowania pamięci jest mniejsza niż zalecana.", + "LinuxVmMaxMapCountWarningTextSecondary": "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.", "Settings": "Ustawienia", "SettingsTabGeneral": "Interfejs Użytkownika", "SettingsTabGeneralGeneral": "Ogólne", "SettingsTabGeneralEnableDiscordRichPresence": "Włącz Bogatą Obecność Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Sprawdź Aktualizacje przy Uruchomieniu", "SettingsTabGeneralShowConfirmExitDialog": "Pokaż Okno Dialogowe \"Potwierdzenia Wyjścia\"", + "SettingsTabGeneralHideCursor": "Ukryj kursor:", + "SettingsTabGeneralHideCursorNever": "Nigdy", "SettingsTabGeneralHideCursorOnIdle": "Ukryj Kursor Podczas Bezczynności", + "SettingsTabGeneralHideCursorAlways": "Zawsze", "SettingsTabGeneralGameDirectories": "Katalogi Gier", "SettingsTabGeneralAdd": "Dodaj", "SettingsTabGeneralRemove": "Usuń", @@ -110,7 +124,7 @@ "SettingsTabSystemSystemLanguageTraditionalChinese": "Chiński Tradycyjny", "SettingsTabSystemSystemTimeZone": "Strefa Czasowa Systemu:", "SettingsTabSystemSystemTime": "Czas Systemu:", - "SettingsTabSystemEnableVsync": "VSync", + "SettingsTabSystemEnableVsync": "Włącz synchronizację pionową", "SettingsTabSystemEnablePptc": "PPTC (Profilowany Cache Trwałych Tłumaczeń)", "SettingsTabSystemEnableFsIntegrityChecks": "Kontrole Integralności Systemu Plików", "SettingsTabSystemAudioBackend": "Backend Dżwięku:", @@ -126,7 +140,7 @@ "SettingsTabGraphicsAPI": "Graficzne API", "SettingsTabGraphicsEnableShaderCache": "Włącz Cache Shaderów", "SettingsTabGraphicsAnisotropicFiltering": "Filtrowanie Anizotropowe:", - "SettingsTabGraphicsAnisotropicFilteringAuto": "Auto", + "SettingsTabGraphicsAnisotropicFilteringAuto": "Automatyczny", "SettingsTabGraphicsAnisotropicFiltering2x": "2x", "SettingsTabGraphicsAnisotropicFiltering4x": "4x", "SettingsTabGraphicsAnisotropicFiltering8x": "8x", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Włącz Logi Dostępu do Systemu Plików", "SettingsTabLoggingFsGlobalAccessLogMode": "Tryb Globalnych Logów Systemu Plików:", "SettingsTabLoggingDeveloperOptions": "Opcje programistyczne (OSTRZEŻENIE: Zmniejszą wydajność)", + "SettingsTabLoggingDeveloperOptionsNote": "UWAGA: Zredukuje wydajność", "SettingsTabLoggingGraphicsBackendLogLevel": "Ilość Logów Backendu Graficznego:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Żadne", "SettingsTabLoggingGraphicsBackendLogLevelError": "Błędy", @@ -187,7 +202,7 @@ "ControllerSettingsDeviceDisabled": "Wyłączone", "ControllerSettingsControllerType": "Typ Kontrolera", "ControllerSettingsControllerTypeHandheld": "Przenośny", - "ControllerSettingsControllerTypeProController": "Pro Controller", + "ControllerSettingsControllerTypeProController": "Pro Kontroler", "ControllerSettingsControllerTypeJoyConPair": "Para JoyCon-ów", "ControllerSettingsControllerTypeJoyConLeft": "Lewy JoyCon", "ControllerSettingsControllerTypeJoyConRight": "Prawy JoyCon", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Dół", "ControllerSettingsDPadLeft": "Lewo", "ControllerSettingsDPadRight": "Prawo", + "ControllerSettingsStickButton": "Przycisk", + "ControllerSettingsStickUp": "Góra ", + "ControllerSettingsStickDown": "Dół ", + "ControllerSettingsStickLeft": "Lewo", + "ControllerSettingsStickRight": "Prawo", + "ControllerSettingsStickStick": "Gałka", + "ControllerSettingsStickInvertXAxis": "Odwróć gałkę X", + "ControllerSettingsStickInvertYAxis": "Odwróć gałkę Y", + "ControllerSettingsStickDeadzone": "Martwa strefa:", "ControllerSettingsLStick": "Lewa Gałka", - "ControllerSettingsLStickButton": "Przycisk", - "ControllerSettingsLStickUp": "Góra", - "ControllerSettingsLStickDown": "Dół", - "ControllerSettingsLStickLeft": "Lewo", - "ControllerSettingsLStickRight": "Prawo", - "ControllerSettingsLStickStick": "Gałka", - "ControllerSettingsLStickInvertXAxis": "Odwróć X Gałki", - "ControllerSettingsLStickInvertYAxis": "Odwróć Y Gałki", - "ControllerSettingsLStickDeadzone": "Martwa Strefa:", "ControllerSettingsRStick": "Prawa Gałka", - "ControllerSettingsRStickButton": "Przycisk", - "ControllerSettingsRStickUp": "Góra", - "ControllerSettingsRStickDown": "Dół", - "ControllerSettingsRStickLeft": "Lewo", - "ControllerSettingsRStickRight": "Prawo", - "ControllerSettingsRStickStick": "Gałka", - "ControllerSettingsRStickInvertXAxis": "Odwróć X Gałki", - "ControllerSettingsRStickInvertYAxis": "Odwróć Y Gałki", - "ControllerSettingsRStickDeadzone": "Martwa Strefa:", "ControllerSettingsTriggersLeft": "Lewe Triggery", "ControllerSettingsTriggersRight": "Prawe Triggery", "ControllerSettingsTriggersButtonsLeft": "Lewe Przyciski Triggerów", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Utwórz Profil", "UserProfilesDelete": "Usuwać", "UserProfilesClose": "Zamknij", + "ProfileNameSelectionWatermark": "Wybierz pseudonim", "ProfileImageSelectionTitle": "Wybór Obrazu Profilu", "ProfileImageSelectionHeader": "Wybierz zdjęcie profilowe", "ProfileImageSelectionNote": "Możesz zaimportować niestandardowy obraz profilu lub wybrać awatar z firmware'u systemowego", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Zapisz Profil", "MenuBarFileToolsTakeScreenshot": "Zrób Zrzut Ekranu", "MenuBarFileToolsHideUi": "Ukryj UI", + "GameListContextMenuRunApplication": "Uruchom aplikację ", "GameListContextMenuToggleFavorite": "Przełącz Ulubione", "GameListContextMenuToggleFavoriteToolTip": "Przełącz status Ulubionej Gry", "SettingsTabGeneralTheme": "Motyw", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Nie znaleziono zainstalowanego firmware'u, ale Ryujinx był w stanie zainstalować firmware {0} z dostarczonej gry.\n\nEmulator uruchomi się teraz.", "DialogFirmwareNoFirmwareInstalledMessage": "Brak Zainstalowanego Firmware'u", "DialogFirmwareInstalledMessage": "Firmware {0} został zainstalowany", + "DialogInstallFileTypesSuccessMessage": "Pomyślnie zainstalowano typy plików!", + "DialogInstallFileTypesErrorMessage": "Nie udało się zainstalować typów plików.", + "DialogUninstallFileTypesSuccessMessage": "Pomyślnie odinstalowano typy plików!", + "DialogUninstallFileTypesErrorMessage": "Nie udało się odinstalować typów plików.", "DialogOpenSettingsWindowLabel": "Otwórz Okno Ustawień", "DialogControllerAppletTitle": "Aplet Kontrolera", "DialogMessageDialogErrorExceptionMessage": "Błąd wyświetlania okna Dialogowego Wiadomości: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Wersja systemu {0} została pomyślnie zainstalowana.", "DialogUserProfileDeletionWarningMessage": "Nie będzie innych profili do otwarcia, jeśli wybrany profil zostanie usunięty", "DialogUserProfileDeletionConfirmMessage": "Czy chcesz usunąć wybrany profil", + "DialogUserProfileUnsavedChangesTitle": "Uwaga - Niezapisane zmiany", + "DialogUserProfileUnsavedChangesMessage": "Wprowadziłeś zmiany dla tego profilu użytkownika, które nie zostały zapisane.", + "DialogUserProfileUnsavedChangesSubMessage": "Czy chcesz odrzucić zmiany?", "DialogControllerSettingsModifiedConfirmMessage": "Aktualne ustawienia kontrolera zostały zaktualizowane.", "DialogControllerSettingsModifiedConfirmSubMessage": "Czy chcesz zapisać?", "DialogLoadNcaErrorMessage": "{0}. Błędny Plik: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Włącz Wszystkie", "DlcManagerDisableAllButton": "Wyłącz Wszystkie", "MenuBarOptionsChangeLanguage": "Zmień Język", + "MenuBarShowFileTypes": "Pokaż typy plików", "CommonSort": "Sortuj", "CommonShowNames": "Pokaż Nazwy", "CommonFavorite": "Ulubione", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Użyj tabeli stron oprogramowania do translacji adresów. Najwyższa celność, ale najwolniejsza wydajność.", "MemoryManagerHostTooltip": "Bezpośrednio mapuj pamięć w przestrzeni adresowej hosta. Znacznie szybsza kompilacja i wykonanie JIT.", "MemoryManagerUnsafeTooltip": "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.", + "UseHypervisorTooltip": "Użyj Hiperwizora zamiast JIT. Znacznie poprawia wydajność, gdy jest dostępny, ale może być niestabilny w swoim obecnym stanie ", "DRamTooltip": "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.", "IgnoreMissingServicesTooltip": "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.", "GraphicsBackendThreadingTooltip": "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.", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Musi mieć co najmniej {0} znaków", "SwkbdMinRangeCharacters": "Musi mieć długość od {0}-{1} znaków", "SoftwareKeyboard": "Klawiatura Oprogramowania", + "SoftwareKeyboardModeNumbersOnly": "Mogą być tylko liczby ", + "SoftwareKeyboardModeAlphabet": "Nie może zawierać znaków CJK", + "SoftwareKeyboardModeASCII": "Musi zawierać tylko tekst ASCII", "DialogControllerAppletMessagePlayerRange": "Aplikacja żąda {0} graczy z:\n\nTYPY: {1}\n\nGRACZE: {2}\n\n{3}Otwórz Ustawienia i ponownie skonfiguruj Sterowanie lub naciśnij Zamknij.", "DialogControllerAppletMessage": "Aplikacja żąda dokładnie {0} graczy z:\n\nTYPY: {1}\n\nGRACZE: {2}\n\n{3}Otwórz teraz Ustawienia i ponownie skonfiguruj Sterowanie lub naciśnij Zamknij.", "DialogControllerAppletDockModeSet": "Ustawiono tryb Zadokowane. Przenośny też jest nieprawidłowy.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Menedżer Zawartości do Pobrania", "UpdateWindowTitle": "Menedżer Aktualizacji Tytułu", "CheatWindowHeading": "Kody Dostępne dla {0} [{1}]", + "BuildId": "Identyfikator wersji:", "DlcWindowHeading": "{0} Zawartości do Pobrania dostępna dla {1} ({2})", "UserProfilesEditProfile": "Edytuj Zaznaczone", "Cancel": "Anuluj", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Zmniejsz Głośność:", "SettingsEnableMacroHLE": "Włącz Macro HLE", "SettingsEnableMacroHLETooltip": "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.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", "VolumeShort": "Głoś", "UserProfilesManageSaves": "Zarządzaj Zapisami", "DeleteUserSave": "Czy chcesz usunąć zapis użytkownika dla tej gry?", @@ -610,5 +633,24 @@ "Search": "Wyszukaj", "UserProfilesRecoverLostAccounts": "Odzyskaj Utracone Konta", "Recover": "Odzyskaj", - "UserProfilesRecoverHeading": "Znaleziono zapisy dla następujących kont" -} + "UserProfilesRecoverHeading": "Znaleziono zapisy dla następujących kont", + "UserProfilesRecoverEmptyList": "Brak profili do odzyskania", + "GraphicsAATooltip": "Stosuje antyaliasing do renderowania gry", + "GraphicsAALabel": "Antyaliasing:", + "GraphicsScalingFilterLabel": "Filtr skalowania:", + "GraphicsScalingFilterTooltip": "Włącza skalowanie bufora ramki", + "GraphicsScalingFilterLevelLabel": "Poziom", + "GraphicsScalingFilterLevelTooltip": "Ustaw poziom filtra skalowania", + "SmaaLow": "SMAA Niskie", + "SmaaMedium": "SMAA Średnie", + "SmaaHigh": "SMAA Wysokie", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Edytuj użytkownika", + "UserEditorTitleCreate": "Utwórz użytkownika", + "SettingsTabNetworkInterface": "Interfejs sieci:", + "NetworkInterfaceTooltip": "Interfejs sieciowy używany do funkcji LAN", + "NetworkInterfaceDefault": "Domyślny", + "PackagingShaders": "Pakuje Shadery ", + "AboutChangelogButton": "Zobacz listę zmian na GitHubie", + "AboutChangelogButtonTooltipMessage": "Kliknij, aby otworzyć listę zmian dla tej wersji w domyślnej przeglądarce." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/pt_BR.json b/src/Ryujinx.Ava/Assets/Locales/pt_BR.json index effe8c028..8909a84fe 100644 --- a/src/Ryujinx.Ava/Assets/Locales/pt_BR.json +++ b/src/Ryujinx.Ava/Assets/Locales/pt_BR.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "Software", "SettingsTabSystemMemoryManagerModeHost": "Hóspede (rápido)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Hóspede sem verificação (mais rápido, inseguro)", + "SettingsTabSystemUseHypervisor": "Usar Hipervisor", "MenuBarFile": "_Arquivo", "MenuBarFileOpenFromFile": "_Abrir ROM do jogo...", "MenuBarFileOpenUnpacked": "Abrir jogo _extraído...", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "_Instalar firmware", "MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware a partir de um arquivo ZIP/XCI", "MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware a partir de um diretório", + "MenuBarToolsManageFileTypes": "Gerenciar tipos de arquivo", + "MenuBarToolsInstallFileTypes": "Instalar tipos de arquivo", + "MenuBarToolsUninstallFileTypes": "Desinstalar tipos de arquivos", "MenuBarHelp": "A_juda", "MenuBarHelpCheckForUpdates": "_Verificar se há atualizações", "MenuBarHelpAbout": "_Sobre", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Extrai a seção Logo do jogo (incluindo atualizações)", "StatusBarGamesLoaded": "{0}/{1} jogos carregados", "StatusBarSystemVersion": "Versão do firmware: {0}", + "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", + "LinuxVmMaxMapCountDialogTextPrimary": "Would you like to increase the value of vm.max_map_count to {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Yes, until the next restart", + "LinuxVmMaxMapCountDialogButtonPersistent": "Yes, permanently", + "LinuxVmMaxMapCountWarningTextPrimary": "Max amount of memory mappings is lower than recommended.", + "LinuxVmMaxMapCountWarningTextSecondary": "The current value of vm.max_map_count ({0}) is lower than {1}. Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.\n\nYou might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.", "Settings": "Configurações", "SettingsTabGeneral": "Geral", "SettingsTabGeneralGeneral": "Geral", "SettingsTabGeneralEnableDiscordRichPresence": "Habilitar Rich Presence do Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Verificar se há atualizações ao iniciar", "SettingsTabGeneralShowConfirmExitDialog": "Exibir diálogo de confirmação ao sair", + "SettingsTabGeneralHideCursor": "Esconder o cursor do mouse:", + "SettingsTabGeneralHideCursorNever": "Nunca", "SettingsTabGeneralHideCursorOnIdle": "Esconder o cursor quando ocioso", + "SettingsTabGeneralHideCursorAlways": "Sempre", "SettingsTabGeneralGameDirectories": "Diretórios de jogo", "SettingsTabGeneralAdd": "Adicionar", "SettingsTabGeneralRemove": "Remover", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Habilitar logs de acesso ao sistema de arquivos", "SettingsTabLoggingFsGlobalAccessLogMode": "Modo global de logs do sistema de arquivos:", "SettingsTabLoggingDeveloperOptions": "Opções do desenvolvedor (AVISO: Vai reduzir a performance)", + "SettingsTabLoggingDeveloperOptionsNote": "AVISO: Reduzirá o desempenho", "SettingsTabLoggingGraphicsBackendLogLevel": "Nível de log do backend gráfico:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Nenhum", "SettingsTabLoggingGraphicsBackendLogLevelError": "Erro", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Baixo", "ControllerSettingsDPadLeft": "Esquerda", "ControllerSettingsDPadRight": "Direita", + "ControllerSettingsStickButton": "Button", + "ControllerSettingsStickUp": "Up", + "ControllerSettingsStickDown": "Down", + "ControllerSettingsStickLeft": "Left", + "ControllerSettingsStickRight": "Right", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "Invert Stick X", + "ControllerSettingsStickInvertYAxis": "Invert Stick Y", + "ControllerSettingsStickDeadzone": "Deadzone:", "ControllerSettingsLStick": "Analógico esquerdo", - "ControllerSettingsLStickButton": "Botão", - "ControllerSettingsLStickUp": "Cima", - "ControllerSettingsLStickDown": "Baixo", - "ControllerSettingsLStickLeft": "Esquerda", - "ControllerSettingsLStickRight": "Direita", - "ControllerSettingsLStickStick": "Analógico", - "ControllerSettingsLStickInvertXAxis": "Inverter eixo X", - "ControllerSettingsLStickInvertYAxis": "Inverter eixo Y", - "ControllerSettingsLStickDeadzone": "Zona morta:", "ControllerSettingsRStick": "Analógico direito", - "ControllerSettingsRStickButton": "Botão", - "ControllerSettingsRStickUp": "Cima", - "ControllerSettingsRStickDown": "Baixo", - "ControllerSettingsRStickLeft": "Esquerda", - "ControllerSettingsRStickRight": "Direita", - "ControllerSettingsRStickStick": "Analógico", - "ControllerSettingsRStickInvertXAxis": "Inverter eixo X", - "ControllerSettingsRStickInvertYAxis": "Inverter eixo Y", - "ControllerSettingsRStickDeadzone": "Zona morta:", "ControllerSettingsTriggersLeft": "Gatilhos esquerda", "ControllerSettingsTriggersRight": "Gatilhos direita", "ControllerSettingsTriggersButtonsLeft": "Botões de gatilho esquerda", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Adicionar novo perfil", "UserProfilesDelete": "Apagar", "UserProfilesClose": "Fechar", + "ProfileNameSelectionWatermark": "Escolha um apelido", "ProfileImageSelectionTitle": "Seleção da imagem de perfil", "ProfileImageSelectionHeader": "Escolha uma imagem de perfil", "ProfileImageSelectionNote": "Você pode importar uma imagem customizada, ou selecionar um avatar do firmware", @@ -281,7 +288,8 @@ "ControllerSettingsRemoveProfileToolTip": "Remover perfil", "ControllerSettingsSaveProfileToolTip": "Salvar perfil", "MenuBarFileToolsTakeScreenshot": "Salvar captura de tela", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "Esconder Interface", + "GameListContextMenuRunApplication": "Run Application", "GameListContextMenuToggleFavorite": "Alternar favorito", "GameListContextMenuToggleFavoriteToolTip": "Marca ou desmarca jogo como favorito", "SettingsTabGeneralTheme": "Tema", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Nenhum firmware instalado foi encontrado, mas Ryujinx conseguiu instalar o firmware {0} do jogo fornecido.\nO emulador será reiniciado.", "DialogFirmwareNoFirmwareInstalledMessage": "Firmware não foi instalado", "DialogFirmwareInstalledMessage": "Firmware {0} foi instalado", + "DialogInstallFileTypesSuccessMessage": "Tipos de arquivo instalados com sucesso!", + "DialogInstallFileTypesErrorMessage": "Falha ao instalar tipos de arquivo.", + "DialogUninstallFileTypesSuccessMessage": "Tipos de arquivo desinstalados com sucesso!", + "DialogUninstallFileTypesErrorMessage": "Falha ao desinstalar tipos de arquivo.", "DialogOpenSettingsWindowLabel": "Abrir janela de configurações", "DialogControllerAppletTitle": "Applet de controle", "DialogMessageDialogErrorExceptionMessage": "Erro ao exibir diálogo de mensagem: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versão do sistema {0} instalada com sucesso.", "DialogUserProfileDeletionWarningMessage": "Não haveria nenhum perfil selecionado se o perfil atual fosse deletado", "DialogUserProfileDeletionConfirmMessage": "Deseja deletar o perfil selecionado", + "DialogUserProfileUnsavedChangesTitle": "Alerta - Alterações não salvas", + "DialogUserProfileUnsavedChangesMessage": "Você fez alterações para este perfil de usuário que não foram salvas.", + "DialogUserProfileUnsavedChangesSubMessage": "Deseja descartar as alterações?", "DialogControllerSettingsModifiedConfirmMessage": "As configurações de controle atuais foram atualizadas.", "DialogControllerSettingsModifiedConfirmSubMessage": "Deseja salvar?", "DialogLoadNcaErrorMessage": "{0}. Arquivo com erro: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Habilitar todos", "DlcManagerDisableAllButton": "Desabilitar todos", "MenuBarOptionsChangeLanguage": "Mudar idioma", + "MenuBarShowFileTypes": "Mostrar tipos de arquivo", "CommonSort": "Ordenar", "CommonShowNames": "Exibir nomes", "CommonFavorite": "Favorito", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Usar uma tabela de página via software para tradução de endereços. Maior precisão, porém performance mais baixa.", "MemoryManagerHostTooltip": "Mapeia memória no espaço de endereço hóspede diretamente. Compilação e execução do JIT muito mais rápida.", "MemoryManagerUnsafeTooltip": "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.", + "UseHypervisorTooltip": "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.", "DRamTooltip": "Expande a memória do sistema emulado de 4GiB para 6GiB", "IgnoreMissingServicesTooltip": "Habilita ou desabilita a opção de ignorar serviços não implementados", "GraphicsBackendThreadingTooltip": "Habilita multithreading do backend gráfico", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Deve ter pelo menos {0} caracteres", "SwkbdMinRangeCharacters": "Deve ter entre {0}-{1} caracteres", "SoftwareKeyboard": "Teclado por Software", + "SoftwareKeyboardModeNumbersOnly": "Must be numbers only", + "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", + "SoftwareKeyboardModeASCII": "Must be ASCII text only", "DialogControllerAppletMessagePlayerRange": "O aplicativo requer {0} jogador(es) com:\n\nTIPOS: {1}\n\nJOGADORES: {2}\n\n{3}Por favor, abra as configurações e reconfigure os controles agora ou clique em Fechar.", "DialogControllerAppletMessage": "O aplicativo requer exatamente {0} jogador(es) com:\n\nTIPOS: {1}\n\nJOGADORES: {2}\n\n{3}Por favor, abra as configurações e reconfigure os controles agora ou clique em Fechar.", "DialogControllerAppletDockModeSet": "Modo TV ativado. Portátil também não é válido.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Gerenciador de DLC", "UpdateWindowTitle": "Gerenciador de atualizações", "CheatWindowHeading": "Cheats disponíveis para {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "{0} DLCs disponíveis para {1} ({2})", "UserProfilesEditProfile": "Editar selecionado", "Cancel": "Cancelar", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Diminuir volume:", "SettingsEnableMacroHLE": "Habilitar emulação de alto nível para Macros", "SettingsEnableMacroHLETooltip": "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.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", "VolumeShort": "Vol", "UserProfilesManageSaves": "Gerenciar jogos salvos", "DeleteUserSave": "Deseja apagar o jogo salvo do usuário para este jogo?", @@ -610,5 +633,24 @@ "Search": "Buscar", "UserProfilesRecoverLostAccounts": "Recuperar contas perdidas", "Recover": "Recuperar", - "UserProfilesRecoverHeading": "Jogos salvos foram encontrados para as seguintes contas" -} + "UserProfilesRecoverHeading": "Jogos salvos foram encontrados para as seguintes contas", + "UserProfilesRecoverEmptyList": "Nenhum perfil para recuperar", + "GraphicsAATooltip": "Aplica anti-serrilhamento à renderização do jogo", + "GraphicsAALabel": "Anti-serrilhado:", + "GraphicsScalingFilterLabel": "Filtro de escala:", + "GraphicsScalingFilterTooltip": "Habilita escala do Framebuffer", + "GraphicsScalingFilterLevelLabel": "Nível", + "GraphicsScalingFilterLevelTooltip": "Define o nível do filtro de escala", + "SmaaLow": "SMAA Baixo", + "SmaaMedium": "SMAA Médio", + "SmaaHigh": "SMAA Alto", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Editar usuário", + "UserEditorTitleCreate": "Criar usuário", + "SettingsTabNetworkInterface": "Interface de rede:", + "NetworkInterfaceTooltip": "A interface de rede usada para recursos LAN (rede local)", + "NetworkInterfaceDefault": "Padrão", + "PackagingShaders": "Packaging Shaders", + "AboutChangelogButton": "View Changelog on GitHub", + "AboutChangelogButtonTooltipMessage": "Click to open the changelog for this version in your default browser." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/ru_RU.json b/src/Ryujinx.Ava/Assets/Locales/ru_RU.json index ea60bd918..a2128e52e 100644 --- a/src/Ryujinx.Ava/Assets/Locales/ru_RU.json +++ b/src/Ryujinx.Ava/Assets/Locales/ru_RU.json @@ -1,12 +1,13 @@ { "Language": "Русский", "MenuBarFileOpenApplet": "Открыть апплет", - "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Открыть апплет Mii Editor в автономном режиме.", - "SettingsTabInputDirectMouseAccess": "Прямой доступ с помощью мыши", + "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Открыть апплет Mii Editor в автономном режиме", + "SettingsTabInputDirectMouseAccess": "Прямой доступ к мыши", "SettingsTabSystemMemoryManagerMode": "Режим диспетчера памяти:", "SettingsTabSystemMemoryManagerModeSoftware": "Программное обеспечение", "SettingsTabSystemMemoryManagerModeHost": "Хост (быстро)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Хост не установлен (самый быстрый, небезопасный)", + "SettingsTabSystemUseHypervisor": "Использовать Гипервизор", "MenuBarFile": "_Файл", "MenuBarFileOpenFromFile": "_Загрузить приложение из файла", "MenuBarFileOpenUnpacked": "Загрузить _Распакованную игру", @@ -25,10 +26,13 @@ "MenuBarTools": "_Инструменты", "MenuBarToolsInstallFirmware": "Установить прошивку", "MenuBarFileToolsInstallFirmwareFromFile": "Установить прошивку из XCI или ZIP", - "MenuBarFileToolsInstallFirmwareFromDirectory": "Установить прошивку из каталога", + "MenuBarFileToolsInstallFirmwareFromDirectory": "Установить прошивку из папки", + "MenuBarToolsManageFileTypes": "Управление типами файлов", + "MenuBarToolsInstallFileTypes": "Установить типы файлов", + "MenuBarToolsUninstallFileTypes": "Удалить типы файлов", "MenuBarHelp": "Помощь", - "MenuBarHelpCheckForUpdates": "Проверить обновление", - "MenuBarHelpAbout": "О", + "MenuBarHelpCheckForUpdates": "Проверка обновления", + "MenuBarHelpAbout": "О программе", "MenuSearch": "Поиск...", "GameListHeaderFavorite": "Избранные", "GameListHeaderIcon": "Значок", @@ -40,44 +44,54 @@ "GameListHeaderFileExtension": "Расширение файла", "GameListHeaderFileSize": "Размер файла", "GameListHeaderPath": "Путь", - "GameListContextMenuOpenUserSaveDirectory": "Открыть каталог сохранений пользователя", - "GameListContextMenuOpenUserSaveDirectoryToolTip": "Открывает каталог, содержащий пользовательское сохранение приложения", - "GameListContextMenuOpenDeviceSaveDirectory": "Открыть каталог пользовательских устройств", - "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "Открывает каталог, содержащий сохранение устройства приложения", - "GameListContextMenuOpenBcatSaveDirectory": "Открыть каталог пользователей BCAT", - "GameListContextMenuOpenBcatSaveDirectoryToolTip": "Открывает каталог, содержащий BCAT сохранения приложения.", - "GameListContextMenuManageTitleUpdates": "Управление обновлениями заголовков", + "GameListContextMenuOpenUserSaveDirectory": "Открыть папку сохранений пользователя", + "GameListContextMenuOpenUserSaveDirectoryToolTip": "Открывает папку, содержащую пользовательские сохранения", + "GameListContextMenuOpenDeviceSaveDirectory": "Открыть папку сохраненных устройств", + "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "Открывает папку, содержащую сохраненные устройства", + "GameListContextMenuOpenBcatSaveDirectory": "Открыть папку сохраненных BCAT", + "GameListContextMenuOpenBcatSaveDirectoryToolTip": "Открывает папку, содержащую сохраненные BCAT.", + "GameListContextMenuManageTitleUpdates": "Управление обновлениями названий", "GameListContextMenuManageTitleUpdatesToolTip": "Открывает окно управления обновлением заголовков", "GameListContextMenuManageDlc": "Управление DLC", "GameListContextMenuManageDlcToolTip": "Открывает окно управления DLC", - "GameListContextMenuOpenModsDirectory": "Открыть каталог модификаций", - "GameListContextMenuOpenModsDirectoryToolTip": "Открывает каталог, содержащий модификации приложения", + "GameListContextMenuOpenModsDirectory": "Открыть папку с модами", + "GameListContextMenuOpenModsDirectoryToolTip": "Открывает папку, содержащую моды приложений и игр", "GameListContextMenuCacheManagement": "Управление кэшем", - "GameListContextMenuCacheManagementPurgePptc": "Очистить кэш PPTC", - "GameListContextMenuCacheManagementPurgePptcToolTip": "Удаляет кэш PPTC приложения", + "GameListContextMenuCacheManagementPurgePptc": "Перестройка очереди PPTC", + "GameListContextMenuCacheManagementPurgePptcToolTip": "Запускает перестройку PPTC во время запуска следующей игры.", "GameListContextMenuCacheManagementPurgeShaderCache": "Очистить кэш шейдеров", "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Удаляет кеш шейдеров приложения", - "GameListContextMenuCacheManagementOpenPptcDirectory": "Открыть PPTC каталог", - "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Открывает каталог, содержащий PPTC кэш приложения", - "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Открыть каталог кэша шейдеров", - "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Открывает каталог, содержащий кэш шейдеров приложения", + "GameListContextMenuCacheManagementOpenPptcDirectory": "Открыть папку PPTC", + "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Открывает папку, содержащую PPTC кэш приложений и игр", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Открыть папку кэша шейдеров", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Открывает папку, содержащую кэш шейдеров приложений и игр", "GameListContextMenuExtractData": "Извлечь данные", "GameListContextMenuExtractDataExeFS": "ExeFS", - "GameListContextMenuExtractDataExeFSToolTip": "Извлеrftn раздел ExeFS из текущей конфигурации приложения (включая обновления)", + "GameListContextMenuExtractDataExeFSToolTip": "Извлечение раздела ExeFS из текущих настроек приложения (включая обновления)", "GameListContextMenuExtractDataRomFS": "RomFS", - "GameListContextMenuExtractDataRomFSToolTip": "Извлекает раздел RomFS из текущей конфигурации приложения (включая обновления)", - "GameListContextMenuExtractDataLogo": "Logo", - "GameListContextMenuExtractDataLogoToolTip": "Извлекает раздел логотипа из текущей конфигурации приложения (включая обновления)", + "GameListContextMenuExtractDataRomFSToolTip": "Извлечение раздела RomFS из текущих настроек приложения (включая обновления)", + "GameListContextMenuExtractDataLogo": "Логотип", + "GameListContextMenuExtractDataLogoToolTip": "Извлечение раздела с логотипом из текущих настроек приложения (включая обновления)", "StatusBarGamesLoaded": "{0}/{1} Игр загружено", "StatusBarSystemVersion": "Версия системы: {0}", + "LinuxVmMaxMapCountDialogTitle": "Обнаружен низкий лимит разметки памяти", + "LinuxVmMaxMapCountDialogTextPrimary": "Вы хотите увеличить значение vm.max_map_count до {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Некоторые игры могут создавать большую разметку памяти, чем разрешено на данный момент по умолчанию. Ryujinx вылетит при превышении этого лимита.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Да, до следующего перезапуска", + "LinuxVmMaxMapCountDialogButtonPersistent": "Да, постоянно", + "LinuxVmMaxMapCountWarningTextPrimary": "Максимальная разметка памяти меньше, чем рекомендуется.", + "LinuxVmMaxMapCountWarningTextSecondary": "Текущее значение vm.max_map_count ({0}) меньше, чем {1}. Некоторые игры могут попытаться создать большую разметку памяти, чем разрешено в данный момент. Ryujinx вылетит как только этот лимит будет превышен.\n\nВозможно, вы захотите вручную увеличить лимит или установить pkexec, что позволит Ryujinx помочь справиться с превышением лимита.", "Settings": "Параметры", "SettingsTabGeneral": "Пользовательский интерфейс", "SettingsTabGeneralGeneral": "Общее", - "SettingsTabGeneralEnableDiscordRichPresence": "Включить расширенное присутствие Discord", + "SettingsTabGeneralEnableDiscordRichPresence": "Включить Discord Rich Presence", "SettingsTabGeneralCheckUpdatesOnLaunch": "Проверять наличие обновлений при запуске", "SettingsTabGeneralShowConfirmExitDialog": "Показать диалоговое окно \"Подтвердить выход\"", + "SettingsTabGeneralHideCursor": "Скрыть курсор", + "SettingsTabGeneralHideCursorNever": "Никогда", "SettingsTabGeneralHideCursorOnIdle": "Скрыть курсор в режиме ожидания", - "SettingsTabGeneralGameDirectories": "Каталоги игр", + "SettingsTabGeneralHideCursorAlways": "Всегда", + "SettingsTabGeneralGameDirectories": "Папки с играми", "SettingsTabGeneralAdd": "Добавить", "SettingsTabGeneralRemove": "Удалить", "SettingsTabSystem": "Система", @@ -149,21 +163,22 @@ "SettingsTabLogging": "Журналирование", "SettingsTabLoggingLogging": "Журналирование", "SettingsTabLoggingEnableLoggingToFile": "Включить запись в файл", - "SettingsTabLoggingEnableStubLogs": "Включить журналы-заглушки", - "SettingsTabLoggingEnableInfoLogs": "Включить информационные журналы", - "SettingsTabLoggingEnableWarningLogs": "Включить журналы предупреждений", - "SettingsTabLoggingEnableErrorLogs": "Включить журналы ошибок", + "SettingsTabLoggingEnableStubLogs": "Включить журнал-заглушку", + "SettingsTabLoggingEnableInfoLogs": "Включить информационный журнал", + "SettingsTabLoggingEnableWarningLogs": "Включить журнал предупреждений", + "SettingsTabLoggingEnableErrorLogs": "Включить журнал ошибок", "SettingsTabLoggingEnableTraceLogs": "Включить журнал трассировки", "SettingsTabLoggingEnableGuestLogs": "Включить гостевые журналы", - "SettingsTabLoggingEnableFsAccessLogs": "Включить журналы доступа Fs", - "SettingsTabLoggingFsGlobalAccessLogMode": "Режим журнала глобального доступа Fs:", - "SettingsTabLoggingDeveloperOptions": "Параметры разработчика (ВНИМАНИЕ: снизит производительность)", - "SettingsTabLoggingGraphicsBackendLogLevel": "Graphics Backend Log Level:", + "SettingsTabLoggingEnableFsAccessLogs": "Включить журналы доступа файловой системы", + "SettingsTabLoggingFsGlobalAccessLogMode": "Режим журнала глобального доступа файловой системы:", + "SettingsTabLoggingDeveloperOptions": "Параметры разработчика", + "SettingsTabLoggingDeveloperOptionsNote": "ВНИМАНИЕ: Снижает производительность", + "SettingsTabLoggingGraphicsBackendLogLevel": "Уровень журнала бэкенда графики:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Ничего", "SettingsTabLoggingGraphicsBackendLogLevelError": "Ошибка", "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "Замедления", "SettingsTabLoggingGraphicsBackendLogLevelAll": "Всё", - "SettingsTabLoggingEnableDebugLogs": "Включить журналы отладки", + "SettingsTabLoggingEnableDebugLogs": "Включить журнал отладки", "SettingsTabInput": "Управление", "SettingsTabInputEnableDockedMode": "Включить режим закрепления", "SettingsTabInputDirectKeyboardAccess": "Прямой доступ с клавиатуры", @@ -187,7 +202,7 @@ "ControllerSettingsDeviceDisabled": "Отключить", "ControllerSettingsControllerType": "Тип контроллера", "ControllerSettingsControllerTypeHandheld": "Портативный", - "ControllerSettingsControllerTypeProController": "Pro Controller", + "ControllerSettingsControllerTypeProController": "Pro Контроллер", "ControllerSettingsControllerTypeJoyConPair": "JoyCon Пара", "ControllerSettingsControllerTypeJoyConLeft": "JoyCon Левый", "ControllerSettingsControllerTypeJoyConRight": "JoyCon Правый", @@ -204,30 +219,21 @@ "ControllerSettingsButtonPlus": "+", "ControllerSettingsButtonMinus": "-", "ControllerSettingsDPad": "Направляющая панель", - "ControllerSettingsDPadUp": "Верх", - "ControllerSettingsDPadDown": "Низ", - "ControllerSettingsDPadLeft": "Лево", - "ControllerSettingsDPadRight": "Право", + "ControllerSettingsDPadUp": "Вверх", + "ControllerSettingsDPadDown": "Вниз", + "ControllerSettingsDPadLeft": "Влево", + "ControllerSettingsDPadRight": "Вправо", + "ControllerSettingsStickButton": "Кнопка", + "ControllerSettingsStickUp": "Вверх", + "ControllerSettingsStickDown": "Вниз", + "ControllerSettingsStickLeft": "Влево", + "ControllerSettingsStickRight": "Вправо", + "ControllerSettingsStickStick": "Стик", + "ControllerSettingsStickInvertXAxis": "Инвертировать X ось", + "ControllerSettingsStickInvertYAxis": "Инвертировать Y ось", + "ControllerSettingsStickDeadzone": "Мёртвая зона:", "ControllerSettingsLStick": "Левый стик", - "ControllerSettingsLStickButton": "Кнопки", - "ControllerSettingsLStickUp": "Верх", - "ControllerSettingsLStickDown": "Низ", - "ControllerSettingsLStickLeft": "Лево", - "ControllerSettingsLStickRight": "Право", - "ControllerSettingsLStickStick": "Стик", - "ControllerSettingsLStickInvertXAxis": "Перевернуть стик X", - "ControllerSettingsLStickInvertYAxis": "Перевернуть стик Y", - "ControllerSettingsLStickDeadzone": "Мёртвая зона:", "ControllerSettingsRStick": "Правый стик", - "ControllerSettingsRStickButton": "Кнопки", - "ControllerSettingsRStickUp": "Верх", - "ControllerSettingsRStickDown": "Низ", - "ControllerSettingsRStickLeft": "Лево", - "ControllerSettingsRStickRight": "Право", - "ControllerSettingsRStickStick": "Стик", - "ControllerSettingsRStickInvertXAxis": "Перевернуть стик X", - "ControllerSettingsRStickInvertYAxis": "Перевернуть стик Y", - "ControllerSettingsRStickDeadzone": "Мёртвая зона:", "ControllerSettingsTriggersLeft": "Триггеры слева", "ControllerSettingsTriggersRight": "Триггеры справа", "ControllerSettingsTriggersButtonsLeft": "Триггерные кнопки слева", @@ -241,7 +247,7 @@ "ControllerSettingsLeftSR": "SR", "ControllerSettingsRightSL": "SL", "ControllerSettingsRightSR": "SR", - "ControllerSettingsExtraButtonsLeft": "Левый кнопки", + "ControllerSettingsExtraButtonsLeft": "Левые кнопки", "ControllerSettingsExtraButtonsRight": "Правые кнопки", "ControllerSettingsMisc": "Разное", "ControllerSettingsTriggerThreshold": "Порог срабатывания:", @@ -262,18 +268,19 @@ "UserProfilesAddNewProfile": "Добавить новый профиль", "UserProfilesDelete": "Удалить", "UserProfilesClose": "Закрыть", + "ProfileNameSelectionWatermark": "Выберите псевдоним", "ProfileImageSelectionTitle": "Выбор изображения профиля", "ProfileImageSelectionHeader": "Выберите изображение профиля", "ProfileImageSelectionNote": "Вы можете импортировать собственное изображение профиля или выбрать аватар из системной прошивки.", - "ProfileImageSelectionImportImage": "Импорт файла изображени", + "ProfileImageSelectionImportImage": "Импорт файла изображения", "ProfileImageSelectionSelectAvatar": "Выберите аватар прошивки", "InputDialogTitle": "Диалоговое окно ввода", - "InputDialogOk": "Да", - "InputDialogCancel": "Закрыть", + "InputDialogOk": "ОК", + "InputDialogCancel": "Отмена", "InputDialogAddNewProfileTitle": "Выберите имя профиля", "InputDialogAddNewProfileHeader": "Пожалуйста, введите имя профиля", "InputDialogAddNewProfileSubtext": "(Максимальная длина: {0})", - "AvatarChoose": "Выбор", + "AvatarChoose": "Выбор аватара", "AvatarSetBackgroundColor": "Установить цвет фона", "AvatarClose": "Закрыть", "ControllerSettingsLoadProfileToolTip": "Загрузить профиль", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Сохранить профиль", "MenuBarFileToolsTakeScreenshot": "Сделать снимок экрана", "MenuBarFileToolsHideUi": "Скрыть UI", + "GameListContextMenuRunApplication": "Запуск приложения", "GameListContextMenuToggleFavorite": "Переключить Избранное", "GameListContextMenuToggleFavoriteToolTip": "Переключить любимый статус игры", "SettingsTabGeneralTheme": "Тема", @@ -296,7 +304,7 @@ "ControllerSettingsRumbleStrongMultiplier": "Множитель сильной вибрации", "ControllerSettingsRumbleWeakMultiplier": "Множитель слабой вибрации", "DialogMessageSaveNotAvailableMessage": "Нет сохраненных данных для {0} [{1:x16}]", - "DialogMessageSaveNotAvailableCreateSaveMessage": "Хотите создать данные сохранения для этой игры?", + "DialogMessageSaveNotAvailableCreateSaveMessage": "Создать сохранение для этой игры?", "DialogConfirmationTitle": "Ryujinx - Подтверждение", "DialogUpdaterTitle": "Ryujinx - Обновление", "DialogErrorTitle": "Ryujinx - Ошибка", @@ -316,7 +324,7 @@ "DialogUpdaterConvertFailedMessage": "Не удалось преобразовать текущую версию Ryujinx.", "DialogUpdaterCancelUpdateMessage": "Отмена обновления!", "DialogUpdaterAlreadyOnLatestVersionMessage": "Вы уже используете самую последнюю версию Ryujinx!", - "DialogUpdaterFailedToGetVersionMessage": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано, если GitHub Actions компилирует новый релиз. Попробуйте ещё раз через несколько минут.", + "DialogUpdaterFailedToGetVersionMessage": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано тем, что в данный момент в GitHub Actions компилируется новый релиз. Повторите попытку позже.", "DialogUpdaterConvertFailedGithubMessage": "Не удалось преобразовать полученную версию Ryujinx из Github Release.", "DialogUpdaterDownloadingMessage": "Загрузка обновления...", "DialogUpdaterExtractionMessage": "Извлечение обновления...", @@ -325,18 +333,22 @@ "DialogUpdaterCompleteMessage": "Обновление завершено!", "DialogUpdaterRestartMessage": "Вы хотите перезапустить Ryujinx сейчас?", "DialogUpdaterArchNotSupportedMessage": "Вы используете не поддерживаемую системную архитектуру!", - "DialogUpdaterArchNotSupportedSubMessage": "(Поддерживаются только системы x64!)", - "DialogUpdaterNoInternetMessage": "Вы не подключены к Интернету!", - "DialogUpdaterNoInternetSubMessage": "Убедитесь, что у вас есть работающее подключение к Интернету!", - "DialogUpdaterDirtyBuildMessage": "Вы не можете обновить Dirty Build Ryujinx!", - "DialogUpdaterDirtyBuildSubMessage": "Загрузите Ryujinx по адресу https://ryujinx.org/ , если вам нужна поддерживаемая версия.", + "DialogUpdaterArchNotSupportedSubMessage": "(Поддерживаются только x64 системы)", + "DialogUpdaterNoInternetMessage": "Вы не подключены к интернету!", + "DialogUpdaterNoInternetSubMessage": "Убедитесь, что у вас есть работающее подключение к интернету!", + "DialogUpdaterDirtyBuildMessage": "Вы не можете обновить Dirty Build!", + "DialogUpdaterDirtyBuildSubMessage": "Загрузите Ryujinx по адресу https://ryujinx.org/ если вам нужна поддерживаемая версия.", "DialogRestartRequiredMessage": "Требуется перезагрузка", - "DialogThemeRestartMessage": "Тема сохранена. Для применения темы требуется перезагрузка.", + "DialogThemeRestartMessage": "Тема сохранена. Для применения темы требуется перезапуск.", "DialogThemeRestartSubMessage": "Вы хотите перезапустить?", "DialogFirmwareInstallEmbeddedMessage": "Хотите установить прошивку, встроенную в эту игру? (Прошивка {0})", - "DialogFirmwareInstallEmbeddedSuccessMessage": "Установленная прошивка не найдена, но Ryujinx удалось установить прошивку {0} из предоставленной игры.\nЭмулятор запустится.", + "DialogFirmwareInstallEmbeddedSuccessMessage": "Установленная прошивка не найдена, но Ryujinx удалось установить прошивку {0} из предоставленной игры.\nТеперь эмулятор запустится.", "DialogFirmwareNoFirmwareInstalledMessage": "Прошивка не установлена", "DialogFirmwareInstalledMessage": "Прошивка {0} была установлена", + "DialogInstallFileTypesSuccessMessage": "Успешно установлены типы файлов!", + "DialogInstallFileTypesErrorMessage": "Не удалось установить типы файлов.", + "DialogUninstallFileTypesSuccessMessage": "Успешно удалены типы файлов!", + "DialogUninstallFileTypesErrorMessage": "Не удалось удалить типы файлов.", "DialogOpenSettingsWindowLabel": "Открыть окно настроек", "DialogControllerAppletTitle": "Апплет контроллера", "DialogMessageDialogErrorExceptionMessage": "Ошибка отображения диалогового окна сообщений: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Версия системы {0} успешно установлена.", "DialogUserProfileDeletionWarningMessage": "Если выбранный профиль будет удален, другие профили не будут открываться.", "DialogUserProfileDeletionConfirmMessage": "Вы хотите удалить выбранный профиль", + "DialogUserProfileUnsavedChangesTitle": "Внимание - Несохраненные изменения", + "DialogUserProfileUnsavedChangesMessage": "Вы внесли изменения в этот профиль пользователя которые не были сохранены.", + "DialogUserProfileUnsavedChangesSubMessage": "Вы хотите отменить изменения?", "DialogControllerSettingsModifiedConfirmMessage": "Текущие настройки контроллера обновлены.", "DialogControllerSettingsModifiedConfirmSubMessage": "Вы хотите сохранить?", "DialogLoadNcaErrorMessage": "{0}. Файл с ошибкой: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Включить все", "DlcManagerDisableAllButton": "Отключить все", "MenuBarOptionsChangeLanguage": "Изменить язык", + "MenuBarShowFileTypes": "Показать типы файлов", "CommonSort": "Сортировать", "CommonShowNames": "Показать названия", "CommonFavorite": "Избранные", @@ -423,68 +439,69 @@ "OrderDescending": "По убыванию", "SettingsTabGraphicsFeatures": "Функции", "ErrorWindowTitle": "Окно ошибки", - "ToggleDiscordTooltip": "Включает или отключает Discord Rich Presenc", - "AddGameDirBoxTooltip": "Введите каталог игры, чтобы добавить его в список", + "ToggleDiscordTooltip": "Включает или отключает отображение в Discord статуса \"Сейчас играет\"", + "AddGameDirBoxTooltip": "Введите папку игры для добавления в список", "AddGameDirTooltip": "AДобавить папку с игрой в список", - "RemoveGameDirTooltip": "Удалить выбранный каталог игры", + "RemoveGameDirTooltip": "Удалить выбранную папку игры", "CustomThemeCheckTooltip": "Включить или отключить пользовательские темы в графическом интерфейсе", - "CustomThemePathTooltip": "Путь к пользовательской теме графического интерфейса", - "CustomThemeBrowseTooltip": "Обзор пользовательской темы графического интерфейса", - "DockModeToggleTooltip": "Включить или отключить режим закрепления", + "CustomThemePathTooltip": "Путь к пользовательской теме интерфейса", + "CustomThemeBrowseTooltip": "Просмотр пользовательской темы интерфейса", + "DockModeToggleTooltip": "\"Стационарный\" режим запускает эмулятор, как если бы Nintendo Switch находилась в доке, что улучшает графику и разрешение в большинстве игр. И наоборот, при отключении этого режима эмулятор будет запускать игры в \"Портативном\" режиме, снижая качество графики.\n\nНастройте управление для Игрока 1 если планируете использовать в \"Стационарном\" режиме; настройте портативное управление если планируете использовать эмулятор в \"Портативном\" режиме.\n\nОставьте включенным если не уверены.", "DirectKeyboardTooltip": "Включить или отключить «поддержку прямого доступа к клавиатуре (HID)» (предоставляет играм доступ к клавиатуре как к устройству ввода текста)", "DirectMouseTooltip": "Включить или отключить «поддержку прямого доступа к мыши (HID)» (предоставляет играм доступ к вашей мыши как указывающему устройству)", - "RegionTooltip": "Изменяет регион системы", - "LanguageTooltip": "Изменяет язык системы", - "TimezoneTooltip": "Изменяет часовой пояс системы", - "TimeTooltip": "Изменяет системное время", - "VSyncToggleTooltip": "Включает или отключает Вертикальную Синхронизацию", - "PptcToggleTooltip": "Включает или отключает PPTC", - "FsIntegrityToggleTooltip": "Включает проверку целостности файлов содержимого игры.", - "AudioBackendTooltip": "Изменяет аудио-бэкэнд", - "MemoryManagerTooltip": "Изменяет способ отображения и доступа к гостевой памяти. Сильно влияет на производительность эмулируемого процессора.", - "MemoryManagerSoftwareTooltip": "Использует таблицу страниц программного обеспечения для преобразования адресов. Самая высокая точность, но самая медленная производительность.", - "MemoryManagerHostTooltip": "Непосредственное отображение памяти в адресном пространстве хоста. Значительно более быстрая JIT-компиляция и выполнение.", - "MemoryManagerUnsafeTooltip": "Напрямую сопоставляет память, но не маскируйте адрес в гостевом адресном пространстве перед доступом. Быстрее, но ценой безопасности. Гостевое приложение может получить доступ к памяти из любой точки Ryujinx, поэтому в этом режиме запускайте только те программы, которым вы доверяете.", - "DRamTooltip": "Увеличивает объем памяти в эмулируемой системе с 4 ГБ до 6 ГБ.", - "IgnoreMissingServicesTooltip": "Включает или отключает параметр игнорирования отсутствующих служб", - "GraphicsBackendThreadingTooltip": "Включает многопоточность графического бэкенда", - "GalThreadingTooltip": "Выполняет команды графического бэкэнда во втором потоке. Обеспечивает многопоточность компиляции шейдеров во время выполнения, уменьшает заикание и повышает производительность драйверов без собственной поддержки многопоточности. Немного различается пиковая производительность на драйверах с многопоточностью. Ryujinx может потребоваться перезапустить, чтобы правильно отключить встроенную многопоточность драйвера, или вам может потребоваться сделать это вручную, чтобы получить максимальную производительность.", - "ShaderCacheToggleTooltip": "Включает или отключает кэш шейдеров", - "ResolutionScaleTooltip": "Масштаб разрешения, применяемый к применимым целям рендеринга", - "ResolutionScaleEntryTooltip": "Шкала разрешения с плавающей запятой, например 1,5. Неинтегральные весы с большей вероятностью вызовут проблемы или сбои.", - "AnisotropyTooltip": "Уровень анизотропной фильтрации (установите значение «Авто», чтобы использовать значение, запрошенное игрой)", - "AspectRatioTooltip": "Соотношение сторон, применяемое к окну рендерера.", + "RegionTooltip": "Изменение региона системы", + "LanguageTooltip": "Изменение языка системы", + "TimezoneTooltip": "Изменение часового пояса системы", + "TimeTooltip": "Изменение системного времени", + "VSyncToggleTooltip": "Эмуляция вертикальной синхронизации консоли, которая ограничивает количество кадров в секунду в большинстве игр; отключение может привести к тому, что игры будут запущены с более высокой частотой кадров, но загрузка игры может занять больше времени, либо игра не запустится вообще.\n\nМожно включать и выключать эту настройку непосредственно в игре с помощью горячих клавиш. Если планируете отключить вериткальную синхронизацию, мы рекомендуем настроить горячие клавиши.\n\nРекомендуется оставить включенным.", + "PptcToggleTooltip": "Сохранение преобразованных JIT-функций таким образом, чтобы их не нужно преобразовывать по новой каждый раз при загрузке игры.\n\nУменьшает статтеры и значительно ускоряет последующую загрузку игр.\n\nРекомендуется оставить включенным.", + "FsIntegrityToggleTooltip": "Проверяет поврежденные файлы при загрузке игры и если поврежденные файлы обнаружены, отображает ошибку о поврежденном хэше в журнале.\n\nНе влияет на производительность и необходим для содействия в устранении неполадок.\n\nРекомендуется оставить включенным.", + "AudioBackendTooltip": "Изменяет используемый аудио-бэкенд для рендера звука.\n\nSDL2 является предпочтительным, в то время как OpenAL и SoundIO используются в качестве резервных. При выборе \"Заглушки\" звук будет отсутствовать.\n\nРекомендуется использование SDL2.", + "MemoryManagerTooltip": "Изменение разметки и доступа к гостевой памяти. Значительно влияет на производительность процессора.\n\nРекомендуется оставить \"Хост не установлен\"", + "MemoryManagerSoftwareTooltip": "Использует таблицу страниц для преобразования адресов. Самая высокая точность, но самая низкая производительность.", + "MemoryManagerHostTooltip": "Прямая разметка памяти в адресном пространстве хоста. Значительно более быстрая JIT-компиляция и запуск.", + "MemoryManagerUnsafeTooltip": "Производит прямую разметку памяти, но не маскирует адрес в гостевом адресном пространстве перед получением доступа. Быстрее, но менее безопасно. Гостевое приложение может получить доступ к памяти из любой точки Ryujinx, поэтому в этом режиме рекомендуется запускать только те программы, которым вы доверяете.", + "UseHypervisorTooltip": "Использует Гипервизор вместо JIT. Значительно увеличивает производительность, но может быть работать нестабильно.", + "DRamTooltip": "Использует альтернативный макет MemoryMode для имитации использования Nintendo Switch для разработчика.\n\nПолезно только для пакетов текстур с высоким разрешением или модов добавляющих разрешение 4К. Не улучшает производительность.\n\nРекомендуется оставить выключенным.", + "IgnoreMissingServicesTooltip": "Игнорирует нереализованные сервисы Horizon OS. Это поможет избежать вылеты при загрузке определенных игр.\n\nРекомендуется оставить выключенным.", + "GraphicsBackendThreadingTooltip": "Выполняет команды графического бэкенда на втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах GPU без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить в Авто.", + "GalThreadingTooltip": "Выполняет команды графического бэкенда на во втором потоке.\n\nУскоряет компиляцию шейдеров, уменьшает статтеры и повышает производительность на драйверах GPU без поддержки многопоточности. Производительность на драйверах с многопоточностью немного выше.\n\nРекомендуется оставить в Авто.", + "ShaderCacheToggleTooltip": "Сохраняет кэш шейдеров на диске, который уменьшает статтеры при последующих запусках.\n\nРекомендуется оставить включенным.", + "ResolutionScaleTooltip": "Масштабирование разрешения", + "ResolutionScaleEntryTooltip": "Масштабирование разрешения с плавающей запятой, например 1,5. Неинтегральное масштабирование с большой вероятностью вызовет сбои в работе.", + "AnisotropyTooltip": "Уровень анизотропной фильтрации (установите значение «Авто», чтобы использовать значение в игре по умолчанию)", + "AspectRatioTooltip": "Соотношение сторон, применяемое к окну.", "ShaderDumpPathTooltip": "Путь дампа графических шейдеров", - "FileLogTooltip": "Включает или отключает ведение журнала в файл на диске", - "StubLogTooltip": "Включает печать сообщений журнала-заглушки", - "InfoLogTooltip": "Включает печать сообщений информационного журнала", - "WarnLogTooltip": "Включает печать сообщений журнала предупреждений", - "ErrorLogTooltip": "Включает печать сообщений журнала ошибок", + "FileLogTooltip": "Включает или отключает ведение журнала в файл на диске. Не влияет на производительность.", + "StubLogTooltip": "Включает ведение журнала-заглушки. Не влияет на производительность.", + "InfoLogTooltip": "Включает печать сообщений информационного журнала. Не влияет на производительность.", + "WarnLogTooltip": "Включает печать сообщений журнала предупреждений. Не влияет на производительность.", + "ErrorLogTooltip": "Включает печать сообщений журнала ошибок. Не влияет на производительность.", "TraceLogTooltip": "Выводит сообщения журнала трассировки в консоли. Не влияет на производительность.", - "GuestLogTooltip": "Включает печать сообщений гостевого журнала", + "GuestLogTooltip": "Включает печать сообщений гостевого журнала. Не влияет на производительность.", "FileAccessLogTooltip": "Включает печать сообщений журнала доступа к файлам", - "FSAccessLogModeTooltip": "Включает вывод журнала доступа к FS на консоль. Возможные режимы 0-3", + "FSAccessLogModeTooltip": "Включает вывод журнала доступа к файловой системе. Возможные режимы: 0-3", "DeveloperOptionTooltip": "Используйте с осторожностью", "OpenGlLogLevel": "Требует включения соответствующих уровней ведения журнала", - "DebugLogTooltip": "Включает печать сообщений журнала отладки", - "LoadApplicationFileTooltip": "Загружает средство выбора файлов, чтобы выбрать файл, совместимый с Switch, для загрузки", - "LoadApplicationFolderTooltip": "Загружает средство выбора файлов, чтобы выбрать распакованное приложение, совместимое с Switch, для загрузки", + "DebugLogTooltip": "Выводит журнал сообщений отладки в консоли.\n\nИспользуйте только в случае просьбы разработчика, так как включение этой функции затруднит чтение журналов и ухудшит работу эмулятора.", + "LoadApplicationFileTooltip": "Открыть файловый менеджер для выбора файла, совместимого с Nintendo Switch.", + "LoadApplicationFolderTooltip": "Открыть файловый менеджер для выбора распакованного приложения, совместимого с Nintendo Switch.", "OpenRyujinxFolderTooltip": "Открывает папку файловой системы Ryujinx. ", "OpenRyujinxLogsTooltip": "Открывает папку, в которую записываются журналы", - "ExitTooltip": "Выходит из Ryujinx", - "OpenSettingsTooltip": "Открывает окно настроек", - "OpenProfileManagerTooltip": "Открывает окно диспетчера профилей пользователей", - "StopEmulationTooltip": "Останавливает эмуляцию текущей игры и вовращение к выбору игры", - "CheckUpdatesTooltip": "Проверяет наличие обновлений Ryujinx", - "OpenAboutTooltip": "Открывает окно «О программе»", + "ExitTooltip": "Выйти из Ryujinx", + "OpenSettingsTooltip": "Открыть окно настроек", + "OpenProfileManagerTooltip": "Открыть диспетчер профилей", + "StopEmulationTooltip": "Остановка эмуляции текущей игры и возврат к списку игр", + "CheckUpdatesTooltip": "Проверка наличия обновления Ryujinx", + "OpenAboutTooltip": "Открыть окно «О программе»", "GridSize": "Размер сетки", "GridSizeTooltip": "Изменение размера элементов сетки", "SettingsTabSystemSystemLanguageBrazilianPortuguese": "Португальский язык (Бразилия)", "AboutRyujinxContributorsButtonHeader": "Посмотреть всех участников", "SettingsTabSystemAudioVolume": "Громкость: ", "AudioVolumeTooltip": "Изменяет громкость звука", - "SettingsTabSystemEnableInternetAccess": "Включить гостевой доступ в Интернет", - "EnableInternetAccessTooltip": "Включает гостевой доступ в Интернет. Если этот параметр включен, приложение будет вести себя так, как если бы эмулированная консоль Switch была подключена к Интернету. Обратите внимание, что в некоторых случаях приложения могут по-прежнему получать доступ к Интернету, даже если эта опция отключена.", + "SettingsTabSystemEnableInternetAccess": "Включить гостевой доступ в Интернет/сетевой режим", + "EnableInternetAccessTooltip": "Позволяет эмулированному приложению подключаться к Интернету.\n\nПри включении этой функции игры с возможностью сетевой игры могут подключаться друг к другу, если все эмуляторы (или реальные консоли) подключены к одной и той же точке доступа.\n\nНЕ разрешает подключение к серверам Nintendo. Может вызвать сбой в некоторых играх, которые пытаются подключиться к Интернету.\n\nРекомендутеся оставить выключенным.", "GameListContextMenuManageCheatToolTip": "Управление читами", "GameListContextMenuManageCheat": "Управление читами", "ControllerSettingsStickRange": "Диапазон:", @@ -497,118 +514,143 @@ "SettingsTabCpuCache": "Кэш ЦП", "SettingsTabCpuMemory": "Память ЦП", "DialogUpdaterFlatpakNotSupportedMessage": "Пожалуйста, обновите Ryujinx через FlatHub.", - "UpdaterDisabledWarningTitle": "Updater Disabled!", - "GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory", - "GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.", - "ControllerSettingsRotate90": "Rotate 90° Clockwise", - "IconSize": "Icon Size", - "IconSizeTooltip": "Change the size of game icons", - "MenuBarOptionsShowConsole": "Открыть консоль", - "ShaderCachePurgeError": "Error purging shader cache at {0}: {1}", - "UserErrorNoKeys": "Keys not found", + "UpdaterDisabledWarningTitle": "Обновление выключено!", + "GameListContextMenuOpenSdModsDirectory": "Открыть папку с модами Atmosphere", + "GameListContextMenuOpenSdModsDirectoryToolTip": "Открывает альтернативную папку SD-карты Atmosphere, которая содержит моды для приложений и игр. Полезно для модов, сделанных для реальной консоли.", + "ControllerSettingsRotate90": "Повернуть на 90° по часовой стрелке", + "IconSize": "Размер иконки", + "IconSizeTooltip": "Изменить размер игровых иконок", + "MenuBarOptionsShowConsole": "Показать консоль", + "ShaderCachePurgeError": "Ошибка очистки кэша шейдеров в {0}: {1}", + "UserErrorNoKeys": "Ключи не найдены", "UserErrorNoFirmware": "Прошивка не найдена", - "UserErrorFirmwareParsingFailed": "Firmware parsing error", + "UserErrorFirmwareParsingFailed": "Ошибка извлечения прошивки", "UserErrorApplicationNotFound": "Приложение не найдено", "UserErrorUnknown": "Неизвестная ошибка", "UserErrorUndefined": "Неопределенная ошибка", - "UserErrorNoKeysDescription": "Ryujinx was unable to find your 'prod.keys' file", - "UserErrorNoFirmwareDescription": "Ryujinx was unable to find any firmwares installed", - "UserErrorFirmwareParsingFailedDescription": "Ryujinx was unable to parse the provided firmware. This is usually caused by outdated keys.", - "UserErrorApplicationNotFoundDescription": "Ryujinx couldn't find a valid application at the given path.", + "UserErrorNoKeysDescription": "Ryujinx не удалось найти ваш 'prod.keys' файл", + "UserErrorNoFirmwareDescription": "Ryujinx не удалось найти ни одной установленной прошивки", + "UserErrorFirmwareParsingFailedDescription": "Ryujinx не удалось распаковать выбранную прошивку. Обычно это вызвано устаревшими ключами.", + "UserErrorApplicationNotFoundDescription": "Ryujinx не удалось найти действительное приложение по указанному пути.", "UserErrorUnknownDescription": "Произошла неизвестная ошибка!", "UserErrorUndefinedDescription": "Произошла неизвестная ошибка! Такого не должно происходить. Пожалуйста, свяжитесь с разработчиками!", - "OpenSetupGuideMessage": "Open the Setup Guide", - "NoUpdate": "No Update", + "OpenSetupGuideMessage": "Открыть руководство по установке", + "NoUpdate": "Нет обновлений", "TitleUpdateVersionLabel": "Version {0} - {1}", - "RyujinxInfo": "Ryujinx - Info", - "RyujinxConfirm": "Ryujinx - Confirmation", + "RyujinxInfo": "Ryujinx - Информация", + "RyujinxConfirm": "Ryujinx - Подтверждение", "FileDialogAllTypes": "Все типы", "Never": "Никогда", - "SwkbdMinCharacters": "Must be at least {0} characters long", - "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long", - "SoftwareKeyboard": "Software Keyboard", - "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n", + "SwkbdMinCharacters": "Должно быть не менее {0} символов.", + "SwkbdMinRangeCharacters": "Должно быть {0}-{1} символов", + "SoftwareKeyboard": "Программная клавиатура", + "SoftwareKeyboardModeNumbersOnly": "Должны быть только цифры", + "SoftwareKeyboardModeAlphabet": "Не должно быть CJK-символов", + "SoftwareKeyboardModeASCII": "Текст должен быть только в ASCII кодировке", + "DialogControllerAppletMessagePlayerRange": "Приложение запрашивает {0} игроков с:\n\nТИПЫ: {1}\n\nИГРОКИ: {2}\n\n{3}Пожалуйста, откройте \"Настройки\" и перенастройте сейчас или нажмите \"Закрыть\".", + "DialogControllerAppletMessage": "Приложение запрашивает ровно {0} игроков с:\n\nТИПЫ: {1}\n\nИГРОКИ: {2}\n\n{3}Пожалуйста, откройте \"Настройки\" и перенастройте Ввод или нажмите \"Закрыть\".", + "DialogControllerAppletDockModeSet": "Установлен стационарный режим. Портативный режим недоступен.", "UpdaterRenaming": "Переименование старых файлов...", - "UpdaterRenameFailed": "Updater was unable to rename file: {0}", + "UpdaterRenameFailed": "Программе обновления не удалось переименовать файл: {0}", "UpdaterAddingFiles": "Добавление новых файлов...", "UpdaterExtracting": "Извлечение обновления...", "UpdaterDownloading": "Загрузка обновления...", "Game": "Игра", - "Docked": "Docked", - "Handheld": "Handheld", - "ConnectionError": "Connection Error.", - "AboutPageDeveloperListMore": "{0} and more...", + "Docked": "Стационарный режим", + "Handheld": "Портативный режим", + "ConnectionError": "Ошибка соединения!", + "AboutPageDeveloperListMore": "{0} и больше...", "ApiError": "Ошибка API.", - "LoadingHeading": "Loading {0}", - "CompilingPPTC": "Compiling PTC", - "CompilingShaders": "Компилируем шейдеры", + "LoadingHeading": "Загрузка {0}", + "CompilingPPTC": "Компиляция PTC", + "CompilingShaders": "Компиляция шейдеров", "AllKeyboards": "Все клавиатуры", - "OpenFileDialogTitle": "Select a supported file to open", - "OpenFolderDialogTitle": "Select a folder with an unpacked game", + "OpenFileDialogTitle": "Выберите совместимый файл для открытия", + "OpenFolderDialogTitle": "Выберите папку с распакованной игрой", "AllSupportedFormats": "Все поддерживаемые форматы", - "RyujinxUpdater": "Ryujinx Updater", - "SettingsTabHotkeys": "Keyboard Hotkeys", - "SettingsTabHotkeysHotkeys": "Keyboard Hotkeys", - "SettingsTabHotkeysToggleVsyncHotkey": "Toggle VSync:", + "RyujinxUpdater": "Ryujinx - Обновление", + "SettingsTabHotkeys": "Горячие клавиши", + "SettingsTabHotkeysHotkeys": "Горячие клавиши", + "SettingsTabHotkeysToggleVsyncHotkey": "Переключить VSync:", "SettingsTabHotkeysScreenshotHotkey": "Скриншот:", "SettingsTabHotkeysShowUiHotkey": "Показать UI:", - "SettingsTabHotkeysPauseHotkey": "Pause:", - "SettingsTabHotkeysToggleMuteHotkey": "Mute:", - "ControllerMotionTitle": "Motion Control Settings", - "ControllerRumbleTitle": "Rumble Settings", - "SettingsSelectThemeFileDialogTitle": "Select Theme File", - "SettingsXamlThemeFile": "Xaml Theme File", - "AvatarWindowTitle": "Manage Accounts - Avatar", + "SettingsTabHotkeysPauseHotkey": "Пауза:", + "SettingsTabHotkeysToggleMuteHotkey": "Приглушить:", + "ControllerMotionTitle": "Настройки управления движением", + "ControllerRumbleTitle": "Настройки вибрации", + "SettingsSelectThemeFileDialogTitle": "Выбрать файл темы", + "SettingsXamlThemeFile": "Файл темы Xaml", + "AvatarWindowTitle": "Управление аккаунтами - Аватар", "Amiibo": "Amiibo", - "Unknown": "Unknown", - "Usage": "Usage", - "Writable": "Writable", + "Unknown": "Неизвестно", + "Usage": "Применение", + "Writable": "Доступно для записи", "SelectDlcDialogTitle": "Выберите файлы DLC", "SelectUpdateDialogTitle": "Выберите файлы обновления", - "UserProfileWindowTitle": "User Profiles Manager", - "CheatWindowTitle": "Cheats Manager", - "DlcWindowTitle": "Downloadable Content Manager", - "UpdateWindowTitle": "Title Update Manager", - "CheatWindowHeading": "Cheats Available for {0} [{1}]", - "DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", - "UserProfilesEditProfile": "Edit Selected", - "Cancel": "Cancel", + "UserProfileWindowTitle": "Менеджер профилей пользователей", + "CheatWindowTitle": "Менеджер читов", + "DlcWindowTitle": "Управление загружаемым контентом для {0} ({1})", + "UpdateWindowTitle": "Менеджер обновления названий", + "CheatWindowHeading": "Читы доступны для {0} [{1}]", + "BuildId": "ID версии:", + "DlcWindowHeading": "{0} Загружаемый контент", + "UserProfilesEditProfile": "Изменить выбранные", + "Cancel": "Отмена", "Save": "Сохранить", - "Discard": "Discard", - "UserProfilesSetProfileImage": "Set Profile Image", - "UserProfileEmptyNameError": "Name is required", - "UserProfileNoImageError": "Profile image must be set", - "GameUpdateWindowHeading": "{0} Update(s) available for {1} ({2})", + "Discard": "Отменить", + "UserProfilesSetProfileImage": "Установить изображение профиля", + "UserProfileEmptyNameError": "Имя обязательно", + "UserProfileNoImageError": "Изображение профиля должно быть установлено", + "GameUpdateWindowHeading": "Обновление доступно для {0} ({1})", "SettingsTabHotkeysResScaleUpHotkey": "Увеличить разрешение:", "SettingsTabHotkeysResScaleDownHotkey": "Уменьшить разрешение:", - "UserProfilesName": "Name:", - "UserProfilesUserId": "User Id:", - "SettingsTabGraphicsBackend": "Graphics Backend", - "SettingsTabGraphicsBackendTooltip": "Graphics Backend to use", + "UserProfilesName": "Имя:", + "UserProfilesUserId": "ID пользователя:", + "SettingsTabGraphicsBackend": "Бэкенд графики", + "SettingsTabGraphicsBackendTooltip": "Использовать графический бэкенд", "SettingsEnableTextureRecompression": "Включить пережатие текстур", - "SettingsEnableTextureRecompressionTooltip": "Сжимает некоторые текстуры для уменьшения использования видеопамяти.\n\nРекомендуется для ГП с 4 ГиБ видеопамяти и менее.\n\nЕсли не уверены, оставьте ВЫКЛ.", - "SettingsTabGraphicsPreferredGpu": "Preferred GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "Select the graphics card that will be used with the Vulkan graphics backend.\n\nDoes not affect the GPU that OpenGL will use.\n\nSet to the GPU flagged as \"dGPU\" if unsure. If there isn't one, leave untouched.", - "SettingsAppRequiredRestartMessage": "Ryujinx Restart Required", - "SettingsGpuBackendRestartMessage": "Graphics Backend or GPU settings have been modified. This will require a restart to be applied", - "SettingsGpuBackendRestartSubMessage": "Do you want to restart now?", + "SettingsEnableTextureRecompressionTooltip": "Сжимает некоторые текстуры для уменьшения использования видеопамяти.\n\nРекомендуется для GPU с 4 гб видеопамяти и менее.\n\nРекомендуется оставить выключенным.", + "SettingsTabGraphicsPreferredGpu": "Предпочтительный GPU", + "SettingsTabGraphicsPreferredGpuTooltip": "Выберите видеокарту, которая будет использоваться с графическим бэкендом Vulkan.\n\nНе влияет на GPU, который будет использовать OpenGL.\n\nУстановите графический процессор, помеченный как \"dGPU\", если вы не уверены. Если его нет, оставьте нетронутым.", + "SettingsAppRequiredRestartMessage": "Требуется перезапуск Ryujinx", + "SettingsGpuBackendRestartMessage": "Графический бэкенд или настройки графического процессора были изменены. Требуется перезапуск для вступления в силу изменений.", + "SettingsGpuBackendRestartSubMessage": "Перезапустить сейчас?", "RyujinxUpdaterMessage": "Вы хотите обновить Ryujinx до последней версии?", "SettingsTabHotkeysVolumeUpHotkey": "Увеличить громкость:", "SettingsTabHotkeysVolumeDownHotkey": "Уменьшить громкость:", - "SettingsEnableMacroHLE": "Enable Macro HLE", - "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", - "VolumeShort": "Vol", - "UserProfilesManageSaves": "Manage Saves", - "DeleteUserSave": "Do you want to delete user save for this game?", + "SettingsEnableMacroHLE": "Включить Macro HLE", + "SettingsEnableMacroHLETooltip": "Высокоуровневая эмуляции макроса GPU.\n\nПовышает производительность, но может вызывать графические сбои в некоторых играх.\n\nРекомендуется оставить включенным.", + "SettingsEnableColorSpacePassthrough": "Пропуск цветового пространства", + "SettingsEnableColorSpacePassthroughTooltip": "Направляет бэкэнд Vulkan на передачу информации о цвете без указания цветового пространства. Для пользователей с экранами с расширенной гаммой данная настройка приводит к получению более ярких цветов за счет снижения корректности цветопередачи.", + "VolumeShort": "Громкость", + "UserProfilesManageSaves": "Управление сохранениями", + "DeleteUserSave": "Вы хотите удалить сохранение пользователя для этой игры?", "IrreversibleActionNote": "Данное действие является необратимым.", - "SaveManagerHeading": "Manage Saves for {0}", - "SaveManagerTitle": "Save Manager", + "SaveManagerHeading": "Редактирование сохранений для {0} ({1})", + "SaveManagerTitle": "Менеджер сохранений", "Name": "Название", "Size": "Размер", - "Search": "Search", - "UserProfilesRecoverLostAccounts": "Recover Lost Accounts", - "Recover": "Recover", - "UserProfilesRecoverHeading": "Saves were found for the following accounts" -} + "Search": "Поиск", + "UserProfilesRecoverLostAccounts": "Восстановить утерянные аккаунты", + "Recover": "Восстановление", + "UserProfilesRecoverHeading": "Были найдены сохранения для следующих аккаунтов", + "UserProfilesRecoverEmptyList": "Нет профилей для восстановления", + "GraphicsAATooltip": "Применяет сглаживание к рейдеру игры.", + "GraphicsAALabel": "Сглаживание:", + "GraphicsScalingFilterLabel": "Масштабирующий фильтр:", + "GraphicsScalingFilterTooltip": "Включает масштабирование кадрового буфера", + "GraphicsScalingFilterLevelLabel": "Уровень", + "GraphicsScalingFilterLevelTooltip": "Установить уровень фильтра масштабирования", + "SmaaLow": "SMAA Низкое", + "SmaaMedium": "SMAA Среднее", + "SmaaHigh": "SMAA Высокое", + "SmaaUltra": "SMAA Ультра", + "UserEditorTitle": "Редактирование пользователя", + "UserEditorTitleCreate": "Создание пользователя", + "SettingsTabNetworkInterface": "Сетевой Интерфейс", + "NetworkInterfaceTooltip": "Сетевой интерфейс, используемый для функций LAN", + "NetworkInterfaceDefault": "По умолчанию", + "PackagingShaders": "Упаковка шейдеров", + "AboutChangelogButton": "Список изменений на GitHub", + "AboutChangelogButtonTooltipMessage": "Нажмите, чтобы открыть список изменений для этой версии в браузере." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/tr_TR.json b/src/Ryujinx.Ava/Assets/Locales/tr_TR.json index decc3cfd6..3f70a781d 100644 --- a/src/Ryujinx.Ava/Assets/Locales/tr_TR.json +++ b/src/Ryujinx.Ava/Assets/Locales/tr_TR.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "Yazılım", "SettingsTabSystemMemoryManagerModeHost": "Host (hızlı)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Unchecked (en hızlısı, tehlikeli)", + "SettingsTabSystemUseHypervisor": "Hypervisor Kullan", "MenuBarFile": "_Dosya", "MenuBarFileOpenFromFile": "_Dosyadan Uygulama Aç", "MenuBarFileOpenUnpacked": "_Sıkıştırılmamış Oyun Aç", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "Yazılım Yükle", "MenuBarFileToolsInstallFirmwareFromFile": "XCI veya ZIP'ten Yazılım Yükle", "MenuBarFileToolsInstallFirmwareFromDirectory": "Bir Dizin Üzerinden Yazılım Yükle", + "MenuBarToolsManageFileTypes": "Dosya uzantılarını yönet", + "MenuBarToolsInstallFileTypes": "Dosya uzantılarını yükle", + "MenuBarToolsUninstallFileTypes": "Dosya uzantılarını kaldır", "MenuBarHelp": "Yardım", "MenuBarHelpCheckForUpdates": "Güncellemeleri Denetle", "MenuBarHelpAbout": "Hakkında", @@ -66,17 +70,27 @@ "GameListContextMenuExtractDataExeFSToolTip": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)", "GameListContextMenuExtractDataRomFS": "RomFS", "GameListContextMenuExtractDataRomFSToolTip": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil)", - "GameListContextMenuExtractDataLogo": "Logo", + "GameListContextMenuExtractDataLogo": "Simge", "GameListContextMenuExtractDataLogoToolTip": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil)", "StatusBarGamesLoaded": "{0}/{1} Oyun Yüklendi", "StatusBarSystemVersion": "Sistem Sürümü: {0}", + "LinuxVmMaxMapCountDialogTitle": "Bellek Haritaları İçin Düşük Limit Tespit Edildi ", + "LinuxVmMaxMapCountDialogTextPrimary": "vm.max_map_count değerini {0} sayısına yükseltmek ister misiniz", + "LinuxVmMaxMapCountDialogTextSecondary": "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.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Evet, bir sonraki yeniden başlatmaya kadar", + "LinuxVmMaxMapCountDialogButtonPersistent": "Evet, kalıcı olarak", + "LinuxVmMaxMapCountWarningTextPrimary": "İzin verilen maksimum bellek haritası değeri tavsiye edildiğinden daha düşük. ", + "LinuxVmMaxMapCountWarningTextSecondary": "Ş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.", "Settings": "Ayarlar", "SettingsTabGeneral": "Kullancı Arayüzü", "SettingsTabGeneralGeneral": "Genel", "SettingsTabGeneralEnableDiscordRichPresence": "Discord Zengin İçerik'i Etkinleştir", "SettingsTabGeneralCheckUpdatesOnLaunch": "Her Açılışta Güncellemeleri Denetle", "SettingsTabGeneralShowConfirmExitDialog": "\"Çıkışı Onayla\" Diyaloğunu Göster", - "SettingsTabGeneralHideCursorOnIdle": "Hareketsizlik durumunda imleci gizle", + "SettingsTabGeneralHideCursor": "İşaretçiyi Gizle:", + "SettingsTabGeneralHideCursorNever": "Hiçbir Zaman", + "SettingsTabGeneralHideCursorOnIdle": "Hareketsiz Durumda", + "SettingsTabGeneralHideCursorAlways": "Her Zaman", "SettingsTabGeneralGameDirectories": "Oyun Dizinleri", "SettingsTabGeneralAdd": "Ekle", "SettingsTabGeneralRemove": "Kaldır", @@ -110,7 +124,7 @@ "SettingsTabSystemSystemLanguageTraditionalChinese": "Geleneksel Çince", "SettingsTabSystemSystemTimeZone": "Sistem Saat Dilimi:", "SettingsTabSystemSystemTime": "Sistem Saati:", - "SettingsTabSystemEnableVsync": "VSync", + "SettingsTabSystemEnableVsync": "Dikey Eşitleme", "SettingsTabSystemEnablePptc": "PPTC (Profilli Sürekli Çeviri Önbelleği)", "SettingsTabSystemEnableFsIntegrityChecks": "FS Bütünlük Kontrolleri", "SettingsTabSystemAudioBackend": "Ses Motoru:", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Fs Erişim Loglarını Etkinleştir", "SettingsTabLoggingFsGlobalAccessLogMode": "Fs Evrensel Erişim Log Modu:", "SettingsTabLoggingDeveloperOptions": "Geliştirici Seçenekleri (UYARI: Performansı düşürecektir)", + "SettingsTabLoggingDeveloperOptionsNote": "UYARI: Oyun performansı azalacak", "SettingsTabLoggingGraphicsBackendLogLevel": "Grafik Arka Uç Günlük Düzeyi", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Hiçbiri", "SettingsTabLoggingGraphicsBackendLogLevelError": "Hata", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Aşağı", "ControllerSettingsDPadLeft": "Sol", "ControllerSettingsDPadRight": "Sağ", + "ControllerSettingsStickButton": "Tuş", + "ControllerSettingsStickUp": "Yukarı", + "ControllerSettingsStickDown": "Aşağı", + "ControllerSettingsStickLeft": "Sol", + "ControllerSettingsStickRight": "Sağ", + "ControllerSettingsStickStick": "Analog", + "ControllerSettingsStickInvertXAxis": "X Eksenini Tersine Çevir", + "ControllerSettingsStickInvertYAxis": "Y Eksenini Tersine Çevir", + "ControllerSettingsStickDeadzone": "Ölü Bölge", "ControllerSettingsLStick": "Sol Analog", - "ControllerSettingsLStickButton": "Tuş", - "ControllerSettingsLStickUp": "Yukarı", - "ControllerSettingsLStickDown": "Aşağı", - "ControllerSettingsLStickLeft": "Sol", - "ControllerSettingsLStickRight": "Sağ", - "ControllerSettingsLStickStick": "Analog", - "ControllerSettingsLStickInvertXAxis": "X Eksenini Tersine Çevir", - "ControllerSettingsLStickInvertYAxis": "Y Eksenini Tersine Çevir", - "ControllerSettingsLStickDeadzone": "Ölü Bölge:", "ControllerSettingsRStick": "Sağ Analog", - "ControllerSettingsRStickButton": "Tuş", - "ControllerSettingsRStickUp": "Yukarı", - "ControllerSettingsRStickDown": "Aşağı", - "ControllerSettingsRStickLeft": "Sol", - "ControllerSettingsRStickRight": "Sağ", - "ControllerSettingsRStickStick": "Analog", - "ControllerSettingsRStickInvertXAxis": "X Eksenini Tersine Çevir", - "ControllerSettingsRStickInvertYAxis": "Y Eksenini Tersine Çevir", - "ControllerSettingsRStickDeadzone": "Ölü Bölge:", "ControllerSettingsTriggersLeft": "Tetikler Sol", "ControllerSettingsTriggersRight": "Tetikler Sağ", "ControllerSettingsTriggersButtonsLeft": "Tetik Tuşları Sol", @@ -262,6 +268,7 @@ "UserProfilesAddNewProfile": "Yeni Profil Ekle", "UserProfilesDelete": "Sil", "UserProfilesClose": "Kapat", + "ProfileNameSelectionWatermark": "Kullanıcı Adı Seç", "ProfileImageSelectionTitle": "Profil Resmi Seçimi", "ProfileImageSelectionHeader": "Profil Resmi Seç", "ProfileImageSelectionNote": "Özel bir profil resmi içeri aktarabilir veya sistem avatarlarından birini seçebilirsiniz", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Profili Kaydet", "MenuBarFileToolsTakeScreenshot": "Ekran Görüntüsü Al", "MenuBarFileToolsHideUi": "Arayüzü Gizle", + "GameListContextMenuRunApplication": "Uygulamayı Çalıştır", "GameListContextMenuToggleFavorite": "Favori Ayarla", "GameListContextMenuToggleFavoriteToolTip": "Oyunu Favorilere Ekle/Çıkar", "SettingsTabGeneralTheme": "Tema", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Yüklü firmware bulunamadı ancak Ryujinx sağlanan oyundan {0} firmware sürümünü yükledi.\nEmülatör şimdi başlatılacak.", "DialogFirmwareNoFirmwareInstalledMessage": "Yazılım Yüklü Değil", "DialogFirmwareInstalledMessage": "Yazılım {0} yüklendi", + "DialogInstallFileTypesSuccessMessage": "Dosya uzantıları başarıyla yüklendi!", + "DialogInstallFileTypesErrorMessage": "Dosya uzantıları yükleme işlemi başarısız oldu.", + "DialogUninstallFileTypesSuccessMessage": "Dosya uzantıları başarıyla kaldırıldı!", + "DialogUninstallFileTypesErrorMessage": "Dosya uzantıları kaldırma işlemi başarısız oldu.", "DialogOpenSettingsWindowLabel": "Seçenekler Penceresini Aç", "DialogControllerAppletTitle": "Kontrolcü Applet'i", "DialogMessageDialogErrorExceptionMessage": "Mesaj diyaloğu gösterilirken hata: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Sistem sürümü {0} başarıyla yüklendi.", "DialogUserProfileDeletionWarningMessage": "Seçilen profil silinirse kullanılabilen başka profil kalmayacak", "DialogUserProfileDeletionConfirmMessage": "Seçilen profili silmek istiyor musunuz", + "DialogUserProfileUnsavedChangesTitle": "Uyarı - Kaydedilmemiş Değişiklikler", + "DialogUserProfileUnsavedChangesMessage": "Kullanıcı profilinizde kaydedilmemiş değişiklikler var.", + "DialogUserProfileUnsavedChangesSubMessage": "Yaptığınız değişiklikleri iptal etmek istediğinize emin misiniz?", "DialogControllerSettingsModifiedConfirmMessage": "Güncel kontrolcü seçenekleri güncellendi.", "DialogControllerSettingsModifiedConfirmSubMessage": "Kaydetmek istiyor musunuz?", "DialogLoadNcaErrorMessage": "{0}. Hatalı Dosya: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Tümünü Aktif Et", "DlcManagerDisableAllButton": "Tümünü Devre Dışı Bırak", "MenuBarOptionsChangeLanguage": "Dili Değiştir", + "MenuBarShowFileTypes": "Dosya Uzantılarını Göster", "CommonSort": "Sırala", "CommonShowNames": "İsimleri Göster", "CommonFavorite": "Favori", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Adres çevirisi için bir işlemci sayfası kullanır. En yüksek doğruluğu ve en yavaş performansı sunar.", "MemoryManagerHostTooltip": "Hafızayı doğrudan host adres aralığında tahsis eder. Çok daha hızlı JIT derleme ve işletimi sunar.", "MemoryManagerUnsafeTooltip": "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.", + "UseHypervisorTooltip": "JIT yerine Hypervisor kullan. Uygun durumlarda performansı büyük oranda arttırır. Ancak şu anki halinde stabil durumda çalışmayabilir.", "DRamTooltip": "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.", "IgnoreMissingServicesTooltip": "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.", "GraphicsBackendThreadingTooltip": "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.", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "En az {0} karakter uzunluğunda olmalı", "SwkbdMinRangeCharacters": "{0}-{1} karakter uzunluğunda olmalı", "SoftwareKeyboard": "Yazılım Klavyesi", + "SoftwareKeyboardModeNumbersOnly": "Sadece Numara Olabilir", + "SoftwareKeyboardModeAlphabet": "Sadece CJK-characters olmayan karakterler olabilir", + "SoftwareKeyboardModeASCII": "Sadece ASCII karakterler olabilir", "DialogControllerAppletMessagePlayerRange": "Uygulama belirtilen türde {0} oyuncu istiyor:\n\nTÜRLER: {1}\n\nOYUNCULAR: {2}\n\n{3}Lütfen şimdi seçeneklerden giriş aygıtlarını ayarlayın veya Kapat'a basın.", "DialogControllerAppletMessage": "Uygulama belirtilen türde tam olarak {0} oyuncu istiyor:\n\nTÜRLER: {1}\n\nOYUNCULAR: {2}\n\n{3}Lütfen şimdi seçeneklerden giriş aygıtlarını ayarlayın veya Kapat'a basın.", "DialogControllerAppletDockModeSet": "Docked mode etkin. Handheld geçersiz.\n\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Oyun DLC'lerini Yönet", "UpdateWindowTitle": "Oyun Güncellemelerini Yönet", "CheatWindowHeading": "{0} için Hile mevcut [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "{0} için DLC mevcut [{1}]", "UserProfilesEditProfile": "Seçiliyi Düzenle", "Cancel": "İptal", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Sesi Azalt:", "SettingsEnableMacroHLE": "Macro HLE'yi Aktifleştir", "SettingsEnableMacroHLETooltip": "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.", + "SettingsEnableColorSpacePassthrough": "Renk Alanı Geçişi", + "SettingsEnableColorSpacePassthroughTooltip": "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.", "VolumeShort": "Ses", "UserProfilesManageSaves": "Kayıtları Yönet", "DeleteUserSave": "Bu oyun için kullanıcı kaydını silmek istiyor musunuz?", @@ -610,5 +633,24 @@ "Search": "Ara", "UserProfilesRecoverLostAccounts": "Kayıp Hesapları Kurtar", "Recover": "Kurtar", - "UserProfilesRecoverHeading": "Aşağıdaki hesaplar için kayıtlar bulundu" -} + "UserProfilesRecoverHeading": "Aşağıdaki hesaplar için kayıtlar bulundu", + "UserProfilesRecoverEmptyList": "Kurtarılacak profil bulunamadı", + "GraphicsAATooltip": "Oyuna Kenar Yumuşatma Ekler", + "GraphicsAALabel": "Kenar Yumuşatma:", + "GraphicsScalingFilterLabel": "Ölçekleme Filtresi:", + "GraphicsScalingFilterTooltip": "Çerçeve Arabellek Filtresini Açar", + "GraphicsScalingFilterLevelLabel": "Seviye", + "GraphicsScalingFilterLevelTooltip": "Ölçekleme Filtre Seviyesini Belirle", + "SmaaLow": "Düşük SMAA", + "SmaaMedium": "Orta SMAA", + "SmaaHigh": "Yüksek SMAA", + "SmaaUltra": "En Yüksek SMAA", + "UserEditorTitle": "Kullanıcıyı Düzenle", + "UserEditorTitleCreate": "Kullanıcı Oluştur", + "SettingsTabNetworkInterface": "Ağ Bağlantısı:", + "NetworkInterfaceTooltip": "LAN özellikleri için kullanılan ağ bağlantısı", + "NetworkInterfaceDefault": "Varsayılan", + "PackagingShaders": "Gölgeler Paketleniyor", + "AboutChangelogButton": "GitHub'da Değişiklikleri Görüntüle", + "AboutChangelogButtonTooltipMessage": "Kullandığınız versiyon için olan değişiklikleri varsayılan tarayıcınızda görmek için tıklayın" +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/uk_UA.json b/src/Ryujinx.Ava/Assets/Locales/uk_UA.json index 111337a42..a119fb4b7 100644 --- a/src/Ryujinx.Ava/Assets/Locales/uk_UA.json +++ b/src/Ryujinx.Ava/Assets/Locales/uk_UA.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "Програмне забезпечення", "SettingsTabSystemMemoryManagerModeHost": "Хост (швидко)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "Неперевірений хост (найшвидший, небезпечний)", + "SettingsTabSystemUseHypervisor": "Use Hypervisor", "MenuBarFile": "_Файл", "MenuBarFileOpenFromFile": "_Завантажити програму з файлу", "MenuBarFileOpenUnpacked": "Завантажити _розпаковану гру", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "Встановити прошивку", "MenuBarFileToolsInstallFirmwareFromFile": "Встановити прошивку з XCI або ZIP", "MenuBarFileToolsInstallFirmwareFromDirectory": "Встановити прошивку з теки", + "MenuBarToolsManageFileTypes": "Manage file types", + "MenuBarToolsInstallFileTypes": "Install file types", + "MenuBarToolsUninstallFileTypes": "Uninstall file types", "MenuBarHelp": "Довідка", "MenuBarHelpCheckForUpdates": "Перевірити оновлення", "MenuBarHelpAbout": "Про програму", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "Видобуває розділ логотипу з поточної конфігурації програми (включаючи оновлення)", "StatusBarGamesLoaded": "{0}/{1} Ігор завантажено", "StatusBarSystemVersion": "Версія системи: {0}", + "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", + "LinuxVmMaxMapCountDialogTextPrimary": "Would you like to increase the value of vm.max_map_count to {0}", + "LinuxVmMaxMapCountDialogTextSecondary": "Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "Yes, until the next restart", + "LinuxVmMaxMapCountDialogButtonPersistent": "Yes, permanently", + "LinuxVmMaxMapCountWarningTextPrimary": "Max amount of memory mappings is lower than recommended.", + "LinuxVmMaxMapCountWarningTextSecondary": "The current value of vm.max_map_count ({0}) is lower than {1}. Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.\n\nYou might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.", "Settings": "Налаштування", "SettingsTabGeneral": "Інтерфейс користувача", "SettingsTabGeneralGeneral": "Загальні", "SettingsTabGeneralEnableDiscordRichPresence": "Увімкнути розширену присутність Discord", "SettingsTabGeneralCheckUpdatesOnLaunch": "Перевіряти наявність оновлень під час запуску", "SettingsTabGeneralShowConfirmExitDialog": "Показати діалогове вікно «Підтвердити вихід».", + "SettingsTabGeneralHideCursor": "Hide Cursor:", + "SettingsTabGeneralHideCursorNever": "Never", "SettingsTabGeneralHideCursorOnIdle": "Приховати курсор у режимі очікування", + "SettingsTabGeneralHideCursorAlways": "Always", "SettingsTabGeneralGameDirectories": "Каталоги ігор", "SettingsTabGeneralAdd": "Додати", "SettingsTabGeneralRemove": "Видалити", @@ -158,6 +172,7 @@ "SettingsTabLoggingEnableFsAccessLogs": "Увімкнути журнали доступу Fs", "SettingsTabLoggingFsGlobalAccessLogMode": "Режим журналу глобального доступу Fs:", "SettingsTabLoggingDeveloperOptions": "Параметри розробника (УВАГА: знизиться продуктивність)", + "SettingsTabLoggingDeveloperOptionsNote": "WARNING: Will reduce performance", "SettingsTabLoggingGraphicsBackendLogLevel": "Рівень журналу графічного сервера:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "Ні", "SettingsTabLoggingGraphicsBackendLogLevelError": "Помилка", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "Вниз", "ControllerSettingsDPadLeft": "Вліво", "ControllerSettingsDPadRight": "Вправо", + "ControllerSettingsStickButton": "Button", + "ControllerSettingsStickUp": "Up", + "ControllerSettingsStickDown": "Down", + "ControllerSettingsStickLeft": "Left", + "ControllerSettingsStickRight": "Right", + "ControllerSettingsStickStick": "Stick", + "ControllerSettingsStickInvertXAxis": "Invert Stick X", + "ControllerSettingsStickInvertYAxis": "Invert Stick Y", + "ControllerSettingsStickDeadzone": "Deadzone:", "ControllerSettingsLStick": "Лівий джойстик", - "ControllerSettingsLStickButton": "Кнопка", - "ControllerSettingsLStickUp": "Вгору", - "ControllerSettingsLStickDown": "Вниз", - "ControllerSettingsLStickLeft": "Вліво", - "ControllerSettingsLStickRight": "Вправо", - "ControllerSettingsLStickStick": "Джойстик", - "ControllerSettingsLStickInvertXAxis": "Інвертувати джойстик по X", - "ControllerSettingsLStickInvertYAxis": "Інвертувати джойстик по Y", - "ControllerSettingsLStickDeadzone": "Мертва зона:", "ControllerSettingsRStick": "Правий джойстик", - "ControllerSettingsRStickButton": "Кнопка", - "ControllerSettingsRStickUp": "Вгору", - "ControllerSettingsRStickDown": "Вниз", - "ControllerSettingsRStickLeft": "Вліво", - "ControllerSettingsRStickRight": "Вправо", - "ControllerSettingsRStickStick": "Джойстик", - "ControllerSettingsRStickInvertXAxis": "Інвертувати джойстик по X", - "ControllerSettingsRStickInvertYAxis": "Інвертувати джойстик по Y", - "ControllerSettingsRStickDeadzone": "Мертва зона:", "ControllerSettingsTriggersLeft": "Тригери ліворуч", "ControllerSettingsTriggersRight": "Тригери праворуч", "ControllerSettingsTriggersButtonsLeft": "Кнопки тригерів ліворуч", @@ -260,8 +266,9 @@ "UserProfilesChangeProfileImage": "Змінити зображення профілю", "UserProfilesAvailableUserProfiles": "Доступні профілі користувачів:", "UserProfilesAddNewProfile": "Створити профіль", - "UserProfilesDeleteSelectedProfile": "Видалити вибране", + "UserProfilesDelete": "Delete", "UserProfilesClose": "Закрити", + "ProfileNameSelectionWatermark": "Choose a nickname", "ProfileImageSelectionTitle": "Вибір зображення профілю", "ProfileImageSelectionHeader": "Виберіть зображення профілю", "ProfileImageSelectionNote": "Ви можете імпортувати власне зображення профілю або вибрати аватар із мікропрограми системи", @@ -282,6 +289,7 @@ "ControllerSettingsSaveProfileToolTip": "Зберегти профіль", "MenuBarFileToolsTakeScreenshot": "Зробити знімок екрана", "MenuBarFileToolsHideUi": "Сховати інтерфейс", + "GameListContextMenuRunApplication": "Run Application", "GameListContextMenuToggleFavorite": "Перемкнути вибране", "GameListContextMenuToggleFavoriteToolTip": "Перемкнути улюблений статус гри", "SettingsTabGeneralTheme": "Тема", @@ -337,6 +345,10 @@ "DialogFirmwareInstallEmbeddedSuccessMessage": "Встановлену прошивку не знайдено, але Ryujinx вдалося встановити прошивку {0} з наданої гри.\\nТепер запуститься емулятор.", "DialogFirmwareNoFirmwareInstalledMessage": "Прошивка не встановлена", "DialogFirmwareInstalledMessage": "Встановлено прошивку {0}", + "DialogInstallFileTypesSuccessMessage": "Successfully installed file types!", + "DialogInstallFileTypesErrorMessage": "Failed to install file types.", + "DialogUninstallFileTypesSuccessMessage": "Successfully uninstalled file types!", + "DialogUninstallFileTypesErrorMessage": "Failed to uninstall file types.", "DialogOpenSettingsWindowLabel": "Відкрити вікно налаштувань", "DialogControllerAppletTitle": "Аплет контролера", "DialogMessageDialogErrorExceptionMessage": "Помилка показу діалогового вікна повідомлення: {0}", @@ -368,6 +380,9 @@ "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Версію системи {0} успішно встановлено.", "DialogUserProfileDeletionWarningMessage": "Якщо вибраний профіль буде видалено, інші профілі не відкриватимуться", "DialogUserProfileDeletionConfirmMessage": "Ви хочете видалити вибраний профіль", + "DialogUserProfileUnsavedChangesTitle": "Warning - Unsaved Changes", + "DialogUserProfileUnsavedChangesMessage": "You have made changes to this user profile that have not been saved.", + "DialogUserProfileUnsavedChangesSubMessage": "Do you want to discard your changes?", "DialogControllerSettingsModifiedConfirmMessage": "Поточні налаштування контролера оновлено.", "DialogControllerSettingsModifiedConfirmSubMessage": "Ви хочете зберегти?", "DialogLoadNcaErrorMessage": "{0}. Файл з помилкою: {1}", @@ -416,6 +431,7 @@ "DlcManagerEnableAllButton": "Увімкнути всі", "DlcManagerDisableAllButton": "Вимкнути всі", "MenuBarOptionsChangeLanguage": "Змінити мову", + "MenuBarShowFileTypes": "Show File Types", "CommonSort": "Сортувати", "CommonShowNames": "Показати назви", "CommonFavorite": "Вибрані", @@ -445,6 +461,7 @@ "MemoryManagerSoftwareTooltip": "Використовує програмну таблицю сторінок для перекладу адрес. Найвища точність, але найповільніша продуктивність.", "MemoryManagerHostTooltip": "Пряме відображення пам'яті в адресному просторі хосту. Набагато швидша компіляція та виконання JIT.", "MemoryManagerUnsafeTooltip": "Пряме відображення пам’яті, але не маскує адресу в гостьовому адресному просторі перед доступом. Швидше, але ціною безпеки. Гостьова програма може отримати доступ до пам’яті з будь-якого місця в Ryujinx, тому запускайте в цьому режимі лише програми, яким ви довіряєте.", + "UseHypervisorTooltip": "Use Hypervisor instead of JIT. Greatly improves performance when available, but can be unstable in its current state.", "DRamTooltip": "Використовує альтернативний макет MemoryMode для імітації моделі розробки Switch.\n\nЦе корисно лише для пакетів текстур з вищою роздільною здатністю або модифікацій із роздільною здатністю 4K. НЕ покращує продуктивність.\n\nЗалиште вимкненим, якщо не впевнені.", "IgnoreMissingServicesTooltip": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим, якщо не впевнені.", "GraphicsBackendThreadingTooltip": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто», якщо не впевнені", @@ -527,6 +544,9 @@ "SwkbdMinCharacters": "Мінімальна кількість символів: {0}", "SwkbdMinRangeCharacters": "Має бути {0}-{1} символів", "SoftwareKeyboard": "Програмна клавіатура", + "SoftwareKeyboardModeNumbersOnly": "Must be numbers only", + "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", + "SoftwareKeyboardModeASCII": "Must be ASCII text only", "DialogControllerAppletMessagePlayerRange": "Програма запитує {0} гравця(ів) з:\n\nТИПИ: {1}\n\nГРАВЦІ: {2}\n\n{3}Будь ласка, відкрийте «Налаштування» та повторно налаштуйте «Введення» або натисніть «Закрити».", "DialogControllerAppletMessage": "Програма запитує рівно стільки гравців: {0} з:\n\nТИПАМИ: {1}\n\nГРАВЦІВ: {2}\n\n{3}Будь ласка, відкрийте «Налаштування» та повторно налаштуйте «Введення» або натисніть «Закрити».", "DialogControllerAppletDockModeSet": "Встановлено режим док-станції. Ручний також недійсний.\n", @@ -572,6 +592,7 @@ "DlcWindowTitle": "Менеджер вмісту для завантаження", "UpdateWindowTitle": "Менеджер оновлення назв", "CheatWindowHeading": "Коди доступні для {0} [{1}]", + "BuildId": "BuildId:", "DlcWindowHeading": "Вміст для завантаження, доступний для {1} ({2}): {0}", "UserProfilesEditProfile": "Редагувати вибране", "Cancel": "Скасувати", @@ -599,6 +620,8 @@ "SettingsTabHotkeysVolumeDownHotkey": "Зменшити гучність:", "SettingsEnableMacroHLE": "Увімкнути макрос HLE", "SettingsEnableMacroHLETooltip": "Високорівнева емуляція коду макросу GPU.\n\nПокращує продуктивність, але може викликати графічні збої в деяких іграх.\n\nЗалиште увімкненим, якщо не впевнені.", + "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", + "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.", "VolumeShort": "Гуч", "UserProfilesManageSaves": "Керувати збереженнями", "DeleteUserSave": "Ви хочете видалити збереження користувача для цієї гри?", @@ -610,5 +633,24 @@ "Search": "Пошук", "UserProfilesRecoverLostAccounts": "Відновлення втрачених облікових записів", "Recover": "Відновити", - "UserProfilesRecoverHeading": "Знайдено збереження для наступних облікових записів" -} + "UserProfilesRecoverHeading": "Знайдено збереження для наступних облікових записів", + "UserProfilesRecoverEmptyList": "No profiles to recover", + "GraphicsAATooltip": "Applies anti-aliasing to the game render", + "GraphicsAALabel": "Anti-Aliasing:", + "GraphicsScalingFilterLabel": "Scaling Filter:", + "GraphicsScalingFilterTooltip": "Enables Framebuffer Scaling", + "GraphicsScalingFilterLevelLabel": "Level", + "GraphicsScalingFilterLevelTooltip": "Set Scaling Filter Level", + "SmaaLow": "SMAA Low", + "SmaaMedium": "SMAA Medium", + "SmaaHigh": "SMAA High", + "SmaaUltra": "SMAA Ultra", + "UserEditorTitle": "Edit User", + "UserEditorTitleCreate": "Create User", + "SettingsTabNetworkInterface": "Network Interface:", + "NetworkInterfaceTooltip": "The network interface used for LAN features", + "NetworkInterfaceDefault": "Default", + "PackagingShaders": "Packaging Shaders", + "AboutChangelogButton": "View Changelog on GitHub", + "AboutChangelogButtonTooltipMessage": "Click to open the changelog for this version in your default browser." +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/zh_CN.json b/src/Ryujinx.Ava/Assets/Locales/zh_CN.json index 25dc3cbaf..d09a80ec6 100644 --- a/src/Ryujinx.Ava/Assets/Locales/zh_CN.json +++ b/src/Ryujinx.Ava/Assets/Locales/zh_CN.json @@ -7,6 +7,7 @@ "SettingsTabSystemMemoryManagerModeSoftware": "软件", "SettingsTabSystemMemoryManagerModeHost": "本机 (快速)", "SettingsTabSystemMemoryManagerModeHostUnchecked": "跳过检查的本机 (最快)", + "SettingsTabSystemUseHypervisor": "使用 Hypervisor 虚拟化", "MenuBarFile": "文件", "MenuBarFileOpenFromFile": "加载文件", "MenuBarFileOpenUnpacked": "加载解包后的游戏", @@ -26,10 +27,13 @@ "MenuBarToolsInstallFirmware": "安装固件", "MenuBarFileToolsInstallFirmwareFromFile": "从 XCI 或 ZIP 安装固件", "MenuBarFileToolsInstallFirmwareFromDirectory": "从文件夹安装固件", + "MenuBarToolsManageFileTypes": "管理文件扩展名", + "MenuBarToolsInstallFileTypes": "关联文件扩展名", + "MenuBarToolsUninstallFileTypes": "取消关联扩展名", "MenuBarHelp": "帮助", "MenuBarHelpCheckForUpdates": "检查更新", "MenuBarHelpAbout": "关于", - "MenuSearch": "搜索……", + "MenuSearch": "搜索…", "GameListHeaderFavorite": "收藏", "GameListHeaderIcon": "图标", "GameListHeaderApplication": "名称", @@ -40,9 +44,9 @@ "GameListHeaderFileExtension": "扩展名", "GameListHeaderFileSize": "大小", "GameListHeaderPath": "路径", - "GameListContextMenuOpenUserSaveDirectory": "打开应用存档目录", + "GameListContextMenuOpenUserSaveDirectory": "打开用户存档目录", "GameListContextMenuOpenUserSaveDirectoryToolTip": "打开储存游戏存档的目录", - "GameListContextMenuOpenDeviceSaveDirectory": "打开应用系统目录", + "GameListContextMenuOpenDeviceSaveDirectory": "打开系统目录", "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "打开包含游戏系统设置的目录", "GameListContextMenuOpenBcatSaveDirectory": "打开 BCAT 目录", "GameListContextMenuOpenBcatSaveDirectoryToolTip": "打开包含游戏 BCAT 数据的目录", @@ -60,7 +64,7 @@ "GameListContextMenuCacheManagementOpenPptcDirectory": "打开 PPTC 目录", "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "打开包含游戏 PPTC 缓存的目录", "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "打开着色器缓存目录", - "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "打开包含应用程序着色器缓存的目录", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "打开包含游戏着色器缓存的目录", "GameListContextMenuExtractData": "提取数据", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "从游戏的当前状态中提取 ExeFS 分区 (包括更新)", @@ -70,13 +74,23 @@ "GameListContextMenuExtractDataLogoToolTip": "从游戏的当前状态中提取图标 (包括更新)", "StatusBarGamesLoaded": "{0}/{1} 游戏加载完成", "StatusBarSystemVersion": "系统版本:{0}", + "LinuxVmMaxMapCountDialogTitle": "检测到内存映射的限制过低", + "LinuxVmMaxMapCountDialogTextPrimary": "你想要将 vm.max_map_count 的值增加到 {0} 吗", + "LinuxVmMaxMapCountDialogTextSecondary": "有些游戏可能会试图创建超过当前允许的内存映射数量。当超过此限制时,Ryujinx会立即崩溃。", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "确定,关闭后重置", + "LinuxVmMaxMapCountDialogButtonPersistent": "确定,永久保存", + "LinuxVmMaxMapCountWarningTextPrimary": "内存映射的最大数量低于推荐值。", + "LinuxVmMaxMapCountWarningTextSecondary": "vm.max_map_count ({0}) 的当前值小于 {1}。 有些游戏可能会试图创建超过当前允许的内存映射量。当大于此限制时,Ryujinx 会立即崩溃。\n\n你可以手动增加内存映射限制或者安装 pkexec,它可以辅助Ryujinx解决该问题。", "Settings": "设置", "SettingsTabGeneral": "用户界面", "SettingsTabGeneralGeneral": "常规", "SettingsTabGeneralEnableDiscordRichPresence": "启用 Discord 在线状态展示", "SettingsTabGeneralCheckUpdatesOnLaunch": "自动检查更新", "SettingsTabGeneralShowConfirmExitDialog": "显示 \"确认退出\" 对话框", - "SettingsTabGeneralHideCursorOnIdle": "自动隐藏鼠标", + "SettingsTabGeneralHideCursor": "隐藏鼠标指针:", + "SettingsTabGeneralHideCursorNever": "从不", + "SettingsTabGeneralHideCursorOnIdle": "自动隐藏", + "SettingsTabGeneralHideCursorAlways": "始终", "SettingsTabGeneralGameDirectories": "游戏目录", "SettingsTabGeneralAdd": "添加", "SettingsTabGeneralRemove": "删除", @@ -97,12 +111,12 @@ "SettingsTabSystemSystemLanguageGerman": "德语", "SettingsTabSystemSystemLanguageItalian": "意大利语", "SettingsTabSystemSystemLanguageSpanish": "西班牙语", - "SettingsTabSystemSystemLanguageChinese": "中文(简体)——无效", + "SettingsTabSystemSystemLanguageChinese": "简体中文", "SettingsTabSystemSystemLanguageKorean": "韩语", "SettingsTabSystemSystemLanguageDutch": "荷兰语", "SettingsTabSystemSystemLanguagePortuguese": "葡萄牙语", "SettingsTabSystemSystemLanguageRussian": "俄语", - "SettingsTabSystemSystemLanguageTaiwanese": "中文(繁体)——无效", + "SettingsTabSystemSystemLanguageTaiwanese": "繁体中文(台湾)", "SettingsTabSystemSystemLanguageBritishEnglish": "英式英语", "SettingsTabSystemSystemLanguageCanadianFrench": "加拿大法语", "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "拉美西班牙语", @@ -116,10 +130,10 @@ "SettingsTabSystemAudioBackend": "音频后端:", "SettingsTabSystemAudioBackendDummy": "无", "SettingsTabSystemAudioBackendOpenAL": "OpenAL", - "SettingsTabSystemAudioBackendSoundIO": "SoundIO", + "SettingsTabSystemAudioBackendSoundIO": "音频输入/输出", "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "修正", - "SettingsTabSystemHacksNote": " (会引起模拟器不稳定)", + "SettingsTabSystemHacksNote": "(会引起模拟器不稳定)", "SettingsTabSystemExpandDramSize": "使用开发机的内存布局", "SettingsTabSystemIgnoreMissingServices": "忽略缺失的服务", "SettingsTabGraphics": "图形", @@ -131,33 +145,34 @@ "SettingsTabGraphicsAnisotropicFiltering4x": "4x", "SettingsTabGraphicsAnisotropicFiltering8x": "8x", "SettingsTabGraphicsAnisotropicFiltering16x": "16x", - "SettingsTabGraphicsResolutionScale": "分辨率缩放:", - "SettingsTabGraphicsResolutionScaleCustom": "自定义 (不推荐)", + "SettingsTabGraphicsResolutionScale": "分辨率缩放:", + "SettingsTabGraphicsResolutionScaleCustom": "自定义(不推荐)", "SettingsTabGraphicsResolutionScaleNative": "原生 (720p/1080p)", "SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)", "SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)", "SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)", - "SettingsTabGraphicsAspectRatio": "宽高比:", + "SettingsTabGraphicsAspectRatio": "宽高比:", "SettingsTabGraphicsAspectRatio4x3": "4:3", "SettingsTabGraphicsAspectRatio16x9": "16:9", "SettingsTabGraphicsAspectRatio16x10": "16:10", "SettingsTabGraphicsAspectRatio21x9": "21:9", "SettingsTabGraphicsAspectRatio32x9": "32:9", - "SettingsTabGraphicsAspectRatioStretch": "拉伸至屏幕", + "SettingsTabGraphicsAspectRatioStretch": "拉伸以适应窗口", "SettingsTabGraphicsDeveloperOptions": "开发者选项", - "SettingsTabGraphicsShaderDumpPath": "图形着色器转储路径:", + "SettingsTabGraphicsShaderDumpPath": "图形着色器转储路径:", "SettingsTabLogging": "日志", "SettingsTabLoggingLogging": "日志", "SettingsTabLoggingEnableLoggingToFile": "保存日志为文件", - "SettingsTabLoggingEnableStubLogs": "记录Stub", - "SettingsTabLoggingEnableInfoLogs": "记录Info", - "SettingsTabLoggingEnableWarningLogs": "记录Warning", - "SettingsTabLoggingEnableErrorLogs": "记录Error", - "SettingsTabLoggingEnableTraceLogs": "记录Trace", - "SettingsTabLoggingEnableGuestLogs": "记录Guest", - "SettingsTabLoggingEnableFsAccessLogs": "记录文件访问", - "SettingsTabLoggingFsGlobalAccessLogMode": "记录全局文件访问模式:", - "SettingsTabLoggingDeveloperOptions": "开发者选项 (警告: 会降低性能)", + "SettingsTabLoggingEnableStubLogs": "启用 Stub 日志", + "SettingsTabLoggingEnableInfoLogs": "启用信息日志", + "SettingsTabLoggingEnableWarningLogs": "启用警告日志", + "SettingsTabLoggingEnableErrorLogs": "启用错误日志", + "SettingsTabLoggingEnableTraceLogs": "启用跟踪日志", + "SettingsTabLoggingEnableGuestLogs": "启用来宾日志", + "SettingsTabLoggingEnableFsAccessLogs": "启用访问日志", + "SettingsTabLoggingFsGlobalAccessLogMode": "全局访问日志模式:", + "SettingsTabLoggingDeveloperOptions": "开发者选项", + "SettingsTabLoggingDeveloperOptionsNote": "警告:会降低性能", "SettingsTabLoggingGraphicsBackendLogLevel": "图形后端日志级别:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "无", "SettingsTabLoggingGraphicsBackendLogLevelError": "错误", @@ -169,7 +184,7 @@ "SettingsTabInputDirectKeyboardAccess": "直通键盘控制", "SettingsButtonSave": "保存", "SettingsButtonClose": "取消", - "SettingsButtonOk": "保存", + "SettingsButtonOk": "确定", "SettingsButtonCancel": "取消", "SettingsButtonApply": "应用", "ControllerSettingsPlayer": "玩家", @@ -188,7 +203,7 @@ "ControllerSettingsControllerType": "手柄类型", "ControllerSettingsControllerTypeHandheld": "掌机", "ControllerSettingsControllerTypeProController": "Pro 手柄", - "ControllerSettingsControllerTypeJoyConPair": "JoyCon", + "ControllerSettingsControllerTypeJoyConPair": "JoyCon 组合", "ControllerSettingsControllerTypeJoyConLeft": "左 JoyCon", "ControllerSettingsControllerTypeJoyConRight": "右 JoyCon", "ControllerSettingsProfile": "预设", @@ -196,7 +211,7 @@ "ControllerSettingsLoad": "加载", "ControllerSettingsAdd": "新建", "ControllerSettingsRemove": "删除", - "ControllerSettingsButtons": "按钮", + "ControllerSettingsButtons": "按键", "ControllerSettingsButtonA": "A", "ControllerSettingsButtonB": "B", "ControllerSettingsButtonX": "X", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "下", "ControllerSettingsDPadLeft": "左", "ControllerSettingsDPadRight": "右", + "ControllerSettingsStickButton": "按下摇杆", + "ControllerSettingsStickUp": "上", + "ControllerSettingsStickDown": "下", + "ControllerSettingsStickLeft": "左", + "ControllerSettingsStickRight": "右", + "ControllerSettingsStickStick": "摇杆", + "ControllerSettingsStickInvertXAxis": "反转 X 轴方向", + "ControllerSettingsStickInvertYAxis": "反转 Y 轴方向", + "ControllerSettingsStickDeadzone": "死区:", "ControllerSettingsLStick": "左摇杆", - "ControllerSettingsLStickButton": "按下摇杆", - "ControllerSettingsLStickUp": "上", - "ControllerSettingsLStickDown": "下", - "ControllerSettingsLStickLeft": "左", - "ControllerSettingsLStickRight": "右", - "ControllerSettingsLStickStick": "摇杆", - "ControllerSettingsLStickInvertXAxis": "反转 X 方向", - "ControllerSettingsLStickInvertYAxis": "反转 Y 方向", - "ControllerSettingsLStickDeadzone": "死区:", "ControllerSettingsRStick": "右摇杆", - "ControllerSettingsRStickButton": "按下摇杆", - "ControllerSettingsRStickUp": "上", - "ControllerSettingsRStickDown": "下", - "ControllerSettingsRStickLeft": "左", - "ControllerSettingsRStickRight": "右", - "ControllerSettingsRStickStick": "摇杆", - "ControllerSettingsRStickInvertXAxis": "反转 X 方向", - "ControllerSettingsRStickInvertYAxis": "反转 Y 方向", - "ControllerSettingsRStickDeadzone": "死区:", "ControllerSettingsTriggersLeft": "左扳机", "ControllerSettingsTriggersRight": "右扳机", "ControllerSettingsTriggersButtonsLeft": "左扳机键", @@ -244,25 +250,26 @@ "ControllerSettingsExtraButtonsLeft": "左背键", "ControllerSettingsExtraButtonsRight": "右背键", "ControllerSettingsMisc": "其他", - "ControllerSettingsTriggerThreshold": "扳机阈值:", + "ControllerSettingsTriggerThreshold": "扳机阈值:", "ControllerSettingsMotion": "体感", "ControllerSettingsMotionUseCemuhookCompatibleMotion": "使用 CemuHook 体感协议", - "ControllerSettingsMotionControllerSlot": "手柄:", + "ControllerSettingsMotionControllerSlot": "手柄:", "ControllerSettingsMotionMirrorInput": "镜像操作", - "ControllerSettingsMotionRightJoyConSlot": "右JoyCon:", - "ControllerSettingsMotionServerHost": "服务器 Host:", - "ControllerSettingsMotionGyroSensitivity": "陀螺仪敏感度:", - "ControllerSettingsMotionGyroDeadzone": "陀螺仪死区:", + "ControllerSettingsMotionRightJoyConSlot": "右JoyCon:", + "ControllerSettingsMotionServerHost": "服务器Host:", + "ControllerSettingsMotionGyroSensitivity": "陀螺仪敏感度:", + "ControllerSettingsMotionGyroDeadzone": "陀螺仪死区:", "ControllerSettingsSave": "保存", "ControllerSettingsClose": "关闭", - "UserProfilesSelectedUserProfile": "选择的用户账户:", + "UserProfilesSelectedUserProfile": "选择的用户账户:", "UserProfilesSaveProfileName": "保存名称", "UserProfilesChangeProfileImage": "更换头像", - "UserProfilesAvailableUserProfiles": "现有账户:", + "UserProfilesAvailableUserProfiles": "现有账户:", "UserProfilesAddNewProfile": "新建账户", - "UserProfilesDeleteSelectedProfile": "删除选中账户", + "UserProfilesDelete": "删除", "UserProfilesClose": "关闭", - "ProfileImageSelectionTitle": "头像选择", + "ProfileNameSelectionWatermark": "选择昵称", + "ProfileImageSelectionTitle": "选择头像", "ProfileImageSelectionHeader": "选择合适的头像图片", "ProfileImageSelectionNote": "您可以导入自定义头像,或从系统中选择头像", "ProfileImageSelectionImportImage": "导入图像文件", @@ -272,8 +279,8 @@ "InputDialogCancel": "取消", "InputDialogAddNewProfileTitle": "选择用户名称", "InputDialogAddNewProfileHeader": "请输入账户名称", - "InputDialogAddNewProfileSubtext": "(最大长度: {0})", - "AvatarChoose": "选择", + "InputDialogAddNewProfileSubtext": "(最大长度:{0})", + "AvatarChoose": "选择头像", "AvatarSetBackgroundColor": "设置背景色", "AvatarClose": "关闭", "ControllerSettingsLoadProfileToolTip": "加载预设", @@ -281,7 +288,8 @@ "ControllerSettingsRemoveProfileToolTip": "删除预设", "ControllerSettingsSaveProfileToolTip": "保存预设", "MenuBarFileToolsTakeScreenshot": "保存截图", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "隐藏界面", + "GameListContextMenuRunApplication": "运行应用", "GameListContextMenuToggleFavorite": "收藏", "GameListContextMenuToggleFavoriteToolTip": "标记喜爱的游戏", "SettingsTabGeneralTheme": "主题", @@ -304,9 +312,9 @@ "DialogExitTitle": "Ryujinx - 关闭", "DialogErrorMessage": "Ryujinx 发生错误", "DialogExitMessage": "是否关闭 Ryujinx?", - "DialogExitSubMessage": "未保存的进度会丢失", - "DialogMessageCreateSaveErrorMessage": "创建特定的存档时出错: {0}", - "DialogMessageFindSaveErrorMessage": "查找特定的存档时出错: {0}", + "DialogExitSubMessage": "未保存的进度将会丢失!", + "DialogMessageCreateSaveErrorMessage": "创建特定的存档时出错:{0}", + "DialogMessageFindSaveErrorMessage": "查找特定的存档时出错:{0}", "FolderDialogExtractTitle": "选择要解压到的文件夹", "DialogNcaExtractionMessage": "提取 {1} 的 {0} 分区...", "DialogNcaExtractionTitle": "Ryujinx - NCA分区提取", @@ -316,13 +324,13 @@ "DialogUpdaterConvertFailedMessage": "无法转换当前 Ryujinx 版本。", "DialogUpdaterCancelUpdateMessage": "更新取消!", "DialogUpdaterAlreadyOnLatestVersionMessage": "您使用的 Ryujinx 是最新版本。", - "DialogUpdaterFailedToGetVersionMessage": "尝试从 Github 获取版本信息时无效。\n可能由于 GitHub Actions 正在编译新版本。请过几分钟重试。", + "DialogUpdaterFailedToGetVersionMessage": "尝试从 Github 获取版本信息时无效。\n可能由于 GitHub Actions 正在编译新版本。请过一会再试。", "DialogUpdaterConvertFailedGithubMessage": "无法转换从 Github 接收到的 Ryujinx 版本。", "DialogUpdaterDownloadingMessage": "下载新版本中...", "DialogUpdaterExtractionMessage": "正在提取更新...", "DialogUpdaterRenamingMessage": "正在删除旧文件...", "DialogUpdaterAddingFilesMessage": "安装更新中...", - "DialogUpdaterCompleteMessage": "更新成功!", + "DialogUpdaterCompleteMessage": "更新成功!", "DialogUpdaterRestartMessage": "立即重启 Ryujinx 完成更新?", "DialogUpdaterArchNotSupportedMessage": "您运行的系统架构不受支持!", "DialogUpdaterArchNotSupportedSubMessage": "(仅支持 x64 系统)", @@ -336,41 +344,48 @@ "DialogFirmwareInstallEmbeddedMessage": "要安装游戏内置的固件吗?(固件 {0})", "DialogFirmwareInstallEmbeddedSuccessMessage": "未找到已安装的固件,但 Ryujinx 可以从现有的游戏安装固件{0}.\n模拟器现在可以运行。", "DialogFirmwareNoFirmwareInstalledMessage": "未安装固件", - "DialogFirmwareInstalledMessage": "已安装固件{0}", + "DialogFirmwareInstalledMessage": "已安装固件 {0}", + "DialogInstallFileTypesSuccessMessage": "关联文件类型成功!", + "DialogInstallFileTypesErrorMessage": "关联文件类型失败。", + "DialogUninstallFileTypesSuccessMessage": "成功解除文件类型关联!", + "DialogUninstallFileTypesErrorMessage": "解除文件类型关联失败。", "DialogOpenSettingsWindowLabel": "打开设置窗口", "DialogControllerAppletTitle": "控制器小窗口", - "DialogMessageDialogErrorExceptionMessage": "显示消息对话框时出错: {0}", - "DialogSoftwareKeyboardErrorExceptionMessage": "显示软件键盘时出错: {0}", - "DialogErrorAppletErrorExceptionMessage": "显示错误对话框时出错: {0}", + "DialogMessageDialogErrorExceptionMessage": "显示消息对话框时出错:{0}", + "DialogSoftwareKeyboardErrorExceptionMessage": "显示软件键盘时出错:{0}", + "DialogErrorAppletErrorExceptionMessage": "显示错误对话框时出错:{0}", "DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogInfoMessage": "\n有关修复此错误的更多信息,可以遵循我们的设置指南。", "DialogUserErrorDialogTitle": "Ryujinx 错误 ({0})", "DialogAmiiboApiTitle": "Amiibo API", "DialogAmiiboApiFailFetchMessage": "从 API 获取信息时出错。", "DialogAmiiboApiConnectErrorMessage": "无法连接到 Amiibo API 服务器。服务器可能已关闭,或者您没有连接网络。", - "DialogProfileInvalidProfileErrorMessage": "预设{0} 与当前输入配置系统不兼容。", + "DialogProfileInvalidProfileErrorMessage": "预设 {0} 与当前输入配置系统不兼容。", "DialogProfileDefaultProfileOverwriteErrorMessage": "默认预设不能被覆盖", "DialogProfileDeleteProfileTitle": "删除预设", "DialogProfileDeleteProfileMessage": "删除后不可恢复,确认删除吗?", "DialogWarning": "警告", - "DialogPPTCDeletionMessage": "您即将删除:\n\n{0}的 PPTC 缓存\n\n确定吗?", - "DialogPPTCDeletionErrorMessage": "清除位于{0}的 PPTC 缓存时出错: {1}", - "DialogShaderDeletionMessage": "您即将删除:\n\n{0}的着色器缓存\n\n确定吗?", - "DialogShaderDeletionErrorMessage": "清除位于{0}的着色器缓存时出错: {1}", + "DialogPPTCDeletionMessage": "您即将删除:\n\n{0} 的 PPTC 缓存\n\n确定吗?", + "DialogPPTCDeletionErrorMessage": "清除位于 {0} 的 PPTC 缓存时出错:{1}", + "DialogShaderDeletionMessage": "您即将删除:\n\n{0} 的着色器缓存\n\n确定吗?", + "DialogShaderDeletionErrorMessage": "清除位于 {0} 的着色器缓存时出错:{1}", "DialogRyujinxErrorMessage": "Ryujinx 遇到错误", - "DialogInvalidTitleIdErrorMessage": "UI 错误:所选游戏没有有效的标题ID", - "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "路径{0}找不到有效的系统固件。", - "DialogFirmwareInstallerFirmwareInstallTitle": "固件{0}", - "DialogFirmwareInstallerFirmwareInstallMessage": "即将安装系统版本{0}。", - "DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n会替换当前系统版本{0}。", + "DialogInvalidTitleIdErrorMessage": "UI错误:所选游戏没有有效的标题ID", + "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "路径 {0} 找不到有效的系统固件。", + "DialogFirmwareInstallerFirmwareInstallTitle": "固件 {0}", + "DialogFirmwareInstallerFirmwareInstallMessage": "即将安装系统版本 {0} 。", + "DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n会替换当前系统版本 {0} 。", "DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n是否确认继续?", "DialogFirmwareInstallerFirmwareInstallWaitMessage": "安装固件中...", - "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "成功安装系统版本{0}。", + "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "成功安装系统版本 {0} 。", "DialogUserProfileDeletionWarningMessage": "删除后将没有可选择的用户账户", "DialogUserProfileDeletionConfirmMessage": "是否删除选择的账户", + "DialogUserProfileUnsavedChangesTitle": "警告 - 未保存的更改", + "DialogUserProfileUnsavedChangesMessage": "您为该用户做出的部分改动尚未保存。", + "DialogUserProfileUnsavedChangesSubMessage": "是否舍弃这些改动?", "DialogControllerSettingsModifiedConfirmMessage": "目前的输入预设已更新", "DialogControllerSettingsModifiedConfirmSubMessage": "要保存吗?", - "DialogLoadNcaErrorMessage": "{0}. 错误的文件: {1}", + "DialogLoadNcaErrorMessage": "{0}. 错误的文件:{1}", "DialogDlcNoDlcErrorMessage": "选择的文件不包含所选游戏的 DLC!", "DialogPerformanceCheckLoggingEnabledMessage": "您启用了跟踪日志,仅供开发人员使用。", "DialogPerformanceCheckLoggingEnabledConfirmMessage": "为了获得最佳性能,建议禁用跟踪日志记录。您是否要立即禁用?", @@ -382,7 +397,7 @@ "DialogSettingsBackendThreadingWarningTitle": "警告 - 后端多线程", "DialogSettingsBackendThreadingWarningMessage": "改变此选项后必须重启 Ryujinx 才能生效。\n\n取决于您的硬件,可能需要手动禁用驱动面板中的线程优化。", "SettingsTabGraphicsFeaturesOptions": "功能", - "SettingsTabGraphicsBackendMultithreading": "后端多线程:", + "SettingsTabGraphicsBackendMultithreading": "多线程图形后端:", "CommonAuto": "自动(推荐)", "CommonOff": "关闭", "CommonOn": "打开", @@ -391,18 +406,18 @@ "DialogProfileInvalidProfileNameErrorMessage": "文件名包含无效字符,请重试。", "MenuBarOptionsPauseEmulation": "暂停", "MenuBarOptionsResumeEmulation": "继续", - "AboutUrlTooltipMessage": "在浏览器中打开 Ryujinx 的官网。", - "AboutDisclaimerMessage": "Ryujinx 以任何方式与Nintendo™及其任何商业伙伴都没有关联", + "AboutUrlTooltipMessage": "在浏览器中打开 Ryujinx 官网。", + "AboutDisclaimerMessage": "Ryujinx 以任何方式与 Nintendo™ 及其任何商业伙伴都没有关联", "AboutAmiiboDisclaimerMessage": "我们的 Amiibo 模拟使用了\nAmiiboAPI (www.amiiboapi.com) ", "AboutPatreonUrlTooltipMessage": "在浏览器中打开 Ryujinx 的 Patreon 赞助页。", "AboutGithubUrlTooltipMessage": "在浏览器中打开 Ryujinx 的 GitHub 代码库。", "AboutDiscordUrlTooltipMessage": "在浏览器中打开 Ryujinx 的 Discord 邀请链接。", "AboutTwitterUrlTooltipMessage": "在浏览器中打开 Ryujinx 的 Twitter 主页。", - "AboutRyujinxAboutTitle": "关于:", - "AboutRyujinxAboutContent": "Ryujinx是一款Nintendo Switch™模拟器。\n您可以在 Patreon 上赞助 Ryujinx。\n关注 Twitter 或 Discord 可以获取模拟器最新动态。\n如果您对开发感兴趣,欢迎来 GitHub 和 Discord 加入我们!", - "AboutRyujinxMaintainersTitle": "由以下作者维护:", - "AboutRyujinxMaintainersContentTooltipMessage": "在浏览器中打开贡献者的网页", - "AboutRyujinxSupprtersTitle": "感谢 Patreon 的赞助者:", + "AboutRyujinxAboutTitle": "关于:", + "AboutRyujinxAboutContent": "Ryujinx 是一款 Nintendo Switch™ 模拟器。\n您可以在 Patreon 上赞助 Ryujinx。\n关注 Twitter 或 Discord 可以获取模拟器最新动态。\n如果您对开发感兴趣,欢迎来 GitHub 或 Discord 加入我们!", + "AboutRyujinxMaintainersTitle": "由以下作者维护:", + "AboutRyujinxMaintainersContentTooltipMessage": "在浏览器中打开贡献者页面", + "AboutRyujinxSupprtersTitle": "感谢 Patreon 的赞助者:", "AmiiboSeriesLabel": "Amiibo 系列", "AmiiboCharacterLabel": "角色", "AmiiboScanButtonLabel": "扫描", @@ -413,9 +428,10 @@ "DlcManagerTableHeadingContainerPathLabel": "文件夹路径", "DlcManagerTableHeadingFullPathLabel": "完整路径", "DlcManagerRemoveAllButton": "全部删除", - "DlcManagerEnableAllButton": "全部选择", + "DlcManagerEnableAllButton": "全部启用", "DlcManagerDisableAllButton": "全部禁用", "MenuBarOptionsChangeLanguage": "更改语言", + "MenuBarShowFileTypes": "主页显示的文件类型", "CommonSort": "排序", "CommonShowNames": "显示名称", "CommonFavorite": "收藏", @@ -430,41 +446,42 @@ "CustomThemeCheckTooltip": "使用自定义UI主题来更改模拟器的外观样式", "CustomThemePathTooltip": "自定义主题的目录", "CustomThemeBrowseTooltip": "查找自定义主题", - "DockModeToggleTooltip": "启用 Switch 的主机模式。\n绝大多数游戏画质会提高,略微增加性能消耗。\n在掌机和主机模式切换的过程中,您可能需要重新设置手柄类型", + "DockModeToggleTooltip": "启用 Switch 的主机模式。\n绝大多数游戏画质会提高,略微增加性能消耗。\n在掌机和主机模式切换的过程中,您可能需要重新设置手柄类型。", "DirectKeyboardTooltip": "开启 \"直连键盘访问(HID)支持\"\n(部分游戏可以使用您的键盘输入文字)", "DirectMouseTooltip": "开启 \"直连鼠标访问(HID)支持\"\n(部分游戏可以使用您的鼠标导航)", "RegionTooltip": "更改系统区域", "LanguageTooltip": "更改系统语言", "TimezoneTooltip": "更改系统时区", "TimeTooltip": "更改系统时钟", - "VSyncToggleTooltip": "关闭后,小部分游戏可以超过60FPS帧率,以获得高帧率体验。\n但是可能出现软锁或读盘时间增加。\n如不确定或没有需求,请保持选项开启", - "PptcToggleTooltip": "缓存编译完成的游戏CPU指令。减少启动时间和卡顿,提高游戏响应速度", - "FsIntegrityToggleTooltip": "检查游戏文件内容的完整性。\n遇到损坏的文件则记录到日志文件,有助于排查错误。\n对性能没有影响。", - "AudioBackendTooltip": "默认推荐SDL,但每种音频后端对各类游戏兼容性不同,遇到音频问题可以尝试切换后端", - "MemoryManagerTooltip": "改变 Switch 内存映射到电脑内存的方式,会影响CPU性能消耗", - "MemoryManagerSoftwareTooltip": "使用软件内存页管理,最精确但是速度最慢", - "MemoryManagerHostTooltip": "直接映射内存页到电脑内存,JIT效率高", - "MemoryManagerUnsafeTooltip": "直接映射内存页,但不检查内存溢出,JIT效率最高。\nRyujinx可以访问任何位置的内存,因而相对不安全。\n此模式下只应运行您信任的游戏或软件(即官方游戏)", + "VSyncToggleTooltip": "关闭后,小部分游戏可以超过60FPS帧率,以获得高帧率体验。\n但是可能出现软锁或读盘时间增加。\n如不确定,就请保持开启状态。", + "PptcToggleTooltip": "缓存编译完成的游戏CPU指令。减少启动时间和卡顿,提高游戏响应速度。\n如不确定,就请保持开启状态。", + "FsIntegrityToggleTooltip": "检查游戏文件内容的完整性。\n遇到损坏的文件则记录到日志文件,有助于排查错误。\n对性能没有影响。\n如不确定,就请保持开启状态。", + "AudioBackendTooltip": "默认推荐SDL2,但每种音频后端对各类游戏兼容性不同,遇到音频问题可以尝试切换后端。", + "MemoryManagerTooltip": "改变 Switch 内存映射到电脑内存的方式,会影响CPU性能消耗。", + "MemoryManagerSoftwareTooltip": "使用软件内存页管理,最精确但是速度最慢。", + "MemoryManagerHostTooltip": "直接映射内存页到电脑内存,使得即时编译效率更高。", + "MemoryManagerUnsafeTooltip": "直接映射内存页,但不检查内存溢出,使得即时编译效率更高。\nRyujinx 可以访问任何位置的内存,因而相对不安全。\n此模式下只应运行您信任的游戏或软件(即官方游戏)。", + "UseHypervisorTooltip": "使用 Hypervisor 虚拟机代替即时编译。在可用的情况下能大幅提高性能。但目前可能不稳定。", "DRamTooltip": "使用Switch开发机的内存布局。\n不会提高任何性能,某些高清纹理包或 4k 分辨率 MOD 可能需要此选项。\n如果不确定,请始终关闭该选项。", - "IgnoreMissingServicesTooltip": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用新的未知系统服务,可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后,则无需开启选项。\n如您的游戏已经正常运行,请保持此选项关闭", - "GraphicsBackendThreadingTooltip": "启用后端多线程", - "GalThreadingTooltip": "使用模拟器内置的多线程优化,减少着色器编译的卡顿,并提高驱动程序的性能(尤其是缺失多线程的AMD)。\nNVIDIA显卡需要重启模拟器才能禁用驱动本身的线程优化,您也可以手动在控制面板将其禁用", - "ShaderCacheToggleTooltip": "开启后,模拟器会保存编译完成的着色器到磁盘,减少游戏渲染新特效和场景时的卡顿", + "IgnoreMissingServicesTooltip": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用新的未知系统服务,可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后,则无需开启选项。\n如您的游戏已经正常运行,请保持此选项关闭。", + "GraphicsBackendThreadingTooltip": "在第二个线程上执行图形后端命令。\n\n加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为自动。", + "GalThreadingTooltip": "在第二个线程上执行图形后端命令。\n\n加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为自动。", + "ShaderCacheToggleTooltip": "开启后,模拟器会保存编译完成的着色器到磁盘,减少游戏渲染新特效和场景时的卡顿。", "ResolutionScaleTooltip": "缩放渲染的分辨率", - "ResolutionScaleEntryTooltip": "尽可能使用例如1.5的浮点倍数。非整数的倍率易引起 BUG", + "ResolutionScaleEntryTooltip": "尽可能使用例如1.5的浮点倍数。非整数的倍率易引起 BUG。", "AnisotropyTooltip": "各向异性过滤等级。提高倾斜视角纹理的清晰度\n('自动'使用游戏默认的等级)", - "AspectRatioTooltip": "渲染窗口的宽高比", + "AspectRatioTooltip": "渲染窗口的宽高比。", "ShaderDumpPathTooltip": "转储图形着色器的路径", - "FileLogTooltip": "是否保存日志文件到硬盘", - "StubLogTooltip": "记录Stub消息", - "InfoLogTooltip": "记录Info消息", - "WarnLogTooltip": "记录Warning消息", - "ErrorLogTooltip": "记录Error消息", - "TraceLogTooltip": "记录Trace消息", - "GuestLogTooltip": "记录Guest消息", - "FileAccessLogTooltip": "记录文件访问消息", - "FSAccessLogModeTooltip": "记录FS访问消息,输出到控制台。可选的模式是0-3", - "DeveloperOptionTooltip": "使用请谨慎", + "FileLogTooltip": "保存日志文件到硬盘。不会影响性能。", + "StubLogTooltip": "在控制台中打印 stub 日志消息。不影响性能。", + "InfoLogTooltip": "在控制台中打印信息日志消息。不影响性能。", + "WarnLogTooltip": "在控制台中打印警告日志消息。不影响性能。", + "ErrorLogTooltip": "打印控制台中的错误日志消息。不影响性能。", + "TraceLogTooltip": "在控制台中打印跟踪日志消息。不影响性能。", + "GuestLogTooltip": "在控制台中打印访客日志消息。不影响性能。", + "FileAccessLogTooltip": "在控制台中打印文件访问日志信息。", + "FSAccessLogModeTooltip": "启用访问日志输出到控制台。可能的模式为 0-3", + "DeveloperOptionTooltip": "谨慎使用", "OpenGlLogLevel": "需要打开适当的日志等级", "DebugLogTooltip": "记录Debug消息", "LoadApplicationFileTooltip": "选择 Switch 支持的游戏格式并加载", @@ -476,18 +493,18 @@ "OpenProfileManagerTooltip": "打开用户账户管理界面", "StopEmulationTooltip": "停止运行当前游戏并回到主界面", "CheckUpdatesTooltip": "检查 Ryujinx 新版本", - "OpenAboutTooltip": "打开'关于'窗口", + "OpenAboutTooltip": "打开“关于”窗口", "GridSize": "网格尺寸", "GridSizeTooltip": "调整网格模式的大小", "SettingsTabSystemSystemLanguageBrazilianPortuguese": "巴西葡萄牙语", "AboutRyujinxContributorsButtonHeader": "查看所有参与者", - "SettingsTabSystemAudioVolume": "音量: ", + "SettingsTabSystemAudioVolume": "音量:", "AudioVolumeTooltip": "调节音量", "SettingsTabSystemEnableInternetAccess": "允许网络访问/局域网模式", - "EnableInternetAccessTooltip": "允许模拟的游戏进程访问互联网。\n当多个模拟器/真实Switch连接到同一个局域网时,带有 LAN 模式的游戏可以相互通信。\n即使开启选项也无法访问 Nintendo 服务器。此外可能导致某些尝试联网的游戏崩溃。\n如果您不确定,请关闭该选项。", + "EnableInternetAccessTooltip": "允许模拟的游戏进程访问互联网。\n当多个模拟器/真实的 Switch 连接到同一个局域网时,带有 LAN 模式的游戏可以相互通信。\n即使开启选项也无法访问 Nintendo 服务器。此外可能导致某些尝试联网的游戏崩溃。\n如果您不确定,请关闭该选项。", "GameListContextMenuManageCheatToolTip": "管理金手指", "GameListContextMenuManageCheat": "管理金手指", - "ControllerSettingsStickRange": "范围", + "ControllerSettingsStickRange": "范围:", "DialogStopEmulationTitle": "Ryujinx - 停止模拟", "DialogStopEmulationMessage": "是否确定停止模拟?", "SettingsTabCpu": "CPU", @@ -497,14 +514,14 @@ "SettingsTabCpuCache": "CPU 缓存", "SettingsTabCpuMemory": "CPU 内存", "DialogUpdaterFlatpakNotSupportedMessage": "请通过 FlatHub 更新 Ryujinx。", - "UpdaterDisabledWarningTitle": "更新已禁用!", + "UpdaterDisabledWarningTitle": "更新已禁用!", "GameListContextMenuOpenSdModsDirectory": "打开 Atmosphere MOD 目录", "GameListContextMenuOpenSdModsDirectoryToolTip": "打开适用于 Atmosphere 自制系统的 MOD 目录", "ControllerSettingsRotate90": "顺时针旋转 90°", "IconSize": "图标尺寸", "IconSizeTooltip": "更改游戏图标大小", "MenuBarOptionsShowConsole": "显示控制台", - "ShaderCachePurgeError": "清除着色器缓存时出错: {0}: {1}", + "ShaderCachePurgeError": "清除着色器缓存时出错:{0}: {1}", "UserErrorNoKeys": "找不到密钥", "UserErrorNoFirmware": "找不到固件", "UserErrorFirmwareParsingFailed": "固件解析错误", @@ -513,25 +530,28 @@ "UserErrorUndefined": "未定义错误", "UserErrorNoKeysDescription": "Ryujinx 找不到 'prod.keys' 文件", "UserErrorNoFirmwareDescription": "Ryujinx 找不到任何已安装的固件", - "UserErrorFirmwareParsingFailedDescription": "Ryujinx 无法解密选择的固件。这通常是由于过旧的密钥。", + "UserErrorFirmwareParsingFailedDescription": "Ryujinx 无法解密选择的固件。这通常是由于使用了过旧的密钥。", "UserErrorApplicationNotFoundDescription": "Ryujinx 在选中路径找不到有效的应用程序。", "UserErrorUnknownDescription": "发生未知错误!", "UserErrorUndefinedDescription": "发生了未定义错误!此类错误不应出现,请联系开发人员!", "OpenSetupGuideMessage": "打开设置教程", "NoUpdate": "无更新", - "TitleUpdateVersionLabel": "版本 {0} - {1}", + "TitleUpdateVersionLabel": "版本 {0}", "RyujinxInfo": "Ryujinx - 信息", "RyujinxConfirm": "Ryujinx - 确认", "FileDialogAllTypes": "全部类型", - "Never": "从未", + "Never": "从不", "SwkbdMinCharacters": "至少应为 {0} 个字长", "SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字长", "SoftwareKeyboard": "软件键盘", - "DialogControllerAppletMessagePlayerRange": "游戏需要 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。", - "DialogControllerAppletMessage": "游戏需要刚好 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3}请打开设置窗口,重新配置手柄输入;或者关闭返回。", + "SoftwareKeyboardModeNumbersOnly": "只接受数字", + "SoftwareKeyboardModeAlphabet": "只接受非中日韩文字", + "SoftwareKeyboardModeASCII": "只接受 ASCII 符号", + "DialogControllerAppletMessagePlayerRange": "游戏需要 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3} 请打开设置窗口,重新配置手柄输入;或者关闭返回。", + "DialogControllerAppletMessage": "游戏需要刚好 {0} 个玩家并满足以下要求:\n\n手柄类型:{1}\n\n玩家类型:{2}\n\n{3} 请打开设置窗口,重新配置手柄输入;或者关闭返回。", "DialogControllerAppletDockModeSet": "目前处于主机模式,无法使用掌机操作方式", "UpdaterRenaming": "正在删除旧文件...", - "UpdaterRenameFailed": "更新过程中无法重命名文件: {0}", + "UpdaterRenameFailed": "更新过程中无法重命名文件:{0}", "UpdaterAddingFiles": "安装更新中...", "UpdaterExtracting": "正在提取更新...", "UpdaterDownloading": "下载新版本中...", @@ -545,17 +565,17 @@ "CompilingPPTC": "编译PPTC缓存中", "CompilingShaders": "编译着色器中", "AllKeyboards": "所有键盘", - "OpenFileDialogTitle": "选择支持的文件格式", + "OpenFileDialogTitle": "选择一个支持的文件以打开", "OpenFolderDialogTitle": "选择一个包含解包游戏的文件夹", "AllSupportedFormats": "所有支持的格式", "RyujinxUpdater": "Ryujinx 更新程序", "SettingsTabHotkeys": "快捷键", "SettingsTabHotkeysHotkeys": "键盘快捷键", - "SettingsTabHotkeysToggleVsyncHotkey": "切换垂直同步", - "SettingsTabHotkeysScreenshotHotkey": "截屏", - "SettingsTabHotkeysShowUiHotkey": "隐藏UI", - "SettingsTabHotkeysPauseHotkey": "暂停", - "SettingsTabHotkeysToggleMuteHotkey": "静音", + "SettingsTabHotkeysToggleVsyncHotkey": "切换垂直同步:", + "SettingsTabHotkeysScreenshotHotkey": "截屏:", + "SettingsTabHotkeysShowUiHotkey": "隐藏 界面:", + "SettingsTabHotkeysPauseHotkey": "暂停:", + "SettingsTabHotkeysToggleMuteHotkey": "静音:", "ControllerMotionTitle": "体感操作设置", "ControllerRumbleTitle": "震动设置", "SettingsSelectThemeFileDialogTitle": "选择主题文件", @@ -569,9 +589,10 @@ "SelectUpdateDialogTitle": "选择更新文件", "UserProfileWindowTitle": "管理用户账户", "CheatWindowTitle": "金手指管理器", - "DlcWindowTitle": "管理游戏 DLC", + "DlcWindowTitle": "管理 {0} ({1}) 的 DLC", "UpdateWindowTitle": "游戏更新管理器", "CheatWindowHeading": "适用于 {0} [{1}] 的金手指", + "BuildId": "游戏版本ID:", "DlcWindowHeading": "{0} 个适用于 {1} ({2}) 的 DLC", "UserProfilesEditProfile": "编辑选中账户", "Cancel": "取消", @@ -580,35 +601,56 @@ "UserProfilesSetProfileImage": "选择头像", "UserProfileEmptyNameError": "必须输入名称", "UserProfileNoImageError": "请选择您的头像", - "GameUpdateWindowHeading": "{0} 个适用于 {1} ({2}) 的更新", - "SettingsTabHotkeysResScaleUpHotkey": "提高分辨率:", - "SettingsTabHotkeysResScaleDownHotkey": "降低分辨率:", - "UserProfilesName": "名称:", - "UserProfilesUserId": "用户 ID:", + "GameUpdateWindowHeading": "管理 {0} ({1}) 的更新", + "SettingsTabHotkeysResScaleUpHotkey": "提高分辨率:", + "SettingsTabHotkeysResScaleDownHotkey": "降低分辨率:", + "UserProfilesName": "名称:", + "UserProfilesUserId": "用户ID:", "SettingsTabGraphicsBackend": "图形后端", "SettingsTabGraphicsBackendTooltip": "显卡使用的图形后端", "SettingsEnableTextureRecompression": "启用纹理重压缩", - "SettingsEnableTextureRecompressionTooltip": "压缩某些纹理以减少显存的使用。\n适合显存小于 4GiB 的 GPU开启。\n如果您不确定,请保持此项为关闭。", + "SettingsEnableTextureRecompressionTooltip": "压缩某些纹理以减少显存的使用。\n适合显存小于 4GiB 的 GPU 开启。\n如果您不确定,请保持此项关闭。", "SettingsTabGraphicsPreferredGpu": "首选 GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "选择Vulkan API使用的显卡。\n此选项不会影响OpenGL API。\n如果您不确定,建议选择\"dGPU(独立显卡)\"。如果没有独立显卡,则无需改动此选项", + "SettingsTabGraphicsPreferredGpuTooltip": "选择 Vulkan API 使用的显卡。\n此选项不会影响 OpenGL API。\n如果您不确定,建议选择\"dGPU(独立显卡)\"。如果没有独立显卡,则无需改动此选项。", "SettingsAppRequiredRestartMessage": "Ryujinx 需要重启", "SettingsGpuBackendRestartMessage": "您修改了图形 API 或显卡设置。需要重新启动才能生效", "SettingsGpuBackendRestartSubMessage": "是否重启模拟器?", "RyujinxUpdaterMessage": "是否更新 Ryujinx 到最新的版本?", - "SettingsTabHotkeysVolumeUpHotkey": "音量加", - "SettingsTabHotkeysVolumeDownHotkey": "音量减", + "SettingsTabHotkeysVolumeUpHotkey": "音量加:", + "SettingsTabHotkeysVolumeDownHotkey": "音量减:", "SettingsEnableMacroHLE": "启用 HLE 宏", - "SettingsEnableMacroHLETooltip": "GPU 宏代码的高级模拟。\n提高性能表现,但可能在某些游戏中引起图形错误。\n如果您不确定,请保持此项为开启。", + "SettingsEnableMacroHLETooltip": "GPU 宏代码的高级模拟。\n提高性能表现,但可能在某些游戏中引起图形错误。\n如果您不确定,请保持此项开启。", + "SettingsEnableColorSpacePassthrough": "颜色空间穿透", + "SettingsEnableColorSpacePassthroughTooltip": "指示 Vulkan 后端在不指定颜色空间的情况下传递颜色信息。对于具有宽色域显示器的用户来说,这可能会以颜色正确性为代价,产生更鲜艳的颜色。", "VolumeShort": "音量", "UserProfilesManageSaves": "管理存档", "DeleteUserSave": "确定删除这个游戏的存档吗?", "IrreversibleActionNote": "删除后不可恢复。", - "SaveManagerHeading": "管理 {0} 的存档", + "SaveManagerHeading": "管理 {0} ({1}) 的存档", "SaveManagerTitle": "存档管理器", "Name": "名称", "Size": "大小", "Search": "搜索", "UserProfilesRecoverLostAccounts": "恢复丢失的账户", "Recover": "恢复", - "UserProfilesRecoverHeading": "找到了这些用户的存档数据" -} + "UserProfilesRecoverHeading": "找到了这些用户的存档数据", + "UserProfilesRecoverEmptyList": "没有可以恢复的配置文件", + "GraphicsAATooltip": "将抗锯齿使用到游戏渲染中", + "GraphicsAALabel": "抗锯齿:", + "GraphicsScalingFilterLabel": "缩放过滤:", + "GraphicsScalingFilterTooltip": "对帧缓冲区进行缩放", + "GraphicsScalingFilterLevelLabel": "等级", + "GraphicsScalingFilterLevelTooltip": "设置缩放过滤级别", + "SmaaLow": "SMAA 低质量", + "SmaaMedium": "SMAA 中质量", + "SmaaHigh": "SMAA 高质量", + "SmaaUltra": "SMAA 极致质量", + "UserEditorTitle": "编辑用户", + "UserEditorTitleCreate": "创建用户", + "SettingsTabNetworkInterface": "网络接口:", + "NetworkInterfaceTooltip": "用于局域网功能的网络接口", + "NetworkInterfaceDefault": "默认", + "PackagingShaders": "整合着色器中", + "AboutChangelogButton": "在Github上查看更新日志", + "AboutChangelogButtonTooltipMessage": "点击这里在您的默认浏览器中打开此版本的更新日志。" +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/zh_TW.json b/src/Ryujinx.Ava/Assets/Locales/zh_TW.json index 940282a0f..a2f59f60d 100644 --- a/src/Ryujinx.Ava/Assets/Locales/zh_TW.json +++ b/src/Ryujinx.Ava/Assets/Locales/zh_TW.json @@ -1,15 +1,16 @@ { - "Language": "繁體中文", - "MenuBarFileOpenApplet": "打開小程式", - "MenuBarFileOpenAppletOpenMiiAppletToolTip": "打開獨立的 Mii 小程式", - "SettingsTabInputDirectMouseAccess": "直通滑鼠操作", - "SettingsTabSystemMemoryManagerMode": "記憶體管理模式:", + "Language": "英文 (美國)", + "MenuBarFileOpenApplet": "開啟 Applet 應用程序", + "MenuBarFileOpenAppletOpenMiiAppletToolTip": "開啟獨立的Mii修改器應用程序", + "SettingsTabInputDirectMouseAccess": "滑鼠直接操作", + "SettingsTabSystemMemoryManagerMode": "記憶體管理模式:", "SettingsTabSystemMemoryManagerModeSoftware": "軟體", - "SettingsTabSystemMemoryManagerModeHost": "Host (快速)", - "SettingsTabSystemMemoryManagerModeHostUnchecked": "Host 略過檢查 (最快,但較不安全)", + "SettingsTabSystemMemoryManagerModeHost": "主機模式 (快速)", + "SettingsTabSystemMemoryManagerModeHostUnchecked": "主機略過檢查模式 (最快, 但不安全)", + "SettingsTabSystemUseHypervisor": "使用 Hypervisor", "MenuBarFile": "_檔案", "MenuBarFileOpenFromFile": "_載入檔案", - "MenuBarFileOpenUnpacked": "載入_解包後的遊戲", + "MenuBarFileOpenUnpacked": "載入_已解開封裝的遊戲", "MenuBarFileOpenEmuFolder": "開啟 Ryujinx 資料夾", "MenuBarFileOpenLogsFolder": "開啟日誌資料夾", "MenuBarFileExit": "_退出", @@ -18,7 +19,7 @@ "MenuBarOptionsStartGamesInFullscreen": "使用全螢幕模式啟動遊戲", "MenuBarOptionsStopEmulation": "停止模擬", "MenuBarOptionsSettings": "_設定", - "MenuBarOptionsManageUserProfiles": "_管理使用者帳號", + "MenuBarOptionsManageUserProfiles": "_管理使用者帳戶", "MenuBarActions": "_動作", "MenuBarOptionsSimulateWakeUpMessage": "模擬喚醒訊息", "MenuBarActionsScanAmiibo": "掃描 Amiibo", @@ -26,6 +27,9 @@ "MenuBarToolsInstallFirmware": "安裝韌體", "MenuBarFileToolsInstallFirmwareFromFile": "從 XCI 或 ZIP 安裝韌體", "MenuBarFileToolsInstallFirmwareFromDirectory": "從資料夾安裝韌體", + "MenuBarToolsManageFileTypes": "管理檔案類型", + "MenuBarToolsInstallFileTypes": "註冊檔案類型", + "MenuBarToolsUninstallFileTypes": "取消註冊檔案類型", "MenuBarHelp": "幫助", "MenuBarHelpCheckForUpdates": "檢查更新", "MenuBarHelpAbout": "關於", @@ -33,34 +37,34 @@ "GameListHeaderFavorite": "收藏", "GameListHeaderIcon": "圖示", "GameListHeaderApplication": "名稱", - "GameListHeaderDeveloper": "開發商", + "GameListHeaderDeveloper": "開發人員", "GameListHeaderVersion": "版本", - "GameListHeaderTimePlayed": "遊玩時間", - "GameListHeaderLastPlayed": "上次遊玩", + "GameListHeaderTimePlayed": "遊玩時數", + "GameListHeaderLastPlayed": "最近遊玩", "GameListHeaderFileExtension": "副檔名", - "GameListHeaderFileSize": "大小", + "GameListHeaderFileSize": "檔案大小", "GameListHeaderPath": "路徑", "GameListContextMenuOpenUserSaveDirectory": "開啟使用者存檔資料夾", - "GameListContextMenuOpenUserSaveDirectoryToolTip": "開啟儲存遊戲存檔的資料夾", + "GameListContextMenuOpenUserSaveDirectoryToolTip": "開啟此遊戲的存檔資料夾", "GameListContextMenuOpenDeviceSaveDirectory": "開啟系統資料夾", - "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "開啟包含遊戲系統設定的資料夾", + "GameListContextMenuOpenDeviceSaveDirectoryToolTip": "開啟此遊戲的系統設定資料夾", "GameListContextMenuOpenBcatSaveDirectory": "開啟 BCAT 資料夾", - "GameListContextMenuOpenBcatSaveDirectoryToolTip": "開啟包含遊戲 BCAT 資料的資料夾", + "GameListContextMenuOpenBcatSaveDirectoryToolTip": "開啟此遊戲的 BCAT 資料夾\n", "GameListContextMenuManageTitleUpdates": "管理遊戲更新", - "GameListContextMenuManageTitleUpdatesToolTip": "開啟更新管理視窗", + "GameListContextMenuManageTitleUpdatesToolTip": "開啟遊戲更新管理視窗", "GameListContextMenuManageDlc": "管理 DLC", "GameListContextMenuManageDlcToolTip": "開啟 DLC 管理視窗", "GameListContextMenuOpenModsDirectory": "開啟模組資料夾", - "GameListContextMenuOpenModsDirectoryToolTip": "開啟存放遊戲模組的資料夾", + "GameListContextMenuOpenModsDirectoryToolTip": "開啟此遊戲的模組資料夾", "GameListContextMenuCacheManagement": "快取管理", "GameListContextMenuCacheManagementPurgePptc": "清除 PPTC 快取", "GameListContextMenuCacheManagementPurgePptcToolTip": "刪除遊戲的 PPTC 快取", - "GameListContextMenuCacheManagementPurgeShaderCache": "清除渲染器快取", - "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "刪除遊戲的渲染器快取", + "GameListContextMenuCacheManagementPurgeShaderCache": "清除著色器快取", + "GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "刪除遊戲的著色器快取", "GameListContextMenuCacheManagementOpenPptcDirectory": "開啟 PPTC 資料夾", - "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "開啟包含遊戲 PPTC 快取的資料夾", - "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "開啟渲染器快取資料夾", - "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "開啟包含應用程式渲染器快取的資料夾", + "GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "開啟此遊戲的 PPTC 快取資料夾", + "GameListContextMenuCacheManagementOpenShaderCacheDirectory": "開啟著色器快取資料夾", + "GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "開啟此遊戲的著色器快取資料夾", "GameListContextMenuExtractData": "提取資料", "GameListContextMenuExtractDataExeFS": "ExeFS", "GameListContextMenuExtractDataExeFSToolTip": "從遊戲的目前狀態中提取 ExeFS 分區(包含更新)", @@ -69,14 +73,24 @@ "GameListContextMenuExtractDataLogo": "圖示", "GameListContextMenuExtractDataLogoToolTip": "從遊戲的目前狀態中提取圖示(包含更新)", "StatusBarGamesLoaded": "{0}/{1} 遊戲載入完成", - "StatusBarSystemVersion": "系統版本: {0}", + "StatusBarSystemVersion": "系統版本: {0}", + "LinuxVmMaxMapCountDialogTitle": "檢測到映射的記憶體上限過低", + "LinuxVmMaxMapCountDialogTextPrimary": "你願意增加 vm.max_map_count to {0} 的數值嗎?", + "LinuxVmMaxMapCountDialogTextSecondary": "遊戲佔用的記憶體超出了映射的上限. Ryujinx的處理程序即將面臨崩潰.", + "LinuxVmMaxMapCountDialogButtonUntilRestart": "碓定 (直至下一次重新啟動)", + "LinuxVmMaxMapCountDialogButtonPersistent": "碓定 (永遠設定)", + "LinuxVmMaxMapCountWarningTextPrimary": "映射記憶體的最大值少於目前建議的下限.", + "LinuxVmMaxMapCountWarningTextSecondary": "目前 vm.max_map_count ({0}) 的數值少於 {1}. 遊戲佔用的記憶體超出了映射的上限. Ryujinx的處理程序即將面臨崩潰.\n\n你可能需要手動增加上限或安裝 pkexec, 這些都能協助Ryujinx完成此操作.", "Settings": "設定", "SettingsTabGeneral": "使用者介面", "SettingsTabGeneralGeneral": "一般", "SettingsTabGeneralEnableDiscordRichPresence": "啟用 Discord 動態狀態展示", "SettingsTabGeneralCheckUpdatesOnLaunch": "自動檢查更新", "SettingsTabGeneralShowConfirmExitDialog": "顯示「確認離開」對話框", + "SettingsTabGeneralHideCursor": "隱藏滑鼠遊標:", + "SettingsTabGeneralHideCursorNever": "永不", "SettingsTabGeneralHideCursorOnIdle": "自動隱藏滑鼠", + "SettingsTabGeneralHideCursorAlways": "總是", "SettingsTabGeneralGameDirectories": "遊戲資料夾", "SettingsTabGeneralAdd": "新增", "SettingsTabGeneralRemove": "刪除", @@ -91,85 +105,86 @@ "SettingsTabSystemSystemRegionKorea": "韓國", "SettingsTabSystemSystemRegionTaiwan": "台灣", "SettingsTabSystemSystemLanguage": "系統語言:", - "SettingsTabSystemSystemLanguageJapanese": "日語", - "SettingsTabSystemSystemLanguageAmericanEnglish": "美式英語", - "SettingsTabSystemSystemLanguageFrench": "法語", - "SettingsTabSystemSystemLanguageGerman": "德語", - "SettingsTabSystemSystemLanguageItalian": "義大利語", - "SettingsTabSystemSystemLanguageSpanish": "西班牙語", + "SettingsTabSystemSystemLanguageJapanese": "日文", + "SettingsTabSystemSystemLanguageAmericanEnglish": "英文 (美國)", + "SettingsTabSystemSystemLanguageFrench": "法文", + "SettingsTabSystemSystemLanguageGerman": "德文", + "SettingsTabSystemSystemLanguageItalian": "義大利文", + "SettingsTabSystemSystemLanguageSpanish": "西班牙文", "SettingsTabSystemSystemLanguageChinese": "中文 (中國)", - "SettingsTabSystemSystemLanguageKorean": "韓語", - "SettingsTabSystemSystemLanguageDutch": "荷蘭語", - "SettingsTabSystemSystemLanguagePortuguese": "葡萄牙語", - "SettingsTabSystemSystemLanguageRussian": "俄語", + "SettingsTabSystemSystemLanguageKorean": "韓文", + "SettingsTabSystemSystemLanguageDutch": "荷蘭文", + "SettingsTabSystemSystemLanguagePortuguese": "葡萄牙文", + "SettingsTabSystemSystemLanguageRussian": "俄文", "SettingsTabSystemSystemLanguageTaiwanese": "中文 (台灣)", - "SettingsTabSystemSystemLanguageBritishEnglish": "英式英語", + "SettingsTabSystemSystemLanguageBritishEnglish": "英文 (英國)", "SettingsTabSystemSystemLanguageCanadianFrench": "加拿大法語", - "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "拉美西班牙語", - "SettingsTabSystemSystemLanguageSimplifiedChinese": "簡體中文 (推薦)", - "SettingsTabSystemSystemLanguageTraditionalChinese": "繁體中文 (推薦)", - "SettingsTabSystemSystemTimeZone": "系統時區:", - "SettingsTabSystemSystemTime": "系統時鐘:", - "SettingsTabSystemEnableVsync": "開啟 VSync", - "SettingsTabSystemEnablePptc": "開啟 PPTC 快取", + "SettingsTabSystemSystemLanguageLatinAmericanSpanish": "拉丁美洲西班牙文", + "SettingsTabSystemSystemLanguageSimplifiedChinese": "簡體中文", + "SettingsTabSystemSystemLanguageTraditionalChinese": "繁體中文", + "SettingsTabSystemSystemTimeZone": "系統時區:", + "SettingsTabSystemSystemTime": "系統時鐘:", + "SettingsTabSystemEnableVsync": "垂直同步", + "SettingsTabSystemEnablePptc": "啟用 PPTC 快取", "SettingsTabSystemEnableFsIntegrityChecks": "開啟檔案系統完整性檢查", - "SettingsTabSystemAudioBackend": "音訊後端:", - "SettingsTabSystemAudioBackendDummy": "無", + "SettingsTabSystemAudioBackend": "音效處理後台架構:", + "SettingsTabSystemAudioBackendDummy": "模擬", "SettingsTabSystemAudioBackendOpenAL": "OpenAL", "SettingsTabSystemAudioBackendSoundIO": "SoundIO", "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "修正", "SettingsTabSystemHacksNote": " (會引起模擬器不穩定)", - "SettingsTabSystemExpandDramSize": "使用替代記憶體布局 (開發人員)", + "SettingsTabSystemExpandDramSize": "使用額外的記憶體佈局 (開發人員)", "SettingsTabSystemIgnoreMissingServices": "忽略缺少的服務", - "SettingsTabGraphics": "圖形", - "SettingsTabGraphicsAPI": "圖形 API", - "SettingsTabGraphicsEnableShaderCache": "啟用渲染器快取", - "SettingsTabGraphicsAnisotropicFiltering": "各向異性過濾:", + "SettingsTabGraphics": "圖像", + "SettingsTabGraphicsAPI": "圖像處理應用程式介面", + "SettingsTabGraphicsEnableShaderCache": "啟用著色器快取", + "SettingsTabGraphicsAnisotropicFiltering": "各向異性過濾:", "SettingsTabGraphicsAnisotropicFilteringAuto": "自動", "SettingsTabGraphicsAnisotropicFiltering2x": "2 倍", "SettingsTabGraphicsAnisotropicFiltering4x": "4 倍", "SettingsTabGraphicsAnisotropicFiltering8x": "8 倍", "SettingsTabGraphicsAnisotropicFiltering16x": "16倍", - "SettingsTabGraphicsResolutionScale": "解析度縮放:", - "SettingsTabGraphicsResolutionScaleCustom": "自訂 (不推薦)", + "SettingsTabGraphicsResolutionScale": "解析度比例:", + "SettingsTabGraphicsResolutionScaleCustom": "自訂 (不建議使用)", "SettingsTabGraphicsResolutionScaleNative": "原生 (720p/1080p)", "SettingsTabGraphicsResolutionScale2x": "2 倍 (1440p/2160p)", "SettingsTabGraphicsResolutionScale3x": "3 倍 (2160p/3240p)", "SettingsTabGraphicsResolutionScale4x": "4 倍 (2880p/4320p)", - "SettingsTabGraphicsAspectRatio": "寬高比:", - "SettingsTabGraphicsAspectRatio4x3": "4:3", - "SettingsTabGraphicsAspectRatio16x9": "16:9", - "SettingsTabGraphicsAspectRatio16x10": "16:10", - "SettingsTabGraphicsAspectRatio21x9": "21:9", - "SettingsTabGraphicsAspectRatio32x9": "32:9", - "SettingsTabGraphicsAspectRatioStretch": "拉伸至螢幕大小", + "SettingsTabGraphicsAspectRatio": "螢幕長寬比例:", + "SettingsTabGraphicsAspectRatio4x3": "4:3", + "SettingsTabGraphicsAspectRatio16x9": "16:9", + "SettingsTabGraphicsAspectRatio16x10": "16:10", + "SettingsTabGraphicsAspectRatio21x9": "21:9", + "SettingsTabGraphicsAspectRatio32x9": "32:9", + "SettingsTabGraphicsAspectRatioStretch": "伸展至螢幕大小", "SettingsTabGraphicsDeveloperOptions": "開發者選項", - "SettingsTabGraphicsShaderDumpPath": "圖形渲染器轉儲路徑:", + "SettingsTabGraphicsShaderDumpPath": "圖形著色器轉存路徑:", "SettingsTabLogging": "日誌", "SettingsTabLoggingLogging": "日誌", - "SettingsTabLoggingEnableLoggingToFile": "儲存日誌為檔案", - "SettingsTabLoggingEnableStubLogs": "記錄 Stub", - "SettingsTabLoggingEnableInfoLogs": "記錄資訊", - "SettingsTabLoggingEnableWarningLogs": "記錄警告", - "SettingsTabLoggingEnableErrorLogs": "記錄錯誤", - "SettingsTabLoggingEnableTraceLogs": "記錄 Trace", - "SettingsTabLoggingEnableGuestLogs": "記錄 Guest", - "SettingsTabLoggingEnableFsAccessLogs": "記錄檔案存取", - "SettingsTabLoggingFsGlobalAccessLogMode": "記錄全域檔案存取模式:", - "SettingsTabLoggingDeveloperOptions": "開發者選項 (警告: 會降低效能)", - "SettingsTabLoggingGraphicsBackendLogLevel": "圖形顯示後端日誌等級:", + "SettingsTabLoggingEnableLoggingToFile": "儲存記錄日誌為檔案", + "SettingsTabLoggingEnableStubLogs": "啟用 Stub 記錄", + "SettingsTabLoggingEnableInfoLogs": "啟用資訊記錄", + "SettingsTabLoggingEnableWarningLogs": "啟用警告記錄", + "SettingsTabLoggingEnableErrorLogs": "啟用錯誤記錄", + "SettingsTabLoggingEnableTraceLogs": "啟用追蹤記錄", + "SettingsTabLoggingEnableGuestLogs": "啟用賓客記錄", + "SettingsTabLoggingEnableFsAccessLogs": "啟用檔案存取記錄", + "SettingsTabLoggingFsGlobalAccessLogMode": "記錄全域檔案存取模式:", + "SettingsTabLoggingDeveloperOptions": "開發者選項", + "SettingsTabLoggingDeveloperOptionsNote": "警告:此操作會降低效能", + "SettingsTabLoggingGraphicsBackendLogLevel": "圖像處理後台記錄等級:", "SettingsTabLoggingGraphicsBackendLogLevelNone": "無", "SettingsTabLoggingGraphicsBackendLogLevelError": "錯誤", "SettingsTabLoggingGraphicsBackendLogLevelPerformance": "減速", "SettingsTabLoggingGraphicsBackendLogLevelAll": "全部", - "SettingsTabLoggingEnableDebugLogs": "啟用除錯日誌", + "SettingsTabLoggingEnableDebugLogs": "啟用除錯記錄", "SettingsTabInput": "輸入", "SettingsTabInputEnableDockedMode": "Docked 模式", - "SettingsTabInputDirectKeyboardAccess": "直通鍵盤控制", + "SettingsTabInputDirectKeyboardAccess": "鍵盤直接操作", "SettingsButtonSave": "儲存", "SettingsButtonClose": "關閉", - "SettingsButtonOk": "嘛好", + "SettingsButtonOk": "確定", "SettingsButtonCancel": "取消", "SettingsButtonApply": "套用", "ControllerSettingsPlayer": "玩家", @@ -182,21 +197,21 @@ "ControllerSettingsPlayer7": "玩家 7", "ControllerSettingsPlayer8": "玩家 8", "ControllerSettingsHandheld": "掌機模式", - "ControllerSettingsInputDevice": "輸入設備", + "ControllerSettingsInputDevice": "輸入裝置", "ControllerSettingsRefresh": "更新", "ControllerSettingsDeviceDisabled": "關閉", - "ControllerSettingsControllerType": "手把類型", + "ControllerSettingsControllerType": "控制器類型", "ControllerSettingsControllerTypeHandheld": "掌機", - "ControllerSettingsControllerTypeProController": "Pro 手把", + "ControllerSettingsControllerTypeProController": "Nintendo Switch Pro控制器", "ControllerSettingsControllerTypeJoyConPair": "JoyCon", "ControllerSettingsControllerTypeJoyConLeft": "左 JoyCon", "ControllerSettingsControllerTypeJoyConRight": "右 JoyCon", - "ControllerSettingsProfile": "預設", + "ControllerSettingsProfile": "配置檔案", "ControllerSettingsProfileDefault": "預設", "ControllerSettingsLoad": "載入", "ControllerSettingsAdd": "建立", "ControllerSettingsRemove": "刪除", - "ControllerSettingsButtons": "按鈕", + "ControllerSettingsButtons": "按鍵", "ControllerSettingsButtonA": "A", "ControllerSettingsButtonB": "B", "ControllerSettingsButtonX": "X", @@ -208,26 +223,17 @@ "ControllerSettingsDPadDown": "下", "ControllerSettingsDPadLeft": "左", "ControllerSettingsDPadRight": "右", + "ControllerSettingsStickButton": "按鍵", + "ControllerSettingsStickUp": "上", + "ControllerSettingsStickDown": "下", + "ControllerSettingsStickLeft": "左", + "ControllerSettingsStickRight": "右", + "ControllerSettingsStickStick": "搖桿", + "ControllerSettingsStickInvertXAxis": "搖桿左右反向", + "ControllerSettingsStickInvertYAxis": "搖桿上下反向", + "ControllerSettingsStickDeadzone": "盲區:", "ControllerSettingsLStick": "左搖桿", - "ControllerSettingsLStickButton": "按下", - "ControllerSettingsLStickUp": "上", - "ControllerSettingsLStickDown": "下", - "ControllerSettingsLStickLeft": "左", - "ControllerSettingsLStickRight": "右", - "ControllerSettingsLStickStick": "桿", - "ControllerSettingsLStickInvertXAxis": "反轉 X 方向", - "ControllerSettingsLStickInvertYAxis": "反轉 Y 方向", - "ControllerSettingsLStickDeadzone": "死區:", "ControllerSettingsRStick": "右搖桿", - "ControllerSettingsRStickButton": "按下", - "ControllerSettingsRStickUp": "上", - "ControllerSettingsRStickDown": "下", - "ControllerSettingsRStickLeft": "左", - "ControllerSettingsRStickRight": "右", - "ControllerSettingsRStickStick": "桿", - "ControllerSettingsRStickInvertXAxis": "反轉 X 方向", - "ControllerSettingsRStickInvertYAxis": "反轉 Y 方向", - "ControllerSettingsRStickDeadzone": "死區:", "ControllerSettingsTriggersLeft": "左 Triggers", "ControllerSettingsTriggersRight": "右 Triggers", "ControllerSettingsTriggersButtonsLeft": "左 Triggers 鍵", @@ -244,69 +250,71 @@ "ControllerSettingsExtraButtonsLeft": "左按鍵", "ControllerSettingsExtraButtonsRight": "右按鍵", "ControllerSettingsMisc": "其他", - "ControllerSettingsTriggerThreshold": "Triggers 閾值:", - "ControllerSettingsMotion": "體感", - "ControllerSettingsMotionUseCemuhookCompatibleMotion": "使用 CemuHook 體感協議", - "ControllerSettingsMotionControllerSlot": "手把:", - "ControllerSettingsMotionMirrorInput": "鏡像操作", - "ControllerSettingsMotionRightJoyConSlot": "右 JoyCon:", - "ControllerSettingsMotionServerHost": "伺服器 Host:", - "ControllerSettingsMotionGyroSensitivity": "陀螺儀敏感度:", - "ControllerSettingsMotionGyroDeadzone": "陀螺儀死區:", + "ControllerSettingsTriggerThreshold": "Triggers 閾值:", + "ControllerSettingsMotion": "傳感器", + "ControllerSettingsMotionUseCemuhookCompatibleMotion": "使用 CemuHook 相容性傳感協定", + "ControllerSettingsMotionControllerSlot": "控制器插槽:", + "ControllerSettingsMotionMirrorInput": "鏡像輸入", + "ControllerSettingsMotionRightJoyConSlot": "右 JoyCon:", + "ControllerSettingsMotionServerHost": "伺服器IP地址:", + "ControllerSettingsMotionGyroSensitivity": "陀螺儀敏感度:", + "ControllerSettingsMotionGyroDeadzone": "陀螺儀盲區:", "ControllerSettingsSave": "儲存", "ControllerSettingsClose": "關閉", - "UserProfilesSelectedUserProfile": "選擇使用者帳號:", - "UserProfilesSaveProfileName": "儲存帳號名稱", - "UserProfilesChangeProfileImage": "更換頭貼", - "UserProfilesAvailableUserProfiles": "現有的帳號:", - "UserProfilesAddNewProfile": "建立帳號", + "UserProfilesSelectedUserProfile": "選擇使用者帳戶:", + "UserProfilesSaveProfileName": "儲存帳戶名稱", + "UserProfilesChangeProfileImage": "更換帳戶頭像", + "UserProfilesAvailableUserProfiles": "現有的使用者帳戶:", + "UserProfilesAddNewProfile": "建立帳戶", "UserProfilesDelete": "刪除", "UserProfilesClose": "關閉", - "ProfileImageSelectionTitle": "頭貼選擇", - "ProfileImageSelectionHeader": "選擇合適的頭貼圖片", - "ProfileImageSelectionNote": "您可以導入自訂頭貼,或從系統中選擇頭貼", + "ProfileNameSelectionWatermark": "選擇一個暱稱", + "ProfileImageSelectionTitle": "帳戶頭像選擇", + "ProfileImageSelectionHeader": "選擇帳戶頭像", + "ProfileImageSelectionNote": "你可以導入自訂頭像,或從系統中選擇頭像", "ProfileImageSelectionImportImage": "導入圖片檔案", - "ProfileImageSelectionSelectAvatar": "選擇系統頭貼", + "ProfileImageSelectionSelectAvatar": "選擇系統頭像", "InputDialogTitle": "輸入對話框", "InputDialogOk": "完成", "InputDialogCancel": "取消", - "InputDialogAddNewProfileTitle": "選擇使用者名稱", - "InputDialogAddNewProfileHeader": "請輸入帳號名稱", - "InputDialogAddNewProfileSubtext": "(最大長度: {0})", + "InputDialogAddNewProfileTitle": "選擇帳戶名稱", + "InputDialogAddNewProfileHeader": "請輸入帳戶名稱", + "InputDialogAddNewProfileSubtext": "(最大長度:{0})", "AvatarChoose": "選擇", "AvatarSetBackgroundColor": "設定背景顏色", "AvatarClose": "關閉", - "ControllerSettingsLoadProfileToolTip": "載入預設", - "ControllerSettingsAddProfileToolTip": "新增預設", - "ControllerSettingsRemoveProfileToolTip": "刪除預設", - "ControllerSettingsSaveProfileToolTip": "儲存預設", + "ControllerSettingsLoadProfileToolTip": "載入配置檔案", + "ControllerSettingsAddProfileToolTip": "新增配置檔案", + "ControllerSettingsRemoveProfileToolTip": "刪除配置檔案", + "ControllerSettingsSaveProfileToolTip": "儲存配置檔案", "MenuBarFileToolsTakeScreenshot": "儲存截圖", - "MenuBarFileToolsHideUi": "Hide UI", + "MenuBarFileToolsHideUi": "隱藏使用者介面", + "GameListContextMenuRunApplication": "執行程式", "GameListContextMenuToggleFavorite": "標記為收藏", "GameListContextMenuToggleFavoriteToolTip": "啟用或取消收藏標記", - "SettingsTabGeneralTheme": "主題", - "SettingsTabGeneralThemeCustomTheme": "自定主題路徑", - "SettingsTabGeneralThemeBaseStyle": "主題樣式", + "SettingsTabGeneralTheme": "佈景主題", + "SettingsTabGeneralThemeCustomTheme": "自訂佈景主題路徑", + "SettingsTabGeneralThemeBaseStyle": "基本佈景主題式樣", "SettingsTabGeneralThemeBaseStyleDark": "深色模式", "SettingsTabGeneralThemeBaseStyleLight": "淺色模式", - "SettingsTabGeneralThemeEnableCustomTheme": "使用自訂主題介面", + "SettingsTabGeneralThemeEnableCustomTheme": "使用自訂佈景主題", "ButtonBrowse": "瀏覽", "ControllerSettingsConfigureGeneral": "配置", "ControllerSettingsRumble": "震動", "ControllerSettingsRumbleStrongMultiplier": "強震動調節", "ControllerSettingsRumbleWeakMultiplier": "弱震動調節", "DialogMessageSaveNotAvailableMessage": "沒有{0} [{1:x16}]的遊戲存檔", - "DialogMessageSaveNotAvailableCreateSaveMessage": "是否建立該遊戲的存檔資料夾?", + "DialogMessageSaveNotAvailableCreateSaveMessage": "是否建立該遊戲的存檔資料夾?", "DialogConfirmationTitle": "Ryujinx - 設定", "DialogUpdaterTitle": "Ryujinx - 更新", "DialogErrorTitle": "Ryujinx - 錯誤", "DialogWarningTitle": "Ryujinx - 警告", "DialogExitTitle": "Ryujinx - 關閉", "DialogErrorMessage": "Ryujinx 遇到了錯誤", - "DialogExitMessage": "是否關閉 Ryujinx?", - "DialogExitSubMessage": "所有未儲存的進度會遺失!", - "DialogMessageCreateSaveErrorMessage": "建立特定的存檔時出錯: {0}", - "DialogMessageFindSaveErrorMessage": "查找特定的存檔時出錯: {0}", + "DialogExitMessage": "你確定要關閉 Ryujinx 嗎?", + "DialogExitSubMessage": "所有未儲存的資料將會遺失!", + "DialogMessageCreateSaveErrorMessage": "建立特定的存檔時出現錯誤: {0}", + "DialogMessageFindSaveErrorMessage": "查找特定的存檔時出現錯誤: {0}", "FolderDialogExtractTitle": "選擇要解壓到的資料夾", "DialogNcaExtractionMessage": "提取{1}的{0}分區...", "DialogNcaExtractionTitle": "Ryujinx - NCA分區提取", @@ -315,74 +323,81 @@ "DialogNcaExtractionSuccessMessage": "提取成功。", "DialogUpdaterConvertFailedMessage": "無法轉換目前 Ryujinx 版本。", "DialogUpdaterCancelUpdateMessage": "更新取消!", - "DialogUpdaterAlreadyOnLatestVersionMessage": "您使用的 Ryujinx 是最新版本。", - "DialogUpdaterFailedToGetVersionMessage": "嘗試從 Github 取得版本訊息時無效。可能是因為 GitHub Actions 正在編譯新版本。請過幾分鐘重試。", + "DialogUpdaterAlreadyOnLatestVersionMessage": "你使用的 Ryujinx 是最新版本。", + "DialogUpdaterFailedToGetVersionMessage": "嘗試從 Github 取得版本訊息時失敗。可能是因為 GitHub Actions 正在編譯新版本。請於數分數後重試。", "DialogUpdaterConvertFailedGithubMessage": "無法轉換從 Github 接收到的 Ryujinx 版本。", - "DialogUpdaterDownloadingMessage": "下載新版本中...", + "DialogUpdaterDownloadingMessage": "下載最新版本中...", "DialogUpdaterExtractionMessage": "正在提取更新...", "DialogUpdaterRenamingMessage": "正在刪除舊檔案...", "DialogUpdaterAddingFilesMessage": "安裝更新中...", "DialogUpdaterCompleteMessage": "更新成功!", - "DialogUpdaterRestartMessage": "立即重啟 Ryujinx 完成更新?", - "DialogUpdaterArchNotSupportedMessage": "您執行的系統架構不受支援!", + "DialogUpdaterRestartMessage": "你確定要立即重新啟動 Ryujinx 嗎?", + "DialogUpdaterArchNotSupportedMessage": "你執行的系統架構不被支援!", "DialogUpdaterArchNotSupportedSubMessage": "(僅支援 x64 系統)", - "DialogUpdaterNoInternetMessage": "沒有連接到網路", - "DialogUpdaterNoInternetSubMessage": "請確保網路連接正常。", + "DialogUpdaterNoInternetMessage": "你沒有連接到網際網絡!", + "DialogUpdaterNoInternetSubMessage": "請確保網際網絡連接正常!", "DialogUpdaterDirtyBuildMessage": "不能更新非官方版本的 Ryujinx!", - "DialogUpdaterDirtyBuildSubMessage": "如果希望使用受支援的版本,請您在 https://ryujinx.org/ 下載。", - "DialogRestartRequiredMessage": "需要重啟模擬器", - "DialogThemeRestartMessage": "主題設定已儲存。需要重新啟動才能生效。", - "DialogThemeRestartSubMessage": "您是否要重啟?", + "DialogUpdaterDirtyBuildSubMessage": "如果你希望使用被受支援的Ryujinx版本,請你在官方網址 https://ryujinx.org/ 下載.", + "DialogRestartRequiredMessage": "模擬器必須重新啟動", + "DialogThemeRestartMessage": "佈景主題設定已儲存。需要重新啟動才能生效。", + "DialogThemeRestartSubMessage": "你確定要現在重新啟動嗎?", "DialogFirmwareInstallEmbeddedMessage": "要安裝遊戲內建的韌體嗎?(韌體 {0})", "DialogFirmwareInstallEmbeddedSuccessMessage": "未找到已安裝的韌體,但 Ryujinx 可以從現有的遊戲安裝韌體{0}.\\n模擬器現在可以執行。", "DialogFirmwareNoFirmwareInstalledMessage": "未安裝韌體", "DialogFirmwareInstalledMessage": "已安裝韌體{0}", - "DialogOpenSettingsWindowLabel": "打開設定視窗", + "DialogInstallFileTypesSuccessMessage": "成功註冊檔案類型!", + "DialogInstallFileTypesErrorMessage": "註冊檔案類型失敗。", + "DialogUninstallFileTypesSuccessMessage": "成功取消註冊檔案類型!", + "DialogUninstallFileTypesErrorMessage": "取消註冊檔案類型失敗。", + "DialogOpenSettingsWindowLabel": "開啟設定視窗", "DialogControllerAppletTitle": "控制器小視窗", - "DialogMessageDialogErrorExceptionMessage": "顯示訊息對話框時出錯: {0}", - "DialogSoftwareKeyboardErrorExceptionMessage": "顯示軟體鍵盤時出錯: {0}", - "DialogErrorAppletErrorExceptionMessage": "顯示錯誤對話框時出錯: {0}", + "DialogMessageDialogErrorExceptionMessage": "顯示訊息對話框時出現錯誤: {0}", + "DialogSoftwareKeyboardErrorExceptionMessage": "顯示軟體鍵盤時出現錯誤: {0}", + "DialogErrorAppletErrorExceptionMessage": "顯示錯誤對話框時出現錯誤: {0}", "DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogInfoMessage": "\n有關修復此錯誤的更多訊息,可以遵循我們的設定指南。", "DialogUserErrorDialogTitle": "Ryujinx 錯誤 ({0})", - "DialogAmiiboApiTitle": "Amiibo API", + "DialogAmiiboApiTitle": "Amiibo 應用程式介面", "DialogAmiiboApiFailFetchMessage": "從 API 取得訊息時出錯。", - "DialogAmiiboApiConnectErrorMessage": "無法連接到 Amiibo API 伺服器。伺服器可能已關閉,或者您沒有網路連接。", - "DialogProfileInvalidProfileErrorMessage": "預設{0} 與目前輸入配置系統不相容。", + "DialogAmiiboApiConnectErrorMessage": "無法連接到 Amiibo API 伺服器。伺服器可能已關閉,或你沒有連接到網際網路。", + "DialogProfileInvalidProfileErrorMessage": "配置檔案 {0} 與目前輸入系統不相容。", "DialogProfileDefaultProfileOverwriteErrorMessage": "無法覆蓋預設的配置檔案", - "DialogProfileDeleteProfileTitle": "刪除配置檔", - "DialogProfileDeleteProfileMessage": "刪除後不可恢復,確定嗎?", + "DialogProfileDeleteProfileTitle": "刪除帳戶", + "DialogProfileDeleteProfileMessage": "此操作不可撤銷, 您確定要繼續嗎?", "DialogWarning": "警告", - "DialogPPTCDeletionMessage": "您即將刪除:\n\n{0}的 PPTC 快取\n\n確定嗎?", + "DialogPPTCDeletionMessage": "下一次重啟時將會重新建立以下遊戲的 PPTC 快取\n\n{0}\n\n你確定要繼續嗎?", "DialogPPTCDeletionErrorMessage": "清除位於{0}的 PPTC 快取時出錯: {1}", - "DialogShaderDeletionMessage": "您即將刪除:\n\n{0}的渲染器快取\n\n確定嗎?", - "DialogShaderDeletionErrorMessage": "清除位於{0}的渲染器快取時出錯: {1}", + "DialogShaderDeletionMessage": "即將刪除以下遊戲的著色器快取:\n\n{0}\n\n你確定要繼續嗎?", + "DialogShaderDeletionErrorMessage": "清除{0}的著色器快取時出現錯誤: {1}", "DialogRyujinxErrorMessage": "Ryujinx 遇到錯誤", "DialogInvalidTitleIdErrorMessage": "UI 錯誤:所選遊戲沒有有效的標題ID", "DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "路徑{0}找不到有效的系統韌體。", "DialogFirmwareInstallerFirmwareInstallTitle": "安裝韌體{0}", "DialogFirmwareInstallerFirmwareInstallMessage": "將安裝{0}版本的系統。", "DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n這將替換目前系統版本{0}。", - "DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n確認進行?", + "DialogFirmwareInstallerFirmwareInstallConfirmMessage": "你確定要繼續嗎?", "DialogFirmwareInstallerFirmwareInstallWaitMessage": "安裝韌體中...", "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "成功安裝系統版本{0}。", - "DialogUserProfileDeletionWarningMessage": "刪除後將沒有可選擇的使用者帳號", - "DialogUserProfileDeletionConfirmMessage": "是否刪除選擇的帳號", - "DialogControllerSettingsModifiedConfirmMessage": "目前的輸入預設已更新", - "DialogControllerSettingsModifiedConfirmSubMessage": "要儲存嗎?", + "DialogUserProfileDeletionWarningMessage": "刪除後將沒有可選擇的使用者帳戶", + "DialogUserProfileDeletionConfirmMessage": "你確定要刪除選擇中的帳戶嗎?", + "DialogUserProfileUnsavedChangesTitle": "警告 - 有未儲存的更改", + "DialogUserProfileUnsavedChangesMessage": "你對此帳戶所做的更改尚未儲存.", + "DialogUserProfileUnsavedChangesSubMessage": "你確定要捨棄更改嗎?", + "DialogControllerSettingsModifiedConfirmMessage": "目前的輸入配置檔案已更新", + "DialogControllerSettingsModifiedConfirmSubMessage": "你確定要儲存嗎?", "DialogLoadNcaErrorMessage": "{0}. 錯誤的檔案: {1}", "DialogDlcNoDlcErrorMessage": "選擇的檔案不包含所選遊戲的 DLC!", - "DialogPerformanceCheckLoggingEnabledMessage": "您啟用了跟蹤日誌,僅供開發人員使用。", - "DialogPerformanceCheckLoggingEnabledConfirmMessage": "為了獲得最佳效能,建議停用跟蹤日誌記錄。您是否要立即停用?", - "DialogPerformanceCheckShaderDumpEnabledMessage": "您啟用了渲染器轉儲,僅供開發人員使用。", - "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "為了獲得最佳效能,建議停用渲染器轉儲。您是否要立即停用?", - "DialogLoadAppGameAlreadyLoadedMessage": "目前已載入有遊戲", + "DialogPerformanceCheckLoggingEnabledMessage": "你啟用了跟蹤記錄,它的設計僅限開發人員使用。", + "DialogPerformanceCheckLoggingEnabledConfirmMessage": "為了獲得最佳效能,建議停用追蹤記錄。你是否要立即停用?", + "DialogPerformanceCheckShaderDumpEnabledMessage": "你啟用了著色器轉存,它的設計僅限開發人員使用。", + "DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "為了獲得最佳效能,建議停用著色器轉存。你是否要立即停用?", + "DialogLoadAppGameAlreadyLoadedMessage": "目前已載入此遊戲", "DialogLoadAppGameAlreadyLoadedSubMessage": "請停止模擬或關閉程式,再啟動另一個遊戲。", "DialogUpdateAddUpdateErrorMessage": "選擇的檔案不包含所選遊戲的更新!", - "DialogSettingsBackendThreadingWarningTitle": "警告 - 後端多執行緒", - "DialogSettingsBackendThreadingWarningMessage": "改變此選項後必須重啟 Ryujinx 才能生效。根據您的硬體,您開啟該選項時,可能需要手動停用驅動程式本身的GL多執行緒。", + "DialogSettingsBackendThreadingWarningTitle": "警告 - 後台多工執行中", + "DialogSettingsBackendThreadingWarningMessage": "更改此選項後必須重啟 Ryujinx 才能生效。根據你的硬體,您開啟該選項時,可能需要手動停用驅動程式本身的GPU多執行緒。", "SettingsTabGraphicsFeaturesOptions": "功能", - "SettingsTabGraphicsBackendMultithreading": "後端多執行緒:", + "SettingsTabGraphicsBackendMultithreading": "圖像處理後台多線程支援:", "CommonAuto": "自動(推薦)", "CommonOff": "關閉", "CommonOn": "打開", @@ -391,89 +406,91 @@ "DialogProfileInvalidProfileNameErrorMessage": "檔案名包含無效字元,請重試。", "MenuBarOptionsPauseEmulation": "暫停", "MenuBarOptionsResumeEmulation": "繼續", - "AboutUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的官網。", - "AboutDisclaimerMessage": "Ryujinx 以任何方式與 Nintendo™ 及其合作伙伴都沒有任何關聯。", + "AboutUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的官方網站。", + "AboutDisclaimerMessage": "Ryujinx 與 Nintendo™ 並沒有任何關聯, 包括其合作伙伴, 及任何形式上。", "AboutAmiiboDisclaimerMessage": "我們的 Amiibo 模擬使用了\nAmiiboAPI (www.amiiboapi.com) ", - "AboutPatreonUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Patreon 贊助頁。", + "AboutPatreonUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Patreon 贊助網頁。", "AboutGithubUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 GitHub 儲存庫。", "AboutDiscordUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Discord 伺服器邀請連結。", "AboutTwitterUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Twitter 首頁。", - "AboutRyujinxAboutTitle": "關於:", - "AboutRyujinxAboutContent": "Ryujinx 是一款 Nintendo Switch™ 模擬器。\n您可以在 Patreon 上贊助 Ryujinx。\n關注 Twitter 或 Discord 可以取得模擬器最新動態。\n如果您對開發本軟體感興趣,歡迎來 GitHub 和 Discord 加入我們!", - "AboutRyujinxMaintainersTitle": "由以下作者維護:", + "AboutRyujinxAboutTitle": "關於:", + "AboutRyujinxAboutContent": "Ryujinx 是 Nintendo Switch™ 的一款模擬器。\n懇請您在 Patreon 上贊助我們。\n關注 Twitter 或 Discord 可以取得我們的最新動態。\n如果您對開發本軟體感興趣,歡迎來 GitHub 和 Discord 加入我們!", + "AboutRyujinxMaintainersTitle": "開發及維護名單:", "AboutRyujinxMaintainersContentTooltipMessage": "在瀏覽器中打開貢獻者的網頁", - "AboutRyujinxSupprtersTitle": "感謝 Patreon 的贊助者:", + "AboutRyujinxSupprtersTitle": "Patreon 的贊助人:", "AmiiboSeriesLabel": "Amiibo 系列", "AmiiboCharacterLabel": "角色", "AmiiboScanButtonLabel": "掃描", "AmiiboOptionsShowAllLabel": "顯示所有 Amiibo", - "AmiiboOptionsUsRandomTagLabel": "修正: 使用隨機標記的 Uuid", - "DlcManagerTableHeadingEnabledLabel": "啟用", + "AmiiboOptionsUsRandomTagLabel": "侵略:使用隨機標記的 Uuid 編碼", + "DlcManagerTableHeadingEnabledLabel": "已啟用", "DlcManagerTableHeadingTitleIdLabel": "遊戲ID", "DlcManagerTableHeadingContainerPathLabel": "資料夾路徑", "DlcManagerTableHeadingFullPathLabel": "完整路徑", "DlcManagerRemoveAllButton": "全部刪除", "DlcManagerEnableAllButton": "啟用全部", "DlcManagerDisableAllButton": "停用全部", - "MenuBarOptionsChangeLanguage": "變更語言", + "MenuBarOptionsChangeLanguage": "更改語言", + "MenuBarShowFileTypes": "顯示檔案類型", "CommonSort": "排序", "CommonShowNames": "顯示名稱", "CommonFavorite": "收藏", "OrderAscending": "從小到大", "OrderDescending": "從大到小", - "SettingsTabGraphicsFeatures": "額外功能", + "SettingsTabGraphicsFeatures": "功能及優化", "ErrorWindowTitle": "錯誤視窗", "ToggleDiscordTooltip": "啟用或關閉 Discord 動態狀態展示", "AddGameDirBoxTooltip": "輸入要添加的遊戲資料夾", "AddGameDirTooltip": "添加遊戲資料夾到列表中", - "RemoveGameDirTooltip": "移除選中的資料夾", - "CustomThemeCheckTooltip": "啟用或關閉自訂主題", - "CustomThemePathTooltip": "自訂主題的資料夾", - "CustomThemeBrowseTooltip": "查找自訂主題", + "RemoveGameDirTooltip": "移除選擇中的遊戲資料夾", + "CustomThemeCheckTooltip": "啟用或關閉自訂佈景主題", + "CustomThemePathTooltip": "自訂佈景主題的資料夾", + "CustomThemeBrowseTooltip": "查找自訂佈景主題", "DockModeToggleTooltip": "是否開啟 Switch 的 Docked 模式", - "DirectKeyboardTooltip": "是否開啟\"直連鍵盤存取(HID) 支援\"\n(部分遊戲可以使用您的鍵盤輸入文字)", - "DirectMouseTooltip": "是否開啟\"直連滑鼠存取(HID) 支援\"\n(部分遊戲可以使用您的滑鼠導航)", - "RegionTooltip": "變更系統區域", - "LanguageTooltip": "變更系統語言", - "TimezoneTooltip": "變更系統時區", - "TimeTooltip": "變更系統時鐘", - "VSyncToggleTooltip": "關閉後,部分使用動態更新率的遊戲可以超過 60Hz 更新率", + "DirectKeyboardTooltip": "支援鍵盤直接存取 (HID協定) . 可供給遊戲使用你的鍵盤作為輸入文字裝置.", + "DirectMouseTooltip": "支援滑鼠直接存取 (HID協定) . 可供給遊戲使用你的滑鼠作為瞄準裝置.", + "RegionTooltip": "更改系統區域", + "LanguageTooltip": "更改系統語言", + "TimezoneTooltip": "更改系統時區", + "TimeTooltip": "更改系統時鐘", + "VSyncToggleTooltip": "模擬遊戲主機垂直同步更新頻率. 重要地反映著遊戲本身的速度; 關閉它可能會令後使用動態更新率的遊戲速度過高, 或會引致載入錯誤等等.\n\n可在遊戲中利用自訂快速鍵開關此功能. 我們也建議使用快速鍵, 如果你計劃關上它.\n\n如果不確定請設定為\"開啟\".", "PptcToggleTooltip": "開啟以後減少遊戲啟動時間和卡頓", "FsIntegrityToggleTooltip": "是否檢查遊戲檔案內容的完整性", - "AudioBackendTooltip": "預設推薦 SDL,但每種音訊後端對各類遊戲相容性不同,遇到音訊問題可以切換後端", - "MemoryManagerTooltip": "改變 Switch 記憶體映射到電腦記憶體的方式,會影響CPU效能消耗", - "MemoryManagerSoftwareTooltip": "使用軟體記憶體頁管理,最精確但是速度最慢", - "MemoryManagerHostTooltip": "直接映射記憶體頁到電腦記憶體, JIT 效率高", - "MemoryManagerUnsafeTooltip": "直接映射記憶體頁,但是不檢查記憶體溢出,JIT效率最高。\nRyujinx 可以存取任何位置的記憶體,因而相對不安全。此模式下只應執行您信任的遊戲或軟體(即官方遊戲)", - "DRamTooltip": "擴充模擬的 Switch 記憶體為 6GiB,某些高畫質材質模組或 4K 模組需要此選項\n這並不會提升性能\n\n如果不確定請關閉本功能", - "IgnoreMissingServicesTooltip": "忽略某些未實作的系統服務,少部分遊戲需要此選項才能啟動", - "GraphicsBackendThreadingTooltip": "啟用後端多執行緒", - "GalThreadingTooltip": "使用模擬器自帶的多執行緒調度,減少渲染器編譯的卡頓,並提高驅動程式的效能(尤其是缺失多執行緒的AMD)。\nNVIDIA使用者需要重啟模擬器才能停用驅動本身的多執行緒,否則您需手動執行停用獲得最佳效能", - "ShaderCacheToggleTooltip": "開啟後快取渲染器到硬碟,減少遊戲卡頓", - "ResolutionScaleTooltip": "縮放渲染的解析度", + "AudioBackendTooltip": "更改音效處理後台架構.\n\n推薦使用SDL2架構, 而OpenAL及SoundIO架構用作後備. Dummy是沒有音效的.\n\n如果不確定請設定為\"SDL2\".", + "MemoryManagerTooltip": "更改模擬器記憶體至電腦記憶體的映射和存取方式,極其影響CPU效能.\n\n如果不確定, 請設定為\"主機略過檢查模式\".", + "MemoryManagerSoftwareTooltip": "使用軟體虛擬分頁表換算, 最精確但是速度最慢.", + "MemoryManagerHostTooltip": "直接地映射模擬記憶體到電腦記憶體. 對 JIT 編譯和執行效率有顯著提升. ", + "MemoryManagerUnsafeTooltip": "直接地映射模擬記憶體到電腦記憶體, 但是不檢查記憶體溢出. 由於 Ryujinx 的子程式可以存取任何位置的記憶體, 因而相對不安全. 故在此模式下只應執行你信任的遊戲或軟體.", + "UseHypervisorTooltip": "使用 Hypervisor 代替 JIT。在本功能可用時就可以大幅增大效能,但目前狀態還不穩定。", + "DRamTooltip": "利用可選擇性的記憶體模式來模擬Switch發展中型號.\n\n此選項只會對高畫質材質包或4K模組有用. 而這並不會提升效能. \n\n如果不確定請關閉本功能.", + "IgnoreMissingServicesTooltip": "忽略某些未被實施的系統服務. 此功能有助於繞過當啟動遊戲時帶來的故障.\n\n如果不確定請關閉本功能。", + "GraphicsBackendThreadingTooltip": "執行雙線程後台繪圖指令, 能夠減少著色器編譯斷續, 並提高GPU驅動效能, 即將它不支持多線程處理. 而對於多線程處理也有少量提升.\n\n如果你不確定請設定為\"自動\"", + "GalThreadingTooltip": "執行雙線程後台繪圖指令.\n\n能夠加速著色器編譯及減少斷續, 並提高GPU驅動效能, 即將它不支持多線程處理. 而對於多線程處理也有少量提升.\n\n如果你不確定請設定為\"自動\"", + "ShaderCacheToggleTooltip": "儲存著色器快取到硬碟,減少存取斷續。\n\n如果不確定請設定為\"開啟\"。", + "ResolutionScaleTooltip": "解析度繪圖倍率", "ResolutionScaleEntryTooltip": "盡量使用如1.5的浮點倍數。非整數的倍率易引起錯誤", "AnisotropyTooltip": "各向異性過濾等級。提高傾斜視角材質的清晰度\n(選擇「自動」將使用遊戲預設指定的等級)", - "AspectRatioTooltip": "模擬器渲染視窗的寬高比", - "ShaderDumpPathTooltip": "轉儲圖形渲染器的路徑", + "AspectRatioTooltip": "模擬器視窗解析度的長寬比", + "ShaderDumpPathTooltip": "圖形著色器轉存路徑", "FileLogTooltip": "是否儲存日誌檔案到硬碟", - "StubLogTooltip": "記錄 Stub 訊息", - "InfoLogTooltip": "記錄資訊訊息", - "WarnLogTooltip": "記錄警告訊息", - "ErrorLogTooltip": "記錄錯誤訊息", - "TraceLogTooltip": "記錄 Trace 訊息", - "GuestLogTooltip": "記錄 Guest 訊息", - "FileAccessLogTooltip": "記錄檔案存取訊息", - "FSAccessLogModeTooltip": "記錄 FS 存取訊息,輸出到控制台。可選的模式是 0-3", + "StubLogTooltip": "在控制台顯示及記錄 Stub 訊息", + "InfoLogTooltip": "在控制台顯示及記錄資訊訊息", + "WarnLogTooltip": "在控制台顯示及記錄警告訊息\n", + "ErrorLogTooltip": "在控制台顯示及記錄錯誤訊息", + "TraceLogTooltip": "在控制台顯示及記錄追蹤訊息", + "GuestLogTooltip": "在控制台顯示及記錄賓客訊息", + "FileAccessLogTooltip": "在控制台顯示及記錄檔案存取訊息", + "FSAccessLogModeTooltip": "在控制台顯示及記錄FS 存取訊息. 可選的模式是 0-3", "DeveloperOptionTooltip": "使用請謹慎", "OpenGlLogLevel": "需要打開適當的日誌等級", - "DebugLogTooltip": "記錄Debug訊息", + "DebugLogTooltip": "在控制台顯示及記錄除錯訊息.\n\n僅限於受訓的成員使用, 因為它很難理解而且令模擬的效能非常地差.\n", "LoadApplicationFileTooltip": "選擇 Switch 支援的遊戲格式並載入", "LoadApplicationFolderTooltip": "選擇解包後的 Switch 遊戲並載入", - "OpenRyujinxFolderTooltip": "打開 Ryujinx 系統資料夾", - "OpenRyujinxLogsTooltip": "打開日誌存放的資料夾", + "OpenRyujinxFolderTooltip": "開啟 Ryujinx 系統資料夾", + "OpenRyujinxLogsTooltip": "開啟存放日誌的資料夾", "ExitTooltip": "關閉 Ryujinx", - "OpenSettingsTooltip": "打開設定視窗", - "OpenProfileManagerTooltip": "打開使用者帳號管理器", + "OpenSettingsTooltip": "開啟設定視窗", + "OpenProfileManagerTooltip": "開啟使用者帳戶管理視窗", "StopEmulationTooltip": "停止執行目前遊戲並回到選擇界面", "CheckUpdatesTooltip": "檢查 Ryujinx 新版本", "OpenAboutTooltip": "開啟關於視窗", @@ -481,30 +498,30 @@ "GridSizeTooltip": "調整網格模式的大小", "SettingsTabSystemSystemLanguageBrazilianPortuguese": "巴西葡萄牙語", "AboutRyujinxContributorsButtonHeader": "查看所有參與者", - "SettingsTabSystemAudioVolume": "音量: ", + "SettingsTabSystemAudioVolume": "音量:", "AudioVolumeTooltip": "調節音量", "SettingsTabSystemEnableInternetAccess": "啟用網路連接", "EnableInternetAccessTooltip": "開啟網路存取。此選項打開後,效果類似於 Switch 連接到網路的狀態。注意即使此選項關閉,應用程式偶爾也有可能連接到網路", "GameListContextMenuManageCheatToolTip": "管理金手指", "GameListContextMenuManageCheat": "管理金手指", - "ControllerSettingsStickRange": "範圍", + "ControllerSettingsStickRange": "範圍:", "DialogStopEmulationTitle": "Ryujinx - 停止模擬", - "DialogStopEmulationMessage": "是否確定停止模擬?", - "SettingsTabCpu": "CPU", + "DialogStopEmulationMessage": "你確定要停止模擬嗎?", + "SettingsTabCpu": "處理器", "SettingsTabAudio": "音訊", "SettingsTabNetwork": "網路", "SettingsTabNetworkConnection": "網路連接", "SettingsTabCpuCache": "CPU 快取", - "SettingsTabCpuMemory": "CPU 記憶體", + "SettingsTabCpuMemory": "CPU 模式", "DialogUpdaterFlatpakNotSupportedMessage": "請透過 Flathub 更新 Ryujinx。", "UpdaterDisabledWarningTitle": "更新已停用!", - "GameListContextMenuOpenSdModsDirectory": "打開 Atmosphere 模組資料夾", - "GameListContextMenuOpenSdModsDirectoryToolTip": "打開包含應用程式模組的額外 Atmosphere SD卡資料夾", + "GameListContextMenuOpenSdModsDirectory": "開啟 Atmosphere 模組資料夾", + "GameListContextMenuOpenSdModsDirectoryToolTip": "開啟此遊戲額外的SD記憶卡Atmosphere模組資料夾. 有用於包裝在真實主機上的模組.\n", "ControllerSettingsRotate90": "順時針旋轉 90°", "IconSize": "圖示尺寸", - "IconSizeTooltip": "變更遊戲圖示大小", + "IconSizeTooltip": "更改遊戲圖示大小", "MenuBarOptionsShowConsole": "顯示控制台", - "ShaderCachePurgeError": "清除渲染器快取時出錯: {0}: {1}", + "ShaderCachePurgeError": "清除 {0} 著色器快取時出現錯誤: {1}", "UserErrorNoKeys": "找不到金鑰", "UserErrorNoFirmware": "找不到韌體", "UserErrorFirmwareParsingFailed": "韌體解析錯誤", @@ -517,7 +534,7 @@ "UserErrorApplicationNotFoundDescription": "Ryujinx 在選中路徑找不到有效的應用程式。", "UserErrorUnknownDescription": "發生未知錯誤!", "UserErrorUndefinedDescription": "發生了未定義錯誤!此類錯誤不應出現,請聯絡開發人員!", - "OpenSetupGuideMessage": "打開設定教學", + "OpenSetupGuideMessage": "開啟設定教學", "NoUpdate": "沒有新版本", "TitleUpdateVersionLabel": "版本 {0} - {1}", "RyujinxInfo": "Ryujinx - 訊息", @@ -527,11 +544,14 @@ "SwkbdMinCharacters": "至少應為 {0} 個字長", "SwkbdMinRangeCharacters": "必須為 {0}-{1} 個字長", "SoftwareKeyboard": "軟體鍵盤", - "DialogControllerAppletMessagePlayerRange": "本遊戲需要 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。", - "DialogControllerAppletMessage": "本遊戲需要剛好 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面,配置手把,或者關閉本視窗。", + "SoftwareKeyboardModeNumbersOnly": "只接受數字", + "SoftwareKeyboardModeAlphabet": "不支援中日韓統一表意文字字元", + "SoftwareKeyboardModeASCII": "只接受 ASCII 符號", + "DialogControllerAppletMessagePlayerRange": "本遊戲需要 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面並配置控制器,或者關閉本視窗。", + "DialogControllerAppletMessage": "本遊戲需要剛好 {0} 個玩家持有:\n\n類型:{1}\n\n玩家:{2}\n\n{3}請打開設定畫面並配置控制器,或者關閉本視窗。", "DialogControllerAppletDockModeSet": "現在處於主機模式,無法使用掌機操作方式\n\n", "UpdaterRenaming": "正在重新命名舊檔案...", - "UpdaterRenameFailed": "更新過程中無法重新命名檔案: {0}", + "UpdaterRenameFailed": "更新過程中無法重新命名檔案: {0}", "UpdaterAddingFiles": "安裝更新中...", "UpdaterExtracting": "正在提取更新...", "UpdaterDownloading": "下載新版本中...", @@ -543,19 +563,19 @@ "ApiError": "API 錯誤", "LoadingHeading": "正在啟動 {0}", "CompilingPPTC": "編譯 PPTC 快取中", - "CompilingShaders": "編譯渲染器中", + "CompilingShaders": "編譯著色器中", "AllKeyboards": "所有鍵盤", "OpenFileDialogTitle": "選擇支援的檔案格式", - "OpenFolderDialogTitle": "選擇一個包含已解包遊戲的資料夾", + "OpenFolderDialogTitle": "選擇一個包含已解開封裝遊戲的資料夾\n", "AllSupportedFormats": "全部支援的格式", "RyujinxUpdater": "Ryujinx 更新程式", "SettingsTabHotkeys": "快捷鍵", "SettingsTabHotkeysHotkeys": "鍵盤快捷鍵", - "SettingsTabHotkeysToggleVsyncHotkey": "切換垂直同步", - "SettingsTabHotkeysScreenshotHotkey": "截圖", - "SettingsTabHotkeysShowUiHotkey": "隱藏使用者介面", - "SettingsTabHotkeysPauseHotkey": "暫停", - "SettingsTabHotkeysToggleMuteHotkey": "靜音", + "SettingsTabHotkeysToggleVsyncHotkey": "切換垂直同步:", + "SettingsTabHotkeysScreenshotHotkey": "截圖:", + "SettingsTabHotkeysShowUiHotkey": "隱藏使用者介面:", + "SettingsTabHotkeysPauseHotkey": "暫停:", + "SettingsTabHotkeysToggleMuteHotkey": "靜音:", "ControllerMotionTitle": "體感操作設定", "ControllerRumbleTitle": "震動設定", "SettingsSelectThemeFileDialogTitle": "選擇主題檔案", @@ -567,48 +587,70 @@ "Writable": "可寫入", "SelectDlcDialogTitle": "選擇 DLC 檔案", "SelectUpdateDialogTitle": "選擇更新檔", - "UserProfileWindowTitle": "管理使用者設定檔", + "UserProfileWindowTitle": "管理使用者帳戶", "CheatWindowTitle": "管理遊戲金手指", "DlcWindowTitle": "管理遊戲 DLC", "UpdateWindowTitle": "管理遊戲更新", "CheatWindowHeading": "金手指可用於 {0} [{1}]", + "BuildId": "版本編號:", "DlcWindowHeading": "DLC 可用於 {0} [{1}]", "UserProfilesEditProfile": "編輯所選", "Cancel": "取消", "Save": "儲存", - "Discard": "放棄變更", - "UserProfilesSetProfileImage": "設定帳號頭貼", + "Discard": "放棄更改", + "UserProfilesSetProfileImage": "設定帳戶頭像", "UserProfileEmptyNameError": "使用者名稱為必填", - "UserProfileNoImageError": "必須設定帳號頭貼", + "UserProfileNoImageError": "必須設定帳戶頭像", "GameUpdateWindowHeading": "更新可用於 {0} [{1}]", "SettingsTabHotkeysResScaleUpHotkey": "提高解析度:", "SettingsTabHotkeysResScaleDownHotkey": "降低解析度:", "UserProfilesName": "使用者名稱:", "UserProfilesUserId": "使用者 ID:", - "SettingsTabGraphicsBackend": "圖形顯示後端", - "SettingsTabGraphicsBackendTooltip": "要用來處理圖形相關內容的後端", + "SettingsTabGraphicsBackend": "圖像處理後台架構", + "SettingsTabGraphicsBackendTooltip": "用來圖像處理的後台架構", "SettingsEnableTextureRecompression": "開啟材質重新壓縮", "SettingsEnableTextureRecompressionTooltip": "壓縮某些材質以減少 VRAM 使用。\n\n推薦用於小於 4GiB VRAM 的 GPU。\n\n如果不確定請關閉本功能。", - "SettingsTabGraphicsPreferredGpu": "首選 GPU", - "SettingsTabGraphicsPreferredGpuTooltip": "選擇與 Vulkan 圖形顯示後端一起使用的 GPU。\n\n不影響 OpenGL 圖形後端所使用的 GPU。\n\n如果不確定,請設定為標記為「dGPU」的 GPU。如果沒有,請保持原設定。", + "SettingsTabGraphicsPreferredGpu": "優先選取的 GPU", + "SettingsTabGraphicsPreferredGpuTooltip": "選擇支持運行Vulkan圖像處理架構的GPU.\n\n此設定不會影響GPU運行OpenGL.\n\n如果不確定, 請設定標籤為\"dGPU\"的GPU. 如果沒有, 請保留原始設定.", "SettingsAppRequiredRestartMessage": "必須重啟 Ryujinx", - "SettingsGpuBackendRestartMessage": "圖形顯示後端或 GPU 相關設定已被修改。需要重新啟動才能套用。", - "SettingsGpuBackendRestartSubMessage": "您想要現在重新啟動本程式嗎?", - "RyujinxUpdaterMessage": "您想要將 Ryujinx 更新到最新版本嗎?", + "SettingsGpuBackendRestartMessage": "圖像處理後台架構或GPU相關設定已被修改。需要重新啟動才能套用。", + "SettingsGpuBackendRestartSubMessage": "你確定要現在重新啟動嗎?", + "RyujinxUpdaterMessage": "你確定要將 Ryujinx 更新到最新版本嗎?", "SettingsTabHotkeysVolumeUpHotkey": "增加音量:", "SettingsTabHotkeysVolumeDownHotkey": "降低音量:", "SettingsEnableMacroHLE": "啟用 Macro HLE", - "SettingsEnableMacroHLETooltip": "GPU Macro 代碼的進階模擬。\n\n可以提升性能,但可能會導致某些遊戲出現圖形顯示故障。\n\n如果不確定請關閉本功能。", + "SettingsEnableMacroHLETooltip": "GPU 微代碼的高階模擬。\n\n可以提升效能,但可能會導致某些遊戲出現圖形顯示故障。\n\n如果不確定請設定為\"開啟\"。", + "SettingsEnableColorSpacePassthrough": "色彩空間直通", + "SettingsEnableColorSpacePassthroughTooltip": "指揮Vulkan後端直通色彩資訊而不需指定色彩空間,對於廣色域顯示的使用者,這會造成較多抖色,犧牲色彩正確性。", "VolumeShort": "音量", "UserProfilesManageSaves": "管理遊戲存檔", - "DeleteUserSave": "您想要刪除本遊戲的存檔嗎?", + "DeleteUserSave": "你確定要刪除此遊戲的存檔嗎?", "IrreversibleActionNote": "本動作將無法挽回。", "SaveManagerHeading": "管理 {0} 的遊戲存檔", "SaveManagerTitle": "遊戲存檔管理器", "Name": "名稱", "Size": "大小", "Search": "搜尋", - "UserProfilesRecoverLostAccounts": "恢復遺失的帳號", + "UserProfilesRecoverLostAccounts": "恢復遺失的帳戶", "Recover": "恢復", - "UserProfilesRecoverHeading": "在以下帳號找到了一些遊戲存檔" -} + "UserProfilesRecoverHeading": "在以下帳戶找到了一些遊戲存檔", + "UserProfilesRecoverEmptyList": "沒有可恢復的使用者帳戶", + "GraphicsAATooltip": "在遊戲繪圖上套用抗鋸齒", + "GraphicsAALabel": "抗鋸齒:", + "GraphicsScalingFilterLabel": "縮放過濾器:", + "GraphicsScalingFilterTooltip": "啟用畫幀緩衝區縮放", + "GraphicsScalingFilterLevelLabel": "記錄檔等級", + "GraphicsScalingFilterLevelTooltip": "設定縮放過濾器的強度", + "SmaaLow": "低階 SMAA", + "SmaaMedium": "中階 SMAA", + "SmaaHigh": "高階 SMAA", + "SmaaUltra": "超高階 SMAA", + "UserEditorTitle": "編輯使用者", + "UserEditorTitleCreate": "建立使用者", + "SettingsTabNetworkInterface": "網路介面:", + "NetworkInterfaceTooltip": "用於具有 LAN 功能的網路介面", + "NetworkInterfaceDefault": "預設", + "PackagingShaders": "著色器封裝", + "AboutChangelogButton": "在 GitHub 查看更新日誌", + "AboutChangelogButtonTooltipMessage": "在瀏覽器中打開此Ryujinx版本的更新日誌。" +} \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml b/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml deleted file mode 100644 index c7f6266fb..000000000 --- a/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs new file mode 100644 index 000000000..34de5223b --- /dev/null +++ b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs @@ -0,0 +1,139 @@ +using Avalonia.Controls; +using Avalonia.Styling; +using Avalonia.Svg.Skia; +using Avalonia.Threading; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.Common; +using Ryujinx.HLE.HOS.Applets; +using Ryujinx.HLE.HOS.Services.Hid; +using System.Linq; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Applet +{ + internal partial class ControllerAppletDialog : UserControl + { + private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg"; + private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg"; + private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg"; + private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg"; + + public static SvgImage ProControllerImage => GetResource(ProControllerResource); + public static SvgImage JoyconPairImage => GetResource(JoyConPairResource); + public static SvgImage JoyconLeftImage => GetResource(JoyConLeftResource); + public static SvgImage JoyconRightImage => GetResource(JoyConRightResource); + + public string PlayerCount { get; set; } = ""; + public bool SupportsProController { get; set; } + public bool SupportsLeftJoycon { get; set; } + public bool SupportsRightJoycon { get; set; } + public bool SupportsJoyconPair { get; set; } + public bool IsDocked { get; set; } + + private readonly MainWindow _mainWindow; + + public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUiArgs args) + { + if (args.PlayerCountMin == args.PlayerCountMax) + { + PlayerCount = args.PlayerCountMin.ToString(); + } + else + { + PlayerCount = $"{args.PlayerCountMin} - {args.PlayerCountMax}"; + } + + SupportsProController = (args.SupportedStyles & ControllerType.ProController) != 0; + SupportsLeftJoycon = (args.SupportedStyles & ControllerType.JoyconLeft) != 0; + SupportsRightJoycon = (args.SupportedStyles & ControllerType.JoyconRight) != 0; + SupportsJoyconPair = (args.SupportedStyles & ControllerType.JoyconPair) != 0; + + IsDocked = args.IsDocked; + + _mainWindow = mainWindow; + + DataContext = this; + + InitializeComponent(); + } + + public ControllerAppletDialog(MainWindow mainWindow) + { + _mainWindow = mainWindow; + DataContext = this; + + InitializeComponent(); + } + + public static async Task ShowControllerAppletDialog(MainWindow window, ControllerAppletUiArgs args) + { + ContentDialog contentDialog = new(); + UserResult result = UserResult.Cancel; + ControllerAppletDialog content = new(window, args); + + contentDialog.Title = LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle]; + contentDialog.Content = content; + + void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) + { + if (eventArgs.Result == ContentDialogResult.Primary) + { + result = UserResult.Ok; + } + } + + contentDialog.Closed += Handler; + + Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); + bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false)); + + contentDialog.Styles.Add(bottomBorder); + + await ContentDialogHelper.ShowAsync(contentDialog); + + return result; + } + + private static SvgImage GetResource(string path) + { + SvgImage image = new(); + + if (!string.IsNullOrWhiteSpace(path)) + { + SvgSource source = new(); + + source.Load(EmbeddedResources.GetStream(path)); + + image.Source = source; + } + + return image; + } + + public void OpenSettingsWindow() + { + if (_mainWindow.SettingsWindow == null) + { + Dispatcher.UIThread.InvokeAsync(async () => + { + _mainWindow.SettingsWindow = new SettingsWindow(_mainWindow.VirtualFileSystem, _mainWindow.ContentManager); + _mainWindow.SettingsWindow.NavPanel.Content = _mainWindow.SettingsWindow.InputPage; + _mainWindow.SettingsWindow.NavPanel.SelectedItem = _mainWindow.SettingsWindow.NavPanel.MenuItems.ElementAt(1); + + await ContentDialogHelper.ShowWindowAsync(_mainWindow.SettingsWindow, _mainWindow); + _mainWindow.SettingsWindow = null; + this.Close(); + }); + } + } + + public void Close() + { + ((ContentDialog)Parent)?.Hide(); + } + } +} + diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml index 211b47254..6186b7d93 100644 --- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml +++ b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml @@ -6,9 +6,11 @@ xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="{locale:Locale ErrorWindowTitle}" + xmlns:views="using:Ryujinx.Ava.UI.Applet" Width="450" Height="340" CanResize="False" + x:DataType="views:ErrorAppletWindow" SizeToContent="Height" mc:Ignorable="d" Focusable="True"> @@ -49,4 +51,4 @@ Orientation="Horizontal" Spacing="10" /> - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs index 4134797ba..ec6f76825 100644 --- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Threading; @@ -19,9 +18,7 @@ public ErrorAppletWindow(Window owner, string[] buttons, string message) Message = message; DataContext = this; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif + int responseId = 0; if (buttons != null) @@ -42,9 +39,6 @@ public ErrorAppletWindow() { DataContext = this; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } public string Message { get; set; } @@ -77,4 +71,4 @@ public async Task Run() return _buttonResponse; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml index 655045690..7e0836065 100644 --- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml +++ b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml @@ -4,7 +4,9 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:views="using:Ryujinx.Ava.UI.Controls" Width="400" + x:DataType="views:SwkbdAppletDialog" mc:Ignorable="d" Focusable="True"> _checkLength; + private Predicate _checkLength = _ => true; + private Predicate _checkInput = _ => true; private int _inputMax; private int _inputMin; - private string _placeholder; + private readonly string _placeholder; private ContentDialog _host; @@ -35,8 +35,6 @@ public SwkbdAppletDialog(string mainText, string secondaryText, string placehold Input.Watermark = _placeholder; Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true); - - SetInputLengthValidation(0, int.MaxValue); // Disable by default. } public SwkbdAppletDialog() @@ -56,17 +54,18 @@ protected override void OnGotFocus(GotFocusEventArgs e) public string MainText { get; set; } = ""; public string SecondaryText { get; set; } = ""; - public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, SoftwareKeyboardUiArgs args) + public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUiArgs args) { - ContentDialog contentDialog = new ContentDialog(); + ContentDialog contentDialog = new(); UserResult result = UserResult.Cancel; - SwkbdAppletDialog content = new SwkbdAppletDialog(args.HeaderText, args.SubtitleText, args.GuideText, args.InitialText); + SwkbdAppletDialog content = new(args.HeaderText, args.SubtitleText, args.GuideText, args.InitialText); string input = string.Empty; content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax); + content.SetInputValidation(args.KeyboardMode); content._host = contentDialog; contentDialog.Title = title; @@ -76,21 +75,28 @@ protected override void OnGotFocus(GotFocusEventArgs e) contentDialog.CloseButtonText = LocaleManager.Instance[LocaleKeys.InputDialogCancel]; contentDialog.Content = content; - TypedEventHandler handler = (sender, eventArgs) => + void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) { if (eventArgs.Result == ContentDialogResult.Primary) { result = UserResult.Ok; input = content.Input.Text; } - }; - contentDialog.Closed += handler; + } + + contentDialog.Closed += Handler; await ContentDialogHelper.ShowAsync(contentDialog); return (result, input); } + private void ApplyValidationInfo(string text) + { + Error.IsVisible = !string.IsNullOrEmpty(text); + Error.Text = text; + } + public void SetInputLengthValidation(int min, int max) { _inputMin = Math.Min(min, max); @@ -99,6 +105,8 @@ public void SetInputLengthValidation(int min, int max) Error.IsVisible = false; Error.FontStyle = FontStyle.Italic; + string validationInfoText = ""; + if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable. { Error.IsVisible = false; @@ -107,21 +115,48 @@ public void SetInputLengthValidation(int min, int max) } else if (_inputMin > 0 && _inputMax == int.MaxValue) { - Error.IsVisible = true; - - Error.Text = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin); + validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin); _checkLength = length => _inputMin <= length; } else { - Error.IsVisible = true; - - Error.Text = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax); + validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax); _checkLength = length => _inputMin <= length && length <= _inputMax; } + ApplyValidationInfo(validationInfoText); + Message_TextInput(this, new TextInputEventArgs()); + } + + private void SetInputValidation(KeyboardMode mode) + { + string validationInfoText = Error.Text; + string localeText; + switch (mode) + { + case KeyboardMode.Numeric: + localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumeric); + validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); + _checkInput = text => text.All(NumericCharacterValidation.IsNumeric); + break; + case KeyboardMode.Alphabet: + localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet); + validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); + _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value)); + break; + case KeyboardMode.ASCII: + localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII); + validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); + _checkInput = text => text.All(char.IsAscii); + break; + default: + _checkInput = _ => true; + break; + } + + ApplyValidationInfo(validationInfoText); Message_TextInput(this, new TextInputEventArgs()); } @@ -129,7 +164,7 @@ private void Message_TextInput(object sender, TextInputEventArgs e) { if (_host != null) { - _host.IsPrimaryButtonEnabled = _checkLength(Message.Length); + _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message); } } @@ -141,8 +176,8 @@ private void Message_KeyUp(object sender, KeyEventArgs e) } else { - _host.IsPrimaryButtonEnabled = _checkLength(Message.Length); + _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message); } } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml index 1750e8000..b8fe7e76f 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml @@ -2,11 +2,21 @@ x:Class="Ryujinx.Ava.UI.Controls.ApplicationContextMenu" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"> + xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" + xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + x:DataType="viewModels:MainWindowViewModel"> + + - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs index dc0dee2ac..0f0071065 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs @@ -10,13 +10,14 @@ using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; using Ryujinx.Common.Configuration; +using Ryujinx.HLE.HOS; +using Ryujinx.Ui.App.Common; using Ryujinx.Ui.Common.Helper; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using Path = System.IO.Path; -using UserId = LibHac.Fs.UserId; namespace Ryujinx.Ava.UI.Controls { @@ -36,11 +37,11 @@ public void ToggleFavorite_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite; - viewModel.ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata => + ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata => { appMetadata.Favorite = viewModel.SelectedApplication.Favorite; }); @@ -51,28 +52,29 @@ public void ToggleFavorite_Click(object sender, RoutedEventArgs args) public void OpenUserSaveDirectory_Click(object sender, RoutedEventArgs args) { - var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - - OpenSaveDirectory(viewModel, SaveDataType.Account, userId: new UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low)); + if (sender is MenuItem { DataContext: MainWindowViewModel viewModel }) + { + OpenSaveDirectory(viewModel, SaveDataType.Account, new UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low)); + } } public void OpenDeviceSaveDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - OpenSaveDirectory(viewModel, SaveDataType.Device, userId: default); + OpenSaveDirectory(viewModel, SaveDataType.Device, default); } public void OpenBcatSaveDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - OpenSaveDirectory(viewModel, SaveDataType.Bcat, userId: default); + OpenSaveDirectory(viewModel, SaveDataType.Bcat, default); } - private void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId) + private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId) { - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { if (!ulong.TryParse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber)) { @@ -94,7 +96,7 @@ public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs ar { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { await TitleUpdateWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName); } @@ -104,7 +106,7 @@ public async void OpenDownloadableContentManager_Click(object sender, RoutedEven { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { await DownloadableContentManagerWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName); } @@ -114,9 +116,13 @@ public async void OpenCheatManager_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - await new CheatWindow(viewModel.VirtualFileSystem, viewModel.SelectedApplication.TitleId, viewModel.SelectedApplication.TitleName).ShowDialog(viewModel.TopLevel as Window); + await new CheatWindow( + viewModel.VirtualFileSystem, + viewModel.SelectedApplication.TitleId, + viewModel.SelectedApplication.TitleName, + viewModel.SelectedApplication.Path).ShowDialog(viewModel.TopLevel as Window); } } @@ -124,10 +130,10 @@ public void OpenModsDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - string modsBasePath = viewModel.VirtualFileSystem.ModLoader.GetModsBasePath(); - string titleModsPath = viewModel.VirtualFileSystem.ModLoader.GetTitleDir(modsBasePath, viewModel.SelectedApplication.TitleId); + string modsBasePath = ModLoader.GetModsBasePath(); + string titleModsPath = ModLoader.GetTitleDir(modsBasePath, viewModel.SelectedApplication.TitleId); OpenHelper.OpenFolder(titleModsPath); } @@ -137,10 +143,10 @@ public void OpenSdModsDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - string sdModsBasePath = viewModel.VirtualFileSystem.ModLoader.GetSdModsBasePath(); - string titleModsPath = viewModel.VirtualFileSystem.ModLoader.GetTitleDir(sdModsBasePath, viewModel.SelectedApplication.TitleId); + string sdModsBasePath = ModLoader.GetSdModsBasePath(); + string titleModsPath = ModLoader.GetTitleDir(sdModsBasePath, viewModel.SelectedApplication.TitleId); OpenHelper.OpenFolder(titleModsPath); } @@ -150,13 +156,14 @@ public async void PurgePtcCache_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning], - LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.TitleName), - LocaleManager.Instance[LocaleKeys.InputDialogYes], - LocaleManager.Instance[LocaleKeys.InputDialogNo], - LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + UserResult result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogWarning], + LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.TitleName), + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); if (result == UserResult.Yes) { @@ -197,13 +204,14 @@ public async void PurgeShaderCache_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning], - LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.TitleName), - LocaleManager.Instance[LocaleKeys.InputDialogYes], - LocaleManager.Instance[LocaleKeys.InputDialogNo], - LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + UserResult result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogWarning], + LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.TitleName), + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); if (result == UserResult.Yes) { @@ -253,7 +261,7 @@ public void OpenPtcDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu"); string mainDir = Path.Combine(ptcDir, "0"); @@ -274,7 +282,7 @@ public void OpenShaderCacheDirectory_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "shader"); @@ -287,13 +295,17 @@ public void OpenShaderCacheDirectory_Click(object sender, RoutedEventArgs args) } } - public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args) + public async void ExtractApplicationExeFs_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - await ApplicationHelper.ExtractSection(NcaSectionType.Logo, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName); + await ApplicationHelper.ExtractSection( + viewModel.StorageProvider, + NcaSectionType.Code, + viewModel.SelectedApplication.Path, + viewModel.SelectedApplication.TitleName); } } @@ -301,19 +313,48 @@ public async void ExtractApplicationRomFs_Click(object sender, RoutedEventArgs a { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - await ApplicationHelper.ExtractSection(NcaSectionType.Data, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName); + await ApplicationHelper.ExtractSection( + viewModel.StorageProvider, + NcaSectionType.Data, + viewModel.SelectedApplication.Path, + viewModel.SelectedApplication.TitleName); } } - public async void ExtractApplicationExeFs_Click(object sender, RoutedEventArgs args) + public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args) + { + var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; + + if (viewModel?.SelectedApplication != null) + { + await ApplicationHelper.ExtractSection( + viewModel.StorageProvider, + NcaSectionType.Logo, + viewModel.SelectedApplication.Path, + viewModel.SelectedApplication.TitleName); + } + } + + public void CreateApplicationShortcut_Click(object sender, RoutedEventArgs args) + { + var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; + + if (viewModel?.SelectedApplication != null) + { + ApplicationData selectedApplication = viewModel.SelectedApplication; + ShortcutHelper.CreateAppShortcut(selectedApplication.Path, selectedApplication.TitleName, selectedApplication.TitleId, selectedApplication.Icon); + } + } + + public async void RunApplication_Click(object sender, RoutedEventArgs args) { var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; - if (viewModel.SelectedApplication != null) + if (viewModel?.SelectedApplication != null) { - await ApplicationHelper.ExtractSection(NcaSectionType.Code, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName); + await viewModel.LoadApplication(viewModel.SelectedApplication.Path); } } } diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml index f7a120b1a..bbdb4c4a7 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml @@ -11,7 +11,9 @@ d:DesignHeight="450" d:DesignWidth="800" Focusable="True" - mc:Ignorable="d"> + mc:Ignorable="d" + xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + x:DataType="viewModels:MainWindowViewModel"> @@ -27,15 +29,15 @@ VerticalAlignment="Stretch" ContextFlyout="{StaticResource ApplicationContextMenu}" DoubleTapped="GameList_DoubleTapped" - Items="{Binding AppsObservableList}" + ItemsSource="{Binding AppsObservableList}" SelectionChanged="GameList_SelectionChanged"> + JustifyContent="FlexStart" /> @@ -43,8 +45,8 @@ - @@ -54,10 +56,10 @@ Margin="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}" - Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}" - Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}" - Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}" + Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}" + Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}" + Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}" + Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}" ClipToBounds="True" CornerRadius="4"> @@ -76,9 +78,9 @@ Margin="0,10,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}"> + IsVisible="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ShowNames}"> - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs index c30c75b36..821d6fd9f 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs @@ -1,7 +1,6 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ui.App.Common; @@ -16,7 +15,7 @@ public partial class ApplicationGridView : UserControl public event EventHandler ApplicationOpened { - add { AddHandler(ApplicationOpenedEvent, value); } + add { AddHandler(ApplicationOpenedEvent, value); } remove { RemoveHandler(ApplicationOpenedEvent, value); } } @@ -25,12 +24,7 @@ public ApplicationGridView() InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - public void GameList_DoubleTapped(object sender, RoutedEventArgs args) + public void GameList_DoubleTapped(object sender, TappedEventArgs args) { if (sender is ListBox listBox) { diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml index fa8ebf627..fecf08883 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml @@ -10,7 +10,9 @@ d:DesignHeight="450" d:DesignWidth="800" Focusable="True" - mc:Ignorable="d"> + mc:Ignorable="d" + xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + x:DataType="viewModels:MainWindowViewModel"> @@ -27,7 +29,7 @@ VerticalAlignment="Stretch" ContextFlyout="{StaticResource ApplicationContextMenu}" DoubleTapped="GameList_DoubleTapped" - Items="{Binding AppsObservableList}" + ItemsSource="{Binding AppsObservableList}" SelectionChanged="GameList_SelectionChanged"> @@ -39,8 +41,8 @@ - @@ -65,10 +67,10 @@ Grid.RowSpan="3" Grid.Column="0" Margin="0" - Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}" - Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}" - Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}" - Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}" + Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}" + Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}" + Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}" + Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}" Source="{Binding Icon, Converter={StaticResource ByteImage}}" /> @@ -108,12 +110,12 @@ - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs index 1a07c4251..dd60503af 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs @@ -1,7 +1,6 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ui.App.Common; @@ -16,7 +15,7 @@ public partial class ApplicationListView : UserControl public event EventHandler ApplicationOpened { - add { AddHandler(ApplicationOpenedEvent, value); } + add { AddHandler(ApplicationOpenedEvent, value); } remove { RemoveHandler(ApplicationOpenedEvent, value); } } @@ -25,12 +24,7 @@ public ApplicationListView() InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - public void GameList_DoubleTapped(object sender, RoutedEventArgs args) + public void GameList_DoubleTapped(object sender, TappedEventArgs args) { if (sender is ListBox listBox) { diff --git a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs index 1b857fae4..a32c052bf 100644 --- a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs @@ -2,7 +2,6 @@ using Avalonia.Controls; using Avalonia.Styling; using Avalonia.Threading; -using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; using LibHac; using LibHac.Common; @@ -10,7 +9,6 @@ using LibHac.Fs.Shim; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Views.User; using Ryujinx.HLE.FileSystem; @@ -19,6 +17,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId; using UserProfile = Ryujinx.Ava.UI.Models.UserProfile; namespace Ryujinx.Ava.UI.Controls @@ -56,7 +55,7 @@ public NavigationDialogHost(AccountManager accountManager, ContentManager conten InitializeComponent(); } - public void GoBack(object parameter = null) + public void GoBack() { if (ContentFrame.BackStack.Count > 0) { @@ -75,14 +74,14 @@ public static async Task Show(AccountManager ownerAccountManager, ContentManager VirtualFileSystem ownerVirtualFileSystem, HorizonClient ownerHorizonClient) { var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient); - ContentDialog contentDialog = new ContentDialog + ContentDialog contentDialog = new() { Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle], PrimaryButtonText = "", SecondaryButtonText = "", CloseButtonText = "", Content = content, - Padding = new Thickness(0) + Padding = new Thickness(0), }; contentDialog.Closed += (sender, args) => @@ -125,7 +124,7 @@ public void LoadProfiles() Span saveDataInfo = stackalloc SaveDataInfo[10]; - HashSet lostAccounts = new(); + HashSet lostAccounts = new(); while (true) { @@ -139,15 +138,15 @@ public void LoadProfiles() for (int i = 0; i < readCount; i++) { var save = saveDataInfo[i]; - var id = new HLE.HOS.Services.Account.Acc.UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High); - if (ViewModel.Profiles.Cast().FirstOrDefault( x=> x.UserId == id) == null) + var id = new UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High); + if (ViewModel.Profiles.Cast().FirstOrDefault(x => x.UserId == id) == null) { lostAccounts.Add(id); } } } - foreach(var account in lostAccounts) + foreach (var account in lostAccounts) { ViewModel.LostProfiles.Add(new UserProfile(new HLE.HOS.Services.Account.Acc.UserProfile(account, "", null), this)); } @@ -166,7 +165,7 @@ public async void DeleteUser(UserProfile userProfile) if (profile == null) { - async void Action() + static async void Action() { await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionWarningMessage]); } @@ -215,4 +214,4 @@ public void ManageSaves() Navigate(typeof(UserSaveManagerView), (this, AccountManager, HorizonClient, VirtualFileSystem)); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs b/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs new file mode 100644 index 000000000..b57c6f0a2 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs @@ -0,0 +1,31 @@ +using Avalonia.Controls; +using Avalonia.Input; +using System; + +namespace Ryujinx.Ava.UI.Controls +{ + public class SliderScroll : Slider + { + protected override Type StyleKeyOverride => typeof(Slider); + + protected override void OnPointerWheelChanged(PointerWheelEventArgs e) + { + var newValue = Value + e.Delta.Y * TickFrequency; + + if (newValue < Minimum) + { + Value = Minimum; + } + else if (newValue > Maximum) + { + Value = Maximum; + } + else + { + Value = newValue; + } + + e.Handled = true; + } + } +} diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs index 80a437e33..7ad1ee332 100644 --- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs @@ -28,4 +28,4 @@ public UpdateWaitWindow() InitializeComponent(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs b/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs index ebf5c16ec..cd63a99b0 100644 --- a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs +++ b/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs @@ -13,4 +13,4 @@ public ApplicationOpenedEventArgs(ApplicationData application, RoutedEvent route RoutedEvent = routedEvent; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs index 3fd368f89..42bd8d5a8 100644 --- a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs +++ b/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs @@ -21,6 +21,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn if (value is byte[] buffer && targetType == typeof(IImage)) { MemoryStream mem = new(buffer); + return new Bitmap(mem); } @@ -32,4 +33,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu throw new NotSupportedException(); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs b/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs index 6730b5711..7e8ba7342 100644 --- a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs +++ b/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs @@ -23,7 +23,7 @@ public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned) IsAssigned = isAssigned; } } - + public ToggleButton ToggledButton { get; set; } private bool _isWaitingForInput; diff --git a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs index cb474506b..a57deb1a0 100644 --- a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs @@ -1,12 +1,12 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Layout; using Avalonia.Media; using Avalonia.Threading; using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Windows; using Ryujinx.Common.Logging; using System; @@ -18,8 +18,9 @@ namespace Ryujinx.Ava.UI.Helpers public static class ContentDialogHelper { private static bool _isChoiceDialogOpen; + private static ContentDialogOverlayWindow _contentDialogOverlayWindow; - public async static Task ShowContentDialog( + private async static Task ShowContentDialog( string title, object content, string primaryButton, @@ -33,18 +34,17 @@ public async static Task ShowContentDialog( ContentDialog contentDialog = new() { - Title = title, - PrimaryButtonText = primaryButton, + Title = title, + PrimaryButtonText = primaryButton, SecondaryButtonText = secondaryButton, - CloseButtonText = closeButton, - Content = content + CloseButtonText = closeButton, + Content = content, + PrimaryButtonCommand = MiniCommand.Create(() => + { + result = primaryButtonResult; + }), }; - contentDialog.PrimaryButtonCommand = MiniCommand.Create(() => - { - result = primaryButtonResult; - }); - contentDialog.SecondaryButtonCommand = MiniCommand.Create(() => { result = UserResult.No; @@ -67,7 +67,7 @@ public async static Task ShowContentDialog( return result; } - private async static Task ShowTextDialog( + public async static Task ShowTextDialog( string title, string primaryText, string secondaryText, @@ -97,7 +97,6 @@ public async static Task ShowDeferredContentDialog( Func doWhileDeferred = null) { bool startedDeferring = false; - UserResult result = UserResult.None; return await ShowTextDialog( title, @@ -124,8 +123,6 @@ async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs ar var deferral = args.GetDeferral(); - result = primaryButton == LocaleManager.Instance[LocaleKeys.InputDialogYes] ? UserResult.Yes : UserResult.Ok; - sender.PrimaryButtonClick -= DeferClose; _ = Task.Run(() => @@ -151,18 +148,18 @@ private static Grid CreateTextDialogContent(string primaryText, string secondary { Grid content = new() { - RowDefinitions = new RowDefinitions() { new RowDefinition(), new RowDefinition() }, - ColumnDefinitions = new ColumnDefinitions() { new ColumnDefinition(GridLength.Auto), new ColumnDefinition() }, + RowDefinitions = new RowDefinitions { new(), new() }, + ColumnDefinitions = new ColumnDefinitions { new(GridLength.Auto), new() }, - MinHeight = 80 + MinHeight = 80, }; SymbolIcon icon = new() { - Symbol = (Symbol)symbol, - Margin = new Thickness(10), - FontSize = 40, - VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center + Symbol = (Symbol)symbol, + Margin = new Thickness(10), + FontSize = 40, + VerticalAlignment = VerticalAlignment.Center, }; Grid.SetColumn(icon, 0); @@ -171,18 +168,18 @@ private static Grid CreateTextDialogContent(string primaryText, string secondary TextBlock primaryLabel = new() { - Text = primaryText, - Margin = new Thickness(5), + Text = primaryText, + Margin = new Thickness(5), TextWrapping = TextWrapping.Wrap, - MaxWidth = 450 + MaxWidth = 450, }; TextBlock secondaryLabel = new() { - Text = secondaryText, - Margin = new Thickness(5), + Text = secondaryText, + Margin = new Thickness(5), TextWrapping = TextWrapping.Wrap, - MaxWidth = 450 + MaxWidth = 450, }; Grid.SetColumn(primaryLabel, 1); @@ -314,33 +311,39 @@ internal static async Task CreateStopEmulationDialog() public static async Task ShowAsync(ContentDialog contentDialog) { ContentDialogResult result; - - ContentDialogOverlayWindow contentDialogOverlayWindow = null; + bool isTopDialog = true; Window parent = GetMainWindow(); - if (parent != null && parent.IsActive && parent is MainWindow window && window.ViewModel.IsGameRunning) + if (_contentDialogOverlayWindow != null) + { + isTopDialog = false; + } + + if (parent is MainWindow window) { - contentDialogOverlayWindow = new() + parent.Activate(); + + _contentDialogOverlayWindow = new ContentDialogOverlayWindow { - Height = parent.Bounds.Height, - Width = parent.Bounds.Width, - Position = parent.PointToScreen(new Point()), - ShowInTaskbar = false + Height = parent.Bounds.Height, + Width = parent.Bounds.Width, + Position = parent.PointToScreen(new Point()), + ShowInTaskbar = false, }; parent.PositionChanged += OverlayOnPositionChanged; void OverlayOnPositionChanged(object sender, PixelPointEventArgs e) { - contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); + _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); } - contentDialogOverlayWindow.ContentDialog = contentDialog; + _contentDialogOverlayWindow.ContentDialog = contentDialog; bool opened = false; - contentDialogOverlayWindow.Opened += OverlayOnActivated; + _contentDialogOverlayWindow.Opened += OverlayOnActivated; async void OverlayOnActivated(object sender, EventArgs e) { @@ -351,12 +354,12 @@ async void OverlayOnActivated(object sender, EventArgs e) opened = true; - contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); + _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); result = await ShowDialog(); } - result = await contentDialogOverlayWindow.ShowDialog(parent); + result = await _contentDialogOverlayWindow.ShowDialog(parent); } else { @@ -365,36 +368,45 @@ async void OverlayOnActivated(object sender, EventArgs e) async Task ShowDialog() { - if (contentDialogOverlayWindow is not null) + if (_contentDialogOverlayWindow is not null) { - result = await contentDialog.ShowAsync(contentDialogOverlayWindow); + result = await contentDialog.ShowAsync(_contentDialogOverlayWindow); - contentDialogOverlayWindow!.Close(); + _contentDialogOverlayWindow!.Close(); } else { - result = await contentDialog.ShowAsync(); + result = ContentDialogResult.None; + + Logger.Warning?.Print(LogClass.Ui, "Content dialog overlay failed to populate. Default value has been returned."); } return result; } - if (contentDialogOverlayWindow is not null) + if (isTopDialog && _contentDialogOverlayWindow is not null) { - contentDialogOverlayWindow.Content = null; - contentDialogOverlayWindow.Close(); + _contentDialogOverlayWindow.Content = null; + _contentDialogOverlayWindow.Close(); } return result; } + public static Task ShowWindowAsync(Window dialogWindow, Window mainWindow = null) + { + mainWindow ??= GetMainWindow(); + + return dialogWindow.ShowDialog(_contentDialogOverlayWindow ?? mainWindow); + } + private static Window GetMainWindow() { - if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime al) + if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime al) { foreach (Window item in al.Windows) { - if (item.IsActive && item is MainWindow window) + if (item is MainWindow window) { return window; } @@ -404,4 +416,4 @@ private static Window GetMainWindow() return null; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs b/src/Ryujinx.Ava/UI/Helpers/Glyph.cs index 4aae854f7..f257dc02c 100644 --- a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs +++ b/src/Ryujinx.Ava/UI/Helpers/Glyph.cs @@ -1,9 +1,9 @@ -namespace Ryujinx.Ava.UI.Helpers +namespace Ryujinx.Ava.UI.Helpers { public enum Glyph { List, Grid, - Chip + Chip, } } diff --git a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs index 3d6c9c018..7da23648e 100644 --- a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs +++ b/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs @@ -1,4 +1,3 @@ -using Avalonia.Data; using Avalonia.Markup.Xaml; using FluentAvalonia.UI.Controls; using System; @@ -8,13 +7,13 @@ namespace Ryujinx.Ava.UI.Helpers { public class GlyphValueConverter : MarkupExtension { - private string _key; + private readonly string _key; - private static Dictionary _glyphs = new Dictionary + private static readonly Dictionary _glyphs = new() { - { Glyph.List, char.ConvertFromUtf32((int)Symbol.List).ToString() }, - { Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll).ToString() }, - { Glyph.Chip, char.ConvertFromUtf32(59748).ToString() } + { Glyph.List, char.ConvertFromUtf32((int)Symbol.List) }, + { Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll) }, + { Glyph.Chip, char.ConvertFromUtf32(59748) }, }; public GlyphValueConverter(string key) @@ -37,13 +36,7 @@ public string this[string key] public override object ProvideValue(IServiceProvider serviceProvider) { - Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension binding = new($"[{_key}]") - { - Mode = BindingMode.OneWay, - Source = this - }; - - return binding.ProvideValue(serviceProvider); + return this[_key]; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs b/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs deleted file mode 100644 index f1fad1576..000000000 --- a/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Input; -using System; -using System.Windows.Input; - -namespace Ryujinx.Ava.UI.Helpers -{ - public class HotKeyControl : ContentControl, ICommandSource - { - public static readonly StyledProperty CommandParameterProperty = - AvaloniaProperty.Register(nameof(CommandParameter)); - - public static readonly DirectProperty CommandProperty = - AvaloniaProperty.RegisterDirect(nameof(Command), - control => control.Command, (control, command) => control.Command = command, enableDataValidation: true); - - public static readonly StyledProperty HotKeyProperty = HotKeyManager.HotKeyProperty.AddOwner