Avalonia UI - Part 1 (#3270)

* avalonia part 1

* remove vulkan ui backend

* move ui common files to ui common project

* get name for oading screen from device

* rebase.

* review 1

* review 1.1

* review

* cleanup

* addressed review

* use cancellation token

* review

* review

* rebased

* cancel library loading when closing window

* remove star  image, use fonticon instead

* delete render control frame buffer when game ends. change position of fav star

* addressed @Thog review

* ensure the right ui is downloaded in updates

* fix crash when showing not supported dialog during controller request

* add prefix to artifact names

* Auto-format Avalonia project

* Fix input

* Fix build, simplify app disposal

* remove nv stutter thread

* addressed review

* add missing change

* maintain window size if new size is zero length

* add game, handheld, docked to local

* reverse scale main window

* Update de_DE.json

* Update de_DE.json

* Update de_DE.json

* Update italian json

* Update it_IT.json

* let render timer poll with no wait

* remove unused code

* more unused code

* enabled tiered compilation and trimming

* check if window event is not closed before signaling

* fix atmospher case

* locale fix

* locale fix

* remove explicit tiered compilation declarations

* Remove ) it_IT.json

* Remove ) de_DE.json

* Update it_IT.json

* Update pt_BR locale with latest strings

* Remove ')'

* add more strings to locale

* update locale

* remove extra slash

* remove extra slash

* set firmware version to 0 if key's not found

* fix

* revert timer changes

* lock  on object instead

* Update it_IT.json

* remove unused method

* add load screen text to locale

* drop swap event

* Update de_DE.json

* Update de_DE.json

* do null check when stopping emulator

* Update de_DE.json

* Create tr_TR.json

* Add tr_TR

* Add tr_TR + Turkish

* Update it_IT.json

* Update Ryujinx.Ava/Input/AvaloniaMappingHelper.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* addressed review

* Update Ryujinx.Ava/Ui/Backend/OpenGl/OpenGlRenderTarget.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* use avalonia's inbuilt renderer on linux

* removed whitespace

* workaround for queue render crash with vsync off

* drop custom backend

* format files

* fix not closing issue

* remove warnings

* rebase

* update avalonia library

* Reposition the Text and Button on About Page

* Assign build version

* Remove appveyor text

Co-authored-by: gdk <gab.dark.100@gmail.com>
Co-authored-by: Niwu34 <67392333+Niwu34@users.noreply.github.com>
Co-authored-by: Antonio Brugnolo <36473846+AntoSkate@users.noreply.github.com>
Co-authored-by: aegiff <99728970+aegiff@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
Co-authored-by: MostlyWhat <78652091+MostlyWhat@users.noreply.github.com>
This commit is contained in:
Emmanuel Hansen 2022-05-15 11:30:15 +00:00 committed by GitHub
parent be60578bc9
commit 9a257d1cc3
161 changed files with 17179 additions and 855 deletions

View file

@ -1,9 +0,0 @@
using System;
namespace Ryujinx.Ui.App
{
public class ApplicationAddedEventArgs : EventArgs
{
public ApplicationData AppData { get; set; }
}
}

View file

@ -1,10 +0,0 @@
using System;
namespace Ryujinx.Ui.App
{
public class ApplicationCountUpdatedEventArgs : EventArgs
{
public int NumAppsFound { get; set; }
public int NumAppsLoaded { get; set; }
}
}

View file

@ -1,21 +0,0 @@
using LibHac.Common;
using LibHac.Ns;
namespace Ryujinx.Ui.App
{
public class ApplicationData
{
public bool Favorite { get; set; }
public byte[] Icon { get; set; }
public string TitleName { get; set; }
public string TitleId { get; set; }
public string Developer { get; set; }
public string Version { get; set; }
public string TimePlayed { get; set; }
public string LastPlayed { get; set; }
public string FileExtension { get; set; }
public string FileSize { get; set; }
public string Path { get; set; }
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
}
}

View file

@ -1,648 +0,0 @@
using LibHac;
using LibHac.Common;
using LibHac.Common.Keys;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ns;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration.System;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Npdm;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.Json;
using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
using Path = System.IO.Path;
namespace Ryujinx.Ui.App
{
public class ApplicationLibrary
{
public event EventHandler<ApplicationAddedEventArgs> ApplicationAdded;
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
private readonly byte[] _nspIcon;
private readonly byte[] _xciIcon;
private readonly byte[] _ncaIcon;
private readonly byte[] _nroIcon;
private readonly byte[] _nsoIcon;
private VirtualFileSystem _virtualFileSystem;
private Language _desiredTitleLanguage;
public ApplicationLibrary(VirtualFileSystem virtualFileSystem)
{
_virtualFileSystem = virtualFileSystem;
_nspIcon = GetResourceBytes("Ryujinx.Ui.Resources.Icon_NSP.png");
_xciIcon = GetResourceBytes("Ryujinx.Ui.Resources.Icon_XCI.png");
_ncaIcon = GetResourceBytes("Ryujinx.Ui.Resources.Icon_NCA.png");
_nroIcon = GetResourceBytes("Ryujinx.Ui.Resources.Icon_NRO.png");
_nsoIcon = GetResourceBytes("Ryujinx.Ui.Resources.Icon_NSO.png");
}
private byte[] GetResourceBytes(string resourceName)
{
Stream resourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream(resourceName);
byte[] resourceByteArray = new byte[resourceStream.Length];
resourceStream.Read(resourceByteArray);
return resourceByteArray;
}
public IEnumerable<string> GetFilesInDirectory(string directory)
{
Stack<string> stack = new Stack<string>();
stack.Push(directory);
while (stack.Count > 0)
{
string dir = stack.Pop();
string[] content = Array.Empty<string>();
try
{
content = Directory.GetFiles(dir, "*");
}
catch (UnauthorizedAccessException)
{
Logger.Warning?.Print(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
}
if (content.Length > 0)
{
foreach (string file in content)
{
yield return file;
}
}
try
{
content = Directory.GetDirectories(dir);
}
catch (UnauthorizedAccessException)
{
Logger.Warning?.Print(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
}
if (content.Length > 0)
{
foreach (string subdir in content)
{
stack.Push(subdir);
}
}
}
}
public void ReadControlData(IFileSystem controlFs, Span<byte> outProperty)
{
using var controlFile = new UniqueRef<IFile>();
controlFs.OpenFile(ref controlFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
controlFile.Get.Read(out _, 0, outProperty, ReadOption.None).ThrowIfFailure();
}
public void LoadApplications(List<string> appDirs, Language desiredTitleLanguage)
{
int numApplicationsFound = 0;
int numApplicationsLoaded = 0;
_desiredTitleLanguage = desiredTitleLanguage;
// Builds the applications list with paths to found applications
List<string> applications = new List<string>();
foreach (string appDir in appDirs)
{
if (!Directory.Exists(appDir))
{
Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\"");
continue;
}
foreach (string app in GetFilesInDirectory(appDir))
{
if ((Path.GetExtension(app).ToLower() == ".nsp") ||
(Path.GetExtension(app).ToLower() == ".pfs0") ||
(Path.GetExtension(app).ToLower() == ".xci") ||
(Path.GetExtension(app).ToLower() == ".nca") ||
(Path.GetExtension(app).ToLower() == ".nro") ||
(Path.GetExtension(app).ToLower() == ".nso"))
{
applications.Add(app);
numApplicationsFound++;
}
}
}
// Loops through applications list, creating a struct and then firing an event containing the struct for each application
foreach (string applicationPath in applications)
{
double fileSize = new FileInfo(applicationPath).Length * 0.000000000931;
string titleName = "Unknown";
string titleId = "0000000000000000";
string developer = "Unknown";
string version = "0";
byte[] applicationIcon = null;
BlitStruct<ApplicationControlProperty> controlHolder = new BlitStruct<ApplicationControlProperty>(1);
try
{
using (FileStream file = new FileStream(applicationPath, FileMode.Open, FileAccess.Read))
{
if ((Path.GetExtension(applicationPath).ToLower() == ".nsp") ||
(Path.GetExtension(applicationPath).ToLower() == ".pfs0") ||
(Path.GetExtension(applicationPath).ToLower() == ".xci"))
{
try
{
PartitionFileSystem pfs;
bool isExeFs = false;
if (Path.GetExtension(applicationPath).ToLower() == ".xci")
{
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
pfs = xci.OpenPartition(XciPartitionType.Secure);
}
else
{
pfs = new PartitionFileSystem(file.AsStorage());
// If the NSP doesn't have a main NCA, decrement the number of applications found and then continue to the next application.
bool hasMainNca = false;
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*"))
{
if (Path.GetExtension(fileEntry.FullPath).ToLower() == ".nca")
{
using var ncaFile = new UniqueRef<IFile>();
pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
// Some main NCAs don't have a data partition, so check if the partition exists before opening it
if (nca.Header.ContentType == NcaContentType.Program && !(nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection()))
{
hasMainNca = true;
break;
}
}
else if (Path.GetFileNameWithoutExtension(fileEntry.FullPath) == "main")
{
isExeFs = true;
}
}
if (!hasMainNca && !isExeFs)
{
numApplicationsFound--;
continue;
}
}
if (isExeFs)
{
applicationIcon = _nspIcon;
using var npdmFile = new UniqueRef<IFile>();
Result result = pfs.OpenFile(ref npdmFile.Ref(), "/main.npdm".ToU8Span(), OpenMode.Read);
if (ResultFs.PathNotFound.Includes(result))
{
Npdm npdm = new Npdm(npdmFile.Get.AsStream());
titleName = npdm.TitleName;
titleId = npdm.Aci0.TitleId.ToString("x16");
}
}
else
{
GetControlFsAndTitleId(pfs, out IFileSystem controlFs, out titleId);
// Check if there is an update available.
if (IsUpdateApplied(titleId, out IFileSystem updatedControlFs))
{
// Replace the original ControlFs by the updated one.
controlFs = updatedControlFs;
}
ReadControlData(controlFs, controlHolder.ByteSpan);
GetGameInformation(ref controlHolder.Value, out titleName, out _, out developer, out version);
// Read the icon from the ControlFS and store it as a byte array
try
{
using var icon = new UniqueRef<IFile>();
controlFs.OpenFile(ref icon.Ref(), $"/icon_{_desiredTitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();
using (MemoryStream stream = new MemoryStream())
{
icon.Get.AsStream().CopyTo(stream);
applicationIcon = stream.ToArray();
}
}
catch (HorizonResultException)
{
foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
{
if (entry.Name == "control.nacp")
{
continue;
}
using var icon = new UniqueRef<IFile>();
controlFs.OpenFile(ref icon.Ref(), entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
using (MemoryStream stream = new MemoryStream())
{
icon.Get.AsStream().CopyTo(stream);
applicationIcon = stream.ToArray();
}
if (applicationIcon != null)
{
break;
}
}
if (applicationIcon == null)
{
applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
}
}
}
}
catch (MissingKeyException exception)
{
applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
}
catch (InvalidDataException)
{
applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {applicationPath}");
}
catch (Exception exception)
{
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. File: '{applicationPath}' Error: {exception}");
numApplicationsFound--;
continue;
}
}
else if (Path.GetExtension(applicationPath).ToLower() == ".nro")
{
BinaryReader reader = new BinaryReader(file);
byte[] Read(long position, int size)
{
file.Seek(position, SeekOrigin.Begin);
return reader.ReadBytes(size);
}
try
{
file.Seek(24, SeekOrigin.Begin);
int assetOffset = reader.ReadInt32();
if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
{
byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
ulong nacpOffset = reader.ReadUInt64();
ulong nacpSize = reader.ReadUInt64();
// Reads and stores game icon as byte array
applicationIcon = Read(assetOffset + iconOffset, (int) iconSize);
// Read the NACP data
Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
GetGameInformation(ref controlHolder.Value, out titleName, out titleId, out developer, out version);
}
else
{
applicationIcon = _nroIcon;
titleName = Path.GetFileNameWithoutExtension(applicationPath);
}
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
numApplicationsFound--;
continue;
}
}
else if (Path.GetExtension(applicationPath).ToLower() == ".nca")
{
try
{
Nca nca = new Nca(_virtualFileSystem.KeySet, new FileStream(applicationPath, FileMode.Open, FileAccess.Read).AsStorage());
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.ContentType != NcaContentType.Program || (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection()))
{
numApplicationsFound--;
continue;
}
}
catch (InvalidDataException)
{
Logger.Warning?.Print(LogClass.Application, $"The NCA header content type check has failed. This is usually because the header key is incorrect or missing. Errored File: {applicationPath}");
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
numApplicationsFound--;
continue;
}
applicationIcon = _ncaIcon;
titleName = Path.GetFileNameWithoutExtension(applicationPath);
}
// If its an NSO we just set defaults
else if (Path.GetExtension(applicationPath).ToLower() == ".nso")
{
applicationIcon = _nsoIcon;
titleName = Path.GetFileNameWithoutExtension(applicationPath);
}
}
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, exception.Message);
numApplicationsFound--;
continue;
}
ApplicationMetadata appMetadata = LoadAndSaveMetaData(titleId);
if (appMetadata.LastPlayed != "Never" && !DateTime.TryParse(appMetadata.LastPlayed, out _))
{
Logger.Warning?.Print(LogClass.Application, $"Last played datetime \"{appMetadata.LastPlayed}\" is invalid for current system culture, skipping (did current culture change?)");
appMetadata.LastPlayed = "Never";
}
ApplicationData data = new ApplicationData
{
Favorite = appMetadata.Favorite,
Icon = applicationIcon,
TitleName = titleName,
TitleId = titleId,
Developer = developer,
Version = version,
TimePlayed = ConvertSecondsToReadableString(appMetadata.TimePlayed),
LastPlayed = appMetadata.LastPlayed,
FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0, 1),
FileSize = (fileSize < 1) ? (fileSize * 1024).ToString("0.##") + "MB" : fileSize.ToString("0.##") + "GB",
Path = applicationPath,
ControlHolder = controlHolder
};
numApplicationsLoaded++;
OnApplicationAdded(new ApplicationAddedEventArgs()
{
AppData = data
});
OnApplicationCountUpdated(new ApplicationCountUpdatedEventArgs()
{
NumAppsFound = numApplicationsFound,
NumAppsLoaded = numApplicationsLoaded
});
}
OnApplicationCountUpdated(new ApplicationCountUpdatedEventArgs()
{
NumAppsFound = numApplicationsFound,
NumAppsLoaded = numApplicationsLoaded
});
}
protected void OnApplicationAdded(ApplicationAddedEventArgs e)
{
ApplicationAdded?.Invoke(null, e);
}
protected void OnApplicationCountUpdated(ApplicationCountUpdatedEventArgs e)
{
ApplicationCountUpdated?.Invoke(null, e);
}
private void GetControlFsAndTitleId(PartitionFileSystem pfs, out IFileSystem controlFs, out string titleId)
{
(_, _, Nca controlNca) = ApplicationLoader.GetGameData(_virtualFileSystem, pfs, 0);
// Return the ControlFS
controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
titleId = controlNca?.Header.TitleId.ToString("x16");
}
internal ApplicationMetadata LoadAndSaveMetaData(string titleId, Action<ApplicationMetadata> modifyFunction = null)
{
string metadataFolder = Path.Combine(AppDataManager.GamesDirPath, titleId, "gui");
string metadataFile = Path.Combine(metadataFolder, "metadata.json");
ApplicationMetadata appMetadata;
if (!File.Exists(metadataFile))
{
Directory.CreateDirectory(metadataFolder);
appMetadata = new ApplicationMetadata();
using (FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough))
{
JsonHelper.Serialize(stream, appMetadata, true);
}
}
try
{
appMetadata = JsonHelper.DeserializeFromFile<ApplicationMetadata>(metadataFile);
}
catch (JsonException)
{
Logger.Warning?.Print(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
appMetadata = new ApplicationMetadata();
}
if (modifyFunction != null)
{
modifyFunction(appMetadata);
using (FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough))
{
JsonHelper.Serialize(stream, appMetadata, true);
}
}
return appMetadata;
}
private string ConvertSecondsToReadableString(double seconds)
{
const int secondsPerMinute = 60;
const int secondsPerHour = secondsPerMinute * 60;
const int secondsPerDay = secondsPerHour * 24;
string readableString;
if (seconds < secondsPerMinute)
{
readableString = $"{seconds}s";
}
else if (seconds < secondsPerHour)
{
readableString = $"{Math.Round(seconds / secondsPerMinute, 2, MidpointRounding.AwayFromZero)} mins";
}
else if (seconds < secondsPerDay)
{
readableString = $"{Math.Round(seconds / secondsPerHour, 2, MidpointRounding.AwayFromZero)} hrs";
}
else
{
readableString = $"{Math.Round(seconds / secondsPerDay, 2, MidpointRounding.AwayFromZero)} days";
}
return readableString;
}
private void GetGameInformation(ref ApplicationControlProperty controlData, out string titleName, out string titleId, out string publisher, out string version)
{
_ = Enum.TryParse(_desiredTitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage);
if (controlData.Title.ItemsRo.Length > (int)desiredTitleLanguage)
{
titleName = controlData.Title[(int)desiredTitleLanguage].NameString.ToString();
publisher = controlData.Title[(int)desiredTitleLanguage].PublisherString.ToString();
}
else
{
titleName = null;
publisher = null;
}
if (string.IsNullOrWhiteSpace(titleName))
{
foreach (ref readonly var controlTitle in controlData.Title.ItemsRo)
{
if (!controlTitle.NameString.IsEmpty())
{
titleName = controlTitle.NameString.ToString();
break;
}
}
}
if (string.IsNullOrWhiteSpace(publisher))
{
foreach (ref readonly var controlTitle in controlData.Title.ItemsRo)
{
if (!controlTitle.PublisherString.IsEmpty())
{
publisher = controlTitle.PublisherString.ToString();
break;
}
}
}
if (controlData.PresenceGroupId != 0)
{
titleId = controlData.PresenceGroupId.ToString("x16");
}
else if (controlData.SaveDataOwnerId != 0)
{
titleId = controlData.SaveDataOwnerId.ToString();
}
else if (controlData.AddOnContentBaseId != 0)
{
titleId = (controlData.AddOnContentBaseId - 0x1000).ToString("x16");
}
else
{
titleId = "0000000000000000";
}
version = controlData.DisplayVersionString.ToString();
}
private bool IsUpdateApplied(string titleId, out IFileSystem updatedControlFs)
{
updatedControlFs = null;
string updatePath = "(unknown)";
try
{
(Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateData(_virtualFileSystem, titleId, 0, out updatePath);
if (patchNca != null && controlNca != null)
{
updatedControlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
return true;
}
}
catch (InvalidDataException)
{
Logger.Warning?.Print(LogClass.Application,
$"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {updatePath}");
}
catch (MissingKeyException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {updatePath}");
}
return false;
}
}
}

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Ui.App
{
public class ApplicationMetadata
{
public bool Favorite { get; set; }
public double TimePlayed { get; set; }
public string LastPlayed { get; set; } = "Never";
}
}

View file

@ -1,4 +1,5 @@
using Gtk;
using Ryujinx.Ui.Common.Configuration;
using System.Reflection;
namespace Ryujinx.Ui.Applet
@ -7,7 +8,7 @@ namespace Ryujinx.Ui.Applet
{
public ErrorAppletDialog(Window parentWindow, DialogFlags dialogFlags, MessageType messageType, string[] buttons) : base(parentWindow, dialogFlags, messageType, ButtonsType.None, null)
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
int responseId = 0;

View file

@ -52,7 +52,7 @@ namespace Ryujinx.Ui.Applet
[GLib.ConnectBefore()]
private void HandleKeyPressEvent(object o, KeyPressEventArgs args)
{
var key = (Common.Configuration.Hid.Key)GTK3MappingHelper.ToInputKey(args.Event.Key);
var key = (Ryujinx.Common.Configuration.Hid.Key)GTK3MappingHelper.ToInputKey(args.Event.Key);
if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true))
{
@ -70,7 +70,7 @@ namespace Ryujinx.Ui.Applet
[GLib.ConnectBefore()]
private void HandleKeyReleaseEvent(object o, KeyReleaseEventArgs args)
{
var key = (Common.Configuration.Hid.Key)GTK3MappingHelper.ToInputKey(args.Event.Key);
var key = (Ryujinx.Common.Configuration.Hid.Key)GTK3MappingHelper.ToInputKey(args.Event.Key);
if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true))
{

View file

@ -99,11 +99,31 @@ namespace Ryujinx.Ui
GL.ClearColor(0, 0, 0, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
SwapBuffers();
SwapBuffers(0);
}
public override void SwapBuffers()
public override void SwapBuffers(object image)
{
if((int)image != 0)
{
// The game's framebruffer is already bound, so blit it to the window's backbuffer
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.ClearColor(0, 0, 0, 1);
GL.BlitFramebuffer(0,
0,
AllocatedWidth,
AllocatedHeight,
0,
0,
AllocatedWidth,
AllocatedHeight,
ClearBufferMask.ColorBufferBit,
BlitFramebufferFilter.Linear);
}
_nativeWindow.SwapBuffers();
}

View file

@ -1,49 +0,0 @@
using Ryujinx.Common.Logging;
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Ryujinx.Ui.Helper
{
public static class ConsoleHelper
{
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
public static void SetConsoleWindowState(bool show)
{
if (OperatingSystem.IsWindows())
{
SetConsoleWindowStateWindows(show);
}
else if (show == false)
{
Logger.Warning?.Print(LogClass.Application, "OS doesn't support hiding console window");
}
}
[SupportedOSPlatform("windows")]
private static void SetConsoleWindowStateWindows(bool show)
{
const int SW_HIDE = 0;
const int SW_SHOW = 5;
IntPtr hWnd = GetConsoleWindow();
if (hWnd == IntPtr.Zero)
{
Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist");
return;
}
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
}
[SupportedOSPlatform("windows")]
[DllImport("kernel32")]
static extern IntPtr GetConsoleWindow();
[SupportedOSPlatform("windows")]
[DllImport("user32")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
}

View file

@ -1,39 +0,0 @@
using Ryujinx.Common.Logging;
using System;
using System.Diagnostics;
namespace Ryujinx.Ui.Helper
{
static class OpenHelper
{
public static void OpenFolder(string path)
{
Process.Start(new ProcessStartInfo
{
FileName = path,
UseShellExecute = true,
Verb = "open"
});
}
public static void OpenUrl(string url)
{
if (OperatingSystem.IsWindows())
{
Process.Start(new ProcessStartInfo("cmd", $"/c start {url.Replace("&", "^&")}"));
}
else if (OperatingSystem.IsLinux())
{
Process.Start("xdg-open", url);
}
else if (OperatingSystem.IsMacOS())
{
Process.Start("open", url);
}
else
{
Logger.Notice.Print(LogClass.Application, $"Cannot open url \"{url}\" on this platform!");
}
}
}
}

View file

@ -1,119 +0,0 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.Widgets;
using System;
using System.IO;
namespace Ryujinx.Ui.Helper
{
/// <summary>
/// Ensure installation validity
/// </summary>
static class SetupValidator
{
public static bool IsFirmwareValid(ContentManager contentManager, out UserError error)
{
bool hasFirmware = contentManager.GetCurrentFirmwareVersion() != null;
if (hasFirmware)
{
error = UserError.Success;
return true;
}
else
{
error = UserError.NoFirmware;
return false;
}
}
public static bool CanFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out SystemVersion firmwareVersion)
{
try
{
firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath);
}
catch (Exception)
{
firmwareVersion = null;
}
return error == UserError.NoFirmware && Path.GetExtension(baseApplicationPath).ToLowerInvariant() == ".xci" && firmwareVersion != null;
}
public static bool TryFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out UserError outError)
{
if (error == UserError.NoFirmware)
{
string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant();
// If the target app to start is a XCI, try to install firmware from it
if (baseApplicationExtension == ".xci")
{
SystemVersion firmwareVersion;
try
{
firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath);
}
catch (Exception)
{
firmwareVersion = null;
}
// The XCI is a valid firmware package, try to install the firmware from it!
if (firmwareVersion != null)
{
try
{
Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
contentManager.InstallFirmware(baseApplicationPath);
Logger.Info?.Print(LogClass.Application, $"System version {firmwareVersion.VersionString} successfully installed.");
outError = UserError.Success;
return true;
}
catch (Exception) { }
}
outError = error;
return false;
}
}
outError = error;
return false;
}
public static bool CanStartApplication(ContentManager contentManager, string baseApplicationPath, out UserError error)
{
if (Directory.Exists(baseApplicationPath) || File.Exists(baseApplicationPath))
{
string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant();
// NOTE: We don't force homebrew developers to install a system firmware.
if (baseApplicationExtension == ".nro" || baseApplicationExtension == ".nso")
{
error = UserError.Success;
return true;
}
return IsFirmwareValid(contentManager, out error);
}
else
{
error = UserError.ApplicationNotFound;
return false;
}
}
}
}

View file

@ -1,6 +1,6 @@
using Gtk;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration;
using Ryujinx.Ui.Common.Configuration;
using System.IO;
namespace Ryujinx.Ui.Helper

View file

@ -16,7 +16,6 @@ using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.System;
using Ryujinx.Configuration;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.OpenGL;
@ -29,7 +28,11 @@ using Ryujinx.Input.HLE;
using Ryujinx.Input.SDL2;
using Ryujinx.Modules;
using Ryujinx.Ui.App;
using Ryujinx.Ui.App.Common;
using Ryujinx.Ui.Applet;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper;
using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Widgets;
using Ryujinx.Ui.Windows;
@ -152,7 +155,7 @@ namespace Ryujinx.Ui
DefaultWidth = monitorWidth < 1280 ? monitorWidth : 1280;
DefaultHeight = monitorHeight < 760 ? monitorHeight : 760;
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
Title = $"Ryujinx {Program.Version}";
// Hide emulation context status bar.

View file

@ -5,7 +5,7 @@ using Gtk;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Input;
@ -117,7 +117,7 @@ namespace Ryujinx.Ui
public abstract void InitializeRenderer();
public abstract void SwapBuffers();
public abstract void SwapBuffers(object image);
public abstract string GetGpuVendorName();
@ -416,7 +416,7 @@ namespace Ryujinx.Ui
while (Device.ConsumeFrameAvailable())
{
Device.PresentFrame(SwapBuffers);
Device.PresentFrame((texture) => { SwapBuffers(texture);});
}
if (_ticks >= _ticksPerFrame)

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 66 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 81 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -64,7 +64,7 @@ namespace Ryujinx.Ui
public override void InitializeRenderer() { }
public override void SwapBuffers() { }
public override void SwapBuffers(object image) { }
public override string GetGpuVendorName()
{

View file

@ -15,6 +15,8 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper;
using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Windows;
using System;
@ -184,7 +186,7 @@ namespace Ryujinx.Ui.Widgets
_dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Cancel, null)
{
Title = "Ryujinx - NCA Section Extractor",
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png"),
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"),
SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(_titleFilePath)}...",
WindowPosition = WindowPosition.Center
};
@ -306,7 +308,7 @@ namespace Ryujinx.Ui.Widgets
MessageDialog dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null)
{
Title = "Ryujinx - NCA Section Extractor",
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png"),
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"),
SecondaryText = "Extraction completed successfully.",
WindowPosition = WindowPosition.Center
};

View file

@ -1,7 +1,8 @@
using Gtk;
using System.Reflection;
using Ryujinx.Common.Logging;
using Ryujinx.Ui.Common.Configuration;
using System.Collections.Generic;
using System.Reflection;
namespace Ryujinx.Ui.Widgets
{
@ -13,7 +14,7 @@ namespace Ryujinx.Ui.Widgets
: base(null, DialogFlags.Modal, messageType, buttonsType, null)
{
Title = title;
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
Text = mainText;
SecondaryText = secondaryText;
WindowPosition = WindowPosition.Center;

View file

@ -1,6 +1,7 @@
using Gtk;
using System;
using System.Reflection;
using Ryujinx.Ui.Common.Configuration;
using GUI = Gtk.Builder.ObjectAttribute;
@ -20,7 +21,7 @@ namespace Ryujinx.Ui.Widgets
private ProfileDialog(Builder builder) : base(builder.GetObject("_profileDialog").Handle)
{
builder.Autoconnect(this);
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
}
private void OkToggle_Activated(object sender, EventArgs args)

View file

@ -1,39 +0,0 @@
namespace Ryujinx.Ui.Widgets
{
/// <summary>
/// Represent a common error that could be reported to the user by the emulator.
/// </summary>
public enum UserError
{
/// <summary>
/// No error to report.
/// </summary>
Success = 0x0,
/// <summary>
/// No keys are present.
/// </summary>
NoKeys = 0x1,
/// <summary>
/// No firmware is installed.
/// </summary>
NoFirmware = 0x2,
/// <summary>
/// Firmware parsing failed.
/// </summary>
/// <remarks>Most likely related to keys.</remarks>
FirmwareParsingFailed = 0x3,
/// <summary>
/// No application was found at the given path.
/// </summary>
ApplicationNotFound = 0x4,
/// <summary>
/// An unknown error.
/// </summary>
Unknown = 0xDEAD
}
}

View file

@ -1,4 +1,6 @@
using Gtk;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Helper;
using Ryujinx.Ui.Helper;
namespace Ryujinx.Ui.Widgets

View file

@ -1,5 +1,6 @@
using Gtk;
using Pango;
using Ryujinx.Ui.Common.Configuration;
using System.Reflection;
namespace Ryujinx.Ui.Windows
@ -87,7 +88,7 @@ namespace Ryujinx.Ui.Windows
//
// _ryujinxLogo
//
_ryujinxLogo = new Image(new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png", 100, 100))
_ryujinxLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png", 100, 100))
{
Margin = 10,
MarginLeft = 15
@ -205,7 +206,7 @@ namespace Ryujinx.Ui.Windows
//
// _patreonLogo
//
_patreonLogo = new Image(new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Patreon.png", 30, 30))
_patreonLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Patreon.png", 30, 30))
{
Margin = 10
};
@ -235,7 +236,7 @@ namespace Ryujinx.Ui.Windows
//
// _githubLogo
//
_githubLogo = new Image(new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_GitHub.png", 30, 30))
_githubLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_GitHub.png", 30, 30))
{
Margin = 10
};
@ -265,7 +266,7 @@ namespace Ryujinx.Ui.Windows
//
// _discordLogo
//
_discordLogo = new Image(new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Discord.png", 30, 30))
_discordLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Discord.png", 30, 30))
{
Margin = 10
};
@ -295,7 +296,7 @@ namespace Ryujinx.Ui.Windows
//
// _twitterLogo
//
_twitterLogo = new Image(new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Twitter.png", 30, 30))
_twitterLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Twitter.png", 30, 30))
{
Margin = 10
};

View file

@ -1,6 +1,6 @@
using Gtk;
using Ryujinx.Common.Utilities;
using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Common.Helper;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Reflection;
@ -12,7 +12,7 @@ namespace Ryujinx.Ui.Windows
{
public AboutWindow() : base($"Ryujinx {Program.Version} - About")
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(OpenHelper)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
InitializeComponent();
_ = DownloadPatronsJson();

View file

@ -2,6 +2,7 @@
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Utilities;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Widgets;
using System;
using System.Collections.Generic;
@ -97,7 +98,7 @@ namespace Ryujinx.Ui.Windows
public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo")
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
InitializeComponent();

View file

@ -7,6 +7,7 @@ using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.Common.Configuration;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
@ -35,7 +36,7 @@ namespace Ryujinx.Ui.Windows
public AvatarWindow() : base($"Ryujinx {Program.Version} - Manage Accounts - Avatar")
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
CanFocus = false;
Resizable = false;

View file

@ -4,7 +4,7 @@ using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Utilities;
using Ryujinx.Configuration;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Input;
using Ryujinx.Input.GTK3;
using Ryujinx.Ui.Widgets;
@ -127,7 +127,7 @@ namespace Ryujinx.Ui.Windows
// NOTE: To get input in this window, we need to bind a custom keyboard driver instead of using the InputManager one as the main window isn't focused...
_gtk3KeyboardDriver = new GTK3KeyboardDriver(this);
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
builder.Autoconnect(this);
@ -381,10 +381,10 @@ namespace Ryujinx.Ui.Windows
_controllerImage.Pixbuf = _controllerType.ActiveId switch
{
"ProController" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_ProCon.svg", 400, 400),
"JoyconLeft" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConLeft.svg", 400, 500),
"JoyconRight" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConRight.svg", 400, 500),
_ => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConPair.svg", 400, 500),
"ProController" => new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Controller_ProCon.svg", 400, 400),
"JoyconLeft" => new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Controller_JoyConLeft.svg", 400, 500),
"JoyconRight" => new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Controller_JoyConRight.svg", 400, 500),
_ => new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Controller_JoyConPair.svg", 400, 500),
};
}

View file

@ -6,8 +6,7 @@ using Ryujinx.Audio.Backends.SoundIo;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Configuration;
using Ryujinx.Configuration.System;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
using Ryujinx.Ui.Helper;
@ -20,6 +19,7 @@ using System.Reflection;
using System.Threading.Tasks;
using GUI = Gtk.Builder.ObjectAttribute;
using Ryujinx.Ui.Common.Configuration.System;
namespace Ryujinx.Ui.Windows
{
@ -109,7 +109,7 @@ namespace Ryujinx.Ui.Windows
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
_parent = parent;
@ -519,7 +519,7 @@ namespace Ryujinx.Ui.Windows
ConfigurationState.Instance.Hid.EnableMouse.Value = _directMouseAccess.Active;
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
ConfigurationState.Instance.System.Language.Value = Enum.Parse<Language>(_systemLanguageSelect.ActiveId);
ConfigurationState.Instance.System.Region.Value = Enum.Parse<Configuration.System.Region>(_systemRegionSelect.ActiveId);
ConfigurationState.Instance.System.Region.Value = Enum.Parse<Common.Configuration.System.Region>(_systemRegionSelect.ActiveId);
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;

View file

@ -1,6 +1,7 @@
using Gtk;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Widgets;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
@ -10,7 +11,6 @@ using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Image = SixLabors.ImageSharp.Image;
using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Windows
public UserProfilesManagerWindow(AccountManager accountManager, ContentManager contentManager, VirtualFileSystem virtualFileSystem) : base($"Ryujinx {Program.Version} - Manage User Profiles")
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
InitializeComponent();