Merge branch 'Ryubing:master' into master
This commit is contained in:
commit
007d3bc045
77
.github/workflows/canary.yml
vendored
77
.github/workflows/canary.yml
vendored
@ -108,6 +108,7 @@ jobs:
|
|||||||
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_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_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 '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
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Create output dir
|
- name: Create output dir
|
||||||
@ -115,71 +116,69 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
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
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_ava
|
pushd publish
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_ava
|
pushd publish
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
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
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
#- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
# if: matrix.platform.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
# run: |
|
run: |
|
||||||
# BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
# PLATFORM_NAME="${{ matrix.platform.name }}"
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
|
||||||
# sudo apt install -y zsync desktop-file-utils appstream
|
sudo apt install -y zsync desktop-file-utils appstream
|
||||||
|
|
||||||
# mkdir -p tools
|
mkdir -p tools
|
||||||
# export PATH="$PATH:$(readlink -f tools)"
|
export PATH="$PATH:$(readlink -f tools)"
|
||||||
|
|
||||||
# Setup appimagetool
|
# Setup appimagetool
|
||||||
# wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
# chmod +x tools/appimagetool
|
chmod +x tools/appimagetool
|
||||||
# chmod +x distribution/linux/appimage/build-appimage.sh
|
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
# if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
# ARCH_NAME=x64
|
ARCH_NAME=x64
|
||||||
# export ARCH=x86_64
|
export ARCH=x86_64
|
||||||
# elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
# ARCH_NAME=arm64
|
ARCH_NAME=arm64
|
||||||
# export ARCH=aarch64
|
export ARCH=aarch64
|
||||||
# else
|
else
|
||||||
# echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
# exit 1
|
exit 1
|
||||||
# fi
|
fi
|
||||||
|
|
||||||
# export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|Canary-Releases|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
# BUILDDIR=publish_ava OUTDIR=publish_ava_appimage distribution/linux/appimage/build-appimage.sh
|
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
# Add to release output
|
pushd publish_appimage
|
||||||
# pushd publish_ava_appimage
|
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
# mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
# mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
popd
|
||||||
# popd
|
shell: bash
|
||||||
# shell: bash
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||||
#artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: |
|
body: |
|
||||||
# Canary builds:
|
# Canary builds:
|
||||||
|
2
.github/workflows/nightly_pr_comment.yml
vendored
2
.github/workflows/nightly_pr_comment.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
|||||||
let body = `Download the artifacts for this pull request:\n`;
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||||
for (const art of artifacts) {
|
for (const art of artifacts) {
|
||||||
const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`;
|
const url = `https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip`;
|
||||||
if (art.name.includes('Debug')) {
|
if (art.name.includes('Debug')) {
|
||||||
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||||
} else {
|
} else {
|
||||||
|
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@ -122,6 +122,15 @@ jobs:
|
|||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
- name: Packing Linux builds
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
pushd publish
|
||||||
|
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
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
@ -159,15 +168,6 @@ jobs:
|
|||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Packing Linux builds
|
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
|
||||||
run: |
|
|
||||||
pushd publish
|
|
||||||
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
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||||
<PackageVersion Include="Concentus" Version="2.2.0" />
|
<PackageVersion Include="Concentus" Version="2.2.0" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||||
@ -41,8 +42,9 @@
|
|||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Gommon" Version="2.6.8" />
|
<PackageVersion Include="Gommon" Version="2.7.0.1" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
|
@ -249,13 +249,12 @@ Global
|
|||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -6,14 +6,14 @@ cd "$ROOTDIR"
|
|||||||
|
|
||||||
BUILDDIR=${BUILDDIR:-publish}
|
BUILDDIR=${BUILDDIR:-publish}
|
||||||
OUTDIR=${OUTDIR:-publish_appimage}
|
OUTDIR=${OUTDIR:-publish_appimage}
|
||||||
UFLAG=${UFLAG:-"gh-releases-zsync|GreemDev|ryujinx|latest|*-x64.AppImage.zsync"}
|
UFLAG=${UFLAG:-"gh-releases-zsync|Ryubing|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||||
|
|
||||||
rm -rf AppDir
|
rm -rf AppDir
|
||||||
mkdir -p AppDir/usr/bin
|
mkdir -p AppDir/usr/bin
|
||||||
|
|
||||||
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||||
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||||
cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
|
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
||||||
|
|
||||||
|
|
||||||
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||||
|
3433
docs/compatibility.csv
Normal file
3433
docs/compatibility.csv
Normal file
File diff suppressed because it is too large
Load Diff
@ -406,7 +406,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
||||||
|
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Abs), res);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,7 +451,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
||||||
|
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Abs), res);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,7 +483,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitScalarUnaryOpF(context, (op1) =>
|
EmitScalarUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Abs), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,7 +522,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitVectorUnaryOpF(context, (op1) =>
|
EmitVectorUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Abs), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2246,7 +2246,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitScalarUnaryOpF(context, (op1) =>
|
EmitScalarUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Floor), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2265,7 +2265,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitVectorUnaryOpF(context, (op1) =>
|
EmitVectorUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Floor), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2322,7 +2322,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitScalarUnaryOpF(context, (op1) =>
|
EmitScalarUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2341,7 +2341,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitVectorUnaryOpF(context, (op1) =>
|
EmitVectorUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2390,7 +2390,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitScalarUnaryOpF(context, (op1) =>
|
EmitScalarUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2409,7 +2409,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
EmitVectorUnaryOpF(context, (op1) =>
|
EmitVectorUnaryOpF(context, (op1) =>
|
||||||
{
|
{
|
||||||
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1);
|
return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1));
|
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1));
|
EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -726,8 +726,8 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (absolute)
|
if (absolute)
|
||||||
{
|
{
|
||||||
ne = EmitUnaryMathCall(context, nameof(Math.Abs), ne);
|
ne = EmitUnaryMathCall(context, nameof(MathHelper.Abs), ne);
|
||||||
me = EmitUnaryMathCall(context, nameof(Math.Abs), me);
|
me = EmitUnaryMathCall(context, nameof(MathHelper.Abs), me);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand e = EmitSoftFloatCall(context, name, ne, me);
|
Operand e = EmitSoftFloatCall(context, name, ne, me);
|
||||||
|
@ -333,7 +333,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +349,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1), signed: true, scalar: false);
|
EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1), signed: true, scalar: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,7 +538,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +554,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,10 +357,10 @@ namespace ARMeilleure.Instructions
|
|||||||
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
||||||
break;
|
break;
|
||||||
case 0b10: // Towards positive infinity
|
case 0b10: // Towards positive infinity
|
||||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert);
|
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
|
||||||
break;
|
break;
|
||||||
case 0b11: // Towards negative infinity
|
case 0b11: // Towards negative infinity
|
||||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert);
|
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,10 +494,10 @@ namespace ARMeilleure.Instructions
|
|||||||
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
||||||
break;
|
break;
|
||||||
case 0b10: // Towards positive infinity
|
case 0b10: // Towards positive infinity
|
||||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert);
|
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
|
||||||
break;
|
break;
|
||||||
case 0b11: // Towards negative infinity
|
case 0b11: // Towards negative infinity
|
||||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert);
|
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +534,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Floor), m));
|
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), m));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +574,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Ceiling), m));
|
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), m));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +613,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Truncate), op1));
|
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,8 +460,8 @@ namespace ARMeilleure.Instructions
|
|||||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||||
|
|
||||||
MethodInfo info = (op.Size & 1) == 0
|
MethodInfo info = (op.Size & 1) == 0
|
||||||
? typeof(MathF).GetMethod(name, new Type[] { typeof(float) })
|
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float) })
|
||||||
: typeof(Math).GetMethod(name, new Type[] { typeof(double) });
|
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double) });
|
||||||
|
|
||||||
return context.Call(info, n);
|
return context.Call(info, n);
|
||||||
}
|
}
|
||||||
@ -470,11 +470,11 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||||
|
|
||||||
string name = nameof(Math.Round);
|
string name = nameof(MathHelper.Round);
|
||||||
|
|
||||||
MethodInfo info = (op.Size & 1) == 0
|
MethodInfo info = (op.Size & 1) == 0
|
||||||
? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) })
|
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float), typeof(int) })
|
||||||
: typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) });
|
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double), typeof(int) });
|
||||||
|
|
||||||
return context.Call(info, n, Const((int)roundMode));
|
return context.Call(info, n, Const((int)roundMode));
|
||||||
}
|
}
|
||||||
@ -510,16 +510,16 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.MarkLabel(lbl1);
|
context.MarkLabel(lbl1);
|
||||||
context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual);
|
context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual);
|
||||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Ceiling), op));
|
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl2);
|
context.MarkLabel(lbl2);
|
||||||
context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual);
|
context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual);
|
||||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Floor), op));
|
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Floor), op));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl3);
|
context.MarkLabel(lbl3);
|
||||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Truncate), op));
|
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lblEnd);
|
context.MarkLabel(lblEnd);
|
||||||
|
71
src/ARMeilleure/Instructions/MathHelper.cs
Normal file
71
src/ARMeilleure/Instructions/MathHelper.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class MathHelper
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double Abs(double value)
|
||||||
|
{
|
||||||
|
return Math.Abs(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double Ceiling(double value)
|
||||||
|
{
|
||||||
|
return Math.Ceiling(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double Floor(double value)
|
||||||
|
{
|
||||||
|
return Math.Floor(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double Round(double value, int mode)
|
||||||
|
{
|
||||||
|
return Math.Round(value, (MidpointRounding)mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double Truncate(double value)
|
||||||
|
{
|
||||||
|
return Math.Truncate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MathHelperF
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float Abs(float value)
|
||||||
|
{
|
||||||
|
return MathF.Abs(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float Ceiling(float value)
|
||||||
|
{
|
||||||
|
return MathF.Ceiling(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float Floor(float value)
|
||||||
|
{
|
||||||
|
return MathF.Floor(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float Round(float value, int mode)
|
||||||
|
{
|
||||||
|
return MathF.Round(value, (MidpointRounding)mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float Truncate(float value)
|
||||||
|
{
|
||||||
|
return MathF.Truncate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ using ARMeilleure.Memory;
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
@ -34,6 +35,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Context = null;
|
Context = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void Break(ulong address, int imm)
|
public static void Break(ulong address, int imm)
|
||||||
{
|
{
|
||||||
Statistics.PauseTimer();
|
Statistics.PauseTimer();
|
||||||
@ -43,6 +45,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Statistics.ResumeTimer();
|
Statistics.ResumeTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void SupervisorCall(ulong address, int imm)
|
public static void SupervisorCall(ulong address, int imm)
|
||||||
{
|
{
|
||||||
Statistics.PauseTimer();
|
Statistics.PauseTimer();
|
||||||
@ -52,6 +55,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Statistics.ResumeTimer();
|
Statistics.ResumeTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void Undefined(ulong address, int opCode)
|
public static void Undefined(ulong address, int opCode)
|
||||||
{
|
{
|
||||||
Statistics.PauseTimer();
|
Statistics.PauseTimer();
|
||||||
@ -62,26 +66,31 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region "System registers"
|
#region "System registers"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetCtrEl0()
|
public static ulong GetCtrEl0()
|
||||||
{
|
{
|
||||||
return GetContext().CtrEl0;
|
return GetContext().CtrEl0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetDczidEl0()
|
public static ulong GetDczidEl0()
|
||||||
{
|
{
|
||||||
return GetContext().DczidEl0;
|
return GetContext().DczidEl0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetCntfrqEl0()
|
public static ulong GetCntfrqEl0()
|
||||||
{
|
{
|
||||||
return GetContext().CntfrqEl0;
|
return GetContext().CntfrqEl0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetCntpctEl0()
|
public static ulong GetCntpctEl0()
|
||||||
{
|
{
|
||||||
return GetContext().CntpctEl0;
|
return GetContext().CntpctEl0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetCntvctEl0()
|
public static ulong GetCntvctEl0()
|
||||||
{
|
{
|
||||||
return GetContext().CntvctEl0;
|
return GetContext().CntvctEl0;
|
||||||
@ -89,26 +98,31 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Read"
|
#region "Read"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static byte ReadByte(ulong address)
|
public static byte ReadByte(ulong address)
|
||||||
{
|
{
|
||||||
return GetMemoryManager().ReadGuest<byte>(address);
|
return GetMemoryManager().ReadGuest<byte>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ushort ReadUInt16(ulong address)
|
public static ushort ReadUInt16(ulong address)
|
||||||
{
|
{
|
||||||
return GetMemoryManager().ReadGuest<ushort>(address);
|
return GetMemoryManager().ReadGuest<ushort>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint ReadUInt32(ulong address)
|
public static uint ReadUInt32(ulong address)
|
||||||
{
|
{
|
||||||
return GetMemoryManager().ReadGuest<uint>(address);
|
return GetMemoryManager().ReadGuest<uint>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong ReadUInt64(ulong address)
|
public static ulong ReadUInt64(ulong address)
|
||||||
{
|
{
|
||||||
return GetMemoryManager().ReadGuest<ulong>(address);
|
return GetMemoryManager().ReadGuest<ulong>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 ReadVector128(ulong address)
|
public static V128 ReadVector128(ulong address)
|
||||||
{
|
{
|
||||||
return GetMemoryManager().ReadGuest<V128>(address);
|
return GetMemoryManager().ReadGuest<V128>(address);
|
||||||
@ -116,47 +130,56 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Write"
|
#region "Write"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void WriteByte(ulong address, byte value)
|
public static void WriteByte(ulong address, byte value)
|
||||||
{
|
{
|
||||||
GetMemoryManager().WriteGuest(address, value);
|
GetMemoryManager().WriteGuest(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void WriteUInt16(ulong address, ushort value)
|
public static void WriteUInt16(ulong address, ushort value)
|
||||||
{
|
{
|
||||||
GetMemoryManager().WriteGuest(address, value);
|
GetMemoryManager().WriteGuest(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void WriteUInt32(ulong address, uint value)
|
public static void WriteUInt32(ulong address, uint value)
|
||||||
{
|
{
|
||||||
GetMemoryManager().WriteGuest(address, value);
|
GetMemoryManager().WriteGuest(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void WriteUInt64(ulong address, ulong value)
|
public static void WriteUInt64(ulong address, ulong value)
|
||||||
{
|
{
|
||||||
GetMemoryManager().WriteGuest(address, value);
|
GetMemoryManager().WriteGuest(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void WriteVector128(ulong address, V128 value)
|
public static void WriteVector128(ulong address, V128 value)
|
||||||
{
|
{
|
||||||
GetMemoryManager().WriteGuest(address, value);
|
GetMemoryManager().WriteGuest(address, value);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void EnqueueForRejit(ulong address)
|
public static void EnqueueForRejit(ulong address)
|
||||||
{
|
{
|
||||||
Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
|
Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SignalMemoryTracking(ulong address, ulong size, bool write)
|
[UnmanagedCallersOnly]
|
||||||
|
public static void SignalMemoryTracking(ulong address, ulong size, byte write)
|
||||||
{
|
{
|
||||||
GetMemoryManager().SignalMemoryTracking(address, size, write);
|
GetMemoryManager().SignalMemoryTracking(address, size, write == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void ThrowInvalidMemoryAccess(ulong address)
|
public static void ThrowInvalidMemoryAccess(ulong address)
|
||||||
{
|
{
|
||||||
throw new InvalidAccessException(address);
|
throw new InvalidAccessException(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong GetFunctionAddress(ulong address)
|
public static ulong GetFunctionAddress(ulong address)
|
||||||
{
|
{
|
||||||
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
||||||
@ -164,12 +187,14 @@ namespace ARMeilleure.Instructions
|
|||||||
return (ulong)function.FuncPointer.ToInt64();
|
return (ulong)function.FuncPointer.ToInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static void InvalidateCacheLine(ulong address)
|
public static void InvalidateCacheLine(ulong address)
|
||||||
{
|
{
|
||||||
Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
|
Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CheckSynchronization()
|
[UnmanagedCallersOnly]
|
||||||
|
public static byte CheckSynchronization()
|
||||||
{
|
{
|
||||||
Statistics.PauseTimer();
|
Statistics.PauseTimer();
|
||||||
|
|
||||||
@ -179,7 +204,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Statistics.ResumeTimer();
|
Statistics.ResumeTimer();
|
||||||
|
|
||||||
return context.Running;
|
return (byte)(context.Running ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecutionContext GetContext()
|
public static ExecutionContext GetContext()
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
static class SoftFallback
|
static class SoftFallback
|
||||||
{
|
{
|
||||||
#region "ShrImm64"
|
#region "ShrImm64"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static long SignedShrImm64(long value, long roundConst, int shift)
|
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||||
{
|
{
|
||||||
if (roundConst == 0L)
|
if (roundConst == 0L)
|
||||||
@ -48,6 +50,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
||||||
{
|
{
|
||||||
if (roundConst == 0L)
|
if (roundConst == 0L)
|
||||||
@ -92,6 +95,7 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Saturation"
|
#region "Saturation"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static int SatF32ToS32(float value)
|
public static int SatF32ToS32(float value)
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value))
|
if (float.IsNaN(value))
|
||||||
@ -103,6 +107,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= int.MinValue ? int.MinValue : (int)value;
|
value <= int.MinValue ? int.MinValue : (int)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static long SatF32ToS64(float value)
|
public static long SatF32ToS64(float value)
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value))
|
if (float.IsNaN(value))
|
||||||
@ -114,6 +119,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= long.MinValue ? long.MinValue : (long)value;
|
value <= long.MinValue ? long.MinValue : (long)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint SatF32ToU32(float value)
|
public static uint SatF32ToU32(float value)
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value))
|
if (float.IsNaN(value))
|
||||||
@ -125,6 +131,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong SatF32ToU64(float value)
|
public static ulong SatF32ToU64(float value)
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value))
|
if (float.IsNaN(value))
|
||||||
@ -136,6 +143,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static int SatF64ToS32(double value)
|
public static int SatF64ToS32(double value)
|
||||||
{
|
{
|
||||||
if (double.IsNaN(value))
|
if (double.IsNaN(value))
|
||||||
@ -147,6 +155,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= int.MinValue ? int.MinValue : (int)value;
|
value <= int.MinValue ? int.MinValue : (int)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static long SatF64ToS64(double value)
|
public static long SatF64ToS64(double value)
|
||||||
{
|
{
|
||||||
if (double.IsNaN(value))
|
if (double.IsNaN(value))
|
||||||
@ -158,6 +167,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= long.MinValue ? long.MinValue : (long)value;
|
value <= long.MinValue ? long.MinValue : (long)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint SatF64ToU32(double value)
|
public static uint SatF64ToU32(double value)
|
||||||
{
|
{
|
||||||
if (double.IsNaN(value))
|
if (double.IsNaN(value))
|
||||||
@ -169,6 +179,7 @@ namespace ARMeilleure.Instructions
|
|||||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong SatF64ToU64(double value)
|
public static ulong SatF64ToU64(double value)
|
||||||
{
|
{
|
||||||
if (double.IsNaN(value))
|
if (double.IsNaN(value))
|
||||||
@ -182,6 +193,7 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Count"
|
#region "Count"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
{
|
{
|
||||||
value ^= value >> 1;
|
value ^= value >> 1;
|
||||||
@ -201,6 +213,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
private static ReadOnlySpan<byte> ClzNibbleTbl => new byte[] { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
private static ReadOnlySpan<byte> ClzNibbleTbl => new byte[] { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
{
|
{
|
||||||
if (value == 0ul)
|
if (value == 0ul)
|
||||||
@ -224,41 +237,49 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Table"
|
#region "Table"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
|
public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
|
||||||
{
|
{
|
||||||
return TblOrTbx(default, vector, bytes, tb0);
|
return TblOrTbx(default, vector, bytes, tb0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
|
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||||
{
|
{
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1);
|
return TblOrTbx(default, vector, bytes, tb0, tb1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||||
{
|
{
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
|
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||||
{
|
{
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
|
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
|
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
|
||||||
{
|
{
|
||||||
return TblOrTbx(dest, vector, bytes, tb0);
|
return TblOrTbx(dest, vector, bytes, tb0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
|
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||||
{
|
{
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1);
|
return TblOrTbx(dest, vector, bytes, tb0, tb1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||||
{
|
{
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
|
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||||
{
|
{
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
||||||
@ -300,14 +321,22 @@ namespace ARMeilleure.Instructions
|
|||||||
private const uint Crc32RevPoly = 0xedb88320;
|
private const uint Crc32RevPoly = 0xedb88320;
|
||||||
private const uint Crc32cRevPoly = 0x82f63b78;
|
private const uint Crc32cRevPoly = 0x82f63b78;
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
|
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
|
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
||||||
|
|
||||||
private static uint Crc32h(uint crc, uint poly, ushort val)
|
private static uint Crc32h(uint crc, uint poly, ushort val)
|
||||||
@ -358,21 +387,25 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Aes"
|
#region "Aes"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Decrypt(V128 value, V128 roundKey)
|
public static V128 Decrypt(V128 value, V128 roundKey)
|
||||||
{
|
{
|
||||||
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Encrypt(V128 value, V128 roundKey)
|
public static V128 Encrypt(V128 value, V128 roundKey)
|
||||||
{
|
{
|
||||||
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 InverseMixColumns(V128 value)
|
public static V128 InverseMixColumns(V128 value)
|
||||||
{
|
{
|
||||||
return CryptoHelper.AesInvMixColumns(value);
|
return CryptoHelper.AesInvMixColumns(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 MixColumns(V128 value)
|
public static V128 MixColumns(V128 value)
|
||||||
{
|
{
|
||||||
return CryptoHelper.AesMixColumns(value);
|
return CryptoHelper.AesMixColumns(value);
|
||||||
@ -380,6 +413,7 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Sha1"
|
#region "Sha1"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
|
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
@ -400,11 +434,13 @@ namespace ARMeilleure.Instructions
|
|||||||
return hash_abcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static uint FixedRotate(uint hash_e)
|
public static uint FixedRotate(uint hash_e)
|
||||||
{
|
{
|
||||||
return hash_e.Rol(30);
|
return hash_e.Rol(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
|
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
@ -425,6 +461,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return hash_abcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
|
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
@ -445,6 +482,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return hash_abcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
|
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
|
||||||
{
|
{
|
||||||
ulong t2 = w4_7.Extract<ulong>(0);
|
ulong t2 = w4_7.Extract<ulong>(0);
|
||||||
@ -455,6 +493,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result ^ (w0_3 ^ w8_11);
|
return result ^ (w0_3 ^ w8_11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
|
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
|
||||||
{
|
{
|
||||||
V128 t = tw0_3 ^ (w12_15 >> 32);
|
V128 t = tw0_3 ^ (w12_15 >> 32);
|
||||||
@ -499,16 +538,19 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Sha256"
|
#region "Sha256"
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||||
{
|
{
|
||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||||
{
|
{
|
||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
|
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
|
||||||
{
|
{
|
||||||
V128 result = new();
|
V128 result = new();
|
||||||
@ -527,6 +569,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
|
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
|
||||||
{
|
{
|
||||||
V128 result = new();
|
V128 result = new();
|
||||||
@ -628,6 +671,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static V128 PolynomialMult64_128(ulong op1, ulong op2)
|
public static V128 PolynomialMult64_128(ulong op1, ulong op2)
|
||||||
{
|
{
|
||||||
V128 result = V128.Zero;
|
V128 result = V128.Zero;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
@ -312,6 +313,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat16_32
|
static class SoftFloat16_32
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPConvert(ushort valueBits)
|
public static float FPConvert(ushort valueBits)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -487,6 +489,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat16_64
|
static class SoftFloat16_64
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPConvert(ushort valueBits)
|
public static double FPConvert(ushort valueBits)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -662,6 +665,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat32_16
|
static class SoftFloat32_16
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ushort FPConvert(float value)
|
public static ushort FPConvert(float value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -781,12 +785,19 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat32
|
static class SoftFloat32
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPAdd(float value1, float value2)
|
public static float FPAdd(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPAddFpscr(value1, value2, false);
|
return FPAddFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPAddFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPAddFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPAddFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -837,7 +848,8 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int FPCompare(float value1, float value2, bool signalNaNs)
|
[UnmanagedCallersOnly]
|
||||||
|
public static int FPCompare(float value1, float value2, byte signalNaNs)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = context.Fpcr;
|
FPCR fpcr = context.Fpcr;
|
||||||
@ -851,7 +863,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
result = 0b0011;
|
result = 0b0011;
|
||||||
|
|
||||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs)
|
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
|
||||||
{
|
{
|
||||||
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
||||||
}
|
}
|
||||||
@ -875,12 +887,13 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPCompareEQ(float value1, float value2)
|
public static float FPCompareEQ(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPCompareEQFpscr(value1, value2, false);
|
return FPCompareEQFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareEQFpscr(float value1, float value2, bool standardFpscr)
|
private static float FPCompareEQFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -907,12 +920,25 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareGE(float value1, float value2)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareEQFpscr(float value1, float value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
return FPCompareGEFpscr(value1, value2, false);
|
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareGEFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareGE(float value1, float value2)
|
||||||
|
{
|
||||||
|
return FPCompareGEFpscrImpl(value1, value2, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareGEFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPCompareGEFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -936,12 +962,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPCompareGT(float value1, float value2)
|
public static float FPCompareGT(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPCompareGTFpscr(value1, value2, false);
|
return FPCompareGTFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareGTFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareGTFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPCompareGTFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -965,26 +998,31 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPCompareLE(float value1, float value2)
|
public static float FPCompareLE(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPCompareGE(value2, value1);
|
return FPCompareGEFpscrImpl(value2, value1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPCompareLT(float value1, float value2)
|
public static float FPCompareLT(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPCompareGT(value2, value1);
|
return FPCompareGTFpscrImpl(value2, value1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareLEFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareLEFpscr(float value1, float value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
return FPCompareGEFpscr(value2, value1, standardFpscr);
|
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPCompareLTFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPCompareLTFpscr(float value1, float value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
return FPCompareGTFpscr(value2, value1, standardFpscr);
|
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPDiv(float value1, float value2)
|
public static float FPDiv(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1037,12 +1075,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMax(float value1, float value2)
|
public static float FPMax(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMaxFpscr(value1, value2, false);
|
return FPMaxFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMaxFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMaxFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1103,12 +1148,13 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMaxNum(float value1, float value2)
|
public static float FPMaxNum(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMaxNumFpscr(value1, value2, false);
|
return FPMaxNumFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMaxNumFpscr(float value1, float value2, bool standardFpscr)
|
private static float FPMaxNumFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1125,15 +1171,28 @@ namespace ARMeilleure.Instructions
|
|||||||
value2 = FPInfinity(true);
|
value2 = FPInfinity(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FPMaxFpscr(value1, value2, standardFpscr);
|
return FPMaxFpscrImpl(value1, value2, standardFpscr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMaxNumFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMin(float value1, float value2)
|
public static float FPMin(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMinFpscr(value1, value2, false);
|
return FPMinFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMinFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMinFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPMinFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1194,12 +1253,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMinNum(float value1, float value2)
|
public static float FPMinNum(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMinNumFpscr(value1, value2, false);
|
return FPMinNumFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMinNumFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMinNumFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPMinNumFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1216,15 +1282,22 @@ namespace ARMeilleure.Instructions
|
|||||||
value2 = FPInfinity(false);
|
value2 = FPInfinity(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FPMinFpscr(value1, value2, standardFpscr);
|
return FPMinFpscrImpl(value1, value2, standardFpscr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMul(float value1, float value2)
|
public static float FPMul(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMulFpscr(value1, value2, false);
|
return FPMulFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMulFpscr(float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMulFpscr(float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPMulFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1271,12 +1344,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMulAdd(float valueA, float value1, float value2)
|
public static float FPMulAdd(float valueA, float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPMulAddFpscr(valueA, value1, value2, false);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMulAddFpscr(float valueA, float value1, float value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPMulAddFpscrImpl(float valueA, float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1342,20 +1422,23 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMulSub(float valueA, float value1, float value2)
|
public static float FPMulSub(float valueA, float value1, float value2)
|
||||||
{
|
{
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPMulSubFpscr(float valueA, float value1, float value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAddFpscr(valueA, value1, value2, standardFpscr);
|
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPMulX(float value1, float value2)
|
public static float FPMulX(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1401,27 +1484,36 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPNegMulAdd(float valueA, float value1, float value2)
|
public static float FPNegMulAdd(float valueA, float value1, float value2)
|
||||||
{
|
{
|
||||||
valueA = valueA.FPNeg();
|
valueA = valueA.FPNeg();
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPNegMulSub(float valueA, float value1, float value2)
|
public static float FPNegMulSub(float valueA, float value1, float value2)
|
||||||
{
|
{
|
||||||
valueA = valueA.FPNeg();
|
valueA = valueA.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRecipEstimate(float value)
|
public static float FPRecipEstimate(float value)
|
||||||
{
|
{
|
||||||
return FPRecipEstimateFpscr(value, false);
|
return FPRecipEstimateFpscrImpl(value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPRecipEstimateFpscr(float value, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPRecipEstimateFpscr(float value, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPRecipEstimateFpscrImpl(float value, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1508,6 +1600,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRecipStep(float value1, float value2)
|
public static float FPRecipStep(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1533,15 +1626,16 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscrImpl(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = FPSubFpscr(FPTwo(false), product, true);
|
result = FPSubFpscrImpl(FPTwo(false), product, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRecipStepFused(float value1, float value2)
|
public static float FPRecipStepFused(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1585,6 +1679,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRecpX(float value)
|
public static float FPRecpX(float value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1610,12 +1705,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRSqrtEstimate(float value)
|
public static float FPRSqrtEstimate(float value)
|
||||||
{
|
{
|
||||||
return FPRSqrtEstimateFpscr(value, false);
|
return FPRSqrtEstimateFpscrImpl(value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPRSqrtEstimateFpscr(float value, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPRSqrtEstimateFpscr(float value, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPRSqrtEstimateFpscrImpl(float value, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -1729,6 +1831,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRSqrtStep(float value1, float value2)
|
public static float FPRSqrtStep(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1754,7 +1857,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscrImpl(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||||
@ -1763,6 +1866,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPRSqrtStepFused(float value1, float value2)
|
public static float FPRSqrtStepFused(float value1, float value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1806,6 +1910,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPSqrt(float value)
|
public static float FPSqrt(float value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -1848,12 +1953,13 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static float FPSub(float value1, float value2)
|
public static float FPSub(float value1, float value2)
|
||||||
{
|
{
|
||||||
return FPSubFpscr(value1, value2, false);
|
return FPSubFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float FPSubFpscr(float value1, float value2, bool standardFpscr)
|
private static float FPSubFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2094,6 +2200,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat64_16
|
static class SoftFloat64_16
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static ushort FPConvert(double value)
|
public static ushort FPConvert(double value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -2213,12 +2320,19 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
static class SoftFloat64
|
static class SoftFloat64
|
||||||
{
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPAdd(double value1, double value2)
|
public static double FPAdd(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPAddFpscr(value1, value2, false);
|
return FPAddFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPAddFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPAddFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPAddFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2269,7 +2383,8 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int FPCompare(double value1, double value2, bool signalNaNs)
|
[UnmanagedCallersOnly]
|
||||||
|
public static int FPCompare(double value1, double value2, byte signalNaNs)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = context.Fpcr;
|
FPCR fpcr = context.Fpcr;
|
||||||
@ -2283,7 +2398,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
result = 0b0011;
|
result = 0b0011;
|
||||||
|
|
||||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs)
|
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
|
||||||
{
|
{
|
||||||
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
||||||
}
|
}
|
||||||
@ -2307,12 +2422,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPCompareEQ(double value1, double value2)
|
public static double FPCompareEQ(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPCompareEQFpscr(value1, value2, false);
|
return FPCompareEQFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPCompareEQFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPCompareEQFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPCompareEQFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2339,12 +2461,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPCompareGE(double value1, double value2)
|
public static double FPCompareGE(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPCompareGEFpscr(value1, value2, false);
|
return FPCompareGEFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPCompareGEFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPCompareGEFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPCompareGEFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2368,12 +2497,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPCompareGT(double value1, double value2)
|
public static double FPCompareGT(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPCompareGTFpscr(value1, value2, false);
|
return FPCompareGTFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPCompareGTFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPCompareGTFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPCompareGTFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2397,26 +2533,31 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPCompareLE(double value1, double value2)
|
public static double FPCompareLE(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPCompareGE(value2, value1);
|
return FPCompareGEFpscrImpl(value2, value1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPCompareLT(double value1, double value2)
|
public static double FPCompareLT(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPCompareGT(value2, value1);
|
return FPCompareGTFpscrImpl(value2, value1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPCompareLEFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPCompareLEFpscr(double value1, double value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
return FPCompareGEFpscr(value2, value1, standardFpscr);
|
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPCompareLTFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPCompareLTFpscr(double value1, double value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
return FPCompareGTFpscr(value2, value1, standardFpscr);
|
return FPCompareGTFpscrImpl(value2, value1, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPDiv(double value1, double value2)
|
public static double FPDiv(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -2469,12 +2610,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMax(double value1, double value2)
|
public static double FPMax(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMaxFpscr(value1, value2, false);
|
return FPMaxFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMaxFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMaxFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMaxFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2535,12 +2683,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMaxNum(double value1, double value2)
|
public static double FPMaxNum(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMaxNumFpscr(value1, value2, false);
|
return FPMaxNumFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMaxNumFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMaxNumFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMaxNumFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2557,15 +2712,22 @@ namespace ARMeilleure.Instructions
|
|||||||
value2 = FPInfinity(true);
|
value2 = FPInfinity(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FPMaxFpscr(value1, value2, standardFpscr);
|
return FPMaxFpscrImpl(value1, value2, standardFpscr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMin(double value1, double value2)
|
public static double FPMin(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMinFpscr(value1, value2, false);
|
return FPMinFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMinFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMinFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMinFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2626,12 +2788,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMinNum(double value1, double value2)
|
public static double FPMinNum(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMinNumFpscr(value1, value2, false);
|
return FPMinNumFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMinNumFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMinNumFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMinNumFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2648,15 +2817,22 @@ namespace ARMeilleure.Instructions
|
|||||||
value2 = FPInfinity(false);
|
value2 = FPInfinity(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FPMinFpscr(value1, value2, standardFpscr);
|
return FPMinFpscrImpl(value1, value2, standardFpscr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMul(double value1, double value2)
|
public static double FPMul(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMulFpscr(value1, value2, false);
|
return FPMulFpscrImpl(value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMulFpscr(double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMulFpscr(double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMulFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2703,12 +2879,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMulAdd(double valueA, double value1, double value2)
|
public static double FPMulAdd(double valueA, double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPMulAddFpscr(valueA, value1, value2, false);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMulAddFpscr(double valueA, double value1, double value2, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPMulAddFpscrImpl(double valueA, double value1, double value2, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2774,20 +2957,23 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMulSub(double valueA, double value1, double value2)
|
public static double FPMulSub(double valueA, double value1, double value2)
|
||||||
{
|
{
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPMulSubFpscr(double valueA, double value1, double value2, byte standardFpscr)
|
||||||
{
|
{
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAddFpscr(valueA, value1, value2, standardFpscr);
|
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPMulX(double value1, double value2)
|
public static double FPMulX(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -2833,27 +3019,36 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPNegMulAdd(double valueA, double value1, double value2)
|
public static double FPNegMulAdd(double valueA, double value1, double value2)
|
||||||
{
|
{
|
||||||
valueA = valueA.FPNeg();
|
valueA = valueA.FPNeg();
|
||||||
value1 = value1.FPNeg();
|
value1 = value1.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPNegMulSub(double valueA, double value1, double value2)
|
public static double FPNegMulSub(double valueA, double value1, double value2)
|
||||||
{
|
{
|
||||||
valueA = valueA.FPNeg();
|
valueA = valueA.FPNeg();
|
||||||
|
|
||||||
return FPMulAdd(valueA, value1, value2);
|
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRecipEstimate(double value)
|
public static double FPRecipEstimate(double value)
|
||||||
{
|
{
|
||||||
return FPRecipEstimateFpscr(value, false);
|
return FPRecipEstimateFpscrImpl(value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPRecipEstimateFpscr(double value, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPRecipEstimateFpscr(double value, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPRecipEstimateFpscrImpl(double value, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -2940,6 +3135,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRecipStep(double value1, double value2)
|
public static double FPRecipStep(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -2965,7 +3161,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscrImpl(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = FPSubFpscr(FPTwo(false), product, true);
|
result = FPSubFpscr(FPTwo(false), product, true);
|
||||||
@ -2974,6 +3170,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRecipStepFused(double value1, double value2)
|
public static double FPRecipStepFused(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -3017,6 +3214,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRecpX(double value)
|
public static double FPRecpX(double value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -3042,12 +3240,19 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRSqrtEstimate(double value)
|
public static double FPRSqrtEstimate(double value)
|
||||||
{
|
{
|
||||||
return FPRSqrtEstimateFpscr(value, false);
|
return FPRSqrtEstimateFpscrImpl(value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double FPRSqrtEstimateFpscr(double value, bool standardFpscr)
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPRSqrtEstimateFpscr(double value, byte standardFpscr)
|
||||||
|
{
|
||||||
|
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPRSqrtEstimateFpscrImpl(double value, bool standardFpscr)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||||
@ -3161,6 +3366,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRSqrtStep(double value1, double value2)
|
public static double FPRSqrtStep(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -3186,7 +3392,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscrImpl(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||||
@ -3195,6 +3401,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPRSqrtStepFused(double value1, double value2)
|
public static double FPRSqrtStepFused(double value1, double value2)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -3238,6 +3445,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPSqrt(double value)
|
public static double FPSqrt(double value)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
@ -3280,6 +3488,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
public static double FPSub(double value1, double value2)
|
public static double FPSub(double value1, double value2)
|
||||||
{
|
{
|
||||||
return FPSubFpscr(value1, value2, false);
|
return FPSubFpscr(value1, value2, false);
|
||||||
|
@ -4,15 +4,9 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
class DelegateInfo
|
class DelegateInfo
|
||||||
{
|
{
|
||||||
#pragma warning disable IDE0052 // Remove unread private member
|
public nint FuncPtr { get; private set; }
|
||||||
private readonly Delegate _dlg; // Ensure that this delegate will not be garbage collected.
|
public DelegateInfo(nint funcPtr)
|
||||||
#pragma warning restore IDE0052
|
|
||||||
|
|
||||||
public nint FuncPtr { get; }
|
|
||||||
|
|
||||||
public DelegateInfo(Delegate dlg, nint funcPtr)
|
|
||||||
{
|
{
|
||||||
_dlg = dlg;
|
|
||||||
FuncPtr = funcPtr;
|
FuncPtr = funcPtr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
using ARMeilleure.Instructions;
|
using ARMeilleure.Instructions;
|
||||||
using ARMeilleure.State;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
@ -35,20 +33,6 @@ namespace ARMeilleure.Translation
|
|||||||
return _delegates.Values[index].FuncPtr; // O(1).
|
return _delegates.Values[index].FuncPtr; // O(1).
|
||||||
}
|
}
|
||||||
|
|
||||||
public static nint GetDelegateFuncPtr(MethodInfo info)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
|
||||||
|
|
||||||
string key = GetKey(info);
|
|
||||||
|
|
||||||
if (!_delegates.TryGetValue(key, out DelegateInfo dlgInfo)) // O(log(n)).
|
|
||||||
{
|
|
||||||
throw new KeyNotFoundException($"({nameof(key)} = {key})");
|
|
||||||
}
|
|
||||||
|
|
||||||
return dlgInfo.FuncPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetDelegateIndex(MethodInfo info)
|
public static int GetDelegateIndex(MethodInfo info)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
@ -65,11 +49,11 @@ namespace ARMeilleure.Translation
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetDelegateInfo(Delegate dlg, nint funcPtr)
|
private static void SetDelegateInfo(MethodInfo method)
|
||||||
{
|
{
|
||||||
string key = GetKey(dlg.Method);
|
string key = GetKey(method);
|
||||||
|
|
||||||
_delegates.Add(key, new DelegateInfo(dlg, funcPtr)); // ArgumentException (key).
|
_delegates.Add(key, new DelegateInfo(method.MethodHandle.GetFunctionPointer())); // ArgumentException (key).
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetKey(MethodInfo info)
|
private static string GetKey(MethodInfo info)
|
||||||
@ -83,528 +67,179 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
_delegates = new SortedList<string, DelegateInfo>();
|
_delegates = new SortedList<string, DelegateInfo>();
|
||||||
|
|
||||||
var dlgMathAbs = new MathAbs(Math.Abs);
|
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Abs)));
|
||||||
var dlgMathCeiling = new MathCeiling(Math.Ceiling);
|
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Ceiling)));
|
||||||
var dlgMathFloor = new MathFloor(Math.Floor);
|
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Floor)));
|
||||||
var dlgMathRound = new MathRound(Math.Round);
|
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Round)));
|
||||||
var dlgMathTruncate = new MathTruncate(Math.Truncate);
|
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Truncate)));
|
||||||
|
|
||||||
var dlgMathFAbs = new MathFAbs(MathF.Abs);
|
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Abs)));
|
||||||
var dlgMathFCeiling = new MathFCeiling(MathF.Ceiling);
|
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Ceiling)));
|
||||||
var dlgMathFFloor = new MathFFloor(MathF.Floor);
|
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Floor)));
|
||||||
var dlgMathFRound = new MathFRound(MathF.Round);
|
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Round)));
|
||||||
var dlgMathFTruncate = new MathFTruncate(MathF.Truncate);
|
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Truncate)));
|
||||||
|
|
||||||
var dlgNativeInterfaceBreak = new NativeInterfaceBreak(NativeInterface.Break);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
|
||||||
var dlgNativeInterfaceCheckSynchronization = new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||||
var dlgNativeInterfaceEnqueueForRejit = new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
|
||||||
var dlgNativeInterfaceGetCntfrqEl0 = new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
|
||||||
var dlgNativeInterfaceGetCntpctEl0 = new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
|
||||||
var dlgNativeInterfaceGetCntvctEl0 = new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
|
||||||
var dlgNativeInterfaceGetCtrEl0 = new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
|
||||||
var dlgNativeInterfaceGetDczidEl0 = new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
|
||||||
var dlgNativeInterfaceGetFunctionAddress = new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
|
||||||
var dlgNativeInterfaceInvalidateCacheLine = new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
|
||||||
var dlgNativeInterfaceReadByte = new NativeInterfaceReadByte(NativeInterface.ReadByte);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
|
||||||
var dlgNativeInterfaceReadUInt16 = new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
|
||||||
var dlgNativeInterfaceReadUInt32 = new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
|
||||||
var dlgNativeInterfaceReadUInt64 = new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
|
||||||
var dlgNativeInterfaceReadVector128 = new NativeInterfaceReadVector128(NativeInterface.ReadVector128);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
|
||||||
var dlgNativeInterfaceSignalMemoryTracking = new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||||
var dlgNativeInterfaceSupervisorCall = new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
|
||||||
var dlgNativeInterfaceThrowInvalidMemoryAccess = new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
|
||||||
var dlgNativeInterfaceUndefined = new NativeInterfaceUndefined(NativeInterface.Undefined);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
|
||||||
var dlgNativeInterfaceWriteByte = new NativeInterfaceWriteByte(NativeInterface.WriteByte);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
|
||||||
var dlgNativeInterfaceWriteUInt16 = new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
|
||||||
var dlgNativeInterfaceWriteUInt32 = new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
|
||||||
var dlgNativeInterfaceWriteUInt64 = new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||||
var dlgNativeInterfaceWriteVector128 = new NativeInterfaceWriteVector128(NativeInterface.WriteVector128);
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||||
|
|
||||||
var dlgSoftFallbackCountLeadingSigns = new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
||||||
var dlgSoftFallbackCountLeadingZeros = new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
||||||
var dlgSoftFallbackCrc32b = new SoftFallbackCrc32b(SoftFallback.Crc32b);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
||||||
var dlgSoftFallbackCrc32cb = new SoftFallbackCrc32cb(SoftFallback.Crc32cb);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb)));
|
||||||
var dlgSoftFallbackCrc32ch = new SoftFallbackCrc32ch(SoftFallback.Crc32ch);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch)));
|
||||||
var dlgSoftFallbackCrc32cw = new SoftFallbackCrc32cw(SoftFallback.Crc32cw);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw)));
|
||||||
var dlgSoftFallbackCrc32cx = new SoftFallbackCrc32cx(SoftFallback.Crc32cx);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx)));
|
||||||
var dlgSoftFallbackCrc32h = new SoftFallbackCrc32h(SoftFallback.Crc32h);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h)));
|
||||||
var dlgSoftFallbackCrc32w = new SoftFallbackCrc32w(SoftFallback.Crc32w);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w)));
|
||||||
var dlgSoftFallbackCrc32x = new SoftFallbackCrc32x(SoftFallback.Crc32x);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x)));
|
||||||
var dlgSoftFallbackDecrypt = new SoftFallbackDecrypt(SoftFallback.Decrypt);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)));
|
||||||
var dlgSoftFallbackEncrypt = new SoftFallbackEncrypt(SoftFallback.Encrypt);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)));
|
||||||
var dlgSoftFallbackFixedRotate = new SoftFallbackFixedRotate(SoftFallback.FixedRotate);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)));
|
||||||
var dlgSoftFallbackHashChoose = new SoftFallbackHashChoose(SoftFallback.HashChoose);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)));
|
||||||
var dlgSoftFallbackHashLower = new SoftFallbackHashLower(SoftFallback.HashLower);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)));
|
||||||
var dlgSoftFallbackHashMajority = new SoftFallbackHashMajority(SoftFallback.HashMajority);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)));
|
||||||
var dlgSoftFallbackHashParity = new SoftFallbackHashParity(SoftFallback.HashParity);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)));
|
||||||
var dlgSoftFallbackHashUpper = new SoftFallbackHashUpper(SoftFallback.HashUpper);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)));
|
||||||
var dlgSoftFallbackInverseMixColumns = new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)));
|
||||||
var dlgSoftFallbackMixColumns = new SoftFallbackMixColumns(SoftFallback.MixColumns);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)));
|
||||||
var dlgSoftFallbackPolynomialMult64_128 = new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128)));
|
||||||
var dlgSoftFallbackSatF32ToS32 = new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)));
|
||||||
var dlgSoftFallbackSatF32ToS64 = new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)));
|
||||||
var dlgSoftFallbackSatF32ToU32 = new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)));
|
||||||
var dlgSoftFallbackSatF32ToU64 = new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)));
|
||||||
var dlgSoftFallbackSatF64ToS32 = new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)));
|
||||||
var dlgSoftFallbackSatF64ToS64 = new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)));
|
||||||
var dlgSoftFallbackSatF64ToU32 = new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)));
|
||||||
var dlgSoftFallbackSatF64ToU64 = new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)));
|
||||||
var dlgSoftFallbackSha1SchedulePart1 = new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)));
|
||||||
var dlgSoftFallbackSha1SchedulePart2 = new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
|
||||||
var dlgSoftFallbackSha256SchedulePart1 = new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
||||||
var dlgSoftFallbackSha256SchedulePart2 = new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
|
||||||
var dlgSoftFallbackSignedShrImm64 = new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
||||||
var dlgSoftFallbackTbl1 = new SoftFallbackTbl1(SoftFallback.Tbl1);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
||||||
var dlgSoftFallbackTbl2 = new SoftFallbackTbl2(SoftFallback.Tbl2);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
||||||
var dlgSoftFallbackTbl3 = new SoftFallbackTbl3(SoftFallback.Tbl3);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
||||||
var dlgSoftFallbackTbl4 = new SoftFallbackTbl4(SoftFallback.Tbl4);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)));
|
||||||
var dlgSoftFallbackTbx1 = new SoftFallbackTbx1(SoftFallback.Tbx1);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)));
|
||||||
var dlgSoftFallbackTbx2 = new SoftFallbackTbx2(SoftFallback.Tbx2);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
||||||
var dlgSoftFallbackTbx3 = new SoftFallbackTbx3(SoftFallback.Tbx3);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
||||||
var dlgSoftFallbackTbx4 = new SoftFallbackTbx4(SoftFallback.Tbx4);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
||||||
var dlgSoftFallbackUnsignedShrImm64 = new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64);
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||||
|
|
||||||
var dlgSoftFloat16_32FPConvert = new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert);
|
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
||||||
var dlgSoftFloat16_64FPConvert = new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert);
|
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
||||||
|
|
||||||
var dlgSoftFloat32FPAdd = new SoftFloat32FPAdd(SoftFloat32.FPAdd);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
|
||||||
var dlgSoftFloat32FPAddFpscr = new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPCompare = new SoftFloat32FPCompare(SoftFloat32.FPCompare);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
|
||||||
var dlgSoftFloat32FPCompareEQ = new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
|
||||||
var dlgSoftFloat32FPCompareEQFpscr = new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPCompareGE = new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
|
||||||
var dlgSoftFloat32FPCompareGEFpscr = new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPCompareGT = new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
|
||||||
var dlgSoftFloat32FPCompareGTFpscr = new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPCompareLE = new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
|
||||||
var dlgSoftFloat32FPCompareLEFpscr = new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPCompareLT = new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
|
||||||
var dlgSoftFloat32FPCompareLTFpscr = new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPDiv = new SoftFloat32FPDiv(SoftFloat32.FPDiv);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
|
||||||
var dlgSoftFloat32FPMax = new SoftFloat32FPMax(SoftFloat32.FPMax);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
|
||||||
var dlgSoftFloat32FPMaxFpscr = new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMaxNum = new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
|
||||||
var dlgSoftFloat32FPMaxNumFpscr = new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMin = new SoftFloat32FPMin(SoftFloat32.FPMin);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
|
||||||
var dlgSoftFloat32FPMinFpscr = new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMinNum = new SoftFloat32FPMinNum(SoftFloat32.FPMinNum);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
|
||||||
var dlgSoftFloat32FPMinNumFpscr = new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMul = new SoftFloat32FPMul(SoftFloat32.FPMul);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
|
||||||
var dlgSoftFloat32FPMulFpscr = new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMulAdd = new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
|
||||||
var dlgSoftFloat32FPMulAddFpscr = new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMulSub = new SoftFloat32FPMulSub(SoftFloat32.FPMulSub);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
|
||||||
var dlgSoftFloat32FPMulSubFpscr = new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPMulX = new SoftFloat32FPMulX(SoftFloat32.FPMulX);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
|
||||||
var dlgSoftFloat32FPNegMulAdd = new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
|
||||||
var dlgSoftFloat32FPNegMulSub = new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
|
||||||
var dlgSoftFloat32FPRecipEstimate = new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
|
||||||
var dlgSoftFloat32FPRecipEstimateFpscr = new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPRecipStep = new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
|
||||||
var dlgSoftFloat32FPRecipStepFused = new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
|
||||||
var dlgSoftFloat32FPRecpX = new SoftFloat32FPRecpX(SoftFloat32.FPRecpX);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
|
||||||
var dlgSoftFloat32FPRSqrtEstimate = new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
|
||||||
var dlgSoftFloat32FPRSqrtEstimateFpscr = new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
|
||||||
var dlgSoftFloat32FPRSqrtStep = new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
|
||||||
var dlgSoftFloat32FPRSqrtStepFused = new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
|
||||||
var dlgSoftFloat32FPSqrt = new SoftFloat32FPSqrt(SoftFloat32.FPSqrt);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
|
||||||
var dlgSoftFloat32FPSub = new SoftFloat32FPSub(SoftFloat32.FPSub);
|
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
|
||||||
|
|
||||||
var dlgSoftFloat32_16FPConvert = new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert);
|
SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
|
||||||
|
|
||||||
var dlgSoftFloat64FPAdd = new SoftFloat64FPAdd(SoftFloat64.FPAdd);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
|
||||||
var dlgSoftFloat64FPAddFpscr = new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPCompare = new SoftFloat64FPCompare(SoftFloat64.FPCompare);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
|
||||||
var dlgSoftFloat64FPCompareEQ = new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
|
||||||
var dlgSoftFloat64FPCompareEQFpscr = new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPCompareGE = new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
|
||||||
var dlgSoftFloat64FPCompareGEFpscr = new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPCompareGT = new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
|
||||||
var dlgSoftFloat64FPCompareGTFpscr = new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPCompareLE = new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
|
||||||
var dlgSoftFloat64FPCompareLEFpscr = new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPCompareLT = new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
|
||||||
var dlgSoftFloat64FPCompareLTFpscr = new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPDiv = new SoftFloat64FPDiv(SoftFloat64.FPDiv);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
|
||||||
var dlgSoftFloat64FPMax = new SoftFloat64FPMax(SoftFloat64.FPMax);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
|
||||||
var dlgSoftFloat64FPMaxFpscr = new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMaxNum = new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
|
||||||
var dlgSoftFloat64FPMaxNumFpscr = new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMin = new SoftFloat64FPMin(SoftFloat64.FPMin);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
|
||||||
var dlgSoftFloat64FPMinFpscr = new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMinNum = new SoftFloat64FPMinNum(SoftFloat64.FPMinNum);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
|
||||||
var dlgSoftFloat64FPMinNumFpscr = new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMul = new SoftFloat64FPMul(SoftFloat64.FPMul);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
|
||||||
var dlgSoftFloat64FPMulFpscr = new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMulAdd = new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
|
||||||
var dlgSoftFloat64FPMulAddFpscr = new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMulSub = new SoftFloat64FPMulSub(SoftFloat64.FPMulSub);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
|
||||||
var dlgSoftFloat64FPMulSubFpscr = new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPMulX = new SoftFloat64FPMulX(SoftFloat64.FPMulX);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
|
||||||
var dlgSoftFloat64FPNegMulAdd = new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
|
||||||
var dlgSoftFloat64FPNegMulSub = new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
|
||||||
var dlgSoftFloat64FPRecipEstimate = new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
|
||||||
var dlgSoftFloat64FPRecipEstimateFpscr = new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPRecipStep = new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
|
||||||
var dlgSoftFloat64FPRecipStepFused = new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
|
||||||
var dlgSoftFloat64FPRecpX = new SoftFloat64FPRecpX(SoftFloat64.FPRecpX);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
|
||||||
var dlgSoftFloat64FPRSqrtEstimate = new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
|
||||||
var dlgSoftFloat64FPRSqrtEstimateFpscr = new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
|
||||||
var dlgSoftFloat64FPRSqrtStep = new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep); // A32 only.
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
|
||||||
var dlgSoftFloat64FPRSqrtStepFused = new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
|
||||||
var dlgSoftFloat64FPSqrt = new SoftFloat64FPSqrt(SoftFloat64.FPSqrt);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
|
||||||
var dlgSoftFloat64FPSub = new SoftFloat64FPSub(SoftFloat64.FPSub);
|
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
|
||||||
|
|
||||||
var dlgSoftFloat64_16FPConvert = new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert);
|
SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)));
|
||||||
|
}
|
||||||
SetDelegateInfo(dlgMathAbs, Marshal.GetFunctionPointerForDelegate<MathAbs>(dlgMathAbs));
|
|
||||||
SetDelegateInfo(dlgMathCeiling, Marshal.GetFunctionPointerForDelegate<MathCeiling>(dlgMathCeiling));
|
|
||||||
SetDelegateInfo(dlgMathFloor, Marshal.GetFunctionPointerForDelegate<MathFloor>(dlgMathFloor));
|
|
||||||
SetDelegateInfo(dlgMathRound, Marshal.GetFunctionPointerForDelegate<MathRound>(dlgMathRound));
|
|
||||||
SetDelegateInfo(dlgMathTruncate, Marshal.GetFunctionPointerForDelegate<MathTruncate>(dlgMathTruncate));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgMathFAbs, Marshal.GetFunctionPointerForDelegate<MathFAbs>(dlgMathFAbs));
|
|
||||||
SetDelegateInfo(dlgMathFCeiling, Marshal.GetFunctionPointerForDelegate<MathFCeiling>(dlgMathFCeiling));
|
|
||||||
SetDelegateInfo(dlgMathFFloor, Marshal.GetFunctionPointerForDelegate<MathFFloor>(dlgMathFFloor));
|
|
||||||
SetDelegateInfo(dlgMathFRound, Marshal.GetFunctionPointerForDelegate<MathFRound>(dlgMathFRound));
|
|
||||||
SetDelegateInfo(dlgMathFTruncate, Marshal.GetFunctionPointerForDelegate<MathFTruncate>(dlgMathFTruncate));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceBreak, Marshal.GetFunctionPointerForDelegate<NativeInterfaceBreak>(dlgNativeInterfaceBreak));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceCheckSynchronization, Marshal.GetFunctionPointerForDelegate<NativeInterfaceCheckSynchronization>(dlgNativeInterfaceCheckSynchronization));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceEnqueueForRejit, Marshal.GetFunctionPointerForDelegate<NativeInterfaceEnqueueForRejit>(dlgNativeInterfaceEnqueueForRejit));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetCntfrqEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntfrqEl0>(dlgNativeInterfaceGetCntfrqEl0));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetCntpctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntpctEl0>(dlgNativeInterfaceGetCntpctEl0));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetCntvctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntvctEl0>(dlgNativeInterfaceGetCntvctEl0));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetCtrEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCtrEl0>(dlgNativeInterfaceGetCtrEl0));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetDczidEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetDczidEl0>(dlgNativeInterfaceGetDczidEl0));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceGetFunctionAddress, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetFunctionAddress>(dlgNativeInterfaceGetFunctionAddress));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceInvalidateCacheLine, Marshal.GetFunctionPointerForDelegate<NativeInterfaceInvalidateCacheLine>(dlgNativeInterfaceInvalidateCacheLine));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceReadByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadByte>(dlgNativeInterfaceReadByte));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceReadUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt16>(dlgNativeInterfaceReadUInt16));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceReadUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt32>(dlgNativeInterfaceReadUInt32));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceReadUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt64>(dlgNativeInterfaceReadUInt64));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceReadVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadVector128>(dlgNativeInterfaceReadVector128));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceSignalMemoryTracking, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSignalMemoryTracking>(dlgNativeInterfaceSignalMemoryTracking));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceSupervisorCall, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSupervisorCall>(dlgNativeInterfaceSupervisorCall));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceThrowInvalidMemoryAccess, Marshal.GetFunctionPointerForDelegate<NativeInterfaceThrowInvalidMemoryAccess>(dlgNativeInterfaceThrowInvalidMemoryAccess));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceUndefined, Marshal.GetFunctionPointerForDelegate<NativeInterfaceUndefined>(dlgNativeInterfaceUndefined));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceWriteByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteByte>(dlgNativeInterfaceWriteByte));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt16>(dlgNativeInterfaceWriteUInt16));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt32>(dlgNativeInterfaceWriteUInt32));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt64>(dlgNativeInterfaceWriteUInt64));
|
|
||||||
SetDelegateInfo(dlgNativeInterfaceWriteVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteVector128>(dlgNativeInterfaceWriteVector128));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCountLeadingSigns, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingSigns>(dlgSoftFallbackCountLeadingSigns));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCountLeadingZeros, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingZeros>(dlgSoftFallbackCountLeadingZeros));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32b, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32b>(dlgSoftFallbackCrc32b));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32cb, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cb>(dlgSoftFallbackCrc32cb));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32ch, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32ch>(dlgSoftFallbackCrc32ch));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32cw, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cw>(dlgSoftFallbackCrc32cw));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32cx, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cx>(dlgSoftFallbackCrc32cx));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32h, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32h>(dlgSoftFallbackCrc32h));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32w, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32w>(dlgSoftFallbackCrc32w));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackCrc32x, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32x>(dlgSoftFallbackCrc32x));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackDecrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackDecrypt>(dlgSoftFallbackDecrypt));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackEncrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackEncrypt>(dlgSoftFallbackEncrypt));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackFixedRotate, Marshal.GetFunctionPointerForDelegate<SoftFallbackFixedRotate>(dlgSoftFallbackFixedRotate));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackHashChoose, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashChoose>(dlgSoftFallbackHashChoose));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackHashLower, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashLower>(dlgSoftFallbackHashLower));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackHashMajority, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashMajority>(dlgSoftFallbackHashMajority));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackHashParity, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashParity>(dlgSoftFallbackHashParity));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackHashUpper, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashUpper>(dlgSoftFallbackHashUpper));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackInverseMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackInverseMixColumns>(dlgSoftFallbackInverseMixColumns));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackMixColumns>(dlgSoftFallbackMixColumns));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackPolynomialMult64_128, Marshal.GetFunctionPointerForDelegate<SoftFallbackPolynomialMult64_128>(dlgSoftFallbackPolynomialMult64_128));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF32ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS32>(dlgSoftFallbackSatF32ToS32));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF32ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS64>(dlgSoftFallbackSatF32ToS64));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF32ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU32>(dlgSoftFallbackSatF32ToU32));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF32ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU64>(dlgSoftFallbackSatF32ToU64));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF64ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS32>(dlgSoftFallbackSatF64ToS32));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF64ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS64>(dlgSoftFallbackSatF64ToS64));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF64ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU32>(dlgSoftFallbackSatF64ToU32));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSatF64ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU64>(dlgSoftFallbackSatF64ToU64));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart1>(dlgSoftFallbackSha1SchedulePart1));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart2>(dlgSoftFallbackSha1SchedulePart2));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart1>(dlgSoftFallbackSha256SchedulePart1));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart2>(dlgSoftFallbackSha256SchedulePart2));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackSignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSignedShrImm64>(dlgSoftFallbackSignedShrImm64));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbl1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl1>(dlgSoftFallbackTbl1));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbl2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl2>(dlgSoftFallbackTbl2));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbl3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl3>(dlgSoftFallbackTbl3));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbl4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl4>(dlgSoftFallbackTbl4));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbx1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx1>(dlgSoftFallbackTbx1));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbx2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx2>(dlgSoftFallbackTbx2));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbx3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx3>(dlgSoftFallbackTbx3));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackTbx4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx4>(dlgSoftFallbackTbx4));
|
|
||||||
SetDelegateInfo(dlgSoftFallbackUnsignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackUnsignedShrImm64>(dlgSoftFallbackUnsignedShrImm64));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFloat16_32FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_32FPConvert>(dlgSoftFloat16_32FPConvert));
|
|
||||||
SetDelegateInfo(dlgSoftFloat16_64FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_64FPConvert>(dlgSoftFloat16_64FPConvert));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAdd>(dlgSoftFloat32FPAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAddFpscr>(dlgSoftFloat32FPAddFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompare>(dlgSoftFloat32FPCompare));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQ>(dlgSoftFloat32FPCompareEQ));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQFpscr>(dlgSoftFloat32FPCompareEQFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGE>(dlgSoftFloat32FPCompareGE));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGEFpscr>(dlgSoftFloat32FPCompareGEFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGT>(dlgSoftFloat32FPCompareGT));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGTFpscr>(dlgSoftFloat32FPCompareGTFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLE>(dlgSoftFloat32FPCompareLE));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLEFpscr>(dlgSoftFloat32FPCompareLEFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLT>(dlgSoftFloat32FPCompareLT));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLTFpscr>(dlgSoftFloat32FPCompareLTFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPDiv>(dlgSoftFloat32FPDiv));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMax>(dlgSoftFloat32FPMax));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxFpscr>(dlgSoftFloat32FPMaxFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNum>(dlgSoftFloat32FPMaxNum));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNumFpscr>(dlgSoftFloat32FPMaxNumFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMin>(dlgSoftFloat32FPMin));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinFpscr>(dlgSoftFloat32FPMinFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNum>(dlgSoftFloat32FPMinNum));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNumFpscr>(dlgSoftFloat32FPMinNumFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMul>(dlgSoftFloat32FPMul));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulFpscr>(dlgSoftFloat32FPMulFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAdd>(dlgSoftFloat32FPMulAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAddFpscr>(dlgSoftFloat32FPMulAddFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSub>(dlgSoftFloat32FPMulSub));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSubFpscr>(dlgSoftFloat32FPMulSubFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulX>(dlgSoftFloat32FPMulX));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulAdd>(dlgSoftFloat32FPNegMulAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulSub>(dlgSoftFloat32FPNegMulSub));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimate>(dlgSoftFloat32FPRecipEstimate));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimateFpscr>(dlgSoftFloat32FPRecipEstimateFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStep>(dlgSoftFloat32FPRecipStep)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStepFused>(dlgSoftFloat32FPRecipStepFused));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecpX>(dlgSoftFloat32FPRecpX));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimate>(dlgSoftFloat32FPRSqrtEstimate));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimateFpscr>(dlgSoftFloat32FPRSqrtEstimateFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStep>(dlgSoftFloat32FPRSqrtStep)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStepFused>(dlgSoftFloat32FPRSqrtStepFused));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSqrt>(dlgSoftFloat32FPSqrt));
|
|
||||||
SetDelegateInfo(dlgSoftFloat32FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSub>(dlgSoftFloat32FPSub));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFloat32_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat32_16FPConvert>(dlgSoftFloat32_16FPConvert));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAdd>(dlgSoftFloat64FPAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAddFpscr>(dlgSoftFloat64FPAddFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompare>(dlgSoftFloat64FPCompare));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQ>(dlgSoftFloat64FPCompareEQ));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQFpscr>(dlgSoftFloat64FPCompareEQFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGE>(dlgSoftFloat64FPCompareGE));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGEFpscr>(dlgSoftFloat64FPCompareGEFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGT>(dlgSoftFloat64FPCompareGT));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGTFpscr>(dlgSoftFloat64FPCompareGTFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLE>(dlgSoftFloat64FPCompareLE));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLEFpscr>(dlgSoftFloat64FPCompareLEFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLT>(dlgSoftFloat64FPCompareLT));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLTFpscr>(dlgSoftFloat64FPCompareLTFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPDiv>(dlgSoftFloat64FPDiv));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMax>(dlgSoftFloat64FPMax));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxFpscr>(dlgSoftFloat64FPMaxFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNum>(dlgSoftFloat64FPMaxNum));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNumFpscr>(dlgSoftFloat64FPMaxNumFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMin>(dlgSoftFloat64FPMin));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinFpscr>(dlgSoftFloat64FPMinFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNum>(dlgSoftFloat64FPMinNum));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNumFpscr>(dlgSoftFloat64FPMinNumFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMul>(dlgSoftFloat64FPMul));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulFpscr>(dlgSoftFloat64FPMulFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAdd>(dlgSoftFloat64FPMulAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAddFpscr>(dlgSoftFloat64FPMulAddFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSub>(dlgSoftFloat64FPMulSub));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSubFpscr>(dlgSoftFloat64FPMulSubFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulX>(dlgSoftFloat64FPMulX));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulAdd>(dlgSoftFloat64FPNegMulAdd));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulSub>(dlgSoftFloat64FPNegMulSub));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimate>(dlgSoftFloat64FPRecipEstimate));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimateFpscr>(dlgSoftFloat64FPRecipEstimateFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStep>(dlgSoftFloat64FPRecipStep)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStepFused>(dlgSoftFloat64FPRecipStepFused));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecpX>(dlgSoftFloat64FPRecpX));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimate>(dlgSoftFloat64FPRSqrtEstimate));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimateFpscr>(dlgSoftFloat64FPRSqrtEstimateFpscr)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStep>(dlgSoftFloat64FPRSqrtStep)); // A32 only.
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStepFused>(dlgSoftFloat64FPRSqrtStepFused));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSqrt>(dlgSoftFloat64FPSqrt));
|
|
||||||
SetDelegateInfo(dlgSoftFloat64FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSub>(dlgSoftFloat64FPSub));
|
|
||||||
|
|
||||||
SetDelegateInfo(dlgSoftFloat64_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat64_16FPConvert>(dlgSoftFloat64_16FPConvert));
|
|
||||||
}
|
|
||||||
|
|
||||||
private delegate double MathAbs(double value);
|
|
||||||
private delegate double MathCeiling(double a);
|
|
||||||
private delegate double MathFloor(double d);
|
|
||||||
private delegate double MathRound(double value, MidpointRounding mode);
|
|
||||||
private delegate double MathTruncate(double d);
|
|
||||||
|
|
||||||
private delegate float MathFAbs(float x);
|
|
||||||
private delegate float MathFCeiling(float x);
|
|
||||||
private delegate float MathFFloor(float x);
|
|
||||||
private delegate float MathFRound(float x, MidpointRounding mode);
|
|
||||||
private delegate float MathFTruncate(float x);
|
|
||||||
|
|
||||||
private delegate void NativeInterfaceBreak(ulong address, int imm);
|
|
||||||
private delegate bool NativeInterfaceCheckSynchronization();
|
|
||||||
private delegate void NativeInterfaceEnqueueForRejit(ulong address);
|
|
||||||
private delegate ulong NativeInterfaceGetCntfrqEl0();
|
|
||||||
private delegate ulong NativeInterfaceGetCntpctEl0();
|
|
||||||
private delegate ulong NativeInterfaceGetCntvctEl0();
|
|
||||||
private delegate ulong NativeInterfaceGetCtrEl0();
|
|
||||||
private delegate ulong NativeInterfaceGetDczidEl0();
|
|
||||||
private delegate ulong NativeInterfaceGetFunctionAddress(ulong address);
|
|
||||||
private delegate void NativeInterfaceInvalidateCacheLine(ulong address);
|
|
||||||
private delegate byte NativeInterfaceReadByte(ulong address);
|
|
||||||
private delegate ushort NativeInterfaceReadUInt16(ulong address);
|
|
||||||
private delegate uint NativeInterfaceReadUInt32(ulong address);
|
|
||||||
private delegate ulong NativeInterfaceReadUInt64(ulong address);
|
|
||||||
private delegate V128 NativeInterfaceReadVector128(ulong address);
|
|
||||||
private delegate void NativeInterfaceSignalMemoryTracking(ulong address, ulong size, bool write);
|
|
||||||
private delegate void NativeInterfaceSupervisorCall(ulong address, int imm);
|
|
||||||
private delegate void NativeInterfaceThrowInvalidMemoryAccess(ulong address);
|
|
||||||
private delegate void NativeInterfaceUndefined(ulong address, int opCode);
|
|
||||||
private delegate void NativeInterfaceWriteByte(ulong address, byte value);
|
|
||||||
private delegate void NativeInterfaceWriteUInt16(ulong address, ushort value);
|
|
||||||
private delegate void NativeInterfaceWriteUInt32(ulong address, uint value);
|
|
||||||
private delegate void NativeInterfaceWriteUInt64(ulong address, ulong value);
|
|
||||||
private delegate void NativeInterfaceWriteVector128(ulong address, V128 value);
|
|
||||||
|
|
||||||
private delegate ulong SoftFallbackCountLeadingSigns(ulong value, int size);
|
|
||||||
private delegate ulong SoftFallbackCountLeadingZeros(ulong value, int size);
|
|
||||||
private delegate uint SoftFallbackCrc32b(uint crc, byte value);
|
|
||||||
private delegate uint SoftFallbackCrc32cb(uint crc, byte value);
|
|
||||||
private delegate uint SoftFallbackCrc32ch(uint crc, ushort value);
|
|
||||||
private delegate uint SoftFallbackCrc32cw(uint crc, uint value);
|
|
||||||
private delegate uint SoftFallbackCrc32cx(uint crc, ulong value);
|
|
||||||
private delegate uint SoftFallbackCrc32h(uint crc, ushort value);
|
|
||||||
private delegate uint SoftFallbackCrc32w(uint crc, uint value);
|
|
||||||
private delegate uint SoftFallbackCrc32x(uint crc, ulong value);
|
|
||||||
private delegate V128 SoftFallbackDecrypt(V128 value, V128 roundKey);
|
|
||||||
private delegate V128 SoftFallbackEncrypt(V128 value, V128 roundKey);
|
|
||||||
private delegate uint SoftFallbackFixedRotate(uint hash_e);
|
|
||||||
private delegate V128 SoftFallbackHashChoose(V128 hash_abcd, uint hash_e, V128 wk);
|
|
||||||
private delegate V128 SoftFallbackHashLower(V128 hash_abcd, V128 hash_efgh, V128 wk);
|
|
||||||
private delegate V128 SoftFallbackHashMajority(V128 hash_abcd, uint hash_e, V128 wk);
|
|
||||||
private delegate V128 SoftFallbackHashParity(V128 hash_abcd, uint hash_e, V128 wk);
|
|
||||||
private delegate V128 SoftFallbackHashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk);
|
|
||||||
private delegate V128 SoftFallbackInverseMixColumns(V128 value);
|
|
||||||
private delegate V128 SoftFallbackMixColumns(V128 value);
|
|
||||||
private delegate V128 SoftFallbackPolynomialMult64_128(ulong op1, ulong op2);
|
|
||||||
private delegate int SoftFallbackSatF32ToS32(float value);
|
|
||||||
private delegate long SoftFallbackSatF32ToS64(float value);
|
|
||||||
private delegate uint SoftFallbackSatF32ToU32(float value);
|
|
||||||
private delegate ulong SoftFallbackSatF32ToU64(float value);
|
|
||||||
private delegate int SoftFallbackSatF64ToS32(double value);
|
|
||||||
private delegate long SoftFallbackSatF64ToS64(double value);
|
|
||||||
private delegate uint SoftFallbackSatF64ToU32(double value);
|
|
||||||
private delegate ulong SoftFallbackSatF64ToU64(double value);
|
|
||||||
private delegate V128 SoftFallbackSha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11);
|
|
||||||
private delegate V128 SoftFallbackSha1SchedulePart2(V128 tw0_3, V128 w12_15);
|
|
||||||
private delegate V128 SoftFallbackSha256SchedulePart1(V128 w0_3, V128 w4_7);
|
|
||||||
private delegate V128 SoftFallbackSha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15);
|
|
||||||
private delegate long SoftFallbackSignedShrImm64(long value, long roundConst, int shift);
|
|
||||||
private delegate V128 SoftFallbackTbl1(V128 vector, int bytes, V128 tb0);
|
|
||||||
private delegate V128 SoftFallbackTbl2(V128 vector, int bytes, V128 tb0, V128 tb1);
|
|
||||||
private delegate V128 SoftFallbackTbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
|
|
||||||
private delegate V128 SoftFallbackTbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
|
|
||||||
private delegate V128 SoftFallbackTbx1(V128 dest, V128 vector, int bytes, V128 tb0);
|
|
||||||
private delegate V128 SoftFallbackTbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1);
|
|
||||||
private delegate V128 SoftFallbackTbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
|
|
||||||
private delegate V128 SoftFallbackTbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
|
|
||||||
private delegate ulong SoftFallbackUnsignedShrImm64(ulong value, long roundConst, int shift);
|
|
||||||
|
|
||||||
private delegate float SoftFloat16_32FPConvert(ushort valueBits);
|
|
||||||
|
|
||||||
private delegate double SoftFloat16_64FPConvert(ushort valueBits);
|
|
||||||
|
|
||||||
private delegate float SoftFloat32FPAdd(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPAddFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate int SoftFloat32FPCompare(float value1, float value2, bool signalNaNs);
|
|
||||||
private delegate float SoftFloat32FPCompareEQ(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPCompareEQFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPCompareGE(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPCompareGEFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPCompareGT(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPCompareGTFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPCompareLE(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPCompareLEFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPCompareLT(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPCompareLTFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPDiv(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMax(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMaxFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMaxNum(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMaxNumFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMin(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMinFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMinNum(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMinNumFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMul(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMulFpscr(float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMulAdd(float valueA, float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMulSub(float valueA, float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPMulX(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPNegMulAdd(float valueA, float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPNegMulSub(float valueA, float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPRecipEstimate(float value);
|
|
||||||
private delegate float SoftFloat32FPRecipEstimateFpscr(float value, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPRecipStep(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPRecipStepFused(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPRecpX(float value);
|
|
||||||
private delegate float SoftFloat32FPRSqrtEstimate(float value);
|
|
||||||
private delegate float SoftFloat32FPRSqrtEstimateFpscr(float value, bool standardFpscr);
|
|
||||||
private delegate float SoftFloat32FPRSqrtStep(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPRSqrtStepFused(float value1, float value2);
|
|
||||||
private delegate float SoftFloat32FPSqrt(float value);
|
|
||||||
private delegate float SoftFloat32FPSub(float value1, float value2);
|
|
||||||
|
|
||||||
private delegate ushort SoftFloat32_16FPConvert(float value);
|
|
||||||
|
|
||||||
private delegate double SoftFloat64FPAdd(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPAddFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate int SoftFloat64FPCompare(double value1, double value2, bool signalNaNs);
|
|
||||||
private delegate double SoftFloat64FPCompareEQ(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPCompareEQFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPCompareGE(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPCompareGEFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPCompareGT(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPCompareGTFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPCompareLE(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPCompareLEFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPCompareLT(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPCompareLTFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPDiv(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMax(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMaxFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMaxNum(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMaxNumFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMin(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMinFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMinNum(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMinNumFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMul(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMulFpscr(double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMulAdd(double valueA, double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMulSub(double valueA, double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPMulX(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPNegMulAdd(double valueA, double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPNegMulSub(double valueA, double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPRecipEstimate(double value);
|
|
||||||
private delegate double SoftFloat64FPRecipEstimateFpscr(double value, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPRecipStep(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPRecipStepFused(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPRecpX(double value);
|
|
||||||
private delegate double SoftFloat64FPRSqrtEstimate(double value);
|
|
||||||
private delegate double SoftFloat64FPRSqrtEstimateFpscr(double value, bool standardFpscr);
|
|
||||||
private delegate double SoftFloat64FPRSqrtStep(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPRSqrtStepFused(double value1, double value2);
|
|
||||||
private delegate double SoftFloat64FPSqrt(double value);
|
|
||||||
private delegate double SoftFloat64FPSub(double value1, double value2);
|
|
||||||
|
|
||||||
private delegate ushort SoftFloat64_16FPConvert(double value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public virtual Operand Call(MethodInfo info, params Operand[] callArgs)
|
public virtual Operand Call(MethodInfo info, params Operand[] callArgs)
|
||||||
{
|
{
|
||||||
nint funcPtr = Delegates.GetDelegateFuncPtr(info);
|
nint funcPtr = info.MethodHandle.GetFunctionPointer();
|
||||||
|
|
||||||
OperandType returnType = GetOperandType(info.ReturnType);
|
OperandType returnType = GetOperandType(info.ReturnType);
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 6997; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 6998; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
@ -9,20 +9,12 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
{
|
{
|
||||||
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent = new(false);
|
||||||
private readonly ManualResetEvent _pauseEvent;
|
private readonly ManualResetEvent _pauseEvent = new(true);
|
||||||
|
|
||||||
public static bool IsSupported => true;
|
public static bool IsSupported => true;
|
||||||
|
|
||||||
public float Volume { get; set; }
|
public float Volume { get; set; } = 1f;
|
||||||
|
|
||||||
public DummyHardwareDeviceDriver()
|
|
||||||
{
|
|
||||||
_updateRequiredEvent = new ManualResetEvent(false);
|
|
||||||
_pauseEvent = new ManualResetEvent(true);
|
|
||||||
|
|
||||||
Volume = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
||||||
{
|
{
|
||||||
@ -60,7 +52,7 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
private void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
7
src/Ryujinx.BuildValidationTasks/IValidationTask.cs
Normal file
7
src/Ryujinx.BuildValidationTasks/IValidationTask.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Ryujinx.BuildValidationTasks
|
||||||
|
{
|
||||||
|
public interface IValidationTask
|
||||||
|
{
|
||||||
|
public bool Execute(string projectPath, bool isGitRunner);
|
||||||
|
}
|
||||||
|
}
|
@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.Build.Utilities;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Microsoft.Build.Framework;
|
|
||||||
|
|
||||||
namespace Ryujinx.BuildValidationTasks
|
|
||||||
{
|
|
||||||
public class LocaleValidationTask : Task
|
|
||||||
{
|
|
||||||
public override bool Execute()
|
|
||||||
{
|
|
||||||
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
|
||||||
|
|
||||||
if (path.Split(["src"], StringSplitOptions.None).Length == 1)
|
|
||||||
{
|
|
||||||
//i assume that we are in a build directory in the solution dir
|
|
||||||
path = new FileInfo(path).Directory!.Parent!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = path.Split(["src"], StringSplitOptions.None)[0];
|
|
||||||
path = new FileInfo(path).Directory!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
string data;
|
|
||||||
|
|
||||||
using (StreamReader sr = new(path))
|
|
||||||
{
|
|
||||||
data = sr.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalesJson json = JsonConvert.DeserializeObject<LocalesJson>(data);
|
|
||||||
|
|
||||||
for (int i = 0; i < json.Locales.Count; i++)
|
|
||||||
{
|
|
||||||
LocalesEntry locale = json.Locales[i];
|
|
||||||
|
|
||||||
foreach (string langCode in json.Languages.Where(it => !locale.Translations.ContainsKey(it)))
|
|
||||||
{
|
|
||||||
locale.Translations.Add(langCode, string.Empty);
|
|
||||||
Log.LogMessage(MessageImportance.High, $"Added '{langCode}' to Locale '{locale.ID}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
|
||||||
json.Locales[i] = locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented);
|
|
||||||
|
|
||||||
using (StreamWriter sw = new(path))
|
|
||||||
{
|
|
||||||
sw.Write(jsonString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocalesJson
|
|
||||||
{
|
|
||||||
public List<string> Languages { get; set; }
|
|
||||||
public List<LocalesEntry> Locales { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocalesEntry
|
|
||||||
{
|
|
||||||
public string ID { get; set; }
|
|
||||||
public Dictionary<string, string> Translations { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
|
||||||
|
namespace Ryujinx.BuildValidationTasks
|
||||||
|
{
|
||||||
|
public class LocalesValidationTask : IValidationTask
|
||||||
|
{
|
||||||
|
public LocalesValidationTask() { }
|
||||||
|
|
||||||
|
public bool Execute(string projectPath, bool isGitRunner)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Running Locale Validation Task...");
|
||||||
|
|
||||||
|
string path = projectPath + "src/Ryujinx/Assets/locales.json";
|
||||||
|
string data;
|
||||||
|
|
||||||
|
using (StreamReader sr = new(path))
|
||||||
|
{
|
||||||
|
data = sr.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalesJson json;
|
||||||
|
|
||||||
|
if (isGitRunner && data.Contains("\r\n"))
|
||||||
|
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
json = JsonSerializer.Deserialize<LocalesJson>(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (JsonException e)
|
||||||
|
{
|
||||||
|
throw new JsonException(e.Message); //shorter and easier stacktrace
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool encounteredIssue = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < json.Locales.Count; i++)
|
||||||
|
{
|
||||||
|
LocalesEntry locale = json.Locales[i];
|
||||||
|
|
||||||
|
foreach (string langCode in json.Languages.Where(lang => !locale.Translations.ContainsKey(lang)))
|
||||||
|
{
|
||||||
|
encounteredIssue = true;
|
||||||
|
|
||||||
|
if (!isGitRunner)
|
||||||
|
{
|
||||||
|
locale.Translations.Add(langCode, string.Empty);
|
||||||
|
Console.WriteLine($"Added '{langCode}' to Locale '{locale.ID}'");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Missing '{langCode}' in Locale '{locale.ID}'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string langCode in json.Languages.Where(lang => locale.Translations.ContainsKey(lang) && lang != "en_US" && locale.Translations[lang] == locale.Translations["en_US"]))
|
||||||
|
{
|
||||||
|
encounteredIssue = true;
|
||||||
|
|
||||||
|
if (!isGitRunner)
|
||||||
|
{
|
||||||
|
locale.Translations[langCode] = string.Empty;
|
||||||
|
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'! Resetting it...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
|
json.Locales[i] = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGitRunner && encounteredIssue)
|
||||||
|
throw new JsonException("1 or more locales are invalid!");
|
||||||
|
|
||||||
|
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
|
||||||
|
{
|
||||||
|
WriteIndented = true,
|
||||||
|
NewLine = "\n",
|
||||||
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||||
|
};
|
||||||
|
|
||||||
|
string jsonString = JsonSerializer.Serialize(json, jsonOptions);
|
||||||
|
|
||||||
|
using (StreamWriter sw = new(path))
|
||||||
|
{
|
||||||
|
sw.Write(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Finished Locale Validation Task!");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesJson
|
||||||
|
{
|
||||||
|
public List<string> Languages { get; set; }
|
||||||
|
public List<LocalesEntry> Locales { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesEntry
|
||||||
|
{
|
||||||
|
public string ID { get; set; }
|
||||||
|
public Dictionary<string, string> Translations { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
37
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.BuildValidationTasks
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Display the number of command line arguments.
|
||||||
|
if (args.Length == 0)
|
||||||
|
throw new ArgumentException("Error: too few arguments!");
|
||||||
|
|
||||||
|
string path = args[0];
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
throw new ArgumentException("Error: path is null or empty!");
|
||||||
|
|
||||||
|
if (!Path.Exists(path))
|
||||||
|
throw new FileLoadException($"path {{{path}}} does not exist!");
|
||||||
|
|
||||||
|
path = Path.GetFullPath(path);
|
||||||
|
|
||||||
|
if (!Directory.GetDirectories(path).Contains($"{path}src"))
|
||||||
|
throw new FileLoadException($"path {{{path}}} is not a valid ryujinx project!");
|
||||||
|
|
||||||
|
bool isGitRunner = path.Contains("runner") || path.Contains("D:\\a\\Ryujinx\\Ryujinx");
|
||||||
|
if (isGitRunner)
|
||||||
|
Console.WriteLine("Is Git Runner!");
|
||||||
|
|
||||||
|
// Run tasks
|
||||||
|
// Pass extra info needed in the task constructors
|
||||||
|
new LocalesValidationTask().Execute(path, isGitRunner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,17 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<OutputType>Exe</OutputType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
|
||||||
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
<Message Text="Running Validation Project" Importance="high" />
|
||||||
<PackageReference Include="Newtonsoft.Json" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<UsingTask TaskName="Ryujinx.BuildValidationTasks.LocaleValidationTask" TaskFactory="TaskHostFactory" AssemblyFile="$(OutDir)Ryujinx.BuildValidationTasks.dll" />
|
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||||
|
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||||
<Target Name="LocalesJsonValidation" AfterTargets="AfterRebuild">
|
ConsoleToMsBuild="true"
|
||||||
<LocaleValidationTask />
|
Condition="'$(RuntimeIdentifier)' == ''"
|
||||||
|
/>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
@ -1,35 +0,0 @@
|
|||||||
namespace Ryujinx.Common
|
|
||||||
{
|
|
||||||
public class BitTricks
|
|
||||||
{
|
|
||||||
// Never actually written bit packing logic before, so I looked it up.
|
|
||||||
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
|
||||||
|
|
||||||
public static ulong PackBitFields(uint[] values, byte[] bitFields)
|
|
||||||
{
|
|
||||||
ulong retVal = values[0]; //we set the first value right away
|
|
||||||
for (int f = 1; f < values.Length; f++)
|
|
||||||
{
|
|
||||||
retVal <<= bitFields[f]; // we shift the previous value
|
|
||||||
retVal += values[f];// and add our current value
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint[] UnpackBitFields(ulong packed, byte[] bitFields)
|
|
||||||
{
|
|
||||||
int fields = bitFields.Length - 1; // number of fields to unpack
|
|
||||||
uint[] retArr = new uint[fields + 1]; // init return array
|
|
||||||
int curPos = 0; // current field bit position (start)
|
|
||||||
int lastEnd; // position where last field ended
|
|
||||||
for (int f = fields; f >= 0; f--) // loop from last
|
|
||||||
{
|
|
||||||
lastEnd = curPos; // we store where the last value ended
|
|
||||||
curPos += bitFields[f]; // we get where the current value starts
|
|
||||||
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
|
||||||
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
|
||||||
}
|
|
||||||
return retArr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
60
src/Ryujinx.Common/Configuration/DirtyHack.cs
Normal file
60
src/Ryujinx.Common/Configuration/DirtyHack.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using Gommon;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum DirtyHack : byte
|
||||||
|
{
|
||||||
|
Xc2MenuSoftlockFix = 1,
|
||||||
|
ShaderTranslationDelay = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
||||||
|
{
|
||||||
|
public DirtyHack Hack => hack;
|
||||||
|
public int Value => value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ulong Pack() => Raw.PackBitFields(PackedFormat);
|
||||||
|
|
||||||
|
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||||
|
{
|
||||||
|
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
|
||||||
|
if (unpackedFields is not [var hack, var value])
|
||||||
|
throw new Exception("The unpack operation on the integer resulted in an invalid unpacked result.");
|
||||||
|
|
||||||
|
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
|
||||||
|
|
||||||
|
public static readonly byte[] PackedFormat = [8, 32];
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DirtyHacks : Dictionary<DirtyHack, int>
|
||||||
|
{
|
||||||
|
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
|
||||||
|
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
|
||||||
|
|
||||||
|
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
|
||||||
|
|
||||||
|
public ulong[] PackEntries()
|
||||||
|
=> Entries.Select(it => it.Pack()).ToArray();
|
||||||
|
|
||||||
|
public EnabledDirtyHack[] Entries
|
||||||
|
=> this
|
||||||
|
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
||||||
|
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
||||||
|
|
||||||
|
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||||
|
|
||||||
|
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
||||||
|
}
|
||||||
|
}
|
@ -1,52 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Configuration
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum DirtyHacks : byte
|
|
||||||
{
|
|
||||||
Xc2MenuSoftlockFix = 1,
|
|
||||||
ShaderCompilationThreadSleep = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
public record EnabledDirtyHack(DirtyHacks Hack, int Value)
|
|
||||||
{
|
|
||||||
private static readonly byte[] _packedFormat = [8, 32];
|
|
||||||
|
|
||||||
public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], _packedFormat);
|
|
||||||
|
|
||||||
public static EnabledDirtyHack FromPacked(ulong packedHack)
|
|
||||||
{
|
|
||||||
var unpackedFields = BitTricks.UnpackBitFields(packedHack, _packedFormat);
|
|
||||||
if (unpackedFields is not [var hack, var value])
|
|
||||||
throw new ArgumentException(nameof(packedHack));
|
|
||||||
|
|
||||||
return new EnabledDirtyHack((DirtyHacks)hack, (int)value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DirtyHackCollection : Dictionary<DirtyHacks, int>
|
|
||||||
{
|
|
||||||
public DirtyHackCollection(EnabledDirtyHack[] hacks)
|
|
||||||
{
|
|
||||||
foreach ((DirtyHacks dirtyHacks, int value) in hacks)
|
|
||||||
{
|
|
||||||
Add(dirtyHacks, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DirtyHackCollection(ulong[] packedHacks)
|
|
||||||
{
|
|
||||||
foreach ((DirtyHacks dirtyHacks, int value) in packedHacks.Select(EnabledDirtyHack.FromPacked))
|
|
||||||
{
|
|
||||||
Add(dirtyHacks, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public new int this[DirtyHacks hack] => TryGetValue(hack, out var value) ? value : -1;
|
|
||||||
|
|
||||||
public bool IsEnabled(DirtyHacks hack) => ContainsKey(hack);
|
|
||||||
}
|
|
||||||
}
|
|
@ -53,6 +53,9 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
|
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
|
||||||
{
|
{
|
||||||
|
if (eventArgs.AreValuesEqual)
|
||||||
|
return;
|
||||||
|
|
||||||
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
|
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
|
||||||
|
|
||||||
Logger.Info?.Print(logClass, message);
|
Logger.Info?.Print(logClass, message);
|
||||||
@ -65,5 +68,22 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public T OldValue { get; } = oldValue;
|
public T OldValue { get; } = oldValue;
|
||||||
public T NewValue { get; } = newValue;
|
public T NewValue { get; } = newValue;
|
||||||
|
|
||||||
|
public bool AreValuesEqual
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (OldValue == null && NewValue == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (OldValue == null && NewValue != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (OldValue != null && NewValue == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return OldValue!.Equals(NewValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,8 @@ namespace Ryujinx.Common
|
|||||||
"010028600EBDA000", // Mario 3D World
|
"010028600EBDA000", // Mario 3D World
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
"01005CA01580E000", // Persona 5
|
"01005CA01580E000", // Persona 5
|
||||||
"01001f5010dfa000", // Pokemon Legends Arceus
|
"0100187003A36000", // Pokémon: Let's Go, Evoli!
|
||||||
|
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
|
||||||
"01008C0016544000", // Sea of Stars
|
"01008C0016544000", // Sea of Stars
|
||||||
"01006A800016E000", // Smash Ultimate
|
"01006A800016E000", // Smash Ultimate
|
||||||
"0100000000010000", // Super Mario Odyessy
|
"0100000000010000", // Super Mario Odyessy
|
||||||
@ -170,6 +171,7 @@ namespace Ryujinx.Common
|
|||||||
"0100b41013c82000", // Cruis'n Blast
|
"0100b41013c82000", // Cruis'n Blast
|
||||||
"01001b300b9be000", // Diablo III: Eternal Collection
|
"01001b300b9be000", // Diablo III: Eternal Collection
|
||||||
"01008c8012920000", // Dying Light Platinum Edition
|
"01008c8012920000", // Dying Light Platinum Edition
|
||||||
|
"01001cc01b2d4000", // Goat Simulator 3
|
||||||
"010073c01af34000", // LEGO Horizon Adventures
|
"010073c01af34000", // LEGO Horizon Adventures
|
||||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||||
"0100b04011742000", // Monster Hunter Rise
|
"0100b04011742000", // Monster Hunter Rise
|
||||||
|
@ -40,5 +40,35 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
return (value >> 32) | (value << 32);
|
return (value >> 32) | (value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Never actually written bit packing logic before, so I looked it up.
|
||||||
|
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
||||||
|
|
||||||
|
public static ulong PackBitFields(this uint[] values, byte[] bitFields)
|
||||||
|
{
|
||||||
|
ulong retVal = values[0]; //we set the first value right away
|
||||||
|
for (int f = 1; f < values.Length; f++)
|
||||||
|
{
|
||||||
|
retVal <<= bitFields[f]; // we shift the previous value
|
||||||
|
retVal += values[f];// and add our current value
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields)
|
||||||
|
{
|
||||||
|
int fields = bitFields.Length - 1; // number of fields to unpack
|
||||||
|
uint[] retArr = new uint[fields + 1]; // init return array
|
||||||
|
int curPos = 0; // current field bit position (start)
|
||||||
|
int lastEnd; // position where last field ended
|
||||||
|
for (int f = fields; f >= 0; f--) // loop from last
|
||||||
|
{
|
||||||
|
lastEnd = curPos; // we store where the last value ended
|
||||||
|
curPos += bitFields[f]; // we get where the current value starts
|
||||||
|
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
||||||
|
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
||||||
|
}
|
||||||
|
return retArr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,11 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||||
|
|
||||||
internal DirtyHackCollection DirtyHacks { get; }
|
/// <summary>
|
||||||
|
/// Enabled dirty hacks.
|
||||||
|
/// Used for workarounds to emulator bugs we can't fix/don't know how to fix yet.
|
||||||
|
/// </summary>
|
||||||
|
internal DirtyHacks DirtyHacks { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -117,7 +121,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Creates a new instance of the GPU emulation context.
|
/// Creates a new instance of the GPU emulation context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="renderer">Host renderer</param>
|
/// <param name="renderer">Host renderer</param>
|
||||||
public GpuContext(IRenderer renderer, DirtyHackCollection hackCollection)
|
public GpuContext(IRenderer renderer, DirtyHacks hacks)
|
||||||
{
|
{
|
||||||
Renderer = renderer;
|
Renderer = renderer;
|
||||||
|
|
||||||
@ -140,7 +144,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
|
|
||||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||||
|
|
||||||
DirtyHacks = hackCollection;
|
DirtyHacks = hacks;
|
||||||
|
|
||||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
@ -366,6 +367,9 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
||||||
|
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
||||||
|
|
||||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -168,14 +168,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return BinarySearch(list, offset, size) >= 0;
|
return BinarySearch(list, offset, size) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly IEnumerable<Range> FindOverlaps(int offset, int size)
|
public readonly List<Range> FindOverlaps(int offset, int size)
|
||||||
{
|
{
|
||||||
var list = _ranges;
|
var list = _ranges;
|
||||||
if (list == null)
|
if (list == null)
|
||||||
{
|
{
|
||||||
yield break;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Range> result = null;
|
||||||
|
|
||||||
int index = BinarySearch(list, offset, size);
|
int index = BinarySearch(list, offset, size);
|
||||||
|
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
@ -187,10 +189,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
yield return list[index++];
|
(result ??= []).Add(list[index++]);
|
||||||
}
|
}
|
||||||
while (index < list.Count && list[index].OverlapsWith(offset, size));
|
while (index < list.Count && list[index].OverlapsWith(offset, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int BinarySearch(List<Range> list, int offset, int size)
|
private static int BinarySearch(List<Range> list, int offset, int size)
|
||||||
|
@ -16,7 +16,9 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string Xc2TitleId = "0100e95004038000";
|
private const string Xc2JpTitleId = "0100f3400332c000";
|
||||||
|
private const string Xc2GlobalTitleId = "0100e95004038000";
|
||||||
|
private static bool IsXc2 => TitleIDs.CurrentApplication.Value.OrDefault() is Xc2GlobalTitleId or Xc2JpTitleId;
|
||||||
|
|
||||||
[CommandCmif(0)]
|
[CommandCmif(0)]
|
||||||
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
||||||
@ -39,7 +41,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
||||||
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
||||||
|
|
||||||
if (context.Device.DirtyHacks.IsEnabled(DirtyHacks.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
|
if (context.Device.DirtyHacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix) && IsXc2)
|
||||||
{
|
{
|
||||||
// Add a load-bearing sleep to avoid XC2 softlock
|
// Add a load-bearing sleep to avoid XC2 softlock
|
||||||
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357
|
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357
|
||||||
|
@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string usedCharacterStr = BitConverter.ToString(usedCharacter).Replace("-", "");
|
string usedCharacterStr = Convert.ToHexString(usedCharacter);
|
||||||
string variationStr = BitConverter.ToString(variation).Replace("-", "");
|
string variationStr = Convert.ToHexString(variation);
|
||||||
string amiiboIDStr = BitConverter.ToString(amiiboID).Replace("-", "");
|
string amiiboIDStr = Convert.ToHexString(amiiboID);
|
||||||
string setIDStr = BitConverter.ToString(setID).Replace("-", "");
|
string setIDStr = Convert.ToHexString(setID);
|
||||||
string head = usedCharacterStr + variationStr;
|
string head = usedCharacterStr + variationStr;
|
||||||
string tail = amiiboIDStr + setIDStr + "02";
|
string tail = amiiboIDStr + setIDStr + "02";
|
||||||
string finalID = head + tail;
|
string finalID = head + tail;
|
||||||
@ -289,8 +289,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
|
|||||||
|
|
||||||
private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas)
|
private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas)
|
||||||
{
|
{
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{BitConverter.ToString(titleId).Replace("-", "")}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{Convert.ToHexString(titleId)}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{BitConverter.ToString(appId).Replace("-", "")}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{Convert.ToHexString(appId)}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}");
|
||||||
|
@ -40,7 +40,7 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
||||||
|
|
||||||
public DirtyHackCollection DirtyHacks { get; }
|
public DirtyHacks DirtyHacks { get; }
|
||||||
|
|
||||||
public Switch(HLEConfiguration configuration)
|
public Switch(HLEConfiguration configuration)
|
||||||
{
|
{
|
||||||
@ -57,7 +57,7 @@ namespace Ryujinx.HLE
|
|||||||
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
||||||
|
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
DirtyHacks = new DirtyHackCollection(Configuration.Hacks);
|
DirtyHacks = new DirtyHacks(Configuration.Hacks);
|
||||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
||||||
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
||||||
|
@ -19,7 +19,7 @@ namespace Ryujinx.UI.LocaleGenerator
|
|||||||
|
|
||||||
StringBuilder enumSourceBuilder = new();
|
StringBuilder enumSourceBuilder = new();
|
||||||
enumSourceBuilder.AppendLine("namespace Ryujinx.Ava.Common.Locale;");
|
enumSourceBuilder.AppendLine("namespace Ryujinx.Ava.Common.Locale;");
|
||||||
enumSourceBuilder.AppendLine("internal enum LocaleKeys");
|
enumSourceBuilder.AppendLine("public enum LocaleKeys");
|
||||||
enumSourceBuilder.AppendLine("{");
|
enumSourceBuilder.AppendLine("{");
|
||||||
foreach (var line in lines)
|
foreach (var line in lines)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,6 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Gommon;
|
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
@ -43,7 +42,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using SPB.Graphics.Vulkan;
|
using SPB.Graphics.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
@ -314,7 +312,7 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
_renderer.Window?.ChangeVSyncMode(e.NewValue);
|
_renderer.Window?.ChangeVSyncMode(e.NewValue);
|
||||||
|
|
||||||
_viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
|
_viewModel.UpdateVSyncIntervalPicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void VSyncModeToggle()
|
public void VSyncModeToggle()
|
||||||
|
10
src/Ryujinx/Assets/Fonts/Mono/AUTHORS.txt
Normal file
10
src/Ryujinx/Assets/Fonts/Mono/AUTHORS.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This is the official list of project authors for copyright purposes.
|
||||||
|
# This file is distinct from the CONTRIBUTORS.txt file.
|
||||||
|
# See the latter for an explanation.
|
||||||
|
#
|
||||||
|
# Names should be added to this file as:
|
||||||
|
# Name or Organization <email address>
|
||||||
|
|
||||||
|
JetBrains <>
|
||||||
|
Philipp Nurullin <philipp.nurullin@jetbrains.com>
|
||||||
|
Konstantin Bulenkov <kb@jetbrains.com>
|
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Bold.ttf
Normal file
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Bold.ttf
Normal file
Binary file not shown.
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-BoldItalic.ttf
Normal file
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Italic.ttf
Normal file
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Italic.ttf
Normal file
Binary file not shown.
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Regular.ttf
Normal file
BIN
src/Ryujinx/Assets/Fonts/Mono/JetBrainsMonoNL-Regular.ttf
Normal file
Binary file not shown.
93
src/Ryujinx/Assets/Fonts/Mono/OFL.txt
Normal file
93
src/Ryujinx/Assets/Fonts/Mono/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
@ -402,7 +402,7 @@
|
|||||||
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
|
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
|
||||||
<x:Double x:Key="MenuItemHeight">26</x:Double>
|
<x:Double x:Key="MenuItemHeight">26</x:Double>
|
||||||
<x:Double x:Key="TabItemMinHeight">28</x:Double>
|
<x:Double x:Key="TabItemMinHeight">28</x:Double>
|
||||||
<x:Double x:Key="ContentDialogMaxWidth">700</x:Double>
|
<x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
|
||||||
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
|
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -52,7 +52,7 @@ namespace Ryujinx.Headless
|
|||||||
// Make process DPI aware for proper window sizing on high-res screens.
|
// Make process DPI aware for proper window sizing on high-res screens.
|
||||||
ForceDpiAware.Windows();
|
ForceDpiAware.Windows();
|
||||||
|
|
||||||
Console.Title = $"Ryujinx Console {Program.Version} (Headless)";
|
Console.Title = $"HeadlessRyujinx Console {Program.Version}";
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@ -163,6 +163,11 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
ReloadConfig();
|
ReloadConfig();
|
||||||
|
|
||||||
|
if (option.InheritConfig)
|
||||||
|
{
|
||||||
|
option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
||||||
_libHacHorizonManager = new LibHacHorizonManager();
|
_libHacHorizonManager = new LibHacHorizonManager();
|
||||||
|
|
||||||
@ -224,15 +229,7 @@ namespace Ryujinx.Headless
|
|||||||
_enableKeyboard = option.EnableKeyboard;
|
_enableKeyboard = option.EnableKeyboard;
|
||||||
_enableMouse = option.EnableMouse;
|
_enableMouse = option.EnableMouse;
|
||||||
|
|
||||||
static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
|
||||||
{
|
|
||||||
InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index);
|
|
||||||
|
|
||||||
if (inputConfig != null)
|
|
||||||
{
|
|
||||||
_inputConfiguration.Add(inputConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
|
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
|
||||||
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
|
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
|
||||||
@ -244,7 +241,6 @@ namespace Ryujinx.Headless
|
|||||||
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
||||||
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
||||||
|
|
||||||
|
|
||||||
if (_inputConfiguration.Count == 0)
|
if (_inputConfiguration.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -306,6 +302,24 @@ namespace Ryujinx.Headless
|
|||||||
}
|
}
|
||||||
|
|
||||||
_inputManager.Dispose();
|
_inputManager.Dispose();
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
||||||
|
{
|
||||||
|
if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0)
|
||||||
|
{
|
||||||
|
Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index);
|
||||||
|
|
||||||
|
if (inputConfig != null)
|
||||||
|
{
|
||||||
|
_inputConfiguration.Add(inputConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupProgressHandler()
|
private static void SetupProgressHandler()
|
||||||
|
@ -154,11 +154,38 @@ namespace Ryujinx.Headless
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
||||||
|
|
||||||
string OptionName(string propertyName) =>
|
|
||||||
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InheritMainConfigInput(string[] originalArgs, ConfigurationState configurationState)
|
||||||
|
{
|
||||||
|
Dictionary<PlayerIndex, (string InputId, string InputProfileName)> indicesToProperties = new()
|
||||||
|
{
|
||||||
|
{ PlayerIndex.Handheld, (nameof(InputIdHandheld), nameof(InputProfileHandheldName)) },
|
||||||
|
{ PlayerIndex.Player1, (nameof(InputId1), nameof(InputProfile1Name)) },
|
||||||
|
{ PlayerIndex.Player2, (nameof(InputId2), nameof(InputProfile2Name)) },
|
||||||
|
{ PlayerIndex.Player3, (nameof(InputId3), nameof(InputProfile3Name)) },
|
||||||
|
{ PlayerIndex.Player4, (nameof(InputId4), nameof(InputProfile4Name)) },
|
||||||
|
{ PlayerIndex.Player5, (nameof(InputId5), nameof(InputProfile5Name)) },
|
||||||
|
{ PlayerIndex.Player6, (nameof(InputId6), nameof(InputProfile6Name)) },
|
||||||
|
{ PlayerIndex.Player7, (nameof(InputId7), nameof(InputProfile7Name)) },
|
||||||
|
{ PlayerIndex.Player8, (nameof(InputId8), nameof(InputProfile8Name)) }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach ((PlayerIndex playerIndex, _) in indicesToProperties
|
||||||
|
.Where(it => NeedsOverride(it.Value.InputId) && NeedsOverride(it.Value.InputProfileName)))
|
||||||
|
{
|
||||||
|
configurationState.Hid.InputConfig.Value.FindFirst(x => x.PlayerIndex == playerIndex)
|
||||||
|
.IfPresent(ic => InheritedInputConfigs[playerIndex] = ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string OptionName(string propertyName) =>
|
||||||
|
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
|
||||||
|
|
||||||
// General
|
// General
|
||||||
|
|
||||||
[Option("use-main-config", Required = false, Default = false, HelpText = "Use the settings from what was configured via the UI.")]
|
[Option("use-main-config", Required = false, Default = false, HelpText = "Use the settings from what was configured via the UI.")]
|
||||||
@ -391,5 +418,7 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]
|
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]
|
||||||
public string InputPath { get; set; }
|
public string InputPath { get; set; }
|
||||||
|
|
||||||
|
public SafeDictionary<PlayerIndex, InputConfig> InheritedInputConfigs = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="BuildValidationProj" BeforeTargets="BeforeRebuild">
|
<Target Name="BuildValidationProj" BeforeTargets="BeforeBuild">
|
||||||
<MSBuild Projects="..\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj" Targets="Rebuild">
|
<Message Text="Building Validation Project for $(TargetFramework)" Importance="high" Condition="'$(RuntimeIdentifier)' == ''" />
|
||||||
</MSBuild>
|
<Exec WorkingDirectory="..\Ryujinx.BuildValidationTasks\" Command="dotnet build -c Debug /clp:NoSummary" />
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
|
||||||
@ -48,6 +49,7 @@
|
|||||||
<PackageReference Include="Avalonia.Svg" />
|
<PackageReference Include="Avalonia.Svg" />
|
||||||
<PackageReference Include="Avalonia.Svg.Skia" />
|
<PackageReference Include="Avalonia.Svg.Skia" />
|
||||||
<PackageReference Include="CommandLineParser" />
|
<PackageReference Include="CommandLineParser" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||||
<PackageReference Include="DiscordRichPresence" />
|
<PackageReference Include="DiscordRichPresence" />
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" />
|
<PackageReference Include="FluentAvaloniaUI" />
|
||||||
@ -59,6 +61,7 @@
|
|||||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
||||||
<PackageReference Include="securifybv.ShellLink" />
|
<PackageReference Include="securifybv.ShellLink" />
|
||||||
|
<PackageReference Include="Sep" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan" />
|
<PackageReference Include="Silk.NET.Vulkan" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
||||||
@ -111,6 +114,10 @@
|
|||||||
<AvaloniaResource Include="UI\**\*.xaml">
|
<AvaloniaResource Include="UI\**\*.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
|
<AvaloniaResource Include="Assets\Fonts\Mono\JetBrainsMonoNL-Bold.ttf" />
|
||||||
|
<AvaloniaResource Include="Assets\Fonts\Mono\JetBrainsMonoNL-BoldItalic.ttf" />
|
||||||
|
<AvaloniaResource Include="Assets\Fonts\Mono\JetBrainsMonoNL-Italic.ttf" />
|
||||||
|
<AvaloniaResource Include="Assets\Fonts\Mono\JetBrainsMonoNL-Regular.ttf" />
|
||||||
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
|
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
|
||||||
<AvaloniaResource Include="Assets\Styles\Themes.xaml">
|
<AvaloniaResource Include="Assets\Styles\Themes.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@ -138,6 +145,9 @@
|
|||||||
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist">
|
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist">
|
||||||
<Link>Assets\ShortcutFiles\shortcut-template.plist</Link>
|
<Link>Assets\ShortcutFiles\shortcut-template.plist</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="..\..\docs\compatibility.csv" LogicalName="RyujinxGameCompatibilityList">
|
||||||
|
<Link>Assets\RyujinxGameCompatibility.csv</Link>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Assets\locales.json" />
|
<EmbeddedResource Include="Assets\locales.json" />
|
||||||
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
||||||
@ -161,4 +171,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="Assets\locales.json" />
|
<AdditionalFiles Include="Assets\locales.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Assets\Fonts\Mono\" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,6 +6,9 @@
|
|||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<FontFamily x:Key="JetBrainsMono">avares://Ryujinx/Assets/Fonts/Mono/#JetBrains Mono</FontFamily>
|
||||||
|
</ResourceDictionary>
|
||||||
<MergeResourceInclude Source="/Assets/Styles/Themes.xaml"/>
|
<MergeResourceInclude Source="/Assets/Styles/Themes.xaml"/>
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
x:DataType="viewModels:MainWindowViewModel">
|
x:DataType="viewModels:MainWindowViewModel">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||||
<controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
@ -26,10 +25,10 @@
|
|||||||
Padding="8"
|
Padding="8"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
ContextFlyout="{StaticResource ApplicationContextMenu}"
|
SelectedItem="{Binding GridSelectedApplication}"
|
||||||
|
ContextFlyout="{Binding GridAppContextMenu}"
|
||||||
DoubleTapped="GameList_DoubleTapped"
|
DoubleTapped="GameList_DoubleTapped"
|
||||||
ItemsSource="{Binding AppsObservableList}"
|
ItemsSource="{Binding AppsObservableList}">
|
||||||
SelectionChanged="GameList_SelectionChanged">
|
|
||||||
<ListBox.ItemsPanel>
|
<ListBox.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<WrapPanel
|
<WrapPanel
|
||||||
|
@ -26,11 +26,5 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
if (sender is ListBox { SelectedItem: ApplicationData selected })
|
if (sender is ListBox { SelectedItem: ApplicationData selected })
|
||||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
|
||||||
{
|
|
||||||
if (DataContext is MainWindowViewModel viewModel && sender is ListBox { SelectedItem: ApplicationData selected })
|
|
||||||
viewModel.GridSelectedApplication = selected;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:converters="clr-namespace:Avalonia.Data.Converters;assembly=Avalonia.Base"
|
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
Focusable="True"
|
Focusable="True"
|
||||||
@ -16,7 +15,6 @@
|
|||||||
x:DataType="viewModels:MainWindowViewModel">
|
x:DataType="viewModels:MainWindowViewModel">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||||
<controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
@ -28,10 +26,10 @@
|
|||||||
Padding="8"
|
Padding="8"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
ContextFlyout="{StaticResource ApplicationContextMenu}"
|
SelectedItem="{Binding ListSelectedApplication}"
|
||||||
|
ContextFlyout="{Binding ListAppContextMenu}"
|
||||||
DoubleTapped="GameList_DoubleTapped"
|
DoubleTapped="GameList_DoubleTapped"
|
||||||
ItemsSource="{Binding AppsObservableList}"
|
ItemsSource="{Binding AppsObservableList}">
|
||||||
SelectionChanged="GameList_SelectionChanged">
|
|
||||||
<ListBox.ItemsPanel>
|
<ListBox.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
|
@ -30,12 +30,6 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
|
||||||
{
|
|
||||||
if (DataContext is MainWindowViewModel viewModel && sender is ListBox { SelectedItem: ApplicationData selected })
|
|
||||||
viewModel.ListSelectedApplication = selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (DataContext is not MainWindowViewModel mwvm)
|
if (DataContext is not MainWindowViewModel mwvm)
|
||||||
|
@ -63,6 +63,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
|
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
|
||||||
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
|
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
|
||||||
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
|
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
|
||||||
|
public static MiniCommand CreateFromTask<TArg>(Func<TArg, Task> callback) => new MiniCommand<TArg>(callback);
|
||||||
|
|
||||||
public abstract bool CanExecute(object parameter);
|
public abstract bool CanExecute(object parameter);
|
||||||
public abstract void Execute(object parameter);
|
public abstract void Execute(object parameter);
|
||||||
|
28
src/Ryujinx/UI/Helpers/PlayabilityStatusConverter.cs
Normal file
28
src/Ryujinx/UI/Helpers/PlayabilityStatusConverter.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
{
|
||||||
|
public class PlayabilityStatusConverter : IValueConverter
|
||||||
|
{
|
||||||
|
private static readonly Lazy<PlayabilityStatusConverter> _shared = new(() => new());
|
||||||
|
public static PlayabilityStatusConverter Shared => _shared.Value;
|
||||||
|
|
||||||
|
public object Convert(object? value, Type _, object? __, CultureInfo ___) =>
|
||||||
|
value.Cast<LocaleKeys>() switch
|
||||||
|
{
|
||||||
|
LocaleKeys.CompatibilityListNothing or
|
||||||
|
LocaleKeys.CompatibilityListBoots or
|
||||||
|
LocaleKeys.CompatibilityListMenus => Brushes.Red,
|
||||||
|
LocaleKeys.CompatibilityListIngame => Brushes.Yellow,
|
||||||
|
_ => Brushes.ForestGreen
|
||||||
|
};
|
||||||
|
|
||||||
|
public object ConvertBack(object? value, Type _, object? __, CultureInfo ___)
|
||||||
|
=> throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignWidth="800"
|
|
||||||
d:DesignHeight="450"
|
|
||||||
x:Class="Ryujinx.Ava.UI.Renderer.RendererHost"
|
|
||||||
FlowDirection="LeftToRight"
|
|
||||||
Focusable="True">
|
|
||||||
</UserControl>
|
|
@ -1,16 +1,15 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Gommon;
|
using Avalonia.Media;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Renderer
|
namespace Ryujinx.Ava.UI.Renderer
|
||||||
{
|
{
|
||||||
public partial class RendererHost : UserControl, IDisposable
|
public class RendererHost : UserControl, IDisposable
|
||||||
{
|
{
|
||||||
public readonly EmbeddedWindow EmbeddedWindow;
|
public readonly EmbeddedWindow EmbeddedWindow;
|
||||||
|
|
||||||
@ -19,7 +18,8 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
|
|
||||||
public RendererHost()
|
public RendererHost()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
Focusable = true;
|
||||||
|
FlowDirection = FlowDirection.LeftToRight;
|
||||||
|
|
||||||
EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
||||||
{
|
{
|
||||||
@ -43,8 +43,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
|
|
||||||
public RendererHost(string titleId)
|
public RendererHost(string titleId)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend))
|
switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend))
|
||||||
{
|
{
|
||||||
case GraphicsBackend.OpenGl:
|
case GraphicsBackend.OpenGl:
|
||||||
@ -109,3 +107,4 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.Common;
|
using Ryujinx.Ava.Common;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
@ -8,42 +9,11 @@ using System;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class AboutWindowViewModel : BaseModel, IDisposable
|
public partial class AboutWindowViewModel : BaseModel, IDisposable
|
||||||
{
|
{
|
||||||
private Bitmap _githubLogo;
|
[ObservableProperty] private Bitmap _githubLogo;
|
||||||
private Bitmap _discordLogo;
|
[ObservableProperty] private Bitmap _discordLogo;
|
||||||
|
[ObservableProperty] private string _version;
|
||||||
private string _version;
|
|
||||||
|
|
||||||
public Bitmap GithubLogo
|
|
||||||
{
|
|
||||||
get => _githubLogo;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_githubLogo = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap DiscordLogo
|
|
||||||
{
|
|
||||||
get => _discordLogo;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_discordLogo = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Version
|
|
||||||
{
|
|
||||||
get => _version;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_version = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Developers => "GreemDev";
|
public string Developers => "GreemDev";
|
||||||
|
|
||||||
|
@ -1,18 +1,10 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class BaseModel : INotifyPropertyChanged
|
public class BaseModel : ObservableObject
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnPropertiesChanged(string firstPropertyName, params ReadOnlySpan<string> propertyNames)
|
protected void OnPropertiesChanged(string firstPropertyName, params ReadOnlySpan<string> propertyNames)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(firstPropertyName);
|
OnPropertyChanged(firstPropertyName);
|
||||||
|
@ -2,6 +2,7 @@ using Avalonia.Collections;
|
|||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
@ -17,13 +18,13 @@ using Application = Avalonia.Application;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class DownloadableContentManagerViewModel : BaseModel
|
public partial class DownloadableContentManagerViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private readonly ApplicationLibrary _applicationLibrary;
|
private readonly ApplicationLibrary _applicationLibrary;
|
||||||
private AvaloniaList<DownloadableContentModel> _downloadableContents = new();
|
private AvaloniaList<DownloadableContentModel> _downloadableContents = new();
|
||||||
private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
|
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
|
||||||
private AvaloniaList<DownloadableContentModel> _views = new();
|
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _views = new();
|
||||||
private bool _showBundledContentNotice = false;
|
[ObservableProperty] private bool _showBundledContentNotice = false;
|
||||||
|
|
||||||
private string _search;
|
private string _search;
|
||||||
private readonly ApplicationData _applicationData;
|
private readonly ApplicationData _applicationData;
|
||||||
@ -41,26 +42,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvaloniaList<DownloadableContentModel> Views
|
|
||||||
{
|
|
||||||
get => _views;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_views = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AvaloniaList<DownloadableContentModel> SelectedDownloadableContents
|
|
||||||
{
|
|
||||||
get => _selectedDownloadableContents;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_selectedDownloadableContents = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Search
|
public string Search
|
||||||
{
|
{
|
||||||
get => _search;
|
get => _search;
|
||||||
@ -77,26 +58,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
|
get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShowBundledContentNotice
|
|
||||||
{
|
|
||||||
get => _showBundledContentNotice;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showBundledContentNotice = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadableContentManagerViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
public DownloadableContentManagerViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||||
{
|
{
|
||||||
_applicationLibrary = applicationLibrary;
|
_applicationLibrary = applicationLibrary;
|
||||||
|
|
||||||
_applicationData = applicationData;
|
_applicationData = applicationData;
|
||||||
|
|
||||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||||
{
|
|
||||||
_storageProvider = desktop.MainWindow.StorageProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadDownloadableContents();
|
LoadDownloadableContents();
|
||||||
}
|
}
|
||||||
@ -139,8 +107,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
// some reason. so we save the items here and add them back after
|
// some reason. so we save the items here and add them back after
|
||||||
var items = SelectedDownloadableContents.ToArray();
|
var items = SelectedDownloadableContents.ToArray();
|
||||||
|
|
||||||
_views.Clear();
|
Views.Clear();
|
||||||
_views.AddRange(view);
|
Views.AddRange(view);
|
||||||
|
|
||||||
foreach (DownloadableContentModel item in items)
|
foreach (DownloadableContentModel item in items)
|
||||||
{
|
{
|
||||||
|
@ -245,9 +245,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
{
|
{
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
_mainWindow =
|
_mainWindow = RyujinxApp.MainWindow;
|
||||||
(MainWindow)((IClassicDesktopStyleApplicationLifetime)Application.Current
|
|
||||||
.ApplicationLifetime).MainWindow;
|
|
||||||
|
|
||||||
AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
|
AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ using Avalonia.Media;
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
@ -54,77 +55,77 @@ using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class MainWindowViewModel : BaseModel
|
public partial class MainWindowViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private const int HotKeyPressDelayMs = 500;
|
private const int HotKeyPressDelayMs = 500;
|
||||||
private delegate int LoadContentFromFolderDelegate(List<string> dirs, out int numRemoved);
|
private delegate int LoadContentFromFolderDelegate(List<string> dirs, out int numRemoved);
|
||||||
|
|
||||||
private ObservableCollectionExtended<ApplicationData> _applications;
|
[ObservableProperty] private ObservableCollectionExtended<ApplicationData> _applications;
|
||||||
private string _aspectStatusText;
|
[ObservableProperty] private string _aspectRatioStatusText;
|
||||||
|
[ObservableProperty] private string _loadHeading;
|
||||||
|
[ObservableProperty] private string _cacheLoadStatus;
|
||||||
|
[ObservableProperty] private string _dockedStatusText;
|
||||||
|
[ObservableProperty] private string _fifoStatusText;
|
||||||
|
[ObservableProperty] private string _gameStatusText;
|
||||||
|
[ObservableProperty] private string _volumeStatusText;
|
||||||
|
[ObservableProperty] private string _gpuNameText;
|
||||||
|
[ObservableProperty] private string _backendText;
|
||||||
|
[ObservableProperty] private string _shaderCountText;
|
||||||
|
[ObservableProperty] private bool _showShaderCompilationHint;
|
||||||
|
[ObservableProperty] private bool _isFullScreen;
|
||||||
|
[ObservableProperty] private int _progressMaximum;
|
||||||
|
[ObservableProperty] private int _progressValue;
|
||||||
|
[ObservableProperty] private bool _showMenuAndStatusBar = true;
|
||||||
|
[ObservableProperty] private bool _showStatusSeparator;
|
||||||
|
[ObservableProperty] private Brush _progressBarForegroundColor;
|
||||||
|
[ObservableProperty] private Brush _progressBarBackgroundColor;
|
||||||
|
[ObservableProperty] private Brush _vSyncModeColor;
|
||||||
|
#nullable enable
|
||||||
|
[ObservableProperty] private byte[]? _selectedIcon;
|
||||||
|
#nullable disable
|
||||||
|
[ObservableProperty] private int _statusBarProgressMaximum;
|
||||||
|
[ObservableProperty] private int _statusBarProgressValue;
|
||||||
|
[ObservableProperty] private string _statusBarProgressStatusText;
|
||||||
|
[ObservableProperty] private bool _statusBarProgressStatusVisible;
|
||||||
|
[ObservableProperty] private bool _isPaused;
|
||||||
|
[ObservableProperty] private bool _isLoadingIndeterminate = true;
|
||||||
|
[ObservableProperty] private bool _showAll;
|
||||||
|
[ObservableProperty] private string _lastScannedAmiiboId;
|
||||||
|
[ObservableProperty] private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
|
||||||
|
[ObservableProperty] private long _lastFullscreenToggle = Environment.TickCount64;
|
||||||
|
[ObservableProperty] private bool _showContent = true;
|
||||||
|
[ObservableProperty] private float _volumeBeforeMute;
|
||||||
|
[ObservableProperty] private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
|
||||||
|
[ObservableProperty] private Cursor _cursor;
|
||||||
|
[ObservableProperty] private string _title;
|
||||||
|
[ObservableProperty] private WindowState _windowState;
|
||||||
|
[ObservableProperty] private double _windowWidth;
|
||||||
|
[ObservableProperty] private double _windowHeight;
|
||||||
|
[ObservableProperty] private bool _isActive;
|
||||||
|
[ObservableProperty] private bool _isSubMenuOpen;
|
||||||
|
[ObservableProperty] private ApplicationContextMenu _listAppContextMenu;
|
||||||
|
[ObservableProperty] private ApplicationContextMenu _gridAppContextMenu;
|
||||||
|
|
||||||
private string _loadHeading;
|
private bool _showLoadProgress;
|
||||||
private string _cacheLoadStatus;
|
private bool _isGameRunning;
|
||||||
private string _searchText;
|
|
||||||
private Timer _searchTimer;
|
|
||||||
private string _dockedStatusText;
|
|
||||||
private string _vSyncModeText;
|
|
||||||
private string _fifoStatusText;
|
|
||||||
private string _gameStatusText;
|
|
||||||
private string _volumeStatusText;
|
|
||||||
private string _gpuStatusText;
|
|
||||||
private string _shaderCountText;
|
|
||||||
private bool _isAmiiboRequested;
|
private bool _isAmiiboRequested;
|
||||||
private bool _isAmiiboBinRequested;
|
private bool _isAmiiboBinRequested;
|
||||||
private bool _showShaderCompilationHint;
|
private string _searchText;
|
||||||
private bool _isGameRunning;
|
private Timer _searchTimer;
|
||||||
private bool _isFullScreen;
|
private string _vSyncModeText;
|
||||||
private int _progressMaximum;
|
|
||||||
private int _progressValue;
|
|
||||||
private long _lastFullscreenToggle = Environment.TickCount64;
|
|
||||||
private bool _showLoadProgress;
|
|
||||||
private bool _showMenuAndStatusBar = true;
|
|
||||||
private bool _showStatusSeparator;
|
|
||||||
private Brush _progressBarForegroundColor;
|
|
||||||
private Brush _progressBarBackgroundColor;
|
|
||||||
private Brush _vSyncModeColor;
|
|
||||||
private byte[] _selectedIcon;
|
|
||||||
private bool _isAppletMenuActive;
|
|
||||||
private int _statusBarProgressMaximum;
|
|
||||||
private int _statusBarProgressValue;
|
|
||||||
private string _statusBarProgressStatusText;
|
|
||||||
private bool _statusBarProgressStatusVisible;
|
|
||||||
private bool _isPaused;
|
|
||||||
private bool _showContent = true;
|
|
||||||
private bool _isLoadingIndeterminate = true;
|
|
||||||
private bool _showAll;
|
|
||||||
private string _lastScannedAmiiboId;
|
|
||||||
private bool _statusBarVisible;
|
|
||||||
private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
|
|
||||||
|
|
||||||
private string _showUiKey = "F4";
|
private string _showUiKey = "F4";
|
||||||
private string _pauseKey = "F5";
|
private string _pauseKey = "F5";
|
||||||
private string _screenshotKey = "F8";
|
private string _screenshotKey = "F8";
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private float _volumeBeforeMute;
|
private bool _isAppletMenuActive;
|
||||||
private string _backendText;
|
private bool _statusBarVisible;
|
||||||
|
|
||||||
private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
|
|
||||||
private bool _canUpdate = true;
|
private bool _canUpdate = true;
|
||||||
private Cursor _cursor;
|
|
||||||
private string _title;
|
|
||||||
private ApplicationData _currentApplicationData;
|
private ApplicationData _currentApplicationData;
|
||||||
private readonly AutoResetEvent _rendererWaitEvent;
|
private readonly AutoResetEvent _rendererWaitEvent;
|
||||||
private WindowState _windowState;
|
|
||||||
private double _windowWidth;
|
|
||||||
private double _windowHeight;
|
|
||||||
private int _customVSyncInterval;
|
private int _customVSyncInterval;
|
||||||
private int _customVSyncIntervalPercentageProxy;
|
private int _customVSyncIntervalPercentageProxy;
|
||||||
|
private ApplicationData _listSelectedApplication;
|
||||||
private bool _isActive;
|
private ApplicationData _gridSelectedApplication;
|
||||||
private bool _isSubMenuOpen;
|
|
||||||
|
|
||||||
public ApplicationData ListSelectedApplication;
|
|
||||||
public ApplicationData GridSelectedApplication;
|
|
||||||
|
|
||||||
// Key is Title ID
|
// Key is Title ID
|
||||||
public SafeDictionary<string, LdnGameData.Array> LdnData = [];
|
public SafeDictionary<string, LdnGameData.Array> LdnData = [];
|
||||||
@ -146,8 +147,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
Applications.ToObservableChangeSet()
|
Applications.ToObservableChangeSet()
|
||||||
.Filter(Filter)
|
.Filter(Filter)
|
||||||
.Sort(GetComparer())
|
.Sort(GetComparer())
|
||||||
.Bind(out _appsObservableList)
|
.OnItemAdded(_ => OnPropertyChanged(nameof(AppsObservableList)))
|
||||||
.AsObservableList();
|
.OnItemRemoved(_ => OnPropertyChanged(nameof(AppsObservableList)))
|
||||||
|
#pragma warning disable MVVMTK0034 // Event to update is fired below
|
||||||
|
.Bind(out _appsObservableList);
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
|
|
||||||
_rendererWaitEvent = new AutoResetEvent(false);
|
_rendererWaitEvent = new AutoResetEvent(false);
|
||||||
|
|
||||||
@ -156,9 +160,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
LoadConfigurableHotKeys();
|
LoadConfigurableHotKeys();
|
||||||
|
|
||||||
Volume = ConfigurationState.Instance.System.AudioVolume;
|
Volume = ConfigurationState.Instance.System.AudioVolume;
|
||||||
}
|
|
||||||
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Initialize(
|
public void Initialize(
|
||||||
ContentManager contentManager,
|
ContentManager contentManager,
|
||||||
@ -218,7 +222,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool CanUpdate
|
public bool CanUpdate
|
||||||
{
|
{
|
||||||
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate(false);
|
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate();
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_canUpdate = value;
|
_canUpdate = value;
|
||||||
@ -226,49 +230,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cursor Cursor
|
|
||||||
{
|
|
||||||
get => _cursor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_cursor = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlyObservableCollection<ApplicationData> AppsObservableList
|
|
||||||
{
|
|
||||||
get => _appsObservableList;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_appsObservableList = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsPaused
|
|
||||||
{
|
|
||||||
get => _isPaused;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isPaused = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long LastFullscreenToggle
|
|
||||||
{
|
|
||||||
get => _lastFullscreenToggle;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_lastFullscreenToggle = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StatusBarVisible
|
public bool StatusBarVisible
|
||||||
{
|
{
|
||||||
get => _statusBarVisible && EnableNonGameRunningControls;
|
get => _statusBarVisible && EnableNonGameRunningControls;
|
||||||
@ -284,17 +245,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool ShowFirmwareStatus => !ShowLoadProgress;
|
public bool ShowFirmwareStatus => !ShowLoadProgress;
|
||||||
|
|
||||||
public bool ShowShaderCompilationHint
|
|
||||||
{
|
|
||||||
get => _showShaderCompilationHint;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showShaderCompilationHint = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsGameRunning
|
public bool IsGameRunning
|
||||||
{
|
{
|
||||||
get => _isGameRunning;
|
get => _isGameRunning;
|
||||||
@ -350,56 +300,38 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GameStatusText
|
public ApplicationData ListSelectedApplication
|
||||||
{
|
{
|
||||||
get => _gameStatusText;
|
get => _listSelectedApplication;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_gameStatusText = value;
|
_listSelectedApplication = value;
|
||||||
|
|
||||||
|
#pragma warning disable MVVMTK0034
|
||||||
|
if (_listSelectedApplication != null && _listAppContextMenu == null)
|
||||||
|
|
||||||
|
ListAppContextMenu = new ApplicationContextMenu();
|
||||||
|
else if (_listSelectedApplication == null && _listAppContextMenu != null)
|
||||||
|
ListAppContextMenu = null!;
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsFullScreen
|
public ApplicationData GridSelectedApplication
|
||||||
{
|
{
|
||||||
get => _isFullScreen;
|
get => _gridSelectedApplication;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_isFullScreen = value;
|
_gridSelectedApplication = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
#pragma warning disable MVVMTK0034
|
||||||
}
|
if (_gridSelectedApplication != null && _gridAppContextMenu == null)
|
||||||
}
|
GridAppContextMenu = new ApplicationContextMenu();
|
||||||
|
else if (_gridSelectedApplication == null && _gridAppContextMenu != null)
|
||||||
public bool IsSubMenuOpen
|
GridAppContextMenu = null!;
|
||||||
{
|
#pragma warning restore MVVMTK0034
|
||||||
get => _isSubMenuOpen;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isSubMenuOpen = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowAll
|
|
||||||
{
|
|
||||||
get => _showAll;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showAll = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LastScannedAmiiboId
|
|
||||||
{
|
|
||||||
get => _lastScannedAmiiboId;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_lastScannedAmiiboId = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
@ -418,87 +350,20 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OpenUserSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
public bool OpenUserSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
||||||
|
|
||||||
public bool OpenDeviceSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
public bool OpenDeviceSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
||||||
|
|
||||||
public bool TrimXCIEnabled => XCIFileTrimmer.CanTrim(SelectedApplication.Path, new XCITrimmerLog.MainWindow(this));
|
public bool TrimXCIEnabled => XCIFileTrimmer.CanTrim(SelectedApplication.Path, new XCITrimmerLog.MainWindow(this));
|
||||||
|
|
||||||
public bool OpenBcatSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
public bool OpenBcatSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
||||||
|
|
||||||
public string LoadHeading
|
|
||||||
{
|
|
||||||
get => _loadHeading;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_loadHeading = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string CacheLoadStatus
|
|
||||||
{
|
|
||||||
get => _cacheLoadStatus;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_cacheLoadStatus = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Brush ProgressBarBackgroundColor
|
|
||||||
{
|
|
||||||
get => _progressBarBackgroundColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_progressBarBackgroundColor = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Brush ProgressBarForegroundColor
|
|
||||||
{
|
|
||||||
get => _progressBarForegroundColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_progressBarForegroundColor = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Brush VSyncModeColor
|
|
||||||
{
|
|
||||||
get => _vSyncModeColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_vSyncModeColor = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowCustomVSyncIntervalPicker
|
public bool ShowCustomVSyncIntervalPicker
|
||||||
|
=> _isGameRunning && AppHost.Device.VSyncMode == VSyncMode.Custom;
|
||||||
|
|
||||||
|
public void UpdateVSyncIntervalPicker()
|
||||||
{
|
{
|
||||||
get
|
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||||
{
|
|
||||||
if (_isGameRunning)
|
|
||||||
{
|
|
||||||
return AppHost.Device.VSyncMode ==
|
|
||||||
VSyncMode.Custom;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CustomVSyncIntervalPercentageProxy
|
public int CustomVSyncIntervalPercentageProxy
|
||||||
@ -551,126 +416,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] SelectedIcon
|
|
||||||
{
|
|
||||||
get => _selectedIcon;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_selectedIcon = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ProgressMaximum
|
|
||||||
{
|
|
||||||
get => _progressMaximum;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_progressMaximum = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ProgressValue
|
|
||||||
{
|
|
||||||
get => _progressValue;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_progressValue = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int StatusBarProgressMaximum
|
|
||||||
{
|
|
||||||
get => _statusBarProgressMaximum;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_statusBarProgressMaximum = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int StatusBarProgressValue
|
|
||||||
{
|
|
||||||
get => _statusBarProgressValue;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_statusBarProgressValue = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StatusBarProgressStatusVisible
|
|
||||||
{
|
|
||||||
get => _statusBarProgressStatusVisible;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_statusBarProgressStatusVisible = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string StatusBarProgressStatusText
|
|
||||||
{
|
|
||||||
get => _statusBarProgressStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_statusBarProgressStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FifoStatusText
|
|
||||||
{
|
|
||||||
get => _fifoStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_fifoStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GpuNameText
|
|
||||||
{
|
|
||||||
get => _gpuStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_gpuStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ShaderCountText
|
|
||||||
{
|
|
||||||
get => _shaderCountText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_shaderCountText = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BackendText
|
|
||||||
{
|
|
||||||
get => _backendText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_backendText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string VSyncModeText
|
public string VSyncModeText
|
||||||
{
|
{
|
||||||
get => _vSyncModeText;
|
get => _vSyncModeText;
|
||||||
@ -679,39 +424,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_vSyncModeText = value;
|
_vSyncModeText = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||||
}
|
|
||||||
|
|
||||||
public string DockedStatusText
|
|
||||||
{
|
|
||||||
get => _dockedStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_dockedStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string AspectRatioStatusText
|
|
||||||
{
|
|
||||||
get => _aspectStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_aspectStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string VolumeStatusText
|
|
||||||
{
|
|
||||||
get => _volumeStatusText;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_volumeStatusText = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,73 +448,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float VolumeBeforeMute
|
|
||||||
{
|
|
||||||
get => _volumeBeforeMute;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_volumeBeforeMute = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowStatusSeparator
|
|
||||||
{
|
|
||||||
get => _showStatusSeparator;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showStatusSeparator = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowMenuAndStatusBar
|
|
||||||
{
|
|
||||||
get => _showMenuAndStatusBar;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showMenuAndStatusBar = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsLoadingIndeterminate
|
|
||||||
{
|
|
||||||
get => _isLoadingIndeterminate;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isLoadingIndeterminate = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsActive
|
|
||||||
{
|
|
||||||
get => _isActive;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isActive = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool ShowContent
|
|
||||||
{
|
|
||||||
get => _showContent;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showContent = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsAppletMenuActive
|
public bool IsAppletMenuActive
|
||||||
{
|
{
|
||||||
get => _isAppletMenuActive && EnableNonGameRunningControls;
|
get => _isAppletMenuActive && EnableNonGameRunningControls;
|
||||||
@ -813,39 +459,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowState WindowState
|
|
||||||
{
|
|
||||||
get => _windowState;
|
|
||||||
internal set
|
|
||||||
{
|
|
||||||
_windowState = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double WindowWidth
|
|
||||||
{
|
|
||||||
get => _windowWidth;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_windowWidth = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double WindowHeight
|
|
||||||
{
|
|
||||||
get => _windowHeight;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_windowHeight = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsGrid => Glyph == Glyph.Grid;
|
public bool IsGrid => Glyph == Glyph.Grid;
|
||||||
public bool IsList => Glyph == Glyph.List;
|
public bool IsList => Glyph == Glyph.List;
|
||||||
|
|
||||||
@ -889,17 +502,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title
|
|
||||||
{
|
|
||||||
get => _title;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_title = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowConsoleVisible
|
public bool ShowConsoleVisible
|
||||||
{
|
{
|
||||||
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
||||||
@ -910,27 +512,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
get => FileAssociationHelper.IsTypeAssociationSupported;
|
get => FileAssociationHelper.IsTypeAssociationSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AreMimeTypesRegistered
|
|
||||||
{
|
|
||||||
get => _areMimeTypesRegistered;
|
|
||||||
set {
|
|
||||||
_areMimeTypesRegistered = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollectionExtended<ApplicationData> Applications
|
|
||||||
{
|
|
||||||
get => _applications;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_applications = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Glyph Glyph
|
public Glyph Glyph
|
||||||
{
|
{
|
||||||
get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
|
get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
|
||||||
@ -948,7 +529,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool ShowNames
|
public bool ShowNames
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; set
|
get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.UI.ShowNames.Value = value;
|
ConfigurationState.Instance.UI.ShowNames.Value = value;
|
||||||
|
|
||||||
@ -1508,8 +1090,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
|
VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
|
||||||
ShowCustomVSyncIntervalPicker =
|
|
||||||
args.VSyncMode == VSyncMode.Custom.ToString();
|
|
||||||
DockedStatusText = args.DockedMode;
|
DockedStatusText = args.DockedMode;
|
||||||
AspectRatioStatusText = args.AspectRatio;
|
AspectRatioStatusText = args.AspectRatio;
|
||||||
GameStatusText = args.GameStatus;
|
GameStatusText = args.GameStatus;
|
||||||
@ -2176,7 +1756,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void ProcessTrimResult(String filename, Ryujinx.Common.Utilities.XCIFileTrimmer.OperationOutcome operationOutcome)
|
public async void ProcessTrimResult(String filename, XCIFileTrimmer.OperationOutcome operationOutcome)
|
||||||
{
|
{
|
||||||
string notifyUser = operationOutcome.ToLocalisedText();
|
string notifyUser = operationOutcome.ToLocalisedText();
|
||||||
|
|
||||||
@ -2191,12 +1771,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
switch (operationOutcome)
|
switch (operationOutcome)
|
||||||
{
|
{
|
||||||
case Ryujinx.Common.Utilities.XCIFileTrimmer.OperationOutcome.Successful:
|
case XCIFileTrimmer.OperationOutcome.Successful:
|
||||||
if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
RyujinxApp.MainWindow.LoadApplications();
|
||||||
{
|
|
||||||
if (desktop.MainWindow is MainWindow mainWindow)
|
|
||||||
mainWindow.LoadApplications();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
@ -18,13 +17,13 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class ModManagerViewModel : BaseModel
|
public partial class ModManagerViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private readonly string _modJsonPath;
|
private readonly string _modJsonPath;
|
||||||
|
|
||||||
private AvaloniaList<ModModel> _mods = new();
|
private AvaloniaList<ModModel> _mods = new();
|
||||||
private AvaloniaList<ModModel> _views = new();
|
[ObservableProperty] private AvaloniaList<ModModel> _views = new();
|
||||||
private AvaloniaList<ModModel> _selectedMods = new();
|
[ObservableProperty] private AvaloniaList<ModModel> _selectedMods = new();
|
||||||
|
|
||||||
private string _search;
|
private string _search;
|
||||||
private readonly ulong _applicationId;
|
private readonly ulong _applicationId;
|
||||||
@ -44,26 +43,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvaloniaList<ModModel> Views
|
|
||||||
{
|
|
||||||
get => _views;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_views = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AvaloniaList<ModModel> SelectedMods
|
|
||||||
{
|
|
||||||
get => _selectedMods;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_selectedMods = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Search
|
public string Search
|
||||||
{
|
{
|
||||||
get => _search;
|
get => _search;
|
||||||
@ -86,10 +65,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
_modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json");
|
_modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json");
|
||||||
|
|
||||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||||
{
|
|
||||||
_storageProvider = desktop.MainWindow.StorageProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadMods(applicationId);
|
LoadMods(applicationId);
|
||||||
}
|
}
|
||||||
@ -146,8 +122,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
.Filter(Filter)
|
.Filter(Filter)
|
||||||
.Bind(out var view).AsObservableList();
|
.Bind(out var view).AsObservableList();
|
||||||
|
|
||||||
|
#pragma warning disable MVVMTK0034 // Event to update is fired below
|
||||||
_views.Clear();
|
_views.Clear();
|
||||||
_views.AddRange(view);
|
_views.AddRange(view);
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
|
|
||||||
SelectedMods = new(Views.Where(x => x.Enabled));
|
SelectedMods = new(Views.Where(x => x.Enabled));
|
||||||
|
|
||||||
|
56
src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs
Normal file
56
src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
{
|
||||||
|
public partial class SettingsHacksViewModel : BaseModel
|
||||||
|
{
|
||||||
|
private readonly SettingsViewModel _baseViewModel;
|
||||||
|
|
||||||
|
public SettingsHacksViewModel() {}
|
||||||
|
|
||||||
|
public SettingsHacksViewModel(SettingsViewModel settingsVm)
|
||||||
|
{
|
||||||
|
_baseViewModel = settingsVm;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
|
||||||
|
[ObservableProperty] private bool _shaderTranslationDelayEnabled = ConfigurationState.Instance.Hacks.EnableShaderTranslationDelay;
|
||||||
|
private int _shaderTranslationSleepDelay = ConfigurationState.Instance.Hacks.ShaderTranslationDelay;
|
||||||
|
|
||||||
|
public string ShaderTranslationDelayValueText => $"{ShaderTranslationDelay}ms";
|
||||||
|
|
||||||
|
public int ShaderTranslationDelay
|
||||||
|
{
|
||||||
|
get => _shaderTranslationSleepDelay;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_shaderTranslationSleepDelay = value;
|
||||||
|
|
||||||
|
OnPropertiesChanged(nameof(ShaderTranslationDelay), nameof(ShaderTranslationDelayValueText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb =>
|
||||||
|
{
|
||||||
|
sb.AppendLine(
|
||||||
|
"This fix applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.")
|
||||||
|
.AppendLine();
|
||||||
|
|
||||||
|
sb.AppendLine("From the issue on GitHub:").AppendLine();
|
||||||
|
sb.Append(
|
||||||
|
"When clicking very fast from game main menu to 2nd submenu, " +
|
||||||
|
"there is a low chance that the game will softlock, " +
|
||||||
|
"the submenu won't show up, while background music is still there.");
|
||||||
|
});
|
||||||
|
|
||||||
|
public static string ShaderTranslationDelayTooltip { get; } = Lambda.String(sb =>
|
||||||
|
{
|
||||||
|
sb.AppendLine("This hack applies the delay you specify every time shaders are attempted to be translated.")
|
||||||
|
.AppendLine();
|
||||||
|
|
||||||
|
sb.Append("Configurable via slider, only when this option is enabled.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Audio.Backends.OpenAL;
|
using Ryujinx.Audio.Backends.OpenAL;
|
||||||
@ -46,9 +47,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
private int _resolutionScale;
|
private int _resolutionScale;
|
||||||
private int _graphicsBackendMultithreadingIndex;
|
private int _graphicsBackendMultithreadingIndex;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private bool _isVulkanAvailable = true;
|
[ObservableProperty] private bool _isVulkanAvailable = true;
|
||||||
private bool _gameDirectoryChanged;
|
[ObservableProperty] private bool _gameDirectoryChanged;
|
||||||
private bool _autoloadDirectoryChanged;
|
[ObservableProperty] private bool _autoloadDirectoryChanged;
|
||||||
private readonly List<string> _gpuIds = new();
|
private readonly List<string> _gpuIds = new();
|
||||||
private int _graphicsBackendIndex;
|
private int _graphicsBackendIndex;
|
||||||
private int _scalingFilter;
|
private int _scalingFilter;
|
||||||
@ -63,11 +64,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
private int _networkInterfaceIndex;
|
private int _networkInterfaceIndex;
|
||||||
private int _multiplayerModeIndex;
|
private int _multiplayerModeIndex;
|
||||||
private string _ldnPassphrase;
|
private string _ldnPassphrase;
|
||||||
private string _ldnServer;
|
[ObservableProperty] private string _ldnServer;
|
||||||
|
|
||||||
private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
|
public SettingsHacksViewModel DirtyHacks { get; }
|
||||||
private bool _shaderTranslationThreadSleep = ConfigurationState.Instance.Hacks.EnableShaderCompilationThreadSleep;
|
|
||||||
private int _shaderTranslationSleepDelay = ConfigurationState.Instance.Hacks.ShaderCompilationThreadSleepDelay;
|
|
||||||
|
|
||||||
public int ResolutionScale
|
public int ResolutionScale
|
||||||
{
|
{
|
||||||
@ -113,43 +112,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsVulkanAvailable
|
|
||||||
{
|
|
||||||
get => _isVulkanAvailable;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isVulkanAvailable = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
|
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
|
||||||
|
|
||||||
public bool IsAppleSiliconMac => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
|
public bool IsAppleSiliconMac => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
|
||||||
|
|
||||||
public bool GameDirectoryChanged
|
|
||||||
{
|
|
||||||
get => _gameDirectoryChanged;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_gameDirectoryChanged = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AutoloadDirectoryChanged
|
|
||||||
{
|
|
||||||
get => _autoloadDirectoryChanged;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_autoloadDirectoryChanged = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsMacOS => OperatingSystem.IsMacOS();
|
public bool IsMacOS => OperatingSystem.IsMacOS();
|
||||||
|
|
||||||
public bool EnableDiscordIntegration { get; set; }
|
public bool EnableDiscordIntegration { get; set; }
|
||||||
@ -189,14 +155,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CustomVSyncIntervalPercentageText
|
public string CustomVSyncIntervalPercentageText => CustomVSyncIntervalPercentageProxy + "%";
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string text = CustomVSyncIntervalPercentageProxy + "%";
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool EnableCustomVSyncInterval
|
public bool EnableCustomVSyncInterval
|
||||||
{
|
{
|
||||||
@ -279,39 +238,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Xc2MenuSoftlockFixEnabled
|
|
||||||
{
|
|
||||||
get => _xc2MenuSoftlockFix;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_xc2MenuSoftlockFix = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShaderTranslationDelayEnabled
|
|
||||||
{
|
|
||||||
get => _shaderTranslationThreadSleep;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_shaderTranslationThreadSleep = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ShaderTranslationDelay
|
|
||||||
{
|
|
||||||
get => _shaderTranslationSleepDelay;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_shaderTranslationSleepDelay = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Language { get; set; }
|
public int Language { get; set; }
|
||||||
public int Region { get; set; }
|
public int Region { get; set; }
|
||||||
public int FsGlobalAccessLogMode { get; set; }
|
public int FsGlobalAccessLogMode { get; set; }
|
||||||
@ -391,7 +317,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_networkInterfaceIndex = value != -1 ? value : 0;
|
_networkInterfaceIndex = value != -1 ? value : 0;
|
||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +326,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_multiplayerModeIndex = value;
|
_multiplayerModeIndex = value;
|
||||||
ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,23 +334,16 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool IsInvalidLdnPassphraseVisible { get; set; }
|
public bool IsInvalidLdnPassphraseVisible { get; set; }
|
||||||
|
|
||||||
public string LdnServer
|
|
||||||
{
|
|
||||||
get => _ldnServer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_ldnServer = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
|
public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
|
||||||
{
|
{
|
||||||
_virtualFileSystem = virtualFileSystem;
|
_virtualFileSystem = virtualFileSystem;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
Task.Run(LoadTimeZones);
|
Task.Run(LoadTimeZones);
|
||||||
|
|
||||||
|
DirtyHacks = new SettingsHacksViewModel(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,6 +363,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
Task.Run(LoadAvailableGpus);
|
Task.Run(LoadAvailableGpus);
|
||||||
LoadCurrentConfiguration();
|
LoadCurrentConfiguration();
|
||||||
|
|
||||||
|
DirtyHacks = new SettingsHacksViewModel(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,11 +415,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public void MatchSystemTime()
|
public void MatchSystemTime()
|
||||||
{
|
{
|
||||||
var dto = DateTimeOffset.Now;
|
(DateTimeOffset dto, TimeSpan timeOfDay) = DateTimeOffset.Now.Extract();
|
||||||
|
|
||||||
CurrentDate = new DateTimeOffset(dto.Year, dto.Month, dto.Day, 0, 0, 0, dto.Offset);
|
CurrentDate = dto;
|
||||||
|
CurrentTime = timeOfDay;
|
||||||
CurrentTime = dto.TimeOfDay;
|
|
||||||
|
|
||||||
OnPropertyChanged(nameof(CurrentDate));
|
OnPropertyChanged(nameof(CurrentDate));
|
||||||
OnPropertyChanged(nameof(CurrentTime));
|
OnPropertyChanged(nameof(CurrentTime));
|
||||||
@ -660,9 +578,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value;
|
OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value;
|
||||||
|
|
||||||
MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value;
|
MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value;
|
||||||
DisableP2P = config.Multiplayer.DisableP2p.Value;
|
DisableP2P = config.Multiplayer.DisableP2p;
|
||||||
LdnPassphrase = config.Multiplayer.LdnPassphrase.Value;
|
LdnPassphrase = config.Multiplayer.LdnPassphrase;
|
||||||
LdnServer = config.Multiplayer.LdnServer.Value;
|
LdnServer = config.Multiplayer.LdnServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveSettings()
|
public void SaveSettings()
|
||||||
@ -678,16 +596,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
config.ShowTitleBar.Value = ShowTitleBar;
|
config.ShowTitleBar.Value = ShowTitleBar;
|
||||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||||
|
|
||||||
if (_gameDirectoryChanged)
|
if (GameDirectoryChanged)
|
||||||
{
|
{
|
||||||
List<string> gameDirs = new(GameDirectories);
|
config.UI.GameDirs.Value = [..GameDirectories];
|
||||||
config.UI.GameDirs.Value = gameDirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_autoloadDirectoryChanged)
|
if (AutoloadDirectoryChanged)
|
||||||
{
|
{
|
||||||
List<string> autoloadDirs = new(AutoloadDirectories);
|
config.UI.AutoloadDirs.Value = [..AutoloadDirectories];
|
||||||
config.UI.AutoloadDirs.Value = autoloadDirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.UI.BaseStyle.Value = BaseStyleIndex switch
|
config.UI.BaseStyle.Value = BaseStyleIndex switch
|
||||||
@ -786,9 +702,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
config.Multiplayer.LdnServer.Value = LdnServer;
|
config.Multiplayer.LdnServer.Value = LdnServer;
|
||||||
|
|
||||||
// Dirty Hacks
|
// Dirty Hacks
|
||||||
config.Hacks.Xc2MenuSoftlockFix.Value = Xc2MenuSoftlockFixEnabled;
|
config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix;
|
||||||
config.Hacks.EnableShaderCompilationThreadSleep.Value = ShaderTranslationDelayEnabled;
|
config.Hacks.EnableShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelayEnabled;
|
||||||
config.Hacks.ShaderCompilationThreadSleepDelay.Value = ShaderTranslationDelay;
|
config.Hacks.ShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelay;
|
||||||
|
|
||||||
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
|
|
||||||
@ -797,8 +713,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
SaveSettingsEvent?.Invoke();
|
SaveSettingsEvent?.Invoke();
|
||||||
|
|
||||||
_gameDirectoryChanged = false;
|
GameDirectoryChanged = false;
|
||||||
_autoloadDirectoryChanged = false;
|
AutoloadDirectoryChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RevertIfNotSaved()
|
private static void RevertIfNotSaved()
|
||||||
@ -822,24 +738,5 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
RevertIfNotSaved();
|
RevertIfNotSaved();
|
||||||
CloseWindow?.Invoke();
|
CloseWindow?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb =>
|
|
||||||
{
|
|
||||||
sb.AppendLine(
|
|
||||||
"This fix applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.")
|
|
||||||
.AppendLine();
|
|
||||||
|
|
||||||
sb.AppendLine("From the issue on GitHub:").AppendLine();
|
|
||||||
sb.Append(
|
|
||||||
"When clicking very fast from game main menu to 2nd submenu, " +
|
|
||||||
"there is a low chance that the game will softlock, " +
|
|
||||||
"the submenu won't show up, while background music is still there.");
|
|
||||||
});
|
|
||||||
|
|
||||||
public static string ShaderTranslationDelayTooltip { get; } = Lambda.String(sb =>
|
|
||||||
{
|
|
||||||
sb.Append(
|
|
||||||
"This hack applies the delay you specify every time shaders are attempted to be translated.");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,74 +1,32 @@
|
|||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Common.Models;
|
using Ryujinx.Ava.Common.Models;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using Ryujinx.HLE.FileSystem;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Application = Avalonia.Application;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public record TitleUpdateViewNoUpdateSentinal();
|
public record TitleUpdateViewModelNoUpdate;
|
||||||
|
|
||||||
public class TitleUpdateViewModel : BaseModel
|
public partial class TitleUpdateViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private ApplicationLibrary ApplicationLibrary { get; }
|
private ApplicationLibrary ApplicationLibrary { get; }
|
||||||
private ApplicationData ApplicationData { get; }
|
private ApplicationData ApplicationData { get; }
|
||||||
|
|
||||||
private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
|
[ObservableProperty] private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
|
||||||
private AvaloniaList<object> _views = new();
|
[ObservableProperty] private AvaloniaList<object> _views = new();
|
||||||
private object _selectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
[ObservableProperty] private object _selectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||||
private bool _showBundledContentNotice = false;
|
[ObservableProperty] private bool _showBundledContentNotice;
|
||||||
|
|
||||||
public AvaloniaList<TitleUpdateModel> TitleUpdates
|
private readonly IStorageProvider _storageProvider;
|
||||||
{
|
|
||||||
get => _titleUpdates;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_titleUpdates = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AvaloniaList<object> Views
|
|
||||||
{
|
|
||||||
get => _views;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_views = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object SelectedUpdate
|
|
||||||
{
|
|
||||||
get => _selectedUpdate;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_selectedUpdate = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowBundledContentNotice
|
|
||||||
{
|
|
||||||
get => _showBundledContentNotice;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showBundledContentNotice = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IStorageProvider StorageProvider;
|
|
||||||
|
|
||||||
public TitleUpdateViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
public TitleUpdateViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||||
{
|
{
|
||||||
@ -76,10 +34,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
ApplicationData = applicationData;
|
ApplicationData = applicationData;
|
||||||
|
|
||||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||||
{
|
|
||||||
StorageProvider = desktop.MainWindow.StorageProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadUpdates();
|
LoadUpdates();
|
||||||
}
|
}
|
||||||
@ -90,7 +45,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
.Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase);
|
.Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase);
|
||||||
|
|
||||||
bool hasBundledContent = false;
|
bool hasBundledContent = false;
|
||||||
SelectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||||
foreach ((TitleUpdateModel update, bool isSelected) in updates)
|
foreach ((TitleUpdateModel update, bool isSelected) in updates)
|
||||||
{
|
{
|
||||||
TitleUpdates.Add(update);
|
TitleUpdates.Add(update);
|
||||||
@ -116,12 +71,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
var selected = SelectedUpdate;
|
var selected = SelectedUpdate;
|
||||||
|
|
||||||
Views.Clear();
|
Views.Clear();
|
||||||
Views.Add(new TitleUpdateViewNoUpdateSentinal());
|
Views.Add(new TitleUpdateViewModelNoUpdate());
|
||||||
Views.AddRange(sortedUpdates);
|
Views.AddRange(sortedUpdates);
|
||||||
|
|
||||||
SelectedUpdate = selected;
|
SelectedUpdate = selected;
|
||||||
|
|
||||||
if (SelectedUpdate is TitleUpdateViewNoUpdateSentinal)
|
if (SelectedUpdate is TitleUpdateViewModelNoUpdate)
|
||||||
{
|
{
|
||||||
SelectedUpdate = Views[0];
|
SelectedUpdate = Views[0];
|
||||||
}
|
}
|
||||||
@ -179,7 +134,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
else if (update == SelectedUpdate as TitleUpdateModel)
|
else if (update == SelectedUpdate as TitleUpdateModel)
|
||||||
{
|
{
|
||||||
SelectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
SortUpdates();
|
SortUpdates();
|
||||||
@ -187,7 +142,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public async Task Add()
|
public async Task Add()
|
||||||
{
|
{
|
||||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||||
{
|
{
|
||||||
AllowMultiple = true,
|
AllowMultiple = true,
|
||||||
FileTypeFilter = new List<FilePickerFileType>
|
FileTypeFilter = new List<FilePickerFileType>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
@ -20,12 +21,12 @@ using Image = SkiaSharp.SKImage;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
internal class UserFirmwareAvatarSelectorViewModel : BaseModel
|
internal partial class UserFirmwareAvatarSelectorViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, byte[]> _avatarStore = new();
|
private static readonly Dictionary<string, byte[]> _avatarStore = new();
|
||||||
|
|
||||||
private ObservableCollection<ProfileImageModel> _images;
|
[ObservableProperty] private ObservableCollection<ProfileImageModel> _images;
|
||||||
private Color _backgroundColor = Colors.White;
|
[ObservableProperty] private Color _backgroundColor = Colors.White;
|
||||||
|
|
||||||
private int _selectedIndex;
|
private int _selectedIndex;
|
||||||
|
|
||||||
@ -34,27 +35,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_images = new ObservableCollection<ProfileImageModel>();
|
_images = new ObservableCollection<ProfileImageModel>();
|
||||||
|
|
||||||
LoadImagesFromStore();
|
LoadImagesFromStore();
|
||||||
}
|
PropertyChanged += (_, args) =>
|
||||||
|
|
||||||
public Color BackgroundColor
|
|
||||||
{
|
{
|
||||||
get => _backgroundColor;
|
if (args.PropertyName == nameof(BackgroundColor))
|
||||||
set
|
|
||||||
{
|
|
||||||
_backgroundColor = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
ChangeImageBackground();
|
ChangeImageBackground();
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollection<ProfileImageModel> Images
|
|
||||||
{
|
|
||||||
get => _images;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_images = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SelectedIndex
|
public int SelectedIndex
|
||||||
@ -70,7 +55,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SelectedImage = _images[_selectedIndex].Data;
|
SelectedImage = Images[_selectedIndex].Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
@ -1,18 +1,9 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
internal class UserProfileImageSelectorViewModel : BaseModel
|
internal partial class UserProfileImageSelectorViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private bool _firmwareFound;
|
[ObservableProperty] private bool _firmwareFound;
|
||||||
|
|
||||||
public bool FirmwareFound
|
|
||||||
{
|
|
||||||
get => _firmwareFound;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_firmwareFound = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
@ -8,74 +9,31 @@ using System.Collections.ObjectModel;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class UserSaveManagerViewModel : BaseModel
|
public partial class UserSaveManagerViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private int _sortIndex;
|
[ObservableProperty] private int _sortIndex;
|
||||||
private int _orderIndex;
|
[ObservableProperty] private int _orderIndex;
|
||||||
private string _search;
|
[ObservableProperty] private string _search;
|
||||||
private ObservableCollection<SaveModel> _saves = new();
|
[ObservableProperty] private ObservableCollection<SaveModel> _saves = new();
|
||||||
private ObservableCollection<SaveModel> _views = new();
|
[ObservableProperty] private ObservableCollection<SaveModel> _views = new();
|
||||||
private readonly AccountManager _accountManager;
|
private readonly AccountManager _accountManager;
|
||||||
|
|
||||||
public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);
|
public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);
|
||||||
|
|
||||||
public int SortIndex
|
|
||||||
{
|
|
||||||
get => _sortIndex;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_sortIndex = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
Sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int OrderIndex
|
|
||||||
{
|
|
||||||
get => _orderIndex;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_orderIndex = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
Sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Search
|
|
||||||
{
|
|
||||||
get => _search;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_search = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
Sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollection<SaveModel> Saves
|
|
||||||
{
|
|
||||||
get => _saves;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_saves = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
Sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollection<SaveModel> Views
|
|
||||||
{
|
|
||||||
get => _views;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_views = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSaveManagerViewModel(AccountManager accountManager)
|
public UserSaveManagerViewModel(AccountManager accountManager)
|
||||||
{
|
{
|
||||||
_accountManager = accountManager;
|
_accountManager = accountManager;
|
||||||
|
PropertyChanged += (_, evt) =>
|
||||||
|
{
|
||||||
|
if (evt.PropertyName is
|
||||||
|
nameof(SortIndex) or
|
||||||
|
nameof(OrderIndex) or
|
||||||
|
nameof(Search) or
|
||||||
|
nameof(Saves))
|
||||||
|
{
|
||||||
|
Sort();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Sort()
|
public void Sort()
|
||||||
@ -85,8 +43,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
.Sort(GetComparer())
|
.Sort(GetComparer())
|
||||||
.Bind(out var view).AsObservableList();
|
.Bind(out var view).AsObservableList();
|
||||||
|
|
||||||
|
#pragma warning disable MVVMTK0034
|
||||||
_views.Clear();
|
_views.Clear();
|
||||||
_views.AddRange(view);
|
_views.AddRange(view);
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
OnPropertyChanged(nameof(Views));
|
OnPropertyChanged(nameof(Views));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +54,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
if (arg is SaveModel save)
|
if (arg is SaveModel save)
|
||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
|
return string.IsNullOrWhiteSpace(Search) || save.Title.ToLower().Contains(Search.ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
ToolTip.Tip="{ext:Locale LoadTitleUpdatesFromFolderTooltip}" />
|
ToolTip.Tip="{ext:Locale LoadTitleUpdatesFromFolderTooltip}" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}" Icon="{ext:Icon mdi-launch}">
|
<MenuItem Header="{ext:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}" Icon="{ext:Icon mdi-launch}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenMiiApplet"
|
Name="MiiAppletMenuItem"
|
||||||
Header="{ext:Locale MenuBarFileOpenAppletOpenMiiApplet}"
|
Header="{ext:Locale MenuBarFileOpenAppletOpenMiiApplet}"
|
||||||
Icon="{ext:Icon fa-solid fa-person}"
|
Icon="{ext:Icon fa-solid fa-person}"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarFileOpenAppletOpenMiiAppletToolTip}" />
|
ToolTip.Tip="{ext:Locale MenuBarFileOpenAppletOpenMiiAppletToolTip}" />
|
||||||
@ -72,7 +72,7 @@
|
|||||||
ToolTip.Tip="{ext:Locale OpenRyujinxLogsTooltip}" />
|
ToolTip.Tip="{ext:Locale OpenRyujinxLogsTooltip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="CloseWindow"
|
Name="CloseRyujinxMenuItem"
|
||||||
Header="{ext:Locale MenuBarFileExit}"
|
Header="{ext:Locale MenuBarFileExit}"
|
||||||
Icon="{ext:Icon fa-solid fa-xmark}"
|
Icon="{ext:Icon fa-solid fa-xmark}"
|
||||||
ToolTip.Tip="{ext:Locale ExitTooltip}" />
|
ToolTip.Tip="{ext:Locale ExitTooltip}" />
|
||||||
@ -167,7 +167,7 @@
|
|||||||
Header="{ext:Locale MenuBarShowFileTypes}" />
|
Header="{ext:Locale MenuBarShowFileTypes}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenSettings"
|
Name="OpenSettingsMenuItem"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Header="{ext:Locale MenuBarOptionsSettings}"
|
Header="{ext:Locale MenuBarOptionsSettings}"
|
||||||
Icon="{ext:Icon fa-solid fa-gear}"
|
Icon="{ext:Icon fa-solid fa-gear}"
|
||||||
@ -210,21 +210,21 @@
|
|||||||
Header="{ext:Locale MenuBarActions}"
|
Header="{ext:Locale MenuBarActions}"
|
||||||
IsEnabled="{Binding IsGameRunning}">
|
IsEnabled="{Binding IsGameRunning}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="PauseEmulation_Click"
|
Name="PauseEmulationMenuItem"
|
||||||
Header="{ext:Locale MenuBarOptionsPauseEmulation}"
|
Header="{ext:Locale MenuBarOptionsPauseEmulation}"
|
||||||
Icon="{ext:Icon fa-solid fa-pause}"
|
Icon="{ext:Icon fa-solid fa-pause}"
|
||||||
InputGesture="{Binding PauseKey}"
|
InputGesture="{Binding PauseKey}"
|
||||||
IsEnabled="{Binding !IsPaused}"
|
IsEnabled="{Binding !IsPaused}"
|
||||||
IsVisible="{Binding !IsPaused}" />
|
IsVisible="{Binding !IsPaused}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="ResumeEmulation_Click"
|
Name="ResumeEmulationMenuItem"
|
||||||
Header="{ext:Locale MenuBarOptionsResumeEmulation}"
|
Header="{ext:Locale MenuBarOptionsResumeEmulation}"
|
||||||
Icon="{ext:Icon fa-solid fa-play}"
|
Icon="{ext:Icon fa-solid fa-play}"
|
||||||
InputGesture="{Binding PauseKey}"
|
InputGesture="{Binding PauseKey}"
|
||||||
IsEnabled="{Binding IsPaused}"
|
IsEnabled="{Binding IsPaused}"
|
||||||
IsVisible="{Binding IsPaused}" />
|
IsVisible="{Binding IsPaused}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="StopEmulation_Click"
|
Name="StopEmulationMenuItem"
|
||||||
Header="{ext:Locale MenuBarOptionsStopEmulation}"
|
Header="{ext:Locale MenuBarOptionsStopEmulation}"
|
||||||
Icon="{ext:Icon fa-solid fa-stop}"
|
Icon="{ext:Icon fa-solid fa-stop}"
|
||||||
InputGesture="Escape"
|
InputGesture="Escape"
|
||||||
@ -233,20 +233,19 @@
|
|||||||
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" />
|
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="ScanAmiiboMenuItem"
|
Command="{Binding OpenAmiiboWindow}"
|
||||||
AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
|
AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
|
||||||
Click="OpenAmiiboWindow"
|
|
||||||
Header="{ext:Locale MenuBarActionsScanAmiibo}"
|
Header="{ext:Locale MenuBarActionsScanAmiibo}"
|
||||||
Icon="{ext:Icon mdi-cube-scan}"
|
Icon="{ext:Icon mdi-cube-scan}"
|
||||||
InputGesture="Ctrl + A"
|
InputGesture="Ctrl + A"
|
||||||
IsEnabled="{Binding IsAmiiboRequested}" />
|
IsEnabled="{Binding IsAmiiboRequested}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="ScanAmiiboMenuItemFromBin"
|
Command="{Binding OpenBinFile}"
|
||||||
AttachedToVisualTree="ScanBinAmiiboMenuItem_AttachedToVisualTree"
|
AttachedToVisualTree="ScanBinAmiiboMenuItem_AttachedToVisualTree"
|
||||||
Click="OpenBinFile"
|
|
||||||
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
||||||
Icon="{ext:Icon mdi-cube-scan}"
|
Icon="{ext:Icon mdi-cube-scan}"
|
||||||
IsVisible="{Binding CanScanAmiiboBinaries}"
|
IsVisible="{Binding CanScanAmiiboBinaries}"
|
||||||
|
InputGesture="Ctrl + B"
|
||||||
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding TakeScreenshot}"
|
Command="{Binding TakeScreenshot}"
|
||||||
@ -261,7 +260,7 @@
|
|||||||
InputGesture="{Binding ShowUiKey}"
|
InputGesture="{Binding ShowUiKey}"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenCheatManagerForCurrentApp"
|
Name="CheatManagerMenuItem"
|
||||||
Header="{ext:Locale GameListContextMenuManageCheat}"
|
Header="{ext:Locale GameListContextMenuManageCheat}"
|
||||||
Icon="{ext:Icon fa-solid fa-code}"
|
Icon="{ext:Icon fa-solid fa-code}"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
@ -276,52 +275,55 @@
|
|||||||
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" Icon="{ext:Icon mdi-folder-cog}" />
|
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" Icon="{ext:Icon mdi-folder-cog}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
<MenuItem Header="{ext:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsInstallFileTypes}" Click="InstallFileTypes_Click" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarToolsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click" IsEnabled="{Binding AreMimeTypesRegistered}" />
|
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBarToolsUninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem Header="{ext:Locale MenuBarToolsXCITrimmer}" IsEnabled="{Binding EnableNonGameRunningControls}" Click="OpenXCITrimmerWindow" Icon="{ext:Icon fa-solid fa-scissors}" />
|
<MenuItem Name="XciTrimmerMenuItem" Header="{ext:Locale MenuBarToolsXCITrimmer}" IsEnabled="{Binding EnableNonGameRunningControls}" Icon="{ext:Icon fa-solid fa-scissors}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}">
|
||||||
<MenuItem Header="{ext:Locale MenuBarViewWindow720}" Tag="1280 720" Click="ChangeWindowSize_Click" />
|
<MenuItem Name="WindowSize720PMenuItem" Header="{ext:Locale MenuBarViewWindow720}" CommandParameter="1280 720" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarViewWindow1080}" Tag="1920 1080" Click="ChangeWindowSize_Click" />
|
<MenuItem Name="WindowSize1080PMenuItem" Header="{ext:Locale MenuBarViewWindow1080}" CommandParameter="1920 1080" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarViewWindow1440}" Tag="2560 1440" Click="ChangeWindowSize_Click" />
|
<MenuItem Name="WindowSize1440PMenuItem" Header="{ext:Locale MenuBarViewWindow1440}" CommandParameter="2560 1440" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarViewWindow2160}" Tag="3840 2160" Click="ChangeWindowSize_Click" />
|
<MenuItem Name="WindowSize2160PMenuItem" Header="{ext:Locale MenuBarViewWindow2160}" CommandParameter="3840 2160" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelp}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelp}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenAboutWindow"
|
Name="AboutWindowMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpAbout}"
|
Header="{ext:Locale MenuBarHelpAbout}"
|
||||||
Icon="{ext:Icon fa-solid fa-circle-info}"
|
Icon="{ext:Icon fa-solid fa-circle-info}"
|
||||||
ToolTip.Tip="{ext:Locale OpenAboutTooltip}" />
|
ToolTip.Tip="{ext:Locale OpenAboutTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="UpdateMenuItem"
|
Name="UpdateMenuItem"
|
||||||
IsEnabled="{Binding CanUpdate}"
|
IsEnabled="{Binding CanUpdate}"
|
||||||
Click="CheckForUpdates"
|
|
||||||
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
||||||
Icon="{ext:Icon mdi-update}"
|
Icon="{ext:Icon mdi-update}"
|
||||||
ToolTip.Tip="{ext:Locale CheckUpdatesTooltip}" />
|
ToolTip.Tip="{ext:Locale CheckUpdatesTooltip}" />
|
||||||
|
<MenuItem
|
||||||
|
Name="CompatibilityListMenuItem"
|
||||||
|
Header="{ext:Locale CompatibilityListOpen}"
|
||||||
|
Icon="{ext:Icon mdi-gamepad}"/>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelpFaqAndGuides}" Icon="{ext:Icon fa-solid fa-question}" >
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelpFaqAndGuides}" Icon="{ext:Icon fa-solid fa-question}" >
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="MenuItem_OnClick"
|
Name="FaqMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpFaq}"
|
Header="{ext:Locale MenuBarHelpFaq}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
Tag="https://github.com/GreemDev/Ryujinx/wiki/FAQ-and-Troubleshooting"
|
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/FAQ-and-Troubleshooting"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="MenuItem_OnClick"
|
Name="SetupGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpSetup}"
|
Header="{ext:Locale MenuBarHelpSetup}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
Tag="https://github.com/GreemDev/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide"
|
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="MenuItem_OnClick"
|
Name="LdnGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-github}"
|
||||||
Tag="https://github.com/GreemDev/Ryujinx/wiki/Multiplayer%E2%80%90(LDN%E2%80%90Local%E2%80%90Wireless)%E2%80%90Guide"
|
CommandParameter="https://github.com/GreemDev/Ryujinx/wiki/Multiplayer%E2%80%90(LDN%E2%80%90Local%E2%80%90Wireless)%E2%80%90Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Layout;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
|
using Ryujinx.Ava.Utilities.Compat;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
@ -16,6 +18,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Main
|
namespace Ryujinx.Ava.UI.Views.Main
|
||||||
{
|
{
|
||||||
@ -33,9 +36,37 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
|
|
||||||
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
|
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
|
||||||
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
|
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
|
||||||
|
|
||||||
|
MiiAppletMenuItem.Command = new AsyncRelayCommand(OpenMiiApplet);
|
||||||
|
CloseRyujinxMenuItem.Command = new RelayCommand(CloseWindow);
|
||||||
|
OpenSettingsMenuItem.Command = new AsyncRelayCommand(OpenSettings);
|
||||||
|
PauseEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Pause());
|
||||||
|
ResumeEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Resume());
|
||||||
|
StopEmulationMenuItem.Command = new AsyncRelayCommand(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
||||||
|
CheatManagerMenuItem.Command = new AsyncRelayCommand(OpenCheatManagerForCurrentApp);
|
||||||
|
InstallFileTypesMenuItem.Command = new AsyncRelayCommand(InstallFileTypes);
|
||||||
|
UninstallFileTypesMenuItem.Command = new AsyncRelayCommand(UninstallFileTypes);
|
||||||
|
XciTrimmerMenuItem.Command = new AsyncRelayCommand(() => XCITrimmerWindow.Show(ViewModel));
|
||||||
|
AboutWindowMenuItem.Command = new AsyncRelayCommand(AboutWindow.Show);
|
||||||
|
CompatibilityListMenuItem.Command = new AsyncRelayCommand(CompatibilityList.Show);
|
||||||
|
|
||||||
|
UpdateMenuItem.Command = new AsyncRelayCommand(async () =>
|
||||||
|
{
|
||||||
|
if (Updater.CanUpdate(true))
|
||||||
|
await Updater.BeginUpdateAsync(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
FaqMenuItem.Command =
|
||||||
|
SetupGuideMenuItem.Command =
|
||||||
|
LdnGuideMenuItem.Command = new RelayCommand<string>(OpenHelper.OpenUrl);
|
||||||
|
|
||||||
|
WindowSize720PMenuItem.Command =
|
||||||
|
WindowSize1080PMenuItem.Command =
|
||||||
|
WindowSize1440PMenuItem.Command =
|
||||||
|
WindowSize2160PMenuItem.Command = new RelayCommand<string>(ChangeWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CheckBox[] GenerateToggleFileTypeItems() =>
|
private IEnumerable<CheckBox> GenerateToggleFileTypeItems() =>
|
||||||
Enum.GetValues<FileTypes>()
|
Enum.GetValues<FileTypes>()
|
||||||
.Select(it => (FileName: Enum.GetName(it)!, FileType: it))
|
.Select(it => (FileName: Enum.GetName(it)!, FileType: it))
|
||||||
.Select(it =>
|
.Select(it =>
|
||||||
@ -45,15 +76,13 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
|
IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
|
||||||
Command = MiniCommand.Create(() => Window.ToggleFileType(it.FileName))
|
Command = MiniCommand.Create(() => Window.ToggleFileType(it.FileName))
|
||||||
}
|
}
|
||||||
).ToArray();
|
);
|
||||||
|
|
||||||
private static MenuItem[] GenerateLanguageMenuItems()
|
private static IEnumerable<MenuItem> GenerateLanguageMenuItems()
|
||||||
{
|
{
|
||||||
List<MenuItem> menuItems = new();
|
const string LocalePath = "Ryujinx/Assets/locales.json";
|
||||||
|
|
||||||
string localePath = "Ryujinx/Assets/locales.json";
|
string languageJson = EmbeddedResources.ReadAllText(LocalePath);
|
||||||
|
|
||||||
string languageJson = EmbeddedResources.ReadAllText(localePath);
|
|
||||||
|
|
||||||
LocalesJson locales = JsonHelper.Deserialize(languageJson, LocalesJsonContext.Default.LocalesJson);
|
LocalesJson locales = JsonHelper.Deserialize(languageJson, LocalesJsonContext.Default.LocalesJson);
|
||||||
|
|
||||||
@ -68,20 +97,23 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
languageName = locales.Locales[index].Translations[language] == "" ? language : locales.Locales[index].Translations[language];
|
string tr = locales.Locales[index].Translations[language];
|
||||||
|
languageName = string.IsNullOrEmpty(tr)
|
||||||
|
? language
|
||||||
|
: tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem menuItem = new()
|
MenuItem menuItem = new()
|
||||||
{
|
{
|
||||||
Padding = new Thickness(10, 0, 0, 0),
|
Padding = new Thickness(15, 0, 0, 0),
|
||||||
Header = " " + languageName,
|
Margin = new Thickness(3, 0, 3, 0),
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
Header = languageName,
|
||||||
Command = MiniCommand.Create(() => MainWindowViewModel.ChangeLanguage(language))
|
Command = MiniCommand.Create(() => MainWindowViewModel.ChangeLanguage(language))
|
||||||
};
|
};
|
||||||
|
|
||||||
menuItems.Add(menuItem);
|
yield return menuItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return menuItems.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
@ -95,22 +127,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StopEmulation_Click(object sender, RoutedEventArgs e)
|
public async Task OpenSettings()
|
||||||
{
|
|
||||||
await ViewModel.AppHost?.ShowExitPrompt().OrCompleted()!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PauseEmulation_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
ViewModel.AppHost?.Pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResumeEmulation_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
ViewModel.AppHost?.Resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void OpenSettings(object sender, RoutedEventArgs e)
|
|
||||||
{
|
{
|
||||||
Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager);
|
Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager);
|
||||||
|
|
||||||
@ -123,7 +140,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
|
|
||||||
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
|
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
|
||||||
|
|
||||||
public async void OpenMiiApplet(object sender, RoutedEventArgs e)
|
public async Task OpenMiiApplet()
|
||||||
{
|
{
|
||||||
if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
|
if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
|
||||||
{
|
{
|
||||||
@ -131,13 +148,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void OpenAmiiboWindow(object sender, RoutedEventArgs e)
|
public async Task OpenCheatManagerForCurrentApp()
|
||||||
=> await ViewModel.OpenAmiiboWindow();
|
|
||||||
|
|
||||||
public async void OpenBinFile(object sender, RoutedEventArgs e)
|
|
||||||
=> await ViewModel.OpenBinFile();
|
|
||||||
|
|
||||||
public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e)
|
|
||||||
{
|
{
|
||||||
if (!ViewModel.IsGameRunning)
|
if (!ViewModel.IsGameRunning)
|
||||||
return;
|
return;
|
||||||
@ -165,7 +176,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
ViewModel.IsAmiiboBinRequested = ViewModel.IsAmiiboRequested && AmiiboBinReader.HasAmiiboKeyFile;
|
ViewModel.IsAmiiboBinRequested = ViewModel.IsAmiiboRequested && AmiiboBinReader.HasAmiiboKeyFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void InstallFileTypes_Click(object sender, RoutedEventArgs e)
|
private async Task InstallFileTypes()
|
||||||
{
|
{
|
||||||
ViewModel.AreMimeTypesRegistered = FileAssociationHelper.Install();
|
ViewModel.AreMimeTypesRegistered = FileAssociationHelper.Install();
|
||||||
if (ViewModel.AreMimeTypesRegistered)
|
if (ViewModel.AreMimeTypesRegistered)
|
||||||
@ -174,7 +185,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e)
|
private async Task UninstallFileTypes()
|
||||||
{
|
{
|
||||||
ViewModel.AreMimeTypesRegistered = !FileAssociationHelper.Uninstall();
|
ViewModel.AreMimeTypesRegistered = !FileAssociationHelper.Uninstall();
|
||||||
if (!ViewModel.AreMimeTypesRegistered)
|
if (!ViewModel.AreMimeTypesRegistered)
|
||||||
@ -183,11 +194,8 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ChangeWindowSize_Click(object sender, RoutedEventArgs e)
|
private void ChangeWindowSize(string resolution)
|
||||||
{
|
{
|
||||||
if (sender is not MenuItem { Tag: string resolution })
|
|
||||||
return;
|
|
||||||
|
|
||||||
(int resolutionWidth, int resolutionHeight) = resolution.Split(' ', 2)
|
(int resolutionWidth, int resolutionHeight) = resolution.Split(' ', 2)
|
||||||
.Into(parts =>
|
.Into(parts =>
|
||||||
(int.Parse(parts[0]), int.Parse(parts[1]))
|
(int.Parse(parts[0]), int.Parse(parts[1]))
|
||||||
@ -200,7 +208,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
double windowWidthScaled = (resolutionWidth * Program.WindowScaleFactor);
|
double windowWidthScaled = (resolutionWidth * Program.WindowScaleFactor);
|
||||||
double windowHeightScaled = ((resolutionHeight + barsHeight) * Program.WindowScaleFactor);
|
double windowHeightScaled = ((resolutionHeight + barsHeight) * Program.WindowScaleFactor);
|
||||||
|
|
||||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
ViewModel.WindowState = WindowState.Normal;
|
ViewModel.WindowState = WindowState.Normal;
|
||||||
|
|
||||||
@ -208,22 +216,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void CheckForUpdates(object sender, RoutedEventArgs e)
|
public void CloseWindow() => Window.Close();
|
||||||
{
|
|
||||||
if (Updater.CanUpdate(true))
|
|
||||||
await Updater.BeginUpdateAsync(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MenuItem_OnClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (sender is MenuItem { Tag: string url })
|
|
||||||
OpenHelper.OpenUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void OpenXCITrimmerWindow(object sender, RoutedEventArgs e) => await XCITrimmerWindow.Show(ViewModel);
|
|
||||||
|
|
||||||
public async void OpenAboutWindow(object sender, RoutedEventArgs e) => await AboutWindow.Show();
|
|
||||||
|
|
||||||
public void CloseWindow(object sender, RoutedEventArgs e) => Window.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
private void VSyncMode_PointerReleased(object sender, PointerReleasedEventArgs e)
|
private void VSyncMode_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||||
{
|
{
|
||||||
Window.ViewModel.ToggleVSyncMode();
|
Window.ViewModel.ToggleVSyncMode();
|
||||||
Logger.Info?.Print(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
|
Logger.Info?.PrintMsg(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||||
|
@ -26,7 +26,6 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
{
|
{
|
||||||
DataContext = ViewModel = window.ViewModel;
|
DataContext = ViewModel = window.ViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Sort_Checked(object sender, RoutedEventArgs args)
|
public void Sort_Checked(object sender, RoutedEventArgs args)
|
||||||
|
@ -29,15 +29,15 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Foreground="{DynamicResource SecondaryTextColor}"
|
Foreground="{DynamicResource SecondaryTextColor}"
|
||||||
TextDecorations="Underline"
|
TextDecorations="Underline"
|
||||||
Text="Game-specific hacks & tricks to alleviate performance issues or crashing. May cause issues." />
|
Text="Game-specific hacks & tricks to alleviate performance issues or crashing. Will cause issues." />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
ToolTip.Tip="{Binding Xc2MenuFixTooltip}">
|
ToolTip.Tip="{Binding DirtyHacks.Xc2MenuFixTooltip}">
|
||||||
<CheckBox
|
<CheckBox
|
||||||
Margin="0"
|
Margin="0"
|
||||||
IsChecked="{Binding Xc2MenuSoftlockFixEnabled}"/>
|
IsChecked="{Binding DirtyHacks.Xc2MenuSoftlockFix}"/>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="Xenoblade Chronicles 2 Menu Softlock Fix" />
|
Text="Xenoblade Chronicles 2 Menu Softlock Fix" />
|
||||||
@ -47,16 +47,20 @@
|
|||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
ToolTip.Tip="{Binding ShaderTranslationDelayTooltip}">
|
ToolTip.Tip="{Binding DirtyHacks.ShaderTranslationDelayTooltip}">
|
||||||
<CheckBox
|
<CheckBox
|
||||||
Margin="0"
|
Margin="0"
|
||||||
IsChecked="{Binding ShaderTranslationDelayEnabled}"/>
|
IsChecked="{Binding DirtyHacks.ShaderTranslationDelayEnabled}"/>
|
||||||
<TextBlock VerticalAlignment="Center"
|
<TextBlock VerticalAlignment="Center"
|
||||||
Text="Arbitrary Delay on Shader Translation"/>
|
Text="Arbitrary Delay on Shader Translation"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
IsVisible="{Binding DirtyHacks.ShaderTranslationDelayEnabled}"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
<Slider HorizontalAlignment="Center"
|
<Slider HorizontalAlignment="Center"
|
||||||
Value="{Binding ShaderTranslationDelay}"
|
Value="{Binding DirtyHacks.ShaderTranslationDelay}"
|
||||||
ToolTip.Tip="{Binding ShaderTranslationDelay}"
|
|
||||||
Width="175"
|
Width="175"
|
||||||
Margin="0,-3,0,0"
|
Margin="0,-3,0,0"
|
||||||
Height="32"
|
Height="32"
|
||||||
@ -68,6 +72,9 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Minimum="1"
|
Minimum="1"
|
||||||
Maximum="1000" />
|
Maximum="1000" />
|
||||||
|
<TextBlock Margin="5,0"
|
||||||
|
Text="{Binding DirtyHacks.ShaderTranslationDelayValueText}"/>
|
||||||
|
</StackPanel>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Settings
|
namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
{
|
{
|
||||||
public partial class SettingsHacksView : UserControl
|
public partial class SettingsHacksView : UserControl
|
||||||
{
|
{
|
||||||
public SettingsViewModel ViewModel;
|
|
||||||
|
|
||||||
public SettingsHacksView()
|
public SettingsHacksView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
<KeyBinding Gesture="F9" Command="{Binding ToggleDockMode}" />
|
<KeyBinding Gesture="F9" Command="{Binding ToggleDockMode}" />
|
||||||
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
||||||
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
||||||
|
<KeyBinding Gesture="Ctrl+B" Command="{Binding OpenBinFile}" />
|
||||||
</Window.KeyBindings>
|
</Window.KeyBindings>
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*">
|
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*">
|
||||||
<helpers:OffscreenTextBox IsEnabled="False" Opacity="0" Name="HiddenTextBox" IsHitTestVisible="False" IsTabStop="False" />
|
<helpers:OffscreenTextBox IsEnabled="False" Opacity="0" Name="HiddenTextBox" IsHitTestVisible="False" IsTabStop="False" />
|
||||||
|
@ -170,7 +170,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
{
|
{
|
||||||
var ldnGameDataArray = e.LdnData.ToList();
|
var ldnGameDataArray = e.LdnData.ToList();
|
||||||
ViewModel.LdnData.Clear();
|
ViewModel.LdnData.Clear();
|
||||||
foreach (var application in ViewModel.Applications)
|
foreach (var application in ViewModel.Applications.Where(it => it.HasControlHolder))
|
||||||
{
|
{
|
||||||
ref var controlHolder = ref application.ControlHolder.Value;
|
ref var controlHolder = ref application.ControlHolder.Value;
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
Padding="10"
|
Padding="10"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
MinHeight="0"
|
MinHeight="0"
|
||||||
|
ToolTip.Tip="{Binding Path}"
|
||||||
Click="OpenLocation">
|
Click="OpenLocation">
|
||||||
<ui:SymbolIcon
|
<ui:SymbolIcon
|
||||||
Symbol="OpenFolder"
|
Symbol="OpenFolder"
|
||||||
|
@ -87,7 +87,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
NavPanel.Content = LoggingPage;
|
NavPanel.Content = LoggingPage;
|
||||||
break;
|
break;
|
||||||
case nameof(HacksPage):
|
case nameof(HacksPage):
|
||||||
HacksPage.ViewModel = ViewModel;
|
HacksPage.DataContext = ViewModel;
|
||||||
NavPanel.Content = HacksPage;
|
NavPanel.Content = HacksPage;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
</Panel>
|
</Panel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
<DataTemplate
|
<DataTemplate
|
||||||
DataType="viewModels:TitleUpdateViewNoUpdateSentinal">
|
DataType="viewModels:TitleUpdateViewModelNoUpdate">
|
||||||
<Panel
|
<Panel
|
||||||
Height="33"
|
Height="33"
|
||||||
Margin="10">
|
Margin="10">
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
||||||
|
|
||||||
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0;
|
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0 && !ControlHolder.ByteSpan.IsZeros();
|
||||||
|
|
||||||
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using DynamicData;
|
using DynamicData;
|
||||||
|
using DynamicData.Kernel;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac;
|
using LibHac;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
@ -75,11 +76,11 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
TitleUpdates = _titleUpdates.AsObservableCache();
|
TitleUpdates = _titleUpdates.AsObservableCache();
|
||||||
DownloadableContents = _downloadableContents.AsObservableCache();
|
DownloadableContents = _downloadableContents.AsObservableCache();
|
||||||
|
|
||||||
_nspIcon = EmbeddedResources.Read("Ryujinx.Assets.UIImages.Icon_NSP.png");
|
_nspIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSP.png");
|
||||||
_xciIcon = EmbeddedResources.Read("Ryujinx.Assets.UIImages.Icon_XCI.png");
|
_xciIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_XCI.png");
|
||||||
_ncaIcon = EmbeddedResources.Read("Ryujinx.Assets.UIImages.Icon_NCA.png");
|
_ncaIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NCA.png");
|
||||||
_nroIcon = EmbeddedResources.Read("Ryujinx.Assets.UIImages.Icon_NRO.png");
|
_nroIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NRO.png");
|
||||||
_nsoIcon = EmbeddedResources.Read("Ryujinx.Assets.UIImages.Icon_NSO.png");
|
_nsoIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSO.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
|
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
|
||||||
@ -1069,10 +1070,11 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
{
|
{
|
||||||
if (update == null) return false;
|
if (update == null) return false;
|
||||||
|
|
||||||
var currentlySelected = TitleUpdates.Items.FindFirst(it =>
|
var currentlySelected = TitleUpdates.Items.FirstOrOptional(it =>
|
||||||
it.TitleUpdate.TitleIdBase == update.TitleIdBase && it.IsSelected);
|
it.TitleUpdate.TitleIdBase == update.TitleIdBase && it.IsSelected);
|
||||||
|
|
||||||
var shouldSelect = currentlySelected.Check(curr => curr.TitleUpdate?.Version < update.Version);
|
var shouldSelect = !currentlySelected.HasValue ||
|
||||||
|
currentlySelected.Value.TitleUpdate.Version < update.Version;
|
||||||
|
|
||||||
_titleUpdates.AddOrUpdate((update, shouldSelect));
|
_titleUpdates.AddOrUpdate((update, shouldSelect));
|
||||||
|
|
||||||
@ -1463,7 +1465,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
TitleUpdatesHelper.LoadTitleUpdatesJson(_virtualFileSystem, application.IdBase);
|
TitleUpdatesHelper.LoadTitleUpdatesJson(_virtualFileSystem, application.IdBase);
|
||||||
it.AddOrUpdate(savedUpdates);
|
it.AddOrUpdate(savedUpdates);
|
||||||
|
|
||||||
var selectedUpdate = savedUpdates.FindFirst(update => update.IsSelected);
|
var selectedUpdate = savedUpdates.FirstOrOptional(update => update.IsSelected);
|
||||||
|
|
||||||
if (TryGetTitleUpdatesFromFile(application.Path, out var bundledUpdates))
|
if (TryGetTitleUpdatesFromFile(application.Path, out var bundledUpdates))
|
||||||
{
|
{
|
||||||
@ -1475,9 +1477,10 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
if (!savedUpdateLookup.Contains(update))
|
if (!savedUpdateLookup.Contains(update))
|
||||||
{
|
{
|
||||||
bool shouldSelect = false;
|
bool shouldSelect = false;
|
||||||
if (selectedUpdate.Check(su => su.Update?.Version < update.Version))
|
if (!selectedUpdate.HasValue || selectedUpdate.Value.Item1.Version < update.Version)
|
||||||
{
|
{
|
||||||
shouldSelect = true;
|
shouldSelect = true;
|
||||||
|
if (selectedUpdate.HasValue)
|
||||||
_titleUpdates.AddOrUpdate((selectedUpdate.Value.Update, false));
|
_titleUpdates.AddOrUpdate((selectedUpdate.Value.Update, false));
|
||||||
selectedUpdate = (update, true);
|
selectedUpdate = (update, true);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Gommon;
|
||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -22,7 +23,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId;
|
LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId;
|
||||||
|
|
||||||
return new Array(receivedData.Where(game =>
|
return new Array(receivedData.Where(game =>
|
||||||
communicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16))
|
communicationId.Items.Contains(game.TitleId.ToULong())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
153
src/Ryujinx/Utilities/Compat/CompatibilityCsv.cs
Normal file
153
src/Ryujinx/Utilities/Compat/CompatibilityCsv.cs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
using Gommon;
|
||||||
|
using nietras.SeparatedValues;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
{
|
||||||
|
public class CompatibilityCsv
|
||||||
|
{
|
||||||
|
public static CompatibilityCsv Shared { get; set; }
|
||||||
|
|
||||||
|
public CompatibilityCsv(SepReader reader)
|
||||||
|
{
|
||||||
|
var entries = new List<CompatibilityEntry>();
|
||||||
|
|
||||||
|
foreach (var row in reader)
|
||||||
|
{
|
||||||
|
entries.Add(new CompatibilityEntry(reader.Header, row));
|
||||||
|
}
|
||||||
|
|
||||||
|
Entries = entries.Where(x => x.Status != null)
|
||||||
|
.OrderBy(it => it.GameName).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompatibilityEntry[] Entries { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CompatibilityEntry
|
||||||
|
{
|
||||||
|
public CompatibilityEntry(SepReaderHeader header, SepReader.Row row)
|
||||||
|
{
|
||||||
|
if (row.ColCount != header.ColNames.Count)
|
||||||
|
throw new InvalidDataException($"CSV row {row.RowIndex} ({row.ToString()}) has mismatched column count");
|
||||||
|
|
||||||
|
var titleIdRow = ColStr(row[header.IndexOf("\"extracted_game_id\"")]);
|
||||||
|
TitleId = !string.IsNullOrEmpty(titleIdRow)
|
||||||
|
? titleIdRow
|
||||||
|
: default(Optional<string>);
|
||||||
|
|
||||||
|
var issueTitleRow = ColStr(row[header.IndexOf("\"issue_title\"")]);
|
||||||
|
if (TitleId.HasValue)
|
||||||
|
issueTitleRow = issueTitleRow.ReplaceIgnoreCase($" - {TitleId}", string.Empty);
|
||||||
|
|
||||||
|
GameName = issueTitleRow.Trim().Trim('"');
|
||||||
|
|
||||||
|
IssueLabels = ColStr(row[header.IndexOf("\"issue_labels\"")]).Split(';');
|
||||||
|
Status = ColStr(row[header.IndexOf("\"extracted_status\"")]).ToLower() switch
|
||||||
|
{
|
||||||
|
"playable" => LocaleKeys.CompatibilityListPlayable,
|
||||||
|
"ingame" => LocaleKeys.CompatibilityListIngame,
|
||||||
|
"menus" => LocaleKeys.CompatibilityListMenus,
|
||||||
|
"boots" => LocaleKeys.CompatibilityListBoots,
|
||||||
|
"nothing" => LocaleKeys.CompatibilityListNothing,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (DateTime.TryParse(ColStr(row[header.IndexOf("\"last_event_date\"")]), out var dt))
|
||||||
|
LastEvent = dt;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
string ColStr(SepReader.Col col) => col.ToString().Trim('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GameName { get; }
|
||||||
|
public Optional<string> TitleId { get; }
|
||||||
|
public string[] IssueLabels { get; }
|
||||||
|
public LocaleKeys? Status { get; }
|
||||||
|
public DateTime LastEvent { get; }
|
||||||
|
|
||||||
|
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
||||||
|
public string FormattedTitleId => TitleId
|
||||||
|
.OrElse(new string(' ', 16));
|
||||||
|
|
||||||
|
public string FormattedIssueLabels => IssueLabels
|
||||||
|
.Where(it => !it.StartsWithIgnoreCase("status"))
|
||||||
|
.Select(FormatLabelName)
|
||||||
|
.JoinToString(", ");
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder("CompatibilityEntry: {");
|
||||||
|
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
|
||||||
|
sb.Append($"{nameof(TitleId)}={TitleId}, ");
|
||||||
|
sb.Append($"{nameof(IssueLabels)}=\"{IssueLabels}\", ");
|
||||||
|
sb.Append($"{nameof(Status)}=\"{Status}\", ");
|
||||||
|
sb.Append($"{nameof(LastEvent)}=\"{LastEvent}\"");
|
||||||
|
sb.Append('}');
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FormatLabelName(string labelName) => labelName.ToLower() switch
|
||||||
|
{
|
||||||
|
"audio" => "Audio",
|
||||||
|
"bug" => "Bug",
|
||||||
|
"cpu" => "CPU",
|
||||||
|
"gpu" => "GPU",
|
||||||
|
"gui" => "GUI",
|
||||||
|
"help wanted" => "Help Wanted",
|
||||||
|
"horizon" => "Horizon",
|
||||||
|
"infra" => "Project Infra",
|
||||||
|
"invalid" => "Invalid",
|
||||||
|
"kernel" => "Kernel",
|
||||||
|
"ldn" => "LDN",
|
||||||
|
"linux" => "Linux",
|
||||||
|
"macos" => "macOS",
|
||||||
|
"question" => "Question",
|
||||||
|
"windows" => "Windows",
|
||||||
|
"graphics-backend:opengl" => "Graphics: OpenGL",
|
||||||
|
"graphics-backend:vulkan" => "Graphics: Vulkan",
|
||||||
|
"ldn-works" => "LDN Works",
|
||||||
|
"ldn-untested" => "LDN Untested",
|
||||||
|
"ldn-broken" => "LDN Broken",
|
||||||
|
"ldn-partial" => "Partial LDN",
|
||||||
|
"nvdec" => "NVDEC",
|
||||||
|
"services" => "NX Services",
|
||||||
|
"services-horizon" => "Horizon OS Services",
|
||||||
|
"slow" => "Runs Slow",
|
||||||
|
"crash" => "Crashes",
|
||||||
|
"deadlock" => "Deadlock",
|
||||||
|
"regression" => "Regression",
|
||||||
|
"opengl" => "OpenGL",
|
||||||
|
"opengl-backend-bug" => "OpenGL Backend Bug",
|
||||||
|
"vulkan-backend-bug" => "Vulkan Backend Bug",
|
||||||
|
"mac-bug" => "Mac-specific Bug(s)",
|
||||||
|
"amd-vendor-bug" => "AMD GPU Bug",
|
||||||
|
"intel-vendor-bug" => "Intel GPU Bug",
|
||||||
|
"loader-allocator" => "Loader Allocator",
|
||||||
|
"audout" => "AudOut",
|
||||||
|
"32-bit" => "32-bit Game",
|
||||||
|
"UE4" => "Unreal Engine 4",
|
||||||
|
"homebrew" => "Homebrew Content",
|
||||||
|
"online-broken" => "Online Broken",
|
||||||
|
_ => Capitalize(labelName)
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string Capitalize(string value)
|
||||||
|
{
|
||||||
|
if (value == string.Empty)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var firstChar = value[0];
|
||||||
|
var rest = value[1..];
|
||||||
|
|
||||||
|
return $"{char.ToUpper(firstChar)}{rest}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/Ryujinx/Utilities/Compat/CompatibilityList.axaml
Normal file
76
src/Ryujinx/Utilities/Compat/CompatibilityList.axaml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:Ryujinx.Ava.Utilities.Compat"
|
||||||
|
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
|
||||||
|
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
|
||||||
|
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Ryujinx.Ava.Utilities.Compat.CompatibilityList"
|
||||||
|
x:DataType="local:CompatibilityViewModel">
|
||||||
|
<UserControl.DataContext>
|
||||||
|
<local:CompatibilityViewModel />
|
||||||
|
</UserControl.DataContext>
|
||||||
|
<Grid RowDefinitions="*,Auto,*">
|
||||||
|
<Grid
|
||||||
|
Grid.Row="0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
ColumnDefinitions="Auto,*"
|
||||||
|
Margin="0 0 0 10">
|
||||||
|
<ui:FontIcon
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
|
||||||
|
Glyph="{helpers:GlyphValueConverter Important}" />
|
||||||
|
<!-- NOTE: aligning to bottom for better visual alignment with glyph -->
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="5, 0, 0, 0"
|
||||||
|
FontStyle="Italic"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{ext:Locale CompatibilityListWarning}" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto">
|
||||||
|
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
|
||||||
|
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
|
||||||
|
<TextBlock Grid.Column="2" Margin="-10, 0, 0, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
|
||||||
|
</Grid>
|
||||||
|
<ScrollViewer Grid.Row="2">
|
||||||
|
<ListBox Margin="0,5, 0, 0"
|
||||||
|
Background="Transparent"
|
||||||
|
ItemsSource="{Binding CurrentEntries}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate DataType="{x:Type local:CompatibilityEntry}">
|
||||||
|
<Grid Width="750" ColumnDefinitions="Auto,Auto,Auto,*"
|
||||||
|
Margin="5">
|
||||||
|
<TextBlock Grid.Column="0"
|
||||||
|
Text="{Binding GameName}"
|
||||||
|
Width="320"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Width="135"
|
||||||
|
Padding="7, 0, 0, 0"
|
||||||
|
FontFamily="{StaticResource JetBrainsMono}"
|
||||||
|
Text="{Binding FormattedTitleId}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock Grid.Column="2"
|
||||||
|
Padding="7, 0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding LocalizedStatus}"
|
||||||
|
Width="85"
|
||||||
|
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
||||||
|
TextWrapping="NoWrap" />
|
||||||
|
<TextBlock Grid.Column="3"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding FormattedIssueLabels}"
|
||||||
|
TextWrapping="WrapWithOverflow" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
65
src/Ryujinx/Utilities/Compat/CompatibilityList.axaml.cs
Normal file
65
src/Ryujinx/Utilities/Compat/CompatibilityList.axaml.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using nietras.SeparatedValues;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
{
|
||||||
|
public partial class CompatibilityList : UserControl
|
||||||
|
{
|
||||||
|
public static async Task Show()
|
||||||
|
{
|
||||||
|
if (CompatibilityCsv.Shared is null)
|
||||||
|
{
|
||||||
|
await using Stream csvStream = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
|
||||||
|
csvStream.Position = 0;
|
||||||
|
|
||||||
|
CompatibilityCsv.Shared = new CompatibilityCsv(Sep.Reader().From(csvStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentDialog contentDialog = new()
|
||||||
|
{
|
||||||
|
PrimaryButtonText = string.Empty,
|
||||||
|
SecondaryButtonText = string.Empty,
|
||||||
|
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
||||||
|
Content = new CompatibilityList
|
||||||
|
{
|
||||||
|
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Style closeButton = new(x => x.Name("CloseButton"));
|
||||||
|
closeButton.Setters.Add(new Setter(WidthProperty, 80d));
|
||||||
|
|
||||||
|
Style closeButtonParent = new(x => x.Name("CommandSpace"));
|
||||||
|
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, Avalonia.Layout.HorizontalAlignment.Right));
|
||||||
|
|
||||||
|
contentDialog.Styles.Add(closeButton);
|
||||||
|
contentDialog.Styles.Add(closeButtonParent);
|
||||||
|
|
||||||
|
await ContentDialogHelper.ShowAsync(contentDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompatibilityList()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TextBox_OnTextChanged(object? sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (DataContext is not CompatibilityViewModel cvm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sender is not TextBox searchBox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cvm.Search(searchBox.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
src/Ryujinx/Utilities/Compat/CompatibilityViewModel.cs
Normal file
59
src/Ryujinx/Utilities/Compat/CompatibilityViewModel.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using ExCSS;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
{
|
||||||
|
public partial class CompatibilityViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
[ObservableProperty] private bool _onlyShowOwnedGames = true;
|
||||||
|
|
||||||
|
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Shared.Entries;
|
||||||
|
private readonly string[] _ownedGameTitleIds = [];
|
||||||
|
private readonly ApplicationLibrary _appLibrary;
|
||||||
|
|
||||||
|
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
||||||
|
? _currentEntries.Where(x =>
|
||||||
|
x.TitleId.Check(tid => _ownedGameTitleIds.ContainsIgnoreCase(tid))
|
||||||
|
|| _appLibrary.Applications.Items.Any(a => a.Name.EqualsIgnoreCase(x.GameName)))
|
||||||
|
: _currentEntries;
|
||||||
|
|
||||||
|
public CompatibilityViewModel() {}
|
||||||
|
|
||||||
|
public CompatibilityViewModel(ApplicationLibrary appLibrary)
|
||||||
|
{
|
||||||
|
_appLibrary = appLibrary;
|
||||||
|
_ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
||||||
|
|
||||||
|
PropertyChanged += (_, args) =>
|
||||||
|
{
|
||||||
|
if (args.PropertyName is nameof(OnlyShowOwnedGames))
|
||||||
|
OnPropertyChanged(nameof(CurrentEntries));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Search(string searchTerm)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(searchTerm))
|
||||||
|
{
|
||||||
|
SetEntries(CompatibilityCsv.Shared.Entries);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEntries(CompatibilityCsv.Shared.Entries.Where(x =>
|
||||||
|
x.GameName.ContainsIgnoreCase(searchTerm)
|
||||||
|
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEntries(IEnumerable<CompatibilityEntry> entries)
|
||||||
|
{
|
||||||
|
#pragma warning disable MVVMTK0034
|
||||||
|
_currentEntries = entries.ToList();
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
|
OnPropertyChanged(nameof(CurrentEntries));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -272,7 +272,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
public MemoryManagerMode MemoryManagerMode { get; set; }
|
public MemoryManagerMode MemoryManagerMode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Expands the RAM amount on the emulated system from 4GiB to 8GiB
|
/// Expands the RAM amount on the emulated system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemoryConfiguration DramSize { get; set; }
|
public MemoryConfiguration DramSize { get; set; }
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Utilities.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Utilities.Configuration.UI;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
@ -10,189 +11,197 @@ using Ryujinx.HLE;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
public void Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath)
|
public void Load(ConfigurationFileFormat cff, string configurationFilePath)
|
||||||
{
|
{
|
||||||
bool configurationFileUpdated = false;
|
bool configurationFileUpdated = false;
|
||||||
|
|
||||||
if (configurationFileFormat.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
|
if (cff.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
|
RyuLogger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {cff.Version}, loading default.");
|
||||||
|
|
||||||
LoadDefault();
|
LoadDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 2)
|
foreach ((int newVersion, Action<ConfigurationFileFormat> migratorFunction)
|
||||||
|
in _migrations.OrderBy(x => x.Key))
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 2.");
|
if (cff.Version >= newVersion)
|
||||||
|
continue;
|
||||||
|
|
||||||
configurationFileFormat.SystemRegion = Region.USA;
|
RyuLogger.Warning?.Print(LogClass.Application,
|
||||||
|
$"Outdated configuration version {cff.Version}, migrating to version {newVersion}.");
|
||||||
|
|
||||||
|
migratorFunction(cff);
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 3)
|
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
||||||
|
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
|
||||||
|
ShowConfirmExit.Value = cff.ShowConfirmExit;
|
||||||
|
IgnoreApplet.Value = cff.IgnoreApplet;
|
||||||
|
RememberWindowState.Value = cff.RememberWindowState;
|
||||||
|
ShowTitleBar.Value = cff.ShowTitleBar;
|
||||||
|
EnableHardwareAcceleration.Value = cff.EnableHardwareAcceleration;
|
||||||
|
HideCursor.Value = cff.HideCursor;
|
||||||
|
|
||||||
|
Logger.EnableFileLog.Value = cff.EnableFileLog;
|
||||||
|
Logger.EnableDebug.Value = cff.LoggingEnableDebug;
|
||||||
|
Logger.EnableStub.Value = cff.LoggingEnableStub;
|
||||||
|
Logger.EnableInfo.Value = cff.LoggingEnableInfo;
|
||||||
|
Logger.EnableWarn.Value = cff.LoggingEnableWarn;
|
||||||
|
Logger.EnableError.Value = cff.LoggingEnableError;
|
||||||
|
Logger.EnableTrace.Value = cff.LoggingEnableTrace;
|
||||||
|
Logger.EnableGuest.Value = cff.LoggingEnableGuest;
|
||||||
|
Logger.EnableFsAccessLog.Value = cff.LoggingEnableFsAccessLog;
|
||||||
|
Logger.FilteredClasses.Value = cff.LoggingFilteredClasses;
|
||||||
|
Logger.GraphicsDebugLevel.Value = cff.LoggingGraphicsDebugLevel;
|
||||||
|
|
||||||
|
Graphics.ResScale.Value = cff.ResScale;
|
||||||
|
Graphics.ResScaleCustom.Value = cff.ResScaleCustom;
|
||||||
|
Graphics.MaxAnisotropy.Value = cff.MaxAnisotropy;
|
||||||
|
Graphics.AspectRatio.Value = cff.AspectRatio;
|
||||||
|
Graphics.ShadersDumpPath.Value = cff.GraphicsShadersDumpPath;
|
||||||
|
Graphics.BackendThreading.Value = cff.BackendThreading;
|
||||||
|
Graphics.GraphicsBackend.Value = cff.GraphicsBackend;
|
||||||
|
Graphics.PreferredGpu.Value = cff.PreferredGpu;
|
||||||
|
Graphics.AntiAliasing.Value = cff.AntiAliasing;
|
||||||
|
Graphics.ScalingFilter.Value = cff.ScalingFilter;
|
||||||
|
Graphics.ScalingFilterLevel.Value = cff.ScalingFilterLevel;
|
||||||
|
Graphics.VSyncMode.Value = cff.VSyncMode;
|
||||||
|
Graphics.EnableCustomVSyncInterval.Value = cff.EnableCustomVSyncInterval;
|
||||||
|
Graphics.CustomVSyncInterval.Value = cff.CustomVSyncInterval;
|
||||||
|
Graphics.EnableShaderCache.Value = cff.EnableShaderCache;
|
||||||
|
Graphics.EnableTextureRecompression.Value = cff.EnableTextureRecompression;
|
||||||
|
Graphics.EnableMacroHLE.Value = cff.EnableMacroHLE;
|
||||||
|
Graphics.EnableColorSpacePassthrough.Value = cff.EnableColorSpacePassthrough;
|
||||||
|
|
||||||
|
System.Language.Value = cff.SystemLanguage;
|
||||||
|
System.Region.Value = cff.SystemRegion;
|
||||||
|
System.TimeZone.Value = cff.SystemTimeZone;
|
||||||
|
System.SystemTimeOffset.Value = cff.SystemTimeOffset;
|
||||||
|
System.EnableDockedMode.Value = cff.DockedMode;
|
||||||
|
System.EnablePtc.Value = cff.EnablePtc;
|
||||||
|
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
|
||||||
|
System.EnableInternetAccess.Value = cff.EnableInternetAccess;
|
||||||
|
System.EnableFsIntegrityChecks.Value = cff.EnableFsIntegrityChecks;
|
||||||
|
System.FsGlobalAccessLogMode.Value = cff.FsGlobalAccessLogMode;
|
||||||
|
System.AudioBackend.Value = cff.AudioBackend;
|
||||||
|
System.AudioVolume.Value = cff.AudioVolume;
|
||||||
|
System.MemoryManagerMode.Value = cff.MemoryManagerMode;
|
||||||
|
System.DramSize.Value = cff.DramSize;
|
||||||
|
System.IgnoreMissingServices.Value = cff.IgnoreMissingServices;
|
||||||
|
System.UseHypervisor.Value = cff.UseHypervisor;
|
||||||
|
|
||||||
|
UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn;
|
||||||
|
UI.GuiColumns.IconColumn.Value = cff.GuiColumns.IconColumn;
|
||||||
|
UI.GuiColumns.AppColumn.Value = cff.GuiColumns.AppColumn;
|
||||||
|
UI.GuiColumns.DevColumn.Value = cff.GuiColumns.DevColumn;
|
||||||
|
UI.GuiColumns.VersionColumn.Value = cff.GuiColumns.VersionColumn;
|
||||||
|
UI.GuiColumns.TimePlayedColumn.Value = cff.GuiColumns.TimePlayedColumn;
|
||||||
|
UI.GuiColumns.LastPlayedColumn.Value = cff.GuiColumns.LastPlayedColumn;
|
||||||
|
UI.GuiColumns.FileExtColumn.Value = cff.GuiColumns.FileExtColumn;
|
||||||
|
UI.GuiColumns.FileSizeColumn.Value = cff.GuiColumns.FileSizeColumn;
|
||||||
|
UI.GuiColumns.PathColumn.Value = cff.GuiColumns.PathColumn;
|
||||||
|
UI.ColumnSort.SortColumnId.Value = cff.ColumnSort.SortColumnId;
|
||||||
|
UI.ColumnSort.SortAscending.Value = cff.ColumnSort.SortAscending;
|
||||||
|
UI.GameDirs.Value = cff.GameDirs;
|
||||||
|
UI.AutoloadDirs.Value = cff.AutoloadDirs ?? [];
|
||||||
|
UI.ShownFileTypes.NSP.Value = cff.ShownFileTypes.NSP;
|
||||||
|
UI.ShownFileTypes.PFS0.Value = cff.ShownFileTypes.PFS0;
|
||||||
|
UI.ShownFileTypes.XCI.Value = cff.ShownFileTypes.XCI;
|
||||||
|
UI.ShownFileTypes.NCA.Value = cff.ShownFileTypes.NCA;
|
||||||
|
UI.ShownFileTypes.NRO.Value = cff.ShownFileTypes.NRO;
|
||||||
|
UI.ShownFileTypes.NSO.Value = cff.ShownFileTypes.NSO;
|
||||||
|
UI.LanguageCode.Value = cff.LanguageCode;
|
||||||
|
UI.BaseStyle.Value = cff.BaseStyle;
|
||||||
|
UI.GameListViewMode.Value = cff.GameListViewMode;
|
||||||
|
UI.ShowNames.Value = cff.ShowNames;
|
||||||
|
UI.IsAscendingOrder.Value = cff.IsAscendingOrder;
|
||||||
|
UI.GridSize.Value = cff.GridSize;
|
||||||
|
UI.ApplicationSort.Value = cff.ApplicationSort;
|
||||||
|
UI.StartFullscreen.Value = cff.StartFullscreen;
|
||||||
|
UI.ShowConsole.Value = cff.ShowConsole;
|
||||||
|
UI.WindowStartup.WindowSizeWidth.Value = cff.WindowStartup.WindowSizeWidth;
|
||||||
|
UI.WindowStartup.WindowSizeHeight.Value = cff.WindowStartup.WindowSizeHeight;
|
||||||
|
UI.WindowStartup.WindowPositionX.Value = cff.WindowStartup.WindowPositionX;
|
||||||
|
UI.WindowStartup.WindowPositionY.Value = cff.WindowStartup.WindowPositionY;
|
||||||
|
UI.WindowStartup.WindowMaximized.Value = cff.WindowStartup.WindowMaximized;
|
||||||
|
|
||||||
|
Hid.EnableKeyboard.Value = cff.EnableKeyboard;
|
||||||
|
Hid.EnableMouse.Value = cff.EnableMouse;
|
||||||
|
Hid.Hotkeys.Value = cff.Hotkeys;
|
||||||
|
Hid.InputConfig.Value = cff.InputConfig ?? [];
|
||||||
|
|
||||||
|
Multiplayer.LanInterfaceId.Value = cff.MultiplayerLanInterfaceId;
|
||||||
|
Multiplayer.Mode.Value = cff.MultiplayerMode;
|
||||||
|
Multiplayer.DisableP2p.Value = cff.MultiplayerDisableP2p;
|
||||||
|
Multiplayer.LdnPassphrase.Value = cff.MultiplayerLdnPassphrase;
|
||||||
|
Multiplayer.LdnServer.Value = cff.LdnServer;
|
||||||
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 3.");
|
Hacks.ShowDirtyHacks.Value = cff.ShowDirtyHacks;
|
||||||
|
|
||||||
configurationFileFormat.SystemTimeZone = "UTC";
|
DirtyHacks hacks = new (cff.DirtyHacks ?? []);
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix);
|
||||||
|
|
||||||
|
Hacks.EnableShaderTranslationDelay.Value = hacks.IsEnabled(DirtyHack.ShaderTranslationDelay);
|
||||||
|
Hacks.ShaderTranslationDelay.Value = hacks[DirtyHack.ShaderTranslationDelay].CoerceAtLeast(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 4)
|
if (configurationFileUpdated)
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
|
ToFileFormat().SaveConfig(configurationFilePath);
|
||||||
|
|
||||||
configurationFileFormat.MaxAnisotropy = -1;
|
RyuLogger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
|
||||||
|
}
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 5)
|
private static readonly Dictionary<int, Action<ConfigurationFileFormat>> _migrations =
|
||||||
|
Collections.NewDictionary<int, Action<ConfigurationFileFormat>>(
|
||||||
|
(2, static cff => cff.SystemRegion = Region.USA),
|
||||||
|
(3, static cff => cff.SystemTimeZone = "UTC"),
|
||||||
|
(4, static cff => cff.MaxAnisotropy = -1),
|
||||||
|
(5, static cff => cff.SystemTimeOffset = 0),
|
||||||
|
(8, static cff => cff.EnablePtc = true),
|
||||||
|
(9, static cff =>
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 5.");
|
cff.ColumnSort = new ColumnSort { SortColumnId = 0, SortAscending = false };
|
||||||
|
cff.Hotkeys = new KeyboardHotkeys { ToggleVSyncMode = Key.F1 };
|
||||||
configurationFileFormat.SystemTimeOffset = 0;
|
}),
|
||||||
|
(10, static cff => cff.AudioBackend = AudioBackend.OpenAl),
|
||||||
configurationFileUpdated = true;
|
(11, static cff =>
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 8)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8.");
|
cff.ResScale = 1;
|
||||||
|
cff.ResScaleCustom = 1.0f;
|
||||||
configurationFileFormat.EnablePtc = true;
|
}),
|
||||||
|
(12, static cff => cff.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None),
|
||||||
configurationFileUpdated = true;
|
// 13 -> LDN1
|
||||||
}
|
(14, static cff => cff.CheckUpdatesOnStart = true),
|
||||||
|
(16, static cff => cff.EnableShaderCache = true),
|
||||||
if (configurationFileFormat.Version < 9)
|
(17, static cff => cff.StartFullscreen = false),
|
||||||
|
(18, static cff => cff.AspectRatio = AspectRatio.Fixed16x9),
|
||||||
|
// 19 -> LDN2
|
||||||
|
(20, static cff => cff.ShowConfirmExit = true),
|
||||||
|
(21, static cff =>
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 9.");
|
|
||||||
|
|
||||||
configurationFileFormat.ColumnSort = new ColumnSort
|
|
||||||
{
|
|
||||||
SortColumnId = 0,
|
|
||||||
SortAscending = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = Key.F1,
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 10)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 10.");
|
|
||||||
|
|
||||||
configurationFileFormat.AudioBackend = AudioBackend.OpenAl;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 11)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 11.");
|
|
||||||
|
|
||||||
configurationFileFormat.ResScale = 1;
|
|
||||||
configurationFileFormat.ResScaleCustom = 1.0f;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 12)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
|
|
||||||
|
|
||||||
configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configurationFileFormat.Version == 13 -> LDN1
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 14)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 14.");
|
|
||||||
|
|
||||||
configurationFileFormat.CheckUpdatesOnStart = true;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 16)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 16.");
|
|
||||||
|
|
||||||
configurationFileFormat.EnableShaderCache = true;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 17)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 17.");
|
|
||||||
|
|
||||||
configurationFileFormat.StartFullscreen = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 18)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 18.");
|
|
||||||
|
|
||||||
configurationFileFormat.AspectRatio = AspectRatio.Fixed16x9;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configurationFileFormat.Version == 19 -> LDN2
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 20)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 20.");
|
|
||||||
|
|
||||||
configurationFileFormat.ShowConfirmExit = true;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 21)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 21.");
|
|
||||||
|
|
||||||
// Initialize network config.
|
// Initialize network config.
|
||||||
|
|
||||||
configurationFileFormat.MultiplayerMode = MultiplayerMode.Disabled;
|
cff.MultiplayerMode = MultiplayerMode.Disabled;
|
||||||
configurationFileFormat.MultiplayerLanInterfaceId = "0";
|
cff.MultiplayerLanInterfaceId = "0";
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
(22, static cff => cff.HideCursor = HideCursorMode.Never),
|
||||||
}
|
(24, static cff =>
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 22)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
|
|
||||||
|
|
||||||
configurationFileFormat.HideCursor = HideCursorMode.Never;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 24)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24.");
|
|
||||||
|
|
||||||
configurationFileFormat.InputConfig = new List<InputConfig>
|
|
||||||
{
|
{
|
||||||
|
cff.InputConfig =
|
||||||
|
[
|
||||||
new StandardKeyboardInputConfig
|
new StandardKeyboardInputConfig
|
||||||
{
|
{
|
||||||
Version = InputConfig.CurrentVersion,
|
Version = InputConfig.CurrentVersion,
|
||||||
@ -240,533 +249,172 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
StickRight = Key.L,
|
StickRight = Key.L,
|
||||||
StickButton = Key.H,
|
StickButton = Key.H,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
}
|
||||||
|
];
|
||||||
if (configurationFileFormat.Version < 25)
|
}),
|
||||||
|
(26, static cff => cff.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe),
|
||||||
|
(27, static cff => cff.EnableMouse = false),
|
||||||
|
(29,
|
||||||
|
static cff =>
|
||||||
|
cff.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 25.");
|
ToggleVSyncMode = Key.F1, Screenshot = Key.F8, ShowUI = Key.F4
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
(30, static cff =>
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 26)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 26.");
|
foreach (InputConfig config in cff.InputConfig)
|
||||||
|
|
||||||
configurationFileFormat.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 27)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 27.");
|
|
||||||
|
|
||||||
configurationFileFormat.EnableMouse = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 28)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 28.");
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = Key.F1,
|
|
||||||
Screenshot = Key.F8,
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 29)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 29.");
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = Key.F1,
|
|
||||||
Screenshot = Key.F8,
|
|
||||||
ShowUI = Key.F4,
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 30)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 30.");
|
|
||||||
|
|
||||||
foreach (InputConfig config in configurationFileFormat.InputConfig)
|
|
||||||
{
|
{
|
||||||
if (config is StandardControllerInputConfig controllerConfig)
|
if (config is StandardControllerInputConfig controllerConfig)
|
||||||
{
|
{
|
||||||
controllerConfig.Rumble = new RumbleConfigController
|
controllerConfig.Rumble = new RumbleConfigController
|
||||||
{
|
{
|
||||||
EnableRumble = false,
|
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
|
||||||
StrongRumble = 1f,
|
|
||||||
WeakRumble = 1f,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
(31, static cff => cff.BackendThreading = BackendThreading.Auto),
|
||||||
}
|
(32, static cff => cff.Hotkeys = new KeyboardHotkeys
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 31)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 31.");
|
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = cff.Hotkeys.Screenshot,
|
||||||
configurationFileFormat.BackendThreading = BackendThreading.Auto;
|
ShowUI = cff.Hotkeys.ShowUI,
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 32)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 32.");
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
|
||||||
Pause = Key.F5,
|
Pause = Key.F5,
|
||||||
};
|
}),
|
||||||
|
(33, static cff =>
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 33)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 33.");
|
cff.Hotkeys = new KeyboardHotkeys
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
{
|
||||||
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = cff.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = cff.Hotkeys.ShowUI,
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
Pause = cff.Hotkeys.Pause,
|
||||||
ToggleMute = Key.F2,
|
ToggleMute = Key.F2,
|
||||||
};
|
};
|
||||||
|
|
||||||
configurationFileFormat.AudioVolume = 1;
|
cff.AudioVolume = 1;
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
(34, static cff => cff.EnableInternetAccess = false),
|
||||||
|
(35, static cff =>
|
||||||
|
{
|
||||||
|
foreach (StandardControllerInputConfig config in cff.InputConfig
|
||||||
|
.OfType<StandardControllerInputConfig>())
|
||||||
|
{
|
||||||
|
config.RangeLeft = 1.0f;
|
||||||
|
config.RangeRight = 1.0f;
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 34)
|
(36, static cff => cff.LoggingEnableTrace = false),
|
||||||
|
(37, static cff => cff.ShowConsole = true),
|
||||||
|
(38, static cff =>
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
|
cff.BaseStyle = "Dark";
|
||||||
|
cff.GameListViewMode = 0;
|
||||||
configurationFileFormat.EnableInternetAccess = false;
|
cff.ShowNames = true;
|
||||||
|
cff.GridSize = 2;
|
||||||
configurationFileUpdated = true;
|
cff.LanguageCode = "en_US";
|
||||||
}
|
}),
|
||||||
|
(39,
|
||||||
if (configurationFileFormat.Version < 35)
|
static cff => cff.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
|
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = cff.Hotkeys.Screenshot,
|
||||||
foreach (InputConfig config in configurationFileFormat.InputConfig)
|
ShowUI = cff.Hotkeys.ShowUI,
|
||||||
{
|
Pause = cff.Hotkeys.Pause,
|
||||||
if (config is StandardControllerInputConfig controllerConfig)
|
ToggleMute = cff.Hotkeys.ToggleMute,
|
||||||
{
|
|
||||||
controllerConfig.RangeLeft = 1.0f;
|
|
||||||
controllerConfig.RangeRight = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 36)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 36.");
|
|
||||||
|
|
||||||
configurationFileFormat.LoggingEnableTrace = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 37)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
|
|
||||||
|
|
||||||
configurationFileFormat.ShowConsole = true;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 38)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 38.");
|
|
||||||
|
|
||||||
configurationFileFormat.BaseStyle = "Dark";
|
|
||||||
configurationFileFormat.GameListViewMode = 0;
|
|
||||||
configurationFileFormat.ShowNames = true;
|
|
||||||
configurationFileFormat.GridSize = 2;
|
|
||||||
configurationFileFormat.LanguageCode = "en_US";
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 39)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
|
||||||
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
|
||||||
ResScaleUp = Key.Unbound,
|
ResScaleUp = Key.Unbound,
|
||||||
ResScaleDown = Key.Unbound,
|
ResScaleDown = Key.Unbound
|
||||||
};
|
}),
|
||||||
|
(40, static cff => cff.GraphicsBackend = GraphicsBackend.OpenGl),
|
||||||
configurationFileUpdated = true;
|
(41,
|
||||||
}
|
static cff => cff.Hotkeys = new KeyboardHotkeys
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 40)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 40.");
|
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = cff.Hotkeys.Screenshot,
|
||||||
configurationFileFormat.GraphicsBackend = GraphicsBackend.OpenGl;
|
ShowUI = cff.Hotkeys.ShowUI,
|
||||||
|
Pause = cff.Hotkeys.Pause,
|
||||||
configurationFileUpdated = true;
|
ToggleMute = cff.Hotkeys.ToggleMute,
|
||||||
}
|
ResScaleUp = cff.Hotkeys.ResScaleUp,
|
||||||
|
ResScaleDown = cff.Hotkeys.ResScaleDown,
|
||||||
if (configurationFileFormat.Version < 41)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
|
||||||
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
|
||||||
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
|
||||||
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
|
||||||
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
|
||||||
VolumeUp = Key.Unbound,
|
VolumeUp = Key.Unbound,
|
||||||
VolumeDown = Key.Unbound,
|
VolumeDown = Key.Unbound
|
||||||
};
|
}),
|
||||||
}
|
(42, static cff => cff.EnableMacroHLE = true),
|
||||||
|
(43, static cff => cff.UseHypervisor = true),
|
||||||
if (configurationFileFormat.Version < 42)
|
(44, static cff =>
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
|
cff.AntiAliasing = AntiAliasing.None;
|
||||||
|
cff.ScalingFilter = ScalingFilter.Bilinear;
|
||||||
configurationFileFormat.EnableMacroHLE = true;
|
cff.ScalingFilterLevel = 80;
|
||||||
}
|
}),
|
||||||
|
(45,
|
||||||
if (configurationFileFormat.Version < 43)
|
static cff => cff.ShownFileTypes = new ShownFileTypes
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 43.");
|
|
||||||
|
|
||||||
configurationFileFormat.UseHypervisor = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 44)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 44.");
|
|
||||||
|
|
||||||
configurationFileFormat.AntiAliasing = AntiAliasing.None;
|
|
||||||
configurationFileFormat.ScalingFilter = ScalingFilter.Bilinear;
|
|
||||||
configurationFileFormat.ScalingFilterLevel = 80;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 45)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 45.");
|
|
||||||
|
|
||||||
configurationFileFormat.ShownFileTypes = new ShownFileTypes
|
|
||||||
{
|
{
|
||||||
NSP = true,
|
NSP = true,
|
||||||
PFS0 = true,
|
PFS0 = true,
|
||||||
XCI = true,
|
XCI = true,
|
||||||
NCA = true,
|
NCA = true,
|
||||||
NRO = true,
|
NRO = true,
|
||||||
NSO = true,
|
NSO = true
|
||||||
};
|
}),
|
||||||
|
(46, static cff => cff.UseHypervisor = OperatingSystem.IsMacOS()),
|
||||||
configurationFileUpdated = true;
|
(47,
|
||||||
}
|
static cff => cff.WindowStartup = new WindowStartup
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 46)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 46.");
|
|
||||||
|
|
||||||
configurationFileFormat.MultiplayerLanInterfaceId = "0";
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 47)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 47.");
|
|
||||||
|
|
||||||
configurationFileFormat.WindowStartup = new WindowStartup
|
|
||||||
{
|
{
|
||||||
WindowPositionX = 0,
|
WindowPositionX = 0,
|
||||||
WindowPositionY = 0,
|
WindowPositionY = 0,
|
||||||
WindowSizeHeight = 760,
|
WindowSizeHeight = 760,
|
||||||
WindowSizeWidth = 1280,
|
WindowSizeWidth = 1280,
|
||||||
WindowMaximized = false,
|
WindowMaximized = false
|
||||||
};
|
}),
|
||||||
|
(48, static cff => cff.EnableColorSpacePassthrough = false),
|
||||||
configurationFileUpdated = true;
|
(49, static _ =>
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 48)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 48.");
|
|
||||||
|
|
||||||
configurationFileFormat.EnableColorSpacePassthrough = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 49)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 49.");
|
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
AppDataManager.FixMacOSConfigurationFolders();
|
AppDataManager.FixMacOSConfigurationFolders();
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
(50, static cff => cff.EnableHardwareAcceleration = true),
|
||||||
}
|
(51, static cff => cff.RememberWindowState = true),
|
||||||
|
(52, static cff => cff.AutoloadDirs = []),
|
||||||
if (configurationFileFormat.Version < 50)
|
(53, static cff => cff.EnableLowPowerPtc = false),
|
||||||
|
(54, static cff => cff.DramSize = MemoryConfiguration.MemoryConfiguration4GiB),
|
||||||
|
(55, static cff => cff.IgnoreApplet = false),
|
||||||
|
(56, static cff => cff.ShowTitleBar = !OperatingSystem.IsWindows()),
|
||||||
|
(57, static cff =>
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 50.");
|
cff.VSyncMode = VSyncMode.Switch;
|
||||||
|
cff.EnableCustomVSyncInterval = false;
|
||||||
|
|
||||||
configurationFileFormat.EnableHardwareAcceleration = true;
|
cff.Hotkeys = new KeyboardHotkeys
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 51)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
|
|
||||||
|
|
||||||
configurationFileFormat.RememberWindowState = true;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 52)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
|
|
||||||
|
|
||||||
configurationFileFormat.AutoloadDirs = [];
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 53)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
|
|
||||||
|
|
||||||
configurationFileFormat.EnableLowPowerPtc = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 54)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 54.");
|
|
||||||
|
|
||||||
configurationFileFormat.DramSize = MemoryConfiguration.MemoryConfiguration4GiB;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 55)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 55.");
|
|
||||||
|
|
||||||
configurationFileFormat.IgnoreApplet = false;
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 56)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 56.");
|
|
||||||
|
|
||||||
configurationFileFormat.ShowTitleBar = !OperatingSystem.IsWindows();
|
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 57)
|
|
||||||
{
|
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 57.");
|
|
||||||
|
|
||||||
configurationFileFormat.VSyncMode = VSyncMode.Switch;
|
|
||||||
configurationFileFormat.EnableCustomVSyncInterval = false;
|
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
|
||||||
{
|
{
|
||||||
ToggleVSyncMode = Key.F1,
|
ToggleVSyncMode = Key.F1,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = cff.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = cff.Hotkeys.ShowUI,
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
Pause = cff.Hotkeys.Pause,
|
||||||
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
ToggleMute = cff.Hotkeys.ToggleMute,
|
||||||
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
ResScaleUp = cff.Hotkeys.ResScaleUp,
|
||||||
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
ResScaleDown = cff.Hotkeys.ResScaleDown,
|
||||||
VolumeUp = configurationFileFormat.Hotkeys.VolumeUp,
|
VolumeUp = cff.Hotkeys.VolumeUp,
|
||||||
VolumeDown = configurationFileFormat.Hotkeys.VolumeDown,
|
VolumeDown = cff.Hotkeys.VolumeDown,
|
||||||
CustomVSyncIntervalIncrement = Key.Unbound,
|
CustomVSyncIntervalIncrement = Key.Unbound,
|
||||||
CustomVSyncIntervalDecrement = Key.Unbound,
|
CustomVSyncIntervalDecrement = Key.Unbound,
|
||||||
};
|
};
|
||||||
|
|
||||||
configurationFileFormat.CustomVSyncInterval = 120;
|
cff.CustomVSyncInterval = 120;
|
||||||
|
}),
|
||||||
configurationFileUpdated = true;
|
// 58 migration accidentally got skipped, but it worked with no issues somehow lol
|
||||||
}
|
(59, static cff =>
|
||||||
|
|
||||||
// 58 migration accidentally got skipped but it worked with no issues somehow lol
|
|
||||||
|
|
||||||
if (configurationFileFormat.Version < 59)
|
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 59.");
|
cff.ShowDirtyHacks = false;
|
||||||
|
cff.DirtyHacks = [];
|
||||||
|
|
||||||
configurationFileFormat.ShowDirtyHacks = false;
|
// This was accidentally enabled by default when it was PRed. That is not what we want,
|
||||||
configurationFileFormat.DirtyHacks = [];
|
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
|
||||||
|
cff.IgnoreApplet = false;
|
||||||
configurationFileUpdated = true;
|
})
|
||||||
}
|
);
|
||||||
|
|
||||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
|
||||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
|
||||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
|
||||||
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
|
|
||||||
Graphics.AspectRatio.Value = configurationFileFormat.AspectRatio;
|
|
||||||
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
|
|
||||||
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
|
|
||||||
Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend;
|
|
||||||
Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu;
|
|
||||||
Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing;
|
|
||||||
Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter;
|
|
||||||
Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel;
|
|
||||||
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
|
|
||||||
Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
|
|
||||||
Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
|
|
||||||
Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
|
|
||||||
Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
|
|
||||||
Logger.EnableTrace.Value = configurationFileFormat.LoggingEnableTrace;
|
|
||||||
Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
|
|
||||||
Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
|
|
||||||
Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
|
|
||||||
Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
|
|
||||||
System.Language.Value = configurationFileFormat.SystemLanguage;
|
|
||||||
System.Region.Value = configurationFileFormat.SystemRegion;
|
|
||||||
System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
|
|
||||||
System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
|
|
||||||
System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
|
|
||||||
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
|
|
||||||
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
|
|
||||||
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
|
|
||||||
IgnoreApplet.Value = configurationFileFormat.IgnoreApplet;
|
|
||||||
RememberWindowState.Value = configurationFileFormat.RememberWindowState;
|
|
||||||
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
|
|
||||||
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
|
||||||
HideCursor.Value = configurationFileFormat.HideCursor;
|
|
||||||
Graphics.VSyncMode.Value = configurationFileFormat.VSyncMode;
|
|
||||||
Graphics.EnableCustomVSyncInterval.Value = configurationFileFormat.EnableCustomVSyncInterval;
|
|
||||||
Graphics.CustomVSyncInterval.Value = configurationFileFormat.CustomVSyncInterval;
|
|
||||||
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
|
||||||
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
|
|
||||||
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
|
|
||||||
Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
|
|
||||||
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
|
|
||||||
System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc;
|
|
||||||
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
|
|
||||||
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
|
||||||
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
|
||||||
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
|
||||||
System.AudioVolume.Value = configurationFileFormat.AudioVolume;
|
|
||||||
System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode;
|
|
||||||
System.DramSize.Value = configurationFileFormat.DramSize;
|
|
||||||
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
|
||||||
System.UseHypervisor.Value = configurationFileFormat.UseHypervisor;
|
|
||||||
UI.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
|
||||||
UI.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
|
||||||
UI.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
|
|
||||||
UI.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
|
|
||||||
UI.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
|
|
||||||
UI.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
|
|
||||||
UI.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
|
|
||||||
UI.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
|
|
||||||
UI.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
|
|
||||||
UI.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
|
|
||||||
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
|
|
||||||
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
|
|
||||||
UI.GameDirs.Value = configurationFileFormat.GameDirs;
|
|
||||||
UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs ?? [];
|
|
||||||
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
|
|
||||||
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
|
|
||||||
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;
|
|
||||||
UI.ShownFileTypes.NCA.Value = configurationFileFormat.ShownFileTypes.NCA;
|
|
||||||
UI.ShownFileTypes.NRO.Value = configurationFileFormat.ShownFileTypes.NRO;
|
|
||||||
UI.ShownFileTypes.NSO.Value = configurationFileFormat.ShownFileTypes.NSO;
|
|
||||||
UI.LanguageCode.Value = configurationFileFormat.LanguageCode;
|
|
||||||
UI.BaseStyle.Value = configurationFileFormat.BaseStyle;
|
|
||||||
UI.GameListViewMode.Value = configurationFileFormat.GameListViewMode;
|
|
||||||
UI.ShowNames.Value = configurationFileFormat.ShowNames;
|
|
||||||
UI.IsAscendingOrder.Value = configurationFileFormat.IsAscendingOrder;
|
|
||||||
UI.GridSize.Value = configurationFileFormat.GridSize;
|
|
||||||
UI.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
|
|
||||||
UI.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
|
|
||||||
UI.ShowConsole.Value = configurationFileFormat.ShowConsole;
|
|
||||||
UI.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
|
|
||||||
UI.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
|
|
||||||
UI.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
|
|
||||||
UI.WindowStartup.WindowPositionY.Value = configurationFileFormat.WindowStartup.WindowPositionY;
|
|
||||||
UI.WindowStartup.WindowMaximized.Value = configurationFileFormat.WindowStartup.WindowMaximized;
|
|
||||||
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
|
||||||
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
|
|
||||||
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
|
|
||||||
Hid.InputConfig.Value = configurationFileFormat.InputConfig ?? [];
|
|
||||||
|
|
||||||
Multiplayer.LanInterfaceId.Value = configurationFileFormat.MultiplayerLanInterfaceId;
|
|
||||||
Multiplayer.Mode.Value = configurationFileFormat.MultiplayerMode;
|
|
||||||
Multiplayer.DisableP2p.Value = configurationFileFormat.MultiplayerDisableP2p;
|
|
||||||
Multiplayer.LdnPassphrase.Value = configurationFileFormat.MultiplayerLdnPassphrase;
|
|
||||||
Multiplayer.LdnServer.Value = configurationFileFormat.LdnServer;
|
|
||||||
|
|
||||||
Hacks.ShowDirtyHacks.Value = configurationFileFormat.ShowDirtyHacks;
|
|
||||||
|
|
||||||
{
|
|
||||||
EnabledDirtyHack[] hacks = configurationFileFormat.DirtyHacks.Select(EnabledDirtyHack.FromPacked).ToArray();
|
|
||||||
|
|
||||||
Hacks.Xc2MenuSoftlockFix.Value = hacks.Any(it => it.Hack == DirtyHacks.Xc2MenuSoftlockFix);
|
|
||||||
|
|
||||||
var shaderCompilationThreadSleep = hacks.FirstOrDefault(it => it.Hack == DirtyHacks.ShaderCompilationThreadSleep);
|
|
||||||
Hacks.EnableShaderCompilationThreadSleep.Value = shaderCompilationThreadSleep != null;
|
|
||||||
Hacks.ShaderCompilationThreadSleepDelay.Value = shaderCompilationThreadSleep?.Value ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configurationFileUpdated)
|
|
||||||
{
|
|
||||||
ToFileFormat().SaveConfig(configurationFilePath);
|
|
||||||
|
|
||||||
Ryujinx.Common.Logging.Logger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
{
|
{
|
||||||
@ -628,24 +629,38 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
|
|
||||||
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
|
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
|
||||||
|
|
||||||
public ReactiveObject<bool> EnableShaderCompilationThreadSleep { get; private set; }
|
public ReactiveObject<bool> EnableShaderTranslationDelay { get; private set; }
|
||||||
|
|
||||||
public ReactiveObject<int> ShaderCompilationThreadSleepDelay { get; private set; }
|
public ReactiveObject<int> ShaderTranslationDelay { get; private set; }
|
||||||
|
|
||||||
public HacksSection()
|
public HacksSection()
|
||||||
{
|
{
|
||||||
ShowDirtyHacks = new ReactiveObject<bool>();
|
ShowDirtyHacks = new ReactiveObject<bool>();
|
||||||
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
|
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
|
||||||
Xc2MenuSoftlockFix.Event += HackChanged;
|
Xc2MenuSoftlockFix.Event += HackChanged;
|
||||||
EnableShaderCompilationThreadSleep = new ReactiveObject<bool>();
|
EnableShaderTranslationDelay = new ReactiveObject<bool>();
|
||||||
EnableShaderCompilationThreadSleep.Event += HackChanged;
|
EnableShaderTranslationDelay.Event += HackChanged;
|
||||||
ShaderCompilationThreadSleepDelay = new ReactiveObject<int>();
|
ShaderTranslationDelay = new ReactiveObject<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
||||||
{
|
{
|
||||||
Ryujinx.Common.Logging.Logger.Info?.Print(LogClass.Configuration, $"EnabledDirtyHacks set to: [{EnabledHacks.Select(x => x.Hack).JoinToString(", ")}]", "LogValueChange");
|
if (!ShowDirtyHacks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var newHacks = EnabledHacks.Select(x => x.Hack)
|
||||||
|
.JoinToString(", ");
|
||||||
|
|
||||||
|
if (newHacks != _lastHackCollection)
|
||||||
|
{
|
||||||
|
RyuLogger.Info?.Print(LogClass.Configuration,
|
||||||
|
$"EnabledDirtyHacks set to: [{newHacks}]", "LogValueChange");
|
||||||
|
|
||||||
|
_lastHackCollection = newHacks;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string _lastHackCollection;
|
||||||
|
|
||||||
public EnabledDirtyHack[] EnabledHacks
|
public EnabledDirtyHack[] EnabledHacks
|
||||||
{
|
{
|
||||||
@ -654,14 +669,14 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
List<EnabledDirtyHack> enabledHacks = [];
|
List<EnabledDirtyHack> enabledHacks = [];
|
||||||
|
|
||||||
if (Xc2MenuSoftlockFix)
|
if (Xc2MenuSoftlockFix)
|
||||||
Apply(DirtyHacks.Xc2MenuSoftlockFix);
|
Apply(DirtyHack.Xc2MenuSoftlockFix);
|
||||||
|
|
||||||
if (EnableShaderCompilationThreadSleep)
|
if (EnableShaderTranslationDelay)
|
||||||
Apply(DirtyHacks.ShaderCompilationThreadSleep, ShaderCompilationThreadSleepDelay);
|
Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
|
||||||
|
|
||||||
return enabledHacks.ToArray();
|
return enabledHacks.ToArray();
|
||||||
|
|
||||||
void Apply(DirtyHacks hack, int value = 0)
|
void Apply(DirtyHack hack, int value = 0)
|
||||||
{
|
{
|
||||||
enabledHacks.Add(new EnabledDirtyHack(hack, value));
|
enabledHacks.Add(new EnabledDirtyHack(hack, value));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user