Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
baf94e0e3e | |||
cf6201a4a6 | |||
18909195d1 | |||
f06d22d6f0 | |||
84d6e8d121 | |||
95c4912d58 | |||
356a75af0b | |||
4ae9921063 | |||
6a8ac389e5 | |||
8dd1eb333c | |||
7dc3a62c14 | |||
e59dba42ef | |||
bd6937ae5c | |||
b82e789d4f | |||
4a6724622e | |||
0c73eba3db | |||
a082e14ede | |||
d29da11d5f | |||
ea07328aea | |||
a0b3d82ee0 | |||
609de33b0b | |||
dfc0819e72 | |||
d4803356bb | |||
459efd0db7 | |||
8bb7a3fc97 | |||
628d092fc6 | |||
6c90d50c8e | |||
d56bab1e24 |
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@ -20,7 +20,7 @@ gpu:
|
|||||||
|
|
||||||
gui:
|
gui:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.Ui.Common/**', 'src/Ryujinx.Ui.LocaleGenerator/**', 'src/Ryujinx.Ava/**']
|
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**', 'src/Ryujinx.Ava/**']
|
||||||
|
|
||||||
horizon:
|
horizon:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
|
56
.github/workflows/build.yml
vendored
56
.github/workflows/build.yml
vendored
@ -10,28 +10,17 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }})
|
name: ${{ matrix.platform.name }} (${{ matrix.configuration }})
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.platform.os }}
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
|
||||||
configuration: [Debug, Release]
|
configuration: [Debug, Release]
|
||||||
include:
|
platform:
|
||||||
- os: ubuntu-latest
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
OS_NAME: Linux x64
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
DOTNET_RUNTIME_IDENTIFIER: linux-x64
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
RELEASE_ZIP_OS_NAME: linux_x64
|
- { name: osx-x64, os: macOS-latest, zip_os_name: osx_x64 }
|
||||||
|
|
||||||
- os: macOS-latest
|
|
||||||
OS_NAME: macOS x64
|
|
||||||
DOTNET_RUNTIME_IDENTIFIER: osx-x64
|
|
||||||
RELEASE_ZIP_OS_NAME: osx_x64
|
|
||||||
|
|
||||||
- os: windows-latest
|
|
||||||
OS_NAME: Windows x64
|
|
||||||
DOTNET_RUNTIME_IDENTIFIER: win-x64
|
|
||||||
RELEASE_ZIP_OS_NAME: win_x64
|
|
||||||
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
@ -52,12 +41,12 @@ jobs:
|
|||||||
- name: Change config filename
|
- name: Change config filename
|
||||||
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Change config filename for macOS
|
- name: Change config filename for macOS
|
||||||
run: sed -r -i '' 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
run: sed -r -i '' 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
if: github.event_name == 'pull_request' && matrix.os == 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'macOS-latest'
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
||||||
@ -68,46 +57,47 @@ jobs:
|
|||||||
commands: dotnet test --no-build -c "${{ matrix.configuration }}"
|
commands: dotnet test --no-build -c "${{ matrix.configuration }}"
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
retry-codes: 139
|
retry-codes: 139
|
||||||
|
if: matrix.platform.name != 'linux-arm64'
|
||||||
|
|
||||||
- name: Publish Ryujinx
|
- name: Publish Ryujinx
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Headless.SDL2
|
- name: Publish Ryujinx.Headless.SDL2
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Ava
|
- name: Publish Ryujinx.Ava
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Set executable bit
|
- name: Set executable bit
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||||
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
||||||
chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
|
chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
|
||||||
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
||||||
path: publish
|
path: publish
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
||||||
path: publish_sdl2_headless
|
path: publish_sdl2_headless
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Ava artifact
|
- name: Upload Ryujinx.Ava artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
||||||
path: publish_ava
|
path: publish_ava
|
||||||
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
name: macOS Universal (${{ matrix.configuration }})
|
name: macOS Universal (${{ matrix.configuration }})
|
||||||
|
72
.github/workflows/flatpak.yml
vendored
72
.github/workflows/flatpak.yml
vendored
@ -51,38 +51,76 @@ jobs:
|
|||||||
- name: Restore Nuget packages
|
- name: Restore Nuget packages
|
||||||
# With .NET 8.0.100, Microsoft.NET.ILLink.Tasks isn't restored by default and only seems to appears when publishing.
|
# With .NET 8.0.100, Microsoft.NET.ILLink.Tasks isn't restored by default and only seems to appears when publishing.
|
||||||
# So we just publish to grab the dependencies
|
# So we just publish to grab the dependencies
|
||||||
run: dotnet publish -c Release -r linux-x64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained
|
run: |
|
||||||
|
dotnet publish -c Release -r linux-x64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained
|
||||||
|
dotnet publish -c Release -r linux-arm64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained
|
||||||
|
|
||||||
- name: Generate nuget_sources.json
|
- name: Generate nuget_sources.json
|
||||||
shell: python
|
shell: python
|
||||||
run: |
|
run: |
|
||||||
|
import hashlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
|
|
||||||
for path in Path(os.environ['NUGET_PACKAGES']).glob('**/*.nupkg.sha512'):
|
|
||||||
name = path.parent.parent.name
|
|
||||||
version = path.parent.name
|
|
||||||
filename = '{}.{}.nupkg'.format(name, version)
|
|
||||||
url = 'https://api.nuget.org/v3-flatcontainer/{}/{}/{}'.format(name, version, filename)
|
|
||||||
|
|
||||||
with path.open() as fp:
|
def create_source_from_external(name, version):
|
||||||
sha512 = binascii.hexlify(base64.b64decode(fp.read())).decode('ascii')
|
full_dir_path = Path(os.environ["NUGET_PACKAGES"]).joinpath(name).joinpath(version)
|
||||||
|
os.makedirs(full_dir_path, exist_ok=True)
|
||||||
|
|
||||||
sources.append({
|
filename = "{}.{}.nupkg".format(name, version)
|
||||||
'type': 'file',
|
url = "https://api.nuget.org/v3-flatcontainer/{}/{}/{}".format(
|
||||||
'url': url,
|
name, version, filename
|
||||||
'sha512': sha512,
|
)
|
||||||
'dest': os.environ['NUGET_SOURCES_DESTDIR'],
|
|
||||||
'dest-filename': filename,
|
|
||||||
})
|
|
||||||
|
|
||||||
with open('flathub/nuget_sources.json', 'w') as fp:
|
print(f"Processing {url}...")
|
||||||
json.dump(sources, fp, indent=4)
|
response = urllib.request.urlopen(url)
|
||||||
|
sha512 = hashlib.sha512(response.read()).hexdigest()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"type": "file",
|
||||||
|
"url": url,
|
||||||
|
"sha512": sha512,
|
||||||
|
"dest": os.environ["NUGET_SOURCES_DESTDIR"],
|
||||||
|
"dest-filename": filename,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
has_added_x64_apphost = False
|
||||||
|
|
||||||
|
for path in Path(os.environ["NUGET_PACKAGES"]).glob("**/*.nupkg.sha512"):
|
||||||
|
name = path.parent.parent.name
|
||||||
|
version = path.parent.name
|
||||||
|
filename = "{}.{}.nupkg".format(name, version)
|
||||||
|
url = "https://api.nuget.org/v3-flatcontainer/{}/{}/{}".format(
|
||||||
|
name, version, filename
|
||||||
|
)
|
||||||
|
|
||||||
|
with path.open() as fp:
|
||||||
|
sha512 = binascii.hexlify(base64.b64decode(fp.read())).decode("ascii")
|
||||||
|
|
||||||
|
sources.append(
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"url": url,
|
||||||
|
"sha512": sha512,
|
||||||
|
"dest": os.environ["NUGET_SOURCES_DESTDIR"],
|
||||||
|
"dest-filename": filename,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# .NET will not add current installed application host to the list, force inject it here.
|
||||||
|
if not has_added_x64_apphost and name.startswith('microsoft.netcore.app.host'):
|
||||||
|
sources.append(create_source_from_external("microsoft.netcore.app.host.linux-x64", version))
|
||||||
|
has_added_x64_apphost = True
|
||||||
|
|
||||||
|
with open("flathub/nuget_sources.json", "w") as fp:
|
||||||
|
json.dump(sources, fp, indent=4)
|
||||||
|
|
||||||
- name: Update flatpak metadata
|
- name: Update flatpak metadata
|
||||||
id: metadata
|
id: metadata
|
||||||
|
41
.github/workflows/release.yml
vendored
41
.github/workflows/release.yml
vendored
@ -45,22 +45,15 @@ jobs:
|
|||||||
})
|
})
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Release ${{ matrix.OS_NAME }}
|
name: Release for ${{ matrix.platform.name }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.platform.os }}
|
||||||
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest, windows-latest ]
|
platform:
|
||||||
include:
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
- os: ubuntu-latest
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
OS_NAME: Linux x64
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
DOTNET_RUNTIME_IDENTIFIER: linux-x64
|
|
||||||
RELEASE_ZIP_OS_NAME: linux_x64
|
|
||||||
|
|
||||||
- os: windows-latest
|
|
||||||
OS_NAME: Windows x64
|
|
||||||
DOTNET_RUNTIME_IDENTIFIER: win-x64
|
|
||||||
RELEASE_ZIP_OS_NAME: win_x64
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@ -93,42 +86,42 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
|
||||||
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
|
||||||
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
|
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.Ava --self-contained true
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_gtk
|
pushd publish_gtk
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
pushd publish_sdl2_headless
|
||||||
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_ava
|
pushd publish_ava
|
||||||
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/test-ava-ryujinx-${{ 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.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_gtk
|
pushd publish_gtk
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
pushd publish_sdl2_headless
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
||||||
tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_ava
|
pushd publish_ava
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
|
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
|
||||||
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
||||||
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" />
|
|
||||||
<PackageVersion Include="LibHac" Version="0.19.0" />
|
<PackageVersion Include="LibHac" Version="0.19.0" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
|
||||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.3.0" />
|
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.3.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
|
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
|
||||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||||
<PackageVersion Include="NetCoreServer" Version="8.0.7" />
|
<PackageVersion Include="NetCoreServer" Version="8.0.7" />
|
||||||
@ -33,10 +32,10 @@
|
|||||||
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
|
||||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
<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.GtkSharp" Version="3.24.24.59-ryujinx" />
|
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
|
@ -71,7 +71,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmp
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ava", "src\Ryujinx.Ava\Ryujinx.Ava.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ava", "src\Ryujinx.Ava\Ryujinx.Ava.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ui.Common", "src\Ryujinx.Ui.Common\Ryujinx.Ui.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -79,7 +79,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spv.Generator", "src\Spv.Generator\Spv.Generator.csproj", "{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spv.Generator", "src\Spv.Generator\Spv.Generator.csproj", "{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ui.LocaleGenerator", "src\Ryujinx.Ui.LocaleGenerator\Ryujinx.Ui.LocaleGenerator.csproj", "{77D01AD9-2C98-478E-AE1D-8F7100738FB4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.LocaleGenerator", "src\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj", "{77D01AD9-2C98-478E-AE1D-8F7100738FB4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Common", "src\Ryujinx.Horizon.Common\Ryujinx.Horizon.Common.csproj", "{77F96ECE-4952-42DB-A528-DED25572A573}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Common", "src\Ryujinx.Horizon.Common\Ryujinx.Horizon.Common.csproj", "{77F96ECE-4952-42DB-A528-DED25572A573}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
||||||
RYUJINX_BIN="Ryujinx"
|
|
||||||
|
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
|
||||||
|
RYUJINX_BIN="Ryujinx.Headless.SDL2"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then
|
||||||
RYUJINX_BIN="Ryujinx.Ava"
|
RYUJINX_BIN="Ryujinx.Ava"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
|
||||||
RYUJINX_BIN="Ryujinx.Headless.SDL2"
|
RYUJINX_BIN="Ryujinx"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$RYUJINX_BIN" ]; then
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMMAND="env DOTNET_EnableAlternateStackCheck=1"
|
COMMAND="env DOTNET_EnableAlternateStackCheck=1"
|
||||||
@ -17,4 +24,4 @@ if command -v gamemoderun > /dev/null 2>&1; then
|
|||||||
COMMAND="$COMMAND gamemoderun"
|
COMMAND="$COMMAND gamemoderun"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
|
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dll" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dll" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.dll</TargetPath>
|
<TargetPath>libsoundio.dll</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dylib" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'win-x64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dylib" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.dylib</TargetPath>
|
<TargetPath>libsoundio.dylib</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.so" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.so" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.so</TargetPath>
|
<TargetPath>libsoundio.so</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
|
@ -8,8 +8,8 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
@ -42,9 +42,9 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
ApplyConfiguredTheme();
|
ApplyConfiguredTheme();
|
||||||
|
|
||||||
ConfigurationState.Instance.Ui.BaseStyle.Event += ThemeChanged_Event;
|
ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
|
||||||
ConfigurationState.Instance.Ui.CustomThemePath.Event += ThemeChanged_Event;
|
ConfigurationState.Instance.UI.CustomThemePath.Event += ThemeChanged_Event;
|
||||||
ConfigurationState.Instance.Ui.EnableCustomTheme.Event += CustomThemeChanged_Event;
|
ConfigurationState.Instance.UI.EnableCustomTheme.Event += CustomThemeChanged_Event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +88,13 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
|
string baseStyle = ConfigurationState.Instance.UI.BaseStyle;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(baseStyle))
|
if (string.IsNullOrWhiteSpace(baseStyle))
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.BaseStyle.Value = "Dark";
|
ConfigurationState.Instance.UI.BaseStyle.Value = "Dark";
|
||||||
|
|
||||||
baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
|
baseStyle = ConfigurationState.Instance.UI.BaseStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestedThemeVariant = baseStyle switch
|
RequestedThemeVariant = baseStyle switch
|
||||||
|
@ -34,10 +34,10 @@ 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 Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
@ -1070,7 +1070,7 @@ namespace Ryujinx.Ava
|
|||||||
case KeyboardHotkeyState.Screenshot:
|
case KeyboardHotkeyState.Screenshot:
|
||||||
ScreenshotRequested = true;
|
ScreenshotRequested = true;
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.ShowUi:
|
case KeyboardHotkeyState.ShowUI:
|
||||||
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.Pause:
|
case KeyboardHotkeyState.Pause:
|
||||||
@ -1160,9 +1160,9 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.Screenshot;
|
state = KeyboardHotkeyState.Screenshot;
|
||||||
}
|
}
|
||||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUi))
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI))
|
||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.ShowUi;
|
state = KeyboardHotkeyState.ShowUI;
|
||||||
}
|
}
|
||||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause))
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause))
|
||||||
{
|
{
|
||||||
|
@ -73,6 +73,10 @@
|
|||||||
"GameListContextMenuCreateShortcut": "Create Application Shortcut",
|
"GameListContextMenuCreateShortcut": "Create Application Shortcut",
|
||||||
"GameListContextMenuCreateShortcutToolTip": "Create a Desktop Shortcut that launches the selected Application",
|
"GameListContextMenuCreateShortcutToolTip": "Create a Desktop Shortcut that launches the selected Application",
|
||||||
"GameListContextMenuCreateShortcutToolTipMacOS": "Create a shortcut in macOS's Applications folder that launches the selected Application",
|
"GameListContextMenuCreateShortcutToolTipMacOS": "Create a shortcut in macOS's Applications folder that launches the selected Application",
|
||||||
|
"GameListContextMenuOpenModsDirectory": "Open Mods Directory",
|
||||||
|
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
|
||||||
|
"GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory",
|
||||||
|
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.",
|
||||||
"StatusBarGamesLoaded": "{0}/{1} Games Loaded",
|
"StatusBarGamesLoaded": "{0}/{1} Games Loaded",
|
||||||
"StatusBarSystemVersion": "System Version: {0}",
|
"StatusBarSystemVersion": "System Version: {0}",
|
||||||
"LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected",
|
"LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected",
|
||||||
|
@ -18,8 +18,8 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -5,7 +5,7 @@ namespace Ryujinx.Ava.Common
|
|||||||
None,
|
None,
|
||||||
ToggleVSync,
|
ToggleVSync,
|
||||||
Screenshot,
|
Screenshot,
|
||||||
ShowUi,
|
ShowUI,
|
||||||
Pause,
|
Pause,
|
||||||
ToggleMute,
|
ToggleMute,
|
||||||
ResScaleUp,
|
ResScaleUp,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -38,9 +38,9 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
// If the view is loaded with the UI Previewer detached, then override it with the saved one or default.
|
// If the view is loaded with the UI Previewer detached, then override it with the saved one or default.
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(ConfigurationState.Instance.Ui.LanguageCode.Value))
|
if (!string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value))
|
||||||
{
|
{
|
||||||
localeLanguageCode = ConfigurationState.Instance.Ui.LanguageCode.Value;
|
localeLanguageCode = ConfigurationState.Instance.UI.LanguageCode.Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,8 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using Ryujinx.Ui.Common.Models.Github;
|
using Ryujinx.UI.Common.Models.Github;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
@ -9,10 +9,10 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.SystemInterop;
|
using Ryujinx.Common.SystemInterop;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using Ryujinx.Ui.Common.SystemInfo;
|
using Ryujinx.UI.Common.SystemInfo;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -43,14 +43,13 @@
|
|||||||
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
|
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
|
||||||
<PackageReference Include="Avalonia.Svg" />
|
<PackageReference Include="Avalonia.Svg" />
|
||||||
<PackageReference Include="Avalonia.Svg.Skia" />
|
<PackageReference Include="Avalonia.Svg.Skia" />
|
||||||
<PackageReference Include="jp2masa.Avalonia.Flexbox" />
|
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" />
|
<PackageReference Include="FluentAvaloniaUI" />
|
||||||
|
|
||||||
<PackageReference Include="OpenTK.Core" />
|
<PackageReference Include="OpenTK.Core" />
|
||||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||||
<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)' != 'win-x64'" />
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
||||||
<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" />
|
||||||
@ -74,12 +73,12 @@
|
|||||||
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Ui.Common\Ryujinx.Ui.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Ui.LocaleGenerator\Ryujinx.Ui.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
<Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
<TargetPath>alsoft.ini</TargetPath>
|
<TargetPath>alsoft.ini</TargetPath>
|
||||||
</Content>
|
</Content>
|
||||||
@ -93,7 +92,7 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
|
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'">
|
||||||
<Content Include="..\..\distribution\linux\Ryujinx.sh">
|
<Content Include="..\..\distribution\linux\Ryujinx.sh">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@ -104,7 +103,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="Ui\**\*.xaml">
|
<AvaloniaResource Include="UI\**\*.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
|
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
|
||||||
|
@ -8,26 +8,26 @@ using Ryujinx.Ava.UI.Windows;
|
|||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
using Ryujinx.HLE.HOS.Applets;
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Applet
|
namespace Ryujinx.Ava.UI.Applet
|
||||||
{
|
{
|
||||||
internal class AvaHostUiHandler : IHostUiHandler
|
internal class AvaHostUIHandler : IHostUIHandler
|
||||||
{
|
{
|
||||||
private readonly MainWindow _parent;
|
private readonly MainWindow _parent;
|
||||||
|
|
||||||
public IHostUiTheme HostUiTheme { get; }
|
public IHostUITheme HostUITheme { get; }
|
||||||
|
|
||||||
public AvaHostUiHandler(MainWindow parent)
|
public AvaHostUIHandler(MainWindow parent)
|
||||||
{
|
{
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
|
||||||
HostUiTheme = new AvaloniaHostUiTheme(parent);
|
HostUITheme = new AvaloniaHostUITheme(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DisplayMessageDialog(ControllerAppletUiArgs args)
|
public bool DisplayMessageDialog(ControllerAppletUIArgs args)
|
||||||
{
|
{
|
||||||
ManualResetEvent dialogCloseEvent = new(false);
|
ManualResetEvent dialogCloseEvent = new(false);
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
return okPressed;
|
return okPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText)
|
public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
|
||||||
{
|
{
|
||||||
ManualResetEvent dialogCloseEvent = new(false);
|
ManualResetEvent dialogCloseEvent = new(false);
|
||||||
|
|
@ -5,7 +5,7 @@ using Avalonia.Threading;
|
|||||||
using Ryujinx.Ava.Input;
|
using Ryujinx.Ava.Input;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using HidKey = Ryujinx.Common.Configuration.Hid.Key;
|
using HidKey = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Applet
|
namespace Ryujinx.Ava.UI.Applet
|
||||||
{
|
{
|
||||||
class AvaloniaHostUiTheme : IHostUiTheme
|
class AvaloniaHostUITheme : IHostUITheme
|
||||||
{
|
{
|
||||||
public AvaloniaHostUiTheme(MainWindow parent)
|
public AvaloniaHostUITheme(MainWindow parent)
|
||||||
{
|
{
|
||||||
FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) ? "Segoe UI Variable" : parent.FontFamily.Name;
|
FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) ? "Segoe UI Variable" : parent.FontFamily.Name;
|
||||||
DefaultBackgroundColor = BrushToThemeColor(parent.Background);
|
DefaultBackgroundColor = BrushToThemeColor(parent.Background);
|
@ -36,7 +36,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
|
|
||||||
private readonly MainWindow _mainWindow;
|
private readonly MainWindow _mainWindow;
|
||||||
|
|
||||||
public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUiArgs args)
|
public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUIArgs args)
|
||||||
{
|
{
|
||||||
if (args.PlayerCountMin == args.PlayerCountMax)
|
if (args.PlayerCountMin == args.PlayerCountMax)
|
||||||
{
|
{
|
||||||
@ -69,7 +69,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<UserResult> ShowControllerAppletDialog(MainWindow window, ControllerAppletUiArgs args)
|
public static async Task<UserResult> ShowControllerAppletDialog(MainWindow window, ControllerAppletUIArgs args)
|
||||||
{
|
{
|
||||||
ContentDialog contentDialog = new();
|
ContentDialog contentDialog = new();
|
||||||
UserResult result = UserResult.Cancel;
|
UserResult result = UserResult.Cancel;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
Height="80"
|
Height="80"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
Margin="5,10,20,10"
|
Margin="5,10,20,10"
|
||||||
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
|
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
Margin="5,10,20,10"
|
Margin="5,10,20,10"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
|
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
@ -54,7 +54,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
public string MainText { get; set; } = "";
|
public string MainText { get; set; } = "";
|
||||||
public string SecondaryText { get; set; } = "";
|
public string SecondaryText { get; set; } = "";
|
||||||
|
|
||||||
public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUiArgs args)
|
public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUIArgs args)
|
||||||
{
|
{
|
||||||
ContentDialog contentDialog = new();
|
ContentDialog contentDialog = new();
|
||||||
|
|
||||||
|
@ -51,6 +51,15 @@
|
|||||||
Header="{locale:Locale GameListContextMenuManageMod}"
|
Header="{locale:Locale GameListContextMenuManageMod}"
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuManageModToolTip}" />
|
ToolTip.Tip="{locale:Locale GameListContextMenuManageModToolTip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
|
<MenuItem
|
||||||
|
Click="OpenModsDirectory_Click"
|
||||||
|
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
|
||||||
|
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
|
||||||
|
<MenuItem
|
||||||
|
Click="OpenSdModsDirectory_Click"
|
||||||
|
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
|
||||||
|
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
|
||||||
|
<Separator />
|
||||||
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
|
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="PurgePtcCache_Click"
|
Click="PurgePtcCache_Click"
|
||||||
|
@ -11,8 +11,8 @@ using Ryujinx.Ava.UI.ViewModels;
|
|||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@ -126,6 +126,32 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
||||||
|
|
||||||
|
if (viewModel?.SelectedApplication != null)
|
||||||
|
{
|
||||||
|
string modsBasePath = ModLoader.GetModsBasePath();
|
||||||
|
string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, viewModel.SelectedApplication.TitleId);
|
||||||
|
|
||||||
|
OpenHelper.OpenFolder(titleModsPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenSdModsDirectory_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
||||||
|
|
||||||
|
if (viewModel?.SelectedApplication != null)
|
||||||
|
{
|
||||||
|
string sdModsBasePath = ModLoader.GetSdModsBasePath();
|
||||||
|
string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, viewModel.SelectedApplication.TitleId);
|
||||||
|
|
||||||
|
OpenHelper.OpenFolder(titleModsPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void OpenModManager_Click(object sender, RoutedEventArgs args)
|
public async void OpenModManager_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
|
|
||||||
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"
|
||||||
@ -33,11 +32,10 @@
|
|||||||
SelectionChanged="GameList_SelectionChanged">
|
SelectionChanged="GameList_SelectionChanged">
|
||||||
<ListBox.ItemsPanel>
|
<ListBox.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<flex:FlexPanel
|
<WrapPanel
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Top"
|
||||||
AlignContent="FlexStart"
|
Orientation="Horizontal" />
|
||||||
JustifyContent="FlexStart" />
|
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
<ListBox.Styles>
|
<ListBox.Styles>
|
||||||
|
@ -3,7 +3,7 @@ using Avalonia.Input;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
@ -3,7 +3,7 @@ using Avalonia.Input;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
Height="70"
|
Height="70"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
Margin="5,10,20,10"
|
Margin="5,10,20,10"
|
||||||
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
|
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
{
|
{
|
||||||
|
@ -383,7 +383,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
{
|
{
|
||||||
result = ContentDialogResult.None;
|
result = ContentDialogResult.None;
|
||||||
|
|
||||||
Logger.Warning?.Print(LogClass.Ui, "Content dialog overlay failed to populate. Default value has been returned.");
|
Logger.Warning?.Print(LogClass.UI, "Content dialog overlay failed to populate. Default value has been returned.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
|
public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, null));
|
GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
|
public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
|
||||||
{
|
{
|
||||||
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, propertyValues));
|
GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, propertyValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
|
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ using LibHac.Ncm;
|
|||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -3,8 +3,8 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using SPB.Graphics;
|
using SPB.Graphics;
|
||||||
using SPB.Platform;
|
using SPB.Platform;
|
||||||
using SPB.Platform.GLX;
|
using SPB.Platform.GLX;
|
||||||
|
@ -3,7 +3,7 @@ using Ryujinx.Common.Configuration;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using SPB.Graphics;
|
using SPB.Graphics;
|
||||||
using SPB.Graphics.Exceptions;
|
using SPB.Graphics.Exceptions;
|
||||||
using SPB.Graphics.OpenGL;
|
using SPB.Graphics.OpenGL;
|
||||||
@ -75,7 +75,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
Logger.Warning?.Print(LogClass.UI, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Renderer
|
namespace Ryujinx.Ava.UI.Renderer
|
||||||
|
@ -29,6 +29,8 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
_context.MakeCurrent(_window);
|
_context.MakeCurrent(_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasContext() => _context.IsCurrent;
|
||||||
|
|
||||||
public static SPBOpenGLContext CreateBackgroundContext(OpenGLContextBase sharedContext)
|
public static SPBOpenGLContext CreateBackgroundContext(OpenGLContextBase sharedContext)
|
||||||
{
|
{
|
||||||
OpenGLContextBase context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, 3, 3, OpenGLContextFlags.Compat, true, sharedContext);
|
OpenGLContextBase context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, 3, 3, OpenGLContextFlags.Compat, true, sharedContext);
|
||||||
|
@ -3,7 +3,7 @@ using Avalonia.Platform;
|
|||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
@ -87,19 +87,19 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
Version = Program.Version;
|
Version = Program.Version;
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Ui.BaseStyle.Value == "Light")
|
if (ConfigurationState.Instance.UI.BaseStyle.Value == "Light")
|
||||||
{
|
{
|
||||||
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.Ui.Common")));
|
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.UI.Common")));
|
||||||
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.Ui.Common")));
|
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.UI.Common")));
|
||||||
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.Ui.Common")));
|
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.UI.Common")));
|
||||||
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.Ui.Common")));
|
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.UI.Common")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.Ui.Common")));
|
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.UI.Common")));
|
||||||
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.Ui.Common")));
|
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.UI.Common")));
|
||||||
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.Ui.Common")));
|
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.UI.Common")));
|
||||||
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.Ui.Common")));
|
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.UI.Common")));
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
|
Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
|
||||||
|
@ -9,7 +9,7 @@ using Ryujinx.Common;
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Ui.Common.Models.Amiibo;
|
using Ryujinx.UI.Common.Models.Amiibo;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -65,7 +65,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_amiiboSeries = new ObservableCollection<string>();
|
_amiiboSeries = new ObservableCollection<string>();
|
||||||
_amiibos = new AvaloniaList<AmiiboApi>();
|
_amiibos = new AvaloniaList<AmiiboApi>();
|
||||||
|
|
||||||
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
|
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.UI.Common/Resources/Logo_Amiibo.png");
|
||||||
|
|
||||||
_ = LoadContentAsync();
|
_ = LoadContentAsync();
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -35,10 +35,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
public class ControllerInputViewModel : BaseModel, IDisposable
|
public class ControllerInputViewModel : BaseModel, IDisposable
|
||||||
{
|
{
|
||||||
private const string Disabled = "disabled";
|
private const string Disabled = "disabled";
|
||||||
private const string ProControllerResource = "Ryujinx.Ui.Common/Resources/Controller_ProCon.svg";
|
private const string ProControllerResource = "Ryujinx.UI.Common/Resources/Controller_ProCon.svg";
|
||||||
private const string JoyConPairResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConPair.svg";
|
private const string JoyConPairResource = "Ryujinx.UI.Common/Resources/Controller_JoyConPair.svg";
|
||||||
private const string JoyConLeftResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConLeft.svg";
|
private const string JoyConLeftResource = "Ryujinx.UI.Common/Resources/Controller_JoyConLeft.svg";
|
||||||
private const string JoyConRightResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConRight.svg";
|
private const string JoyConRightResource = "Ryujinx.UI.Common/Resources/Controller_JoyConRight.svg";
|
||||||
private const string KeyboardString = "keyboard";
|
private const string KeyboardString = "keyboard";
|
||||||
private const string ControllerString = "controller";
|
private const string ControllerString = "controller";
|
||||||
private readonly MainWindow _mainWindow;
|
private readonly MainWindow _mainWindow;
|
||||||
|
@ -25,13 +25,13 @@ using Ryujinx.HLE;
|
|||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -138,7 +138,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
InputManager inputManager,
|
InputManager inputManager,
|
||||||
UserChannelPersistence userChannelPersistence,
|
UserChannelPersistence userChannelPersistence,
|
||||||
LibHacHorizonManager libHacHorizonManager,
|
LibHacHorizonManager libHacHorizonManager,
|
||||||
IHostUiHandler uiHandler,
|
IHostUIHandler uiHandler,
|
||||||
Action<bool> showLoading,
|
Action<bool> showLoading,
|
||||||
Action<bool> switchToGameControl,
|
Action<bool> switchToGameControl,
|
||||||
Action<Control> setMainContent,
|
Action<Control> setMainContent,
|
||||||
@ -685,10 +685,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool StartGamesInFullscreen
|
public bool StartGamesInFullscreen
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.Ui.StartFullscreen;
|
get => ConfigurationState.Instance.UI.StartFullscreen;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.StartFullscreen.Value = value;
|
ConfigurationState.Instance.UI.StartFullscreen.Value = value;
|
||||||
|
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
|
|
||||||
@ -698,10 +698,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool ShowConsole
|
public bool ShowConsole
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.Ui.ShowConsole;
|
get => ConfigurationState.Instance.UI.ShowConsole;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.ShowConsole.Value = value;
|
ConfigurationState.Instance.UI.ShowConsole.Value = value;
|
||||||
|
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
|
|
||||||
@ -743,10 +743,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public Glyph Glyph
|
public Glyph Glyph
|
||||||
{
|
{
|
||||||
get => (Glyph)ConfigurationState.Instance.Ui.GameListViewMode.Value;
|
get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.GameListViewMode.Value = (int)value;
|
ConfigurationState.Instance.UI.GameListViewMode.Value = (int)value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
OnPropertyChanged(nameof(IsGrid));
|
OnPropertyChanged(nameof(IsGrid));
|
||||||
@ -758,9 +758,9 @@ 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;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
OnPropertyChanged(nameof(GridSizeScale));
|
OnPropertyChanged(nameof(GridSizeScale));
|
||||||
@ -772,10 +772,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
internal ApplicationSort SortMode
|
internal ApplicationSort SortMode
|
||||||
{
|
{
|
||||||
get => (ApplicationSort)ConfigurationState.Instance.Ui.ApplicationSort.Value;
|
get => (ApplicationSort)ConfigurationState.Instance.UI.ApplicationSort.Value;
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.ApplicationSort.Value = (int)value;
|
ConfigurationState.Instance.UI.ApplicationSort.Value = (int)value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
OnPropertyChanged(nameof(SortName));
|
OnPropertyChanged(nameof(SortName));
|
||||||
@ -788,7 +788,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ConfigurationState.Instance.Ui.GridSize.Value switch
|
return ConfigurationState.Instance.UI.GridSize.Value switch
|
||||||
{
|
{
|
||||||
1 => 78,
|
1 => 78,
|
||||||
2 => 100,
|
2 => 100,
|
||||||
@ -803,7 +803,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ConfigurationState.Instance.Ui.GridSize.Value switch
|
return ConfigurationState.Instance.UI.GridSize.Value switch
|
||||||
{
|
{
|
||||||
1 => 120,
|
1 => 120,
|
||||||
2 => ShowNames ? 210 : 150,
|
2 => ShowNames ? 210 : 150,
|
||||||
@ -816,10 +816,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public int GridSizeScale
|
public int GridSizeScale
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.Ui.GridSize;
|
get => ConfigurationState.Instance.UI.GridSize;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.GridSize.Value = value;
|
ConfigurationState.Instance.UI.GridSize.Value = value;
|
||||||
|
|
||||||
if (value < 2)
|
if (value < 2)
|
||||||
{
|
{
|
||||||
@ -860,10 +860,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool IsAscending
|
public bool IsAscending
|
||||||
{
|
{
|
||||||
get => ConfigurationState.Instance.Ui.IsAscendingOrder;
|
get => ConfigurationState.Instance.UI.IsAscendingOrder;
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.IsAscendingOrder.Value = value;
|
ConfigurationState.Instance.UI.IsAscendingOrder.Value = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
OnPropertyChanged(nameof(SortMode));
|
OnPropertyChanged(nameof(SortMode));
|
||||||
@ -919,7 +919,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
public RendererHost RendererHostControl { get; private set; }
|
public RendererHost RendererHostControl { get; private set; }
|
||||||
public bool IsClosing { get; set; }
|
public bool IsClosing { get; set; }
|
||||||
public LibHacHorizonManager LibHacHorizonManager { get; internal set; }
|
public LibHacHorizonManager LibHacHorizonManager { get; internal set; }
|
||||||
public IHostUiHandler UiHandler { get; internal set; }
|
public IHostUIHandler UiHandler { get; internal set; }
|
||||||
public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
|
public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
|
||||||
public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
|
public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
|
||||||
public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
|
public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
|
||||||
@ -928,10 +928,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
public bool IsSortedByType => SortMode == ApplicationSort.FileType;
|
public bool IsSortedByType => SortMode == ApplicationSort.FileType;
|
||||||
public bool IsSortedBySize => SortMode == ApplicationSort.FileSize;
|
public bool IsSortedBySize => SortMode == ApplicationSort.FileSize;
|
||||||
public bool IsSortedByPath => SortMode == ApplicationSort.Path;
|
public bool IsSortedByPath => SortMode == ApplicationSort.Path;
|
||||||
public bool IsGridSmall => ConfigurationState.Instance.Ui.GridSize == 1;
|
public bool IsGridSmall => ConfigurationState.Instance.UI.GridSize == 1;
|
||||||
public bool IsGridMedium => ConfigurationState.Instance.Ui.GridSize == 2;
|
public bool IsGridMedium => ConfigurationState.Instance.UI.GridSize == 2;
|
||||||
public bool IsGridLarge => ConfigurationState.Instance.Ui.GridSize == 3;
|
public bool IsGridLarge => ConfigurationState.Instance.UI.GridSize == 3;
|
||||||
public bool IsGridHuge => ConfigurationState.Instance.Ui.GridSize == 4;
|
public bool IsGridHuge => ConfigurationState.Instance.UI.GridSize == 4;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -1245,7 +1245,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public void LoadConfigurableHotKeys()
|
public void LoadConfigurableHotKeys()
|
||||||
{
|
{
|
||||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUi, out var showUiKey))
|
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI, out var showUiKey))
|
||||||
{
|
{
|
||||||
ShowUiKey = new KeyGesture(showUiKey);
|
ShowUiKey = new KeyGesture(showUiKey);
|
||||||
}
|
}
|
||||||
@ -1350,16 +1350,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public void OpenLogsFolder()
|
public void OpenLogsFolder()
|
||||||
{
|
{
|
||||||
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
|
string logPath = AppDataManager.GetOrCreateLogsDir();
|
||||||
|
if (!string.IsNullOrEmpty(logPath))
|
||||||
if (LoggerModule.LogDirectoryPath != null)
|
|
||||||
{
|
{
|
||||||
logPath = LoggerModule.LogDirectoryPath;
|
OpenHelper.OpenFolder(logPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
new DirectoryInfo(logPath).Create();
|
|
||||||
|
|
||||||
OpenHelper.OpenFolder(logPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleDockMode()
|
public void ToggleDockMode()
|
||||||
@ -1390,7 +1385,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.LanguageCode.Value = (string)languageCode;
|
ConfigurationState.Instance.UI.LanguageCode.Value = (string)languageCode;
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Graphics.Vulkan;
|
using Ryujinx.Graphics.Vulkan;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Configuration.System;
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -408,9 +408,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
HideCursor = (int)config.HideCursor.Value;
|
HideCursor = (int)config.HideCursor.Value;
|
||||||
|
|
||||||
GameDirectories.Clear();
|
GameDirectories.Clear();
|
||||||
GameDirectories.AddRange(config.Ui.GameDirs.Value);
|
GameDirectories.AddRange(config.UI.GameDirs.Value);
|
||||||
|
|
||||||
BaseStyleIndex = config.Ui.BaseStyle == "Light" ? 0 : 1;
|
BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
EnableDockedMode = config.System.EnableDockedMode;
|
EnableDockedMode = config.System.EnableDockedMode;
|
||||||
@ -494,10 +494,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
if (_directoryChanged)
|
if (_directoryChanged)
|
||||||
{
|
{
|
||||||
List<string> gameDirs = new(GameDirectories);
|
List<string> gameDirs = new(GameDirectories);
|
||||||
config.Ui.GameDirs.Value = gameDirs;
|
config.UI.GameDirs.Value = gameDirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Ui.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
|
config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
config.System.EnableDockedMode.Value = EnableDockedMode;
|
config.System.EnableDockedMode.Value = EnableDockedMode;
|
||||||
|
@ -17,7 +17,7 @@ using Ryujinx.Common.Configuration;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -10,9 +10,9 @@ using Ryujinx.Ava.UI.Windows;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -43,7 +43,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
checkBoxes.Add(new CheckBox
|
checkBoxes.Add(new CheckBox
|
||||||
{
|
{
|
||||||
Content = $".{fileName}",
|
Content = $".{fileName}",
|
||||||
IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.Ui.ShownFileTypes),
|
IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
|
||||||
Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
|
Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using Avalonia.Interactivity;
|
|||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Main
|
namespace Ryujinx.Ava.UI.Views.Main
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysShowUiHotkey}" Width="230" />
|
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysShowUiHotkey}" Width="230" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding KeyboardHotkeys.ShowUi, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding KeyboardHotkeys.ShowUI, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
||||||
@ -40,11 +39,10 @@
|
|||||||
ItemsSource="{Binding Profiles}">
|
ItemsSource="{Binding Profiles}">
|
||||||
<ListBox.ItemsPanel>
|
<ListBox.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<flex:FlexPanel
|
<WrapPanel
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Center"
|
||||||
AlignContent="FlexStart"
|
Orientation="Horizontal"/>
|
||||||
JustifyContent="FlexStart" />
|
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
<ListBox.Styles>
|
<ListBox.Styles>
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
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"
|
||||||
@ -45,33 +44,37 @@
|
|||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Image
|
<StackPanel
|
||||||
Grid.Column="0"
|
Grid.Column="1"
|
||||||
Height="80"
|
Orientation="Horizontal"
|
||||||
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
|
HorizontalAlignment="Center"
|
||||||
<flex:FlexPanel
|
Spacing="10">
|
||||||
Grid.Column="2"
|
<Image
|
||||||
HorizontalAlignment="Stretch"
|
Height="80"
|
||||||
VerticalAlignment="Stretch"
|
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common"
|
||||||
Direction="Column"
|
|
||||||
JustifyContent="SpaceAround"
|
|
||||||
RowSpacing="2">
|
|
||||||
<TextBlock
|
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
IsHitTestVisible="True" />
|
||||||
|
<WrapPanel
|
||||||
|
HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontSize="28"
|
Orientation="Vertical">
|
||||||
FontWeight="Bold"
|
<TextBlock
|
||||||
Text="Ryujinx"
|
FontSize="28"
|
||||||
TextAlignment="Center"
|
FontWeight="Bold"
|
||||||
Width="110" />
|
Text="Ryujinx"
|
||||||
<TextBlock
|
TextAlignment="Start"
|
||||||
HorizontalAlignment="Center"
|
Width="110"
|
||||||
VerticalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
FontSize="11"
|
VerticalAlignment="Center" />
|
||||||
Text="(REE-YOU-JINX)"
|
<TextBlock
|
||||||
TextAlignment="Center"
|
FontSize="11"
|
||||||
Width="110" />
|
Text="(REE-YOU-JINX)"
|
||||||
</flex:FlexPanel>
|
TextAlignment="Start"
|
||||||
|
Width="110"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</WrapPanel>
|
||||||
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
@ -7,7 +7,7 @@ using FluentAvalonia.UI.Controls;
|
|||||||
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.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Button = Avalonia.Controls.Button;
|
using Button = Avalonia.Controls.Button;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ui.Common.Models.Amiibo;
|
using Ryujinx.UI.Common.Models.Amiibo;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Windows
|
namespace Ryujinx.Ava.UI.Windows
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.Models;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.Models;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Button = Avalonia.Controls.Button;
|
using Button = Avalonia.Controls.Button;
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Ryujinx.Input.SDL2;
|
using Ryujinx.Input.SDL2;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
using Ryujinx.Ui.App.Common;
|
using Ryujinx.UI.App.Common;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.UI.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
@ -40,7 +40,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
private static bool _deferLoad;
|
private static bool _deferLoad;
|
||||||
private static string _launchPath;
|
private static string _launchPath;
|
||||||
private static bool _startFullscreen;
|
private static bool _startFullscreen;
|
||||||
internal readonly AvaHostUiHandler UiHandler;
|
internal readonly AvaHostUIHandler UiHandler;
|
||||||
|
|
||||||
public VirtualFileSystem VirtualFileSystem { get; private set; }
|
public VirtualFileSystem VirtualFileSystem { get; private set; }
|
||||||
public ContentManager ContentManager { get; private set; }
|
public ContentManager ContentManager { get; private set; }
|
||||||
@ -69,7 +69,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Load();
|
Load();
|
||||||
|
|
||||||
UiHandler = new AvaHostUiHandler(this);
|
UiHandler = new AvaHostUIHandler(this);
|
||||||
|
|
||||||
ViewModel.Title = $"Ryujinx {Program.Version}";
|
ViewModel.Title = $"Ryujinx {Program.Version}";
|
||||||
|
|
||||||
@ -319,13 +319,13 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
private void SetWindowSizePosition()
|
private void SetWindowSizePosition()
|
||||||
{
|
{
|
||||||
PixelPoint savedPoint = new(ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX,
|
PixelPoint savedPoint = new(ConfigurationState.Instance.UI.WindowStartup.WindowPositionX,
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY);
|
||||||
|
|
||||||
ViewModel.WindowHeight = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
|
ViewModel.WindowHeight = ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
|
||||||
ViewModel.WindowWidth = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
|
ViewModel.WindowWidth = ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
|
||||||
|
|
||||||
ViewModel.WindowState = ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal;
|
ViewModel.WindowState = ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal;
|
||||||
|
|
||||||
if (CheckScreenBounds(savedPoint))
|
if (CheckScreenBounds(savedPoint))
|
||||||
{
|
{
|
||||||
@ -353,13 +353,13 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
private void SaveWindowSizePosition()
|
private void SaveWindowSizePosition()
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight.Value = (int)Height;
|
ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)Height;
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth.Value = (int)Width;
|
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)Width;
|
||||||
|
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX.Value = Position.X;
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY.Value = Position.Y;
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
||||||
|
|
||||||
ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
|
ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
|
||||||
|
|
||||||
MainWindowViewModel.SaveConfig();
|
MainWindowViewModel.SaveConfig();
|
||||||
}
|
}
|
||||||
@ -512,12 +512,12 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
_ = fileType switch
|
_ = fileType switch
|
||||||
{
|
{
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
"NSP" => ConfigurationState.Instance.Ui.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NSP,
|
"NSP" => ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSP,
|
||||||
"PFS0" => ConfigurationState.Instance.Ui.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.PFS0,
|
"PFS0" => ConfigurationState.Instance.UI.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.UI.ShownFileTypes.PFS0,
|
||||||
"XCI" => ConfigurationState.Instance.Ui.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.XCI,
|
"XCI" => ConfigurationState.Instance.UI.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.UI.ShownFileTypes.XCI,
|
||||||
"NCA" => ConfigurationState.Instance.Ui.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NCA,
|
"NCA" => ConfigurationState.Instance.UI.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NCA,
|
||||||
"NRO" => ConfigurationState.Instance.Ui.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NRO,
|
"NRO" => ConfigurationState.Instance.UI.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NRO,
|
||||||
"NSO" => ConfigurationState.Instance.Ui.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NSO,
|
"NSO" => ConfigurationState.Instance.UI.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSO,
|
||||||
_ => throw new ArgumentOutOfRangeException(fileType),
|
_ => throw new ArgumentOutOfRangeException(fileType),
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
@ -537,7 +537,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
Thread applicationLibraryThread = new(() =>
|
Thread applicationLibraryThread = new(() =>
|
||||||
{
|
{
|
||||||
ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, ConfigurationState.Instance.System.Language);
|
ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs, ConfigurationState.Instance.System.Language);
|
||||||
|
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
})
|
})
|
||||||
|
@ -40,14 +40,14 @@
|
|||||||
Name="EnableAllButton"
|
Name="EnableAllButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding EnableAll}">
|
Command="{Binding EnableAll}">
|
||||||
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
|
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Name="DisableAllButton"
|
Name="DisableAllButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding DisableAll}">
|
Command="{Binding DisableAll}">
|
||||||
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
|
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -6,7 +6,7 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.Models;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Button = Avalonia.Controls.Button;
|
using Button = Avalonia.Controls.Button;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ using Avalonia.Media;
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||||
TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
|
TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
|
||||||
|
|
||||||
using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
|
using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
|
||||||
|
|
||||||
Icon = new WindowIcon(stream);
|
Icon = new WindowIcon(stream);
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
|
@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.Models;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Button = Avalonia.Controls.Button;
|
using Button = Avalonia.Controls.Button;
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ namespace Ryujinx.Common.Configuration
|
|||||||
public static string KeysDirPath { get; private set; }
|
public static string KeysDirPath { get; private set; }
|
||||||
public static string KeysDirPathUser { get; }
|
public static string KeysDirPathUser { get; }
|
||||||
|
|
||||||
|
public static string LogsDirPath { get; private set; }
|
||||||
|
|
||||||
public const string DefaultNandDir = "bis";
|
public const string DefaultNandDir = "bis";
|
||||||
public const string DefaultSdcardDir = "sdcard";
|
public const string DefaultSdcardDir = "sdcard";
|
||||||
private const string DefaultModsDir = "mods";
|
private const string DefaultModsDir = "mods";
|
||||||
@ -46,15 +48,7 @@ namespace Ryujinx.Common.Configuration
|
|||||||
|
|
||||||
public static void Initialize(string baseDirPath)
|
public static void Initialize(string baseDirPath)
|
||||||
{
|
{
|
||||||
string appDataPath;
|
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||||
if (OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appDataPath.Length == 0)
|
if (appDataPath.Length == 0)
|
||||||
{
|
{
|
||||||
@ -118,9 +112,126 @@ namespace Ryujinx.Common.Configuration
|
|||||||
SetupBasePaths();
|
SetupBasePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetOrCreateLogsDir()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(LogsDirPath))
|
||||||
|
{
|
||||||
|
return LogsDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Notice.Print(LogClass.Application, "Logging directory not found; attempting to create new logging directory.");
|
||||||
|
LogsDirPath = SetUpLogsDir();
|
||||||
|
|
||||||
|
return LogsDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string SetUpLogsDir()
|
||||||
|
{
|
||||||
|
string logDir = "";
|
||||||
|
|
||||||
|
if (Mode == LaunchMode.Portable)
|
||||||
|
{
|
||||||
|
logDir = Path.Combine(BaseDirPath, "Logs");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
// NOTE: Should evaluate to "~/Library/Logs/Ryujinx/".
|
||||||
|
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs", DefaultBaseDir);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
logDir = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(logDir))
|
||||||
|
{
|
||||||
|
// NOTE: Should evaluate to "~/Library/Application Support/Ryujinx/Logs".
|
||||||
|
logDir = Path.Combine(BaseDirPath, "Logs");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
// NOTE: Should evaluate to a "Logs" directory in whatever directory Ryujinx was launched from.
|
||||||
|
logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
logDir = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(logDir))
|
||||||
|
{
|
||||||
|
// NOTE: Should evaluate to "C:\Users\user\AppData\Roaming\Ryujinx\Logs".
|
||||||
|
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
// NOTE: Should evaluate to "~/.config/Ryujinx/Logs".
|
||||||
|
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return logDir;
|
||||||
|
}
|
||||||
|
|
||||||
private static void SetupBasePaths()
|
private static void SetupBasePaths()
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(BaseDirPath);
|
Directory.CreateDirectory(BaseDirPath);
|
||||||
|
LogsDirPath = SetUpLogsDir();
|
||||||
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
|
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
|
||||||
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
|
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
|
||||||
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
||||||
|
@ -6,7 +6,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||||||
{
|
{
|
||||||
public Key ToggleVsync { get; set; }
|
public Key ToggleVsync { get; set; }
|
||||||
public Key Screenshot { get; set; }
|
public Key Screenshot { get; set; }
|
||||||
public Key ShowUi { get; set; }
|
public Key ShowUI { get; set; }
|
||||||
public Key Pause { get; set; }
|
public Key Pause { get; set; }
|
||||||
public Key ToggleMute { get; set; }
|
public Key ToggleMute { get; set; }
|
||||||
public Key ResScaleUp { get; set; }
|
public Key ResScaleUp { get; set; }
|
||||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Common.Logging
|
|||||||
ServiceVi,
|
ServiceVi,
|
||||||
SurfaceFlinger,
|
SurfaceFlinger,
|
||||||
TamperMachine,
|
TamperMachine,
|
||||||
Ui,
|
UI,
|
||||||
Vic,
|
Vic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using Ryujinx.Common.SystemInterop;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
@ -22,6 +23,9 @@ namespace Ryujinx.Common.Logging
|
|||||||
|
|
||||||
public readonly struct Log
|
public readonly struct Log
|
||||||
{
|
{
|
||||||
|
private static readonly string _homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||||
|
private static readonly string _homeDirRedacted = Path.Combine(Directory.GetParent(_homeDir).FullName, "[redacted]");
|
||||||
|
|
||||||
internal readonly LogLevel Level;
|
internal readonly LogLevel Level;
|
||||||
|
|
||||||
internal Log(LogLevel level)
|
internal Log(LogLevel level)
|
||||||
@ -100,7 +104,12 @@ namespace Ryujinx.Common.Logging
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static string FormatMessage(LogClass logClass, string caller, string message) => $"{logClass} {caller}: {message}";
|
private static string FormatMessage(LogClass logClass, string caller, string message)
|
||||||
|
{
|
||||||
|
message = message.Replace(_homeDir, _homeDirRedacted);
|
||||||
|
|
||||||
|
return $"{logClass} {caller}: {message}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Log? Debug { get; private set; }
|
public static Log? Debug { get; private set; }
|
||||||
|
@ -23,7 +23,18 @@ namespace Ryujinx.Common.Logging.Targets
|
|||||||
public static FileStream PrepareLogFile(string path)
|
public static FileStream PrepareLogFile(string path)
|
||||||
{
|
{
|
||||||
// Ensure directory is present
|
// Ensure directory is present
|
||||||
DirectoryInfo logDir = new(path);
|
DirectoryInfo logDir;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logDir = new DirectoryInfo(path);
|
||||||
|
}
|
||||||
|
catch (ArgumentException exception)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, $"Logging directory path ('{path}') was invalid: {exception}");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logDir.Create();
|
logDir.Create();
|
||||||
|
@ -10,6 +10,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
public readonly List<InstInfo> Instructions;
|
public readonly List<InstInfo> Instructions;
|
||||||
public readonly bool EndsWithBranch;
|
public readonly bool EndsWithBranch;
|
||||||
public readonly bool HasHostCall;
|
public readonly bool HasHostCall;
|
||||||
|
public readonly bool HasHostCallSkipContext;
|
||||||
public readonly bool IsTruncated;
|
public readonly bool IsTruncated;
|
||||||
public readonly bool IsLoopEnd;
|
public readonly bool IsLoopEnd;
|
||||||
public readonly bool IsThumb;
|
public readonly bool IsThumb;
|
||||||
@ -20,6 +21,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
List<InstInfo> instructions,
|
List<InstInfo> instructions,
|
||||||
bool endsWithBranch,
|
bool endsWithBranch,
|
||||||
bool hasHostCall,
|
bool hasHostCall,
|
||||||
|
bool hasHostCallSkipContext,
|
||||||
bool isTruncated,
|
bool isTruncated,
|
||||||
bool isLoopEnd,
|
bool isLoopEnd,
|
||||||
bool isThumb)
|
bool isThumb)
|
||||||
@ -31,6 +33,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
Instructions = instructions;
|
Instructions = instructions;
|
||||||
EndsWithBranch = endsWithBranch;
|
EndsWithBranch = endsWithBranch;
|
||||||
HasHostCall = hasHostCall;
|
HasHostCall = hasHostCall;
|
||||||
|
HasHostCallSkipContext = hasHostCallSkipContext;
|
||||||
IsTruncated = isTruncated;
|
IsTruncated = isTruncated;
|
||||||
IsLoopEnd = isLoopEnd;
|
IsLoopEnd = isLoopEnd;
|
||||||
IsThumb = isThumb;
|
IsThumb = isThumb;
|
||||||
@ -57,6 +60,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
Instructions.GetRange(0, splitIndex),
|
Instructions.GetRange(0, splitIndex),
|
||||||
false,
|
false,
|
||||||
HasHostCall,
|
HasHostCall,
|
||||||
|
HasHostCallSkipContext,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
IsThumb);
|
IsThumb);
|
||||||
@ -67,6 +71,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
Instructions.GetRange(splitIndex, splitCount),
|
Instructions.GetRange(splitIndex, splitCount),
|
||||||
EndsWithBranch,
|
EndsWithBranch,
|
||||||
HasHostCall,
|
HasHostCall,
|
||||||
|
HasHostCallSkipContext,
|
||||||
IsTruncated,
|
IsTruncated,
|
||||||
IsLoopEnd,
|
IsLoopEnd,
|
||||||
IsThumb);
|
IsThumb);
|
||||||
|
@ -208,6 +208,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
InstMeta meta;
|
InstMeta meta;
|
||||||
InstFlags extraFlags = InstFlags.None;
|
InstFlags extraFlags = InstFlags.None;
|
||||||
bool hasHostCall = false;
|
bool hasHostCall = false;
|
||||||
|
bool hasHostCallSkipContext = false;
|
||||||
bool isTruncated = false;
|
bool isTruncated = false;
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -246,9 +247,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
meta = InstTableA32<T>.GetMeta(encoding, cpuPreset.Version, cpuPreset.Features);
|
meta = InstTableA32<T>.GetMeta(encoding, cpuPreset.Version, cpuPreset.Features);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta.Name.IsSystemOrCall() && !hasHostCall)
|
if (meta.Name.IsSystemOrCall())
|
||||||
{
|
{
|
||||||
hasHostCall = meta.Name.IsCall() || InstEmitSystem.NeedsCall(meta.Name);
|
if (!hasHostCall)
|
||||||
|
{
|
||||||
|
hasHostCall = InstEmitSystem.NeedsCall(meta.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasHostCallSkipContext)
|
||||||
|
{
|
||||||
|
hasHostCallSkipContext = meta.Name.IsCall() || InstEmitSystem.NeedsCallSkipContext(meta.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insts.Add(new(encoding, meta.Name, meta.EmitFunc, meta.Flags | extraFlags));
|
insts.Add(new(encoding, meta.Name, meta.EmitFunc, meta.Flags | extraFlags));
|
||||||
@ -259,8 +268,8 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
|
|
||||||
if (!isTruncated && IsBackwardsBranch(meta.Name, encoding))
|
if (!isTruncated && IsBackwardsBranch(meta.Name, encoding))
|
||||||
{
|
{
|
||||||
hasHostCall = true;
|
|
||||||
isLoopEnd = true;
|
isLoopEnd = true;
|
||||||
|
hasHostCallSkipContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(
|
return new(
|
||||||
@ -269,6 +278,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
insts,
|
insts,
|
||||||
!isTruncated,
|
!isTruncated,
|
||||||
hasHostCall,
|
hasHostCall,
|
||||||
|
hasHostCallSkipContext,
|
||||||
isTruncated,
|
isTruncated,
|
||||||
isLoopEnd,
|
isLoopEnd,
|
||||||
isThumb);
|
isThumb);
|
||||||
|
@ -6,6 +6,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
{
|
{
|
||||||
public readonly List<Block> Blocks;
|
public readonly List<Block> Blocks;
|
||||||
public readonly bool HasHostCall;
|
public readonly bool HasHostCall;
|
||||||
|
public readonly bool HasHostCallSkipContext;
|
||||||
public readonly bool IsTruncated;
|
public readonly bool IsTruncated;
|
||||||
|
|
||||||
public MultiBlock(List<Block> blocks)
|
public MultiBlock(List<Block> blocks)
|
||||||
@ -15,12 +16,14 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
Block block = blocks[0];
|
Block block = blocks[0];
|
||||||
|
|
||||||
HasHostCall = block.HasHostCall;
|
HasHostCall = block.HasHostCall;
|
||||||
|
HasHostCallSkipContext = block.HasHostCallSkipContext;
|
||||||
|
|
||||||
for (int index = 1; index < blocks.Count; index++)
|
for (int index = 1; index < blocks.Count; index++)
|
||||||
{
|
{
|
||||||
block = blocks[index];
|
block = blocks[index];
|
||||||
|
|
||||||
HasHostCall |= block.HasHostCall;
|
HasHostCall |= block.HasHostCall;
|
||||||
|
HasHostCallSkipContext |= block.HasHostCallSkipContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = blocks[^1];
|
block = blocks[^1];
|
||||||
|
@ -106,6 +106,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
|
|||||||
if ((regMask & AbiConstants.ReservedRegsMask) == 0)
|
if ((regMask & AbiConstants.ReservedRegsMask) == 0)
|
||||||
{
|
{
|
||||||
_gprMask |= regMask;
|
_gprMask |= regMask;
|
||||||
|
UsedGprsMask |= regMask;
|
||||||
|
|
||||||
return firstCalleeSaved;
|
return firstCalleeSaved;
|
||||||
}
|
}
|
||||||
|
@ -305,12 +305,23 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp);
|
ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reservedStackSize = 0;
|
||||||
|
|
||||||
|
if (multiBlock.HasHostCall)
|
||||||
|
{
|
||||||
|
reservedStackSize = CalculateStackSizeForCallSpill(regAlloc.UsedGprsMask, regAlloc.UsedFpSimdMask, UsablePStateMask);
|
||||||
|
}
|
||||||
|
else if (multiBlock.HasHostCallSkipContext)
|
||||||
|
{
|
||||||
|
reservedStackSize = 2 * sizeof(ulong); // Context and page table pointers.
|
||||||
|
}
|
||||||
|
|
||||||
RegisterSaveRestore rsr = new(
|
RegisterSaveRestore rsr = new(
|
||||||
regAlloc.UsedGprsMask & AbiConstants.GprCalleeSavedRegsMask,
|
regAlloc.UsedGprsMask & AbiConstants.GprCalleeSavedRegsMask,
|
||||||
regAlloc.UsedFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask,
|
regAlloc.UsedFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask,
|
||||||
OperandType.FP64,
|
OperandType.FP64,
|
||||||
multiBlock.HasHostCall,
|
multiBlock.HasHostCall || multiBlock.HasHostCallSkipContext,
|
||||||
multiBlock.HasHostCall ? CalculateStackSizeForCallSpill(regAlloc.UsedGprsMask, regAlloc.UsedFpSimdMask, UsablePStateMask) : 0);
|
reservedStackSize);
|
||||||
|
|
||||||
TailMerger tailMerger = new();
|
TailMerger tailMerger = new();
|
||||||
|
|
||||||
@ -596,7 +607,8 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
name == InstName.Ldm ||
|
name == InstName.Ldm ||
|
||||||
name == InstName.Ldmda ||
|
name == InstName.Ldmda ||
|
||||||
name == InstName.Ldmdb ||
|
name == InstName.Ldmdb ||
|
||||||
name == InstName.Ldmib)
|
name == InstName.Ldmib ||
|
||||||
|
name == InstName.Pop)
|
||||||
{
|
{
|
||||||
// Arm32 does not have a return instruction, instead returns are implemented
|
// Arm32 does not have a return instruction, instead returns are implemented
|
||||||
// either using BX LR (for leaf functions), or POP { ... PC }.
|
// either using BX LR (for leaf functions), or POP { ... PC }.
|
||||||
@ -711,7 +723,14 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case BranchType.SyncPoint:
|
case BranchType.SyncPoint:
|
||||||
InstEmitSystem.WriteSyncPoint(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset());
|
InstEmitSystem.WriteSyncPoint(
|
||||||
|
context.Writer,
|
||||||
|
ref asm,
|
||||||
|
context.RegisterAllocator,
|
||||||
|
context.TailMerger,
|
||||||
|
context.GetReservedStackOffset(),
|
||||||
|
context.StoreToContext,
|
||||||
|
context.LoadFromContext);
|
||||||
break;
|
break;
|
||||||
case BranchType.SoftwareInterrupt:
|
case BranchType.SoftwareInterrupt:
|
||||||
context.StoreToContext();
|
context.StoreToContext();
|
||||||
|
@ -199,12 +199,12 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
|
public static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
|
||||||
{
|
{
|
||||||
WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true);
|
WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
|
public static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
|
||||||
{
|
{
|
||||||
WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false);
|
WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false);
|
||||||
}
|
}
|
||||||
|
@ -354,11 +354,18 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
// All instructions that might do a host call should be included here.
|
// All instructions that might do a host call should be included here.
|
||||||
// That is required to reserve space on the stack for caller saved registers.
|
// That is required to reserve space on the stack for caller saved registers.
|
||||||
|
|
||||||
|
return name == InstName.Mrrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool NeedsCallSkipContext(InstName name)
|
||||||
|
{
|
||||||
|
// All instructions that might do a host call should be included here.
|
||||||
|
// That is required to reserve space on the stack for caller saved registers.
|
||||||
|
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
case InstName.Mcr:
|
case InstName.Mcr:
|
||||||
case InstName.Mrc:
|
case InstName.Mrc:
|
||||||
case InstName.Mrrc:
|
|
||||||
case InstName.Svc:
|
case InstName.Svc:
|
||||||
case InstName.Udf:
|
case InstName.Udf:
|
||||||
return true;
|
return true;
|
||||||
@ -372,7 +379,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
Assembler asm = new(writer);
|
Assembler asm = new(writer);
|
||||||
|
|
||||||
WriteCall(ref asm, regAlloc, GetBkptHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
|
WriteCall(ref asm, regAlloc, GetBkptHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
|
||||||
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
|
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteSvc(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint svcId)
|
public static void WriteSvc(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint svcId)
|
||||||
@ -380,7 +387,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
Assembler asm = new(writer);
|
Assembler asm = new(writer);
|
||||||
|
|
||||||
WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, svcId);
|
WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, svcId);
|
||||||
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
|
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteUdf(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm)
|
public static void WriteUdf(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm)
|
||||||
@ -388,7 +395,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
Assembler asm = new(writer);
|
Assembler asm = new(writer);
|
||||||
|
|
||||||
WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
|
WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
|
||||||
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
|
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteReadCntpct(CodeWriter writer, RegisterAllocator regAlloc, int spillBaseOffset, int rt, int rt2)
|
public static void WriteReadCntpct(CodeWriter writer, RegisterAllocator regAlloc, int spillBaseOffset, int rt, int rt2)
|
||||||
@ -422,14 +429,14 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
WriteFill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister);
|
WriteFill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteSyncPoint(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset)
|
public static void WriteSyncPoint(
|
||||||
{
|
CodeWriter writer,
|
||||||
Assembler asm = new(writer);
|
ref Assembler asm,
|
||||||
|
RegisterAllocator regAlloc,
|
||||||
WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: false, spillBaseOffset);
|
TailMerger tailMerger,
|
||||||
}
|
int spillBaseOffset,
|
||||||
|
Action storeToContext = null,
|
||||||
private static void WriteSyncPoint(CodeWriter writer, ref Assembler asm, RegisterAllocator regAlloc, TailMerger tailMerger, bool skipContext, int spillBaseOffset)
|
Action loadFromContext = null)
|
||||||
{
|
{
|
||||||
int tempRegister = regAlloc.AllocateTempGprRegister();
|
int tempRegister = regAlloc.AllocateTempGprRegister();
|
||||||
|
|
||||||
@ -440,7 +447,8 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
int branchIndex = writer.InstructionPointer;
|
int branchIndex = writer.InstructionPointer;
|
||||||
asm.Cbnz(rt, 0);
|
asm.Cbnz(rt, 0);
|
||||||
|
|
||||||
WriteSpill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister);
|
storeToContext?.Invoke();
|
||||||
|
WriteSpill(ref asm, regAlloc, 1u << tempRegister, skipContext: true, spillBaseOffset, tempRegister);
|
||||||
|
|
||||||
Operand rn = Register(tempRegister == 0 ? 1 : 0);
|
Operand rn = Register(tempRegister == 0 ? 1 : 0);
|
||||||
|
|
||||||
@ -449,7 +457,8 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
|
|
||||||
tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32));
|
tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32));
|
||||||
|
|
||||||
WriteFill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister);
|
WriteFill(ref asm, regAlloc, 1u << tempRegister, skipContext: true, spillBaseOffset, tempRegister);
|
||||||
|
loadFromContext?.Invoke();
|
||||||
|
|
||||||
asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
|
asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
|
||||||
|
|
||||||
@ -514,18 +523,31 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
|
|
||||||
private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
|
private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
|
||||||
{
|
{
|
||||||
WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: true);
|
if (skipContext)
|
||||||
|
{
|
||||||
|
InstEmitFlow.WriteSpillSkipContext(ref asm, regAlloc, spillOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
|
private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
|
||||||
{
|
{
|
||||||
WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: false);
|
if (skipContext)
|
||||||
|
{
|
||||||
|
InstEmitFlow.WriteFillSkipContext(ref asm, regAlloc, spillOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteSpillOrFill(
|
private static void WriteSpillOrFill(
|
||||||
ref Assembler asm,
|
ref Assembler asm,
|
||||||
RegisterAllocator regAlloc,
|
RegisterAllocator regAlloc,
|
||||||
bool skipContext,
|
|
||||||
uint exceptMask,
|
uint exceptMask,
|
||||||
int spillOffset,
|
int spillOffset,
|
||||||
int tempRegister,
|
int tempRegister,
|
||||||
@ -533,11 +555,6 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
{
|
{
|
||||||
uint gprMask = regAlloc.UsedGprsMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask);
|
uint gprMask = regAlloc.UsedGprsMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask);
|
||||||
|
|
||||||
if (skipContext)
|
|
||||||
{
|
|
||||||
gprMask &= ~Compiler.UsableGprsMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spill)
|
if (!spill)
|
||||||
{
|
{
|
||||||
// We must reload the status register before reloading the GPRs,
|
// We must reload the status register before reloading the GPRs,
|
||||||
@ -600,11 +617,6 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
|
|
||||||
uint fpSimdMask = regAlloc.UsedFpSimdMask;
|
uint fpSimdMask = regAlloc.UsedFpSimdMask;
|
||||||
|
|
||||||
if (skipContext)
|
|
||||||
{
|
|
||||||
fpSimdMask &= ~Compiler.UsableFpSimdMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fpSimdMask != 0)
|
while (fpSimdMask != 0)
|
||||||
{
|
{
|
||||||
int reg = BitOperations.TrailingZeroCount(fpSimdMask);
|
int reg = BitOperations.TrailingZeroCount(fpSimdMask);
|
||||||
|
@ -147,6 +147,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
A1B5G5R5Unorm,
|
A1B5G5R5Unorm,
|
||||||
B8G8R8A8Unorm,
|
B8G8R8A8Unorm,
|
||||||
B8G8R8A8Srgb,
|
B8G8R8A8Srgb,
|
||||||
|
B10G10R10A2Unorm,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FormatExtensions
|
public static class FormatExtensions
|
||||||
@ -260,6 +261,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
case Format.R10G10B10A2Sint:
|
case Format.R10G10B10A2Sint:
|
||||||
case Format.R10G10B10A2Uscaled:
|
case Format.R10G10B10A2Uscaled:
|
||||||
case Format.R10G10B10A2Sscaled:
|
case Format.R10G10B10A2Sscaled:
|
||||||
|
case Format.B10G10R10A2Unorm:
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case Format.S8Uint:
|
case Format.S8Uint:
|
||||||
@ -451,6 +453,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
case Format.R32G32Uint:
|
case Format.R32G32Uint:
|
||||||
case Format.B8G8R8A8Unorm:
|
case Format.B8G8R8A8Unorm:
|
||||||
case Format.B8G8R8A8Srgb:
|
case Format.B8G8R8A8Srgb:
|
||||||
|
case Format.B10G10R10A2Unorm:
|
||||||
case Format.R10G10B10A2Unorm:
|
case Format.R10G10B10A2Unorm:
|
||||||
case Format.R10G10B10A2Uint:
|
case Format.R10G10B10A2Uint:
|
||||||
case Format.R8G8B8A8Unorm:
|
case Format.R8G8B8A8Unorm:
|
||||||
@ -611,6 +614,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
case Format.B5G5R5A1Unorm:
|
case Format.B5G5R5A1Unorm:
|
||||||
case Format.B8G8R8A8Unorm:
|
case Format.B8G8R8A8Unorm:
|
||||||
case Format.B8G8R8A8Srgb:
|
case Format.B8G8R8A8Srgb:
|
||||||
|
case Format.B10G10R10A2Unorm:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +277,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
|
|
||||||
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
|
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
|
||||||
|
|
||||||
|
// If remapping is disabled, we always copy the components directly, in order.
|
||||||
|
// If it's enabled, but the mapping is just XYZW, we also copy them in order.
|
||||||
|
bool isIdentityRemap = !remap ||
|
||||||
|
(_state.State.SetRemapComponentsDstX == SetRemapComponentsDst.SrcX &&
|
||||||
|
(dstComponents < 2 || _state.State.SetRemapComponentsDstY == SetRemapComponentsDst.SrcY) &&
|
||||||
|
(dstComponents < 3 || _state.State.SetRemapComponentsDstZ == SetRemapComponentsDst.SrcZ) &&
|
||||||
|
(dstComponents < 4 || _state.State.SetRemapComponentsDstW == SetRemapComponentsDst.SrcW));
|
||||||
|
|
||||||
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
|
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
|
||||||
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
|
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
|
||||||
|
|
||||||
@ -284,7 +292,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
// but only if we are doing a complete copy,
|
// but only if we are doing a complete copy,
|
||||||
// and not for block linear to linear copies, since those are typically accessed from the CPU.
|
// and not for block linear to linear copies, since those are typically accessed from the CPU.
|
||||||
|
|
||||||
if (completeSource && completeDest && !(dstLinear && !srcLinear))
|
if (completeSource && completeDest && !(dstLinear && !srcLinear) && isIdentityRemap)
|
||||||
{
|
{
|
||||||
var target = memoryManager.Physical.TextureCache.FindTexture(
|
var target = memoryManager.Physical.TextureCache.FindTexture(
|
||||||
memoryManager,
|
memoryManager,
|
||||||
@ -353,14 +361,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
TextureParams srcParams = new(srcRegionX, srcRegionY, srcBaseOffset, srcBpp, srcLinear, srcCalculator);
|
TextureParams srcParams = new(srcRegionX, srcRegionY, srcBaseOffset, srcBpp, srcLinear, srcCalculator);
|
||||||
TextureParams dstParams = new(dstRegionX, dstRegionY, dstBaseOffset, dstBpp, dstLinear, dstCalculator);
|
TextureParams dstParams = new(dstRegionX, dstRegionY, dstBaseOffset, dstBpp, dstLinear, dstCalculator);
|
||||||
|
|
||||||
// If remapping is enabled, we always copy the components directly, in order.
|
|
||||||
// If it's enabled, but the mapping is just XYZW, we also copy them in order.
|
|
||||||
bool isIdentityRemap = !remap ||
|
|
||||||
(_state.State.SetRemapComponentsDstX == SetRemapComponentsDst.SrcX &&
|
|
||||||
(dstComponents < 2 || _state.State.SetRemapComponentsDstY == SetRemapComponentsDst.SrcY) &&
|
|
||||||
(dstComponents < 3 || _state.State.SetRemapComponentsDstZ == SetRemapComponentsDst.SrcZ) &&
|
|
||||||
(dstComponents < 4 || _state.State.SetRemapComponentsDstW == SetRemapComponentsDst.SrcW));
|
|
||||||
|
|
||||||
if (isIdentityRemap)
|
if (isIdentityRemap)
|
||||||
{
|
{
|
||||||
// The order of the components doesn't change, so we can just copy directly
|
// The order of the components doesn't change, so we can just copy directly
|
||||||
|
@ -26,6 +26,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
public const int PrimitiveRestartStateIndex = 12;
|
public const int PrimitiveRestartStateIndex = 12;
|
||||||
public const int RenderTargetStateIndex = 27;
|
public const int RenderTargetStateIndex = 27;
|
||||||
|
|
||||||
|
// Vertex buffers larger than this size will be clamped to the mapped size.
|
||||||
|
private const ulong VertexBufferSizeToMappedSizeThreshold = 256 * 1024 * 1024; // 256 MB
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
private readonly GpuChannel _channel;
|
private readonly GpuChannel _channel;
|
||||||
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
||||||
@ -1144,6 +1147,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
size = Math.Min(size, maxVertexBufferSize);
|
size = Math.Min(size, maxVertexBufferSize);
|
||||||
}
|
}
|
||||||
|
else if (size > VertexBufferSizeToMappedSizeThreshold)
|
||||||
|
{
|
||||||
|
// Make sure we have a sane vertex buffer size, since in some cases applications
|
||||||
|
// might set the "end address" of the vertex buffer to the end of the GPU address space,
|
||||||
|
// which would result in a several GBs large buffer.
|
||||||
|
|
||||||
|
size = _channel.MemoryManager.GetMappedSize(address, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -37,6 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
|
|||||||
R16G16Sint = 0xdc,
|
R16G16Sint = 0xdc,
|
||||||
R16G16Uint = 0xdd,
|
R16G16Uint = 0xdd,
|
||||||
R16G16Float = 0xde,
|
R16G16Float = 0xde,
|
||||||
|
B10G10R10A2Unorm = 0xdf,
|
||||||
R11G11B10Float = 0xe0,
|
R11G11B10Float = 0xe0,
|
||||||
R32Sint = 0xe3,
|
R32Sint = 0xe3,
|
||||||
R32Uint = 0xe4,
|
R32Uint = 0xe4,
|
||||||
@ -104,6 +105,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
|
|||||||
ColorFormat.R16G16Sint => new FormatInfo(Format.R16G16Sint, 1, 1, 4, 2),
|
ColorFormat.R16G16Sint => new FormatInfo(Format.R16G16Sint, 1, 1, 4, 2),
|
||||||
ColorFormat.R16G16Uint => new FormatInfo(Format.R16G16Uint, 1, 1, 4, 2),
|
ColorFormat.R16G16Uint => new FormatInfo(Format.R16G16Uint, 1, 1, 4, 2),
|
||||||
ColorFormat.R16G16Float => new FormatInfo(Format.R16G16Float, 1, 1, 4, 2),
|
ColorFormat.R16G16Float => new FormatInfo(Format.R16G16Float, 1, 1, 4, 2),
|
||||||
|
ColorFormat.B10G10R10A2Unorm => new FormatInfo(Format.B10G10R10A2Unorm, 1, 1, 4, 4),
|
||||||
ColorFormat.R11G11B10Float => new FormatInfo(Format.R11G11B10Float, 1, 1, 4, 3),
|
ColorFormat.R11G11B10Float => new FormatInfo(Format.R11G11B10Float, 1, 1, 4, 3),
|
||||||
ColorFormat.R32Sint => new FormatInfo(Format.R32Sint, 1, 1, 4, 1),
|
ColorFormat.R32Sint => new FormatInfo(Format.R32Sint, 1, 1, 4, 1),
|
||||||
ColorFormat.R32Uint => new FormatInfo(Format.R32Uint, 1, 1, 4, 1),
|
ColorFormat.R32Uint => new FormatInfo(Format.R32Uint, 1, 1, 4, 1),
|
||||||
|
@ -30,6 +30,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
_thread.Start();
|
_thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasContext() => _backgroundContext.HasContext();
|
||||||
|
|
||||||
private void Run()
|
private void Run()
|
||||||
{
|
{
|
||||||
InBackground = true;
|
InBackground = true;
|
||||||
|
@ -161,6 +161,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551));
|
Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551));
|
||||||
Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||||
Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||||
|
Add(Format.B10G10R10A2Unorm, new FormatInfo(4, false, false, All.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed));
|
||||||
|
|
||||||
Add(Format.R8Unorm, SizedInternalFormat.R8);
|
Add(Format.R8Unorm, SizedInternalFormat.R8);
|
||||||
Add(Format.R8Uint, SizedInternalFormat.R8ui);
|
Add(Format.R8Uint, SizedInternalFormat.R8ui);
|
||||||
|
@ -7,21 +7,6 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
{
|
{
|
||||||
void MakeCurrent();
|
void MakeCurrent();
|
||||||
|
|
||||||
// TODO: Support more APIs per platform.
|
bool HasContext();
|
||||||
static bool HasContext()
|
|
||||||
{
|
|
||||||
if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
return WGLHelper.GetCurrentContext() != IntPtr.Zero;
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
return GLXHelper.GetCurrentContext() != IntPtr.Zero;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
{
|
{
|
||||||
// alwaysBackground is ignored, since we cannot switch from the current context.
|
// alwaysBackground is ignored, since we cannot switch from the current context.
|
||||||
|
|
||||||
if (IOpenGLContext.HasContext())
|
if (_window.BackgroundContext.HasContext())
|
||||||
{
|
{
|
||||||
action(); // We have a context already - use that (assuming it is the main one).
|
action(); // We have a context already - use that (assuming it is the main one).
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TranslatorContext.Definitions.Stage == ShaderStage.Vertex && TranslatorContext.Options.TargetApi == TargetApi.Vulkan)
|
// Vulkan requires the point size to be always written on the shader if the primitive topology is points.
|
||||||
|
// OpenGL requires the point size to be always written on the shader if PROGRAM_POINT_SIZE is set.
|
||||||
|
if (TranslatorContext.Definitions.Stage == ShaderStage.Vertex)
|
||||||
{
|
{
|
||||||
// Vulkan requires the point size to be always written on the shader if the primitive topology is points.
|
|
||||||
this.Store(StorageKind.Output, IoVariable.PointSize, null, ConstF(TranslatorContext.Definitions.PointSize));
|
this.Store(StorageKind.Output, IoVariable.PointSize, null, ConstF(TranslatorContext.Definitions.PointSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Device\Ryujinx.Graphics.Device.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Device\Ryujinx.Graphics.Device.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Host1x\Ryujinx.Graphics.Host1x.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -161,6 +161,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
||||||
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
||||||
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
||||||
|
Add(Format.B10G10R10A2Unorm, VkFormat.A2R10G10B10UnormPack32);
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +839,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int level = 0; level < levels; level++)
|
for (int level = 0; level < levels; level++)
|
||||||
{
|
{
|
||||||
int mipSize = GetBufferDataLength(Info.GetMipSize2D(dstLevel + level) * dstLayers);
|
int mipSize = GetBufferDataLength(is3D && !singleSlice
|
||||||
|
? Info.GetMipSize(dstLevel + level)
|
||||||
|
: Info.GetMipSize2D(dstLevel + level) * dstLayers);
|
||||||
|
|
||||||
int endOffset = offset + mipSize;
|
int endOffset = offset + mipSize;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ using Ryujinx.HLE.FileSystem;
|
|||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE
|
namespace Ryujinx.HLE
|
||||||
@ -63,7 +63,7 @@ namespace Ryujinx.HLE
|
|||||||
/// The handler for various UI related operations needed outside of HLE.
|
/// The handler for various UI related operations needed outside of HLE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly IHostUiHandler HostUiHandler;
|
internal readonly IHostUIHandler HostUIHandler;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control the memory configuration used by the emulation context.
|
/// Control the memory configuration used by the emulation context.
|
||||||
@ -177,7 +177,7 @@ namespace Ryujinx.HLE
|
|||||||
IRenderer gpuRenderer,
|
IRenderer gpuRenderer,
|
||||||
IHardwareDeviceDriver audioDeviceDriver,
|
IHardwareDeviceDriver audioDeviceDriver,
|
||||||
MemoryConfiguration memoryConfiguration,
|
MemoryConfiguration memoryConfiguration,
|
||||||
IHostUiHandler hostUiHandler,
|
IHostUIHandler hostUIHandler,
|
||||||
SystemLanguage systemLanguage,
|
SystemLanguage systemLanguage,
|
||||||
RegionCode region,
|
RegionCode region,
|
||||||
bool enableVsync,
|
bool enableVsync,
|
||||||
@ -204,7 +204,7 @@ namespace Ryujinx.HLE
|
|||||||
GpuRenderer = gpuRenderer;
|
GpuRenderer = gpuRenderer;
|
||||||
AudioDeviceDriver = audioDeviceDriver;
|
AudioDeviceDriver = audioDeviceDriver;
|
||||||
MemoryConfiguration = memoryConfiguration;
|
MemoryConfiguration = memoryConfiguration;
|
||||||
HostUiHandler = hostUiHandler;
|
HostUIHandler = hostUIHandler;
|
||||||
SystemLanguage = systemLanguage;
|
SystemLanguage = systemLanguage;
|
||||||
Region = region;
|
Region = region;
|
||||||
EnableVsync = enableVsync;
|
EnableVsync = enableVsync;
|
||||||
|
@ -86,7 +86,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
PlayerIndex primaryIndex;
|
PlayerIndex primaryIndex;
|
||||||
while (!_system.Device.Hid.Npads.Validate(playerMin, playerMax, (ControllerType)privateArg.NpadStyleSet, out configuredCount, out primaryIndex))
|
while (!_system.Device.Hid.Npads.Validate(playerMin, playerMax, (ControllerType)privateArg.NpadStyleSet, out configuredCount, out primaryIndex))
|
||||||
{
|
{
|
||||||
ControllerAppletUiArgs uiArgs = new()
|
ControllerAppletUIArgs uiArgs = new()
|
||||||
{
|
{
|
||||||
PlayerCountMin = playerMin,
|
PlayerCountMin = playerMin,
|
||||||
PlayerCountMax = playerMax,
|
PlayerCountMax = playerMax,
|
||||||
@ -95,7 +95,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
IsDocked = _system.State.DockedMode,
|
IsDocked = _system.State.DockedMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!_system.Device.UiHandler.DisplayMessageDialog(uiArgs))
|
if (!_system.Device.UIHandler.DisplayMessageDialog(uiArgs))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets
|
namespace Ryujinx.HLE.HOS.Applets
|
||||||
{
|
{
|
||||||
public struct ControllerAppletUiArgs
|
public struct ControllerAppletUIArgs
|
||||||
{
|
{
|
||||||
public int PlayerCountMin;
|
public int PlayerCountMin;
|
||||||
public int PlayerCountMax;
|
public int PlayerCountMax;
|
@ -166,13 +166,13 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
string[] buttons = GetButtonsText(module, description, "DlgBtn");
|
string[] buttons = GetButtonsText(module, description, "DlgBtn");
|
||||||
|
|
||||||
bool showDetails = _horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons);
|
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons);
|
||||||
if (showDetails)
|
if (showDetails)
|
||||||
{
|
{
|
||||||
message = GetMessageText(module, description, "FlvMsg");
|
message = GetMessageText(module, description, "FlvMsg");
|
||||||
buttons = GetButtonsText(module, description, "FlvBtn");
|
buttons = GetButtonsText(module, description, "FlvBtn");
|
||||||
|
|
||||||
_horizon.Device.UiHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons);
|
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,12 +200,12 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
buttons.Add("OK");
|
buttons.Add("OK");
|
||||||
|
|
||||||
bool showDetails = _horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber}", "\n" + messageText, buttons.ToArray());
|
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber}", "\n" + messageText, buttons.ToArray());
|
||||||
if (showDetails)
|
if (showDetails)
|
||||||
{
|
{
|
||||||
buttons.RemoveAt(0);
|
buttons.RemoveAt(0);
|
||||||
|
|
||||||
_horizon.Device.UiHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray());
|
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -4,8 +4,8 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||||
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
|
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.HLE.Ui.Input;
|
using Ryujinx.HLE.UI.Input;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -92,14 +92,14 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
_keyboardBackgroundInitialize = MemoryMarshal.Read<SoftwareKeyboardInitialize>(keyboardConfig);
|
_keyboardBackgroundInitialize = MemoryMarshal.Read<SoftwareKeyboardInitialize>(keyboardConfig);
|
||||||
_backgroundState = InlineKeyboardState.Uninitialized;
|
_backgroundState = InlineKeyboardState.Uninitialized;
|
||||||
|
|
||||||
if (_device.UiHandler == null)
|
if (_device.UIHandler == null)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.ServiceAm, "GUI Handler is not set, software keyboard applet will not work properly");
|
Logger.Error?.Print(LogClass.ServiceAm, "GUI Handler is not set, software keyboard applet will not work properly");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create a text handler that converts keyboard strokes to strings.
|
// Create a text handler that converts keyboard strokes to strings.
|
||||||
_dynamicTextInputHandler = _device.UiHandler.CreateDynamicTextInputHandler();
|
_dynamicTextInputHandler = _device.UIHandler.CreateDynamicTextInputHandler();
|
||||||
_dynamicTextInputHandler.TextChangedEvent += HandleTextChangedEvent;
|
_dynamicTextInputHandler.TextChangedEvent += HandleTextChangedEvent;
|
||||||
_dynamicTextInputHandler.KeyPressedEvent += HandleKeyPressedEvent;
|
_dynamicTextInputHandler.KeyPressedEvent += HandleKeyPressedEvent;
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
_npads.NpadButtonDownEvent += HandleNpadButtonDownEvent;
|
_npads.NpadButtonDownEvent += HandleNpadButtonDownEvent;
|
||||||
_npads.NpadButtonUpEvent += HandleNpadButtonUpEvent;
|
_npads.NpadButtonUpEvent += HandleNpadButtonUpEvent;
|
||||||
|
|
||||||
_keyboardRenderer = new SoftwareKeyboardRenderer(_device.UiHandler.HostUiTheme);
|
_keyboardRenderer = new SoftwareKeyboardRenderer(_device.UIHandler.HostUITheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
@ -199,7 +199,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
_keyboardForegroundConfig.StringLengthMax = 100;
|
_keyboardForegroundConfig.StringLengthMax = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_device.UiHandler == null)
|
if (_device.UIHandler == null)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, "GUI Handler is not set. Falling back to default");
|
Logger.Warning?.Print(LogClass.Application, "GUI Handler is not set. Falling back to default");
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Call the configured GUI handler to get user's input.
|
// Call the configured GUI handler to get user's input.
|
||||||
var args = new SoftwareKeyboardUiArgs
|
var args = new SoftwareKeyboardUIArgs
|
||||||
{
|
{
|
||||||
KeyboardMode = _keyboardForegroundConfig.Mode,
|
KeyboardMode = _keyboardForegroundConfig.Mode,
|
||||||
HeaderText = StripUnicodeControlCodes(_keyboardForegroundConfig.HeaderText),
|
HeaderText = StripUnicodeControlCodes(_keyboardForegroundConfig.HeaderText),
|
||||||
@ -222,7 +222,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||||||
InitialText = initialText,
|
InitialText = initialText,
|
||||||
};
|
};
|
||||||
|
|
||||||
_lastResult = _device.UiHandler.DisplayInputDialog(args, out _textValue) ? KeyboardResult.Accept : KeyboardResult.Cancel;
|
_lastResult = _device.UIHandler.DisplayInputDialog(args, out _textValue) ? KeyboardResult.Accept : KeyboardResult.Cancel;
|
||||||
_textValue ??= initialText ?? DefaultInputText;
|
_textValue ??= initialText ?? DefaultInputText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -15,13 +15,13 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
|
|
||||||
private readonly object _stateLock = new();
|
private readonly object _stateLock = new();
|
||||||
|
|
||||||
private readonly SoftwareKeyboardUiState _state = new();
|
private readonly SoftwareKeyboardUIState _state = new();
|
||||||
private readonly SoftwareKeyboardRendererBase _renderer;
|
private readonly SoftwareKeyboardRendererBase _renderer;
|
||||||
|
|
||||||
private readonly TimedAction _textBoxBlinkTimedAction = new();
|
private readonly TimedAction _textBoxBlinkTimedAction = new();
|
||||||
private readonly TimedAction _renderAction = new();
|
private readonly TimedAction _renderAction = new();
|
||||||
|
|
||||||
public SoftwareKeyboardRenderer(IHostUiTheme uiTheme)
|
public SoftwareKeyboardRenderer(IHostUITheme uiTheme)
|
||||||
{
|
{
|
||||||
_renderer = new SoftwareKeyboardRendererBase(uiTheme);
|
_renderer = new SoftwareKeyboardRendererBase(uiTheme);
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
StartRenderer(_renderAction, _renderer, _state, _stateLock);
|
StartRenderer(_renderAction, _renderer, _state, _stateLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StartTextBoxBlinker(TimedAction timedAction, SoftwareKeyboardUiState state, object stateLock)
|
private static void StartTextBoxBlinker(TimedAction timedAction, SoftwareKeyboardUIState state, object stateLock)
|
||||||
{
|
{
|
||||||
timedAction.Reset(() =>
|
timedAction.Reset(() =>
|
||||||
{
|
{
|
||||||
@ -45,9 +45,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
}, TextBoxBlinkSleepMilliseconds);
|
}, TextBoxBlinkSleepMilliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StartRenderer(TimedAction timedAction, SoftwareKeyboardRendererBase renderer, SoftwareKeyboardUiState state, object stateLock)
|
private static void StartRenderer(TimedAction timedAction, SoftwareKeyboardRendererBase renderer, SoftwareKeyboardUIState state, object stateLock)
|
||||||
{
|
{
|
||||||
SoftwareKeyboardUiState internalState = new();
|
SoftwareKeyboardUIState internalState = new();
|
||||||
|
|
||||||
bool canCreateSurface = false;
|
bool canCreateSurface = false;
|
||||||
bool needsUpdate = true;
|
bool needsUpdate = true;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using SixLabors.Fonts;
|
using SixLabors.Fonts;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
private Point _logoPosition;
|
private Point _logoPosition;
|
||||||
private float _messagePositionY;
|
private float _messagePositionY;
|
||||||
|
|
||||||
public SoftwareKeyboardRendererBase(IHostUiTheme uiTheme)
|
public SoftwareKeyboardRendererBase(IHostUITheme uiTheme)
|
||||||
{
|
{
|
||||||
int ryujinxLogoSize = 32;
|
int ryujinxLogoSize = 32;
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawMutableElements(SoftwareKeyboardUiState state)
|
public void DrawMutableElements(SoftwareKeyboardUIState state)
|
||||||
{
|
{
|
||||||
if (_surface == null)
|
if (_surface == null)
|
||||||
{
|
{
|
||||||
@ -322,7 +322,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||||||
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
|
private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUIState state)
|
||||||
{
|
{
|
||||||
var inputTextRectangle = MeasureString(state.InputText, _inputTextFont);
|
var inputTextRectangle = MeasureString(state.InputText, _inputTextFont);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets
|
namespace Ryujinx.HLE.HOS.Applets
|
||||||
{
|
{
|
||||||
public struct SoftwareKeyboardUiArgs
|
public struct SoftwareKeyboardUIArgs
|
||||||
{
|
{
|
||||||
public KeyboardMode KeyboardMode;
|
public KeyboardMode KeyboardMode;
|
||||||
public string HeaderText;
|
public string HeaderText;
|
@ -1,11 +1,11 @@
|
|||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TODO
|
/// TODO
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class SoftwareKeyboardUiState
|
internal class SoftwareKeyboardUIState
|
||||||
{
|
{
|
||||||
public string InputText = "";
|
public string InputText = "";
|
||||||
public int CursorBegin = 0;
|
public int CursorBegin = 0;
|
@ -22,6 +22,9 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
|||||||
private readonly UserId _userId;
|
private readonly UserId _userId;
|
||||||
#pragma warning restore IDE0052
|
#pragma warning restore IDE0052
|
||||||
|
|
||||||
|
private byte[] _cachedTokenData;
|
||||||
|
private DateTime _cachedTokenExpiry;
|
||||||
|
|
||||||
public ManagerServer(UserId userId)
|
public ManagerServer(UserId userId)
|
||||||
{
|
{
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
@ -144,7 +147,13 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
byte[] tokenData = Encoding.ASCII.GetBytes(GenerateIdToken());
|
if (_cachedTokenData == null || DateTime.UtcNow > _cachedTokenExpiry)
|
||||||
|
{
|
||||||
|
_cachedTokenExpiry = DateTime.UtcNow + TimeSpan.FromHours(3);
|
||||||
|
_cachedTokenData = Encoding.ASCII.GetBytes(GenerateIdToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] tokenData = _cachedTokenData;
|
||||||
|
|
||||||
context.Memory.Write(bufferPosition, tokenData);
|
context.Memory.Write(bufferPosition, tokenData);
|
||||||
context.ResponseData.Write(tokenData.Length);
|
context.ResponseData.Write(tokenData.Length);
|
||||||
|
@ -97,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
|
|
||||||
if (titleId == 0)
|
if (titleId == 0)
|
||||||
{
|
{
|
||||||
context.Device.UiHandler.ExecuteProgram(context.Device, ProgramSpecifyKind.RestartProgram, titleId);
|
context.Device.UIHandler.ExecuteProgram(context.Device, ProgramSpecifyKind.RestartProgram, titleId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -524,7 +524,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceAm, new { kind, value });
|
Logger.Stub?.PrintStub(LogClass.ServiceAm, new { kind, value });
|
||||||
|
|
||||||
context.Device.UiHandler.ExecuteProgram(context.Device, kind, value);
|
context.Device.UIHandler.ExecuteProgram(context.Device, kind, value);
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
|||||||
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService;
|
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService;
|
||||||
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.Types;
|
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.Types;
|
||||||
using Ryujinx.HLE.HOS.Services.Vi.Types;
|
using Ryujinx.HLE.HOS.Services.Vi.Types;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,7 +7,7 @@ using Ryujinx.HLE.HOS;
|
|||||||
using Ryujinx.HLE.HOS.Services.Apm;
|
using Ryujinx.HLE.HOS.Services.Apm;
|
||||||
using Ryujinx.HLE.HOS.Services.Hid;
|
using Ryujinx.HLE.HOS.Services.Hid;
|
||||||
using Ryujinx.HLE.Loaders.Processes;
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
using Ryujinx.HLE.Ui;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ namespace Ryujinx.HLE
|
|||||||
public PerformanceStatistics Statistics { get; }
|
public PerformanceStatistics Statistics { get; }
|
||||||
public Hid Hid { get; }
|
public Hid Hid { get; }
|
||||||
public TamperMachine TamperMachine { get; }
|
public TamperMachine TamperMachine { get; }
|
||||||
public IHostUiHandler UiHandler { get; }
|
public IHostUIHandler UIHandler { get; }
|
||||||
|
|
||||||
public bool EnableDeviceVsync { get; set; } = true;
|
public bool EnableDeviceVsync { get; set; } = true;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
FileSystem = Configuration.VirtualFileSystem;
|
FileSystem = Configuration.VirtualFileSystem;
|
||||||
UiHandler = Configuration.HostUiHandler;
|
UIHandler = Configuration.HostUIHandler;
|
||||||
|
|
||||||
MemoryAllocationFlags memoryAllocationFlags = configuration.MemoryManagerMode == MemoryManagerMode.SoftwarePageTable
|
MemoryAllocationFlags memoryAllocationFlags = configuration.MemoryManagerMode == MemoryManagerMode.SoftwarePageTable
|
||||||
? MemoryAllocationFlags.Reserve
|
? MemoryAllocationFlags.Reserve
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user