Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7539e26144 | ||
|
1c3697b6a4 | ||
|
81f848e54f | ||
|
358a781639 |
@@ -58,6 +58,8 @@ namespace Ryujinx.Ava
|
|||||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||||
private const int TargetFps = 60;
|
private const int TargetFps = 60;
|
||||||
|
|
||||||
|
private const float VolumeDelta = 0.05f;
|
||||||
|
|
||||||
private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None);
|
private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None);
|
||||||
|
|
||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
@@ -73,6 +75,7 @@ namespace Ryujinx.Ava
|
|||||||
private bool _isStopped;
|
private bool _isStopped;
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private long _lastCursorMoveTime;
|
private long _lastCursorMoveTime;
|
||||||
|
private float _newVolume;
|
||||||
private long _ticks = 0;
|
private long _ticks = 0;
|
||||||
|
|
||||||
private KeyboardHotkeyState _prevHotkeyState;
|
private KeyboardHotkeyState _prevHotkeyState;
|
||||||
@@ -1003,6 +1006,18 @@ namespace Ryujinx.Ava
|
|||||||
GraphicsConfig.ResScale =
|
GraphicsConfig.ResScale =
|
||||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||||
break;
|
break;
|
||||||
|
case KeyboardHotkeyState.VolumeUp:
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() + VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
|
||||||
|
_parent.ViewModel.Volume = Device.GetVolume();
|
||||||
|
break;
|
||||||
|
case KeyboardHotkeyState.VolumeDown:
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() - VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
|
||||||
|
_parent.ViewModel.Volume = Device.GetVolume();
|
||||||
|
break;
|
||||||
case KeyboardHotkeyState.None:
|
case KeyboardHotkeyState.None:
|
||||||
(_keyboardInterface as AvaloniaKeyboard).Clear();
|
(_keyboardInterface as AvaloniaKeyboard).Clear();
|
||||||
break;
|
break;
|
||||||
@@ -1068,6 +1083,14 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.ResScaleDown;
|
state = KeyboardHotkeyState.ResScaleDown;
|
||||||
}
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeUp))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.VolumeUp;
|
||||||
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeDown))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.VolumeDown;
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@@ -574,12 +574,12 @@
|
|||||||
"Discard": "Discard",
|
"Discard": "Discard",
|
||||||
"UserProfilesSetProfileImage": "Set Profile Image",
|
"UserProfilesSetProfileImage": "Set Profile Image",
|
||||||
"UserProfileEmptyNameError": "Name is required",
|
"UserProfileEmptyNameError": "Name is required",
|
||||||
"UserProfileNoImageError": "Profile image must be set",
|
"UserProfileNoImageError": "Profile image must be set",
|
||||||
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
|
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
|
||||||
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
|
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
|
||||||
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
|
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
|
||||||
"UserProfilesName": "Name:",
|
"UserProfilesName": "Name:",
|
||||||
"UserProfilesUserId" : "User Id:",
|
"UserProfilesUserId": "User Id:",
|
||||||
"SettingsTabGraphicsBackend": "Graphics Backend",
|
"SettingsTabGraphicsBackend": "Graphics Backend",
|
||||||
"SettingsTabGraphicsBackendTooltip": "Graphics Backend to use",
|
"SettingsTabGraphicsBackendTooltip": "Graphics Backend to use",
|
||||||
"SettingsEnableTextureRecompression": "Enable Texture Recompression",
|
"SettingsEnableTextureRecompression": "Enable Texture Recompression",
|
||||||
@@ -589,5 +589,8 @@
|
|||||||
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
|
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
|
||||||
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
|
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
|
||||||
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
|
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
|
||||||
|
"RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?",
|
||||||
|
"SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:",
|
||||||
|
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
|
||||||
"VolumeShort": "Vol"
|
"VolumeShort": "Vol"
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
Pause,
|
Pause,
|
||||||
ToggleMute,
|
ToggleMute,
|
||||||
ResScaleUp,
|
ResScaleUp,
|
||||||
ResScaleDown
|
ResScaleDown,
|
||||||
|
VolumeUp,
|
||||||
|
VolumeDown
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,4 +1,6 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
using ICSharpCode.SharpZipLib.GZip;
|
using ICSharpCode.SharpZipLib.GZip;
|
||||||
using ICSharpCode.SharpZipLib.Tar;
|
using ICSharpCode.SharpZipLib.Tar;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
@@ -11,11 +13,13 @@ using Ryujinx.Common;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -40,6 +44,8 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
|
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
|
||||||
|
|
||||||
|
public static bool UpdateSuccessful { get; private set; }
|
||||||
|
|
||||||
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
|
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
|
||||||
{
|
{
|
||||||
if (Running)
|
if (Running)
|
||||||
@@ -198,11 +204,18 @@ namespace Ryujinx.Modules
|
|||||||
_buildSize = -1;
|
_buildSize = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
Dispatcher.UIThread.Post(async () =>
|
||||||
{
|
{
|
||||||
// Show a message asking the user if they want to update
|
// Show a message asking the user if they want to update
|
||||||
UpdaterWindow updateDialog = new(mainWindow, newVersion, _buildUrl);
|
var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
|
||||||
await updateDialog.ShowDialog(mainWindow);
|
LocaleManager.Instance["RyujinxUpdaterMessage"],
|
||||||
|
$"{Program.Version} -> {newVersion}");
|
||||||
|
|
||||||
|
if (shouldUpdate)
|
||||||
|
{
|
||||||
|
UpdateRyujinx(mainWindow, _buildUrl);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,8 +229,10 @@ namespace Ryujinx.Modules
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateRyujinx(UpdaterWindow updateDialog, string downloadUrl)
|
public static async void UpdateRyujinx(Window parent, string downloadUrl)
|
||||||
{
|
{
|
||||||
|
UpdateSuccessful = false;
|
||||||
|
|
||||||
// Empty update dir, although it shouldn't ever have anything inside it
|
// Empty update dir, although it shouldn't ever have anything inside it
|
||||||
if (Directory.Exists(UpdateDir))
|
if (Directory.Exists(UpdateDir))
|
||||||
{
|
{
|
||||||
@@ -228,25 +243,56 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
string updateFile = Path.Combine(UpdateDir, "update.bin");
|
string updateFile = Path.Combine(UpdateDir, "update.bin");
|
||||||
|
|
||||||
// Download the update .zip
|
var taskDialog = new TaskDialog()
|
||||||
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterDownloading"];
|
{
|
||||||
updateDialog.ProgressBar.Value = 0;
|
Header = LocaleManager.Instance["RyujinxUpdater"],
|
||||||
updateDialog.ProgressBar.Maximum = 100;
|
SubHeader = LocaleManager.Instance["UpdaterDownloading"],
|
||||||
|
IconSource = new SymbolIconSource { Symbol = Symbol.Download },
|
||||||
|
Buttons = { },
|
||||||
|
ShowProgressBar = true
|
||||||
|
};
|
||||||
|
|
||||||
Task.Run(() =>
|
taskDialog.XamlRoot = parent;
|
||||||
|
|
||||||
|
taskDialog.Opened += (s, e) =>
|
||||||
{
|
{
|
||||||
if (_buildSize >= 0)
|
if (_buildSize >= 0)
|
||||||
{
|
{
|
||||||
DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
|
DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
|
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
await taskDialog.ShowAsync(true);
|
||||||
|
|
||||||
|
if (UpdateSuccessful)
|
||||||
|
{
|
||||||
|
var shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
|
||||||
|
LocaleManager.Instance["DialogUpdaterCompleteMessage"],
|
||||||
|
LocaleManager.Instance["DialogUpdaterRestartMessage"]);
|
||||||
|
|
||||||
|
if (shouldRestart)
|
||||||
|
{
|
||||||
|
string ryuName = Path.GetFileName(Environment.ProcessPath);
|
||||||
|
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
||||||
|
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray());
|
||||||
|
|
||||||
|
if (!OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
chmod(ryuExe, Convert.ToUInt32("0777", 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
Process.Start(ryuExe, ryuArg);
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DoUpdateWithMultipleThreads(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
|
private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
||||||
{
|
{
|
||||||
// Multi-Threaded Updater
|
// Multi-Threaded Updater
|
||||||
long chunkSize = _buildSize / ConnectionCount;
|
long chunkSize = _buildSize / ConnectionCount;
|
||||||
@@ -290,7 +336,7 @@ namespace Ryujinx.Modules
|
|||||||
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
|
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
|
||||||
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
|
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
|
||||||
|
|
||||||
updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
|
taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
|
||||||
};
|
};
|
||||||
|
|
||||||
client.DownloadDataCompleted += (_, args) =>
|
client.DownloadDataCompleted += (_, args) =>
|
||||||
@@ -301,6 +347,8 @@ namespace Ryujinx.Modules
|
|||||||
{
|
{
|
||||||
webClients[index].Dispose();
|
webClients[index].Dispose();
|
||||||
|
|
||||||
|
taskDialog.Hide();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,14 +368,14 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InstallUpdate(updateDialog, updateFile);
|
InstallUpdate(taskDialog, updateFile);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, e.Message);
|
Logger.Warning?.Print(LogClass.Application, e.Message);
|
||||||
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
|
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
|
||||||
|
|
||||||
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
|
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -348,7 +396,7 @@ namespace Ryujinx.Modules
|
|||||||
webClients[j].CancelAsync();
|
webClients[j].CancelAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
|
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -356,7 +404,7 @@ namespace Ryujinx.Modules
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DoUpdateWithSingleThreadWorker(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
|
private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
||||||
{
|
{
|
||||||
using (HttpClient client = new HttpClient())
|
using (HttpClient client = new HttpClient())
|
||||||
{
|
{
|
||||||
@@ -384,19 +432,26 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
byteWritten += readSize;
|
byteWritten += readSize;
|
||||||
|
|
||||||
updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
|
taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
|
||||||
|
|
||||||
updateFileStream.Write(buffer, 0, readSize);
|
updateFileStream.Write(buffer, 0, readSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallUpdate(updateDialog, updateFile);
|
InstallUpdate(taskDialog, updateFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DoUpdateWithSingleThread(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static double GetPercentage(double value, double max)
|
||||||
{
|
{
|
||||||
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile));
|
return max == 0 ? 0 : value / max * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
||||||
|
{
|
||||||
|
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile));
|
||||||
worker.Name = "Updater.SingleThreadWorker";
|
worker.Name = "Updater.SingleThreadWorker";
|
||||||
worker.Start();
|
worker.Start();
|
||||||
}
|
}
|
||||||
@@ -414,11 +469,11 @@ namespace Ryujinx.Modules
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async void InstallUpdate(UpdaterWindow updateDialog, string updateFile)
|
private static async void InstallUpdate(TaskDialog taskDialog, string updateFile)
|
||||||
{
|
{
|
||||||
// Extract Update
|
// Extract Update
|
||||||
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterExtracting"];
|
taskDialog.SubHeader = LocaleManager.Instance["UpdaterExtracting"];
|
||||||
updateDialog.ProgressBar.Value = 0;
|
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
||||||
|
|
||||||
if (OperatingSystem.IsLinux())
|
if (OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@@ -426,8 +481,6 @@ namespace Ryujinx.Modules
|
|||||||
using (Stream gzipStream = new GZipInputStream(inStream))
|
using (Stream gzipStream = new GZipInputStream(inStream))
|
||||||
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
|
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
|
||||||
{
|
{
|
||||||
updateDialog.ProgressBar.Maximum = inStream.Length;
|
|
||||||
|
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
TarEntry tarEntry;
|
TarEntry tarEntry;
|
||||||
@@ -450,12 +503,12 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
updateDialog.ProgressBar.Value += entry.Size;
|
taskDialog.SetProgressBarState(GetPercentage(entry.Size, inStream.Length), TaskDialogProgressState.Normal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
updateDialog.ProgressBar.Value = inStream.Length;
|
taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -463,12 +516,12 @@ namespace Ryujinx.Modules
|
|||||||
using (Stream inStream = File.OpenRead(updateFile))
|
using (Stream inStream = File.OpenRead(updateFile))
|
||||||
using (ZipFile zipFile = new ZipFile(inStream))
|
using (ZipFile zipFile = new ZipFile(inStream))
|
||||||
{
|
{
|
||||||
updateDialog.ProgressBar.Maximum = zipFile.Count;
|
|
||||||
|
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
double count = 0;
|
||||||
foreach (ZipEntry zipEntry in zipFile)
|
foreach (ZipEntry zipEntry in zipFile)
|
||||||
{
|
{
|
||||||
|
count++;
|
||||||
if (zipEntry.IsDirectory) continue;
|
if (zipEntry.IsDirectory) continue;
|
||||||
|
|
||||||
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
|
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
|
||||||
@@ -485,7 +538,7 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
updateDialog.ProgressBar.Value++;
|
taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -497,22 +550,23 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
List<string> allFiles = EnumerateFilesToDelete().ToList();
|
List<string> allFiles = EnumerateFilesToDelete().ToList();
|
||||||
|
|
||||||
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterRenaming"];
|
taskDialog.SubHeader = LocaleManager.Instance["UpdaterRenaming"];
|
||||||
updateDialog.ProgressBar.Value = 0;
|
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
||||||
updateDialog.ProgressBar.Maximum = allFiles.Count;
|
|
||||||
|
|
||||||
// Replace old files
|
// Replace old files
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
double count = 0;
|
||||||
foreach (string file in allFiles)
|
foreach (string file in allFiles)
|
||||||
{
|
{
|
||||||
|
count++;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Move(file, file + ".ryuold");
|
File.Move(file, file + ".ryuold");
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
updateDialog.ProgressBar.Value++;
|
taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -523,23 +577,20 @@ namespace Ryujinx.Modules
|
|||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterAddingFiles"];
|
taskDialog.SubHeader = LocaleManager.Instance["UpdaterAddingFiles"];
|
||||||
updateDialog.ProgressBar.Value = 0;
|
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
||||||
updateDialog.ProgressBar.Maximum = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog);
|
MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
|
||||||
});
|
});
|
||||||
|
|
||||||
Directory.Delete(UpdateDir, true);
|
Directory.Delete(UpdateDir, true);
|
||||||
|
|
||||||
SetUnixPermissions();
|
SetUnixPermissions();
|
||||||
|
|
||||||
updateDialog.MainText.Text = LocaleManager.Instance["DialogUpdaterCompleteMessage"];
|
UpdateSuccessful = true;
|
||||||
updateDialog.SecondaryText.Text = LocaleManager.Instance["DialogUpdaterRestartMessage"];
|
|
||||||
|
|
||||||
updateDialog.ProgressBar.IsVisible = false;
|
taskDialog.Hide();
|
||||||
updateDialog.ButtonBox.IsVisible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
@@ -618,8 +669,9 @@ namespace Ryujinx.Modules
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MoveAllFilesOver(string root, string dest, UpdaterWindow dialog)
|
private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
|
||||||
{
|
{
|
||||||
|
var total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
|
||||||
foreach (string directory in Directory.GetDirectories(root))
|
foreach (string directory in Directory.GetDirectories(root))
|
||||||
{
|
{
|
||||||
string dirName = Path.GetFileName(directory);
|
string dirName = Path.GetFileName(directory);
|
||||||
@@ -629,16 +681,18 @@ namespace Ryujinx.Modules
|
|||||||
Directory.CreateDirectory(Path.Combine(dest, dirName));
|
Directory.CreateDirectory(Path.Combine(dest, dirName));
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
|
MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double count = 0;
|
||||||
foreach (string file in Directory.GetFiles(root))
|
foreach (string file in Directory.GetFiles(root))
|
||||||
{
|
{
|
||||||
|
count++;
|
||||||
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
|
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
|
||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
dialog.ProgressBar.Value++;
|
taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
|
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
|
||||||
Title="Ryujinx - About"
|
|
||||||
Width="850"
|
Width="850"
|
||||||
Height="550"
|
Height="550"
|
||||||
MinWidth="500"
|
MinWidth="500"
|
||||||
|
@@ -257,6 +257,22 @@
|
|||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeUpHotkey}" Width="230" />
|
||||||
|
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding KeyboardHotkeys.VolumeUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeDownHotkey}" Width="230" />
|
||||||
|
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding KeyboardHotkeys.VolumeDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
<window:StyleableWindow
|
|
||||||
x:Class="Ryujinx.Ava.Ui.Windows.UpdaterWindow"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
|
|
||||||
Title="Ryujinx Updater"
|
|
||||||
Width="500"
|
|
||||||
Height="500"
|
|
||||||
MinWidth="500"
|
|
||||||
MinHeight="500"
|
|
||||||
d:DesignHeight="350"
|
|
||||||
d:DesignWidth="400"
|
|
||||||
CanResize="False"
|
|
||||||
SizeToContent="Height"
|
|
||||||
WindowStartupLocation="CenterOwner"
|
|
||||||
mc:Ignorable="d">
|
|
||||||
<Grid
|
|
||||||
Margin="20"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Name="MainText"
|
|
||||||
Grid.Row="1"
|
|
||||||
Height="20"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<TextBlock
|
|
||||||
Name="SecondaryText"
|
|
||||||
Grid.Row="2"
|
|
||||||
Height="20"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ProgressBar
|
|
||||||
Name="ProgressBar"
|
|
||||||
Grid.Row="3"
|
|
||||||
Margin="20"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
IsVisible="False"
|
|
||||||
Maximum="100"
|
|
||||||
Minimum="0" />
|
|
||||||
<StackPanel
|
|
||||||
Name="ButtonBox"
|
|
||||||
Grid.Row="4"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
IsVisible="False"
|
|
||||||
Orientation="Horizontal"
|
|
||||||
Spacing="20">
|
|
||||||
<Button MinWidth="50" Command="{Binding YesPressed}">
|
|
||||||
<TextBlock Text="{locale:Locale InputDialogYes}" TextAlignment="Center" />
|
|
||||||
</Button>
|
|
||||||
<Button MinWidth="50" Command="{Binding NoPressed}">
|
|
||||||
<TextBlock Text="{locale:Locale InputDialogNo}" TextAlignment="Center" />
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</window:StyleableWindow>
|
|
@@ -1,73 +0,0 @@
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
using Ryujinx.Modules;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Ui.Windows
|
|
||||||
{
|
|
||||||
public partial class UpdaterWindow : StyleableWindow
|
|
||||||
{
|
|
||||||
private readonly string _buildUrl;
|
|
||||||
private readonly MainWindow _mainWindow;
|
|
||||||
private readonly Version _newVersion;
|
|
||||||
private bool _restartQuery;
|
|
||||||
|
|
||||||
public UpdaterWindow()
|
|
||||||
{
|
|
||||||
DataContext = this;
|
|
||||||
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
Title = LocaleManager.Instance["RyujinxUpdater"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpdaterWindow(MainWindow mainWindow, Version newVersion, string buildUrl) : this()
|
|
||||||
{
|
|
||||||
_mainWindow = mainWindow;
|
|
||||||
_newVersion = newVersion;
|
|
||||||
_buildUrl = buildUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("libc", SetLastError = true)]
|
|
||||||
private static extern int chmod(string path, uint mode);
|
|
||||||
|
|
||||||
public void YesPressed()
|
|
||||||
{
|
|
||||||
if (_restartQuery)
|
|
||||||
{
|
|
||||||
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.Ava.exe" : "Ryujinx.Ava";
|
|
||||||
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
|
||||||
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().AsEnumerable().Skip(1).ToArray());
|
|
||||||
|
|
||||||
if (!OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
chmod(ryuExe, 0777);
|
|
||||||
}
|
|
||||||
|
|
||||||
Process.Start(ryuExe, ryuArg);
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ButtonBox.IsVisible = false;
|
|
||||||
ProgressBar.IsVisible = true;
|
|
||||||
|
|
||||||
SecondaryText.Text = "";
|
|
||||||
_restartQuery = true;
|
|
||||||
|
|
||||||
Updater.UpdateRyujinx(this, _buildUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NoPressed()
|
|
||||||
{
|
|
||||||
_mainWindow.UpdateMenuItem.IsEnabled = true;
|
|
||||||
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,5 +9,7 @@
|
|||||||
public Key ToggleMute { get; set; }
|
public Key ToggleMute { get; set; }
|
||||||
public Key ResScaleUp { get; set; }
|
public Key ResScaleUp { get; set; }
|
||||||
public Key ResScaleDown { get; set; }
|
public Key ResScaleDown { get; set; }
|
||||||
|
public Key VolumeUp { get; set; }
|
||||||
|
public Key VolumeDown { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -123,7 +123,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// <param name="releaseCallback">Texture release callback</param>
|
/// <param name="releaseCallback">Texture release callback</param>
|
||||||
/// <param name="userObj">User defined object passed to the release callback</param>
|
/// <param name="userObj">User defined object passed to the release callback</param>
|
||||||
/// <exception cref="ArgumentException">Thrown when <paramref name="pid"/> is invalid</exception>
|
/// <exception cref="ArgumentException">Thrown when <paramref name="pid"/> is invalid</exception>
|
||||||
public void EnqueueFrameThreadSafe(
|
/// <returns>True if the frame was added to the queue, false otherwise</returns>
|
||||||
|
public bool EnqueueFrameThreadSafe(
|
||||||
ulong pid,
|
ulong pid,
|
||||||
ulong address,
|
ulong address,
|
||||||
int width,
|
int width,
|
||||||
@@ -140,7 +141,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
{
|
{
|
||||||
if (!_context.PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory))
|
if (!_context.PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid));
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel, 4);
|
FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel, 4);
|
||||||
@@ -184,6 +185,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
acquireCallback,
|
acquireCallback,
|
||||||
releaseCallback,
|
releaseCallback,
|
||||||
userObj));
|
userObj));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -453,7 +453,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||||||
Item = item
|
Item = item
|
||||||
};
|
};
|
||||||
|
|
||||||
_device.Gpu.Window.EnqueueFrameThreadSafe(
|
if (_device.Gpu.Window.EnqueueFrameThreadSafe(
|
||||||
layer.Owner,
|
layer.Owner,
|
||||||
frameBufferAddress,
|
frameBufferAddress,
|
||||||
frameBufferWidth,
|
frameBufferWidth,
|
||||||
@@ -466,20 +466,25 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||||||
crop,
|
crop,
|
||||||
AcquireBuffer,
|
AcquireBuffer,
|
||||||
ReleaseBuffer,
|
ReleaseBuffer,
|
||||||
textureCallbackInformation);
|
textureCallbackInformation))
|
||||||
|
|
||||||
if (item.Fence.FenceCount == 0)
|
|
||||||
{
|
{
|
||||||
_device.Gpu.Window.SignalFrameReady();
|
if (item.Fence.FenceCount == 0)
|
||||||
_device.Gpu.GPFifo.Interrupt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item.Fence.RegisterCallback(_device.Gpu, (x) =>
|
|
||||||
{
|
{
|
||||||
_device.Gpu.Window.SignalFrameReady();
|
_device.Gpu.Window.SignalFrameReady();
|
||||||
_device.Gpu.GPFifo.Interrupt();
|
_device.Gpu.GPFifo.Interrupt();
|
||||||
});
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Fence.RegisterCallback(_device.Gpu, (x) =>
|
||||||
|
{
|
||||||
|
_device.Gpu.Window.SignalFrameReady();
|
||||||
|
_device.Gpu.GPFifo.Interrupt();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReleaseBuffer(textureCallbackInformation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -124,7 +124,7 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public void SetVolume(float volume)
|
public void SetVolume(float volume)
|
||||||
{
|
{
|
||||||
System.SetVolume(volume);
|
System.SetVolume(Math.Clamp(volume, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetVolume()
|
public float GetVolume()
|
||||||
|
@@ -14,7 +14,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 40;
|
public const int CurrentVersion = 41;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
|
@@ -677,7 +677,9 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
ShowUi = Key.F4,
|
ShowUi = Key.F4,
|
||||||
Pause = Key.F5,
|
Pause = Key.F5,
|
||||||
ResScaleUp = Key.Unbound,
|
ResScaleUp = Key.Unbound,
|
||||||
ResScaleDown = Key.Unbound
|
ResScaleDown = Key.Unbound,
|
||||||
|
VolumeUp = Key.Unbound,
|
||||||
|
VolumeDown = Key.Unbound
|
||||||
};
|
};
|
||||||
Hid.InputConfig.Value = new List<InputConfig>
|
Hid.InputConfig.Value = new List<InputConfig>
|
||||||
{
|
{
|
||||||
@@ -1156,6 +1158,24 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 41)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUi = configurationFileFormat.Hotkeys.ShowUi,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||||
|
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
||||||
|
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
||||||
|
VolumeUp = Key.Unbound,
|
||||||
|
VolumeDown = Key.Unbound
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||||
|
@@ -35,6 +35,7 @@ namespace Ryujinx.Ui
|
|||||||
private const int SwitchPanelHeight = 720;
|
private const int SwitchPanelHeight = 720;
|
||||||
private const int TargetFps = 60;
|
private const int TargetFps = 60;
|
||||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||||
|
private const float VolumeDelta = 0.05f;
|
||||||
|
|
||||||
public ManualResetEvent WaitEvent { get; set; }
|
public ManualResetEvent WaitEvent { get; set; }
|
||||||
public NpadManager NpadManager { get; }
|
public NpadManager NpadManager { get; }
|
||||||
@@ -57,6 +58,7 @@ namespace Ryujinx.Ui
|
|||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
|
|
||||||
private long _ticks = 0;
|
private long _ticks = 0;
|
||||||
|
private float _newVolume;
|
||||||
|
|
||||||
private readonly Stopwatch _chrono;
|
private readonly Stopwatch _chrono;
|
||||||
|
|
||||||
@@ -643,6 +645,20 @@ namespace Ryujinx.Ui
|
|||||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.VolumeUp) &&
|
||||||
|
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.VolumeUp))
|
||||||
|
{
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() + VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.VolumeDown) &&
|
||||||
|
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.VolumeDown))
|
||||||
|
{
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() - VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
}
|
||||||
|
|
||||||
_prevHotkeyState = currentHotkeyState;
|
_prevHotkeyState = currentHotkeyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +691,9 @@ namespace Ryujinx.Ui
|
|||||||
Pause = 1 << 3,
|
Pause = 1 << 3,
|
||||||
ToggleMute = 1 << 4,
|
ToggleMute = 1 << 4,
|
||||||
ResScaleUp = 1 << 5,
|
ResScaleUp = 1 << 5,
|
||||||
ResScaleDown = 1 << 6
|
ResScaleDown = 1 << 6,
|
||||||
|
VolumeUp = 1 << 7,
|
||||||
|
VolumeDown = 1 << 8
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyboardHotkeyState GetHotkeyState()
|
private KeyboardHotkeyState GetHotkeyState()
|
||||||
@@ -717,6 +735,16 @@ namespace Ryujinx.Ui
|
|||||||
state |= KeyboardHotkeyState.ResScaleDown;
|
state |= KeyboardHotkeyState.ResScaleDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeUp))
|
||||||
|
{
|
||||||
|
state |= KeyboardHotkeyState.VolumeUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeDown))
|
||||||
|
{
|
||||||
|
state |= KeyboardHotkeyState.VolumeDown;
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user