mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-06-04 11:29:14 +00:00
Compare commits
15 Commits
Canary-1.3
...
01220db18c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01220db18c | ||
|
|
ecd1c1240c | ||
|
|
3ad4d4a692 | ||
|
|
6fe7fb8dcb | ||
|
|
fc357d3ba4 | ||
|
|
32ee806070 | ||
|
|
4e81a4c2f4 | ||
|
|
9cae62096a | ||
|
|
648b609ebb | ||
|
|
5ae86fc493 | ||
|
|
6f90e47a73 | ||
|
|
ac5f9857e2 | ||
|
|
55c2ae2b3d | ||
|
|
b51999a1ba | ||
|
|
bfc0d62732 |
6
.github/workflows/canary.yml
vendored
6
.github/workflows/canary.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.31
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -162,7 +162,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.30
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -215,7 +215,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.30
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
|||||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.31
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -161,7 +161,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.30
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -217,7 +217,7 @@ jobs:
|
|||||||
- name: Install gli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64' 2.0.30
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="11.3.6" />
|
<PackageVersion Include="Avalonia" Version="11.3.12" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.12" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.3.12" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.6" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.12" />
|
||||||
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.6.2" />
|
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.4" />
|
||||||
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.6.2" />
|
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.4" />
|
||||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<PackageVersion Include="Concentus" Version="2.2.2" />
|
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI.NoAnim" Version="2.4.0-build3" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.5.0" />
|
||||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||||
|
|||||||
@@ -575,6 +575,31 @@
|
|||||||
"zh_TW": "停止模擬"
|
"zh_TW": "停止模擬"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "MenuBarOptionsRestartEmulation",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Restart Emulation",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "Starta om emulering",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarOptionsSettings",
|
"ID": "MenuBarOptionsSettings",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@@ -11317,7 +11342,7 @@
|
|||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "",
|
"pt_BR": "",
|
||||||
"ru_RU": "",
|
"ru_RU": "",
|
||||||
"sv_SE": "",
|
"sv_SE": "Spara",
|
||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
@@ -24876,4 +24901,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -488,6 +488,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
if (keyPaths.Length is 0)
|
if (keyPaths.Length is 0)
|
||||||
throw new FileNotFoundException($"Directory '{keysSource}' contained no '.keys' files.");
|
throw new FileNotFoundException($"Directory '{keysSource}' contained no '.keys' files.");
|
||||||
|
|
||||||
|
List<string> failedFiles = new();
|
||||||
|
|
||||||
foreach (string filePath in keyPaths)
|
foreach (string filePath in keyPaths)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -497,17 +499,20 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, e.Message);
|
Logger.Error?.Print(LogClass.Application, e.Message);
|
||||||
|
failedFiles.Add(Path.GetFileName(filePath));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string destPath = Path.Combine(installDirectory, Path.GetFileName(filePath));
|
string destPath = Path.Combine(installDirectory, Path.GetFileName(filePath));
|
||||||
|
|
||||||
if (File.Exists(destPath))
|
|
||||||
File.Delete(destPath);
|
|
||||||
|
|
||||||
File.Copy(filePath, destPath, true);
|
File.Copy(filePath, destPath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Failed to install the following key files: {string.Join(", ", failedFiles)}");
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,8 +523,6 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
|
|
||||||
FileInfo info = new(keysSource);
|
FileInfo info = new(keysSource);
|
||||||
|
|
||||||
using FileStream file = File.OpenRead(keysSource);
|
|
||||||
|
|
||||||
if (info.Extension is not ".keys")
|
if (info.Extension is not ".keys")
|
||||||
throw new InvalidFirmwarePackageException("Input file extension is not .keys");
|
throw new InvalidFirmwarePackageException("Input file extension is not .keys");
|
||||||
|
|
||||||
@@ -534,10 +537,6 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
|
|
||||||
string dest = Path.Combine(installDirectory, info.Name);
|
string dest = Path.Combine(installDirectory, info.Name);
|
||||||
|
|
||||||
if (File.Exists(dest))
|
|
||||||
File.Delete(dest);
|
|
||||||
|
|
||||||
// overwrite: true seems to not work on its own? https://github.com/Ryubing/Issues/issues/189
|
|
||||||
File.Copy(keysSource, dest, true);
|
File.Copy(keysSource, dest, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,7 +1058,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AreKeysAlredyPresent(string pathToCheck)
|
public static bool AreKeysAlreadyPresent(string pathToCheck)
|
||||||
{
|
{
|
||||||
string[] fileNames = ["prod.keys", "title.keys", "console.keys", "dev.keys"];
|
string[] fileNames = ["prod.keys", "title.keys", "console.keys", "dev.keys"];
|
||||||
foreach (string file in fileNames)
|
foreach (string file in fileNames)
|
||||||
|
|||||||
@@ -246,21 +246,21 @@ namespace Ryujinx.HLE.HOS
|
|||||||
public void InitializeServices()
|
public void InitializeServices()
|
||||||
{
|
{
|
||||||
SmRegistry = new SmRegistry();
|
SmRegistry = new SmRegistry();
|
||||||
SmServer = new ServerBase(KernelContext, "SmServer", () => new IUserInterface(KernelContext, SmRegistry));
|
SmServer = new ServerBase(KernelContext, "Sm", () => new IUserInterface(KernelContext, SmRegistry));
|
||||||
|
|
||||||
// Wait until SM server thread is done with initialization,
|
// Wait until SM server thread is done with initialization,
|
||||||
// only then doing connections to SM is safe.
|
// only then doing connections to SM is safe.
|
||||||
SmServer.InitDone.WaitOne();
|
SmServer.InitDone.WaitOne();
|
||||||
|
|
||||||
BsdServer = new ServerBase(KernelContext, "BsdServer");
|
BsdServer = new ServerBase(KernelContext, "Bsd");
|
||||||
FsServer = new ServerBase(KernelContext, "FsServer");
|
FsServer = new ServerBase(KernelContext, "Fs");
|
||||||
HidServer = new ServerBase(KernelContext, "HidServer");
|
HidServer = new ServerBase(KernelContext, "Hid");
|
||||||
NvDrvServer = new ServerBase(KernelContext, "NvservicesServer");
|
NvDrvServer = new ServerBase(KernelContext, "Nv");
|
||||||
TimeServer = new ServerBase(KernelContext, "TimeServer");
|
TimeServer = new ServerBase(KernelContext, "Time");
|
||||||
ViServer = new ServerBase(KernelContext, "ViServerU");
|
ViServer = new ServerBase(KernelContext, "Vi:u");
|
||||||
ViServerM = new ServerBase(KernelContext, "ViServerM");
|
ViServerM = new ServerBase(KernelContext, "Vi:m");
|
||||||
ViServerS = new ServerBase(KernelContext, "ViServerS");
|
ViServerS = new ServerBase(KernelContext, "Vi:s");
|
||||||
LdnServer = new ServerBase(KernelContext, "LdnServer");
|
LdnServer = new ServerBase(KernelContext, "Ldn");
|
||||||
|
|
||||||
StartNewServices();
|
StartNewServices();
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
ProcessCreationFlags.Is64Bit |
|
ProcessCreationFlags.Is64Bit |
|
||||||
ProcessCreationFlags.PoolPartitionSystem;
|
ProcessCreationFlags.PoolPartitionSystem;
|
||||||
|
|
||||||
ProcessCreationInfo creationInfo = new("Service", 1, 0, 0x8000000, 1, Flags, 0, 0);
|
ProcessCreationInfo creationInfo = new(service.Name, 1, 0, 0x8000000, 1, Flags, 0, 0);
|
||||||
|
|
||||||
uint[] defaultCapabilities =
|
uint[] defaultCapabilities =
|
||||||
[
|
[
|
||||||
@@ -570,6 +570,11 @@ namespace Ryujinx.HLE.HOS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DebugGetApplicationProcessMinidump()
|
||||||
|
{
|
||||||
|
return DebugGetApplicationProcess()?.Debugger?.GetMinidump();
|
||||||
|
}
|
||||||
|
|
||||||
internal KProcess DebugGetApplicationProcess()
|
internal KProcess DebugGetApplicationProcess()
|
||||||
{
|
{
|
||||||
lock (KernelContext.Processes)
|
lock (KernelContext.Processes)
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
_activeCount = 0;
|
_activeCount = 0;
|
||||||
|
|
||||||
JoyHold = NpadJoyHoldType.Vertical;
|
JoyHold = NpadJoyHoldType.Vertical;
|
||||||
|
SixAxisActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player)
|
internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player)
|
||||||
@@ -580,6 +581,29 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
|
|
||||||
return needUpdateRight;
|
return needUpdateRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isAtRest(int playerNumber)
|
||||||
|
{
|
||||||
|
ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[playerNumber].InternalState;
|
||||||
|
|
||||||
|
if (currentNpad.StyleSet == NpadStyleTag.None)
|
||||||
|
{
|
||||||
|
return true; // it will always be at rest because it cannot move.
|
||||||
|
}
|
||||||
|
|
||||||
|
ref SixAxisSensorState storage = ref GetSixAxisSensorLifo(ref currentNpad, false).GetCurrentEntryRef();
|
||||||
|
|
||||||
|
float acceleration = Math.Abs(storage.Acceleration.X)
|
||||||
|
+ Math.Abs(storage.Acceleration.Y)
|
||||||
|
+ Math.Abs(storage.Acceleration.Z);
|
||||||
|
|
||||||
|
float angularVelocity = Math.Abs(storage.AngularVelocity.X)
|
||||||
|
+ Math.Abs(storage.AngularVelocity.Y)
|
||||||
|
+ Math.Abs(storage.AngularVelocity.Z);
|
||||||
|
|
||||||
|
// TODO: check against config deadzone and add sensitivity setting
|
||||||
|
return ((acceleration <= 1.0F) && (angularVelocity <= 1.0F));
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateDisconnectedInputSixAxis(PlayerIndex index)
|
private void UpdateDisconnectedInputSixAxis(PlayerIndex index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -602,19 +602,33 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CommandCmif(82)]
|
[CommandCmif(82)]
|
||||||
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
|
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAtRest
|
||||||
public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
|
public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int sixAxisSensorHandle = context.RequestData.ReadInt32();
|
int sixAxisSensorHandle = context.RequestData.ReadInt32();
|
||||||
|
|
||||||
|
// 4 byte struct w/ 4-byte alignment
|
||||||
|
|
||||||
|
// uint typeValue = (uint) sixAxisSensorHandle; // 0x0 0x4 TypeValue
|
||||||
|
// uint npadStyleIndex = (uint) sixAxisSensorHandle & 0xff; // 0x0 0x1 NpadStyleIndex
|
||||||
|
int playerNumber = (sixAxisSensorHandle << 8) & 0xff; // 0x1 0x1 PlayerNumber
|
||||||
|
// uint deviceIdx= ((uint) sixAxisSensorHandle << 16) & 0xff; // 0x2 0x1 DeviceIdx
|
||||||
|
// uint unknown = ((uint) sixAxisSensorHandle << 24) & 0xff;
|
||||||
|
|
||||||
|
// 32bit sign extension padding -> if = 0, + offset, else - offset
|
||||||
|
|
||||||
|
// npadStyleIndex = ((npadStyleIndex & 0x8000) == 0) ? npadStyleIndex | 0xFFFF0000 : npadStyleIndex & 0xFFFF0000;
|
||||||
|
// playerNumber = ((playerNumber & 0x8000) == 0) ? playerNumber | 0xFFFF0000 : playerNumber & 0xFFFF0000;
|
||||||
|
// deviceIdx = ((deviceIdx & 0x8000) == 0) ? deviceIdx | 0xFFFF0000 : deviceIdx & 0xFFFF0000;
|
||||||
|
// unknown = ((unknown & 0x8000) == 0) ? unknown | 0xFFFF0000 : unknown & 0xFFFF0000;
|
||||||
|
|
||||||
context.RequestData.BaseStream.Position += 4; // Padding
|
context.RequestData.BaseStream.Position += 4; // Padding
|
||||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
bool isAtRest = true;
|
// TODO: link to context.Device.Hid.Npads.SixAxisActive when properly implemented
|
||||||
|
// We currently do not support stopping or starting SixAxisTracking.
|
||||||
context.ResponseData.Write(isAtRest);
|
|
||||||
|
context.ResponseData.Write(context.Device.Hid.Npads.isAtRest(playerNumber));
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,7 +643,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
|
context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
|
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,9 +79,15 @@ namespace Ryujinx.HLE.HOS.Services
|
|||||||
ProcessCreationFlags.Is64Bit |
|
ProcessCreationFlags.Is64Bit |
|
||||||
ProcessCreationFlags.PoolPartitionSystem;
|
ProcessCreationFlags.PoolPartitionSystem;
|
||||||
|
|
||||||
ProcessCreationInfo creationInfo = new("Service", 1, 0, 0x8000000, 1, Flags, 0, 0);
|
ProcessCreationInfo creationInfo = new(Name, 1, 0, 0x8000000, 1, Flags, 0, 0);
|
||||||
|
|
||||||
KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, Main);
|
KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, () =>
|
||||||
|
{
|
||||||
|
var currentThread = KernelStatic.GetCurrentThread();
|
||||||
|
currentThread.HostThread.Name = $"{{{Name}}}";
|
||||||
|
|
||||||
|
Main();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
|
private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
|
||||||
|
|||||||
@@ -17,13 +17,12 @@ namespace Ryujinx.HLE.HOS.Services.Sm
|
|||||||
private static readonly Dictionary<string, Type> _services;
|
private static readonly Dictionary<string, Type> _services;
|
||||||
|
|
||||||
private readonly SmRegistry _registry;
|
private readonly SmRegistry _registry;
|
||||||
private readonly ServerBase _commonServer;
|
private ServerBase _commonServer;
|
||||||
|
|
||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
|
|
||||||
public IUserInterface(KernelContext context, SmRegistry registry) : base(registerTipc: true)
|
public IUserInterface(KernelContext context, SmRegistry registry) : base(registerTipc: true)
|
||||||
{
|
{
|
||||||
_commonServer = new ServerBase(context, "CommonServer");
|
|
||||||
_registry = registry;
|
_registry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +96,11 @@ namespace Ryujinx.HLE.HOS.Services.Sm
|
|||||||
|
|
||||||
IpcService service = GetServiceInstance(type, context, serviceAttribute.Parameter);
|
IpcService service = GetServiceInstance(type, context, serviceAttribute.Parameter);
|
||||||
|
|
||||||
|
if (_commonServer is null)
|
||||||
|
{
|
||||||
|
_commonServer = new ServerBase(context.Device.System.KernelContext, "Common");
|
||||||
|
}
|
||||||
|
|
||||||
service.TrySetServer(_commonServer);
|
service.TrySetServer(_commonServer);
|
||||||
service.Server.AddSessionObj(session.ServerSession, service);
|
service.Server.AddSessionObj(session.ServerSession, service);
|
||||||
}
|
}
|
||||||
@@ -253,7 +257,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
|
|||||||
|
|
||||||
public override void DestroyAtExit()
|
public override void DestroyAtExit()
|
||||||
{
|
{
|
||||||
_commonServer.Dispose();
|
_commonServer?.Dispose();
|
||||||
|
|
||||||
base.DestroyAtExit();
|
base.DestroyAtExit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
public ISslService(ServiceCtx context) { }
|
public ISslService(ServiceCtx context) { }
|
||||||
|
|
||||||
[CommandCmif(0)]
|
[CommandCmif(0)]
|
||||||
// CreateContext(nn::ssl::sf::SslVersion, u64, pid) -> object<nn::ssl::sf::ISslContext>
|
// CreateContext(nn::ssl::sf::SslVersion, u64 pid_placeholder, pid) -> object<nn::ssl::sf::ISslContext>
|
||||||
public ResultCode CreateContext(ServiceCtx context)
|
public ResultCode CreateContext(ServiceCtx context)
|
||||||
{
|
{
|
||||||
SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32();
|
SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32();
|
||||||
@@ -126,14 +126,18 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CommandCmif(100)]
|
[CommandCmif(100)]
|
||||||
// CreateContextForSystem(u64 pid, nn::ssl::sf::SslVersion, u64)
|
// CreateContextForSystem(nn::ssl::sf::SslVersion, u64 pid_placeholder, pid) -> object<nn::ssl::sf::ISslContextForSystem>
|
||||||
public ResultCode CreateContextForSystem(ServiceCtx context)
|
public ResultCode CreateContextForSystem(ServiceCtx context)
|
||||||
{
|
{
|
||||||
ulong pid = context.RequestData.ReadUInt64();
|
|
||||||
SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32();
|
SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32();
|
||||||
|
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||||
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
||||||
|
#pragma warning restore IDE0059
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { pid, sslVersion, pidPlaceholder });
|
// Note: We use ISslContext here instead of ISslContextForSystem class because Ryujinx implements both in one class.
|
||||||
|
MakeObject(context, new ISslContext(context.Request.HandleDesc.PId, sslVersion));
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ namespace Ryujinx.Horizon
|
|||||||
private readonly Action<ServiceTable> _entrypoint;
|
private readonly Action<ServiceTable> _entrypoint;
|
||||||
private readonly ServiceTable _serviceTable;
|
private readonly ServiceTable _serviceTable;
|
||||||
private readonly HorizonOptions _options;
|
private readonly HorizonOptions _options;
|
||||||
|
public readonly string Name;
|
||||||
|
|
||||||
internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options)
|
internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options, string name)
|
||||||
{
|
{
|
||||||
_entrypoint = entrypoint;
|
_entrypoint = entrypoint;
|
||||||
_serviceTable = serviceTable;
|
_serviceTable = serviceTable;
|
||||||
_options = options;
|
_options = options;
|
||||||
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace Ryujinx.Horizon
|
|||||||
|
|
||||||
void RegisterService<T>() where T : IService
|
void RegisterService<T>() where T : IService
|
||||||
{
|
{
|
||||||
entries.Add(new ServiceEntry(T.Main, this, options));
|
entries.Add(new ServiceEntry(T.Main, this, options, typeof(T).Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterService<ArpMain>();
|
RegisterService<ArpMain>();
|
||||||
|
|||||||
@@ -386,6 +386,30 @@ namespace Ryujinx.Ava
|
|||||||
exceptions.Add(initialException);
|
exceptions.Add(initialException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isTerminating && HLE.Switch.Shared is { } device)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Print a short message first just in case it crashes again during minidump creation (should not happen)
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Unhandled exception caught: {initialException.GetType().Name}. Creating guest program minidump...");
|
||||||
|
|
||||||
|
var minidump = device.System?.DebugGetApplicationProcessMinidump();
|
||||||
|
|
||||||
|
if (minidump == null)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, "Failed to create minidump");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Info?.Print(LogClass.Application, minidump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Failed to create minidump: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Exception e in exceptions)
|
foreach (Exception e in exceptions)
|
||||||
{
|
{
|
||||||
string message = $"Unhandled exception caught: {e}";
|
string message = $"Unhandled exception caught: {e}";
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<PackageReference Include="Svg.Controls.Avalonia" />
|
<PackageReference Include="Svg.Controls.Avalonia" />
|
||||||
<PackageReference Include="Svg.Controls.Skia.Avalonia" />
|
<PackageReference Include="Svg.Controls.Skia.Avalonia" />
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="FluentAvaloniaUI.NoAnim" />
|
<PackageReference Include="FluentAvaloniaUI" />
|
||||||
<PackageReference Include="CommandLineParser" />
|
<PackageReference Include="CommandLineParser" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||||
<PackageReference Include="DiscordRichPresence" />
|
<PackageReference Include="DiscordRichPresence" />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Avalonia.Markup.Xaml;
|
|||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Windowing;
|
using FluentAvalonia.UI.Windowing;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
@@ -53,6 +54,9 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
Name = FormatTitle();
|
Name = FormatTitle();
|
||||||
|
|
||||||
|
// Disable menu animations
|
||||||
|
FAUISettings.SetAnimationsEnabledAtAppLevel(false);
|
||||||
|
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
private string _screenshotKey = "F8";
|
private string _screenshotKey = "F8";
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private ApplicationData _currentApplicationData;
|
private ApplicationData _currentApplicationData;
|
||||||
|
private bool _pendingRestart;
|
||||||
private readonly AutoResetEvent _rendererWaitEvent;
|
private readonly AutoResetEvent _rendererWaitEvent;
|
||||||
private int _customVSyncInterval;
|
private int _customVSyncInterval;
|
||||||
private int _customVSyncIntervalPercentageProxy;
|
private int _customVSyncIntervalPercentageProxy;
|
||||||
@@ -1062,7 +1063,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
string dialogMessage =
|
string dialogMessage =
|
||||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage);
|
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage);
|
||||||
|
|
||||||
if (ContentManager.AreKeysAlredyPresent(systemDirectory))
|
if (ContentManager.AreKeysAlreadyPresent(systemDirectory))
|
||||||
{
|
{
|
||||||
dialogMessage +=
|
dialogMessage +=
|
||||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys
|
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys
|
||||||
@@ -1250,6 +1251,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
await LoadApplication(_currentApplicationData);
|
await LoadApplication(_currentApplicationData);
|
||||||
}
|
}
|
||||||
|
else if (_pendingRestart)
|
||||||
|
{
|
||||||
|
_pendingRestart = false;
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"Restarting emulation for '{_currentApplicationData.Name}'");
|
||||||
|
|
||||||
|
await LoadApplication(_currentApplicationData);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise, clear state.
|
// Otherwise, clear state.
|
||||||
@@ -1258,6 +1267,21 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RestartEmulation()
|
||||||
|
{
|
||||||
|
if (AppHost is null || _currentApplicationData is null)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Application, "RestartEmulation called but no application is running.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"Restart requested for '{_currentApplicationData.Name}'");
|
||||||
|
|
||||||
|
_pendingRestart = true;
|
||||||
|
AppHost.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
private void Update_StatusBar(object sender, StatusUpdatedEventArgs args)
|
private void Update_StatusBar(object sender, StatusUpdatedEventArgs args)
|
||||||
{
|
{
|
||||||
if (ShowMenuAndStatusBar && !ShowLoadProgress)
|
if (ShowMenuAndStatusBar && !ShowLoadProgress)
|
||||||
|
|||||||
@@ -47,18 +47,13 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal" IsEnabled="{Binding ShowLedColorPicker}">
|
<StackPanel Orientation="Horizontal" IsEnabled="{Binding ShowLedColorPicker}">
|
||||||
<TextBlock MinWidth="75" MaxWidth="200" Text="{ext:Locale ControllerSettingsLedColor}" />
|
<TextBlock MinWidth="75" MaxWidth="200" Text="{ext:Locale ControllerSettingsLedColor}" />
|
||||||
<ui:ColorPickerButton
|
<ColorPicker
|
||||||
Margin="5"
|
Margin="5"
|
||||||
IsMoreButtonVisible="False"
|
|
||||||
UseColorPalette="False"
|
|
||||||
UseColorTriangle="False"
|
|
||||||
UseColorWheel="False"
|
|
||||||
ShowAcceptDismissButtons="False"
|
|
||||||
IsAlphaEnabled="False"
|
IsAlphaEnabled="False"
|
||||||
AttachedToVisualTree="ColorPickerButton_OnAttachedToVisualTree"
|
AttachedToVisualTree="ColorPicker_OnAttachedToVisualTree"
|
||||||
ColorChanged="ColorPickerButton_OnColorChanged"
|
ColorChanged="ColorPicker_OnColorChanged"
|
||||||
Color="{Binding LedColor, Mode=TwoWay}">
|
Color="{Binding LedColor, Mode=TwoWay}">
|
||||||
</ui:ColorPickerButton>
|
</ColorPicker>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
@@ -30,19 +31,17 @@ namespace Ryujinx.UI.Views.Input
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args)
|
private void ColorPicker_OnColorChanged(object sender, ColorChangedEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.NewColor.HasValue)
|
|
||||||
return;
|
|
||||||
if (!ViewModel.EnableLedChanging)
|
if (!ViewModel.EnableLedChanging)
|
||||||
return;
|
return;
|
||||||
if (ViewModel.TurnOffLed)
|
if (ViewModel.TurnOffLed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewModel.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32());
|
ViewModel.ParentModel.SelectedGamepad.SetLed(args.NewColor.ToUInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
|
private void ColorPicker_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
|
||||||
{
|
{
|
||||||
if (!ViewModel.EnableLedChanging)
|
if (!ViewModel.EnableLedChanging)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -167,6 +167,12 @@
|
|||||||
Icon="{ext:Icon fa-solid fa-stop}"
|
Icon="{ext:Icon fa-solid fa-stop}"
|
||||||
InputGesture="Escape"
|
InputGesture="Escape"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
|
<MenuItem
|
||||||
|
Name="RestartEmulationMenuItem"
|
||||||
|
Header="{ext:Locale MenuBarOptionsRestartEmulation}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-rotate-right}"
|
||||||
|
InputGesture="Ctrl + R"
|
||||||
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" Icon="{ext:Icon fa-solid fa-sun}" />
|
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" Icon="{ext:Icon fa-solid fa-sun}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
PauseEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Pause());
|
PauseEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Pause());
|
||||||
ResumeEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Resume());
|
ResumeEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.Resume());
|
||||||
StopEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
StopEmulationMenuItem.Command = Commands.Create(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
||||||
|
RestartEmulationMenuItem.Command = Commands.Create(() => ViewModel.RestartEmulation());
|
||||||
CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp);
|
CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp);
|
||||||
InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes);
|
InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes);
|
||||||
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
|
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
|
||||||
|
|||||||
@@ -78,22 +78,16 @@
|
|||||||
Spacing="10"
|
Spacing="10"
|
||||||
Margin="0 24 0 0"
|
Margin="0 24 0 0"
|
||||||
HorizontalAlignment="Right">
|
HorizontalAlignment="Right">
|
||||||
<ui:ColorPickerButton
|
<ColorPicker
|
||||||
FlyoutPlacement="Top"
|
|
||||||
IsMoreButtonVisible="False"
|
|
||||||
UseColorPalette="False"
|
|
||||||
UseColorTriangle="False"
|
|
||||||
UseColorWheel="False"
|
|
||||||
ShowAcceptDismissButtons="False"
|
|
||||||
IsAlphaEnabled="False"
|
IsAlphaEnabled="False"
|
||||||
Color="{Binding BackgroundColor, Mode=TwoWay}"
|
Color="{Binding BackgroundColor, Mode=TwoWay}"
|
||||||
Name="ColorButton">
|
Name="ColorButton">
|
||||||
<ui:ColorPickerButton.Styles>
|
<ColorPicker.Styles>
|
||||||
<Style Selector="Grid#Root > DockPanel > Grid">
|
<Style Selector="Grid#Root > DockPanel > Grid">
|
||||||
<Setter Property="IsVisible" Value="False" />
|
<Setter Property="IsVisible" Value="False" />
|
||||||
</Style>
|
</Style>
|
||||||
</ui:ColorPickerButton.Styles>
|
</ColorPicker.Styles>
|
||||||
</ui:ColorPickerButton>
|
</ColorPicker>
|
||||||
<Button
|
<Button
|
||||||
Content="{ext:Locale AvatarChoose}"
|
Content="{ext:Locale AvatarChoose}"
|
||||||
Height="35"
|
Height="35"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
||||||
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
||||||
<KeyBinding Gesture="Ctrl+B" Command="{Binding OpenBinFile}" />
|
<KeyBinding Gesture="Ctrl+B" Command="{Binding OpenBinFile}" />
|
||||||
|
<KeyBinding Gesture="Ctrl+R" Command="{Binding RestartEmulation}" />
|
||||||
<KeyBinding Gesture="Ctrl+Shift+R" Command="{Binding ReloadRenderDocApi}" />
|
<KeyBinding Gesture="Ctrl+Shift+R" Command="{Binding ReloadRenderDocApi}" />
|
||||||
<KeyBinding Gesture="Ctrl+Shift+C" Command="{Binding ToggleCapture}" />
|
<KeyBinding Gesture="Ctrl+Shift+C" Command="{Binding ToggleCapture}" />
|
||||||
</Window.KeyBindings>
|
</Window.KeyBindings>
|
||||||
|
|||||||
Reference in New Issue
Block a user