Compare commits

..

20 Commits

Author SHA1 Message Date
d1a093e5ca Stub VSMS related ioctls (#6313)
* Stub VSMS related ioctls

* Clean up usings
2024-02-15 19:48:22 +01:00
dfb14a5607 Updaters: Fix ARM Linux Updater (#6316)
* Remove Arch Checks

* Fix ARM Linux updater
2024-02-15 10:41:43 +01:00
jcm
904a5ffcb4 Handle exceptions when checking user data directory for symlink (#6304)
Co-authored-by: jcm <butt@butts.com>
2024-02-12 00:10:21 +01:00
jcm
946633276b macOS: Stop storing user data in Documents for some users; fix symlinks (#6241)
* macOS: Stop storing user data in Documents for some users; fix symlinks

* Use SupportedOSPlatform tag, catch exceptions, log warning instead of error

* Provide best path hints to user if symlink fixup fails

---------

Co-authored-by: jcm <butt@butts.com>
2024-02-11 19:04:39 +01:00
baf94e0e3e infra: Force add linux-x64 apphost in flathub nuget source (#6302)
Required when building on the arm64 runner.

Signed-off-by: Mary Guillemard <mary@mary.zone>
2024-02-11 16:45:58 +01:00
cf6201a4a6 infra: Restore Nuget packages for linux-arm64 for Flatpak
Signed-off-by: Mary Guillemard <mary@mary.zone>
2024-02-11 13:21:54 +01:00
18909195d1 Old buttons (#6237) 2024-02-11 03:12:43 +01:00
f06d22d6f0 Infra: Capitalisation Consistency (#6296)
* Rename Ryujinx.UI.Common

* Rename Ryujinx.UI.LocaleGenerator

* Update in Files

AboutWindow

* Configuration State

* Rename projects

* Ryujinx/UI

* Fix build

* Main remaining inconsistencies

* HLE.UI Namespace

* HLE.UI Files

* Namespace

* Ryujinx.UI.Common.Configuration.UI

* Ryujinx.UI.Common,Configuration.UI Files

* More instances
2024-02-11 03:09:18 +01:00
jcm
84d6e8d121 Standardize logging locations across desktop platforms (#6238)
* Standardize logging locations across desktop platforms

* Return null instead of empty literal on exceptions

* Remove LogDirectoryPath from LoggerModule

* Catch exception when creating DirectoryInfo in FileLogTarget

* Remove redundant log path vars, handle exception better, add null check

* Address styling issues

* Remove extra newline, quote file path in log, move directory check to OpenHelper

* Add GetOrCreateLogsDir to get/create log directory during runtime

* misc format changes

* Update src/Ryujinx.Common/Configuration/AppDataManager.cs

---------

Co-authored-by: jcm <butt@butts.com>
Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
2024-02-11 02:17:19 +01:00
95c4912d58 Linux: Reorder available executables in Ryujinx.sh (#6171)
* Avoid Ryujinx.Headless.SDL2 as a last resort in Ryujinx.desktop when you
  have more than one executable installed.
2024-02-11 00:57:23 +01:00
356a75af0b Remove ReflectionBinding in Mod Manager (#6280) 2024-02-11 00:52:11 +01:00
4ae9921063 Update Avalonia About Window like requested in PR #6267 (#6278)
* Update About Window like requested in PR #6267

* Feedback

* Apply suggestions from code review

Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>

* Fix indents

---------

Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
2024-02-11 00:45:14 +01:00
6a8ac389e5 Fix mip offset/size for full 3D texture upload on Vulkan (#6294) 2024-02-11 00:41:17 +01:00
8dd1eb333c Add missing RID exclusions for linux-arm64 (#6298)
* Add missing RID exclusions for linux-arm64

Signed-off-by: Mary Guillemard <mary@mary.zone>

* Remove libsoundio.so from linux-arm64 deployment

This is a x86_64 library.

Signed-off-by: Mary Guillemard <mary@mary.zone>

---------

Signed-off-by: Mary Guillemard <mary@mary.zone>
2024-02-10 22:49:32 +01:00
7dc3a62c14 ci: Enable Linux ARM64 on build and release (#6291)
* ci: Enable Linux ARM64 on build and release

Signed-off-by: Mary <mary@mary.zone>

* Address gdkchan comment

Signed-off-by: Mary <mary@mary.zone>

---------

Signed-off-by: Mary <mary@mary.zone>
2024-02-10 22:05:46 +01:00
e59dba42ef Set PointSize in shader on OpenGL (#6292)
Previously we were only doing it for Vulkan, but it turns out that
not setting it when PROGRAM_POINT_SIZE is set is considered UB
on OpenGL Core.

Signed-off-by: Mary <mary@mary.zone>
2024-02-10 20:27:17 +01:00
bd6937ae5c Make IOpenGLContext.HasContext context dependent (#6290)
This makes IOpenGLContext.HasContext not static and be implementable.

By doing this, we can support more than WGL and WGL.

This also allows the SDL2 headless version to run under Wayland.

Signed-off-by: Mary <mary@mary.zone>
2024-02-10 20:13:10 +01:00
jcm
b82e789d4f Load custom SDL mappings from application data folder (#6295)
Co-authored-by: jcm <butt@butts.com>
2024-02-10 19:41:02 +01:00
4a6724622e Force CPU copy for non-identity DMA remap (#6293) 2024-02-10 15:38:58 -03:00
0c73eba3db misc: Update to Ryujinx.Graphics.Nvdec.Dependencies 5.0.3-build14 (#6279)
Signed-off-by: Mary Guillemard <mary@mary.zone>
2024-02-10 11:23:44 +01:00
214 changed files with 1184 additions and 888 deletions

2
.github/labeler.yml vendored
View File

@ -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:

View File

@ -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 }})

View File

@ -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

View File

@ -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

View File

@ -32,7 +32,7 @@
<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.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />

View File

@ -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

View File

@ -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" "$@"

View File

@ -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>

View File

@ -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

View File

@ -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))
{ {

View File

@ -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",
@ -329,8 +333,6 @@
"DialogUpdaterAddingFilesMessage": "Adding New Update...", "DialogUpdaterAddingFilesMessage": "Adding New Update...",
"DialogUpdaterCompleteMessage": "Update Complete!", "DialogUpdaterCompleteMessage": "Update Complete!",
"DialogUpdaterRestartMessage": "Do you want to restart Ryujinx now?", "DialogUpdaterRestartMessage": "Do you want to restart Ryujinx now?",
"DialogUpdaterArchNotSupportedMessage": "You are not running a supported system architecture!",
"DialogUpdaterArchNotSupportedSubMessage": "(Only x64 systems are supported!)",
"DialogUpdaterNoInternetMessage": "You are not connected to the Internet!", "DialogUpdaterNoInternetMessage": "You are not connected to the Internet!",
"DialogUpdaterNoInternetSubMessage": "Please verify that you have a working Internet connection!", "DialogUpdaterNoInternetSubMessage": "Please verify that you have a working Internet connection!",
"DialogUpdaterDirtyBuildMessage": "You Cannot update a Dirty build of Ryujinx!", "DialogUpdaterDirtyBuildMessage": "You Cannot update a Dirty build of Ryujinx!",

View File

@ -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;

View File

@ -5,7 +5,7 @@ namespace Ryujinx.Ava.Common
None, None,
ToggleVSync, ToggleVSync,
Screenshot, Screenshot,
ShowUi, ShowUI,
Pause, Pause,
ToggleMute, ToggleMute,
ResScaleUp, ResScaleUp,

View File

@ -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
{ {

View File

@ -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;
@ -68,7 +68,8 @@ namespace Ryujinx.Modules
} }
else if (OperatingSystem.IsLinux()) else if (OperatingSystem.IsLinux())
{ {
_platformExt = "linux_x64.tar.gz"; var arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
_platformExt = $"linux_{arch}.tar.gz";
} }
Version newVersion; Version newVersion;
@ -637,20 +638,6 @@ namespace Ryujinx.Modules
public static bool CanUpdate(bool showWarnings) public static bool CanUpdate(bool showWarnings)
{ {
#if !DISABLE_UPDATER #if !DISABLE_UPDATER
if (RuntimeInformation.OSArchitecture != Architecture.X64 && !OperatingSystem.IsMacOS())
{
if (showWarnings)
{
Dispatcher.UIThread.InvokeAsync(() =>
ContentDialogHelper.CreateWarningDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterArchNotSupportedMessage],
LocaleManager.Instance[LocaleKeys.DialogUpdaterArchNotSupportedSubMessage])
);
}
return false;
}
if (!NetworkInterface.GetIsNetworkAvailable()) if (!NetworkInterface.GetIsNetworkAvailable())
{ {
if (showWarnings) if (showWarnings)

View File

@ -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;

View File

@ -47,9 +47,9 @@
<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" />
@ -73,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>
@ -92,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>
@ -103,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" />

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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"

View File

@ -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"

View File

@ -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();

View File

@ -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"

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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"
@ -39,4 +39,4 @@
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</Window> </Window>

View File

@ -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
{ {

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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}");
} }
} }

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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();
} }

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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;

View File

@ -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)),
}); });
} }

View File

@ -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

View File

@ -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>

View File

@ -44,31 +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"
<WrapPanel Spacing="10">
Grid.Column="2" <Image
HorizontalAlignment="Right" Height="80"
VerticalAlignment="Center" Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common"
Orientation="Vertical">
<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)"
</WrapPanel> TextAlignment="Start"
Width="110"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</WrapPanel>
</StackPanel>
</Grid> </Grid>
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"

View File

@ -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;

View File

@ -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
{ {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}) })

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System; using System;
using System.IO; using System.IO;
using System.Runtime.Versioning;
namespace Ryujinx.Common.Configuration namespace Ryujinx.Common.Configuration
{ {
@ -30,6 +31,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 +49,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)
{ {
@ -101,26 +96,134 @@ namespace Ryujinx.Common.Configuration
BaseDirPath = Path.GetFullPath(BaseDirPath); // convert relative paths BaseDirPath = Path.GetFullPath(BaseDirPath); // convert relative paths
// NOTE: Moves the Ryujinx folder in `~/.config` to `~/Library/Application Support` if one is found if (IsPathSymlink(BaseDirPath))
// and a Ryujinx folder does not already exist in Application Support.
// Also creates a symlink from `~/.config/Ryujinx` to `~/Library/Application Support/Ryujinx` to preserve backwards compatibility.
// This should be removed in the future.
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
{ {
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir); Logger.Warning?.Print(LogClass.Application, $"Application data directory is a symlink. This may be unintended.");
if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath))
{
FileSystemUtils.MoveDirectory(oldConfigPath, BaseDirPath);
Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath);
}
} }
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));
@ -130,8 +233,91 @@ namespace Ryujinx.Common.Configuration
// Should be removed, when the existence of the old directory isn't checked anymore. // Should be removed, when the existence of the old directory isn't checked anymore.
private static bool IsPathSymlink(string path) private static bool IsPathSymlink(string path)
{ {
FileAttributes attributes = File.GetAttributes(path); try
return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint; {
FileAttributes attributes = File.GetAttributes(path);
return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint;
}
catch
{
return false;
}
}
[SupportedOSPlatform("macos")]
public static void FixMacOSConfigurationFolders()
{
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".config", DefaultBaseDir);
if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath))
{
FileSystemUtils.MoveDirectory(oldConfigPath, BaseDirPath);
Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath);
}
string correctApplicationDataDirectoryPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
if (IsPathSymlink(correctApplicationDataDirectoryPath))
{
//copy the files somewhere temporarily
string tempPath = Path.Combine(Path.GetTempPath(), DefaultBaseDir);
try
{
FileSystemUtils.CopyDirectory(correctApplicationDataDirectoryPath, tempPath, true);
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application,
$"Critical error copying Ryujinx application data into the temp folder. {exception}");
try
{
FileSystemInfo resolvedDirectoryInfo =
Directory.ResolveLinkTarget(correctApplicationDataDirectoryPath, true);
string resolvedPath = resolvedDirectoryInfo.FullName;
Logger.Error?.Print(LogClass.Application, $"Please manually move your Ryujinx data from {resolvedPath} to {correctApplicationDataDirectoryPath}, and remove the symlink.");
}
catch (Exception symlinkException)
{
Logger.Error?.Print(LogClass.Application, $"Unable to resolve the symlink for Ryujinx application data: {symlinkException}. Follow the symlink at {correctApplicationDataDirectoryPath} and move your data back to the Application Support folder.");
}
return;
}
//delete the symlink
try
{
//This will fail if this is an actual directory, so there is no way we can actually delete user data here.
File.Delete(correctApplicationDataDirectoryPath);
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application,
$"Critical error deleting the Ryujinx application data folder symlink at {correctApplicationDataDirectoryPath}. {exception}");
try
{
FileSystemInfo resolvedDirectoryInfo =
Directory.ResolveLinkTarget(correctApplicationDataDirectoryPath, true);
string resolvedPath = resolvedDirectoryInfo.FullName;
Logger.Error?.Print(LogClass.Application, $"Please manually move your Ryujinx data from {resolvedPath} to {correctApplicationDataDirectoryPath}, and remove the symlink.");
}
catch (Exception symlinkException)
{
Logger.Error?.Print(LogClass.Application, $"Unable to resolve the symlink for Ryujinx application data: {symlinkException}. Follow the symlink at {correctApplicationDataDirectoryPath} and move your data back to the Application Support folder.");
}
return;
}
//put the files back
try
{
FileSystemUtils.CopyDirectory(tempPath, correctApplicationDataDirectoryPath, true);
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application,
$"Critical error copying Ryujinx application data into the correct location. {exception}. Please manually move your application data from {tempPath} to {correctApplicationDataDirectoryPath}.");
}
}
} }
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName; public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;

View File

@ -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; }

View File

@ -70,7 +70,7 @@ namespace Ryujinx.Common.Logging
ServiceVi, ServiceVi,
SurfaceFlinger, SurfaceFlinger,
TamperMachine, TamperMachine,
Ui, UI,
Vic, Vic,
} }
} }

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}
} }
} }

View File

@ -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).
} }

View File

@ -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));
} }

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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());
} }
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -50,6 +50,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
case 0x06: case 0x06:
result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments); result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments);
break; break;
case 0x12:
result = CallIoctlMethod<NumVsmsArguments>(NumVsms, arguments);
break;
case 0x13:
result = CallIoctlMethod<VsmsMappingArguments>(VsmsMapping, arguments);
break;
case 0x14: case 0x14:
result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments); result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments);
break; break;
@ -76,6 +82,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
case 0x06: case 0x06:
result = CallIoctlMethod<GetTpcMasksArguments, int>(GetTpcMasks, arguments, inlineOutBuffer); result = CallIoctlMethod<GetTpcMasksArguments, int>(GetTpcMasks, arguments, inlineOutBuffer);
break; break;
case 0x12:
result = CallIoctlMethod<NumVsmsArguments>(NumVsms, arguments);
break;
case 0x13:
result = CallIoctlMethod<VsmsMappingArguments>(VsmsMapping, arguments);
break;
} }
} }
@ -216,6 +228,27 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
return NvInternalResult.Success; return NvInternalResult.Success;
} }
private NvInternalResult NumVsms(ref NumVsmsArguments arguments)
{
Logger.Stub?.PrintStub(LogClass.ServiceNv);
arguments.NumVsms = 2;
return NvInternalResult.Success;
}
private NvInternalResult VsmsMapping(ref VsmsMappingArguments arguments)
{
Logger.Stub?.PrintStub(LogClass.ServiceNv);
arguments.Sm0GpcIndex = 0;
arguments.Sm0TpcIndex = 0;
arguments.Sm1GpcIndex = 0;
arguments.Sm1TpcIndex = 1;
return NvInternalResult.Success;
}
private NvInternalResult GetActiveSlotMask(ref GetActiveSlotMaskArguments arguments) private NvInternalResult GetActiveSlotMask(ref GetActiveSlotMaskArguments arguments)
{ {
Logger.Stub?.PrintStub(LogClass.ServiceNv); Logger.Stub?.PrintStub(LogClass.ServiceNv);

View File

@ -0,0 +1,11 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types
{
[StructLayout(LayoutKind.Sequential)]
struct NumVsmsArguments
{
public uint NumVsms;
public uint Reserved;
}
}

View File

@ -0,0 +1,13 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types
{
[StructLayout(LayoutKind.Sequential)]
struct VsmsMappingArguments
{
public byte Sm0GpcIndex;
public byte Sm0TpcIndex;
public byte Sm1GpcIndex;
public byte Sm1TpcIndex;
}
}

View File

@ -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;

View File

@ -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

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public delegate void DynamicTextChangedHandler(string text, int cursorBegin, int cursorEnd, bool overwriteMode); public delegate void DynamicTextChangedHandler(string text, int cursorBegin, int cursorEnd, bool overwriteMode);
} }

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public interface IDynamicTextInputHandler : IDisposable public interface IDynamicTextInputHandler : IDisposable
{ {

View File

@ -1,16 +1,16 @@
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;
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public interface IHostUiHandler public interface IHostUIHandler
{ {
/// <summary> /// <summary>
/// Displays an Input Dialog box to the user and blocks until text is entered. /// Displays an Input Dialog box to the user and blocks until text is entered.
/// </summary> /// </summary>
/// <param name="userText">Text that the user entered. Set to `null` on internal errors</param> /// <param name="userText">Text that the user entered. Set to `null` on internal errors</param>
/// <returns>True when OK is pressed, False otherwise. Also returns True on internal errors</returns> /// <returns>True when OK is pressed, False otherwise. Also returns True on internal errors</returns>
bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText); bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText);
/// <summary> /// <summary>
/// Displays a Message Dialog box to the user and blocks until it is closed. /// Displays a Message Dialog box to the user and blocks until it is closed.
@ -22,7 +22,7 @@ namespace Ryujinx.HLE.Ui
/// Displays a Message Dialog box specific to Controller Applet and blocks until it is closed. /// Displays a Message Dialog box specific to Controller Applet and blocks until it is closed.
/// </summary> /// </summary>
/// <returns>True when OK is pressed, False otherwise.</returns> /// <returns>True when OK is pressed, False otherwise.</returns>
bool DisplayMessageDialog(ControllerAppletUiArgs args); bool DisplayMessageDialog(ControllerAppletUIArgs args);
/// <summary> /// <summary>
/// Tell the UI that we need to transisition to another program. /// Tell the UI that we need to transisition to another program.
@ -46,6 +46,6 @@ namespace Ryujinx.HLE.Ui
/// <summary> /// <summary>
/// Gets fonts and colors used by the host. /// Gets fonts and colors used by the host.
/// </summary> /// </summary>
IHostUiTheme HostUiTheme { get; } IHostUITheme HostUITheme { get; }
} }
} }

View File

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public interface IHostUiTheme public interface IHostUITheme
{ {
string FontFamily { get; } string FontFamily { get; }

View File

@ -1,6 +1,6 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
namespace Ryujinx.HLE.Ui.Input namespace Ryujinx.HLE.UI.Input
{ {
delegate void NpadButtonHandler(int npadIndex, NpadButton button); delegate void NpadButtonHandler(int npadIndex, NpadButton button);
} }

View File

@ -1,7 +1,7 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
namespace Ryujinx.HLE.Ui.Input namespace Ryujinx.HLE.UI.Input
{ {
/// <summary> /// <summary>
/// Class that converts Hid entries for the Npad into pressed / released events. /// Class that converts Hid entries for the Npad into pressed / released events.

View File

@ -1,6 +1,6 @@
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public delegate bool KeyPressedHandler(Key key); public delegate bool KeyPressedHandler(Key key);
} }

View File

@ -1,6 +1,6 @@
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public delegate bool KeyReleasedHandler(Key key); public delegate bool KeyReleasedHandler(Key key);
} }

View File

@ -1,7 +1,7 @@
using Ryujinx.HLE.HOS.Services.SurfaceFlinger; using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
using System; using System;
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
/// <summary> /// <summary>
/// Information about the indirect layer that is being drawn to. /// Information about the indirect layer that is being drawn to.

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Ui namespace Ryujinx.HLE.UI
{ {
public readonly struct ThemeColor public readonly struct ThemeColor
{ {

View File

@ -1,4 +1,4 @@
using Ryujinx.HLE.Ui; using Ryujinx.HLE.UI;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,8 +1,8 @@
using Ryujinx.HLE.Ui; using Ryujinx.HLE.UI;
namespace Ryujinx.Headless.SDL2 namespace Ryujinx.Headless.SDL2
{ {
internal class HeadlessHostUiTheme : IHostUiTheme internal class HeadlessHostUiTheme : IHostUITheme
{ {
public string FontFamily => "sans-serif"; public string FontFamily => "sans-serif";

View File

@ -96,6 +96,8 @@ namespace Ryujinx.Headless.SDL2.OpenGL
} }
} }
public bool HasContext() => SDL_GL_GetCurrentContext() != IntPtr.Zero;
public void Dispose() public void Dispose()
{ {
SDL_GL_DeleteContext(_context); SDL_GL_DeleteContext(_context);

View File

@ -427,16 +427,12 @@ namespace Ryujinx.Headless.SDL2
if (!option.DisableFileLog) if (!option.DisableFileLog)
{ {
FileStream logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (logFile == null) if (!string.IsNullOrEmpty(logDir))
{ {
logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDataManager.BaseDirPath, "Logs")); logFile = FileLogTarget.PrepareLogFile(logDir);
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
}
} }
if (logFile != null) if (logFile != null)
@ -447,6 +443,10 @@ namespace Ryujinx.Headless.SDL2
AsyncLogTargetOverflowAction.Block AsyncLogTargetOverflowAction.Block
)); ));
} }
else
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
}
} }
// Setup graphics configuration // Setup graphics configuration

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