mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-07 22:05:47 +00:00
Compare commits
19 Commits
3a3e5e5c5a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf083a716c | ||
|
|
2d2661298c | ||
|
|
c4788154fd | ||
|
|
49dd56953c | ||
|
|
722eb93554 | ||
|
|
b0179e6433 | ||
|
|
1d3d4197b7 | ||
|
|
d2b2d65061 | ||
|
|
e1dcaef709 | ||
|
|
b222f671f3 | ||
|
|
4d0cd61b6a | ||
|
|
4e86159bce | ||
|
|
0d66cfa281 | ||
|
|
e656de5fff | ||
|
|
518dd65484 | ||
|
|
88421959a6 | ||
|
|
87ce5162be | ||
|
|
a3e10a1e5a | ||
|
|
1e06c86d47 |
@@ -1,7 +1,7 @@
|
||||
name: Build PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- '**'
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: Change config filename
|
||||
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||
shell: bash
|
||||
if: forgejo.event_name == 'pull_request'
|
||||
if: forgejo.event_name == 'pull_request_target'
|
||||
|
||||
- name: 'Cache: ~/.nuget/packages'
|
||||
uses: actions/cache@v5
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Publish Ryujinx
|
||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.result }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
||||
if: forgejo.event_name == 'pull_request'
|
||||
if: forgejo.event_name == 'pull_request_target'
|
||||
|
||||
- name: Packing Windows builds
|
||||
if: contains(matrix.platform.name, 'win')
|
||||
@@ -98,10 +98,10 @@ jobs:
|
||||
with:
|
||||
name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}
|
||||
path: artifact
|
||||
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'win')
|
||||
if: forgejo.event_name == 'pull_request_target' && contains(matrix.platform.name, 'win')
|
||||
|
||||
- name: Build AppImage
|
||||
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux')
|
||||
if: forgejo.event_name == 'pull_request_target' && contains(matrix.platform.name, 'linux')
|
||||
run: |
|
||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
|
||||
- name: Upload Ryujinx AppImage artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux')
|
||||
if: forgejo.event_name == 'pull_request_target' && contains(matrix.platform.name, 'linux')
|
||||
with:
|
||||
name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}-AppImage
|
||||
path: publish_appimage
|
||||
@@ -182,7 +182,7 @@ jobs:
|
||||
- name: Change config filename
|
||||
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||
shell: bash
|
||||
if: forgejo.event_name == 'pull_request'
|
||||
if: forgejo.event_name == 'pull_request_target'
|
||||
|
||||
- name: 'Cache: ~/.nuget/packages'
|
||||
uses: actions/cache@v5
|
||||
@@ -201,4 +201,47 @@ jobs:
|
||||
with:
|
||||
name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-macos_universal
|
||||
path: "publish/*.tar.gz"
|
||||
if: forgejo.event_name == 'pull_request'
|
||||
if: forgejo.event_name == 'pull_request_target'
|
||||
|
||||
post_comment:
|
||||
name: Post comment linking uploaded artifacts
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
- build_macos
|
||||
steps:
|
||||
- uses: actions/github-script@v9
|
||||
env:
|
||||
COMMENTER_TOKEN: ${{ secrets.COMMENTER_TOKEN }}
|
||||
with:
|
||||
github-token: 'n/a'
|
||||
script: |
|
||||
const forgejo = getOctokit(process.env.COMMENTER_TOKEN, {
|
||||
baseUrl: 'https://git.ryujinx.app/api/v1'
|
||||
});
|
||||
|
||||
const {owner, repo} = context.repo;
|
||||
const run_id = ${{ env.FORGEJO_RUN_ID }};
|
||||
|
||||
const issue_number = ${{ forgejo.event.pull_request.number }};
|
||||
core.info(`Using run ID ${run_id} from pull request ${issue_number}`);
|
||||
|
||||
const {data: {artifacts}} = await forgejo.rest.actions.listWorkflowRunArtifacts({owner, repo, run_id});
|
||||
if (artifacts == undefined || !artifacts.length) {
|
||||
return core.error(`No artifacts found for run ID`);
|
||||
}
|
||||
let body = `Download the artifacts for this pull request:\n`;
|
||||
for (const art of artifacts) {
|
||||
const url = `https://git.ryujinx.app/api/v1/repos/${owner}/${repo}/actions/artifacts/${art.id}/zip`;
|
||||
body += `\n* [${art.name}](${url})`;
|
||||
}
|
||||
|
||||
const {data: comments} = await forgejo.rest.issues.listComments({repo, owner, issue_number});
|
||||
const existing_comment = comments.find((c) => c.user.login === 'forgejo-actions');
|
||||
if (existing_comment) {
|
||||
core.info(`Updating comment ${existing_comment.id}`);
|
||||
await forgejo.rest.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
|
||||
} else {
|
||||
core.info(`Creating a comment`);
|
||||
await forgejo.rest.issues.createComment({repo, owner, issue_number, body});
|
||||
}
|
||||
|
||||
@@ -143,9 +143,7 @@ jobs:
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
runs-on: docker
|
||||
container:
|
||||
image: ghcr.io/catthehacker/ubuntu:act-latest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
@@ -207,7 +205,7 @@ jobs:
|
||||
|
||||
post_ci:
|
||||
name: Post-CI Steps
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- macos_release
|
||||
- release
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
name: Comment PR artifacts links
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['Build PR']
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
pr_comment:
|
||||
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const {owner, repo} = context.repo;
|
||||
const run_id = ${{github.event.workflow_run.id}};
|
||||
const pull_head_sha = '${{github.event.workflow_run.head_sha}}';
|
||||
|
||||
const issue_number = await (async () => {
|
||||
const pulls = await github.rest.pulls.list({owner, repo});
|
||||
for await (const {data} of github.paginate.iterator(pulls)) {
|
||||
for (const pull of data) {
|
||||
if (pull.head.sha === pull_head_sha) {
|
||||
return pull.number;
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
if (issue_number) {
|
||||
core.info(`Using pull request ${issue_number}`);
|
||||
} else {
|
||||
return core.error(`No matching pull request found`);
|
||||
}
|
||||
|
||||
const {data: {artifacts}} = await github.rest.actions.listWorkflowRunArtifacts({owner, repo, run_id});
|
||||
if (!artifacts.length) {
|
||||
return core.error(`No artifacts found`);
|
||||
}
|
||||
let body = `Download the artifacts for this pull request:\n`;
|
||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||
for (const art of artifacts) {
|
||||
const url = `https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip`;
|
||||
if (art.name.includes('Debug')) {
|
||||
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||
} else {
|
||||
body += `\n* [${art.name}](${url})`;
|
||||
}
|
||||
}
|
||||
hidden_debug_artifacts += `\n</details>`;
|
||||
body += hidden_debug_artifacts;
|
||||
|
||||
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||
const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]');
|
||||
if (existing_comment) {
|
||||
core.info(`Updating comment ${existing_comment.id}`);
|
||||
await github.rest.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
|
||||
} else {
|
||||
core.info(`Creating a comment`);
|
||||
await github.rest.issues.createComment({repo, owner, issue_number, body});
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
</td>
|
||||
<td align="center" width="75%">
|
||||
|
||||
# Ryujinx
|
||||
<h1 class="ryu-gradient-text">Ryujinx</h1>
|
||||
|
||||
[](https://update.ryujinx.app/latest/stable)
|
||||
[](https://update.ryujinx.app/latest/canary)
|
||||
@@ -21,7 +21,7 @@
|
||||
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
||||
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
||||
It was written from scratch and development on the project began in September 2017.
|
||||
Ryujinx is available on a self-managed <a href="https://github.com/Ryubing/forgejo" target="_blank">modified</a> <a href="https://forgejo.org/" target="_blank">Forgejo</a> instance under the <a href="https://git.ryujinx.app/projects/Ryubing/src/branch/master/LICENSE.txt" target="_blank">MIT license</a>.
|
||||
Ryujinx is available on a self-managed <a class="forgejo-gradient-text" href="https://github.com/Ryubing/forgejo" target="_blank">modified Forgejo</a> instance under the <a href="https://git.ryujinx.app/projects/Ryubing/src/branch/master/LICENSE.txt" target="_blank">MIT license</a>.
|
||||
<br />
|
||||
</p>
|
||||
<p align="center">
|
||||
|
||||
@@ -21425,6 +21425,31 @@
|
||||
"zh_TW": "需要重新啟動 Ryujinx"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsShowConsoleRestartMessage",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "The console will be available the next time Ryujinx starts.",
|
||||
"es_ES": "La consola estará disponible la próxima vez que se inicie Ryujinx.",
|
||||
"fr_FR": "La console sera disponible au prochain démarrage de Ryujinx.",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsGpuBackendRestartMessage",
|
||||
"Translations": {
|
||||
|
||||
@@ -12,20 +12,12 @@ namespace Ryujinx.Common.Helper
|
||||
private static partial nint GetConsoleWindow();
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[LibraryImport("user32")]
|
||||
[LibraryImport("kernel32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[LibraryImport("user32")]
|
||||
private static partial nint GetForegroundWindow();
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[LibraryImport("user32")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static partial bool SetForegroundWindow(nint hWnd);
|
||||
private static partial bool FreeConsole();
|
||||
|
||||
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
|
||||
public static bool HasConsoleWindow => OperatingSystem.IsWindows() && GetConsoleWindow() != nint.Zero;
|
||||
|
||||
public static void SetConsoleWindowState(bool show)
|
||||
{
|
||||
@@ -42,22 +34,31 @@ namespace Ryujinx.Common.Helper
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static void SetConsoleWindowStateWindows(bool show)
|
||||
{
|
||||
const int SW_HIDE = 0;
|
||||
const int SW_SHOW = 5;
|
||||
|
||||
nint hWnd = GetConsoleWindow();
|
||||
|
||||
if (hWnd == nint.Zero)
|
||||
if (show)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist");
|
||||
if (GetConsoleWindow() != nint.Zero)
|
||||
{
|
||||
Logger.SetConsoleTargetEnabled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SetForegroundWindow(hWnd);
|
||||
Logger.SetConsoleTargetEnabled(false);
|
||||
DetachConsole();
|
||||
}
|
||||
|
||||
hWnd = GetForegroundWindow();
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static void DetachConsole()
|
||||
{
|
||||
if (GetConsoleWindow() == nint.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
|
||||
if (!FreeConsole())
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, "Attempted to detach console window but the operation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,11 +136,7 @@ namespace Ryujinx.Common.Logging
|
||||
|
||||
_time = Stopwatch.StartNew();
|
||||
|
||||
// Logger should log to console by default
|
||||
AddTarget(new AsyncLogTargetWrapper(
|
||||
new ConsoleLogTarget("console"),
|
||||
1000,
|
||||
AsyncLogTargetOverflowAction.Discard));
|
||||
SetConsoleTargetEnabled(true);
|
||||
|
||||
Notice = new Log(LogLevel.Notice);
|
||||
|
||||
@@ -173,6 +169,21 @@ namespace Ryujinx.Common.Logging
|
||||
Updated += target.Log;
|
||||
}
|
||||
|
||||
public static void SetConsoleTargetEnabled(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
AddTarget(new AsyncLogTargetWrapper(
|
||||
new ConsoleLogTarget("console"),
|
||||
1000,
|
||||
AsyncLogTargetOverflowAction.Discard));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveTarget("console");
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveTarget(string target)
|
||||
{
|
||||
ILogTarget logTarget = GetTarget(target);
|
||||
|
||||
@@ -49,9 +49,9 @@
|
||||
<PackageReference Include="SharpCompress" />
|
||||
<PackageReference Include="Svg.Controls.Avalonia" />
|
||||
<PackageReference Include="Svg.Controls.Skia.Avalonia" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Win32" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx'" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Win32" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.macOS" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64' AND '$(RuntimeIdentifier)' != 'osx'" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||
<PackageReference Include="DynamicData" />
|
||||
<PackageReference Include="FluentAvaloniaUI" />
|
||||
<PackageReference Include="CommandLineParser" />
|
||||
|
||||
@@ -656,10 +656,19 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
get => ConfigurationState.Instance.UI.ShowConsole;
|
||||
set
|
||||
{
|
||||
bool restartRequired = value && !ConsoleHelper.HasConsoleWindow;
|
||||
|
||||
ConfigurationState.Instance.UI.ShowConsole.Value = value;
|
||||
|
||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||
|
||||
if (restartRequired)
|
||||
{
|
||||
NotificationHelper.ShowInformation(
|
||||
LocaleManager.Instance[LocaleKeys.SettingsAppRequiredRestartMessage],
|
||||
LocaleManager.Instance[LocaleKeys.SettingsShowConsoleRestartMessage]);
|
||||
}
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user