Compare commits

..

1 Commits

Author SHA1 Message Date
GreemDev
c997f52dcd Attempt 1 2025-04-09 01:03:32 -05:00
788 changed files with 8782 additions and 15380 deletions

View File

@@ -16,17 +16,6 @@ tab_width = 4
# New line preferences
end_of_line = lf
insert_final_newline = true
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_explicit_tuple_names = true:suggestion
# Markdown, JSON, YAML, props and csproj files
[*.{md,json,yml,props,csproj}]
@@ -117,7 +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:silent
csharp_style_prefer_method_group_conversion = true
# Code-block preferences
csharp_prefer_braces = true:silent
@@ -188,9 +177,9 @@ csharp_preserve_single_line_statements = false
# Naming rules
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = suggestion
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.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
@@ -247,22 +236,28 @@ dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case
# Other settings
csharp_style_prefer_top_level_statements = true:suggestion
csharp_style_prefer_primary_constructors = false:suggestion
csharp_prefer_system_threading_lock = true:suggestion
# Analyzers
dotnet_diagnostic.CA1069.severity = none # CA1069: Enums values should not be duplicated
# Disable Collection initialization can be simplified
# 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
dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
# 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/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels

View File

@@ -21,9 +21,60 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
RELEASE: 1
jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release:
name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
@@ -31,7 +82,7 @@ jobs:
matrix:
platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps:
@@ -57,8 +108,11 @@ jobs:
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
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
shell: bash
- name: Create output dir
@@ -75,24 +129,7 @@ jobs:
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
@@ -102,10 +139,8 @@ jobs:
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash
- name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest'
run: |
@@ -134,17 +169,41 @@ jobs:
exit 1
fi
export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|Canary-Releases|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash
popd
shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release:
name: Release MacOS universal
@@ -161,16 +220,6 @@ jobs:
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign
run: |
@@ -197,53 +246,24 @@ jobs:
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
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx
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 1
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create tag
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}"
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=CreateReleaseFromGenericPackageFiles "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|main|Canary ${{ steps.version_info.outputs.build_version }}|**Full Changelog:** [${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
artifacts: "publish_ava/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }}
body: ""
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}

View File

@@ -1,224 +0,0 @@
name: Release job (Debug)
on:
workflow_dispatch:
inputs: {}
concurrency: release
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RELEASE: 1
jobs:
release:
name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
strategy:
matrix:
platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps:
- 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 }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $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
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_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
run: "mkdir release_output"
- name: Publish
run: |
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./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
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash
- name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest'
run: |
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
PLATFORM_NAME="${{ matrix.platform.name }}"
sudo apt install -y zsync desktop-file-utils appstream
mkdir -p tools
export PATH="$PATH:$(readlink -f tools)"
# Setup appimagetool
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x tools/appimagetool
chmod +x distribution/linux/appimage/build-appimage.sh
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
ARCH_NAME=x64
export ARCH=x86_64
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
ARCH_NAME=arm64
export ARCH=aarch64
else
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
exit 1
fi
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash
macos_release:
name: Release MacOS universal
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Setup LLVM 17
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- 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 }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $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_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|test|THIS IS NOT INTENDED FOR END USER USAGE"

View File

@@ -11,9 +11,57 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
RELEASE: 1
jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release:
name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
@@ -21,7 +69,7 @@ jobs:
matrix:
platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps:
@@ -47,6 +95,9 @@ jobs:
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
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
@@ -64,24 +115,7 @@ jobs:
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
@@ -91,12 +125,8 @@ jobs:
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest'
run: |
@@ -132,11 +162,32 @@ jobs:
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release:
name: Release MacOS universal
runs-on: ubuntu-24.04
@@ -152,16 +203,6 @@ jobs:
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign
run: |
@@ -186,49 +227,26 @@ jobs:
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
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|${{ steps.version_info.outputs.build_version }}|msd:${{ steps.version_info.outputs.build_version }}"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "publish/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }}
body: ""
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}

4
.gitignore vendored
View File

@@ -178,7 +178,3 @@ PublishProfiles/
# Ignore MacOS Attribute Files
._*
# Ignore distribution build files
distribution/macos/temp/
distribution/macos/output/

View File

@@ -1,18 +0,0 @@
function pub {
dotnet publish -c release
}
function package {
cd src/$1
pub
mv bin/Release/$1.1.0.0.nupkg ../../pkgs/$1.1.0.0.nupkg
cd ../../
}
rm -rf pkgs
mkdir pkgs
package ARMeilleure
package Ryujinx.Memory
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs

View File

@@ -2,17 +2,18 @@
All updates to this Ryujinx branch will be documented in this file.
## [1.3.2](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.2>) - 2025-06-09
## [1.3.1](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.1>) - 2025-04-23
## [1.2.86](<https://github.com/Ryubing/Stable-Releases/releases/tag/1.2.86>) - 2025-03-13
## [1.2.86](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.2.86>) - 2025-03-13
A list of notable changes can be found on the release linked in the version number above.
## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16
A list of notable changes can be found on the release linked in the version number above.
## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22
A list of notable changes can be found on the release linked in the version number above.
## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19
A list of notable changes can be found on the release linked in the version number above.
## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19
A list of notable changes can be found on the release linked in the version number above.
@@ -251,4 +252,4 @@ Added Low-power PPTC mode strings to the translation files.
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)).
- Changed executable icon to rainbow logo.
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.

View File

@@ -23,6 +23,7 @@
<PackageVersion Include="DynamicData" Version="9.0.4" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
<PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="LibHac" Version="0.19.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
@@ -40,10 +41,7 @@
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
<PackageVersion Include="Gommon" Version="2.7.1.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.6.0" />

View File

@@ -7,8 +7,8 @@
# Ryujinx
[![Latest release](https://img.shields.io/gitlab/v/release/ryubing%2Fryujinx?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=stable&color=32cd32)](https://update.ryujinx.app/latest/stable)
[![Latest canary release](https://img.shields.io/gitlab/v/release/ryubing%2Fcanary?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=canary&color=FF4500)](https://update.ryujinx.app/latest/canary)
[![Latest release](https://img.shields.io/github/v/release/Ryubing/Stable-Releases?label=stable)](https://github.com/Ryubing/Stable-Releases/releases/latest)
[![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest)
<br>
<a href="https://discord.gg/PEuzjrFXUA">
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
@@ -31,7 +31,7 @@
<br>
This is not a Ryujinx revival project. This is not a Phoenix project.
<br>
Guides and documentation can be found on the <a href="https://git.ryujinx.app/groups/ryubing/-/wikis/home">Wiki tab</a>.
Guides and documentation can be found on the <a href="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/home">Wiki tab</a>.
</p>
<p align="center">
@@ -49,13 +49,13 @@ Stable builds are made every so often, based on the `master` branch, that then g
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
You can find the stable releases [here](https://git.ryujinx.app/ryubing/ryujinx/-/releases).
You can find the latest stable release [here](https://github.com/Ryubing/Stable-Releases/releases/latest).
Canary builds are compiled automatically for each commit on the `master` branch.
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
These canary builds are only recommended for experienced users.
You can find the canary releases [here](https://git.ryujinx.app/ryubing/canary/-/releases).
You can find the latest canary release [here](https://github.com/Ryubing/Canary-Releases/releases/latest).
## Documentation
@@ -111,7 +111,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
## Credits
- [LibHac](https://git.ryujinx.app/ryubing/libhac) is used for our file-system.
- [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.
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.

View File

@@ -77,8 +77,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -86,9 +84,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.github\workflows\canary.yml = .github\workflows\canary.yml
Directory.Packages.props = Directory.Packages.props
.github\workflows\release.yml = .github\workflows\release.yml
nuget.config = nuget.config
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
mkdir -p "$OUTDIR"
appimagetool -n --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
-u "$UFLAG" \
AppDir "$OUTDIR"/Ryujinx.AppImage

View File

@@ -562,29 +562,26 @@ search_path = [
for path in content_directory.rglob("**/*.dylib"):
if not path.name.startswith("._"):
current_search_path = [path.parent]
current_search_path.extend(search_path)
current_search_path = [path.parent]
current_search_path.extend(search_path)
print(f"Fixing path '{path}' using search path of '{current_search_path}' for context of '{content_directory}'.")
fixup_dylib(
path,
get_path_related_to_target_exec(content_directory, path),
current_search_path,
content_directory,
)
fixup_dylib(
path,
get_path_related_to_target_exec(content_directory, path),
current_search_path,
content_directory,
)
for path in content_directory.rglob("**/*.so"):
if not path.name.startswith("._"):
current_search_path = [path.parent]
current_search_path.extend(search_path)
current_search_path = [path.parent]
current_search_path.extend(search_path)
fixup_dylib(
path,
get_path_related_to_target_exec(content_directory, path),
current_search_path,
content_directory,
)
fixup_dylib(
path,
get_path_related_to_target_exec(content_directory, path),
current_search_path,
content_directory,
)
with open(executable_path, "rb") as input:

View File

@@ -30,32 +30,21 @@ cp -r "$PUBLISH_DIRECTORY/THIRDPARTY.md" "$APP_BUNDLE_DIRECTORY/Contents/Resourc
echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
# Fixup libraries and executable
echo "Running bundle fix up python script"
python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx
# Now sign it
echo "Starting signing process"
if ! [ -x "$(command -v codesign)" ];
then
if ! [ -x "$(command -v rcodesign)" ];
then
echo "Cannot find rcodesign on your system, please install rcodesign and ensure it is in your search path."
echo "Cannot find rcodesign on your system, please install rcodesign."
exit 1
fi
echo "Using rcodesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec rcodesign sign {} \;
echo "Signing app bundle as ad-hoc"
# cargo install apple-codesign
echo "Usign rcodesign for ad-hoc signing"
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY"
else
echo "Using codesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
echo "Signing app bundle as ad-hoc"
echo "Usign codesign for ad-hoc signing"
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY"
fi

View File

@@ -20,18 +20,6 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7
CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
elif [ "$VERSION" == "1.1.0" ]; then

View File

@@ -20,18 +20,6 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7
CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
elif [ "$VERSION" == "1.1.0" ]; then

View File

@@ -188,8 +188,6 @@
01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27
01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18
01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12
01009E8012976000,"AKIBA'S TRIP: Hellbound & Debriefed",,playable,2025-07-30 23:22:47
0100D74019A0E000,"AKIBA'S TRIP: Undead & Undressed Director's Cut",,playable,2025-07-31 13:58:42
010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35
0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36
010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27
@@ -603,7 +601,6 @@
010060200A4BE000,"Brawlout",ldn-untested;online,playable,2021-06-04 17:35:35
0100C1B00E1CA000,"Brawlout Demo",demo,playable,2021-02-13 22:46:53
010022C016DC8000,"Breakout: Recharged",slow,ingame,2022-11-06 15:32:57
010048A021C40000,"Breakout Beyond",,playable,2025-04-26 19:11:35
01000AA013A5E000,"Breathedge",UE4;nvdec,playable,2021-05-06 15:44:28
01003D50100F4000,"Breathing Fear",,playable,2020-07-14 15:12:29
010026800BB06000,"Brick Breaker",nvdec;online,playable,2020-12-15 18:26:23
@@ -1097,7 +1094,6 @@
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
010018f01e0a0000,"Eternights",,playable,2025-07-30 12:10:24
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
@@ -1128,7 +1124,6 @@
0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06
010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39
0100767008502000,"FANTASY HERO unsigned legacy",,playable,2022-07-26 12:28:52
0100755017EE0000,"FANTASY LIFE i: The Girl Who Steals Time",gpu;crash;vulkan-backend-bug,ingame,2025-06-08 20:41:00
0100944003820000,"Fantasy Strike",online,playable,2021-02-27 01:59:18
01000E2012F6E000,"Fantasy Tavern Sextet -Vol.1 New World Days-",gpu;crash;Needs Update,ingame,2022-12-05 16:48:00
01005C10136CA000,"Fantasy Tavern Sextet -Vol.2 Adventurer's Days-",gpu;slow;crash,ingame,2021-11-06 02:57:29
@@ -1243,8 +1238,6 @@
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
0100c4e018a24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
01007E6019872000,"FRONT MISSION 3: Remake",,playable,2025-07-30 12:12:02
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33
@@ -1523,7 +1516,6 @@
010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53
0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15
0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22
010059801B736000,"IronFall: Invasion",,playable,2025-07-30 11:42:30
01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57
01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29
0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37
@@ -2036,7 +2028,6 @@
0100628004BCE000,"Nights of Azure 2: Bride of the New Moon",crash;nvdec;regression,menus,2022-11-24 16:00:39
010042300C4F6000,"Nightshade百花百狼",nvdec,playable,2020-05-10 19:43:31
0100AA0008736000,"Nihilumbra",,playable,2020-05-10 16:00:12
01009FA01FF6C000,"Nikoderiko: The Magical World",gpu,ingame,2025-04-26 19:13:31
0100D03003F0E000,"Nine Parchments",ldn-untested,playable,2022-08-07 12:32:08
0100E2F014F46000,"NINJA GAIDEN Σ",nvdec,playable,2022-11-13 16:27:02
0100696014F4A000,"NINJA GAIDEN Σ2",nvdec,playable,2024-07-31 21:53:48
@@ -2263,7 +2254,6 @@
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
@@ -2312,7 +2302,6 @@
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
0100c3a017834000,"Prodeus",,playable,2025-07-30 12:07:52
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
@@ -2444,7 +2433,6 @@
0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14
01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06
010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02
0100D1801A0F4000,"Risk of Rain Returns",,playable,2025-06-28 04:24:04
010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05
0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28
010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47
@@ -2755,7 +2743,6 @@
01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51
010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33
0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05
0100E1D01EB2E000,"Squeakross: Home Squeak Home",,playable,2025-06-16 02:02:00
010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08
0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32
0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16
@@ -2775,7 +2762,7 @@
0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51
01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19
0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",,playable,2025-07-30 12:09:37
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",services-horizon;crash;Needs Update,nothing,2024-05-05 17:25:11
010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43
01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55
010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05
@@ -2983,7 +2970,6 @@
0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28
01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35
0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06
0100BA5013E52000,"The Falconeer: Warrior Edition",,playable,2025-07-30 12:04:50
01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16
01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08
0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39
@@ -3027,7 +3013,6 @@
01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32
0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05
01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07
01009C901ACEE000,"The Legend of Nayuta: Boundless Trails",,ingame,2025-06-12 15:47
01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01
0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58
01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46
@@ -3206,7 +3191,6 @@
010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05
0100752011628000,"TTV2",,playable,2020-11-27 13:21:36
0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20
0100D1A01D7BA000,"Turbo Overkill",,playable,2025-07-30 12:08:57
010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24
0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05
010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56
@@ -3230,8 +3214,6 @@
0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56
01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45
010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18
01009B700D0B8000,"Undead Horde",,playable,2025-07-30 12:05:05
0100FC301A878000,"Undead Horde 2: Necropolis",,playable,2025-07-30 12:06:07
01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58
010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46
01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00
1 title_id game_name labels status last_updated
188 01003DD00BFEE000 Airheart - Tales of broken Wings playable 2021-02-26 15:20:27
189 01007F100DE52000 Akane nvdec playable 2022-07-21 00:12:18
190 01009A800F0C8000 Akash: Path of the Five gpu;nvdec ingame 2020-12-14 22:33:12
01009E8012976000 AKIBA'S TRIP: Hellbound & Debriefed playable 2025-07-30 23:22:47
0100D74019A0E000 AKIBA'S TRIP: Undead & Undressed Director's Cut playable 2025-07-31 13:58:42
191 010053100B0EA000 Akihabara - Feel the Rhythm Remixed playable 2021-02-22 14:39:35
192 0100D4C00EE0C000 Akuarium slow playable 2020-12-12 23:43:36
193 010026E00FEBE000 Akuto: Showdown playable 2020-08-04 19:43:27
601 010060200A4BE000 Brawlout ldn-untested;online playable 2021-06-04 17:35:35
602 0100C1B00E1CA000 Brawlout Demo demo playable 2021-02-13 22:46:53
603 010022C016DC8000 Breakout: Recharged slow ingame 2022-11-06 15:32:57
010048A021C40000 Breakout Beyond playable 2025-04-26 19:11:35
604 01000AA013A5E000 Breathedge UE4;nvdec playable 2021-05-06 15:44:28
605 01003D50100F4000 Breathing Fear playable 2020-07-14 15:12:29
606 010026800BB06000 Brick Breaker nvdec;online playable 2020-12-15 18:26:23
1094 0100F9600E746000 ESP Ra.De. Psi audio;slow ingame 2024-03-07 15:05:08
1095 010073000FE18000 Esports powerful pro yakyuu 2020 gpu;crash;Needs More Attention ingame 2024-04-29 05:34:14
1096 01004F9012FD8000 Estranged: The Departure nvdec;UE4 playable 2022-10-24 10:37:58
010018f01e0a0000 Eternights playable 2025-07-30 12:10:24
1097 0100CB900B498000 Eternum Ex playable 2021-01-13 20:28:32
1098 010092501EB2C000 Europa (Demo) gpu;crash;UE4 ingame 2024-04-23 10:47:12
1099 01007BE0160D6000 EVE ghost enemies gpu ingame 2023-01-14 03:13:30
1124 0100034012606000 Family Mysteries: Poisonous Promises audio;crash menus 2021-11-26 12:35:06
1125 010017C012726000 Fantasy Friends playable 2022-10-17 19:42:39
1126 0100767008502000 FANTASY HERO ~unsigned legacy~ playable 2022-07-26 12:28:52
0100755017EE0000 FANTASY LIFE i: The Girl Who Steals Time gpu;crash;vulkan-backend-bug ingame 2025-06-08 20:41:00
1127 0100944003820000 Fantasy Strike online playable 2021-02-27 01:59:18
1128 01000E2012F6E000 Fantasy Tavern Sextet -Vol.1 New World Days- gpu;crash;Needs Update ingame 2022-12-05 16:48:00
1129 01005C10136CA000 Fantasy Tavern Sextet -Vol.2 Adventurer's Days- gpu;slow;crash ingame 2021-11-06 02:57:29
1238 010003F00BD48000 Friday the 13th: Killer Puzzle playable 2021-01-28 01:33:38
1239 010092A00C4B6000 Friday the 13th: The Game Ultimate Slasher Edition nvdec;online-broken;UE4 playable 2022-09-06 17:33:27
1240 0100F200178F4000 FRONT MISSION 1st: Remake playable 2023-06-09 07:44:24
0100c4e018a24000 FRONT MISSION 2: Remake playable 2025-07-30 12:11:23
01007E6019872000 FRONT MISSION 3: Remake playable 2025-07-30 12:12:02
1241 0100861012474000 Frontline Zed playable 2020-10-03 12:55:59
1242 0100B5300B49A000 Frost playable 2022-07-27 12:00:36
1243 010038A007AA4000 FruitFall Crush playable 2020-10-20 11:33:33
1516 010095C016C14000 Iridium playable 2022-08-05 23:19:53
1517 0100AD300B786000 Iris School of Wizardry -Vinculum Hearts- playable 2022-12-05 13:11:15
1518 0100945012168000 Iris.Fall nvdec playable 2022-10-18 13:40:22
010059801B736000 IronFall: Invasion playable 2025-07-30 11:42:30
1519 01005270118D6000 Iron Wings slow ingame 2022-08-07 08:32:57
1520 01004DB003E6A000 IRONCAST playable 2021-01-13 13:54:29
1521 0100E5700CD56000 Irony Curtain: From Matryoshka with Love playable 2021-06-04 20:12:37
2028 0100628004BCE000 Nights of Azure 2: Bride of the New Moon crash;nvdec;regression menus 2022-11-24 16:00:39
2029 010042300C4F6000 Nightshade/百花百狼 nvdec playable 2020-05-10 19:43:31
2030 0100AA0008736000 Nihilumbra playable 2020-05-10 16:00:12
01009FA01FF6C000 Nikoderiko: The Magical World gpu ingame 2025-04-26 19:13:31
2031 0100D03003F0E000 Nine Parchments ldn-untested playable 2022-08-07 12:32:08
2032 0100E2F014F46000 NINJA GAIDEN Σ nvdec playable 2022-11-13 16:27:02
2033 0100696014F4A000 NINJA GAIDEN Σ2 nvdec playable 2024-07-31 21:53:48
2254 010086F0064CE000 Poi: Explorer Edition nvdec playable 2021-01-21 19:32:00
2255 0100EB6012FD2000 Poison Control playable 2021-05-16 14:01:54
2256 010072400E04A000 Pokémon Café ReMix playable 2021-08-17 20:00:04
010008c01e742000 Pokémon Friends crash;services menus 2025-07-24 13:32:00
2257 01003D200BAA2000 Pokémon Mystery Dungeon™: Rescue Team DX mac-bug playable 2024-01-21 00:16:32
2258 01008DB008C2C000 Pokémon Shield + Pokémon Shield Expansion Pass deadlock;crash;online-broken;ldn-works;LAN ingame 2024-08-12 07:20:22
2259 0100ABF008968000 Pokémon Sword + Pokémon Sword Expansion Pass deadlock;crash;online-broken;ldn-works;LAN ingame 2024-08-26 15:40:37
2302 010077B00BDD8000 Professional Farmer: Nintendo Switch™ Edition slow playable 2020-12-16 13:38:19
2303 010018300C83A000 Professor Lupo and his Horrible Pets playable 2020-06-12 00:08:45
2304 0100D1F0132F6000 Professor Lupo: Ocean playable 2021-04-14 16:33:33
0100c3a017834000 Prodeus playable 2025-07-30 12:07:52
2305 0100BBD00976C000 Project Highrise: Architect's Edition playable 2022-08-10 17:19:12
2306 0100ACE00DAB6000 Project Nimbus: Complete Edition nvdec;UE4;vulkan-backend-bug playable 2022-08-10 17:35:43
2307 01002980140F6000 Project TRIANGLE STRATEGY™ Debut Demo UE4;demo playable 2022-10-24 21:40:27
2433 0100E9C010EA8000 Rise of Insanity playable 2020-08-30 15:42:14
2434 01006BA00E652000 Rise: Race The Future playable 2021-02-27 13:29:06
2435 010020C012F48000 Rising Hell playable 2022-10-31 13:54:02
0100D1801A0F4000 Risk of Rain Returns playable 2025-06-28 04:24:04
2436 010076D00E4BA000 Risk of Rain 2 online-broken playable 2024-03-04 17:01:05
2437 0100E8300A67A000 RISK® Global Domination nvdec;online-broken playable 2022-08-01 18:53:28
2438 010042500FABA000 Ritual: Crown of Horns playable 2021-01-26 16:01:47
2743 01005D701264A000 SpyHack playable 2021-04-15 10:53:51
2744 010077B00E046000 Spyro™ Reignited Trilogy nvdec;UE4 playable 2022-09-11 18:38:33
2745 0100085012A0E000 Squeakers playable 2020-12-13 12:13:05
0100E1D01EB2E000 Squeakross: Home Squeak Home playable 2025-06-16 02:02:00
2746 010009300D31C000 Squidgies Takeover playable 2020-07-20 22:28:08
2747 0100FCD0102EC000 Squidlit playable 2020-08-06 12:38:32
2748 0100EBF00E702000 STAR OCEAN First Departure R nvdec playable 2021-07-05 19:29:16
2762 0100E6B0115FC000 Star99 online menus 2021-11-26 14:18:51
2763 01002100137BA000 Stardash playable 2021-01-21 16:31:19
2764 0100E65002BB8000 Stardew Valley online-broken;ldn-untested playable 2024-02-14 03:11:19
2765 01002CC003FE6000 Starlink: Battle for Atlas™ Digital Edition services-horizon;crash;Needs Update playable nothing 2025-07-30 12:09:37 2024-05-05 17:25:11
2766 010098E010FDA000 Starlit Adventures Golden Stars playable 2020-11-21 12:14:43
2767 01001BB00AC26000 STARSHIP AVENGER Operation: Take Back Earth playable 2021-01-12 15:52:55
2768 010000700A572000 State of Anarchy: Master of Mayhem nvdec playable 2021-01-12 19:00:05
2970 0100C2E0129A6000 The Executioner nvdec playable 2021-01-23 00:31:28
2971 01006050114D4000 The Experiment: Escape Room gpu ingame 2022-09-30 13:20:35
2972 0100B5900DFB2000 The Eyes of Ara playable 2022-09-16 14:44:06
0100BA5013E52000 The Falconeer: Warrior Edition playable 2025-07-30 12:04:50
2973 01002DD00AF9E000 The Fall gpu ingame 2020-05-31 23:31:16
2974 01003E5002320000 The Fall Part 2: Unbound playable 2021-11-06 02:18:08
2975 0100CDC00789E000 The Final Station nvdec playable 2022-08-22 15:54:39
3013 01009B101044C000 The Legend of Heroes: Trails of Cold Steel III Demo demo;nvdec playable 2021-04-23 01:07:32
3014 0100D3C010DE8000 The Legend of Heroes: Trails of Cold Steel IV nvdec playable 2021-04-23 14:01:05
3015 01005E5013862000 THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改] crash nothing 2021-09-30 14:41:07
01009C901ACEE000 The Legend of Nayuta: Boundless Trails ingame 2025-06-12 15:47
3016 01008CF01BAAC000 The Legend of Zelda Echoes of Wisdom nvdec;ASTC;intel-vendor-bug playable 2024-10-01 14:11:01
3017 0100509005AF2000 The Legend of Zelda: Breath of the Wild Demo demo ingame 2022-12-24 05:02:58
3018 01007EF00011E000 The Legend of Zelda™: Breath of the Wild gpu;amd-vendor-bug;mac-bug ingame 2024-09-23 19:35:46
3191 010000400F582000 TT Isle of Man Ride on the Edge 2 gpu;nvdec;online-broken ingame 2022-09-30 22:13:05
3192 0100752011628000 TTV2 playable 2020-11-27 13:21:36
3193 0100AFE00452E000 Tumblestone playable 2021-01-07 17:49:20
0100D1A01D7BA000 Turbo Overkill playable 2025-07-30 12:08:57
3194 010085500D5F6000 Turok gpu ingame 2021-06-04 13:16:24
3195 0100CDC00D8D6000 Turok 2: Seeds of Evil gpu;vulkan ingame 2022-09-12 17:50:05
3196 010004B0130C8000 Turrican Flashback audout playable 2021-08-30 10:07:56
3214 0100592005164000 UNBOX: Newbie's Adventure UE4 playable 2022-08-29 13:12:56
3215 01002D900C5E4000 Uncanny Valley nvdec playable 2021-06-04 13:28:45
3216 010076F011F54000 Undead & Beyond nvdec playable 2022-10-04 09:11:18
01009B700D0B8000 Undead Horde playable 2025-07-30 12:05:05
0100FC301A878000 Undead Horde 2: Necropolis playable 2025-07-30 12:06:07
3217 01008F3013E4E000 Under Leaves playable 2021-05-22 18:13:58
3218 010080B00AD66000 Undertale playable 2022-08-31 17:31:46
3219 01008F80049C6000 Unepic playable 2024-01-15 17:03:00

View File

@@ -1,25 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />
<add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
</packageSources>
<packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element -->
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="Ryujinx.UpdateClient">
<package pattern="Ryujinx.UpdateClient" />
<package pattern="Ryujinx.Systems.Update.Common" />
</packageSource>
<packageSource key="LibHacAlpha">
<package pattern="Ryujinx.LibHac" />
</packageSource>
</packageSourceMapping>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@@ -3,10 +3,10 @@
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
</ItemGroup>

View File

@@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsMemoryLoadOrStore(Instruction inst)
{
return inst is Instruction.Load or Instruction.Store;
return inst == Instruction.Load || inst == Instruction.Store;
}
private static bool ConstTooLong(Operand constOp, OperandType accessType)

View File

@@ -774,7 +774,6 @@ namespace ARMeilleure.CodeGen.Arm64
instI |= 1 << 22; // sh flag
imm >>= 12;
}
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
}
else

View File

@@ -52,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
// Any value AND all ones will be equal itself, so it's effectively a no-op.
// Any value OR all ones will be equal all ones, so one can just use MOV.
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
if (value is 0 or ulong.MaxValue)
if (value == 0 || value == ulong.MaxValue)
{
immN = 0;
immS = 0;

View File

@@ -1,7 +1,6 @@
using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory;
using System;
using System.Collections.Generic;
@@ -15,7 +14,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4;
private readonly RecyclableMemoryStream _stream;
private readonly Stream _stream;
public int StreamOffset => (int)_stream.Length;

View File

@@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
// The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last;
Debug.Assert(last.Instruction is Instruction.Tailcall or
Instruction.Return);
Debug.Assert(last.Instruction == Instruction.Tailcall ||
last.Instruction == Instruction.Return);
}
else
{
@@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type != OperandType.V128);
@@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type.IsInteger());
@@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsLoadOrStore(Operation operation)
{
return operation.Instruction is Instruction.Load or Instruction.Store;
return operation.Instruction == Instruction.Load || operation.Instruction == Instruction.Store;
}
private static OperandType GetMemOpValueType(Operation operation)
@@ -1499,7 +1499,6 @@ namespace ARMeilleure.CodeGen.Arm64
return false;
}
}
if (memOp.Index != default)
{
return false;
@@ -1554,7 +1553,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void EnsureSameReg(Operand op1, Operand op2)
{
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value);
}

View File

@@ -509,6 +509,7 @@ namespace ARMeilleure.CodeGen.Arm64
context.Assembler.WriteInstruction(instruction, rd, rn);
}
}
private static void GenerateScalarTernary(

View File

@@ -137,7 +137,6 @@ namespace ARMeilleure.CodeGen.Arm64
{
return val != 0;
}
return false;
}

View File

@@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
{
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
return info.Type is IntrinsicType.ScalarBinaryRd or
IntrinsicType.ScalarTernaryFPRdByElem or
IntrinsicType.ScalarTernaryShlRd or
IntrinsicType.ScalarTernaryShrRd or
IntrinsicType.Vector128BinaryRd or
IntrinsicType.VectorBinaryRd or
IntrinsicType.VectorInsertByElem or
IntrinsicType.VectorTernaryRd or
IntrinsicType.VectorTernaryRdBitwise or
IntrinsicType.VectorTernaryFPRdByElem or
IntrinsicType.VectorTernaryRdByElem or
IntrinsicType.VectorTernaryShlRd or
IntrinsicType.VectorTernaryShrRd;
return info.Type == IntrinsicType.ScalarBinaryRd ||
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 ||
info.Type == IntrinsicType.VectorTernaryRdBitwise ||
info.Type == IntrinsicType.VectorTernaryFPRdByElem ||
info.Type == IntrinsicType.VectorTernaryRdByElem ||
info.Type == IntrinsicType.VectorTernaryShlRd ||
info.Type == IntrinsicType.VectorTernaryShrRd;
}
private static bool HasConstSrc1(Operation node, ulong value)
@@ -849,7 +849,7 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison compType = (Comparison)comp.AsInt32();
return compType is Comparison.Equal or Comparison.NotEqual;
return compType == Comparison.Equal || compType == Comparison.NotEqual;
}
}
@@ -871,9 +871,9 @@ namespace ARMeilleure.CodeGen.Arm64
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
// Those have integer inputs that don't support consts.
return info.Type is not IntrinsicType.ScalarFPConvGpr and
not IntrinsicType.ScalarFPConvFixedGpr and
not IntrinsicType.SetRegister;
return info.Type != IntrinsicType.ScalarFPConvGpr &&
info.Type != IntrinsicType.ScalarFPConvFixedGpr &&
info.Type != IntrinsicType.SetRegister;
}
return false;

View File

@@ -37,7 +37,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x + y);
}
break;
case Instruction.BitwiseAnd:
@@ -49,7 +48,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x & y);
}
break;
case Instruction.BitwiseExclusiveOr:
@@ -61,7 +59,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x ^ y);
}
break;
case Instruction.BitwiseNot:
@@ -73,7 +70,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => ~x);
}
break;
case Instruction.BitwiseOr:
@@ -85,7 +81,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x | y);
}
break;
case Instruction.ConvertI64ToI32:
@@ -93,7 +88,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI32(operation, (x) => x);
}
break;
case Instruction.Compare:
@@ -135,7 +129,6 @@ namespace ARMeilleure.CodeGen.Optimizations
break;
}
}
break;
case Instruction.Copy:
@@ -147,7 +140,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => x);
}
break;
case Instruction.Divide:
@@ -159,7 +151,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
}
break;
case Instruction.DivideUI:
@@ -171,7 +162,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
}
break;
case Instruction.Multiply:
@@ -183,7 +173,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x * y);
}
break;
case Instruction.Negate:
@@ -195,7 +184,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => -x);
}
break;
case Instruction.ShiftLeft:
@@ -207,7 +195,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x << (int)y);
}
break;
case Instruction.ShiftRightSI:
@@ -219,7 +206,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
}
break;
case Instruction.ShiftRightUI:
@@ -231,7 +217,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
}
break;
case Instruction.SignExtend16:
@@ -243,7 +228,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (short)x);
}
break;
case Instruction.SignExtend32:
@@ -255,7 +239,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (int)x);
}
break;
case Instruction.SignExtend8:
@@ -267,7 +250,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (sbyte)x);
}
break;
case Instruction.ZeroExtend16:
@@ -279,7 +261,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (ushort)x);
}
break;
case Instruction.ZeroExtend32:
@@ -291,7 +272,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (uint)x);
}
break;
case Instruction.ZeroExtend8:
@@ -303,7 +283,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (byte)x);
}
break;
case Instruction.Subtract:
@@ -315,7 +294,6 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x - y);
}
break;
}
}

View File

@@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
private static bool HasSideEffects(Operation node)
{
return node.Instruction is Instruction.Call
or Instruction.Tailcall
or Instruction.CompareAndSwap
or Instruction.CompareAndSwap16
or Instruction.CompareAndSwap8;
return node.Instruction == Instruction.Call
|| node.Instruction == Instruction.Tailcall
|| node.Instruction == Instruction.CompareAndSwap
|| node.Instruction == Instruction.CompareAndSwap16
|| node.Instruction == Instruction.CompareAndSwap8;
}
private static bool IsPropagableCompare(Operation operation)

View File

@@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// If this is a copy (or copy-like operation), set the copy source interval as well.
// This is used for register preferencing later on, which allows the copy to be eliminated
// in some cases.
if (node.Instruction is Instruction.Copy or Instruction.ZeroExtend32)
if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32)
{
Operand source = node.GetSource(0);
@@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static bool IsLocalOrRegister(OperandKind kind)
{
return kind is OperandKind.LocalVariable or
OperandKind.Register;
return kind == OperandKind.LocalVariable ||
kind == OperandKind.Register;
}
}
}

View File

@@ -1478,7 +1478,7 @@ namespace ARMeilleure.CodeGen.X86
private static bool Is64Bits(OperandType type)
{
return type is OperandType.I64 or OperandType.FP64;
return type == OperandType.I64 || type == OperandType.FP64;
}
private static bool IsImm8(ulong immediate, OperandType type)

View File

@@ -13,6 +13,7 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0;
[Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags
{
None = 0,

View File

@@ -1,6 +1,5 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory;
using System.IO;
using System.Numerics;
@@ -9,7 +8,7 @@ namespace ARMeilleure.CodeGen.X86
{
class CodeGenContext
{
private readonly RecyclableMemoryStream _stream;
private readonly Stream _stream;
private readonly Operand[] _blockLabels;
public int StreamOffset => (int)_stream.Length;

View File

@@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
// The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last;
Debug.Assert(last.Instruction is Instruction.Tailcall or
Instruction.Return);
Debug.Assert(last.Instruction == Instruction.Tailcall ||
last.Instruction == Instruction.Return);
}
else
{
@@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
Debug.Assert(src3.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory);
EnsureSameType(dest, src1, src2, src3);
Debug.Assert(dest.Type == OperandType.V128);
@@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
if (dest.Type == OperandType.FP32)
{
@@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
return;
}
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value);
}

View File

@@ -66,7 +66,6 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
}
break;
case Instruction.ConvertToFPUI:
@@ -82,7 +81,6 @@ namespace ARMeilleure.CodeGen.X86
{
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
}
break;
case Instruction.Negate:
@@ -90,7 +88,6 @@ namespace ARMeilleure.CodeGen.X86
{
GenerateNegate(block.Operations, node);
}
break;
case Instruction.Return:
@@ -102,7 +99,6 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
}
break;
case Instruction.Tailcall:
@@ -114,7 +110,6 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
}
break;
case Instruction.VectorInsert8:
@@ -122,7 +117,6 @@ namespace ARMeilleure.CodeGen.X86
{
GenerateVectorInsert8(block.Operations, node);
}
break;
case Instruction.Extended:
@@ -138,7 +132,6 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources([Const(stackOffset)]);
}
break;
}
}
@@ -319,9 +312,9 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Extended:
{
bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
Intrinsic.X86Blendvps or
Intrinsic.X86Pblendvb;
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.
@@ -520,8 +513,8 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = node.Destination;
Operand source = node.GetSource(0);
Debug.Assert(dest.Type is OperandType.FP32 or
OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Debug.Assert(dest.Type == OperandType.FP32 ||
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Operation currentNode = node;
@@ -768,7 +761,7 @@ namespace ARMeilleure.CodeGen.X86
Comparison compType = (Comparison)comp.AsInt32();
return compType is Comparison.Equal or Comparison.NotEqual;
return compType == Comparison.Equal || compType == Comparison.NotEqual;
}
}

View File

@@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
private static bool IsMemoryLoadOrStore(Instruction inst)
{
return inst is Instruction.Load or
Instruction.Load16 or
Instruction.Load8 or
Instruction.Store or
Instruction.Store16 or
Instruction.Store8;
return inst == Instruction.Load ||
inst == Instruction.Load16 ||
inst == Instruction.Load8 ||
inst == Instruction.Store ||
inst == Instruction.Store16 ||
inst == Instruction.Store8;
}
}
}

View File

@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86
{
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum X86Register
{
Invalid = -1,

View File

@@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
}
// Compare and branch instructions are always conditional.
if (opCode.Instruction.Name is InstName.Cbz or
InstName.Cbnz)
if (opCode.Instruction.Name == InstName.Cbz ||
opCode.Instruction.Name == InstName.Cbnz)
{
return false;
}
@@ -274,10 +274,9 @@ namespace ARMeilleure.Decoders
{
if (opCode is OpCodeT32)
{
return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
not InstName.Cmp and not InstName.Cmn;
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq &&
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn;
}
return true;
}
@@ -285,7 +284,7 @@ namespace ARMeilleure.Decoders
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
// a write back to PC (wback == true && Rn == 15), however the later may
// be "undefined" depending on the CPU, so compilers should not produce that.
if (opCode is IOpCode32Mem or IOpCode32MemMult)
if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult)
{
int rt, rn;
@@ -327,15 +326,15 @@ namespace ARMeilleure.Decoders
}
// Explicit branch instructions.
return opCode is IOpCode32BImm or
IOpCode32BReg;
return opCode is IOpCode32BImm ||
opCode is IOpCode32BReg;
}
private static bool IsCall(OpCode opCode)
{
return opCode.Instruction.Name is InstName.Bl or
InstName.Blr or
InstName.Blx;
return opCode.Instruction.Name == InstName.Bl ||
opCode.Instruction.Name == InstName.Blr ||
opCode.Instruction.Name == InstName.Blx;
}
private static bool IsException(OpCode opCode)
@@ -345,9 +344,9 @@ namespace ARMeilleure.Decoders
private static bool IsTrap(OpCode opCode)
{
return opCode.Instruction.Name is InstName.Brk or
InstName.Trap or
InstName.Und;
return opCode.Instruction.Name == InstName.Brk ||
opCode.Instruction.Name == InstName.Trap ||
opCode.Instruction.Name == InstName.Und;
}
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)

View File

@@ -162,7 +162,6 @@ namespace ARMeilleure.Decoders
}
}
}
return false;
}
}

View File

@@ -20,7 +20,6 @@ namespace ARMeilleure.Decoders
Instruction = InstDescriptor.Undefined;
return;
}
Q = ((opCode >> 21) & 0x1) != 0;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;

View File

@@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
Regs = _regsMap[(opCode >> 8) & 0xf];

View File

@@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
}
}
}

View File

@@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
PostIdx = type == MemOp.PostIndexed;
Unscaled = type is MemOp.Unscaled or
MemOp.Unprivileged;
Unscaled = type == MemOp.Unscaled ||
type == MemOp.Unprivileged;
// Unscaled and Unprivileged doesn't write back,
// but they do use the 9-bits Signed Immediate.

View File

@@ -1381,7 +1381,6 @@ namespace ARMeilleure.Decoders
{
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
}
SetT32(thumbEncoding, name, emitter, makeOpT32);
}
@@ -1410,7 +1409,6 @@ namespace ARMeilleure.Decoders
{
throw new ArgumentException("Invalid ASIMD instruction encoding");
}
SetT32(thumbEncoding, name, emitter, makeOpT32);
}

View File

@@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
{
class IRDumper
{
private const char Indentation = ' ';
private const string Indentation = " ";
private int _indentLevel;
@@ -30,11 +30,14 @@ namespace ARMeilleure.Diagnostics
private void Indent()
{
if (_indentLevel == 0)
return;
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length);
_builder.EnsureCapacity(_builder.Capacity + _indentLevel);
_builder.Append(Indentation, _indentLevel);
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
}
}
private void IncreaseIndentation()
@@ -232,8 +235,8 @@ namespace ARMeilleure.Diagnostics
{
_builder.Append('.').Append(operation.Intrinsic);
}
else if (operation.Instruction is Instruction.BranchIf or
Instruction.Compare)
else if (operation.Instruction == Instruction.BranchIf ||
operation.Instruction == Instruction.Compare)
{
comparison = true;
}
@@ -259,7 +262,6 @@ namespace ARMeilleure.Diagnostics
DumpOperand(source);
}
}
break;
}

View File

@@ -899,7 +899,6 @@ namespace ARMeilleure.Instructions
{
n = context.ShiftLeft(n, Const(shift));
}
break;
case ShiftType.Asr:
if (shift == 32)
@@ -910,7 +909,6 @@ namespace ARMeilleure.Instructions
{
n = context.ShiftRightSI(n, Const(shift));
}
break;
}

View File

@@ -266,7 +266,7 @@ namespace ARMeilleure.Instructions
}
}
private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
private static Exception InvalidOpCodeType(OpCode opCode)
{
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
}
@@ -318,7 +318,6 @@ namespace ARMeilleure.Instructions
{
m = GetRrxC(context, m, setCarry);
}
break;
}
}

View File

@@ -143,12 +143,6 @@ namespace ARMeilleure.Instructions
public static void EmitCall(ArmEmitterContext context, ulong immediate)
{
if (context.IsSingleStep)
{
context.Return(Const(immediate));
return;
}
bool isRecursive = immediate == context.EntryAddress;
if (isRecursive)
@@ -163,24 +157,12 @@ namespace ARMeilleure.Instructions
public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
{
if (context.IsSingleStep)
{
if (target.Type == OperandType.I32)
{
target = context.ZeroExtend32(OperandType.I64, target);
}
context.Return(target);
}
else
{
EmitTableBranch(context, target, isJump: false);
}
EmitTableBranch(context, target, isJump: false);
}
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
{
if (isReturn || context.IsSingleStep)
if (isReturn)
{
if (target.Type == OperandType.I32)
{

View File

@@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
{
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
Debug.Assert(size is >= 0 and < 4);
Debug.Assert(size >= 0 && size < 4);
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
if (castagnoli && Optimizations.UseSse42)

View File

@@ -90,7 +90,6 @@ namespace ARMeilleure.Instructions
{
value = context.ConvertI64ToI32(value);
}
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
context.Copy(reg, value);

View File

@@ -140,7 +140,7 @@ namespace ARMeilleure.Instructions
if (pair)
{
Debug.Assert(op.Size is 2 or 3, "Invalid size for pairwise store.");
Debug.Assert(op.Size == 2 || op.Size == 3, "Invalid size for pairwise store.");
Operand t2 = GetIntOrZR(context, op.Rt2);

View File

@@ -42,7 +42,6 @@ namespace ARMeilleure.Instructions
{
context.Store(exValuePtr, Const(0UL));
}
if (size < 4)
{
context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL));

View File

@@ -59,7 +59,7 @@ namespace ARMeilleure.Instructions
{
Operand value = GetInt(context, rt);
if (ext is Extension.Sx32 or Extension.Sx64)
if (ext == Extension.Sx32 || ext == Extension.Sx64)
{
OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32;
@@ -123,9 +123,9 @@ namespace ARMeilleure.Instructions
private static bool IsSimd(ArmEmitterContext context)
{
return context.CurrOp is IOpCodeSimd and
not (OpCodeSimdMemMs or
OpCodeSimdMemSs);
return context.CurrOp is IOpCodeSimd &&
!(context.CurrOp is OpCodeSimdMemMs ||
context.CurrOp is OpCodeSimdMemSs);
}
public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size)
@@ -717,7 +717,7 @@ namespace ARMeilleure.Instructions
};
}
private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
private static Exception InvalidOpCodeType(OpCode opCode)
{
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
}
@@ -768,7 +768,6 @@ namespace ARMeilleure.Instructions
{
m = InstEmitAluHelper.GetRrxC(context, m, setCarry);
}
break;
}
}

View File

@@ -33,6 +33,7 @@ namespace ARMeilleure.Instructions
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,

View File

@@ -5266,7 +5266,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift)
{
// The upper part of op is assumed to be zero.
Debug.Assert(shift is >= 0 and < 64);
Debug.Assert(shift >= 0 && shift < 64);
if (shift == 0)
{

View File

@@ -231,12 +231,10 @@ namespace ARMeilleure.Instructions
{
result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8);
}
for (int i = 8; i < 16; i++)
{
result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8);
}
return (result2, result);
}
@@ -263,7 +261,6 @@ namespace ARMeilleure.Instructions
nMaskHigh = nMaskLow + 0x0808080808080808L;
mMaskHigh = mMaskLow + 0x0808080808080808L;
}
nMask = X86GetElements(context, nMaskHigh, nMaskLow);
mMask = X86GetElements(context, mMaskHigh, mMaskLow);
Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask);
@@ -288,7 +285,6 @@ namespace ARMeilleure.Instructions
{
extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size);
}
byteOff++;
res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size);
@@ -1308,7 +1304,6 @@ namespace ARMeilleure.Instructions
case 2:
return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6)));
}
break;
case 2:
// Rev32
@@ -1321,7 +1316,6 @@ namespace ARMeilleure.Instructions
mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L);
return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask);
}
break;
case 1:
// Rev16
@@ -1347,7 +1341,6 @@ namespace ARMeilleure.Instructions
case 3:
return context.ByteSwap(op1);
}
break;
case 1:
switch (op.Size)
@@ -1362,7 +1355,6 @@ namespace ARMeilleure.Instructions
context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)),
context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16))));
}
break;
case 2:
// Swap upper and lower halves.

View File

@@ -1119,7 +1119,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed)
{
Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64);
Debug.Assert((uint)size < 2);
OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64;
@@ -1136,7 +1136,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits);
@@ -1160,7 +1160,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits);
@@ -1184,7 +1184,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
if (fBits == 0)
{
@@ -1203,7 +1203,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
if (fBits == 0)
{

View File

@@ -385,7 +385,6 @@ namespace ARMeilleure.Instructions
{
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
}
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
res = context.VectorExtract16(res, 0);
InsertScalar16(context, op.Vd, op.T, res);
@@ -398,7 +397,6 @@ namespace ARMeilleure.Instructions
{
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
}
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
InsertScalar(context, op.Vd, res);
}
@@ -637,7 +635,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed)
{
Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64);
if (signed)
{

View File

@@ -363,7 +363,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
{
Debug.Assert(op.Type is OperandType.I32 or OperandType.I64);
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64);
Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L)));
@@ -489,7 +489,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op)
{
Debug.Assert(op.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(op.Type == OperandType.FP32 || op.Type == OperandType.FP64);
Operand lbl1 = Label();
Operand lbl2 = Label();
@@ -1676,7 +1676,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lbl1 = Label();
Operand lblEnd = Label();
@@ -1709,7 +1709,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lblEnd = Label();
@@ -1735,7 +1735,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst is 8 or 16 or 32);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
Operand lbl1 = Label();
Operand lblEnd = Label();
@@ -1768,7 +1768,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst is 8 or 16 or 32);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
Operand lblEnd = Label();

View File

@@ -31,7 +31,7 @@ namespace ARMeilleure.Instructions
{
Debug.Assert(type != OperandType.V128);
if (type is OperandType.FP64 or OperandType.I64)
if (type == OperandType.FP64 || type == OperandType.I64)
{
// From dreg.
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
@@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(value.Type != OperandType.V128);
Operand vec, insert;
if (value.Type is OperandType.FP64 or OperandType.I64)
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64)
{
// From dreg.
vec = GetVecA32(reg >> 1);
@@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions
public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value)
{
Debug.Assert(value.Type is OperandType.FP32 or OperandType.I32);
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.I32);
Operand vec, insert;
vec = GetVecA32(reg >> 2);
@@ -880,7 +880,6 @@ namespace ARMeilleure.Instructions
{
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
}
res = EmitDoubleWordInsert(context, d, res, op.Vd);
}

View File

@@ -146,7 +146,6 @@ namespace ARMeilleure.Instructions
{
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
}
res = EmitDoubleWordInsert(context, d, res, op.Vd);
}

View File

@@ -268,7 +268,6 @@ namespace ARMeilleure.Instructions
{
m = context.BitwiseNot(m);
}
return context.BitwiseExclusiveOr(
context.BitwiseAnd(m,
context.BitwiseExclusiveOr(d, n)), d);

View File

@@ -110,7 +110,6 @@ namespace ARMeilleure.Instructions
EmitStoreSimd(context, address, d >> 1, index, op.Size);
}
}
offset += eBytes;
d += op.Increment;
}

View File

@@ -1634,7 +1634,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand res = context.AllocateLocal(OperandType.I64);
@@ -1657,7 +1657,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lblEnd = Label();
@@ -1732,7 +1732,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lbl1 = Label();
Operand lblEnd = Label();
@@ -1769,7 +1769,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lbl1 = Label();
Operand lbl2 = Label();
@@ -1813,7 +1813,6 @@ namespace ARMeilleure.Instructions
? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);
@@ -1851,7 +1850,6 @@ namespace ARMeilleure.Instructions
{
context.Copy(res, sar);
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);
@@ -1908,7 +1906,6 @@ namespace ARMeilleure.Instructions
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);

View File

@@ -3,7 +3,6 @@ using ARMeilleure.State;
using ARMeilleure.Translation;
using System;
using System.Runtime.InteropServices;
using ExecutionContext = ARMeilleure.State.ExecutionContext;
namespace ARMeilleure.Instructions
{
@@ -70,13 +69,13 @@ namespace ARMeilleure.Instructions
[UnmanagedCallersOnly]
public static ulong GetCtrEl0()
{
return ExecutionContext.CtrEl0;
return GetContext().CtrEl0;
}
[UnmanagedCallersOnly]
public static ulong GetDczidEl0()
{
return ExecutionContext.DczidEl0;
return GetContext().DczidEl0;
}
[UnmanagedCallersOnly]
@@ -201,11 +200,7 @@ namespace ARMeilleure.Instructions
ExecutionContext context = GetContext();
// If debugging, we'll handle interrupts outside
if (!Optimizations.EnableDebugging)
{
context.CheckInterrupt();
}
context.CheckInterrupt();
Statistics.ResumeTimer();

View File

@@ -24,7 +24,7 @@ namespace ARMeilleure.Instructions
{
uint src = (uint)idx + 256u;
Debug.Assert(src is >= 256u and < 512u);
Debug.Assert(256u <= src && src < 512u);
src = (src << 1) + 1u;
@@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1;
Debug.Assert(dst is >= 256u and < 512u);
Debug.Assert(256u <= dst && dst < 512u);
tbl[idx] = (byte)(dst - 256u);
}
@@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
{
uint src = (uint)idx + 128u;
Debug.Assert(src is >= 128u and < 512u);
Debug.Assert(128u <= src && src < 512u);
if (src < 256u)
{
@@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1;
Debug.Assert(dst is >= 256u and < 512u);
Debug.Assert(256u <= dst && dst < 512u);
tbl[idx] = (byte)(dst - 256u);
}
@@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions
float result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
if ((context.Fpcr & FPCR.Dn) != 0)
{
@@ -498,7 +498,7 @@ namespace ARMeilleure.Instructions
double result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
if ((context.Fpcr & FPCR.Dn) != 0)
{
@@ -676,7 +676,7 @@ namespace ARMeilleure.Instructions
ushort resultBits;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
if (altHp)
{
@@ -1086,7 +1086,7 @@ namespace ARMeilleure.Instructions
{
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
@@ -1522,7 +1522,7 @@ namespace ARMeilleure.Instructions
float result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -1689,7 +1689,7 @@ namespace ARMeilleure.Instructions
float result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -1726,7 +1726,7 @@ namespace ARMeilleure.Instructions
float result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -1920,7 +1920,7 @@ namespace ARMeilleure.Instructions
float result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -2211,7 +2211,7 @@ namespace ARMeilleure.Instructions
ushort resultBits;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
if (altHp)
{
@@ -3057,7 +3057,7 @@ namespace ARMeilleure.Instructions
double result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -3224,7 +3224,7 @@ namespace ARMeilleure.Instructions
double result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -3261,7 +3261,7 @@ namespace ARMeilleure.Instructions
double result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@@ -3455,7 +3455,7 @@ namespace ARMeilleure.Instructions
double result;
if (type is FPType.SNaN or FPType.QNaN)
if (type == FPType.SNaN || type == FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}

View File

@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.IntermediateRepresentation
{
[Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum Intrinsic : ushort
{
// X86 (SSE and AVX)

View File

@@ -446,7 +446,7 @@ namespace ARMeilleure.IntermediateRepresentation
Data* data = null;
// If constant or register, then try to look up in the intern table before allocating.
if (kind is OperandKind.Constant or OperandKind.Register)
if (kind == OperandKind.Constant || kind == OperandKind.Register)
{
uint hash = (uint)HashCode.Combine(kind, type, value);

View File

@@ -16,8 +16,8 @@ namespace ARMeilleure.IntermediateRepresentation
{
public static bool IsInteger(this OperandType type)
{
return type is OperandType.I32 or
OperandType.I64;
return type == OperandType.I32 ||
type == OperandType.I64;
}
public static RegisterType ToRegisterType(this OperandType type)

View File

@@ -47,12 +47,12 @@ namespace ARMeilleure.Memory
{
public static bool IsHostMapped(this MemoryManagerType type)
{
return type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
return type == MemoryManagerType.HostMapped || type == MemoryManagerType.HostMappedUnsafe;
}
public static bool IsHostTracked(this MemoryManagerType type)
{
return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
return type == MemoryManagerType.HostTracked || type == MemoryManagerType.HostTrackedUnsafe;
}
public static bool IsHostMappedOrTracked(this MemoryManagerType type)

View File

@@ -12,7 +12,6 @@ namespace ARMeilleure
public static bool AllowLcqInFunctionTable { get; set; } = true;
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
public static bool EnableDebugging { get; set; } = false;
public static bool UseAdvSimdIfAvailable { get; set; } = true;
public static bool UseArm64AesIfAvailable { get; set; } = true;

View File

@@ -1,5 +1,4 @@
using ARMeilleure.Memory;
using System.Threading;
namespace ARMeilleure.State
{
@@ -11,14 +10,16 @@ namespace ARMeilleure.State
internal nint NativeContextPtr => _nativeContext.BasePtr;
internal bool Interrupted { get; private set; }
private bool _interrupted;
private readonly ICounter _counter;
public ulong Pc => _nativeContext.GetPc();
public static uint CtrEl0 => 0x8444c004;
public static uint DczidEl0 => 0x00000004;
#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;
@@ -66,8 +67,6 @@ namespace ARMeilleure.State
public bool IsAarch32 { get; set; }
public ulong ThreadUid { get; set; }
internal ExecutionMode ExecutionMode
{
get
@@ -93,19 +92,14 @@ namespace ARMeilleure.State
private readonly ExceptionCallbackNoArgs _interruptCallback;
private readonly ExceptionCallback _breakCallback;
private readonly ExceptionCallbackNoArgs _stepCallback;
private readonly ExceptionCallback _supervisorCallback;
private readonly ExceptionCallback _undefinedCallback;
internal int ShouldStep;
public ulong DebugPc { get; set; }
public ExecutionContext(
IJitMemoryAllocator allocator,
ICounter counter,
ExceptionCallbackNoArgs interruptCallback = null,
ExceptionCallback breakCallback = null,
ExceptionCallbackNoArgs stepCallback = null,
ExceptionCallback supervisorCallback = null,
ExceptionCallback undefinedCallback = null)
{
@@ -113,7 +107,6 @@ namespace ARMeilleure.State
_counter = counter;
_interruptCallback = interruptCallback;
_breakCallback = breakCallback;
_stepCallback = stepCallback;
_supervisorCallback = supervisorCallback;
_undefinedCallback = undefinedCallback;
@@ -136,9 +129,9 @@ namespace ARMeilleure.State
internal void CheckInterrupt()
{
if (Interrupted)
if (_interrupted)
{
Interrupted = false;
_interrupted = false;
_interruptCallback?.Invoke(this);
}
@@ -148,37 +141,16 @@ namespace ARMeilleure.State
public void RequestInterrupt()
{
Interrupted = true;
}
public void StepHandler()
{
_stepCallback?.Invoke(this);
}
public void RequestDebugStep()
{
Interlocked.Exchange(ref ShouldStep, 1);
RequestInterrupt();
_interrupted = true;
}
internal void OnBreak(ulong address, int imm)
{
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_breakCallback?.Invoke(this, address, imm);
}
internal void OnSupervisorCall(ulong address, int imm)
{
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_supervisorCallback?.Invoke(this, address, imm);
}

View File

@@ -22,12 +22,6 @@ namespace ARMeilleure.State
public ulong ExclusiveValueHigh;
public int Running;
public long Tpidr2El0;
/// <summary>
/// Precise PC value used for debugging.
/// This will only be set when Optimizations.EnableDebugging is true.
/// </summary>
public ulong DebugPrecisePc;
}
private static NativeCtxStorage _dummyStorage = new();
@@ -45,11 +39,6 @@ namespace ARMeilleure.State
public ulong GetPc()
{
if (Optimizations.EnableDebugging)
{
return GetStorage().DebugPrecisePc;
}
// TODO: More precise tracking of PC value.
return GetStorage().DispatchAddress;
}
@@ -122,7 +111,6 @@ namespace ARMeilleure.State
{
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
}
return value;
}
@@ -167,7 +155,6 @@ namespace ARMeilleure.State
value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
}
}
return value;
}
@@ -279,11 +266,6 @@ namespace ARMeilleure.State
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
}
public static int GetDebugPrecisePcOffset()
{
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
}
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
{
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);

View File

@@ -52,7 +52,6 @@ namespace ARMeilleure.Translation
public bool HighCq { get; }
public bool HasPtc { get; }
public Aarch32Mode Mode { get; }
public bool IsSingleStep { get; }
private int _ifThenBlockStateIndex = 0;
private Condition[] _ifThenBlockState = [];
@@ -67,8 +66,7 @@ namespace ARMeilleure.Translation
ulong entryAddress,
bool highCq,
bool hasPtc,
Aarch32Mode mode,
bool isSingleStep)
Aarch32Mode mode)
{
Memory = memory;
CountTable = countTable;
@@ -78,7 +76,6 @@ namespace ARMeilleure.Translation
HighCq = highCq;
HasPtc = hasPtc;
Mode = mode;
IsSingleStep = isSingleStep;
_labels = new Dictionary<ulong, Operand>();
}

View File

@@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
private static JitCacheInvalidation _jitCacheInvalidator;
private static readonly List<CacheMemoryAllocator> _cacheAllocators = [];
private static List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheEntry> _cacheEntries = [];
@@ -205,6 +205,7 @@ namespace ARMeilleure.Translation.Cache
return allocOffsetNew;
}
private static int AlignCodeSize(int codeSize)
{
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);

View File

@@ -32,7 +32,7 @@ namespace ARMeilleure.Translation
return _delegates.Values[index].FuncPtr; // O(1).
}
public static int GetDelegateIndex(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
@@ -48,7 +48,7 @@ namespace ARMeilleure.Translation
return index;
}
private static void SetDelegateInfo(MethodInfo method)
{
string key = GetKey(method);

View File

@@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
{
continue;
}
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
{
BasicBlock current = block.Predecessors[pBlkIndex];

View File

@@ -124,7 +124,7 @@ namespace ARMeilleure.Translation
/// </summary>
/// <param name="node">The node to search for values within</param>
/// <param name="list">The list to add values to</param>
private static void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
private void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
{
if (node == null)
{
@@ -165,7 +165,6 @@ namespace ARMeilleure.Translation
return node;
}
}
return null;
}
@@ -176,7 +175,7 @@ namespace ARMeilleure.Translation
/// <param name="end">End of the range</param>
/// <param name="overlaps">Overlaps array to place results in</param>
/// <param name="overlapCount">Overlaps count to update</param>
private static void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
private void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
{
if (node == null || start.CompareTo(node.Max) >= 0)
{
@@ -312,7 +311,6 @@ namespace ARMeilleure.Translation
return false;
}
}
IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent);
if (newNode.Parent == null)
{
@@ -424,14 +422,12 @@ namespace ARMeilleure.Translation
{
return Maximum(node.Left);
}
IntervalTreeNode<TK, TV> parent = node.Parent;
while (parent != null && node == parent.Left)
{
node = parent;
parent = parent.Parent;
}
return parent;
}
@@ -456,7 +452,6 @@ namespace ARMeilleure.Translation
RotateLeft(ParentOf(ptr));
sibling = RightOf(ParentOf(ptr));
}
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
{
SetColor(sibling, Red);
@@ -471,7 +466,6 @@ namespace ARMeilleure.Translation
RotateRight(sibling);
sibling = RightOf(ParentOf(ptr));
}
SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black);
SetColor(RightOf(sibling), Black);
@@ -490,7 +484,6 @@ namespace ARMeilleure.Translation
RotateRight(ParentOf(ptr));
sibling = LeftOf(ParentOf(ptr));
}
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
{
SetColor(sibling, Red);
@@ -505,7 +498,6 @@ namespace ARMeilleure.Translation
RotateLeft(sibling);
sibling = LeftOf(ParentOf(ptr));
}
SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black);
SetColor(LeftOf(sibling), Black);
@@ -514,7 +506,6 @@ namespace ARMeilleure.Translation
}
}
}
SetColor(ptr, Black);
}
@@ -541,7 +532,6 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode);
RotateLeft(balanceNode);
}
SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateRight(ParentOf(ParentOf(balanceNode)));
@@ -565,14 +555,12 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode);
RotateRight(balanceNode);
}
SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateLeft(ParentOf(ParentOf(balanceNode)));
}
}
}
SetColor(_root, Black);
}
@@ -586,7 +574,6 @@ namespace ARMeilleure.Translation
{
node.Right.Parent = node;
}
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
right.Parent = nodeParent;
if (nodeParent == null)
@@ -601,7 +588,6 @@ namespace ARMeilleure.Translation
{
nodeParent.Right = right;
}
right.Left = node;
node.Parent = right;
@@ -619,7 +605,6 @@ namespace ARMeilleure.Translation
{
node.Left.Parent = node;
}
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
left.Parent = nodeParent;
if (nodeParent == null)
@@ -634,7 +619,6 @@ namespace ARMeilleure.Translation
{
nodeParent.Left = left;
}
left.Right = node;
node.Parent = left;

View File

@@ -33,7 +33,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 7009; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 7007; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";
@@ -193,7 +193,7 @@ namespace ARMeilleure.Translation.PTC
_infosStream.Seek(0L, SeekOrigin.Begin);
bool foundBadFunction = false;
for (int index = 0; index < _infosStream.Length / Unsafe.SizeOf<InfoEntry>(); index++)
for (int index = 0; index < GetEntriesCount(); index++)
{
InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream);
foreach (ulong address in blacklist)
@@ -303,13 +303,6 @@ namespace ARMeilleure.Translation.PTC
return false;
}
if (outerHeader.DebuggerMode != Optimizations.EnableDebugging)
{
InvalidateCompressedStream(compressedStream);
return false;
}
nint intPtr = nint.Zero;
try
@@ -486,7 +479,6 @@ namespace ARMeilleure.Translation.PTC
MemoryManagerMode = GetMemoryManagerMode(),
OSPlatform = GetOSPlatform(),
Architecture = (uint)RuntimeInformation.ProcessArchitecture,
DebuggerMode = Optimizations.EnableDebugging,
UncompressedStreamSize =
(long)Unsafe.SizeOf<InnerHeader>() +
@@ -574,7 +566,6 @@ namespace ARMeilleure.Translation.PTC
{
if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
{
ResetCarriersIfNeeded();
return;
}
@@ -843,6 +834,8 @@ namespace ARMeilleure.Translation.PTC
return;
}
int degreeOfParallelism = Environment.ProcessorCount;
if (Optimizations.LowPower)
@@ -879,7 +872,7 @@ namespace ARMeilleure.Translation.PTC
Debug.Assert(Profiler.IsAddressInStaticCodeRange(address));
TranslatedFunction func = translator.Translate(address, executionMode, highCq, pptcTranslation: true);
TranslatedFunction func = translator.Translate(address, executionMode, highCq);
if (func == null)
{
@@ -902,12 +895,13 @@ namespace ARMeilleure.Translation.PTC
}
}
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
.Select(idx =>
.Select(idx =>
new Thread(TranslateFuncs)
{
IsBackground = true,
Name = "Ptc.TranslateThread." + idx
IsBackground = true,
Name = "Ptc.TranslateThread." + idx
}
).ToList();
@@ -917,7 +911,6 @@ namespace ARMeilleure.Translation.PTC
{
thread.Start();
}
foreach (Thread thread in threads)
{
thread.Join();
@@ -931,8 +924,8 @@ namespace ARMeilleure.Translation.PTC
sw.Stop();
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
Logger.Info?.Print(LogClass.Ptc,
Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}");
@@ -1076,7 +1069,7 @@ namespace ARMeilleure.Translation.PTC
return osPlatform;
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 87*/)]
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 86*/)]
private struct OuterHeader
{
public ulong Magic;
@@ -1088,7 +1081,6 @@ namespace ARMeilleure.Translation.PTC
public byte MemoryManagerMode;
public uint OSPlatform;
public uint Architecture;
public bool DebuggerMode;
public long UncompressedStreamSize;
@@ -1171,8 +1163,8 @@ namespace ARMeilleure.Translation.PTC
public void Close()
{
if (State is PtcState.Enabled or
PtcState.Continuing)
if (State == PtcState.Enabled ||
State == PtcState.Continuing)
{
State = PtcState.Closing;
}

View File

@@ -1,6 +1,5 @@
using ARMeilleure.State;
using Humanizer;
using Microsoft.IO;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
@@ -27,7 +26,7 @@ namespace ARMeilleure.Translation.PTC
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions =
private static readonly uint[] _migrateInternalVersions =
[
1866,
5518,
@@ -76,7 +75,7 @@ namespace ARMeilleure.Translation.PTC
Enabled = false;
}
private void TimerElapsed(object _, ElapsedEventArgs __)
private void TimerElapsed(object _, ElapsedEventArgs __)
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
@@ -152,7 +151,7 @@ namespace ARMeilleure.Translation.PTC
if (!funcProfile.Blacklist)
continue;
if (!funcs.Contains(ptr))
if (!funcs.Contains(ptr))
funcs.Add(ptr);
}
@@ -220,7 +219,7 @@ namespace ARMeilleure.Translation.PTC
return false;
}
using RecyclableMemoryStream stream = MemoryStreamManager.Shared.GetStream();
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L);
try
@@ -294,10 +293,10 @@ namespace ARMeilleure.Translation.PTC
{
if (migrateEntryFunc != null)
{
return DeserializeAndUpdateDictionary(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
}
return DeserializeDictionary<ulong, FuncProfile>(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
}
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
@@ -468,8 +467,8 @@ namespace ARMeilleure.Translation.PTC
public void Start()
{
if (_ptc.State is PtcState.Enabled or
PtcState.Continuing)
if (_ptc.State == PtcState.Enabled ||
_ptc.State == PtcState.Continuing)
{
Enabled = true;

View File

@@ -119,25 +119,7 @@ namespace ARMeilleure.Translation
NativeInterface.RegisterThread(context, Memory, this);
if (Optimizations.EnableDebugging)
{
context.DebugPc = address;
do
{
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
{
context.DebugPc = Step(context, context.DebugPc);
context.StepHandler();
}
else
{
context.DebugPc = ExecuteSingle(context, context.DebugPc);
}
context.CheckInterrupt();
}
while (context.Running && context.DebugPc != 0);
}
else if (Optimizations.UseUnmanagedDispatchLoop)
if (Optimizations.UseUnmanagedDispatchLoop)
{
Stubs.DispatchLoop(context.NativeContextPtr, address);
}
@@ -193,7 +175,7 @@ namespace ARMeilleure.Translation
return nextAddr;
}
private ulong Step(State.ExecutionContext context, ulong address)
public ulong Step(State.ExecutionContext context, ulong address)
{
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
@@ -204,8 +186,6 @@ namespace ARMeilleure.Translation
return address;
}
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
{
if (!Functions.TryGetValue(address, out TranslatedFunction func))
@@ -239,7 +219,7 @@ namespace ARMeilleure.Translation
}
}
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false, bool pptcTranslation = false)
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
{
ArmEmitterContext context = new(
Memory,
@@ -249,8 +229,7 @@ namespace ARMeilleure.Translation
address,
highCq,
_ptc.State != PtcState.Disabled,
mode: Aarch32Mode.User,
isSingleStep: singleStep);
mode: Aarch32Mode.User);
Logger.StartPass(PassName.Decoding);
@@ -267,7 +246,7 @@ namespace ARMeilleure.Translation
context.Branch(context.GetLabel(address));
}
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter, pptcTranslation);
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter);
if (cfg == null)
{
@@ -347,8 +326,7 @@ namespace ARMeilleure.Translation
ArmEmitterContext context,
Block[] blocks,
out Range range,
out Counter<uint> counter,
bool pptcTranslation)
out Counter<uint> counter)
{
counter = null;
@@ -388,13 +366,9 @@ namespace ARMeilleure.Translation
if (block.Exit)
{
// Return to managed rather than tail call.
bool useReturns = Optimizations.EnableDebugging;
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, block.Address);
}
// Left option here as it may be useful if we need to return to managed rather than tail call in
// future. (eg. for debug)
bool useReturns = false;
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
}
@@ -418,11 +392,6 @@ namespace ARMeilleure.Translation
}
}
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, opCode.Address);
}
Operand lblPredicateSkip = default;
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
@@ -442,10 +411,7 @@ namespace ARMeilleure.Translation
if (opCode.Instruction.Emitter != null)
{
opCode.Instruction.Emitter(context);
// if we're pre-compiling PPTC functions, and we hit an Undefined instruction as the first
// instruction in the block, mark the function as blacklisted
// this way, we don't pre-compile Exlaunch hooks, which allows ExeFS mods to run with PPTC
if (pptcTranslation && opCode.Instruction.Name == InstName.Und && blkIndex == 0)
if (opCode.Instruction.Name == InstName.Und && blkIndex == 0)
{
range = new Range(rangeStart, rangeEnd);
return null;
@@ -519,14 +485,6 @@ namespace ARMeilleure.Translation
context.MarkLabel(lblExit);
}
internal static void EmitDebugPrecisePcUpdate(EmitterContext context, ulong address)
{
long debugPrecisePcOffs = NativeContext.GetDebugPrecisePcOffset();
Operand debugPrecisePcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(debugPrecisePcOffs));
context.Store(debugPrecisePcAddr, Const(address));
}
public void InvalidateJitCacheRegion(ulong address, ulong size)
{
ulong[] overlapAddresses = [];

View File

@@ -178,7 +178,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
public bool SupportsChannelCount(uint channelCount)
{
return channelCount is 1 or 2 or 6;
return channelCount == 1 || channelCount == 2 || channelCount == 6;
}
public bool SupportsDirection(Direction direction)

View File

@@ -24,8 +24,10 @@ namespace Ryujinx.Audio.Backends.SDL2
// 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(nint name, out SDL_AudioSpec spec, int isCapture);
#pragma warning restore SYSLIB1054
public SDL2HardwareDeviceDriver()
{

View File

@@ -162,7 +162,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsChannelCount(uint channelCount)
{
return channelCount is 1 or 2 or 6;
return channelCount == 1 || channelCount == 2 || channelCount == 6;
}
public bool SupportsSampleFormat(SampleFormat sampleFormat)
@@ -184,7 +184,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsDirection(Direction direction)
{
return direction is Direction.Input or Direction.Output;
return direction == Direction.Input || direction == Direction.Output;
}
}
}

View File

@@ -73,12 +73,12 @@ namespace Ryujinx.Audio.Backends.Dummy
public bool SupportsDirection(Direction direction)
{
return direction is Direction.Output or Direction.Input;
return direction == Direction.Output || direction == Direction.Input;
}
public bool SupportsChannelCount(uint channelCount)
{
return channelCount is 1 or 2 or 6;
return channelCount == 1 || channelCount == 2 || channelCount == 6;
}
}
}

View File

@@ -109,7 +109,7 @@ namespace Ryujinx.Audio.Common
/// <returns>The state of the session</returns>
public AudioDeviceState GetState()
{
Debug.Assert(_state is AudioDeviceState.Started or AudioDeviceState.Stopped);
Debug.Assert(_state == AudioDeviceState.Started || _state == AudioDeviceState.Stopped);
return _state;
}

View File

@@ -166,7 +166,7 @@ namespace Ryujinx.Audio.Input
/// </summary>
/// <param name="filtered">If true, filter disconnected devices</param>
/// <returns>The list of all audio inputs name</returns>
public static string[] ListAudioIns(bool filtered)
public string[] ListAudioIns(bool filtered)
{
if (filtered)
{

View File

@@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Input
return ResultCode.DeviceNotFound;
}
if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate)
{
return ResultCode.UnsupportedSampleRate;
}
if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6)
{
return ResultCode.UnsupportedChannelConfiguration;
}

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.Audio.Integration
{
uint channelCount = GetChannelCount();
Debug.Assert(channelCount is > 0 and <= Constants.ChannelCountMax);
Debug.Assert(channelCount > 0 && channelCount <= Constants.ChannelCountMax);
return channelCount != Constants.ChannelCountMax;
}

View File

@@ -165,7 +165,7 @@ namespace Ryujinx.Audio.Output
/// Get the list of all audio outputs name.
/// </summary>
/// <returns>The list of all audio outputs name</returns>
public static string[] ListAudioOuts()
public string[] ListAudioOuts()
{
return [Constants.DefaultDeviceOutputName];
}

View File

@@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Output
return ResultCode.DeviceNotFound;
}
if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate)
{
return ResultCode.UnsupportedSampleRate;
}
if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6)
{
return ResultCode.UnsupportedChannelConfiguration;
}

View File

@@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// <param name="volume">The new master volume.</param>
public void UpdateMasterVolume(float volume)
{
Debug.Assert(volume is >= 0.0f and <= 1.0f);
Debug.Assert(volume >= 0.0f && volume <= 1.0f);
MasterVolume = volume;
}

View File

@@ -17,7 +17,9 @@ namespace Ryujinx.Audio.Renderer.Device
/// The default <see cref="VirtualDevice"/>.
/// </summary>
/// <remarks>This is used when the USB device is the default one on older revision.</remarks>
public static VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
#pragma warning disable CA1822 // Mark member as static
public VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
#pragma warning restore CA1822
/// <summary>
/// The current active <see cref="VirtualDevice"/>.

View File

@@ -26,15 +26,12 @@ namespace Ryujinx.Audio.Renderer.Dsp
ReadOnlySpan<float> inputBuffer,
uint sampleCount)
{
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -67,15 +64,12 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -113,15 +107,12 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
float mixState = 0f;
@@ -166,16 +157,13 @@ namespace Ryujinx.Audio.Renderer.Dsp
BiquadFilterParameter parameter = parameters[stageIndex];
ref BiquadFilterState state = ref states[stageIndex];
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -213,25 +201,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
Span<short> numerator0Span = parameter0.Numerator.AsSpan();
Span<short> numerator1Span = parameter1.Numerator.AsSpan();
Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -279,24 +261,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
Span<short> numerator0Span = parameter0.Numerator.AsSpan();
Span<short> numerator1Span = parameter1.Numerator.AsSpan();
Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
float mixState = 0f;

View File

@@ -39,14 +39,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = outputBufferIndex;
SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}

View File

@@ -1,6 +1,5 @@
using Ryujinx.Audio.Renderer.Parameter.Sink;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System;
using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -29,12 +28,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Input = new ushort[Constants.ChannelCountMax];
InputCount = parameter.InputCount;
Span<byte> inputSpan = parameter.Input.AsSpan();
for (int i = 0; i < InputCount; i++)
{
Input[i] = (ushort)(bufferOffset + inputSpan[i]);
Input[i] = (ushort)(bufferOffset + parameter.Input[i]);
}
CircularBuffer = circularBufferAddressInfo.GetReference(true);

View File

@@ -42,14 +42,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
}
}
@@ -174,12 +171,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain);
statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean);
Span<float> lastSamplesSpan = statistics.LastSamples.AsSpan();
for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++)
{
lastSamplesSpan[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
statistics.LastSamples[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
}
}
}

View File

@@ -52,14 +52,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(2);
}

View File

@@ -42,14 +42,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = Parameter.Input.AsSpan();
Span<byte> outputSpan = Parameter.Output.AsSpan();
for (int i = 0; i < Parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
}
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
@@ -132,6 +129,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain,
0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain);
for (int i = 0; i < sampleCount; i++)
{
Vector4 channelInput = new()

View File

@@ -42,15 +42,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
ref VoiceUpdateState state = ref State.Span[0];
Span<float> depopBuffer = DepopBuffer.Span;
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
for (int i = 0; i < MixBufferCount; i++)
{
if (lastSamplesSpan[i] != 0)
if (state.LastSamples[i] != 0)
{
depopBuffer[OutputBufferIndices[i]] += lastSamplesSpan[i];
depopBuffer[OutputBufferIndices[i]] += state.LastSamples[i];
lastSamplesSpan[i] = 0;
state.LastSamples[i] = 0;
}
}
}

Some files were not shown because too many files have changed in this diff Show More