Revert "Adjust naming conventions and general refactoring in HLE Project (#490)" (#526)

This reverts commit 85dbb9559a.
This commit is contained in:
gdkchan 2018-12-04 22:52:39 -02:00 committed by GitHub
parent 85dbb9559a
commit 3615a70cae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
299 changed files with 12276 additions and 12268 deletions

View file

@ -7,109 +7,109 @@ namespace Ryujinx.HLE
{ {
public const long RamSize = 4L * 1024 * 1024 * 1024; public const long RamSize = 4L * 1024 * 1024 * 1024;
public IntPtr RamPointer { get; } public IntPtr RamPointer { get; private set; }
private unsafe byte* _ramPtr; private unsafe byte* RamPtr;
public unsafe DeviceMemory() public unsafe DeviceMemory()
{ {
RamPointer = Marshal.AllocHGlobal(new IntPtr(RamSize)); RamPointer = Marshal.AllocHGlobal(new IntPtr(RamSize));
_ramPtr = (byte*)RamPointer; RamPtr = (byte*)RamPointer;
} }
public sbyte ReadSByte(long position) public sbyte ReadSByte(long Position)
{ {
return (sbyte)ReadByte(position); return (sbyte)ReadByte(Position);
} }
public short ReadInt16(long position) public short ReadInt16(long Position)
{ {
return (short)ReadUInt16(position); return (short)ReadUInt16(Position);
} }
public int ReadInt32(long position) public int ReadInt32(long Position)
{ {
return (int)ReadUInt32(position); return (int)ReadUInt32(Position);
} }
public long ReadInt64(long position) public long ReadInt64(long Position)
{ {
return (long)ReadUInt64(position); return (long)ReadUInt64(Position);
} }
public unsafe byte ReadByte(long position) public unsafe byte ReadByte(long Position)
{ {
return *(_ramPtr + position); return *((byte*)(RamPtr + Position));
} }
public unsafe ushort ReadUInt16(long position) public unsafe ushort ReadUInt16(long Position)
{ {
return *((ushort*)(_ramPtr + position)); return *((ushort*)(RamPtr + Position));
} }
public unsafe uint ReadUInt32(long position) public unsafe uint ReadUInt32(long Position)
{ {
return *((uint*)(_ramPtr + position)); return *((uint*)(RamPtr + Position));
} }
public unsafe ulong ReadUInt64(long position) public unsafe ulong ReadUInt64(long Position)
{ {
return *((ulong*)(_ramPtr + position)); return *((ulong*)(RamPtr + Position));
} }
public void WriteSByte(long position, sbyte value) public void WriteSByte(long Position, sbyte Value)
{ {
WriteByte(position, (byte)value); WriteByte(Position, (byte)Value);
} }
public void WriteInt16(long position, short value) public void WriteInt16(long Position, short Value)
{ {
WriteUInt16(position, (ushort)value); WriteUInt16(Position, (ushort)Value);
} }
public void WriteInt32(long position, int value) public void WriteInt32(long Position, int Value)
{ {
WriteUInt32(position, (uint)value); WriteUInt32(Position, (uint)Value);
} }
public void WriteInt64(long position, long value) public void WriteInt64(long Position, long Value)
{ {
WriteUInt64(position, (ulong)value); WriteUInt64(Position, (ulong)Value);
} }
public unsafe void WriteByte(long position, byte value) public unsafe void WriteByte(long Position, byte Value)
{ {
*(_ramPtr + position) = value; *((byte*)(RamPtr + Position)) = Value;
} }
public unsafe void WriteUInt16(long position, ushort value) public unsafe void WriteUInt16(long Position, ushort Value)
{ {
*((ushort*)(_ramPtr + position)) = value; *((ushort*)(RamPtr + Position)) = Value;
} }
public unsafe void WriteUInt32(long position, uint value) public unsafe void WriteUInt32(long Position, uint Value)
{ {
*((uint*)(_ramPtr + position)) = value; *((uint*)(RamPtr + Position)) = Value;
} }
public unsafe void WriteUInt64(long position, ulong value) public unsafe void WriteUInt64(long Position, ulong Value)
{ {
*((ulong*)(_ramPtr + position)) = value; *((ulong*)(RamPtr + Position)) = Value;
} }
public void FillWithZeros(long position, int size) public void FillWithZeros(long Position, int Size)
{ {
int size8 = size & ~(8 - 1); int Size8 = Size & ~(8 - 1);
for (int offs = 0; offs < size8; offs += 8) for (int Offs = 0; Offs < Size8; Offs += 8)
{ {
WriteInt64(position + offs, 0); WriteInt64(Position + Offs, 0);
} }
for (int offs = size8; offs < (size - size8); offs++) for (int Offs = Size8; Offs < (Size - Size8); Offs++)
{ {
WriteByte(position + offs, 0); WriteByte(Position + Offs, 0);
} }
} }
@ -118,7 +118,7 @@ namespace Ryujinx.HLE
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool Disposing)
{ {
Marshal.FreeHGlobal(RamPointer); Marshal.FreeHGlobal(RamPointer);
} }

View file

@ -4,6 +4,6 @@ namespace Ryujinx.HLE.Exceptions
{ {
public class InvalidNpdmException : Exception public class InvalidNpdmException : Exception
{ {
public InvalidNpdmException(string message) : base(message) { } public InvalidNpdmException(string ExMsg) : base(ExMsg) { }
} }
} }

View file

@ -8,6 +8,6 @@ namespace Ryujinx.HLE.Exceptions
public UndefinedInstructionException() : base() { } public UndefinedInstructionException() : base() { }
public UndefinedInstructionException(long position, int opCode) : base(string.Format(ExMsg, position, opCode)) { } public UndefinedInstructionException(long Position, int OpCode) : base(string.Format(ExMsg, Position, OpCode)) { }
} }
} }

View file

@ -9,297 +9,297 @@ namespace Ryujinx.HLE.FileSystem.Content
{ {
internal class ContentManager internal class ContentManager
{ {
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries; private Dictionary<StorageId, LinkedList<LocationEntry>> LocationEntries;
private Dictionary<string, long> _sharedFontTitleDictionary; private Dictionary<string, long> SharedFontTitleDictionary;
private SortedDictionary<(ulong, ContentType), string> _contentDictionary; private SortedDictionary<(ulong, ContentType), string> ContentDictionary;
private Switch _device; private Switch Device;
public ContentManager(Switch device) public ContentManager(Switch Device)
{ {
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>(); ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); LocationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_sharedFontTitleDictionary = new Dictionary<string, long> SharedFontTitleDictionary = new Dictionary<string, long>()
{ {
{ "FontStandard", 0x0100000000000811 }, { "FontStandard", 0x0100000000000811 },
{ "FontChineseSimplified", 0x0100000000000814 }, { "FontChineseSimplified", 0x0100000000000814 },
{ "FontExtendedChineseSimplified", 0x0100000000000814 }, { "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 }, { "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 }, { "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended", 0x0100000000000810 } { "FontNintendoExtended" , 0x0100000000000810 },
}; };
_device = device; this.Device = Device;
} }
public void LoadEntries() public void LoadEntries()
{ {
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>(); ContentDictionary = new SortedDictionary<(ulong, ContentType), string>();
foreach (StorageId storageId in Enum.GetValues(typeof(StorageId))) foreach (StorageId StorageId in Enum.GetValues(typeof(StorageId)))
{ {
string contentDirectory = null; string ContentDirectory = null;
string contentPathString = null; string ContentPathString = null;
string registeredDirectory = null; string RegisteredDirectory = null;
try try
{ {
contentPathString = LocationHelper.GetContentRoot(storageId); ContentPathString = LocationHelper.GetContentRoot(StorageId);
contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString); ContentDirectory = LocationHelper.GetRealPath(Device.FileSystem, ContentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered"); RegisteredDirectory = Path.Combine(ContentDirectory, "registered");
} }
catch (NotSupportedException) catch (NotSupportedException NEx)
{ {
continue; continue;
} }
Directory.CreateDirectory(registeredDirectory); Directory.CreateDirectory(RegisteredDirectory);
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>(); LinkedList<LocationEntry> LocationList = new LinkedList<LocationEntry>();
void AddEntry(LocationEntry entry) void AddEntry(LocationEntry Entry)
{ {
locationList.AddLast(entry); LocationList.AddLast(Entry);
} }
foreach (string directoryPath in Directory.EnumerateDirectories(registeredDirectory)) foreach (string DirectoryPath in Directory.EnumerateDirectories(RegisteredDirectory))
{ {
if (Directory.GetFiles(directoryPath).Length > 0) if (Directory.GetFiles(DirectoryPath).Length > 0)
{ {
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); string NcaName = new DirectoryInfo(DirectoryPath).Name.Replace(".nca", string.Empty);
using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read)) using (FileStream NcaFile = new FileStream(Directory.GetFiles(DirectoryPath)[0], FileMode.Open, FileAccess.Read))
{ {
Nca nca = new Nca(_device.System.KeySet, ncaFile, false); Nca Nca = new Nca(Device.System.KeySet, NcaFile, false);
string switchPath = Path.Combine(contentPathString + ":", string SwitchPath = Path.Combine(ContentPathString + ":",
ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart('\\')); NcaFile.Name.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); SwitchPath = SwitchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry Entry = new LocationEntry(SwitchPath,
0, 0,
(long)nca.Header.TitleId, (long)Nca.Header.TitleId,
nca.Header.ContentType); Nca.Header.ContentType);
AddEntry(entry); AddEntry(Entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
ncaFile.Close(); NcaFile.Close();
nca.Dispose(); Nca.Dispose();
ncaFile.Dispose(); NcaFile.Dispose();
} }
} }
} }
foreach (string filePath in Directory.EnumerateFiles(contentDirectory)) foreach (string FilePath in Directory.EnumerateFiles(ContentDirectory))
{ {
if (Path.GetExtension(filePath) == ".nca") if (Path.GetExtension(FilePath) == ".nca")
{ {
string ncaName = Path.GetFileNameWithoutExtension(filePath); string NcaName = Path.GetFileNameWithoutExtension(FilePath);
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using (FileStream NcaFile = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
{ {
Nca nca = new Nca(_device.System.KeySet, ncaFile, false); Nca Nca = new Nca(Device.System.KeySet, NcaFile, false);
string switchPath = Path.Combine(contentPathString + ":", string SwitchPath = Path.Combine(ContentPathString + ":",
filePath.Replace(contentDirectory, string.Empty).TrimStart('\\')); FilePath.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); SwitchPath = SwitchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry Entry = new LocationEntry(SwitchPath,
0, 0,
(long)nca.Header.TitleId, (long)Nca.Header.TitleId,
nca.Header.ContentType); Nca.Header.ContentType);
AddEntry(entry); AddEntry(Entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); ContentDictionary.Add((Nca.Header.TitleId, Nca.Header.ContentType), NcaName);
ncaFile.Close(); NcaFile.Close();
nca.Dispose(); Nca.Dispose();
ncaFile.Dispose(); NcaFile.Dispose();
} }
} }
} }
if(_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0) if(LocationEntries.ContainsKey(StorageId) && LocationEntries[StorageId]?.Count == 0)
{ {
_locationEntries.Remove(storageId); LocationEntries.Remove(StorageId);
} }
if (!_locationEntries.ContainsKey(storageId)) if (!LocationEntries.ContainsKey(StorageId))
{ {
_locationEntries.Add(storageId, locationList); LocationEntries.Add(StorageId, LocationList);
} }
} }
} }
public void ClearEntry(long titleId, ContentType contentType,StorageId storageId) public void ClearEntry(long TitleId, ContentType ContentType,StorageId StorageId)
{ {
RemoveLocationEntry(titleId, contentType, storageId); RemoveLocationEntry(TitleId, ContentType, StorageId);
} }
public void RefreshEntries(StorageId storageId, int flag) public void RefreshEntries(StorageId StorageId, int Flag)
{ {
LinkedList<LocationEntry> locationList = _locationEntries[storageId]; LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
LinkedListNode<LocationEntry> locationEntry = locationList.First; LinkedListNode<LocationEntry> LocationEntry = LocationList.First;
while (locationEntry != null) while (LocationEntry != null)
{ {
LinkedListNode<LocationEntry> nextLocationEntry = locationEntry.Next; LinkedListNode<LocationEntry> NextLocationEntry = LocationEntry.Next;
if (locationEntry.Value.Flag == flag) if (LocationEntry.Value.Flag == Flag)
{ {
locationList.Remove(locationEntry.Value); LocationList.Remove(LocationEntry.Value);
} }
locationEntry = nextLocationEntry; LocationEntry = NextLocationEntry;
} }
} }
public bool HasNca(string ncaId, StorageId storageId) public bool HasNca(string NcaId, StorageId StorageId)
{ {
if (_contentDictionary.ContainsValue(ncaId)) if (ContentDictionary.ContainsValue(NcaId))
{ {
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); var Content = ContentDictionary.FirstOrDefault(x => x.Value == NcaId);
long titleId = (long)content.Key.Item1; long TitleId = (long)Content.Key.Item1;
ContentType contentType = content.Key.Item2; ContentType ContentType = Content.Key.Item2;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId); StorageId Storage = GetInstalledStorage(TitleId, ContentType, StorageId);
return storage == storageId; return Storage == StorageId;
} }
return false; return false;
} }
public UInt128 GetInstalledNcaId(long titleId, ContentType contentType) public UInt128 GetInstalledNcaId(long TitleId, ContentType ContentType)
{ {
if (_contentDictionary.ContainsKey(((ulong)titleId,contentType))) if (ContentDictionary.ContainsKey(((ulong)TitleId,ContentType)))
{ {
return new UInt128(_contentDictionary[((ulong)titleId,contentType)]); return new UInt128(ContentDictionary[((ulong)TitleId,ContentType)]);
} }
return new UInt128(); return new UInt128();
} }
public StorageId GetInstalledStorage(long titleId, ContentType contentType, StorageId storageId) public StorageId GetInstalledStorage(long TitleId, ContentType ContentType, StorageId StorageId)
{ {
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
return locationEntry.ContentPath != null ? return LocationEntry.ContentPath != null ?
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None; LocationHelper.GetStorageId(LocationEntry.ContentPath) : StorageId.None;
} }
public string GetInstalledContentPath(long titleId, StorageId storageId, ContentType contentType) public string GetInstalledContentPath(long TitleId, StorageId StorageId, ContentType ContentType)
{ {
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); LocationEntry LocationEntry = GetLocation(TitleId, ContentType, StorageId);
if (VerifyContentType(locationEntry, contentType)) if (VerifyContentType(LocationEntry, ContentType))
{ {
return locationEntry.ContentPath; return LocationEntry.ContentPath;
} }
return string.Empty; return string.Empty;
} }
public void RedirectLocation(LocationEntry newEntry, StorageId storageId) public void RedirectLocation(LocationEntry NewEntry, StorageId StorageId)
{ {
LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId); LocationEntry LocationEntry = GetLocation(NewEntry.TitleId, NewEntry.ContentType, StorageId);
if (locationEntry.ContentPath != null) if (LocationEntry.ContentPath != null)
{ {
RemoveLocationEntry(newEntry.TitleId, newEntry.ContentType, storageId); RemoveLocationEntry(NewEntry.TitleId, NewEntry.ContentType, StorageId);
} }
AddLocationEntry(newEntry, storageId); AddLocationEntry(NewEntry, StorageId);
} }
private bool VerifyContentType(LocationEntry locationEntry, ContentType contentType) private bool VerifyContentType(LocationEntry LocationEntry, ContentType ContentType)
{ {
if (locationEntry.ContentPath == null) if (LocationEntry.ContentPath == null)
{ {
return false; return false;
} }
StorageId storageId = LocationHelper.GetStorageId(locationEntry.ContentPath); StorageId StorageId = LocationHelper.GetStorageId(LocationEntry.ContentPath);
string installedPath = _device.FileSystem.SwitchPathToSystemPath(locationEntry.ContentPath); string InstalledPath = Device.FileSystem.SwitchPathToSystemPath(LocationEntry.ContentPath);
if (!string.IsNullOrWhiteSpace(installedPath)) if (!string.IsNullOrWhiteSpace(InstalledPath))
{ {
if (File.Exists(installedPath)) if (File.Exists(InstalledPath))
{ {
FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read); FileStream File = new FileStream(InstalledPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, file, false); Nca Nca = new Nca(Device.System.KeySet, File, false);
bool contentCheck = nca.Header.ContentType == contentType; bool ContentCheck = Nca.Header.ContentType == ContentType;
nca.Dispose(); Nca.Dispose();
file.Dispose(); File.Dispose();
return contentCheck; return ContentCheck;
} }
} }
return false; return false;
} }
private void AddLocationEntry(LocationEntry entry, StorageId storageId) private void AddLocationEntry(LocationEntry Entry, StorageId StorageId)
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> LocationList = null;
if (_locationEntries.ContainsKey(storageId)) if (LocationEntries.ContainsKey(StorageId))
{ {
locationList = _locationEntries[storageId]; LocationList = LocationEntries[StorageId];
} }
if (locationList != null) if (LocationList != null)
{ {
if (locationList.Contains(entry)) if (LocationList.Contains(Entry))
{ {
locationList.Remove(entry); LocationList.Remove(Entry);
} }
locationList.AddLast(entry); LocationList.AddLast(Entry);
} }
} }
private void RemoveLocationEntry(long titleId, ContentType contentType, StorageId storageId) private void RemoveLocationEntry(long TitleId, ContentType ContentType, StorageId StorageId)
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> LocationList = null;
if (_locationEntries.ContainsKey(storageId)) if (LocationEntries.ContainsKey(StorageId))
{ {
locationList = _locationEntries[storageId]; LocationList = LocationEntries[StorageId];
} }
if (locationList != null) if (LocationList != null)
{ {
LocationEntry entry = LocationEntry Entry =
locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType); LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
if (entry.ContentPath != null) if (Entry.ContentPath != null)
{ {
locationList.Remove(entry); LocationList.Remove(Entry);
} }
} }
} }
public bool TryGetFontTitle(string fontName, out long titleId) public bool TryGetFontTitle(string FontName, out long TitleId)
{ {
return _sharedFontTitleDictionary.TryGetValue(fontName, out titleId); return SharedFontTitleDictionary.TryGetValue(FontName, out TitleId);
} }
private LocationEntry GetLocation(long titleId, ContentType contentType,StorageId storageId) private LocationEntry GetLocation(long TitleId, ContentType ContentType,StorageId StorageId)
{ {
LinkedList<LocationEntry> locationList = _locationEntries[storageId]; LinkedList<LocationEntry> LocationList = LocationEntries[StorageId];
return locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType); return LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
} }
} }
} }

View file

@ -1,25 +1,28 @@
using LibHac; using System;
using System.Collections.Generic;
using System.Text;
using LibHac;
namespace Ryujinx.HLE.FileSystem.Content namespace Ryujinx.HLE.FileSystem.Content
{ {
public struct LocationEntry public struct LocationEntry
{ {
public string ContentPath { get; } public string ContentPath { get; private set; }
public int Flag { get; private set; } public int Flag { get; private set; }
public long TitleId { get; } public long TitleId { get; private set; }
public ContentType ContentType { get; } public ContentType ContentType { get; private set; }
public LocationEntry(string contentPath, int flag, long titleId, ContentType contentType) public LocationEntry(string ContentPath, int Flag, long TitleId, ContentType ContentType)
{ {
ContentPath = contentPath; this.ContentPath = ContentPath;
Flag = flag; this.Flag = Flag;
TitleId = titleId; this.TitleId = TitleId;
ContentType = contentType; this.ContentType = ContentType;
} }
public void SetFlag(int flag) public void SetFlag(int Flag)
{ {
Flag = flag; this.Flag = Flag;
} }
} }
} }

View file

@ -7,30 +7,30 @@ namespace Ryujinx.HLE.FileSystem.Content
{ {
internal static class LocationHelper internal static class LocationHelper
{ {
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath) public static string GetRealPath(VirtualFileSystem FileSystem, string SwitchContentPath)
{ {
string basePath = fileSystem.GetBasePath(); string BasePath = FileSystem.GetBasePath();
switch (switchContentPath) switch (SwitchContentPath)
{ {
case ContentPath.SystemContent: case ContentPath.SystemContent:
return Path.Combine(fileSystem.GetBasePath(), SystemNandPath, "Contents"); return Path.Combine(FileSystem.GetBasePath(), SystemNandPath, "Contents");
case ContentPath.UserContent: case ContentPath.UserContent:
return Path.Combine(fileSystem.GetBasePath(), UserNandPath, "Contents"); return Path.Combine(FileSystem.GetBasePath(), UserNandPath, "Contents");
case ContentPath.SdCardContent: case ContentPath.SdCardContent:
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents"); return Path.Combine(FileSystem.GetSdCardPath(), "Nintendo", "Contents");
case ContentPath.System: case ContentPath.System:
return Path.Combine(basePath, SystemNandPath); return Path.Combine(BasePath, SystemNandPath);
case ContentPath.User: case ContentPath.User:
return Path.Combine(basePath, UserNandPath); return Path.Combine(BasePath, UserNandPath);
default: default:
throw new NotSupportedException($"Content Path `{switchContentPath}` is not supported."); throw new NotSupportedException($"Content Path `{SwitchContentPath}` is not supported.");
} }
} }
public static string GetContentPath(ContentStorageId contentStorageId) public static string GetContentPath(ContentStorageId ContentStorageId)
{ {
switch (contentStorageId) switch (ContentStorageId)
{ {
case ContentStorageId.NandSystem: case ContentStorageId.NandSystem:
return ContentPath.SystemContent; return ContentPath.SystemContent;
@ -39,13 +39,13 @@ namespace Ryujinx.HLE.FileSystem.Content
case ContentStorageId.SdCard: case ContentStorageId.SdCard:
return ContentPath.SdCardContent; return ContentPath.SdCardContent;
default: default:
throw new NotSupportedException($"Content Storage `{contentStorageId}` is not supported."); throw new NotSupportedException($"Content Storage `{ContentStorageId}` is not supported.");
} }
} }
public static string GetContentRoot(StorageId storageId) public static string GetContentRoot(StorageId StorageId)
{ {
switch (storageId) switch (StorageId)
{ {
case StorageId.NandSystem: case StorageId.NandSystem:
return ContentPath.SystemContent; return ContentPath.SystemContent;
@ -54,15 +54,15 @@ namespace Ryujinx.HLE.FileSystem.Content
case StorageId.SdCard: case StorageId.SdCard:
return ContentPath.SdCardContent; return ContentPath.SdCardContent;
default: default:
throw new NotSupportedException($"Storage Id `{storageId}` is not supported."); throw new NotSupportedException($"Storage Id `{StorageId}` is not supported.");
} }
} }
public static StorageId GetStorageId(string contentPathString) public static StorageId GetStorageId(string ContentPathString)
{ {
string cleanedPath = contentPathString.Split(':')[0]; string CleanedPath = ContentPathString.Split(':')[0];
switch (cleanedPath) switch (CleanedPath)
{ {
case ContentPath.SystemContent: case ContentPath.SystemContent:
case ContentPath.System: case ContentPath.System:

View file

@ -10,228 +10,228 @@ namespace Ryujinx.HLE.FileSystem
{ {
class FileSystemProvider : IFileSystemProvider class FileSystemProvider : IFileSystemProvider
{ {
private readonly string _basePath; private readonly string BasePath;
private readonly string _rootPath; private readonly string RootPath;
public FileSystemProvider(string basePath, string rootPath) public FileSystemProvider(string BasePath, string RootPath)
{ {
_basePath = basePath; this.BasePath = BasePath;
_rootPath = rootPath; this.RootPath = RootPath;
CheckIfDescendentOfRootPath(basePath); CheckIfDescendentOfRootPath(BasePath);
} }
public long CreateDirectory(string name) public long CreateDirectory(string Name)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
if (Directory.Exists(name)) if (Directory.Exists(Name))
{ {
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
} }
Directory.CreateDirectory(name); Directory.CreateDirectory(Name);
return 0; return 0;
} }
public long CreateFile(string name, long size) public long CreateFile(string Name, long Size)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
if (File.Exists(name)) if (File.Exists(Name))
{ {
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
} }
using (FileStream newFile = File.Create(name)) using (FileStream NewFile = File.Create(Name))
{ {
newFile.SetLength(size); NewFile.SetLength(Size);
} }
return 0; return 0;
} }
public long DeleteDirectory(string name, bool recursive) public long DeleteDirectory(string Name, bool Recursive)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
string dirName = name; string DirName = Name;
if (!Directory.Exists(dirName)) if (!Directory.Exists(DirName))
{ {
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
Directory.Delete(dirName, recursive); Directory.Delete(DirName, Recursive);
return 0; return 0;
} }
public long DeleteFile(string name) public long DeleteFile(string Name)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
if (!File.Exists(name)) if (!File.Exists(Name))
{ {
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
else else
{ {
File.Delete(name); File.Delete(Name);
} }
return 0; return 0;
} }
public DirectoryEntry[] GetDirectories(string path) public DirectoryEntry[] GetDirectories(string Path)
{ {
CheckIfDescendentOfRootPath(path); CheckIfDescendentOfRootPath(Path);
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach(string directory in Directory.EnumerateDirectories(path)) foreach(string Directory in Directory.EnumerateDirectories(Path))
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory); DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
return entries.ToArray(); return Entries.ToArray();
} }
public DirectoryEntry[] GetEntries(string path) public DirectoryEntry[] GetEntries(string Path)
{ {
CheckIfDescendentOfRootPath(path); CheckIfDescendentOfRootPath(Path);
if (Directory.Exists(path)) if (Directory.Exists(Path))
{ {
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach (string directory in Directory.EnumerateDirectories(path)) foreach (string Directory in Directory.EnumerateDirectories(Path))
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(directory, DirectoryEntryType.Directory); DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory, DirectoryEntryType.Directory);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
foreach (string file in Directory.EnumerateFiles(path)) foreach (string File in Directory.EnumerateFiles(Path))
{ {
FileInfo fileInfo = new FileInfo(file); FileInfo FileInfo = new FileInfo(File);
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length); DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
} }
return null; return null;
} }
public DirectoryEntry[] GetFiles(string path) public DirectoryEntry[] GetFiles(string Path)
{ {
CheckIfDescendentOfRootPath(path); CheckIfDescendentOfRootPath(Path);
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach (string file in Directory.EnumerateFiles(path)) foreach (string File in Directory.EnumerateFiles(Path))
{ {
FileInfo fileInfo = new FileInfo(file); FileInfo FileInfo = new FileInfo(File);
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length); DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
return entries.ToArray(); return Entries.ToArray();
} }
public long GetFreeSpace(ServiceCtx context) public long GetFreeSpace(ServiceCtx Context)
{ {
return context.Device.FileSystem.GetDrive().AvailableFreeSpace; return Context.Device.FileSystem.GetDrive().AvailableFreeSpace;
} }
public string GetFullPath(string name) public string GetFullPath(string Name)
{ {
if (name.StartsWith("//")) if (Name.StartsWith("//"))
{ {
name = name.Substring(2); Name = Name.Substring(2);
} }
else if (name.StartsWith('/')) else if (Name.StartsWith('/'))
{ {
name = name.Substring(1); Name = Name.Substring(1);
} }
else else
{ {
return null; return null;
} }
string fullPath = Path.Combine(_basePath, name); string FullPath = Path.Combine(BasePath, Name);
CheckIfDescendentOfRootPath(fullPath); CheckIfDescendentOfRootPath(FullPath);
return fullPath; return FullPath;
} }
public long GetTotalSpace(ServiceCtx context) public long GetTotalSpace(ServiceCtx Context)
{ {
return context.Device.FileSystem.GetDrive().TotalSize; return Context.Device.FileSystem.GetDrive().TotalSize;
} }
public bool DirectoryExists(string name) public bool DirectoryExists(string Name)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
return Directory.Exists(name); return Directory.Exists(Name);
} }
public bool FileExists(string name) public bool FileExists(string Name)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
return File.Exists(name); return File.Exists(Name);
} }
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface) public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
if (Directory.Exists(name)) if (Directory.Exists(Name))
{ {
directoryInterface = new IDirectory(name, filterFlags, this); DirectoryInterface = new IDirectory(Name, FilterFlags, this);
return 0; return 0;
} }
directoryInterface = null; DirectoryInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
public long OpenFile(string name, out IFile fileInterface) public long OpenFile(string Name, out IFile FileInterface)
{ {
CheckIfDescendentOfRootPath(name); CheckIfDescendentOfRootPath(Name);
if (File.Exists(name)) if (File.Exists(Name))
{ {
FileStream stream = new FileStream(name, FileMode.Open); FileStream Stream = new FileStream(Name, FileMode.Open);
fileInterface = new IFile(stream, name); FileInterface = new IFile(Stream, Name);
return 0; return 0;
} }
fileInterface = null; FileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
public long RenameDirectory(string oldName, string newName) public long RenameDirectory(string OldName, string NewName)
{ {
CheckIfDescendentOfRootPath(oldName); CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(newName); CheckIfDescendentOfRootPath(NewName);
if (Directory.Exists(oldName)) if (Directory.Exists(OldName))
{ {
Directory.Move(oldName, newName); Directory.Move(OldName, NewName);
} }
else else
{ {
@ -241,14 +241,14 @@ namespace Ryujinx.HLE.FileSystem
return 0; return 0;
} }
public long RenameFile(string oldName, string newName) public long RenameFile(string OldName, string NewName)
{ {
CheckIfDescendentOfRootPath(oldName); CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(newName); CheckIfDescendentOfRootPath(NewName);
if (File.Exists(oldName)) if (File.Exists(OldName))
{ {
File.Move(oldName, newName); File.Move(OldName, NewName);
} }
else else
{ {
@ -258,24 +258,24 @@ namespace Ryujinx.HLE.FileSystem
return 0; return 0;
} }
public void CheckIfDescendentOfRootPath(string path) public void CheckIfDescendentOfRootPath(string Path)
{ {
DirectoryInfo pathInfo = new DirectoryInfo(path); DirectoryInfo PathInfo = new DirectoryInfo(Path);
DirectoryInfo rootInfo = new DirectoryInfo(_rootPath); DirectoryInfo RootInfo = new DirectoryInfo(RootPath);
while (pathInfo.Parent != null) while (PathInfo.Parent != null)
{ {
if (pathInfo.Parent.FullName == rootInfo.FullName) if (PathInfo.Parent.FullName == RootInfo.FullName)
{ {
return; return;
} }
else else
{ {
pathInfo = pathInfo.Parent; PathInfo = PathInfo.Parent;
} }
} }
throw new InvalidOperationException($"Path {path} is not a child directory of {_rootPath}"); throw new InvalidOperationException($"Path {Path} is not a child directory of {RootPath}");
} }
} }
} }

View file

@ -1,40 +1,41 @@
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.FspSrv; using Ryujinx.HLE.HOS.Services.FspSrv;
using System;
namespace Ryujinx.HLE.FileSystem namespace Ryujinx.HLE.FileSystem
{ {
interface IFileSystemProvider interface IFileSystemProvider
{ {
long CreateFile(string name, long size); long CreateFile(string Name, long Size);
long CreateDirectory(string name); long CreateDirectory(string Name);
long RenameFile(string oldName, string newName); long RenameFile(string OldName, string NewName);
long RenameDirectory(string oldName, string newName); long RenameDirectory(string OldName, string NewName);
DirectoryEntry[] GetEntries(string path); DirectoryEntry[] GetEntries(string Path);
DirectoryEntry[] GetDirectories(string path); DirectoryEntry[] GetDirectories(string Path);
DirectoryEntry[] GetFiles(string path); DirectoryEntry[] GetFiles(string Path);
long DeleteFile(string name); long DeleteFile(string Name);
long DeleteDirectory(string name, bool recursive); long DeleteDirectory(string Name, bool Recursive);
bool FileExists(string name); bool FileExists(string Name);
bool DirectoryExists(string name); bool DirectoryExists(string Name);
long OpenFile(string name, out IFile fileInterface); long OpenFile(string Name, out IFile FileInterface);
long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface); long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface);
string GetFullPath(string name); string GetFullPath(string Name);
long GetFreeSpace(ServiceCtx context); long GetFreeSpace(ServiceCtx Context);
long GetTotalSpace(ServiceCtx context); long GetTotalSpace(ServiceCtx Context);
} }
} }

View file

@ -12,98 +12,98 @@ namespace Ryujinx.HLE.FileSystem
{ {
class PFsProvider : IFileSystemProvider class PFsProvider : IFileSystemProvider
{ {
private Pfs _pfs; private Pfs Pfs;
public PFsProvider(Pfs pfs) public PFsProvider(Pfs Pfs)
{ {
_pfs = pfs; this.Pfs = Pfs;
} }
public long CreateDirectory(string name) public long CreateDirectory(string Name)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long CreateFile(string name, long size) public long CreateFile(string Name, long Size)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long DeleteDirectory(string name, bool recursive) public long DeleteDirectory(string Name, bool Recursive)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long DeleteFile(string name) public long DeleteFile(string Name)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public DirectoryEntry[] GetDirectories(string path) public DirectoryEntry[] GetDirectories(string Path)
{ {
return new DirectoryEntry[0]; return new DirectoryEntry[0];
} }
public DirectoryEntry[] GetEntries(string path) public DirectoryEntry[] GetEntries(string Path)
{ {
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach (PfsFileEntry file in _pfs.Files) foreach (PfsFileEntry File in Pfs.Files)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size); DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
return entries.ToArray(); return Entries.ToArray();
} }
public DirectoryEntry[] GetFiles(string path) public DirectoryEntry[] GetFiles(string Path)
{ {
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach (PfsFileEntry file in _pfs.Files) foreach (PfsFileEntry File in Pfs.Files)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.Size); DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.Size);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
return entries.ToArray(); return Entries.ToArray();
} }
public long GetFreeSpace(ServiceCtx context) public long GetFreeSpace(ServiceCtx Context)
{ {
return 0; return 0;
} }
public string GetFullPath(string name) public string GetFullPath(string Name)
{ {
return name; return Name;
} }
public long GetTotalSpace(ServiceCtx context) public long GetTotalSpace(ServiceCtx Context)
{ {
return _pfs.Files.Sum(x => x.Size); return Pfs.Files.Sum(x => x.Size);
} }
public bool DirectoryExists(string name) public bool DirectoryExists(string Name)
{ {
return name == "/"; return Name == "/" ? true : false;
} }
public bool FileExists(string name) public bool FileExists(string Name)
{ {
name = name.TrimStart('/'); Name = Name.TrimStart('/');
return _pfs.FileExists(name); return Pfs.FileExists(Name);
} }
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface) public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
{ {
if (name == "/") if (Name == "/")
{ {
directoryInterface = new IDirectory(name, filterFlags, this); DirectoryInterface = new IDirectory(Name, FilterFlags, this);
return 0; return 0;
} }
@ -111,34 +111,34 @@ namespace Ryujinx.HLE.FileSystem
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long OpenFile(string name, out IFile fileInterface) public long OpenFile(string Name, out IFile FileInterface)
{ {
name = name.TrimStart('/'); Name = Name.TrimStart('/');
if (_pfs.FileExists(name)) if (Pfs.FileExists(Name))
{ {
Stream stream = _pfs.OpenFile(name); Stream Stream = Pfs.OpenFile(Name);
fileInterface = new IFile(stream, name); FileInterface = new IFile(Stream, Name);
return 0; return 0;
} }
fileInterface = null; FileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
public long RenameDirectory(string oldName, string newName) public long RenameDirectory(string OldName, string NewName)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long RenameFile(string oldName, string newName) public long RenameFile(string OldName, string NewName)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public void CheckIfOutsideBasePath(string path) public void CheckIfOutsideBasePath(string Path)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View file

@ -12,150 +12,150 @@ namespace Ryujinx.HLE.FileSystem
{ {
class RomFsProvider : IFileSystemProvider class RomFsProvider : IFileSystemProvider
{ {
private Romfs _romFs; private Romfs RomFs;
public RomFsProvider(Stream storageStream) public RomFsProvider(Stream StorageStream)
{ {
_romFs = new Romfs(storageStream); RomFs = new Romfs(StorageStream);
} }
public long CreateDirectory(string name) public long CreateDirectory(string Name)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long CreateFile(string name, long size) public long CreateFile(string Name, long Size)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long DeleteDirectory(string name, bool recursive) public long DeleteDirectory(string Name, bool Recursive)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long DeleteFile(string name) public long DeleteFile(string Name)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public DirectoryEntry[] GetDirectories(string path) public DirectoryEntry[] GetDirectories(string Path)
{ {
List<DirectoryEntry> directories = new List<DirectoryEntry>(); List<DirectoryEntry> Directories = new List<DirectoryEntry>();
foreach(RomfsDir directory in _romFs.Directories) foreach(RomfsDir Directory in RomFs.Directories)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory); DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
directories.Add(directoryEntry); Directories.Add(DirectoryEntry);
} }
return directories.ToArray(); return Directories.ToArray();
} }
public DirectoryEntry[] GetEntries(string path) public DirectoryEntry[] GetEntries(string Path)
{ {
List<DirectoryEntry> entries = new List<DirectoryEntry>(); List<DirectoryEntry> Entries = new List<DirectoryEntry>();
foreach (RomfsDir directory in _romFs.Directories) foreach (RomfsDir Directory in RomFs.Directories)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(directory.Name, DirectoryEntryType.Directory); DirectoryEntry DirectoryEntry = new DirectoryEntry(Directory.Name, DirectoryEntryType.Directory);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
foreach (RomfsFile file in _romFs.Files) foreach (RomfsFile File in RomFs.Files)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength); DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
entries.Add(directoryEntry); Entries.Add(DirectoryEntry);
} }
return entries.ToArray(); return Entries.ToArray();
} }
public DirectoryEntry[] GetFiles(string path) public DirectoryEntry[] GetFiles(string Path)
{ {
List<DirectoryEntry> files = new List<DirectoryEntry>(); List<DirectoryEntry> Files = new List<DirectoryEntry>();
foreach (RomfsFile file in _romFs.Files) foreach (RomfsFile File in RomFs.Files)
{ {
DirectoryEntry directoryEntry = new DirectoryEntry(file.Name, DirectoryEntryType.File, file.DataLength); DirectoryEntry DirectoryEntry = new DirectoryEntry(File.Name, DirectoryEntryType.File, File.DataLength);
files.Add(directoryEntry); Files.Add(DirectoryEntry);
} }
return files.ToArray(); return Files.ToArray();
} }
public long GetFreeSpace(ServiceCtx context) public long GetFreeSpace(ServiceCtx Context)
{ {
return 0; return 0;
} }
public string GetFullPath(string name) public string GetFullPath(string Name)
{ {
return name; return Name;
} }
public long GetTotalSpace(ServiceCtx context) public long GetTotalSpace(ServiceCtx Context)
{ {
return _romFs.Files.Sum(x => x.DataLength); return RomFs.Files.Sum(x => x.DataLength);
} }
public bool DirectoryExists(string name) public bool DirectoryExists(string Name)
{ {
return _romFs.Directories.Exists(x=>x.Name == name); return RomFs.Directories.Exists(x=>x.Name == Name);
} }
public bool FileExists(string name) public bool FileExists(string Name)
{ {
return _romFs.FileExists(name); return RomFs.FileExists(Name);
} }
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface) public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
{ {
RomfsDir directory = _romFs.Directories.Find(x => x.Name == name); RomfsDir Directory = RomFs.Directories.Find(x => x.Name == Name);
if (directory != null) if (Directory != null)
{ {
directoryInterface = new IDirectory(name, filterFlags, this); DirectoryInterface = new IDirectory(Name, FilterFlags, this);
return 0; return 0;
} }
directoryInterface = null; DirectoryInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
public long OpenFile(string name, out IFile fileInterface) public long OpenFile(string Name, out IFile FileInterface)
{ {
if (_romFs.FileExists(name)) if (RomFs.FileExists(Name))
{ {
Stream stream = _romFs.OpenFile(name); Stream Stream = RomFs.OpenFile(Name);
fileInterface = new IFile(stream, name); FileInterface = new IFile(Stream, Name);
return 0; return 0;
} }
fileInterface = null; FileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
} }
public long RenameDirectory(string oldName, string newName) public long RenameDirectory(string OldName, string NewName)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public long RenameFile(string oldName, string newName) public long RenameFile(string OldName, string NewName)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public void CheckIfOutsideBasePath(string path) public void CheckIfOutsideBasePath(string Path)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View file

@ -7,39 +7,39 @@ namespace Ryujinx.HLE.FileSystem
{ {
static class SaveHelper static class SaveHelper
{ {
public static string GetSavePath(SaveInfo saveMetaData, ServiceCtx context) public static string GetSavePath(SaveInfo SaveMetaData, ServiceCtx Context)
{ {
string baseSavePath = NandPath; string BaseSavePath = NandPath;
long currentTitleId = saveMetaData.TitleId; long CurrentTitleId = SaveMetaData.TitleId;
switch (saveMetaData.SaveSpaceId) switch (SaveMetaData.SaveSpaceId)
{ {
case SaveSpaceId.NandUser: case SaveSpaceId.NandUser:
baseSavePath = UserNandPath; BaseSavePath = UserNandPath;
break; break;
case SaveSpaceId.NandSystem: case SaveSpaceId.NandSystem:
baseSavePath = SystemNandPath; BaseSavePath = SystemNandPath;
break; break;
case SaveSpaceId.SdCard: case SaveSpaceId.SdCard:
baseSavePath = Path.Combine(SdCardPath, "Nintendo"); BaseSavePath = Path.Combine(SdCardPath, "Nintendo");
break; break;
} }
baseSavePath = Path.Combine(baseSavePath, "save"); BaseSavePath = Path.Combine(BaseSavePath, "save");
if (saveMetaData.TitleId == 0 && saveMetaData.SaveDataType == SaveDataType.SaveData) if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData)
{ {
currentTitleId = context.Process.TitleId; CurrentTitleId = Context.Process.TitleId;
} }
string saveAccount = saveMetaData.UserId.IsZero() ? "savecommon" : saveMetaData.UserId.ToString(); string SaveAccount = SaveMetaData.UserId.IsZero() ? "savecommon" : SaveMetaData.UserId.ToString();
string savePath = Path.Combine(baseSavePath, string SavePath = Path.Combine(BaseSavePath,
saveMetaData.SaveId.ToString("x16"), SaveMetaData.SaveId.ToString("x16"),
saveAccount, SaveAccount,
saveMetaData.SaveDataType == SaveDataType.SaveData ? currentTitleId.ToString("x16") : string.Empty); SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("x16") : string.Empty);
return savePath; return SavePath;
} }
} }
} }

View file

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.FileSystem
{ {
struct SaveInfo struct SaveInfo
{ {
public long TitleId { get; } public long TitleId { get; private set; }
public long SaveId { get; } public long SaveId { get; private set; }
public UInt128 UserId { get; } public UInt128 UserId { get; private set; }
public SaveDataType SaveDataType { get; } public SaveDataType SaveDataType { get; private set; }
public SaveSpaceId SaveSpaceId { get; } public SaveSpaceId SaveSpaceId { get; private set; }
public SaveInfo( public SaveInfo(
long titleId, long TitleId,
long saveId, long SaveId,
SaveDataType saveDataType, SaveDataType SaveDataType,
UInt128 userId, UInt128 UserId,
SaveSpaceId saveSpaceId) SaveSpaceId SaveSpaceId)
{ {
TitleId = titleId; this.TitleId = TitleId;
UserId = userId; this.UserId = UserId;
SaveId = saveId; this.SaveId = SaveId;
SaveDataType = saveDataType; this.SaveDataType = SaveDataType;
SaveSpaceId = saveSpaceId; this.SaveSpaceId = SaveSpaceId;
} }
} }
} }

View file

@ -18,40 +18,40 @@ namespace Ryujinx.HLE.FileSystem
public Stream RomFs { get; private set; } public Stream RomFs { get; private set; }
public void LoadRomFs(string fileName) public void LoadRomFs(string FileName)
{ {
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read); RomFs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
} }
public void SetRomFs(Stream romfsStream) public void SetRomFs(Stream RomfsStream)
{ {
RomFs?.Close(); RomFs?.Close();
RomFs = romfsStream; RomFs = RomfsStream;
} }
public string GetFullPath(string basePath, string fileName) public string GetFullPath(string BasePath, string FileName)
{ {
if (fileName.StartsWith("//")) if (FileName.StartsWith("//"))
{ {
fileName = fileName.Substring(2); FileName = FileName.Substring(2);
} }
else if (fileName.StartsWith('/')) else if (FileName.StartsWith('/'))
{ {
fileName = fileName.Substring(1); FileName = FileName.Substring(1);
} }
else else
{ {
return null; return null;
} }
string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName)); string FullPath = Path.GetFullPath(Path.Combine(BasePath, FileName));
if (!fullPath.StartsWith(GetBasePath())) if (!FullPath.StartsWith(GetBasePath()))
{ {
return null; return null;
} }
return fullPath; return FullPath;
} }
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath); public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
@ -60,84 +60,84 @@ namespace Ryujinx.HLE.FileSystem
public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath); public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
public string GetGameSavePath(SaveInfo save, ServiceCtx context) public string GetGameSavePath(SaveInfo Save, ServiceCtx Context)
{ {
return MakeDirAndGetFullPath(SaveHelper.GetSavePath(save, context)); return MakeDirAndGetFullPath(SaveHelper.GetSavePath(Save, Context));
} }
public string GetFullPartitionPath(string partitionPath) public string GetFullPartitionPath(string PartitionPath)
{ {
return MakeDirAndGetFullPath(partitionPath); return MakeDirAndGetFullPath(PartitionPath);
} }
public string SwitchPathToSystemPath(string switchPath) public string SwitchPathToSystemPath(string SwitchPath)
{ {
string[] parts = switchPath.Split(":"); string[] Parts = SwitchPath.Split(":");
if (parts.Length != 2) if (Parts.Length != 2)
{ {
return null; return null;
} }
return GetFullPath(MakeDirAndGetFullPath(parts[0]), parts[1]); return GetFullPath(MakeDirAndGetFullPath(Parts[0]), Parts[1]);
} }
public string SystemPathToSwitchPath(string systemPath) public string SystemPathToSwitchPath(string SystemPath)
{ {
string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar; string BaseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
if (systemPath.StartsWith(baseSystemPath)) if (SystemPath.StartsWith(BaseSystemPath))
{ {
string rawPath = systemPath.Replace(baseSystemPath, ""); string RawPath = SystemPath.Replace(BaseSystemPath, "");
int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar); int FirstSeparatorOffset = RawPath.IndexOf(Path.DirectorySeparatorChar);
if (firstSeparatorOffset == -1) if (FirstSeparatorOffset == -1)
{ {
return $"{rawPath}:/"; return $"{RawPath}:/";
} }
string basePath = rawPath.Substring(0, firstSeparatorOffset); string BasePath = RawPath.Substring(0, FirstSeparatorOffset);
string fileName = rawPath.Substring(firstSeparatorOffset + 1); string FileName = RawPath.Substring(FirstSeparatorOffset + 1);
return $"{basePath}:/{fileName}"; return $"{BasePath}:/{FileName}";
} }
return null; return null;
} }
private string MakeDirAndGetFullPath(string dir) private string MakeDirAndGetFullPath(string Dir)
{ {
// Handles Common Switch Content Paths // Handles Common Switch Content Paths
switch (dir) switch (Dir)
{ {
case ContentPath.SdCard: case ContentPath.SdCard:
case "@Sdcard": case "@Sdcard":
dir = SdCardPath; Dir = SdCardPath;
break; break;
case ContentPath.User: case ContentPath.User:
dir = UserNandPath; Dir = UserNandPath;
break; break;
case ContentPath.System: case ContentPath.System:
dir = SystemNandPath; Dir = SystemNandPath;
break; break;
case ContentPath.SdCardContent: case ContentPath.SdCardContent:
dir = Path.Combine(SdCardPath, "Nintendo", "Contents"); Dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
break; break;
case ContentPath.UserContent: case ContentPath.UserContent:
dir = Path.Combine(UserNandPath, "Contents"); Dir = Path.Combine(UserNandPath, "Contents");
break; break;
case ContentPath.SystemContent: case ContentPath.SystemContent:
dir = Path.Combine(SystemNandPath, "Contents"); Dir = Path.Combine(SystemNandPath, "Contents");
break; break;
} }
string fullPath = Path.Combine(GetBasePath(), dir); string FullPath = Path.Combine(GetBasePath(), Dir);
if (!Directory.Exists(fullPath)) if (!Directory.Exists(FullPath))
{ {
Directory.CreateDirectory(fullPath); Directory.CreateDirectory(FullPath);
} }
return fullPath; return FullPath;
} }
public DriveInfo GetDrive() public DriveInfo GetDrive()
@ -147,9 +147,9 @@ namespace Ryujinx.HLE.FileSystem
public string GetBasePath() public string GetBasePath()
{ {
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(appDataPath, BasePath); return Path.Combine(AppDataPath, BasePath);
} }
public void Dispose() public void Dispose()

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ArraySubscriptingExpression : BaseNode public class ArraySubscriptingExpression : BaseNode
{ {
private BaseNode _leftNode; private BaseNode LeftNode;
private BaseNode _subscript; private BaseNode Subscript;
public ArraySubscriptingExpression(BaseNode leftNode, BaseNode subscript) : base(NodeType.ArraySubscriptingExpression) public ArraySubscriptingExpression(BaseNode LeftNode, BaseNode Subscript) : base(NodeType.ArraySubscriptingExpression)
{ {
_leftNode = leftNode; this.LeftNode = LeftNode;
_subscript = subscript; this.Subscript = Subscript;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
_leftNode.Print(writer); LeftNode.Print(Writer);
writer.Write(")["); Writer.Write(")[");
_subscript.Print(writer); Subscript.Print(Writer);
writer.Write("]"); Writer.Write("]");
} }
} }
} }

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ArrayType : BaseNode public class ArrayType : BaseNode
{ {
private BaseNode _base; private BaseNode Base;
private BaseNode _dimensionExpression; private BaseNode DimensionExpression;
private string _dimensionString; private string DimensionString;
public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType) public ArrayType(BaseNode Base, BaseNode DimensionExpression = null) : base(NodeType.ArrayType)
{ {
_base = Base; this.Base = Base;
_dimensionExpression = dimensionExpression; this.DimensionExpression = DimensionExpression;
} }
public ArrayType(BaseNode Base, string dimensionString) : base(NodeType.ArrayType) public ArrayType(BaseNode Base, string DimensionString) : base(NodeType.ArrayType)
{ {
_base = Base; this.Base = Base;
_dimensionString = dimensionString; this.DimensionString = DimensionString;
} }
public override bool HasRightPart() public override bool HasRightPart()
@ -30,30 +30,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true; return true;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_base.PrintLeft(writer); Base.PrintLeft(Writer);
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
// FIXME: detect if previous char was a ]. // FIXME: detect if previous char was a ].
writer.Write(" "); Writer.Write(" ");
writer.Write("["); Writer.Write("[");
if (_dimensionString != null) if (DimensionString != null)
{ {
writer.Write(_dimensionString); Writer.Write(DimensionString);
} }
else if (_dimensionExpression != null) else if (DimensionExpression != null)
{ {
_dimensionExpression.Print(writer); DimensionExpression.Print(Writer);
} }
writer.Write("]"); Writer.Write("]");
_base.PrintRight(writer); Base.PrintRight(Writer);
} }
} }
} }

View file

@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public enum NodeType public enum NodeType
{ {
CvQualifierType, CVQualifierType,
SimpleReferenceType, SimpleReferenceType,
NameType, NameType,
EncodedFunction, EncodedFunction,
@ -62,22 +62,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public NodeType Type { get; protected set; } public NodeType Type { get; protected set; }
public BaseNode(NodeType type) public BaseNode(NodeType Type)
{ {
Type = type; this.Type = Type;
} }
public virtual void Print(TextWriter writer) public virtual void Print(TextWriter Writer)
{ {
PrintLeft(writer); PrintLeft(Writer);
if (HasRightPart()) if (HasRightPart())
{ {
PrintRight(writer); PrintRight(Writer);
} }
} }
public abstract void PrintLeft(TextWriter writer); public abstract void PrintLeft(TextWriter Writer);
public virtual bool HasRightPart() public virtual bool HasRightPart()
{ {
@ -99,15 +99,15 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null; return null;
} }
public virtual void PrintRight(TextWriter writer) {} public virtual void PrintRight(TextWriter Writer) {}
public override string ToString() public override string ToString()
{ {
StringWriter writer = new StringWriter(); StringWriter Writer = new StringWriter();
Print(writer); Print(Writer);
return writer.ToString(); return Writer.ToString();
} }
} }
} }

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class BinaryExpression : BaseNode public class BinaryExpression : BaseNode
{ {
private BaseNode _leftPart; private BaseNode LeftPart;
private string _name; private string Name;
private BaseNode _rightPart; private BaseNode RightPart;
public BinaryExpression(BaseNode leftPart, string name, BaseNode rightPart) : base(NodeType.BinaryExpression) public BinaryExpression(BaseNode LeftPart, string Name, BaseNode RightPart) : base(NodeType.BinaryExpression)
{ {
_leftPart = leftPart; this.LeftPart = LeftPart;
_name = name; this.Name = Name;
_rightPart = rightPart; this.RightPart = RightPart;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_name.Equals(">")) if (Name.Equals(">"))
{ {
writer.Write("("); Writer.Write("(");
} }
writer.Write("("); Writer.Write("(");
_leftPart.Print(writer); LeftPart.Print(Writer);
writer.Write(") "); Writer.Write(") ");
writer.Write(_name); Writer.Write(Name);
writer.Write(" ("); Writer.Write(" (");
_rightPart.Print(writer); RightPart.Print(Writer);
writer.Write(")"); Writer.Write(")");
if (_name.Equals(">")) if (Name.Equals(">"))
{ {
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class BracedExpression : BaseNode public class BracedExpression : BaseNode
{ {
private BaseNode _element; private BaseNode Element;
private BaseNode _expression; private BaseNode Expression;
private bool _isArrayExpression; private bool IsArrayExpression;
public BracedExpression(BaseNode element, BaseNode expression, bool isArrayExpression) : base(NodeType.BracedExpression) public BracedExpression(BaseNode Element, BaseNode Expression, bool IsArrayExpression) : base(NodeType.BracedExpression)
{ {
_element = element; this.Element = Element;
_expression = expression; this.Expression = Expression;
_isArrayExpression = isArrayExpression; this.IsArrayExpression = IsArrayExpression;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_isArrayExpression) if (IsArrayExpression)
{ {
writer.Write("["); Writer.Write("[");
_element.Print(writer); Element.Print(Writer);
writer.Write("]"); Writer.Write("]");
} }
else else
{ {
writer.Write("."); Writer.Write(".");
_element.Print(writer); Element.Print(Writer);
} }
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression)) if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
{ {
writer.Write(" = "); Writer.Write(" = ");
} }
_expression.Print(writer); Expression.Print(Writer);
} }
} }
} }

View file

@ -4,31 +4,31 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class BracedRangeExpression : BaseNode public class BracedRangeExpression : BaseNode
{ {
private BaseNode _firstNode; private BaseNode FirstNode;
private BaseNode _lastNode; private BaseNode LastNode;
private BaseNode _expression; private BaseNode Expression;
public BracedRangeExpression(BaseNode firstNode, BaseNode lastNode, BaseNode expression) : base(NodeType.BracedRangeExpression) public BracedRangeExpression(BaseNode FirstNode, BaseNode LastNode, BaseNode Expression) : base(NodeType.BracedRangeExpression)
{ {
_firstNode = firstNode; this.FirstNode = FirstNode;
_lastNode = lastNode; this.LastNode = LastNode;
_expression = expression; this.Expression = Expression;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("["); Writer.Write("[");
_firstNode.Print(writer); FirstNode.Print(Writer);
writer.Write(" ... "); Writer.Write(" ... ");
_lastNode.Print(writer); LastNode.Print(Writer);
writer.Write("]"); Writer.Write("]");
if (!_expression.GetType().Equals(NodeType.BracedExpression) || !_expression.GetType().Equals(NodeType.BracedRangeExpression)) if (!Expression.GetType().Equals(NodeType.BracedExpression) || !Expression.GetType().Equals(NodeType.BracedRangeExpression))
{ {
writer.Write(" = "); Writer.Write(" = ");
} }
_expression.Print(writer); Expression.Print(Writer);
} }
} }
} }

View file

@ -5,20 +5,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class CallExpression : NodeArray public class CallExpression : NodeArray
{ {
private BaseNode _callee; private BaseNode Callee;
public CallExpression(BaseNode callee, List<BaseNode> nodes) : base(nodes, NodeType.CallExpression) public CallExpression(BaseNode Callee, List<BaseNode> Nodes) : base(Nodes, NodeType.CallExpression)
{ {
_callee = callee; this.Callee = Callee;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_callee.Print(writer); Callee.Print(Writer);
writer.Write("("); Writer.Write("(");
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray())); Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class CastExpression : BaseNode public class CastExpression : BaseNode
{ {
private string _kind; private string Kind;
private BaseNode _to; private BaseNode To;
private BaseNode _from; private BaseNode From;
public CastExpression(string kind, BaseNode to, BaseNode from) : base(NodeType.CastExpression) public CastExpression(string Kind, BaseNode To, BaseNode From) : base(NodeType.CastExpression)
{ {
_kind = kind; this.Kind = Kind;
_to = to; this.To = To;
_from = from; this.From = From;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_kind); Writer.Write(Kind);
writer.Write("<"); Writer.Write("<");
_to.PrintLeft(writer); To.PrintLeft(Writer);
writer.Write(">("); Writer.Write(">(");
_from.PrintLeft(writer); From.PrintLeft(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ConditionalExpression : BaseNode public class ConditionalExpression : BaseNode
{ {
private BaseNode _thenNode; private BaseNode ThenNode;
private BaseNode _elseNode; private BaseNode ElseNode;
private BaseNode _conditionNode; private BaseNode ConditionNode;
public ConditionalExpression(BaseNode conditionNode, BaseNode thenNode, BaseNode elseNode) : base(NodeType.ConditionalExpression) public ConditionalExpression(BaseNode ConditionNode, BaseNode ThenNode, BaseNode ElseNode) : base(NodeType.ConditionalExpression)
{ {
_thenNode = thenNode; this.ThenNode = ThenNode;
_conditionNode = conditionNode; this.ConditionNode = ConditionNode;
_elseNode = elseNode; this.ElseNode = ElseNode;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
_conditionNode.Print(writer); ConditionNode.Print(Writer);
writer.Write(") ? ("); Writer.Write(") ? (");
_thenNode.Print(writer); ThenNode.Print(Writer);
writer.Write(") : ("); Writer.Write(") : (");
_elseNode.Print(writer); ElseNode.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ConversionExpression : BaseNode public class ConversionExpression : BaseNode
{ {
private BaseNode _typeNode; private BaseNode TypeNode;
private BaseNode _expressions; private BaseNode Expressions;
public ConversionExpression(BaseNode typeNode, BaseNode expressions) : base(NodeType.ConversionExpression) public ConversionExpression(BaseNode TypeNode, BaseNode Expressions) : base(NodeType.ConversionExpression)
{ {
_typeNode = typeNode; this.TypeNode = TypeNode;
_expressions = expressions; this.Expressions = Expressions;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
_typeNode.Print(writer); TypeNode.Print(Writer);
writer.Write(")("); Writer.Write(")(");
_expressions.Print(writer); Expressions.Print(Writer);
} }
} }
} }

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ConversionOperatorType : ParentNode public class ConversionOperatorType : ParentNode
{ {
public ConversionOperatorType(BaseNode child) : base(NodeType.ConversionOperatorType, child) { } public ConversionOperatorType(BaseNode Child) : base(NodeType.ConversionOperatorType, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("operator "); Writer.Write("operator ");
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class CtorDtorNameType : ParentNode public class CtorDtorNameType : ParentNode
{ {
private bool _isDestructor; private bool IsDestructor;
public CtorDtorNameType(BaseNode name, bool isDestructor) : base(NodeType.CtorDtorNameType, name) public CtorDtorNameType(BaseNode Name, bool IsDestructor) : base(NodeType.CtorDtorNameType, Name)
{ {
_isDestructor = isDestructor; this.IsDestructor = IsDestructor;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_isDestructor) if (IsDestructor)
{ {
writer.Write("~"); Writer.Write("~");
} }
writer.Write(Child.GetName()); Writer.Write(Child.GetName());
} }
} }
} }

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class CtorVtableSpecialName : BaseNode public class CtorVtableSpecialName : BaseNode
{ {
private BaseNode _firstType; private BaseNode FirstType;
private BaseNode _secondType; private BaseNode SecondType;
public CtorVtableSpecialName(BaseNode firstType, BaseNode secondType) : base(NodeType.CtorVtableSpecialName) public CtorVtableSpecialName(BaseNode FirstType, BaseNode SecondType) : base(NodeType.CtorVtableSpecialName)
{ {
_firstType = firstType; this.FirstType = FirstType;
_secondType = secondType; this.SecondType = SecondType;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("construction vtable for "); Writer.Write("construction vtable for ");
_firstType.Print(writer); FirstType.Print(Writer);
writer.Write("-in-"); Writer.Write("-in-");
_secondType.Print(writer); SecondType.Print(Writer);
} }
} }
} }

View file

@ -4,30 +4,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class DeleteExpression : ParentNode public class DeleteExpression : ParentNode
{ {
private bool _isGlobal; private bool IsGlobal;
private bool _isArrayExpression; private bool IsArrayExpression;
public DeleteExpression(BaseNode child, bool isGlobal, bool isArrayExpression) : base(NodeType.DeleteExpression, child) public DeleteExpression(BaseNode Child, bool IsGlobal, bool IsArrayExpression) : base(NodeType.DeleteExpression, Child)
{ {
_isGlobal = isGlobal; this.IsGlobal = IsGlobal;
_isArrayExpression = isArrayExpression; this.IsArrayExpression = IsArrayExpression;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_isGlobal) if (IsGlobal)
{ {
writer.Write("::"); Writer.Write("::");
} }
writer.Write("delete"); Writer.Write("delete");
if (_isArrayExpression) if (IsArrayExpression)
{ {
writer.Write("[] "); Writer.Write("[] ");
} }
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class DtorName : ParentNode public class DtorName : ParentNode
{ {
public DtorName(BaseNode name) : base(NodeType.DtOrName, name) { } public DtorName(BaseNode Name) : base(NodeType.DtOrName, Name) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("~"); Writer.Write("~");
Child.PrintLeft(writer); Child.PrintLeft(Writer);
} }
} }
} }

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class DynamicExceptionSpec : ParentNode public class DynamicExceptionSpec : ParentNode
{ {
public DynamicExceptionSpec(BaseNode child) : base(NodeType.DynamicExceptionSpec, child) { } public DynamicExceptionSpec(BaseNode Child) : base(NodeType.DynamicExceptionSpec, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("throw("); Writer.Write("throw(");
Child.Print(writer); Child.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,18 +4,18 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ElaboratedType : ParentNode public class ElaboratedType : ParentNode
{ {
private string _elaborated; private string Elaborated;
public ElaboratedType(string elaborated, BaseNode type) : base(NodeType.ElaboratedType, type) public ElaboratedType(string Elaborated, BaseNode Type) : base(NodeType.ElaboratedType, Type)
{ {
_elaborated = elaborated; this.Elaborated = Elaborated;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_elaborated); Writer.Write(Elaborated);
writer.Write(" "); Writer.Write(" ");
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class EnclosedExpression : BaseNode public class EnclosedExpression : BaseNode
{ {
private string _prefix; private string Prefix;
private BaseNode _expression; private BaseNode Expression;
private string _postfix; private string Postfix;
public EnclosedExpression(string prefix, BaseNode expression, string postfix) : base(NodeType.EnclosedExpression) public EnclosedExpression(string Prefix, BaseNode Expression, string Postfix) : base(NodeType.EnclosedExpression)
{ {
_prefix = prefix; this.Prefix = Prefix;
_expression = expression; this.Expression = Expression;
_postfix = postfix; this.Postfix = Postfix;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_prefix); Writer.Write(Prefix);
_expression.Print(writer); Expression.Print(Writer);
writer.Write(_postfix); Writer.Write(Postfix);
} }
} }
} }

View file

@ -4,36 +4,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class EncodedFunction : BaseNode public class EncodedFunction : BaseNode
{ {
private BaseNode _name; private BaseNode Name;
private BaseNode _params; private BaseNode Params;
private BaseNode _cv; private BaseNode CV;
private BaseNode _ref; private BaseNode Ref;
private BaseNode _attrs; private BaseNode Attrs;
private BaseNode _ret; private BaseNode Ret;
public EncodedFunction(BaseNode name, BaseNode Params, BaseNode cv, BaseNode Ref, BaseNode attrs, BaseNode ret) : base(NodeType.NameType) public EncodedFunction(BaseNode Name, BaseNode Params, BaseNode CV, BaseNode Ref, BaseNode Attrs, BaseNode Ret) : base(NodeType.NameType)
{ {
_name = name; this.Name = Name;
_params = Params; this.Params = Params;
_cv = cv; this.CV = CV;
_ref = Ref; this.Ref = Ref;
_attrs = attrs; this.Attrs = Attrs;
_ret = ret; this.Ret = Ret;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_ret != null) if (Ret != null)
{ {
_ret.PrintLeft(writer); Ret.PrintLeft(Writer);
if (!_ret.HasRightPart()) if (!Ret.HasRightPart())
{ {
writer.Write(" "); Writer.Write(" ");
} }
} }
_name.Print(writer); Name.Print(Writer);
} }
@ -42,35 +42,35 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true; return true;
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
if (_params != null) if (Params != null)
{ {
_params.Print(writer); Params.Print(Writer);
} }
writer.Write(")"); Writer.Write(")");
if (_ret != null) if (Ret != null)
{ {
_ret.PrintRight(writer); Ret.PrintRight(Writer);
} }
if (_cv != null) if (CV != null)
{ {
_cv.Print(writer); CV.Print(Writer);
} }
if (_ref != null) if (Ref != null)
{ {
_ref.Print(writer); Ref.Print(Writer);
} }
if (_attrs != null) if (Attrs != null)
{ {
_attrs.Print(writer); Attrs.Print(Writer);
} }
} }
} }

View file

@ -4,45 +4,45 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class FoldExpression : BaseNode public class FoldExpression : BaseNode
{ {
private bool _isLeftFold; private bool IsLeftFold;
private string _operatorName; private string OperatorName;
private BaseNode _expression; private BaseNode Expression;
private BaseNode _initializer; private BaseNode Initializer;
public FoldExpression(bool isLeftFold, string operatorName, BaseNode expression, BaseNode initializer) : base(NodeType.FunctionParameter) public FoldExpression(bool IsLeftFold, string OperatorName, BaseNode Expression, BaseNode Initializer) : base(NodeType.FunctionParameter)
{ {
_isLeftFold = isLeftFold; this.IsLeftFold = IsLeftFold;
_operatorName = operatorName; this.OperatorName = OperatorName;
_expression = expression; this.Expression = Expression;
_initializer = initializer; this.Initializer = Initializer;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
if (_isLeftFold && _initializer != null) if (IsLeftFold && Initializer != null)
{ {
_initializer.Print(writer); Initializer.Print(Writer);
writer.Write(" "); Writer.Write(" ");
writer.Write(_operatorName); Writer.Write(OperatorName);
writer.Write(" "); Writer.Write(" ");
} }
writer.Write(_isLeftFold ? "... " : " "); Writer.Write(IsLeftFold ? "... " : " ");
writer.Write(_operatorName); Writer.Write(OperatorName);
writer.Write(!_isLeftFold ? " ..." : " "); Writer.Write(!IsLeftFold ? " ..." : " ");
_expression.Print(writer); Expression.Print(Writer);
if (!_isLeftFold && _initializer != null) if (!IsLeftFold && Initializer != null)
{ {
_initializer.Print(writer); Initializer.Print(Writer);
writer.Write(" "); Writer.Write(" ");
writer.Write(_operatorName); Writer.Write(OperatorName);
writer.Write(" "); Writer.Write(" ");
} }
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
// TODO: Compute inside the Demangler // TODO: Compute inside the Demangler
public BaseNode Reference; public BaseNode Reference;
private int _index; private int Index;
public ForwardTemplateReference(int index) : base(NodeType.ForwardTemplateReference) public ForwardTemplateReference(int Index) : base(NodeType.ForwardTemplateReference)
{ {
_index = index; this.Index = Index;
} }
public override string GetName() public override string GetName()
@ -18,14 +18,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Reference.GetName(); return Reference.GetName();
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
Reference.PrintLeft(writer); Reference.PrintLeft(Writer);
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
Reference.PrintRight(writer); Reference.PrintRight(Writer);
} }
public override bool HasRightPart() public override bool HasRightPart()

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class FunctionParameter : BaseNode public class FunctionParameter : BaseNode
{ {
private string _number; private string Number;
public FunctionParameter(string number) : base(NodeType.FunctionParameter) public FunctionParameter(string Number) : base(NodeType.FunctionParameter)
{ {
_number = number; this.Number = Number;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("fp "); Writer.Write("fp ");
if (_number != null) if (Number != null)
{ {
writer.Write(_number); Writer.Write(Number);
} }
} }
} }

View file

@ -4,47 +4,47 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class FunctionType : BaseNode public class FunctionType : BaseNode
{ {
private BaseNode _returnType; private BaseNode ReturnType;
private BaseNode _params; private BaseNode Params;
private BaseNode _cvQualifier; private BaseNode CVQualifier;
private SimpleReferenceType _referenceQualifier; private SimpleReferenceType ReferenceQualifier;
private BaseNode _exceptionSpec; private BaseNode ExceptionSpec;
public FunctionType(BaseNode returnType, BaseNode Params, BaseNode cvQualifier, SimpleReferenceType referenceQualifier, BaseNode exceptionSpec) : base(NodeType.FunctionType) public FunctionType(BaseNode ReturnType, BaseNode Params, BaseNode CVQualifier, SimpleReferenceType ReferenceQualifier, BaseNode ExceptionSpec) : base(NodeType.FunctionType)
{ {
_returnType = returnType; this.ReturnType = ReturnType;
_params = Params; this.Params = Params;
_cvQualifier = cvQualifier; this.CVQualifier = CVQualifier;
_referenceQualifier = referenceQualifier; this.ReferenceQualifier = ReferenceQualifier;
_exceptionSpec = exceptionSpec; this.ExceptionSpec = ExceptionSpec;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_returnType.PrintLeft(writer); ReturnType.PrintLeft(Writer);
writer.Write(" "); Writer.Write(" ");
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
_params.Print(writer); Params.Print(Writer);
writer.Write(")"); Writer.Write(")");
_returnType.PrintRight(writer); ReturnType.PrintRight(Writer);
_cvQualifier.Print(writer); CVQualifier.Print(Writer);
if (_referenceQualifier.Qualifier != Reference.None) if (ReferenceQualifier.Qualifier != Reference.None)
{ {
writer.Write(" "); Writer.Write(" ");
_referenceQualifier.PrintQualifier(writer); ReferenceQualifier.PrintQualifier(Writer);
} }
if (_exceptionSpec != null) if (ExceptionSpec != null)
{ {
writer.Write(" "); Writer.Write(" ");
_exceptionSpec.Print(writer); ExceptionSpec.Print(Writer);
} }
} }

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class GlobalQualifiedName : ParentNode public class GlobalQualifiedName : ParentNode
{ {
public GlobalQualifiedName(BaseNode child) : base(NodeType.GlobalQualifiedName, child) { } public GlobalQualifiedName(BaseNode Child) : base(NodeType.GlobalQualifiedName, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("::"); Writer.Write("::");
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -5,25 +5,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class InitListExpression : BaseNode public class InitListExpression : BaseNode
{ {
private BaseNode _typeNode; private BaseNode TypeNode;
private List<BaseNode> _nodes; private List<BaseNode> Nodes;
public InitListExpression(BaseNode typeNode, List<BaseNode> nodes) : base(NodeType.InitListExpression) public InitListExpression(BaseNode TypeNode, List<BaseNode> Nodes) : base(NodeType.InitListExpression)
{ {
_typeNode = typeNode; this.TypeNode = TypeNode;
_nodes = nodes; this.Nodes = Nodes;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_typeNode != null) if (TypeNode != null)
{ {
_typeNode.Print(writer); TypeNode.Print(Writer);
} }
writer.Write("{"); Writer.Write("{");
writer.Write(string.Join<BaseNode>(", ", _nodes.ToArray())); Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write("}"); Writer.Write("}");
} }
} }
} }

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class IntegerCastExpression : ParentNode public class IntegerCastExpression : ParentNode
{ {
private string _number; private string Number;
public IntegerCastExpression(BaseNode type, string number) : base(NodeType.IntegerCastExpression, type) public IntegerCastExpression(BaseNode Type, string Number) : base(NodeType.IntegerCastExpression, Type)
{ {
_number = number; this.Number = Number;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
Child.Print(writer); Child.Print(Writer);
writer.Write(")"); Writer.Write(")");
writer.Write(_number); Writer.Write(Number);
} }
} }
} }

View file

@ -4,37 +4,37 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class IntegerLiteral : BaseNode public class IntegerLiteral : BaseNode
{ {
private string _literalName; private string LitteralName;
private string _literalValue; private string LitteralValue;
public IntegerLiteral(string literalName, string literalValue) : base(NodeType.IntegerLiteral) public IntegerLiteral(string LitteralName, string LitteralValue) : base(NodeType.IntegerLiteral)
{ {
_literalValue = literalValue; this.LitteralValue = LitteralValue;
_literalName = literalName; this.LitteralName = LitteralName;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_literalName.Length > 3) if (LitteralName.Length > 3)
{ {
writer.Write("("); Writer.Write("(");
writer.Write(_literalName); Writer.Write(LitteralName);
writer.Write(")"); Writer.Write(")");
} }
if (_literalValue[0] == 'n') if (LitteralValue[0] == 'n')
{ {
writer.Write("-"); Writer.Write("-");
writer.Write(_literalValue.Substring(1)); Writer.Write(LitteralValue.Substring(1));
} }
else else
{ {
writer.Write(_literalValue); Writer.Write(LitteralValue);
} }
if (_literalName.Length <= 3) if (LitteralName.Length <= 3)
{ {
writer.Write(_literalName); Writer.Write(LitteralName);
} }
} }
} }

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class LiteralOperator : ParentNode public class LiteralOperator : ParentNode
{ {
public LiteralOperator(BaseNode child) : base(NodeType.LiteralOperator, child) { } public LiteralOperator(BaseNode Child) : base(NodeType.LiteralOperator, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("operator \""); Writer.Write("operator \"");
Child.PrintLeft(writer); Child.PrintLeft(Writer);
writer.Write("\""); Writer.Write("\"");
} }
} }
} }

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class LocalName : BaseNode public class LocalName : BaseNode
{ {
private BaseNode _encoding; private BaseNode Encoding;
private BaseNode _entity; private BaseNode Entity;
public LocalName(BaseNode encoding, BaseNode entity) : base(NodeType.LocalName) public LocalName(BaseNode Encoding, BaseNode Entity) : base(NodeType.LocalName)
{ {
_encoding = encoding; this.Encoding = Encoding;
_entity = entity; this.Entity = Entity;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_encoding.Print(writer); Encoding.Print(Writer);
writer.Write("::"); Writer.Write("::");
_entity.Print(writer); Entity.Print(Writer);
} }
} }
} }

View file

@ -4,22 +4,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class MemberExpression : BaseNode public class MemberExpression : BaseNode
{ {
private BaseNode _leftNode; private BaseNode LeftNode;
private string _kind; private string Kind;
private BaseNode _rightNode; private BaseNode RightNode;
public MemberExpression(BaseNode leftNode, string kind, BaseNode rightNode) : base(NodeType.MemberExpression) public MemberExpression(BaseNode LeftNode, string Kind, BaseNode RightNode) : base(NodeType.MemberExpression)
{ {
_leftNode = leftNode; this.LeftNode = LeftNode;
_kind = kind; this.Kind = Kind;
_rightNode = rightNode; this.RightNode = RightNode;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_leftNode.Print(writer); LeftNode.Print(Writer);
writer.Write(_kind); Writer.Write(Kind);
_rightNode.Print(writer); RightNode.Print(Writer);
} }
} }
} }

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class NameType : BaseNode public class NameType : BaseNode
{ {
private string _nameValue; private string NameValue;
public NameType(string nameValue, NodeType type) : base(type) public NameType(string NameValue, NodeType Type) : base(Type)
{ {
_nameValue = nameValue; this.NameValue = NameValue;
} }
public NameType(string nameValue) : base(NodeType.NameType) public NameType(string NameValue) : base(NodeType.NameType)
{ {
_nameValue = nameValue; this.NameValue = NameValue;
} }
public override string GetName() public override string GetName()
{ {
return _nameValue; return NameValue;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_nameValue); Writer.Write(NameValue);
} }
} }
} }

View file

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class NameTypeWithTemplateArguments : BaseNode public class NameTypeWithTemplateArguments : BaseNode
{ {
private BaseNode _prev; private BaseNode Prev;
private BaseNode _templateArgument; private BaseNode TemplateArgument;
public NameTypeWithTemplateArguments(BaseNode prev, BaseNode templateArgument) : base(NodeType.NameTypeWithTemplateArguments) public NameTypeWithTemplateArguments(BaseNode Prev, BaseNode TemplateArgument) : base(NodeType.NameTypeWithTemplateArguments)
{ {
_prev = prev; this.Prev = Prev;
_templateArgument = templateArgument; this.TemplateArgument = TemplateArgument;
} }
public override string GetName() public override string GetName()
{ {
return _prev.GetName(); return Prev.GetName();
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_prev.Print(writer); Prev.Print(Writer);
_templateArgument.Print(writer); TemplateArgument.Print(Writer);
} }
} }
} }

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class NestedName : ParentNode public class NestedName : ParentNode
{ {
private BaseNode _name; private BaseNode Name;
public NestedName(BaseNode name, BaseNode type) : base(NodeType.NestedName, type) public NestedName(BaseNode Name, BaseNode Type) : base(NodeType.NestedName, Type)
{ {
_name = name; this.Name = Name;
} }
public override string GetName() public override string GetName()
{ {
return _name.GetName(); return Name.GetName();
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
Child.Print(writer); Child.Print(Writer);
writer.Write("::"); Writer.Write("::");
_name.Print(writer); Name.Print(Writer);
} }
} }
} }

View file

@ -4,51 +4,51 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class NewExpression : BaseNode public class NewExpression : BaseNode
{ {
private NodeArray _expressions; private NodeArray Expressions;
private BaseNode _typeNode; private BaseNode TypeNode;
private NodeArray _initializers; private NodeArray Initializers;
private bool _isGlobal; private bool IsGlobal;
private bool _isArrayExpression; private bool IsArrayExpression;
public NewExpression(NodeArray expressions, BaseNode typeNode, NodeArray initializers, bool isGlobal, bool isArrayExpression) : base(NodeType.NewExpression) public NewExpression(NodeArray Expressions, BaseNode TypeNode, NodeArray Initializers, bool IsGlobal, bool IsArrayExpression) : base(NodeType.NewExpression)
{ {
_expressions = expressions; this.Expressions = Expressions;
_typeNode = typeNode; this.TypeNode = TypeNode;
_initializers = initializers; this.Initializers = Initializers;
_isGlobal = isGlobal; this.IsGlobal = IsGlobal;
_isArrayExpression = isArrayExpression; this.IsArrayExpression = IsArrayExpression;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (_isGlobal) if (IsGlobal)
{ {
writer.Write("::operator "); Writer.Write("::operator ");
} }
writer.Write("new "); Writer.Write("new ");
if (_isArrayExpression) if (IsArrayExpression)
{ {
writer.Write("[] "); Writer.Write("[] ");
} }
if (_expressions.Nodes.Count != 0) if (Expressions.Nodes.Count != 0)
{ {
writer.Write("("); Writer.Write("(");
_expressions.Print(writer); Expressions.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
_typeNode.Print(writer); TypeNode.Print(Writer);
if (_initializers.Nodes.Count != 0) if (Initializers.Nodes.Count != 0)
{ {
writer.Write("("); Writer.Write("(");
_initializers.Print(writer); Initializers.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -7,14 +7,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public List<BaseNode> Nodes { get; protected set; } public List<BaseNode> Nodes { get; protected set; }
public NodeArray(List<BaseNode> nodes) : base(NodeType.NodeArray) public NodeArray(List<BaseNode> Nodes) : base(NodeType.NodeArray)
{ {
Nodes = nodes; this.Nodes = Nodes;
} }
public NodeArray(List<BaseNode> nodes, NodeType type) : base(type) public NodeArray(List<BaseNode> Nodes, NodeType Type) : base(Type)
{ {
Nodes = nodes; this.Nodes = Nodes;
} }
public override bool IsArray() public override bool IsArray()
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true; return true;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray())); Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
} }
} }
} }

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class NoexceptSpec : ParentNode public class NoexceptSpec : ParentNode
{ {
public NoexceptSpec(BaseNode child) : base(NodeType.NoexceptSpec, child) { } public NoexceptSpec(BaseNode Child) : base(NodeType.NoexceptSpec, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("noexcept("); Writer.Write("noexcept(");
Child.Print(writer); Child.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PackedTemplateParameter : NodeArray public class PackedTemplateParameter : NodeArray
{ {
public PackedTemplateParameter(List<BaseNode> nodes) : base(nodes, NodeType.PackedTemplateParameter) { } public PackedTemplateParameter(List<BaseNode> Nodes) : base(Nodes, NodeType.PackedTemplateParameter) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
foreach (BaseNode node in Nodes) foreach (BaseNode Node in Nodes)
{ {
node.PrintLeft(writer); Node.PrintLeft(Writer);
} }
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
foreach (BaseNode node in Nodes) foreach (BaseNode Node in Nodes)
{ {
node.PrintLeft(writer); Node.PrintLeft(Writer);
} }
} }
public override bool HasRightPart() public override bool HasRightPart()
{ {
foreach (BaseNode node in Nodes) foreach (BaseNode Node in Nodes)
{ {
if (node.HasRightPart()) if (Node.HasRightPart())
{ {
return true; return true;
} }

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PackedTemplateParameterExpansion : ParentNode public class PackedTemplateParameterExpansion : ParentNode
{ {
public PackedTemplateParameterExpansion(BaseNode child) : base(NodeType.PackedTemplateParameterExpansion, child) {} public PackedTemplateParameterExpansion(BaseNode Child) : base(NodeType.PackedTemplateParameterExpansion, Child) {}
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (Child is PackedTemplateParameter) if (Child is PackedTemplateParameter)
{ {
if (((PackedTemplateParameter)Child).Nodes.Count != 0) if (((PackedTemplateParameter)Child).Nodes.Count != 0)
{ {
Child.Print(writer); Child.Print(Writer);
} }
} }
else else
{ {
writer.Write("..."); Writer.Write("...");
} }
} }
} }

View file

@ -2,11 +2,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public abstract class ParentNode : BaseNode public abstract class ParentNode : BaseNode
{ {
public BaseNode Child { get; } public BaseNode Child { get; private set; }
public ParentNode(NodeType type, BaseNode child) : base(type) public ParentNode(NodeType Type, BaseNode Child) : base(Type)
{ {
Child = child; this.Child = Child;
} }
public override string GetName() public override string GetName()

View file

@ -4,42 +4,42 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PointerType : BaseNode public class PointerType : BaseNode
{ {
private BaseNode _child; private BaseNode Child;
public PointerType(BaseNode child) : base(NodeType.PointerType) public PointerType(BaseNode Child) : base(NodeType.PointerType)
{ {
_child = child; this.Child = Child;
} }
public override bool HasRightPart() public override bool HasRightPart()
{ {
return _child.HasRightPart(); return Child.HasRightPart();
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_child.PrintLeft(writer); Child.PrintLeft(Writer);
if (_child.IsArray()) if (Child.IsArray())
{ {
writer.Write(" "); Writer.Write(" ");
} }
if (_child.IsArray() || _child.HasFunctions()) if (Child.IsArray() || Child.HasFunctions())
{ {
writer.Write("("); Writer.Write("(");
} }
writer.Write("*"); Writer.Write("*");
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
if (_child.IsArray() || _child.HasFunctions()) if (Child.IsArray() || Child.HasFunctions())
{ {
writer.Write(")"); Writer.Write(")");
} }
_child.PrintRight(writer); Child.PrintRight(Writer);
} }
} }
} }

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PostfixExpression : ParentNode public class PostfixExpression : ParentNode
{ {
private string _operator; private string Operator;
public PostfixExpression(BaseNode type, string Operator) : base(NodeType.PostfixExpression, type) public PostfixExpression(BaseNode Type, string Operator) : base(NodeType.PostfixExpression, Type)
{ {
_operator = Operator; this.Operator = Operator;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("("); Writer.Write("(");
Child.Print(writer); Child.Print(Writer);
writer.Write(")"); Writer.Write(")");
writer.Write(_operator); Writer.Write(Operator);
} }
} }
} }

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PostfixQualifiedType : ParentNode public class PostfixQualifiedType : ParentNode
{ {
private string _postfixQualifier; private string PostfixQualifier;
public PostfixQualifiedType(string postfixQualifier, BaseNode type) : base(NodeType.PostfixQualifiedType, type) public PostfixQualifiedType(string PostfixQualifier, BaseNode Type) : base(NodeType.PostfixQualifiedType, Type)
{ {
_postfixQualifier = postfixQualifier; this.PostfixQualifier = PostfixQualifier;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
Child.Print(writer); Child.Print(Writer);
writer.Write(_postfixQualifier); Writer.Write(PostfixQualifier);
} }
} }
} }

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class PrefixExpression : ParentNode public class PrefixExpression : ParentNode
{ {
private string _prefix; private string Prefix;
public PrefixExpression(string prefix, BaseNode child) : base(NodeType.PrefixExpression, child) public PrefixExpression(string Prefix, BaseNode Child) : base(NodeType.PrefixExpression, Child)
{ {
_prefix = prefix; this.Prefix = Prefix;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_prefix); Writer.Write(Prefix);
writer.Write("("); Writer.Write("(");
Child.Print(writer); Child.Print(Writer);
writer.Write(")"); Writer.Write(")");
} }
} }
} }

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class QualifiedName : BaseNode public class QualifiedName : BaseNode
{ {
private BaseNode _qualifier; private BaseNode Qualifier;
private BaseNode _name; private BaseNode Name;
public QualifiedName(BaseNode qualifier, BaseNode name) : base(NodeType.QualifiedName) public QualifiedName(BaseNode Qualifier, BaseNode Name) : base(NodeType.QualifiedName)
{ {
_qualifier = qualifier; this.Qualifier = Qualifier;
_name = name; this.Name = Name;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_qualifier.Print(writer); Qualifier.Print(Writer);
writer.Write("::"); Writer.Write("::");
_name.Print(writer); Name.Print(Writer);
} }
} }
} }

View file

@ -2,7 +2,7 @@ using System.IO;
namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public enum Cv public enum CV
{ {
None, None,
Const, Const,
@ -17,41 +17,41 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
LValue LValue
} }
public class CvType : ParentNode public class CVType : ParentNode
{ {
public Cv Qualifier; public CV Qualifier;
public CvType(Cv qualifier, BaseNode child) : base(NodeType.CvQualifierType, child) public CVType(CV Qualifier, BaseNode Child) : base(NodeType.CVQualifierType, Child)
{ {
Qualifier = qualifier; this.Qualifier = Qualifier;
} }
public void PrintQualifier(TextWriter writer) public void PrintQualifier(TextWriter Writer)
{ {
if ((Qualifier & Cv.Const) != 0) if ((Qualifier & CV.Const) != 0)
{ {
writer.Write(" const"); Writer.Write(" const");
} }
if ((Qualifier & Cv.Volatile) != 0) if ((Qualifier & CV.Volatile) != 0)
{ {
writer.Write(" volatile"); Writer.Write(" volatile");
} }
if ((Qualifier & Cv.Restricted) != 0) if ((Qualifier & CV.Restricted) != 0)
{ {
writer.Write(" restrict"); Writer.Write(" restrict");
} }
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (Child != null) if (Child != null)
{ {
Child.PrintLeft(writer); Child.PrintLeft(Writer);
} }
PrintQualifier(writer); PrintQualifier(Writer);
} }
public override bool HasRightPart() public override bool HasRightPart()
@ -59,11 +59,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart(); return Child != null && Child.HasRightPart();
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
if (Child != null) if (Child != null)
{ {
Child.PrintRight(writer); Child.PrintRight(Writer);
} }
} }
} }
@ -72,36 +72,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public Reference Qualifier; public Reference Qualifier;
public SimpleReferenceType(Reference qualifier, BaseNode child) : base(NodeType.SimpleReferenceType, child) public SimpleReferenceType(Reference Qualifier, BaseNode Child) : base(NodeType.SimpleReferenceType, Child)
{ {
Qualifier = qualifier; this.Qualifier = Qualifier;
} }
public void PrintQualifier(TextWriter writer) public void PrintQualifier(TextWriter Writer)
{ {
if ((Qualifier & Reference.LValue) != 0) if ((Qualifier & Reference.LValue) != 0)
{ {
writer.Write("&"); Writer.Write("&");
} }
if ((Qualifier & Reference.RValue) != 0) if ((Qualifier & Reference.RValue) != 0)
{ {
writer.Write("&&"); Writer.Write("&&");
} }
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (Child != null) if (Child != null)
{ {
Child.PrintLeft(writer); Child.PrintLeft(Writer);
} }
else if (Qualifier != Reference.None) else if (Qualifier != Reference.None)
{ {
writer.Write(" "); Writer.Write(" ");
} }
PrintQualifier(writer); PrintQualifier(Writer);
} }
public override bool HasRightPart() public override bool HasRightPart()
@ -109,11 +109,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart(); return Child != null && Child.HasRightPart();
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
if (Child != null) if (Child != null)
{ {
Child.PrintRight(writer); Child.PrintRight(Writer);
} }
} }
} }

View file

@ -4,44 +4,44 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ReferenceType : BaseNode public class ReferenceType : BaseNode
{ {
private string _reference; private string Reference;
private BaseNode _child; private BaseNode Child;
public ReferenceType(string reference, BaseNode child) : base(NodeType.ReferenceType) public ReferenceType(string Reference, BaseNode Child) : base(NodeType.ReferenceType)
{ {
_reference = reference; this.Reference = Reference;
_child = child; this.Child = Child;
} }
public override bool HasRightPart() public override bool HasRightPart()
{ {
return _child.HasRightPart(); return Child.HasRightPart();
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
_child.PrintLeft(writer); Child.PrintLeft(Writer);
if (_child.IsArray()) if (Child.IsArray())
{ {
writer.Write(" "); Writer.Write(" ");
} }
if (_child.IsArray() || _child.HasFunctions()) if (Child.IsArray() || Child.HasFunctions())
{ {
writer.Write("("); Writer.Write("(");
} }
writer.Write(_reference); Writer.Write(Reference);
} }
public override void PrintRight(TextWriter writer) public override void PrintRight(TextWriter Writer)
{ {
if (_child.IsArray() || _child.HasFunctions()) if (Child.IsArray() || Child.HasFunctions())
{ {
writer.Write(")"); Writer.Write(")");
} }
_child.PrintRight(writer); Child.PrintRight(Writer);
} }
} }
} }

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class SpecialName : ParentNode public class SpecialName : ParentNode
{ {
private string _specialValue; private string SpecialValue;
public SpecialName(string specialValue, BaseNode type) : base(NodeType.SpecialName, type) public SpecialName(string SpecialValue, BaseNode Type) : base(NodeType.SpecialName, Type)
{ {
_specialValue = specialValue; this.SpecialValue = SpecialValue;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write(_specialValue); Writer.Write(SpecialValue);
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -11,14 +11,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
String, String,
IStream, IStream,
OStream, OStream,
IOStream IOStream,
} }
private SpecialType _specialSubstitutionKey; private SpecialType SpecialSubstitutionKey;
public SpecialSubstitution(SpecialType specialSubstitutionKey) : base(NodeType.SpecialSubstitution) public SpecialSubstitution(SpecialType SpecialSubstitutionKey) : base(NodeType.SpecialSubstitution)
{ {
_specialSubstitutionKey = specialSubstitutionKey; this.SpecialSubstitutionKey = SpecialSubstitutionKey;
} }
public void SetExtended() public void SetExtended()
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
public override string GetName() public override string GetName()
{ {
switch (_specialSubstitutionKey) switch (SpecialSubstitutionKey)
{ {
case SpecialType.Allocator: case SpecialType.Allocator:
return "allocator"; return "allocator";
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
private string GetExtendedName() private string GetExtendedName()
{ {
switch (_specialSubstitutionKey) switch (SpecialSubstitutionKey)
{ {
case SpecialType.Allocator: case SpecialType.Allocator:
return "std::allocator"; return "std::allocator";
@ -73,16 +73,16 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null; return null;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
if (Type == NodeType.ExpandedSpecialSubstitution) if (Type == NodeType.ExpandedSpecialSubstitution)
{ {
writer.Write(GetExtendedName()); Writer.Write(GetExtendedName());
} }
else else
{ {
writer.Write("std::"); Writer.Write("std::");
writer.Write(GetName()); Writer.Write(GetName());
} }
} }
} }

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class StdQualifiedName : ParentNode public class StdQualifiedName : ParentNode
{ {
public StdQualifiedName(BaseNode child) : base(NodeType.StdQualifiedName, child) { } public StdQualifiedName(BaseNode Child) : base(NodeType.StdQualifiedName, Child) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("std::"); Writer.Write("std::");
Child.Print(writer); Child.Print(Writer);
} }
} }
} }

View file

@ -5,22 +5,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class TemplateArguments : NodeArray public class TemplateArguments : NodeArray
{ {
public TemplateArguments(List<BaseNode> nodes) : base(nodes, NodeType.TemplateArguments) { } public TemplateArguments(List<BaseNode> Nodes) : base(Nodes, NodeType.TemplateArguments) { }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
string Params = string.Join<BaseNode>(", ", Nodes.ToArray()); string Params = string.Join<BaseNode>(", ", Nodes.ToArray());
writer.Write("<"); Writer.Write("<");
writer.Write(Params); Writer.Write(Params);
if (Params.EndsWith(">")) if (Params.EndsWith(">"))
{ {
writer.Write(" "); Writer.Write(" ");
} }
writer.Write(">"); Writer.Write(">");
} }
} }
} }

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ThrowExpression : BaseNode public class ThrowExpression : BaseNode
{ {
private BaseNode _expression; private BaseNode Expression;
public ThrowExpression(BaseNode expression) : base(NodeType.ThrowExpression) public ThrowExpression(BaseNode Expression) : base(NodeType.ThrowExpression)
{ {
_expression = expression; this.Expression = Expression;
} }
public override void PrintLeft(TextWriter writer) public override void PrintLeft(TextWriter Writer)
{ {
writer.Write("throw "); Writer.Write("throw ");
_expression.Print(writer); Expression.Print(Writer);
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,9 @@ namespace Ryujinx.HLE.HOS
{ {
static class ErrorCode static class ErrorCode
{ {
public static uint MakeError(ErrorModule module, int code) public static uint MakeError(ErrorModule Module, int Code)
{ {
return (uint)module | ((uint)code << 9); return (uint)Module | ((uint)Code << 9);
} }
} }
} }

View file

@ -8,18 +8,18 @@ namespace Ryujinx.HLE.HOS
Htcs = 4, Htcs = 4,
Ncm = 5, Ncm = 5,
Dd = 6, Dd = 6,
DebugMonitor = 7, Debug_Monitor = 7,
Lr = 8, Lr = 8,
Loader = 9, Loader = 9,
IpcCommandInterface = 10, IPC_Command_Interface = 10,
Ipc = 11, IPC = 11,
Pm = 15, Pm = 15,
Ns = 16, Ns = 16,
Socket = 17, Socket = 17,
Htc = 18, Htc = 18,
NcmContent = 20, Ncm_Content = 20,
Sm = 21, Sm = 21,
RoUserland = 22, RO_Userland = 22,
SdMmc = 24, SdMmc = 24,
Ovln = 25, Ovln = 25,
Spl = 26, Spl = 26,
@ -41,13 +41,13 @@ namespace Ryujinx.HLE.HOS
Pcie = 120, Pcie = 120,
Friends = 121, Friends = 121,
Bcat = 122, Bcat = 122,
Ssl = 123, SSL = 123,
Account = 124, Account = 124,
News = 125, News = 125,
Mii = 126, Mii = 126,
Nfc = 127, Nfc = 127,
Am = 128, Am = 128,
PlayReport = 129, Play_Report = 129,
Ahid = 130, Ahid = 130,
Qlaunch = 132, Qlaunch = 132,
Pcv = 133, Pcv = 133,
@ -64,23 +64,23 @@ namespace Ryujinx.HLE.HOS
Ec = 144, Ec = 144,
ETicket = 145, ETicket = 145,
Ngc = 146, Ngc = 146,
ErrorReport = 147, Error_Report = 147,
Apm = 148, Apm = 148,
Profiler = 150, Profiler = 150,
ErrorUpload = 151, Error_Upload = 151,
Audio = 153, Audio = 153,
Npns = 154, Npns = 154,
NpnsHttpStream = 155, Npns_Http_Stream = 155,
Arp = 157, Arp = 157,
Swkbd = 158, Swkbd = 158,
Boot = 159, Boot = 159,
NfcMifare = 161, Nfc_Mifare = 161,
UserlandAssert = 162, Userland_Assert = 162,
Fatal = 163, Fatal = 163,
NimShop = 164, Nim_Shop = 164,
Spsm = 165, Spsm = 165,
Bgtc = 167, Bgtc = 167,
UserlandCrash = 168, Userland_Crash = 168,
SRepo = 180, SRepo = 180,
Dauth = 181, Dauth = 181,
Hid = 202, Hid = 202,
@ -92,10 +92,10 @@ namespace Ryujinx.HLE.HOS
Web = 210, Web = 210,
Grc = 212, Grc = 212,
Migration = 216, Migration = 216,
MigrationLdcServer = 217, Migration_Ldc_Server = 217,
GeneralWebApplet = 800, General_Web_Applet = 800,
WifiWebAuthApplet = 809, Wifi_Web_Auth_Applet = 809,
WhitelistedApplet = 810, Whitelisted_Applet = 810,
ShopN = 811 ShopN = 811
} }
} }

View file

@ -13,116 +13,116 @@ namespace Ryujinx.HLE.HOS.Font
{ {
class SharedFontManager class SharedFontManager
{ {
private Switch _device; private Switch Device;
private long _physicalAddress; private long PhysicalAddress;
private string _fontsPath; private string FontsPath;
private struct FontInfo private struct FontInfo
{ {
public int Offset; public int Offset;
public int Size; public int Size;
public FontInfo(int offset, int size) public FontInfo(int Offset, int Size)
{ {
Offset = offset; this.Offset = Offset;
Size = size; this.Size = Size;
} }
} }
private Dictionary<SharedFontType, FontInfo> _fontData; private Dictionary<SharedFontType, FontInfo> FontData;
public SharedFontManager(Switch device, long physicalAddress) public SharedFontManager(Switch Device, long PhysicalAddress)
{ {
_physicalAddress = physicalAddress; this.PhysicalAddress = PhysicalAddress;
_device = device; this.Device = Device;
_fontsPath = Path.Combine(device.FileSystem.GetSystemPath(), "fonts"); FontsPath = Path.Combine(Device.FileSystem.GetSystemPath(), "fonts");
} }
public void EnsureInitialized(ContentManager contentManager) public void EnsureInitialized(ContentManager ContentManager)
{ {
if (_fontData == null) if (FontData == null)
{ {
_device.Memory.FillWithZeros(_physicalAddress, Horizon.FontSize); Device.Memory.FillWithZeros(PhysicalAddress, Horizon.FontSize);
uint fontOffset = 0; uint FontOffset = 0;
FontInfo CreateFont(string name) FontInfo CreateFont(string Name)
{ {
if (contentManager.TryGetFontTitle(name, out long fontTitle)) if (ContentManager.TryGetFontTitle(Name, out long FontTitle))
{ {
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, ContentType.Data); string ContentPath = ContentManager.GetInstalledContentPath(FontTitle, StorageId.NandSystem, ContentType.Data);
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath); string FontPath = Device.FileSystem.SwitchPathToSystemPath(ContentPath);
if (!string.IsNullOrWhiteSpace(fontPath)) if (!string.IsNullOrWhiteSpace(FontPath))
{ {
int fileIndex = 0; int FileIndex = 0;
//Use second file in Chinese Font title for standard //Use second file in Chinese Font title for standard
if(name == "FontChineseSimplified") if(Name == "FontChineseSimplified")
{ {
fileIndex = 1; FileIndex = 1;
} }
FileStream ncaFileStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read); FileStream NcaFileStream = new FileStream(FontPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, ncaFileStream, false); Nca Nca = new Nca(Device.System.KeySet, NcaFileStream, false);
NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Romfs romfs = new Romfs(nca.OpenSection(romfsSection.SectionNum, false, _device.System.FsIntegrityCheckLevel)); Romfs Romfs = new Romfs(Nca.OpenSection(RomfsSection.SectionNum, false, Device.System.FsIntegrityCheckLevel));
Stream fontFile = romfs.OpenFile(romfs.Files[fileIndex]); Stream FontFile = Romfs.OpenFile(Romfs.Files[FileIndex]);
byte[] data = DecryptFont(fontFile); byte[] Data = DecryptFont(FontFile);
FontInfo info = new FontInfo((int)fontOffset, data.Length); FontInfo Info = new FontInfo((int)FontOffset, Data.Length);
WriteMagicAndSize(_physicalAddress + fontOffset, data.Length); WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length);
fontOffset += 8; FontOffset += 8;
uint start = fontOffset; uint Start = FontOffset;
for (; fontOffset - start < data.Length; fontOffset++) for (; FontOffset - Start < Data.Length; FontOffset++)
{ {
_device.Memory.WriteByte(_physicalAddress + fontOffset, data[fontOffset - start]); Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]);
} }
ncaFileStream.Dispose(); NcaFileStream.Dispose();
nca.Dispose(); Nca.Dispose();
return info; return Info;
} }
} }
string fontFilePath = Path.Combine(_fontsPath, name + ".ttf"); string FontFilePath = Path.Combine(FontsPath, Name + ".ttf");
if (File.Exists(fontFilePath)) if (File.Exists(FontFilePath))
{ {
byte[] data = File.ReadAllBytes(fontFilePath); byte[] Data = File.ReadAllBytes(FontFilePath);
FontInfo info = new FontInfo((int)fontOffset, data.Length); FontInfo Info = new FontInfo((int)FontOffset, Data.Length);
WriteMagicAndSize(_physicalAddress + fontOffset, data.Length); WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length);
fontOffset += 8; FontOffset += 8;
uint start = fontOffset; uint Start = FontOffset;
for (; fontOffset - start < data.Length; fontOffset++) for (; FontOffset - Start < Data.Length; FontOffset++)
{ {
_device.Memory.WriteByte(_physicalAddress + fontOffset, data[fontOffset - start]); Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]);
} }
return info; return Info;
} }
else else
{ {
throw new InvalidSystemResourceException($"Font \"{name}.ttf\" not found. Please provide it in \"{_fontsPath}\"."); throw new InvalidSystemResourceException($"Font \"{Name}.ttf\" not found. Please provide it in \"{FontsPath}\".");
} }
} }
_fontData = new Dictionary<SharedFontType, FontInfo> FontData = new Dictionary<SharedFontType, FontInfo>()
{ {
{ SharedFontType.JapanUsEurope, CreateFont("FontStandard") }, { SharedFontType.JapanUsEurope, CreateFont("FontStandard") },
{ SharedFontType.SimplifiedChinese, CreateFont("FontChineseSimplified") }, { SharedFontType.SimplifiedChinese, CreateFont("FontChineseSimplified") },
@ -132,39 +132,39 @@ namespace Ryujinx.HLE.HOS.Font
{ SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") } { SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") }
}; };
if (fontOffset > Horizon.FontSize) if (FontOffset > Horizon.FontSize)
{ {
throw new InvalidSystemResourceException( throw new InvalidSystemResourceException(
$"The sum of all fonts size exceed the shared memory size. " + $"The sum of all fonts size exceed the shared memory size. " +
$"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. " + $"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. " +
$"(actual size: {fontOffset} bytes)."); $"(actual size: {FontOffset} bytes).");
} }
} }
} }
private void WriteMagicAndSize(long position, int size) private void WriteMagicAndSize(long Position, int Size)
{ {
const int decMagic = 0x18029a7f; const int DecMagic = 0x18029a7f;
const int key = 0x49621806; const int Key = 0x49621806;
int encryptedSize = EndianSwap.Swap32(size ^ key); int EncryptedSize = EndianSwap.Swap32(Size ^ Key);
_device.Memory.WriteInt32(position + 0, decMagic); Device.Memory.WriteInt32(Position + 0, DecMagic);
_device.Memory.WriteInt32(position + 4, encryptedSize); Device.Memory.WriteInt32(Position + 4, EncryptedSize);
} }
public int GetFontSize(SharedFontType fontType) public int GetFontSize(SharedFontType FontType)
{ {
EnsureInitialized(_device.System.ContentManager); EnsureInitialized(Device.System.ContentManager);
return _fontData[fontType].Size; return FontData[FontType].Size;
} }
public int GetSharedMemoryAddressOffset(SharedFontType fontType) public int GetSharedMemoryAddressOffset(SharedFontType FontType)
{ {
EnsureInitialized(_device.System.ContentManager); EnsureInitialized(Device.System.ContentManager);
return _fontData[fontType].Offset + 8; return FontData[FontType].Offset + 8;
} }
} }
} }

View file

@ -6,62 +6,62 @@ namespace Ryujinx.HLE.HOS
{ {
class GlobalStateTable class GlobalStateTable
{ {
private ConcurrentDictionary<KProcess, IdDictionary> _dictByProcess; private ConcurrentDictionary<KProcess, IdDictionary> DictByProcess;
public GlobalStateTable() public GlobalStateTable()
{ {
_dictByProcess = new ConcurrentDictionary<KProcess, IdDictionary>(); DictByProcess = new ConcurrentDictionary<KProcess, IdDictionary>();
} }
public bool Add(KProcess process, int id, object data) public bool Add(KProcess Process, int Id, object Data)
{ {
IdDictionary dict = _dictByProcess.GetOrAdd(process, (key) => new IdDictionary()); IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
return dict.Add(id, data); return Dict.Add(Id, Data);
} }
public int Add(KProcess process, object data) public int Add(KProcess Process, object Data)
{ {
IdDictionary dict = _dictByProcess.GetOrAdd(process, (key) => new IdDictionary()); IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
return dict.Add(data); return Dict.Add(Data);
} }
public object GetData(KProcess process, int id) public object GetData(KProcess Process, int Id)
{ {
if (_dictByProcess.TryGetValue(process, out IdDictionary dict)) if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
{ {
return dict.GetData(id); return Dict.GetData(Id);
} }
return null; return null;
} }
public T GetData<T>(KProcess process, int id) public T GetData<T>(KProcess Process, int Id)
{ {
if (_dictByProcess.TryGetValue(process, out IdDictionary dict)) if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
{ {
return dict.GetData<T>(id); return Dict.GetData<T>(Id);
} }
return default(T); return default(T);
} }
public object Delete(KProcess process, int id) public object Delete(KProcess Process, int Id)
{ {
if (_dictByProcess.TryGetValue(process, out IdDictionary dict)) if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
{ {
return dict.Delete(id); return Dict.Delete(Id);
} }
return null; return null;
} }
public ICollection<object> DeleteProcess(KProcess process) public ICollection<object> DeleteProcess(KProcess Process)
{ {
if (_dictByProcess.TryRemove(process, out IdDictionary dict)) if (DictByProcess.TryRemove(Process, out IdDictionary Dict))
{ {
return dict.Clear(); return Dict.Clear();
} }
return null; return null;

View file

@ -8,70 +8,70 @@ namespace Ryujinx.HLE.HOS
public const string TemporaryNroSuffix = ".ryu_tmp.nro"; public const string TemporaryNroSuffix = ".ryu_tmp.nro";
//http://switchbrew.org/index.php?title=Homebrew_ABI //http://switchbrew.org/index.php?title=Homebrew_ABI
public static void WriteHbAbiData(MemoryManager memory, long position, int mainThreadHandle, string switchPath) public static void WriteHbAbiData(MemoryManager Memory, long Position, int MainThreadHandle, string SwitchPath)
{ {
//MainThreadHandle. //MainThreadHandle.
WriteConfigEntry(memory, ref position, 1, 0, mainThreadHandle); WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle);
//NextLoadPath. //NextLoadPath.
WriteConfigEntry(memory, ref position, 2, 0, position + 0x200, position + 0x400); WriteConfigEntry(Memory, ref Position, 2, 0, Position + 0x200, Position + 0x400);
//Argv. //Argv.
long argvPosition = position + 0xC00; long ArgvPosition = Position + 0xC00;
memory.WriteBytes(argvPosition, Encoding.ASCII.GetBytes(switchPath + "\0")); Memory.WriteBytes(ArgvPosition, Encoding.ASCII.GetBytes(SwitchPath + "\0"));
WriteConfigEntry(memory, ref position, 5, 0, 0, argvPosition); WriteConfigEntry(Memory, ref Position, 5, 0, 0, ArgvPosition);
//AppletType. //AppletType.
WriteConfigEntry(memory, ref position, 7); WriteConfigEntry(Memory, ref Position, 7);
//EndOfList. //EndOfList.
WriteConfigEntry(memory, ref position, 0); WriteConfigEntry(Memory, ref Position, 0);
} }
private static void WriteConfigEntry( private static void WriteConfigEntry(
MemoryManager memory, MemoryManager Memory,
ref long position, ref long Position,
int key, int Key,
int flags = 0, int Flags = 0,
long value0 = 0, long Value0 = 0,
long value1 = 0) long Value1 = 0)
{ {
memory.WriteInt32(position + 0x00, key); Memory.WriteInt32(Position + 0x00, Key);
memory.WriteInt32(position + 0x04, flags); Memory.WriteInt32(Position + 0x04, Flags);
memory.WriteInt64(position + 0x08, value0); Memory.WriteInt64(Position + 0x08, Value0);
memory.WriteInt64(position + 0x10, value1); Memory.WriteInt64(Position + 0x10, Value1);
position += 0x18; Position += 0x18;
} }
public static string ReadHbAbiNextLoadPath(MemoryManager memory, long position) public static string ReadHbAbiNextLoadPath(MemoryManager Memory, long Position)
{ {
string fileName = null; string FileName = null;
while (true) while (true)
{ {
long key = memory.ReadInt64(position); long Key = Memory.ReadInt64(Position);
if (key == 2) if (Key == 2)
{ {
long value0 = memory.ReadInt64(position + 0x08); long Value0 = Memory.ReadInt64(Position + 0x08);
long value1 = memory.ReadInt64(position + 0x10); long Value1 = Memory.ReadInt64(Position + 0x10);
fileName = MemoryHelper.ReadAsciiString(memory, value0, value1 - value0); FileName = MemoryHelper.ReadAsciiString(Memory, Value0, Value1 - Value0);
break; break;
} }
else if (key == 0) else if (Key == 0)
{ {
break; break;
} }
position += 0x18; Position += 0x18;
} }
return fileName; return FileName;
} }
} }
} }

View file

@ -35,34 +35,34 @@ namespace Ryujinx.HLE.HOS
internal long PrivilegedProcessLowestId { get; set; } = 1; internal long PrivilegedProcessLowestId { get; set; } = 1;
internal long PrivilegedProcessHighestId { get; set; } = 8; internal long PrivilegedProcessHighestId { get; set; } = 8;
internal Switch Device { get; } internal Switch Device { get; private set; }
public SystemStateMgr State { get; } public SystemStateMgr State { get; private set; }
internal bool KernelInitialized { get; } internal bool KernelInitialized { get; private set; }
internal KResourceLimit ResourceLimit { get; } internal KResourceLimit ResourceLimit { get; private set; }
internal KMemoryRegionManager[] MemoryRegions { get; } internal KMemoryRegionManager[] MemoryRegions { get; private set; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; } internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; private set; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; } internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; private set; }
internal KSlabHeap UserSlabHeapPages { get; } internal KSlabHeap UserSlabHeapPages { get; private set; }
internal KCriticalSection CriticalSection { get; } internal KCriticalSection CriticalSection { get; private set; }
internal KScheduler Scheduler { get; } internal KScheduler Scheduler { get; private set; }
internal KTimeManager TimeManager { get; } internal KTimeManager TimeManager { get; private set; }
internal KSynchronization Synchronization { get; } internal KSynchronization Synchronization { get; private set; }
internal KContextIdManager ContextIdManager { get; } internal KContextIdManager ContextIdManager { get; private set; }
private long _kipId; private long KipId;
private long _processId; private long ProcessId;
private long _threadUid; private long ThreadUid;
internal CountdownEvent ThreadCounter; internal CountdownEvent ThreadCounter;
@ -72,20 +72,20 @@ namespace Ryujinx.HLE.HOS
internal bool EnableVersionChecks { get; private set; } internal bool EnableVersionChecks { get; private set; }
internal AppletStateMgr AppletState { get; } internal AppletStateMgr AppletState { get; private set; }
internal KSharedMemory HidSharedMem { get; } internal KSharedMemory HidSharedMem { get; private set; }
internal KSharedMemory FontSharedMem { get; } internal KSharedMemory FontSharedMem { get; private set; }
internal SharedFontManager Font { get; } internal SharedFontManager Font { get; private set; }
internal ContentManager ContentManager { get; } internal ContentManager ContentManager { get; private set; }
internal KEvent VsyncEvent { get; } internal KEvent VsyncEvent { get; private set; }
internal Keyset KeySet { get; private set; } internal Keyset KeySet { get; private set; }
private bool _hasStarted; private bool HasStarted;
public Nacp ControlData { get; set; } public Nacp ControlData { get; set; }
@ -93,11 +93,11 @@ namespace Ryujinx.HLE.HOS
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; } public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
internal long HidBaseAddress { get; } internal long HidBaseAddress { get; private set; }
public Horizon(Switch device) public Horizon(Switch Device)
{ {
Device = device; this.Device = Device;
State = new SystemStateMgr(); State = new SystemStateMgr();
@ -125,8 +125,8 @@ namespace Ryujinx.HLE.HOS
ContextIdManager = new KContextIdManager(); ContextIdManager = new KContextIdManager();
_kipId = InitialKipId; KipId = InitialKipId;
_processId = InitialProcessId; ProcessId = InitialProcessId;
Scheduler.StartAutoPreemptionThread(); Scheduler.StartAutoPreemptionThread();
@ -140,90 +140,90 @@ namespace Ryujinx.HLE.HOS
//Note: This is not really correct, but with HLE of services, the only memory //Note: This is not really correct, but with HLE of services, the only memory
//region used that is used is Application, so we can use the other ones for anything. //region used that is used is Application, so we can use the other ones for anything.
KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices]; KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.NvServices];
ulong hidPa = region.Address; ulong HidPa = Region.Address;
ulong fontPa = region.Address + HidSize; ulong FontPa = Region.Address + HidSize;
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase); HidBaseAddress = (long)(HidPa - DramMemoryMap.DramBase);
KPageList hidPageList = new KPageList(); KPageList HidPageList = new KPageList();
KPageList fontPageList = new KPageList(); KPageList FontPageList = new KPageList();
hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize); HidPageList .AddRange(HidPa, HidSize / KMemoryManager.PageSize);
fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize); FontPageList.AddRange(FontPa, FontSize / KMemoryManager.PageSize);
HidSharedMem = new KSharedMemory(hidPageList, 0, 0, MemoryPermission.Read); HidSharedMem = new KSharedMemory(HidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(fontPageList, 0, 0, MemoryPermission.Read); FontSharedMem = new KSharedMemory(FontPageList, 0, 0, MemoryPermission.Read);
AppletState = new AppletStateMgr(this); AppletState = new AppletStateMgr(this);
AppletState.SetFocus(true); AppletState.SetFocus(true);
Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase)); Font = new SharedFontManager(Device, (long)(FontPa - DramMemoryMap.DramBase));
VsyncEvent = new KEvent(this); VsyncEvent = new KEvent(this);
LoadKeySet(); LoadKeySet();
ContentManager = new ContentManager(device); ContentManager = new ContentManager(Device);
} }
public void LoadCart(string exeFsDir, string romFsFile = null) public void LoadCart(string ExeFsDir, string RomFsFile = null)
{ {
if (romFsFile != null) if (RomFsFile != null)
{ {
Device.FileSystem.LoadRomFs(romFsFile); Device.FileSystem.LoadRomFs(RomFsFile);
} }
string npdmFileName = Path.Combine(exeFsDir, "main.npdm"); string NpdmFileName = Path.Combine(ExeFsDir, "main.npdm");
Npdm metaData = null; Npdm MetaData = null;
if (File.Exists(npdmFileName)) if (File.Exists(NpdmFileName))
{ {
Logger.PrintInfo(LogClass.Loader, $"Loading main.npdm..."); Logger.PrintInfo(LogClass.Loader, $"Loading main.npdm...");
using (FileStream input = new FileStream(npdmFileName, FileMode.Open)) using (FileStream Input = new FileStream(NpdmFileName, FileMode.Open))
{ {
metaData = new Npdm(input); MetaData = new Npdm(Input);
} }
} }
else else
{ {
Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!"); Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
metaData = GetDefaultNpdm(); MetaData = GetDefaultNpdm();
} }
List<IExecutable> staticObjects = new List<IExecutable>(); List<IExecutable> StaticObjects = new List<IExecutable>();
void LoadNso(string searchPattern) void LoadNso(string SearchPattern)
{ {
foreach (string file in Directory.GetFiles(exeFsDir, searchPattern)) foreach (string File in Directory.GetFiles(ExeFsDir, SearchPattern))
{ {
if (Path.GetExtension(file) != string.Empty) if (Path.GetExtension(File) != string.Empty)
{ {
continue; continue;
} }
Logger.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(file)}..."); Logger.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(File)}...");
using (FileStream input = new FileStream(file, FileMode.Open)) using (FileStream Input = new FileStream(File, FileMode.Open))
{ {
NxStaticObject staticObject = new NxStaticObject(input); NxStaticObject StaticObject = new NxStaticObject(Input);
staticObjects.Add(staticObject); StaticObjects.Add(StaticObject);
} }
} }
} }
if (!metaData.Is64Bits) if (!MetaData.Is64Bits)
{ {
throw new NotImplementedException("32-bit titles are unsupported!"); throw new NotImplementedException("32-bit titles are unsupported!");
} }
CurrentTitle = metaData.Aci0.TitleId.ToString("x16"); CurrentTitle = MetaData.ACI0.TitleId.ToString("x16");
LoadNso("rtld"); LoadNso("rtld");
LoadNso("main"); LoadNso("main");
@ -232,18 +232,18 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries(); ContentManager.LoadEntries();
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray()); ProgramLoader.LoadStaticObjects(this, MetaData, StaticObjects.ToArray());
} }
public void LoadXci(string xciFile) public void LoadXci(string XciFile)
{ {
FileStream file = new FileStream(xciFile, FileMode.Open, FileAccess.Read); FileStream File = new FileStream(XciFile, FileMode.Open, FileAccess.Read);
Xci xci = new Xci(KeySet, file); Xci Xci = new Xci(KeySet, File);
(Nca mainNca, Nca controlNca) = GetXciGameData(xci); (Nca MainNca, Nca ControlNca) = GetXciGameData(Xci);
if (mainNca == null) if (MainNca == null)
{ {
Logger.PrintError(LogClass.Loader, "Unable to load XCI"); Logger.PrintError(LogClass.Loader, "Unable to load XCI");
@ -252,23 +252,23 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries(); ContentManager.LoadEntries();
LoadNca(mainNca, controlNca); LoadNca(MainNca, ControlNca);
} }
private (Nca Main, Nca Control) GetXciGameData(Xci xci) private (Nca Main, Nca Control) GetXciGameData(Xci Xci)
{ {
if (xci.SecurePartition == null) if (Xci.SecurePartition == null)
{ {
throw new InvalidDataException("Could not find XCI secure partition"); throw new InvalidDataException("Could not find XCI secure partition");
} }
Nca mainNca = null; Nca MainNca = null;
Nca patchNca = null; Nca PatchNca = null;
Nca controlNca = null; Nca ControlNca = null;
foreach (PfsFileEntry ticketEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik"))) foreach (PfsFileEntry TicketEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik")))
{ {
Ticket ticket = new Ticket(xci.SecurePartition.OpenFile(ticketEntry)); Ticket ticket = new Ticket(Xci.SecurePartition.OpenFile(TicketEntry));
if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId)) if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
{ {
@ -276,107 +276,107 @@ namespace Ryujinx.HLE.HOS
} }
} }
foreach (PfsFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) foreach (PfsFileEntry FileEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
{ {
Stream ncaStream = xci.SecurePartition.OpenFile(fileEntry); Stream NcaStream = Xci.SecurePartition.OpenFile(FileEntry);
Nca nca = new Nca(KeySet, ncaStream, true); Nca Nca = new Nca(KeySet, NcaStream, true);
if (nca.Header.ContentType == ContentType.Program) if (Nca.Header.ContentType == ContentType.Program)
{ {
if (nca.Sections.Any(x => x?.Type == SectionType.Romfs)) if (Nca.Sections.Any(x => x?.Type == SectionType.Romfs))
{ {
mainNca = nca; MainNca = Nca;
} }
else if (nca.Sections.Any(x => x?.Type == SectionType.Bktr)) else if (Nca.Sections.Any(x => x?.Type == SectionType.Bktr))
{ {
patchNca = nca; PatchNca = Nca;
} }
} }
else if (nca.Header.ContentType == ContentType.Control) else if (Nca.Header.ContentType == ContentType.Control)
{ {
controlNca = nca; ControlNca = Nca;
} }
} }
if (mainNca == null) if (MainNca == null)
{ {
Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided XCI file"); Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided XCI file");
} }
mainNca.SetBaseNca(patchNca); MainNca.SetBaseNca(PatchNca);
if (controlNca != null) if (ControlNca != null)
{ {
ReadControlData(controlNca); ReadControlData(ControlNca);
} }
if (patchNca != null) if (PatchNca != null)
{ {
patchNca.SetBaseNca(mainNca); PatchNca.SetBaseNca(MainNca);
return (patchNca, controlNca); return (PatchNca, ControlNca);
} }
return (mainNca, controlNca); return (MainNca, ControlNca);
} }
public void ReadControlData(Nca controlNca) public void ReadControlData(Nca ControlNca)
{ {
Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
byte[] controlFile = controlRomfs.GetFile("/control.nacp"); byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile));
ControlData = new Nacp(reader); ControlData = new Nacp(Reader);
} }
public void LoadNca(string ncaFile) public void LoadNca(string NcaFile)
{ {
FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read); FileStream File = new FileStream(NcaFile, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(KeySet, file, true); Nca Nca = new Nca(KeySet, File, true);
LoadNca(nca, null); LoadNca(Nca, null);
} }
public void LoadNsp(string nspFile) public void LoadNsp(string NspFile)
{ {
FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read); FileStream File = new FileStream(NspFile, FileMode.Open, FileAccess.Read);
Pfs nsp = new Pfs(file); Pfs Nsp = new Pfs(File);
PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik")); PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));
// Load title key from the NSP's ticket in case the user doesn't have a title key file // Load title key from the NSP's ticket in case the user doesn't have a title key file
if (ticketFile != null) if (TicketFile != null)
{ {
Ticket ticket = new Ticket(nsp.OpenFile(ticketFile)); Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));
KeySet.TitleKeys[ticket.RightsId] = ticket.GetTitleKey(KeySet); KeySet.TitleKeys[Ticket.RightsId] = Ticket.GetTitleKey(KeySet);
} }
Nca mainNca = null; Nca MainNca = null;
Nca controlNca = null; Nca ControlNca = null;
foreach (PfsFileEntry ncaFile in nsp.Files.Where(x => x.Name.EndsWith(".nca"))) foreach (PfsFileEntry NcaFile in Nsp.Files.Where(x => x.Name.EndsWith(".nca")))
{ {
Nca nca = new Nca(KeySet, nsp.OpenFile(ncaFile), true); Nca Nca = new Nca(KeySet, Nsp.OpenFile(NcaFile), true);
if (nca.Header.ContentType == ContentType.Program) if (Nca.Header.ContentType == ContentType.Program)
{ {
mainNca = nca; MainNca = Nca;
} }
else if (nca.Header.ContentType == ContentType.Control) else if (Nca.Header.ContentType == ContentType.Control)
{ {
controlNca = nca; ControlNca = Nca;
} }
} }
if (mainNca != null) if (MainNca != null)
{ {
LoadNca(mainNca, controlNca); LoadNca(MainNca, ControlNca);
return; return;
} }
@ -384,100 +384,100 @@ namespace Ryujinx.HLE.HOS
Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file"); Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
} }
public void LoadNca(Nca mainNca, Nca controlNca) public void LoadNca(Nca MainNca, Nca ControlNca)
{ {
if (mainNca.Header.ContentType != ContentType.Program) if (MainNca.Header.ContentType != ContentType.Program)
{ {
Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA"); Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");
return; return;
} }
Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel); Stream RomfsStream = MainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel); Stream ExefsStream = MainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);
if (exefsStream == null) if (ExefsStream == null)
{ {
Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA"); Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");
return; return;
} }
if (romfsStream == null) if (RomfsStream == null)
{ {
Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA"); Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
} }
else else
{ {
Device.FileSystem.SetRomFs(romfsStream); Device.FileSystem.SetRomFs(RomfsStream);
} }
Pfs exefs = new Pfs(exefsStream); Pfs Exefs = new Pfs(ExefsStream);
Npdm metaData = null; Npdm MetaData = null;
if (exefs.FileExists("main.npdm")) if (Exefs.FileExists("main.npdm"))
{ {
Logger.PrintInfo(LogClass.Loader, "Loading main.npdm..."); Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");
metaData = new Npdm(exefs.OpenFile("main.npdm")); MetaData = new Npdm(Exefs.OpenFile("main.npdm"));
} }
else else
{ {
Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!"); Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
metaData = GetDefaultNpdm(); MetaData = GetDefaultNpdm();
} }
List<IExecutable> staticObjects = new List<IExecutable>(); List<IExecutable> StaticObjects = new List<IExecutable>();
void LoadNso(string filename) void LoadNso(string Filename)
{ {
foreach (PfsFileEntry file in exefs.Files.Where(x => x.Name.StartsWith(filename))) foreach (PfsFileEntry File in Exefs.Files.Where(x => x.Name.StartsWith(Filename)))
{ {
if (Path.GetExtension(file.Name) != string.Empty) if (Path.GetExtension(File.Name) != string.Empty)
{ {
continue; continue;
} }
Logger.PrintInfo(LogClass.Loader, $"Loading {filename}..."); Logger.PrintInfo(LogClass.Loader, $"Loading {Filename}...");
NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file)); NxStaticObject StaticObject = new NxStaticObject(Exefs.OpenFile(File));
staticObjects.Add(staticObject); StaticObjects.Add(StaticObject);
} }
} }
Nacp ReadControlData() Nacp ReadControlData()
{ {
Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
byte[] controlFile = controlRomfs.GetFile("/control.nacp"); byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile));
Nacp controlData = new Nacp(reader); Nacp ControlData = new Nacp(Reader);
CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title; CurrentTitle = ControlData.Languages[(int)State.DesiredTitleLanguage].Title;
if (string.IsNullOrWhiteSpace(CurrentTitle)) if (string.IsNullOrWhiteSpace(CurrentTitle))
{ {
CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; CurrentTitle = ControlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
} }
return controlData; return ControlData;
} }
if (controlNca != null) if (ControlNca != null)
{ {
ReadControlData(); ReadControlData();
} }
else else
{ {
CurrentTitle = metaData.Aci0.TitleId.ToString("x16"); CurrentTitle = MetaData.ACI0.TitleId.ToString("x16");
} }
if (!metaData.Is64Bits) if (!MetaData.Is64Bits)
{ {
throw new NotImplementedException("32-bit titles are not supported!"); throw new NotImplementedException("32-bit titles are not supported!");
} }
@ -489,67 +489,67 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries(); ContentManager.LoadEntries();
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray()); ProgramLoader.LoadStaticObjects(this, MetaData, StaticObjects.ToArray());
} }
public void LoadProgram(string filePath) public void LoadProgram(string FilePath)
{ {
Npdm metaData = GetDefaultNpdm(); Npdm MetaData = GetDefaultNpdm();
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro"; bool IsNro = Path.GetExtension(FilePath).ToLower() == ".nro";
using (FileStream input = new FileStream(filePath, FileMode.Open)) using (FileStream Input = new FileStream(FilePath, FileMode.Open))
{ {
IExecutable staticObject = isNro IExecutable StaticObject = IsNro
? (IExecutable)new NxRelocatableObject(input) ? (IExecutable)new NxRelocatableObject(Input)
: new NxStaticObject(input); : (IExecutable)new NxStaticObject(Input);
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject }); ProgramLoader.LoadStaticObjects(this, MetaData, new IExecutable[] { StaticObject });
} }
} }
private Npdm GetDefaultNpdm() private Npdm GetDefaultNpdm()
{ {
Assembly asm = Assembly.GetCallingAssembly(); Assembly Asm = Assembly.GetCallingAssembly();
using (Stream npdmStream = asm.GetManifestResourceStream("Ryujinx.HLE.Homebrew.npdm")) using (Stream NpdmStream = Asm.GetManifestResourceStream("Ryujinx.HLE.Homebrew.npdm"))
{ {
return new Npdm(npdmStream); return new Npdm(NpdmStream);
} }
} }
public void LoadKeySet() public void LoadKeySet()
{ {
string keyFile = null; string KeyFile = null;
string titleKeyFile = null; string TitleKeyFile = null;
string consoleKeyFile = null; string ConsoleKeyFile = null;
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string Home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
LoadSetAtPath(Path.Combine(home, ".switch")); LoadSetAtPath(Path.Combine(Home, ".switch"));
LoadSetAtPath(Device.FileSystem.GetSystemPath()); LoadSetAtPath(Device.FileSystem.GetSystemPath());
KeySet = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile); KeySet = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile, ConsoleKeyFile);
void LoadSetAtPath(string basePath) void LoadSetAtPath(string BasePath)
{ {
string localKeyFile = Path.Combine(basePath, "prod.keys"); string LocalKeyFile = Path.Combine(BasePath, "prod.keys");
string localTitleKeyFile = Path.Combine(basePath, "title.keys"); string LocalTitleKeyFile = Path.Combine(BasePath, "title.keys");
string localConsoleKeyFile = Path.Combine(basePath, "console.keys"); string LocalConsoleKeyFile = Path.Combine(BasePath, "console.keys");
if (File.Exists(localKeyFile)) if (File.Exists(LocalKeyFile))
{ {
keyFile = localKeyFile; KeyFile = LocalKeyFile;
} }
if (File.Exists(localTitleKeyFile)) if (File.Exists(LocalTitleKeyFile))
{ {
titleKeyFile = localTitleKeyFile; TitleKeyFile = LocalTitleKeyFile;
} }
if (File.Exists(localConsoleKeyFile)) if (File.Exists(LocalConsoleKeyFile))
{ {
consoleKeyFile = localConsoleKeyFile; ConsoleKeyFile = LocalConsoleKeyFile;
} }
} }
} }
@ -561,22 +561,22 @@ namespace Ryujinx.HLE.HOS
internal long GetThreadUid() internal long GetThreadUid()
{ {
return Interlocked.Increment(ref _threadUid) - 1; return Interlocked.Increment(ref ThreadUid) - 1;
} }
internal long GetKipId() internal long GetKipId()
{ {
return Interlocked.Increment(ref _kipId) - 1; return Interlocked.Increment(ref KipId) - 1;
} }
internal long GetProcessId() internal long GetProcessId()
{ {
return Interlocked.Increment(ref _processId) - 1; return Interlocked.Increment(ref ProcessId) - 1;
} }
public void EnableMultiCoreScheduling() public void EnableMultiCoreScheduling()
{ {
if (!_hasStarted) if (!HasStarted)
{ {
Scheduler.MultiCoreScheduling = true; Scheduler.MultiCoreScheduling = true;
} }
@ -584,7 +584,7 @@ namespace Ryujinx.HLE.HOS
public void DisableMultiCoreScheduling() public void DisableMultiCoreScheduling()
{ {
if (!_hasStarted) if (!HasStarted)
{ {
Scheduler.MultiCoreScheduling = false; Scheduler.MultiCoreScheduling = false;
} }
@ -595,16 +595,16 @@ namespace Ryujinx.HLE.HOS
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool Disposing)
{ {
if (disposing) if (Disposing)
{ {
//Force all threads to exit. //Force all threads to exit.
lock (Processes) lock (Processes)
{ {
foreach (KProcess process in Processes.Values) foreach (KProcess Process in Processes.Values)
{ {
process.StopAllThreads(); Process.StopAllThreads();
} }
} }

View file

@ -6,56 +6,56 @@ namespace Ryujinx.HLE.HOS
{ {
class IdDictionary class IdDictionary
{ {
private ConcurrentDictionary<int, object> _objs; private ConcurrentDictionary<int, object> Objs;
public IdDictionary() public IdDictionary()
{ {
_objs = new ConcurrentDictionary<int, object>(); Objs = new ConcurrentDictionary<int, object>();
} }
public bool Add(int id, object data) public bool Add(int Id, object Data)
{ {
return _objs.TryAdd(id, data); return Objs.TryAdd(Id, Data);
} }
public int Add(object data) public int Add(object Data)
{ {
for (int id = 1; id < int.MaxValue; id++) for (int Id = 1; Id < int.MaxValue; Id++)
{ {
if (_objs.TryAdd(id, data)) if (Objs.TryAdd(Id, Data))
{ {
return id; return Id;
} }
} }
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
public object GetData(int id) public object GetData(int Id)
{ {
if (_objs.TryGetValue(id, out object data)) if (Objs.TryGetValue(Id, out object Data))
{ {
return data; return Data;
} }
return null; return null;
} }
public T GetData<T>(int id) public T GetData<T>(int Id)
{ {
if (_objs.TryGetValue(id, out object data) && data is T) if (Objs.TryGetValue(Id, out object Data) && Data is T)
{ {
return (T)data; return (T)Data;
} }
return default(T); return default(T);
} }
public object Delete(int id) public object Delete(int Id)
{ {
if (_objs.TryRemove(id, out object obj)) if (Objs.TryRemove(Id, out object Obj))
{ {
return obj; return Obj;
} }
return null; return null;
@ -63,11 +63,11 @@ namespace Ryujinx.HLE.HOS
public ICollection<object> Clear() public ICollection<object> Clear()
{ {
ICollection<object> values = _objs.Values; ICollection<object> Values = Objs.Values;
_objs.Clear(); Objs.Clear();
return values; return Values;
} }
} }
} }

View file

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Ipc
{ {
struct IpcBuffDesc struct IpcBuffDesc
{ {
public long Position { get; } public long Position { get; private set; }
public long Size { get; } public long Size { get; private set; }
public int Flags { get; } public int Flags { get; private set; }
public IpcBuffDesc(BinaryReader reader) public IpcBuffDesc(BinaryReader Reader)
{ {
long word0 = reader.ReadUInt32(); long Word0 = Reader.ReadUInt32();
long word1 = reader.ReadUInt32(); long Word1 = Reader.ReadUInt32();
long word2 = reader.ReadUInt32(); long Word2 = Reader.ReadUInt32();
Position = word1; Position = Word1;
Position |= (word2 << 4) & 0x0f00000000; Position |= (Word2 << 4) & 0x0f00000000;
Position |= (word2 << 34) & 0x7000000000; Position |= (Word2 << 34) & 0x7000000000;
Size = word0; Size = Word0;
Size |= (word2 << 8) & 0xf00000000; Size |= (Word2 << 8) & 0xf00000000;
Flags = (int)word2 & 3; Flags = (int)Word2 & 3;
} }
} }
} }

View file

@ -5,87 +5,87 @@ namespace Ryujinx.HLE.HOS.Ipc
{ {
class IpcHandleDesc class IpcHandleDesc
{ {
public bool HasPId { get; } public bool HasPId { get; private set; }
public long PId { get; } public long PId { get; private set; }
public int[] ToCopy { get; } public int[] ToCopy { get; private set; }
public int[] ToMove { get; } public int[] ToMove { get; private set; }
public IpcHandleDesc(BinaryReader reader) public IpcHandleDesc(BinaryReader Reader)
{ {
int word = reader.ReadInt32(); int Word = Reader.ReadInt32();
HasPId = (word & 1) != 0; HasPId = (Word & 1) != 0;
ToCopy = new int[(word >> 1) & 0xf]; ToCopy = new int[(Word >> 1) & 0xf];
ToMove = new int[(word >> 5) & 0xf]; ToMove = new int[(Word >> 5) & 0xf];
PId = HasPId ? reader.ReadInt64() : 0; PId = HasPId ? Reader.ReadInt64() : 0;
for (int index = 0; index < ToCopy.Length; index++) for (int Index = 0; Index < ToCopy.Length; Index++)
{ {
ToCopy[index] = reader.ReadInt32(); ToCopy[Index] = Reader.ReadInt32();
} }
for (int index = 0; index < ToMove.Length; index++) for (int Index = 0; Index < ToMove.Length; Index++)
{ {
ToMove[index] = reader.ReadInt32(); ToMove[Index] = Reader.ReadInt32();
} }
} }
public IpcHandleDesc(int[] copy, int[] move) public IpcHandleDesc(int[] Copy, int[] Move)
{ {
ToCopy = copy ?? throw new ArgumentNullException(nameof(copy)); ToCopy = Copy ?? throw new ArgumentNullException(nameof(Copy));
ToMove = move ?? throw new ArgumentNullException(nameof(move)); ToMove = Move ?? throw new ArgumentNullException(nameof(Move));
} }
public IpcHandleDesc(int[] copy, int[] move, long pId) : this(copy, move) public IpcHandleDesc(int[] Copy, int[] Move, long PId) : this(Copy, Move)
{ {
PId = pId; this.PId = PId;
HasPId = true; HasPId = true;
} }
public static IpcHandleDesc MakeCopy(params int[] handles) public static IpcHandleDesc MakeCopy(params int[] Handles)
{ {
return new IpcHandleDesc(handles, new int[0]); return new IpcHandleDesc(Handles, new int[0]);
} }
public static IpcHandleDesc MakeMove(params int[] handles) public static IpcHandleDesc MakeMove(params int[] Handles)
{ {
return new IpcHandleDesc(new int[0], handles); return new IpcHandleDesc(new int[0], Handles);
} }
public byte[] GetBytes() public byte[] GetBytes()
{ {
using (MemoryStream ms = new MemoryStream()) using (MemoryStream MS = new MemoryStream())
{ {
BinaryWriter writer = new BinaryWriter(ms); BinaryWriter Writer = new BinaryWriter(MS);
int word = HasPId ? 1 : 0; int Word = HasPId ? 1 : 0;
word |= (ToCopy.Length & 0xf) << 1; Word |= (ToCopy.Length & 0xf) << 1;
word |= (ToMove.Length & 0xf) << 5; Word |= (ToMove.Length & 0xf) << 5;
writer.Write(word); Writer.Write(Word);
if (HasPId) if (HasPId)
{ {
writer.Write(PId); Writer.Write((long)PId);
} }
foreach (int handle in ToCopy) foreach (int Handle in ToCopy)
{ {
writer.Write(handle); Writer.Write(Handle);
} }
foreach (int handle in ToMove) foreach (int Handle in ToMove)
{ {
writer.Write(handle); Writer.Write(Handle);
} }
return ms.ToArray(); return MS.ToArray();
} }
} }
} }

View file

@ -8,61 +8,61 @@ namespace Ryujinx.HLE.HOS.Ipc
static class IpcHandler static class IpcHandler
{ {
public static long IpcCall( public static long IpcCall(
Switch device, Switch Device,
KProcess process, KProcess Process,
MemoryManager memory, MemoryManager Memory,
KSession session, KSession Session,
IpcMessage request, IpcMessage Request,
long cmdPtr) long CmdPtr)
{ {
IpcMessage response = new IpcMessage(); IpcMessage Response = new IpcMessage();
using (MemoryStream raw = new MemoryStream(request.RawData)) using (MemoryStream Raw = new MemoryStream(Request.RawData))
{ {
BinaryReader reqReader = new BinaryReader(raw); BinaryReader ReqReader = new BinaryReader(Raw);
if (request.Type == IpcMessageType.Request || if (Request.Type == IpcMessageType.Request ||
request.Type == IpcMessageType.RequestWithContext) Request.Type == IpcMessageType.RequestWithContext)
{ {
response.Type = IpcMessageType.Response; Response.Type = IpcMessageType.Response;
using (MemoryStream resMs = new MemoryStream()) using (MemoryStream ResMS = new MemoryStream())
{ {
BinaryWriter resWriter = new BinaryWriter(resMs); BinaryWriter ResWriter = new BinaryWriter(ResMS);
ServiceCtx context = new ServiceCtx( ServiceCtx Context = new ServiceCtx(
device, Device,
process, Process,
memory, Memory,
session, Session,
request, Request,
response, Response,
reqReader, ReqReader,
resWriter); ResWriter);
session.Service.CallMethod(context); Session.Service.CallMethod(Context);
response.RawData = resMs.ToArray(); Response.RawData = ResMS.ToArray();
} }
} }
else if (request.Type == IpcMessageType.Control || else if (Request.Type == IpcMessageType.Control ||
request.Type == IpcMessageType.ControlWithContext) Request.Type == IpcMessageType.ControlWithContext)
{ {
long magic = reqReader.ReadInt64(); long Magic = ReqReader.ReadInt64();
long cmdId = reqReader.ReadInt64(); long CmdId = ReqReader.ReadInt64();
switch (cmdId) switch (CmdId)
{ {
case 0: case 0:
{ {
request = FillResponse(response, 0, session.Service.ConvertToDomain()); Request = FillResponse(Response, 0, Session.Service.ConvertToDomain());
break; break;
} }
case 3: case 3:
{ {
request = FillResponse(response, 0, 0x500); Request = FillResponse(Response, 0, 0x500);
break; break;
} }
@ -71,73 +71,73 @@ namespace Ryujinx.HLE.HOS.Ipc
case 2: case 2:
case 4: case 4:
{ {
int unknown = reqReader.ReadInt32(); int Unknown = ReqReader.ReadInt32();
if (process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success) if (Process.HandleTable.GenerateHandle(Session, out int Handle) != KernelResult.Success)
{ {
throw new InvalidOperationException("Out of handles!"); throw new InvalidOperationException("Out of handles!");
} }
response.HandleDesc = IpcHandleDesc.MakeMove(handle); Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
request = FillResponse(response, 0); Request = FillResponse(Response, 0);
break; break;
} }
default: throw new NotImplementedException(cmdId.ToString()); default: throw new NotImplementedException(CmdId.ToString());
} }
} }
else if (request.Type == IpcMessageType.CloseSession) else if (Request.Type == IpcMessageType.CloseSession)
{ {
//TODO //TODO
} }
else else
{ {
throw new NotImplementedException(request.Type.ToString()); throw new NotImplementedException(Request.Type.ToString());
} }
memory.WriteBytes(cmdPtr, response.GetBytes(cmdPtr)); Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr));
} }
return 0; return 0;
} }
private static IpcMessage FillResponse(IpcMessage response, long result, params int[] values) private static IpcMessage FillResponse(IpcMessage Response, long Result, params int[] Values)
{ {
using (MemoryStream ms = new MemoryStream()) using (MemoryStream MS = new MemoryStream())
{ {
BinaryWriter writer = new BinaryWriter(ms); BinaryWriter Writer = new BinaryWriter(MS);
foreach (int value in values) foreach (int Value in Values)
{ {
writer.Write(value); Writer.Write(Value);
} }
return FillResponse(response, result, ms.ToArray()); return FillResponse(Response, Result, MS.ToArray());
} }
} }
private static IpcMessage FillResponse(IpcMessage response, long result, byte[] data = null) private static IpcMessage FillResponse(IpcMessage Response, long Result, byte[] Data = null)
{ {
response.Type = IpcMessageType.Response; Response.Type = IpcMessageType.Response;
using (MemoryStream ms = new MemoryStream()) using (MemoryStream MS = new MemoryStream())
{ {
BinaryWriter writer = new BinaryWriter(ms); BinaryWriter Writer = new BinaryWriter(MS);
writer.Write(IpcMagic.Sfco); Writer.Write(IpcMagic.Sfco);
writer.Write(result); Writer.Write(Result);
if (data != null) if (Data != null)
{ {
writer.Write(data); Writer.Write(Data);
} }
response.RawData = ms.ToArray(); Response.RawData = MS.ToArray();
} }
return response; return Response;
} }
} }
} }

View file

@ -9,13 +9,13 @@ namespace Ryujinx.HLE.HOS.Ipc
public IpcHandleDesc HandleDesc { get; set; } public IpcHandleDesc HandleDesc { get; set; }
public List<IpcPtrBuffDesc> PtrBuff { get; } public List<IpcPtrBuffDesc> PtrBuff { get; private set; }
public List<IpcBuffDesc> SendBuff { get; } public List<IpcBuffDesc> SendBuff { get; private set; }
public List<IpcBuffDesc> ReceiveBuff { get; } public List<IpcBuffDesc> ReceiveBuff { get; private set; }
public List<IpcBuffDesc> ExchangeBuff { get; } public List<IpcBuffDesc> ExchangeBuff { get; private set; }
public List<IpcRecvListBuffDesc> RecvListBuff { get; } public List<IpcRecvListBuffDesc> RecvListBuff { get; private set; }
public List<int> ObjectIds { get; } public List<int> ObjectIds { get; private set; }
public byte[] RawData { get; set; } public byte[] RawData { get; set; }
@ -30,185 +30,183 @@ namespace Ryujinx.HLE.HOS.Ipc
ObjectIds = new List<int>(); ObjectIds = new List<int>();
} }
public IpcMessage(byte[] data, long cmdPtr) : this() public IpcMessage(byte[] Data, long CmdPtr) : this()
{ {
using (MemoryStream ms = new MemoryStream(data)) using (MemoryStream MS = new MemoryStream(Data))
{ {
BinaryReader reader = new BinaryReader(ms); BinaryReader Reader = new BinaryReader(MS);
Initialize(reader, cmdPtr); Initialize(Reader, CmdPtr);
} }
} }
private void Initialize(BinaryReader reader, long cmdPtr) private void Initialize(BinaryReader Reader, long CmdPtr)
{ {
int word0 = reader.ReadInt32(); int Word0 = Reader.ReadInt32();
int word1 = reader.ReadInt32(); int Word1 = Reader.ReadInt32();
Type = (IpcMessageType)(word0 & 0xffff); Type = (IpcMessageType)(Word0 & 0xffff);
int ptrBuffCount = (word0 >> 16) & 0xf; int PtrBuffCount = (Word0 >> 16) & 0xf;
int sendBuffCount = (word0 >> 20) & 0xf; int SendBuffCount = (Word0 >> 20) & 0xf;
int recvBuffCount = (word0 >> 24) & 0xf; int RecvBuffCount = (Word0 >> 24) & 0xf;
int xchgBuffCount = (word0 >> 28) & 0xf; int XchgBuffCount = (Word0 >> 28) & 0xf;
int rawDataSize = (word1 >> 0) & 0x3ff; int RawDataSize = (Word1 >> 0) & 0x3ff;
int recvListFlags = (word1 >> 10) & 0xf; int RecvListFlags = (Word1 >> 10) & 0xf;
bool hndDescEnable = ((word1 >> 31) & 0x1) != 0; bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
if (hndDescEnable) if (HndDescEnable)
{ {
HandleDesc = new IpcHandleDesc(reader); HandleDesc = new IpcHandleDesc(Reader);
} }
for (int index = 0; index < ptrBuffCount; index++) for (int Index = 0; Index < PtrBuffCount; Index++)
{ {
PtrBuff.Add(new IpcPtrBuffDesc(reader)); PtrBuff.Add(new IpcPtrBuffDesc(Reader));
} }
void ReadBuff(List<IpcBuffDesc> buff, int count) void ReadBuff(List<IpcBuffDesc> Buff, int Count)
{ {
for (int index = 0; index < count; index++) for (int Index = 0; Index < Count; Index++)
{ {
buff.Add(new IpcBuffDesc(reader)); Buff.Add(new IpcBuffDesc(Reader));
} }
} }
ReadBuff(SendBuff, sendBuffCount); ReadBuff(SendBuff, SendBuffCount);
ReadBuff(ReceiveBuff, recvBuffCount); ReadBuff(ReceiveBuff, RecvBuffCount);
ReadBuff(ExchangeBuff, xchgBuffCount); ReadBuff(ExchangeBuff, XchgBuffCount);
rawDataSize *= 4; RawDataSize *= 4;
long recvListPos = reader.BaseStream.Position + rawDataSize; long RecvListPos = Reader.BaseStream.Position + RawDataSize;
long pad0 = GetPadSize16(reader.BaseStream.Position + cmdPtr); long Pad0 = GetPadSize16(Reader.BaseStream.Position + CmdPtr);
reader.BaseStream.Seek(pad0, SeekOrigin.Current); Reader.BaseStream.Seek(Pad0, SeekOrigin.Current);
int recvListCount = recvListFlags - 2; int RecvListCount = RecvListFlags - 2;
if (recvListCount == 0) if (RecvListCount == 0)
{ {
recvListCount = 1; RecvListCount = 1;
} }
else if (recvListCount < 0) else if (RecvListCount < 0)
{ {
recvListCount = 0; RecvListCount = 0;
} }
RawData = reader.ReadBytes(rawDataSize); RawData = Reader.ReadBytes(RawDataSize);
reader.BaseStream.Seek(recvListPos, SeekOrigin.Begin); Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin);
for (int index = 0; index < recvListCount; index++) for (int Index = 0; Index < RecvListCount; Index++)
{ {
RecvListBuff.Add(new IpcRecvListBuffDesc(reader)); RecvListBuff.Add(new IpcRecvListBuffDesc(Reader));
} }
} }
public byte[] GetBytes(long cmdPtr) public byte[] GetBytes(long CmdPtr)
{ {
using (MemoryStream ms = new MemoryStream()) using (MemoryStream MS = new MemoryStream())
{ {
BinaryWriter writer = new BinaryWriter(ms); BinaryWriter Writer = new BinaryWriter(MS);
int word0; int Word0;
int word1; int Word1;
word0 = (int)Type; Word0 = (int)Type;
word0 |= (PtrBuff.Count & 0xf) << 16; Word0 |= (PtrBuff.Count & 0xf) << 16;
word0 |= (SendBuff.Count & 0xf) << 20; Word0 |= (SendBuff.Count & 0xf) << 20;
word0 |= (ReceiveBuff.Count & 0xf) << 24; Word0 |= (ReceiveBuff.Count & 0xf) << 24;
word0 |= (ExchangeBuff.Count & 0xf) << 28; Word0 |= (ExchangeBuff.Count & 0xf) << 28;
byte[] handleData = new byte[0]; byte[] HandleData = new byte[0];
if (HandleDesc != null) if (HandleDesc != null)
{ {
handleData = HandleDesc.GetBytes(); HandleData = HandleDesc.GetBytes();
} }
int dataLength = RawData?.Length ?? 0; int DataLength = RawData?.Length ?? 0;
int pad0 = (int)GetPadSize16(cmdPtr + 8 + handleData.Length); int Pad0 = (int)GetPadSize16(CmdPtr + 8 + HandleData.Length);
//Apparently, padding after Raw Data is 16 bytes, however when there is //Apparently, padding after Raw Data is 16 bytes, however when there is
//padding before Raw Data too, we need to subtract the size of this padding. //padding before Raw Data too, we need to subtract the size of this padding.
//This is the weirdest padding I've seen so far... //This is the weirdest padding I've seen so far...
int pad1 = 0x10 - pad0; int Pad1 = 0x10 - Pad0;
dataLength = (dataLength + pad0 + pad1) / 4; DataLength = (DataLength + Pad0 + Pad1) / 4;
word1 = dataLength & 0x3ff; Word1 = DataLength & 0x3ff;
if (HandleDesc != null) if (HandleDesc != null)
{ {
word1 |= 1 << 31; Word1 |= 1 << 31;
} }
writer.Write(word0); Writer.Write(Word0);
writer.Write(word1); Writer.Write(Word1);
writer.Write(handleData); Writer.Write(HandleData);
ms.Seek(pad0, SeekOrigin.Current); MS.Seek(Pad0, SeekOrigin.Current);
if (RawData != null) if (RawData != null)
{ {
writer.Write(RawData); Writer.Write(RawData);
} }
writer.Write(new byte[pad1]); Writer.Write(new byte[Pad1]);
return ms.ToArray(); return MS.ToArray();
} }
} }
private long GetPadSize16(long position) private long GetPadSize16(long Position)
{ {
if ((position & 0xf) != 0) if ((Position & 0xf) != 0)
{ {
return 0x10 - (position & 0xf); return 0x10 - (Position & 0xf);
} }
return 0; return 0;
} }
// ReSharper disable once InconsistentNaming public (long Position, long Size) GetBufferType0x21(int Index = 0)
public (long Position, long Size) GetBufferType0x21(int index = 0)
{ {
if (PtrBuff.Count > index && if (PtrBuff.Count > Index &&
PtrBuff[index].Position != 0 && PtrBuff[Index].Position != 0 &&
PtrBuff[index].Size != 0) PtrBuff[Index].Size != 0)
{ {
return (PtrBuff[index].Position, PtrBuff[index].Size); return (PtrBuff[Index].Position, PtrBuff[Index].Size);
} }
if (SendBuff.Count > index && if (SendBuff.Count > Index &&
SendBuff[index].Position != 0 && SendBuff[Index].Position != 0 &&
SendBuff[index].Size != 0) SendBuff[Index].Size != 0)
{ {
return (SendBuff[index].Position, SendBuff[index].Size); return (SendBuff[Index].Position, SendBuff[Index].Size);
} }
return (0, 0); return (0, 0);
} }
// ReSharper disable once InconsistentNaming public (long Position, long Size) GetBufferType0x22(int Index = 0)
public (long Position, long Size) GetBufferType0x22(int index = 0)
{ {
if (RecvListBuff.Count > index && if (RecvListBuff.Count > Index &&
RecvListBuff[index].Position != 0 && RecvListBuff[Index].Position != 0 &&
RecvListBuff[index].Size != 0) RecvListBuff[Index].Size != 0)
{ {
return (RecvListBuff[index].Position, RecvListBuff[index].Size); return (RecvListBuff[Index].Position, RecvListBuff[Index].Size);
} }
if (ReceiveBuff.Count > index && if (ReceiveBuff.Count > Index &&
ReceiveBuff[index].Position != 0 && ReceiveBuff[Index].Position != 0 &&
ReceiveBuff[index].Size != 0) ReceiveBuff[Index].Size != 0)
{ {
return (ReceiveBuff[index].Position, ReceiveBuff[index].Size); return (ReceiveBuff[Index].Position, ReceiveBuff[Index].Size);
} }
return (0, 0); return (0, 0);

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Ipc
{ {
struct IpcPtrBuffDesc struct IpcPtrBuffDesc
{ {
public long Position { get; } public long Position { get; private set; }
public int Index { get; } public int Index { get; private set; }
public long Size { get; } public long Size { get; private set; }
public IpcPtrBuffDesc(BinaryReader reader) public IpcPtrBuffDesc(BinaryReader Reader)
{ {
long word0 = reader.ReadUInt32(); long Word0 = Reader.ReadUInt32();
long word1 = reader.ReadUInt32(); long Word1 = Reader.ReadUInt32();
Position = word1; Position = Word1;
Position |= (word0 << 20) & 0x0f00000000; Position |= (Word0 << 20) & 0x0f00000000;
Position |= (word0 << 30) & 0x7000000000; Position |= (Word0 << 30) & 0x7000000000;
Index = ((int)word0 >> 0) & 0x03f; Index = ((int)Word0 >> 0) & 0x03f;
Index |= ((int)word0 >> 3) & 0x1c0; Index |= ((int)Word0 >> 3) & 0x1c0;
Size = (ushort)(word0 >> 16); Size = (ushort)(Word0 >> 16);
} }
} }
} }

View file

@ -4,16 +4,16 @@ namespace Ryujinx.HLE.HOS.Ipc
{ {
struct IpcRecvListBuffDesc struct IpcRecvListBuffDesc
{ {
public long Position { get; } public long Position { get; private set; }
public long Size { get; } public long Size { get; private set; }
public IpcRecvListBuffDesc(BinaryReader reader) public IpcRecvListBuffDesc(BinaryReader Reader)
{ {
long value = reader.ReadInt64(); long Value = Reader.ReadInt64();
Position = value & 0xffffffffffff; Position = Value & 0xffffffffffff;
Size = (ushort)(value >> 48); Size = (ushort)(Value >> 48);
} }
} }
} }

View file

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.HOS.Ipc namespace Ryujinx.HLE.HOS.Ipc
{ {
delegate long ServiceProcessRequest(ServiceCtx context); delegate long ServiceProcessRequest(ServiceCtx Context);
} }

View file

@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private class PausableThread private class PausableThread
{ {
public ManualResetEvent Event { get; } public ManualResetEvent Event { get; private set; }
public bool IsExiting { get; set; } public bool IsExiting { get; set; }
@ -17,49 +17,49 @@ namespace Ryujinx.HLE.HOS.Kernel
} }
} }
private ConcurrentDictionary<Thread, PausableThread> _threads; private ConcurrentDictionary<Thread, PausableThread> Threads;
public HleCoreManager() public HleCoreManager()
{ {
_threads = new ConcurrentDictionary<Thread, PausableThread>(); Threads = new ConcurrentDictionary<Thread, PausableThread>();
} }
public void Set(Thread thread) public void Set(Thread Thread)
{ {
GetThread(thread).Event.Set(); GetThread(Thread).Event.Set();
} }
public void Reset(Thread thread) public void Reset(Thread Thread)
{ {
GetThread(thread).Event.Reset(); GetThread(Thread).Event.Reset();
} }
public void Wait(Thread thread) public void Wait(Thread Thread)
{ {
PausableThread pausableThread = GetThread(thread); PausableThread PausableThread = GetThread(Thread);
if (!pausableThread.IsExiting) if (!PausableThread.IsExiting)
{ {
pausableThread.Event.WaitOne(); PausableThread.Event.WaitOne();
} }
} }
public void Exit(Thread thread) public void Exit(Thread Thread)
{ {
GetThread(thread).IsExiting = true; GetThread(Thread).IsExiting = true;
} }
private PausableThread GetThread(Thread thread) private PausableThread GetThread(Thread Thread)
{ {
return _threads.GetOrAdd(thread, (key) => new PausableThread()); return Threads.GetOrAdd(Thread, (Key) => new PausableThread());
} }
public void RemoveThread(Thread thread) public void RemoveThread(Thread Thread)
{ {
if (_threads.TryRemove(thread, out PausableThread pausableThread)) if (Threads.TryRemove(Thread, out PausableThread PausableThread))
{ {
pausableThread.Event.Set(); PausableThread.Event.Set();
pausableThread.Event.Dispose(); PausableThread.Event.Dispose();
} }
} }
} }

View file

@ -14,138 +14,138 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private const int Mod0 = 'M' << 0 | 'O' << 8 | 'D' << 16 | '0' << 24; private const int Mod0 = 'M' << 0 | 'O' << 8 | 'D' << 16 | '0' << 24;
private KProcess _owner; private KProcess Owner;
private class Image private class Image
{ {
public long BaseAddress { get; } public long BaseAddress { get; private set; }
public ElfSymbol[] Symbols { get; } public ElfSymbol[] Symbols { get; private set; }
public Image(long baseAddress, ElfSymbol[] symbols) public Image(long BaseAddress, ElfSymbol[] Symbols)
{ {
BaseAddress = baseAddress; this.BaseAddress = BaseAddress;
Symbols = symbols; this.Symbols = Symbols;
} }
} }
private List<Image> _images; private List<Image> Images;
private int _loaded; private int Loaded;
public HleProcessDebugger(KProcess owner) public HleProcessDebugger(KProcess Owner)
{ {
_owner = owner; this.Owner = Owner;
_images = new List<Image>(); Images = new List<Image>();
} }
public void PrintGuestStackTrace(CpuThreadState threadState) public void PrintGuestStackTrace(CpuThreadState ThreadState)
{ {
EnsureLoaded(); EnsureLoaded();
StringBuilder trace = new StringBuilder(); StringBuilder Trace = new StringBuilder();
trace.AppendLine("Guest stack trace:"); Trace.AppendLine("Guest stack trace:");
void AppendTrace(long address) void AppendTrace(long Address)
{ {
Image image = GetImage(address, out int imageIndex); Image Image = GetImage(Address, out int ImageIndex);
if (image == null || !TryGetSubName(image, address, out string subName)) if (Image == null || !TryGetSubName(Image, Address, out string SubName))
{ {
subName = $"Sub{address:x16}"; SubName = $"Sub{Address:x16}";
} }
else if (subName.StartsWith("_Z")) else if (SubName.StartsWith("_Z"))
{ {
subName = Demangler.Parse(subName); SubName = Demangler.Parse(SubName);
} }
if (image != null) if (Image != null)
{ {
long offset = address - image.BaseAddress; long Offset = Address - Image.BaseAddress;
string imageName = GetGuessedNsoNameFromIndex(imageIndex); string ImageName = GetGuessedNsoNameFromIndex(ImageIndex);
string imageNameAndOffset = $"[{_owner.Name}] {imageName}:0x{offset:x8}"; string ImageNameAndOffset = $"[{Owner.Name}] {ImageName}:0x{Offset:x8}";
trace.AppendLine($" {imageNameAndOffset} {subName}"); Trace.AppendLine($" {ImageNameAndOffset} {SubName}");
} }
else else
{ {
trace.AppendLine($" [{_owner.Name}] ??? {subName}"); Trace.AppendLine($" [{Owner.Name}] ??? {SubName}");
} }
} }
long framePointer = (long)threadState.X29; long FramePointer = (long)ThreadState.X29;
while (framePointer != 0) while (FramePointer != 0)
{ {
if ((framePointer & 7) != 0 || if ((FramePointer & 7) != 0 ||
!_owner.CpuMemory.IsMapped(framePointer) || !Owner.CpuMemory.IsMapped(FramePointer) ||
!_owner.CpuMemory.IsMapped(framePointer + 8)) !Owner.CpuMemory.IsMapped(FramePointer + 8))
{ {
break; break;
} }
//Note: This is the return address, we need to subtract one instruction //Note: This is the return address, we need to subtract one instruction
//worth of bytes to get the branch instruction address. //worth of bytes to get the branch instruction address.
AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4); AppendTrace(Owner.CpuMemory.ReadInt64(FramePointer + 8) - 4);
framePointer = _owner.CpuMemory.ReadInt64(framePointer); FramePointer = Owner.CpuMemory.ReadInt64(FramePointer);
} }
Logger.PrintInfo(LogClass.Cpu, trace.ToString()); Logger.PrintInfo(LogClass.Cpu, Trace.ToString());
} }
private bool TryGetSubName(Image image, long address, out string name) private bool TryGetSubName(Image Image, long Address, out string Name)
{ {
address -= image.BaseAddress; Address -= Image.BaseAddress;
int left = 0; int Left = 0;
int right = image.Symbols.Length - 1; int Right = Image.Symbols.Length - 1;
while (left <= right) while (Left <= Right)
{ {
int size = right - left; int Size = Right - Left;
int middle = left + (size >> 1); int Middle = Left + (Size >> 1);
ElfSymbol symbol = image.Symbols[middle]; ElfSymbol Symbol = Image.Symbols[Middle];
long endAddr = symbol.Value + symbol.Size; long EndAddr = Symbol.Value + Symbol.Size;
if ((ulong)address >= (ulong)symbol.Value && (ulong)address < (ulong)endAddr) if ((ulong)Address >= (ulong)Symbol.Value && (ulong)Address < (ulong)EndAddr)
{ {
name = symbol.Name; Name = Symbol.Name;
return true; return true;
} }
if ((ulong)address < (ulong)symbol.Value) if ((ulong)Address < (ulong)Symbol.Value)
{ {
right = middle - 1; Right = Middle - 1;
} }
else else
{ {
left = middle + 1; Left = Middle + 1;
} }
} }
name = null; Name = null;
return false; return false;
} }
private Image GetImage(long address, out int index) private Image GetImage(long Address, out int Index)
{ {
lock (_images) lock (Images)
{ {
for (index = _images.Count - 1; index >= 0; index--) for (Index = Images.Count - 1; Index >= 0; Index--)
{ {
if ((ulong)address >= (ulong)_images[index].BaseAddress) if ((ulong)Address >= (ulong)Images[Index].BaseAddress)
{ {
return _images[index]; return Images[Index];
} }
} }
} }
@ -153,42 +153,42 @@ namespace Ryujinx.HLE.HOS.Kernel
return null; return null;
} }
private string GetGuessedNsoNameFromIndex(int index) private string GetGuessedNsoNameFromIndex(int Index)
{ {
if ((uint)index > 11) if ((uint)Index > 11)
{ {
return "???"; return "???";
} }
if (index == 0) if (Index == 0)
{ {
return "rtld"; return "rtld";
} }
else if (index == 1) else if (Index == 1)
{ {
return "main"; return "main";
} }
else if (index == GetImagesCount() - 1) else if (Index == GetImagesCount() - 1)
{ {
return "sdk"; return "sdk";
} }
else else
{ {
return "subsdk" + (index - 2); return "subsdk" + (Index - 2);
} }
} }
private int GetImagesCount() private int GetImagesCount()
{ {
lock (_images) lock (Images)
{ {
return _images.Count; return Images.Count;
} }
} }
private void EnsureLoaded() private void EnsureLoaded()
{ {
if (Interlocked.CompareExchange(ref _loaded, 1, 0) == 0) if (Interlocked.CompareExchange(ref Loaded, 1, 0) == 0)
{ {
ScanMemoryForTextSegments(); ScanMemoryForTextSegments();
} }
@ -196,115 +196,115 @@ namespace Ryujinx.HLE.HOS.Kernel
private void ScanMemoryForTextSegments() private void ScanMemoryForTextSegments()
{ {
ulong oldAddress = 0; ulong OldAddress = 0;
ulong address = 0; ulong Address = 0;
while (address >= oldAddress) while (Address >= OldAddress)
{ {
KMemoryInfo info = _owner.MemoryManager.QueryMemory(address); KMemoryInfo Info = Owner.MemoryManager.QueryMemory(Address);
if (info.State == MemoryState.Reserved) if (Info.State == MemoryState.Reserved)
{ {
break; break;
} }
if (info.State == MemoryState.CodeStatic && info.Permission == MemoryPermission.ReadAndExecute) if (Info.State == MemoryState.CodeStatic && Info.Permission == MemoryPermission.ReadAndExecute)
{ {
LoadMod0Symbols(_owner.CpuMemory, (long)info.Address); LoadMod0Symbols(Owner.CpuMemory, (long)Info.Address);
} }
oldAddress = address; OldAddress = Address;
address = info.Address + info.Size; Address = Info.Address + Info.Size;
} }
} }
private void LoadMod0Symbols(MemoryManager memory, long textOffset) private void LoadMod0Symbols(MemoryManager Memory, long TextOffset)
{ {
long mod0Offset = textOffset + memory.ReadUInt32(textOffset + 4); long Mod0Offset = TextOffset + Memory.ReadUInt32(TextOffset + 4);
if (mod0Offset < textOffset || !memory.IsMapped(mod0Offset) || (mod0Offset & 3) != 0) if (Mod0Offset < TextOffset || !Memory.IsMapped(Mod0Offset) || (Mod0Offset & 3) != 0)
{ {
return; return;
} }
Dictionary<ElfDynamicTag, long> dynamic = new Dictionary<ElfDynamicTag, long>(); Dictionary<ElfDynamicTag, long> Dynamic = new Dictionary<ElfDynamicTag, long>();
int mod0Magic = memory.ReadInt32(mod0Offset + 0x0); int Mod0Magic = Memory.ReadInt32(Mod0Offset + 0x0);
if (mod0Magic != Mod0) if (Mod0Magic != Mod0)
{ {
return; return;
} }
long dynamicOffset = memory.ReadInt32(mod0Offset + 0x4) + mod0Offset; long DynamicOffset = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
long bssStartOffset = memory.ReadInt32(mod0Offset + 0x8) + mod0Offset; long BssStartOffset = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
long bssEndOffset = memory.ReadInt32(mod0Offset + 0xc) + mod0Offset; long BssEndOffset = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
long ehHdrStartOffset = memory.ReadInt32(mod0Offset + 0x10) + mod0Offset; long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
long ehHdrEndOffset = memory.ReadInt32(mod0Offset + 0x14) + mod0Offset; long EhHdrEndOffset = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
long modObjOffset = memory.ReadInt32(mod0Offset + 0x18) + mod0Offset; long ModObjOffset = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;
while (true) while (true)
{ {
long tagVal = memory.ReadInt64(dynamicOffset + 0); long TagVal = Memory.ReadInt64(DynamicOffset + 0);
long value = memory.ReadInt64(dynamicOffset + 8); long Value = Memory.ReadInt64(DynamicOffset + 8);
dynamicOffset += 0x10; DynamicOffset += 0x10;
ElfDynamicTag tag = (ElfDynamicTag)tagVal; ElfDynamicTag Tag = (ElfDynamicTag)TagVal;
if (tag == ElfDynamicTag.DT_NULL) if (Tag == ElfDynamicTag.DT_NULL)
{ {
break; break;
} }
dynamic[tag] = value; Dynamic[Tag] = Value;
} }
if (!dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long strTab) || if (!Dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long StrTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long symTab) || !Dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long SymTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long symEntSize)) !Dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long SymEntSize))
{ {
return; return;
} }
long strTblAddr = textOffset + strTab; long StrTblAddr = TextOffset + StrTab;
long symTblAddr = textOffset + symTab; long SymTblAddr = TextOffset + SymTab;
List<ElfSymbol> symbols = new List<ElfSymbol>(); List<ElfSymbol> Symbols = new List<ElfSymbol>();
while ((ulong)symTblAddr < (ulong)strTblAddr) while ((ulong)SymTblAddr < (ulong)StrTblAddr)
{ {
ElfSymbol sym = GetSymbol(memory, symTblAddr, strTblAddr); ElfSymbol Sym = GetSymbol(Memory, SymTblAddr, StrTblAddr);
symbols.Add(sym); Symbols.Add(Sym);
symTblAddr += symEntSize; SymTblAddr += SymEntSize;
} }
lock (_images) lock (Images)
{ {
_images.Add(new Image(textOffset, symbols.OrderBy(x => x.Value).ToArray())); Images.Add(new Image(TextOffset, Symbols.OrderBy(x => x.Value).ToArray()));
} }
} }
private ElfSymbol GetSymbol(MemoryManager memory, long address, long strTblAddr) private ElfSymbol GetSymbol(MemoryManager Memory, long Address, long StrTblAddr)
{ {
int nameIndex = memory.ReadInt32(address + 0); int NameIndex = Memory.ReadInt32(Address + 0);
int info = memory.ReadByte (address + 4); int Info = Memory.ReadByte (Address + 4);
int other = memory.ReadByte (address + 5); int Other = Memory.ReadByte (Address + 5);
int shIdx = memory.ReadInt16(address + 6); int SHIdx = Memory.ReadInt16(Address + 6);
long value = memory.ReadInt64(address + 8); long Value = Memory.ReadInt64(Address + 8);
long size = memory.ReadInt64(address + 16); long Size = Memory.ReadInt64(Address + 16);
string name = string.Empty; string Name = string.Empty;
for (int chr; (chr = memory.ReadByte(strTblAddr + nameIndex++)) != 0;) for (int Chr; (Chr = Memory.ReadByte(StrTblAddr + NameIndex++)) != 0;)
{ {
name += (char)chr; Name += (char)Chr;
} }
return new ElfSymbol(name, info, other, shIdx, value, size); return new ElfSymbol(Name, Info, Other, SHIdx, Value, Size);
} }
} }
} }

View file

@ -7,21 +7,21 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private const int RoundRobinTimeQuantumMs = 10; private const int RoundRobinTimeQuantumMs = 10;
private int _currentCore; private int CurrentCore;
public bool MultiCoreScheduling { get; set; } public bool MultiCoreScheduling { get; set; }
public HleCoreManager CoreManager { get; } public HleCoreManager CoreManager { get; private set; }
private bool _keepPreempting; private bool KeepPreempting;
public void StartAutoPreemptionThread() public void StartAutoPreemptionThread()
{ {
Thread preemptionThread = new Thread(PreemptCurrentThread); Thread PreemptionThread = new Thread(PreemptCurrentThread);
_keepPreempting = true; KeepPreempting = true;
preemptionThread.Start(); PreemptionThread.Start();
} }
public void ContextSwitch() public void ContextSwitch()
@ -30,28 +30,28 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
if (MultiCoreScheduling) if (MultiCoreScheduling)
{ {
int selectedCount = 0; int SelectedCount = 0;
for (int core = 0; core < CpuCoresCount; core++) for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
{ {
KCoreContext coreContext = CoreContexts[core]; KCoreContext CoreContext = CoreContexts[Core];
if (coreContext.ContextSwitchNeeded && (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false)) if (CoreContext.ContextSwitchNeeded && (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false))
{ {
coreContext.ContextSwitch(); CoreContext.ContextSwitch();
} }
if (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false) if (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false)
{ {
selectedCount++; SelectedCount++;
} }
} }
if (selectedCount == 0) if (SelectedCount == 0)
{ {
CoreManager.Reset(Thread.CurrentThread); CoreManager.Reset(Thread.CurrentThread);
} }
else if (selectedCount == 1) else if (SelectedCount == 1)
{ {
CoreManager.Set(Thread.CurrentThread); CoreManager.Set(Thread.CurrentThread);
} }
@ -62,41 +62,41 @@ namespace Ryujinx.HLE.HOS.Kernel
} }
else else
{ {
KThread currentThread = CoreContexts[_currentCore].CurrentThread; KThread CurrentThread = CoreContexts[CurrentCore].CurrentThread;
bool hasThreadExecuting = currentThread != null; bool HasThreadExecuting = CurrentThread != null;
if (hasThreadExecuting) if (HasThreadExecuting)
{ {
//If this is not the thread that is currently executing, we need //If this is not the thread that is currently executing, we need
//to request an interrupt to allow safely starting another thread. //to request an interrupt to allow safely starting another thread.
if (!currentThread.Context.IsCurrentThread()) if (!CurrentThread.Context.IsCurrentThread())
{ {
currentThread.Context.RequestInterrupt(); CurrentThread.Context.RequestInterrupt();
return; return;
} }
CoreManager.Reset(currentThread.Context.Work); CoreManager.Reset(CurrentThread.Context.Work);
} }
//Advance current core and try picking a thread, //Advance current core and try picking a thread,
//keep advancing if it is null. //keep advancing if it is null.
for (int core = 0; core < 4; core++) for (int Core = 0; Core < 4; Core++)
{ {
_currentCore = (_currentCore + 1) % CpuCoresCount; CurrentCore = (CurrentCore + 1) % CpuCoresCount;
KCoreContext coreContext = CoreContexts[_currentCore]; KCoreContext CoreContext = CoreContexts[CurrentCore];
coreContext.UpdateCurrentThread(); CoreContext.UpdateCurrentThread();
if (coreContext.CurrentThread != null) if (CoreContext.CurrentThread != null)
{ {
coreContext.CurrentThread.ClearExclusive(); CoreContext.CurrentThread.ClearExclusive();
CoreManager.Set(coreContext.CurrentThread.Context.Work); CoreManager.Set(CoreContext.CurrentThread.Context.Work);
coreContext.CurrentThread.Context.Execute(); CoreContext.CurrentThread.Context.Execute();
break; break;
} }
@ -104,7 +104,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//If nothing was running before, then we are on a "external" //If nothing was running before, then we are on a "external"
//HLE thread, we don't need to wait. //HLE thread, we don't need to wait.
if (!hasThreadExecuting) if (!HasThreadExecuting)
{ {
return; return;
} }
@ -119,13 +119,13 @@ namespace Ryujinx.HLE.HOS.Kernel
//Preempts current thread every 10 milliseconds on a round-robin fashion, //Preempts current thread every 10 milliseconds on a round-robin fashion,
//when multi core scheduling is disabled, to try ensuring that all threads //when multi core scheduling is disabled, to try ensuring that all threads
//gets a chance to run. //gets a chance to run.
while (_keepPreempting) while (KeepPreempting)
{ {
lock (CoreContexts) lock (CoreContexts)
{ {
KThread currentThread = CoreContexts[_currentCore].CurrentThread; KThread CurrentThread = CoreContexts[CurrentCore].CurrentThread;
currentThread?.Context.RequestInterrupt(); CurrentThread?.Context.RequestInterrupt();
} }
PreemptThreads(); PreemptThreads();
@ -134,16 +134,16 @@ namespace Ryujinx.HLE.HOS.Kernel
} }
} }
public void ExitThread(KThread thread) public void ExitThread(KThread Thread)
{ {
thread.Context.StopExecution(); Thread.Context.StopExecution();
CoreManager.Exit(thread.Context.Work); CoreManager.Exit(Thread.Context.Work);
} }
public void RemoveThread(KThread thread) public void RemoveThread(KThread Thread)
{ {
CoreManager.RemoveThread(thread.Context.Work); CoreManager.RemoveThread(Thread.Context.Work);
} }
} }
} }

View file

@ -9,641 +9,641 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private const int HasListenersMask = 0x40000000; private const int HasListenersMask = 0x40000000;
private Horizon _system; private Horizon System;
public List<KThread> CondVarThreads; public List<KThread> CondVarThreads;
public List<KThread> ArbiterThreads; public List<KThread> ArbiterThreads;
public KAddressArbiter(Horizon system) public KAddressArbiter(Horizon System)
{ {
_system = system; this.System = System;
CondVarThreads = new List<KThread>(); CondVarThreads = new List<KThread>();
ArbiterThreads = new List<KThread>(); ArbiterThreads = new List<KThread>();
} }
public long ArbitrateLock(int ownerHandle, long mutexAddress, int requesterHandle) public long ArbitrateLock(int OwnerHandle, long MutexAddress, int RequesterHandle)
{ {
KThread currentThread = _system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
currentThread.SignaledObj = null; CurrentThread.SignaledObj = null;
currentThread.ObjSyncResult = 0; CurrentThread.ObjSyncResult = 0;
KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
if (!KernelTransfer.UserToKernelInt32(_system, mutexAddress, out int mutexValue)) if (!KernelTransfer.UserToKernelInt32(System, MutexAddress, out int MutexValue))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);;
} }
if (mutexValue != (ownerHandle | HasListenersMask)) if (MutexValue != (OwnerHandle | HasListenersMask))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return 0; return 0;
} }
KThread mutexOwner = currentProcess.HandleTable.GetObject<KThread>(ownerHandle); KThread MutexOwner = CurrentProcess.HandleTable.GetObject<KThread>(OwnerHandle);
if (mutexOwner == null) if (MutexOwner == null)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); return MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
} }
currentThread.MutexAddress = mutexAddress; CurrentThread.MutexAddress = MutexAddress;
currentThread.ThreadHandleForUserMutex = requesterHandle; CurrentThread.ThreadHandleForUserMutex = RequesterHandle;
mutexOwner.AddMutexWaiter(currentThread); MutexOwner.AddMutexWaiter(CurrentThread);
currentThread.Reschedule(ThreadSchedState.Paused); CurrentThread.Reschedule(ThreadSchedState.Paused);
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.MutexOwner != null) if (CurrentThread.MutexOwner != null)
{ {
currentThread.MutexOwner.RemoveMutexWaiter(currentThread); CurrentThread.MutexOwner.RemoveMutexWaiter(CurrentThread);
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return (uint)currentThread.ObjSyncResult; return (uint)CurrentThread.ObjSyncResult;
} }
public long ArbitrateUnlock(long mutexAddress) public long ArbitrateUnlock(long MutexAddress)
{ {
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
KThread currentThread = _system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
(long result, KThread newOwnerThread) = MutexUnlock(currentThread, mutexAddress); (long Result, KThread NewOwnerThread) = MutexUnlock(CurrentThread, MutexAddress);
if (result != 0 && newOwnerThread != null) if (Result != 0 && NewOwnerThread != null)
{ {
newOwnerThread.SignaledObj = null; NewOwnerThread.SignaledObj = null;
newOwnerThread.ObjSyncResult = (int)result; NewOwnerThread.ObjSyncResult = (int)Result;
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return result; return Result;
} }
public long WaitProcessWideKeyAtomic( public long WaitProcessWideKeyAtomic(
long mutexAddress, long MutexAddress,
long condVarAddress, long CondVarAddress,
int threadHandle, int ThreadHandle,
long timeout) long Timeout)
{ {
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
KThread currentThread = _system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
currentThread.SignaledObj = null; CurrentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout); CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
if (currentThread.ShallBeTerminated || if (CurrentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending) CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating); return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
} }
(long result, _) = MutexUnlock(currentThread, mutexAddress); (long Result, _) = MutexUnlock(CurrentThread, MutexAddress);
if (result != 0) if (Result != 0)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return result; return Result;
} }
currentThread.MutexAddress = mutexAddress; CurrentThread.MutexAddress = MutexAddress;
currentThread.ThreadHandleForUserMutex = threadHandle; CurrentThread.ThreadHandleForUserMutex = ThreadHandle;
currentThread.CondVarAddress = condVarAddress; CurrentThread.CondVarAddress = CondVarAddress;
CondVarThreads.Add(currentThread); CondVarThreads.Add(CurrentThread);
if (timeout != 0) if (Timeout != 0)
{ {
currentThread.Reschedule(ThreadSchedState.Paused); CurrentThread.Reschedule(ThreadSchedState.Paused);
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
} }
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.UnscheduleFutureInvocation(currentThread); System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
} }
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.MutexOwner != null) if (CurrentThread.MutexOwner != null)
{ {
currentThread.MutexOwner.RemoveMutexWaiter(currentThread); CurrentThread.MutexOwner.RemoveMutexWaiter(CurrentThread);
} }
CondVarThreads.Remove(currentThread); CondVarThreads.Remove(CurrentThread);
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return (uint)currentThread.ObjSyncResult; return (uint)CurrentThread.ObjSyncResult;
} }
private (long, KThread) MutexUnlock(KThread currentThread, long mutexAddress) private (long, KThread) MutexUnlock(KThread CurrentThread, long MutexAddress)
{ {
KThread newOwnerThread = currentThread.RelinquishMutex(mutexAddress, out int count); KThread NewOwnerThread = CurrentThread.RelinquishMutex(MutexAddress, out int Count);
int mutexValue = 0; int MutexValue = 0;
if (newOwnerThread != null) if (NewOwnerThread != null)
{ {
mutexValue = newOwnerThread.ThreadHandleForUserMutex; MutexValue = NewOwnerThread.ThreadHandleForUserMutex;
if (count >= 2) if (Count >= 2)
{ {
mutexValue |= HasListenersMask; MutexValue |= HasListenersMask;
} }
newOwnerThread.SignaledObj = null; NewOwnerThread.SignaledObj = null;
newOwnerThread.ObjSyncResult = 0; NewOwnerThread.ObjSyncResult = 0;
newOwnerThread.ReleaseAndResume(); NewOwnerThread.ReleaseAndResume();
} }
long result = 0; long Result = 0;
if (!KernelTransfer.KernelToUserInt32(_system, mutexAddress, mutexValue)) if (!KernelTransfer.KernelToUserInt32(System, MutexAddress, MutexValue))
{ {
result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); Result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
} }
return (result, newOwnerThread); return (Result, NewOwnerThread);
} }
public void SignalProcessWideKey(long address, int count) public void SignalProcessWideKey(long Address, int Count)
{ {
Queue<KThread> signaledThreads = new Queue<KThread>(); Queue<KThread> SignaledThreads = new Queue<KThread>();
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
IOrderedEnumerable<KThread> sortedThreads = CondVarThreads.OrderBy(x => x.DynamicPriority); IOrderedEnumerable<KThread> SortedThreads = CondVarThreads.OrderBy(x => x.DynamicPriority);
foreach (KThread thread in sortedThreads.Where(x => x.CondVarAddress == address)) foreach (KThread Thread in SortedThreads.Where(x => x.CondVarAddress == Address))
{ {
TryAcquireMutex(thread); TryAcquireMutex(Thread);
signaledThreads.Enqueue(thread); SignaledThreads.Enqueue(Thread);
//If the count is <= 0, we should signal all threads waiting. //If the count is <= 0, we should signal all threads waiting.
if (count >= 1 && --count == 0) if (Count >= 1 && --Count == 0)
{ {
break; break;
} }
} }
while (signaledThreads.TryDequeue(out KThread thread)) while (SignaledThreads.TryDequeue(out KThread Thread))
{ {
CondVarThreads.Remove(thread); CondVarThreads.Remove(Thread);
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
} }
private KThread TryAcquireMutex(KThread requester) private KThread TryAcquireMutex(KThread Requester)
{ {
long address = requester.MutexAddress; long Address = Requester.MutexAddress;
KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
if (!KernelTransfer.UserToKernelInt32(_system, address, out int mutexValue)) if (!KernelTransfer.UserToKernelInt32(System, Address, out int MutexValue))
{ {
//Invalid address. //Invalid address.
currentProcess.CpuMemory.ClearExclusive(0); CurrentProcess.CpuMemory.ClearExclusive(0);
requester.SignaledObj = null; Requester.SignaledObj = null;
requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return null; return null;
} }
while (true) while (true)
{ {
if (currentProcess.CpuMemory.TestExclusive(0, address)) if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
{ {
if (mutexValue != 0) if (MutexValue != 0)
{ {
//Update value to indicate there is a mutex waiter now. //Update value to indicate there is a mutex waiter now.
currentProcess.CpuMemory.WriteInt32(address, mutexValue | HasListenersMask); CurrentProcess.CpuMemory.WriteInt32(Address, MutexValue | HasListenersMask);
} }
else else
{ {
//No thread owning the mutex, assign to requesting thread. //No thread owning the mutex, assign to requesting thread.
currentProcess.CpuMemory.WriteInt32(address, requester.ThreadHandleForUserMutex); CurrentProcess.CpuMemory.WriteInt32(Address, Requester.ThreadHandleForUserMutex);
} }
currentProcess.CpuMemory.ClearExclusiveForStore(0); CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
break; break;
} }
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
mutexValue = currentProcess.CpuMemory.ReadInt32(address); MutexValue = CurrentProcess.CpuMemory.ReadInt32(Address);
} }
if (mutexValue == 0) if (MutexValue == 0)
{ {
//We now own the mutex. //We now own the mutex.
requester.SignaledObj = null; Requester.SignaledObj = null;
requester.ObjSyncResult = 0; Requester.ObjSyncResult = 0;
requester.ReleaseAndResume(); Requester.ReleaseAndResume();
return null; return null;
} }
mutexValue &= ~HasListenersMask; MutexValue &= ~HasListenersMask;
KThread mutexOwner = currentProcess.HandleTable.GetObject<KThread>(mutexValue); KThread MutexOwner = CurrentProcess.HandleTable.GetObject<KThread>(MutexValue);
if (mutexOwner != null) if (MutexOwner != null)
{ {
//Mutex already belongs to another thread, wait for it. //Mutex already belongs to another thread, wait for it.
mutexOwner.AddMutexWaiter(requester); MutexOwner.AddMutexWaiter(Requester);
} }
else else
{ {
//Invalid mutex owner. //Invalid mutex owner.
requester.SignaledObj = null; Requester.SignaledObj = null;
requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
requester.ReleaseAndResume(); Requester.ReleaseAndResume();
} }
return mutexOwner; return MutexOwner;
} }
public long WaitForAddressIfEqual(long address, int value, long timeout) public long WaitForAddressIfEqual(long Address, int Value, long Timeout)
{ {
KThread currentThread = _system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.ShallBeTerminated || if (CurrentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending) CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating); return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
} }
currentThread.SignaledObj = null; CurrentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout); CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue)) if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
} }
if (currentValue == value) if (CurrentValue == Value)
{ {
if (timeout == 0) if (Timeout == 0)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.Timeout); return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
} }
currentThread.MutexAddress = address; CurrentThread.MutexAddress = Address;
currentThread.WaitingInArbitration = true; CurrentThread.WaitingInArbitration = true;
InsertSortedByPriority(ArbiterThreads, currentThread); InsertSortedByPriority(ArbiterThreads, CurrentThread);
currentThread.Reschedule(ThreadSchedState.Paused); CurrentThread.Reschedule(ThreadSchedState.Paused);
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.UnscheduleFutureInvocation(currentThread); System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
} }
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.WaitingInArbitration) if (CurrentThread.WaitingInArbitration)
{ {
ArbiterThreads.Remove(currentThread); ArbiterThreads.Remove(CurrentThread);
currentThread.WaitingInArbitration = false; CurrentThread.WaitingInArbitration = false;
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return currentThread.ObjSyncResult; return CurrentThread.ObjSyncResult;
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState); return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
} }
public long WaitForAddressIfLessThan(long address, int value, bool shouldDecrement, long timeout) public long WaitForAddressIfLessThan(long Address, int Value, bool ShouldDecrement, long Timeout)
{ {
KThread currentThread = _system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.ShallBeTerminated || if (CurrentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending) CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating); return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
} }
currentThread.SignaledObj = null; CurrentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout); CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
//If ShouldDecrement is true, do atomic decrement of the value at Address. //If ShouldDecrement is true, do atomic decrement of the value at Address.
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue)) if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
} }
if (shouldDecrement) if (ShouldDecrement)
{ {
while (currentValue < value) while (CurrentValue < Value)
{ {
if (currentProcess.CpuMemory.TestExclusive(0, address)) if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
{ {
currentProcess.CpuMemory.WriteInt32(address, currentValue - 1); CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue - 1);
currentProcess.CpuMemory.ClearExclusiveForStore(0); CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
break; break;
} }
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address); CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
} }
} }
currentProcess.CpuMemory.ClearExclusive(0); CurrentProcess.CpuMemory.ClearExclusive(0);
if (currentValue < value) if (CurrentValue < Value)
{ {
if (timeout == 0) if (Timeout == 0)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.Timeout); return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
} }
currentThread.MutexAddress = address; CurrentThread.MutexAddress = Address;
currentThread.WaitingInArbitration = true; CurrentThread.WaitingInArbitration = true;
InsertSortedByPriority(ArbiterThreads, currentThread); InsertSortedByPriority(ArbiterThreads, CurrentThread);
currentThread.Reschedule(ThreadSchedState.Paused); CurrentThread.Reschedule(ThreadSchedState.Paused);
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
if (timeout > 0) if (Timeout > 0)
{ {
_system.TimeManager.UnscheduleFutureInvocation(currentThread); System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
} }
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
if (currentThread.WaitingInArbitration) if (CurrentThread.WaitingInArbitration)
{ {
ArbiterThreads.Remove(currentThread); ArbiterThreads.Remove(CurrentThread);
currentThread.WaitingInArbitration = false; CurrentThread.WaitingInArbitration = false;
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return currentThread.ObjSyncResult; return CurrentThread.ObjSyncResult;
} }
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState); return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
} }
private void InsertSortedByPriority(List<KThread> threads, KThread thread) private void InsertSortedByPriority(List<KThread> Threads, KThread Thread)
{ {
int nextIndex = -1; int NextIndex = -1;
for (int index = 0; index < threads.Count; index++) for (int Index = 0; Index < Threads.Count; Index++)
{ {
if (threads[index].DynamicPriority > thread.DynamicPriority) if (Threads[Index].DynamicPriority > Thread.DynamicPriority)
{ {
nextIndex = index; NextIndex = Index;
break; break;
} }
} }
if (nextIndex != -1) if (NextIndex != -1)
{ {
threads.Insert(nextIndex, thread); Threads.Insert(NextIndex, Thread);
} }
else else
{ {
threads.Add(thread); Threads.Add(Thread);
} }
} }
public long Signal(long address, int count) public long Signal(long Address, int Count)
{ {
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
WakeArbiterThreads(address, count); WakeArbiterThreads(Address, Count);
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return 0; return 0;
} }
public long SignalAndIncrementIfEqual(long address, int value, int count) public long SignalAndIncrementIfEqual(long Address, int Value, int Count)
{ {
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue)) if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
} }
while (currentValue == value) while (CurrentValue == Value)
{ {
if (currentProcess.CpuMemory.TestExclusive(0, address)) if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
{ {
currentProcess.CpuMemory.WriteInt32(address, currentValue + 1); CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue + 1);
currentProcess.CpuMemory.ClearExclusiveForStore(0); CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
break; break;
} }
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address); CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
} }
currentProcess.CpuMemory.ClearExclusive(0); CurrentProcess.CpuMemory.ClearExclusive(0);
if (currentValue != value) if (CurrentValue != Value)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState); return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
} }
WakeArbiterThreads(address, count); WakeArbiterThreads(Address, Count);
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return 0; return 0;
} }
public long SignalAndModifyIfEqual(long address, int value, int count) public long SignalAndModifyIfEqual(long Address, int Value, int Count)
{ {
_system.CriticalSection.Enter(); System.CriticalSection.Enter();
int offset; int Offset;
//The value is decremented if the number of threads waiting is less //The value is decremented if the number of threads waiting is less
//or equal to the Count of threads to be signaled, or Count is zero //or equal to the Count of threads to be signaled, or Count is zero
//or negative. It is incremented if there are no threads waiting. //or negative. It is incremented if there are no threads waiting.
int waitingCount = 0; int WaitingCount = 0;
foreach (KThread thread in ArbiterThreads.Where(x => x.MutexAddress == address)) foreach (KThread Thread in ArbiterThreads.Where(x => x.MutexAddress == Address))
{ {
if (++waitingCount > count) if (++WaitingCount > Count)
{ {
break; break;
} }
} }
if (waitingCount > 0) if (WaitingCount > 0)
{ {
offset = waitingCount <= count || count <= 0 ? -1 : 0; Offset = WaitingCount <= Count || Count <= 0 ? -1 : 0;
} }
else else
{ {
offset = 1; Offset = 1;
} }
KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue)) if (!KernelTransfer.UserToKernelInt32(System, Address, out int CurrentValue))
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
} }
while (currentValue == value) while (CurrentValue == Value)
{ {
if (currentProcess.CpuMemory.TestExclusive(0, address)) if (CurrentProcess.CpuMemory.TestExclusive(0, Address))
{ {
currentProcess.CpuMemory.WriteInt32(address, currentValue + offset); CurrentProcess.CpuMemory.WriteInt32(Address, CurrentValue + Offset);
currentProcess.CpuMemory.ClearExclusiveForStore(0); CurrentProcess.CpuMemory.ClearExclusiveForStore(0);
break; break;
} }
currentProcess.CpuMemory.SetExclusive(0, address); CurrentProcess.CpuMemory.SetExclusive(0, Address);
currentValue = currentProcess.CpuMemory.ReadInt32(address); CurrentValue = CurrentProcess.CpuMemory.ReadInt32(Address);
} }
currentProcess.CpuMemory.ClearExclusive(0); CurrentProcess.CpuMemory.ClearExclusive(0);
if (currentValue != value) if (CurrentValue != Value)
{ {
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.InvalidState); return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
} }
WakeArbiterThreads(address, count); WakeArbiterThreads(Address, Count);
_system.CriticalSection.Leave(); System.CriticalSection.Leave();
return 0; return 0;
} }
private void WakeArbiterThreads(long address, int count) private void WakeArbiterThreads(long Address, int Count)
{ {
Queue<KThread> signaledThreads = new Queue<KThread>(); Queue<KThread> SignaledThreads = new Queue<KThread>();
foreach (KThread thread in ArbiterThreads.Where(x => x.MutexAddress == address)) foreach (KThread Thread in ArbiterThreads.Where(x => x.MutexAddress == Address))
{ {
signaledThreads.Enqueue(thread); SignaledThreads.Enqueue(Thread);
//If the count is <= 0, we should signal all threads waiting. //If the count is <= 0, we should signal all threads waiting.
if (count >= 1 && --count == 0) if (Count >= 1 && --Count == 0)
{ {
break; break;
} }
} }
while (signaledThreads.TryDequeue(out KThread thread)) while (SignaledThreads.TryDequeue(out KThread Thread))
{ {
thread.SignaledObj = null; Thread.SignaledObj = null;
thread.ObjSyncResult = 0; Thread.ObjSyncResult = 0;
thread.ReleaseAndResume(); Thread.ReleaseAndResume();
thread.WaitingInArbitration = false; Thread.WaitingInArbitration = false;
ArbiterThreads.Remove(thread); ArbiterThreads.Remove(Thread);
} }
} }
} }

View file

@ -4,14 +4,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
protected Horizon System; protected Horizon System;
public KAutoObject(Horizon system) public KAutoObject(Horizon System)
{ {
System = system; this.System = System;
} }
public virtual KernelResult SetName(string name) public virtual KernelResult SetName(string Name)
{ {
if (!System.AutoObjectNames.TryAdd(name, this)) if (!System.AutoObjectNames.TryAdd(Name, this))
{ {
return KernelResult.InvalidState; return KernelResult.InvalidState;
} }
@ -19,9 +19,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success; return KernelResult.Success;
} }
public static KernelResult RemoveName(Horizon system, string name) public static KernelResult RemoveName(Horizon System, string Name)
{ {
if (!system.AutoObjectNames.TryRemove(name, out _)) if (!System.AutoObjectNames.TryRemove(Name, out _))
{ {
return KernelResult.NotFound; return KernelResult.NotFound;
} }
@ -29,11 +29,11 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success; return KernelResult.Success;
} }
public static KAutoObject FindNamedObject(Horizon system, string name) public static KAutoObject FindNamedObject(Horizon System, string Name)
{ {
if (system.AutoObjectNames.TryGetValue(name, out KAutoObject obj)) if (System.AutoObjectNames.TryGetValue(Name, out KAutoObject Obj))
{ {
return obj; return Obj;
} }
return null; return null;

View file

@ -2,30 +2,30 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KClientPort : KSynchronizationObject class KClientPort : KSynchronizationObject
{ {
private int _sessionsCount; private int SessionsCount;
private int _currentCapacity; private int CurrentCapacity;
private int _maxSessions; private int MaxSessions;
private KPort _parent; private KPort Parent;
public KClientPort(Horizon system) : base(system) { } public KClientPort(Horizon System) : base(System) { }
public void Initialize(KPort parent, int maxSessions) public void Initialize(KPort Parent, int MaxSessions)
{ {
_maxSessions = maxSessions; this.MaxSessions = MaxSessions;
_parent = parent; this.Parent = Parent;
} }
public new static KernelResult RemoveName(Horizon system, string name) public new static KernelResult RemoveName(Horizon System, string Name)
{ {
KAutoObject foundObj = FindNamedObject(system, name); KAutoObject FoundObj = KAutoObject.FindNamedObject(System, Name);
if (!(foundObj is KClientPort)) if (!(FoundObj is KClientPort))
{ {
return KernelResult.NotFound; return KernelResult.NotFound;
} }
return KAutoObject.RemoveName(system, name); return KAutoObject.RemoveName(System, Name);
} }
} }
} }

View file

@ -5,67 +5,67 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
static class KConditionVariable static class KConditionVariable
{ {
public static void Wait(Horizon system, LinkedList<KThread> threadList, object mutex, long timeout) public static void Wait(Horizon System, LinkedList<KThread> ThreadList, object Mutex, long Timeout)
{ {
KThread currentThread = system.Scheduler.GetCurrentThread(); KThread CurrentThread = System.Scheduler.GetCurrentThread();
system.CriticalSection.Enter(); System.CriticalSection.Enter();
Monitor.Exit(mutex); Monitor.Exit(Mutex);
currentThread.Withholder = threadList; CurrentThread.Withholder = ThreadList;
currentThread.Reschedule(ThreadSchedState.Paused); CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.WithholderNode = threadList.AddLast(currentThread); CurrentThread.WithholderNode = ThreadList.AddLast(CurrentThread);
if (currentThread.ShallBeTerminated || if (CurrentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending) CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
{ {
threadList.Remove(currentThread.WithholderNode); ThreadList.Remove(CurrentThread.WithholderNode);
currentThread.Reschedule(ThreadSchedState.Running); CurrentThread.Reschedule(ThreadSchedState.Running);
currentThread.Withholder = null; CurrentThread.Withholder = null;
system.CriticalSection.Leave(); System.CriticalSection.Leave();
} }
else else
{ {
if (timeout > 0) if (Timeout > 0)
{ {
system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
} }
system.CriticalSection.Leave(); System.CriticalSection.Leave();
if (timeout > 0) if (Timeout > 0)
{ {
system.TimeManager.UnscheduleFutureInvocation(currentThread); System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
} }
} }
Monitor.Enter(mutex); Monitor.Enter(Mutex);
} }
public static void NotifyAll(Horizon system, LinkedList<KThread> threadList) public static void NotifyAll(Horizon System, LinkedList<KThread> ThreadList)
{ {
system.CriticalSection.Enter(); System.CriticalSection.Enter();
LinkedListNode<KThread> node = threadList.First; LinkedListNode<KThread> Node = ThreadList.First;
for (; node != null; node = threadList.First) for (; Node != null; Node = ThreadList.First)
{ {
KThread thread = node.Value; KThread Thread = Node.Value;
threadList.Remove(thread.WithholderNode); ThreadList.Remove(Thread.WithholderNode);
thread.Withholder = null; Thread.Withholder = null;
thread.Reschedule(ThreadSchedState.Running); Thread.Reschedule(ThreadSchedState.Running);
} }
system.CriticalSection.Leave(); System.CriticalSection.Leave();
} }
} }
} }

View file

@ -7,77 +7,77 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private const int IdMasksCount = 8; private const int IdMasksCount = 8;
private int[] _idMasks; private int[] IdMasks;
private int _nextFreeBitHint; private int NextFreeBitHint;
public KContextIdManager() public KContextIdManager()
{ {
_idMasks = new int[IdMasksCount]; IdMasks = new int[IdMasksCount];
} }
public int GetId() public int GetId()
{ {
lock (_idMasks) lock (IdMasks)
{ {
int id = 0; int Id = 0;
if (!TestBit(_nextFreeBitHint)) if (!TestBit(NextFreeBitHint))
{ {
id = _nextFreeBitHint; Id = NextFreeBitHint;
} }
else else
{ {
for (int index = 0; index < IdMasksCount; index++) for (int Index = 0; Index < IdMasksCount; Index++)
{ {
int mask = _idMasks[index]; int Mask = IdMasks[Index];
int firstFreeBit = BitUtils.CountLeadingZeros32((mask + 1) & ~mask); int FirstFreeBit = BitUtils.CountLeadingZeros32((Mask + 1) & ~Mask);
if (firstFreeBit < 32) if (FirstFreeBit < 32)
{ {
int baseBit = index * 32 + 31; int BaseBit = Index * 32 + 31;
id = baseBit - firstFreeBit; Id = BaseBit - FirstFreeBit;
break; break;
} }
else if (index == IdMasksCount - 1) else if (Index == IdMasksCount - 1)
{ {
throw new InvalidOperationException("Maximum number of Ids reached!"); throw new InvalidOperationException("Maximum number of Ids reached!");
} }
} }
} }
_nextFreeBitHint = id + 1; NextFreeBitHint = Id + 1;
SetBit(id); SetBit(Id);
return id; return Id;
} }
} }
public void PutId(int id) public void PutId(int Id)
{ {
lock (_idMasks) lock (IdMasks)
{ {
ClearBit(id); ClearBit(Id);
} }
} }
private bool TestBit(int bit) private bool TestBit(int Bit)
{ {
return (_idMasks[_nextFreeBitHint / 32] & (1 << (_nextFreeBitHint & 31))) != 0; return (IdMasks[NextFreeBitHint / 32] & (1 << (NextFreeBitHint & 31))) != 0;
} }
private void SetBit(int bit) private void SetBit(int Bit)
{ {
_idMasks[_nextFreeBitHint / 32] |= (1 << (_nextFreeBitHint & 31)); IdMasks[NextFreeBitHint / 32] |= (1 << (NextFreeBitHint & 31));
} }
private void ClearBit(int bit) private void ClearBit(int Bit)
{ {
_idMasks[_nextFreeBitHint / 32] &= ~(1 << (_nextFreeBitHint & 31)); IdMasks[NextFreeBitHint / 32] &= ~(1 << (NextFreeBitHint & 31));
} }
} }
} }

View file

@ -4,9 +4,9 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KCoreContext class KCoreContext
{ {
private KScheduler _scheduler; private KScheduler Scheduler;
private HleCoreManager _coreManager; private HleCoreManager CoreManager;
public bool ContextSwitchNeeded { get; private set; } public bool ContextSwitchNeeded { get; private set; }
@ -17,15 +17,15 @@ namespace Ryujinx.HLE.HOS.Kernel
public KThread CurrentThread { get; private set; } public KThread CurrentThread { get; private set; }
public KThread SelectedThread { get; private set; } public KThread SelectedThread { get; private set; }
public KCoreContext(KScheduler scheduler, HleCoreManager coreManager) public KCoreContext(KScheduler Scheduler, HleCoreManager CoreManager)
{ {
_scheduler = scheduler; this.Scheduler = Scheduler;
_coreManager = coreManager; this.CoreManager = CoreManager;
} }
public void SelectThread(KThread thread) public void SelectThread(KThread Thread)
{ {
SelectedThread = thread; SelectedThread = Thread;
if (SelectedThread != CurrentThread) if (SelectedThread != CurrentThread)
{ {
@ -43,10 +43,10 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null) if (CurrentThread != null)
{ {
long currentTime = PerformanceCounter.ElapsedMilliseconds; long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime; CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime; CurrentThread.LastScheduledTime = CurrentTime;
} }
} }
@ -58,21 +58,21 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null) if (CurrentThread != null)
{ {
_coreManager.Reset(CurrentThread.Context.Work); CoreManager.Reset(CurrentThread.Context.Work);
} }
CurrentThread = SelectedThread; CurrentThread = SelectedThread;
if (CurrentThread != null) if (CurrentThread != null)
{ {
long currentTime = PerformanceCounter.ElapsedMilliseconds; long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime; CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime; CurrentThread.LastScheduledTime = CurrentTime;
CurrentThread.ClearExclusive(); CurrentThread.ClearExclusive();
_coreManager.Set(CurrentThread.Context.Work); CoreManager.Set(CurrentThread.Context.Work);
CurrentThread.Context.Execute(); CurrentThread.Context.Execute();
} }

View file

@ -5,15 +5,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KCriticalSection class KCriticalSection
{ {
private Horizon _system; private Horizon System;
public object LockObj { get; } public object LockObj { get; private set; }
private int _recursionCount; private int RecursionCount;
public KCriticalSection(Horizon system) public KCriticalSection(Horizon System)
{ {
_system = system; this.System = System;
LockObj = new object(); LockObj = new object();
} }
@ -22,53 +22,53 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
Monitor.Enter(LockObj); Monitor.Enter(LockObj);
_recursionCount++; RecursionCount++;
} }
public void Leave() public void Leave()
{ {
if (_recursionCount == 0) if (RecursionCount == 0)
{ {
return; return;
} }
bool doContextSwitch = false; bool DoContextSwitch = false;
if (--_recursionCount == 0) if (--RecursionCount == 0)
{ {
if (_system.Scheduler.ThreadReselectionRequested) if (System.Scheduler.ThreadReselectionRequested)
{ {
_system.Scheduler.SelectThreads(); System.Scheduler.SelectThreads();
} }
Monitor.Exit(LockObj); Monitor.Exit(LockObj);
if (_system.Scheduler.MultiCoreScheduling) if (System.Scheduler.MultiCoreScheduling)
{ {
lock (_system.Scheduler.CoreContexts) lock (System.Scheduler.CoreContexts)
{ {
for (int core = 0; core < KScheduler.CpuCoresCount; core++) for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
{ {
KCoreContext coreContext = _system.Scheduler.CoreContexts[core]; KCoreContext CoreContext = System.Scheduler.CoreContexts[Core];
if (coreContext.ContextSwitchNeeded) if (CoreContext.ContextSwitchNeeded)
{ {
CpuThread currentHleThread = coreContext.CurrentThread?.Context; CpuThread CurrentHleThread = CoreContext.CurrentThread?.Context;
if (currentHleThread == null) if (CurrentHleThread == null)
{ {
//Nothing is running, we can perform the context switch immediately. //Nothing is running, we can perform the context switch immediately.
coreContext.ContextSwitch(); CoreContext.ContextSwitch();
} }
else if (currentHleThread.IsCurrentThread()) else if (CurrentHleThread.IsCurrentThread())
{ {
//Thread running on the current core, context switch will block. //Thread running on the current core, context switch will block.
doContextSwitch = true; DoContextSwitch = true;
} }
else else
{ {
//Thread running on another core, request a interrupt. //Thread running on another core, request a interrupt.
currentHleThread.RequestInterrupt(); CurrentHleThread.RequestInterrupt();
} }
} }
} }
@ -76,7 +76,7 @@ namespace Ryujinx.HLE.HOS.Kernel
} }
else else
{ {
doContextSwitch = true; DoContextSwitch = true;
} }
} }
else else
@ -84,9 +84,9 @@ namespace Ryujinx.HLE.HOS.Kernel
Monitor.Exit(LockObj); Monitor.Exit(LockObj);
} }
if (doContextSwitch) if (DoContextSwitch)
{ {
_system.Scheduler.ContextSwitch(); System.Scheduler.ContextSwitch();
} }
} }
} }

View file

@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KEvent class KEvent
{ {
public KReadableEvent ReadableEvent { get; } public KReadableEvent ReadableEvent { get; private set; }
public KWritableEvent WritableEvent { get; } public KWritableEvent WritableEvent { get; private set; }
public KEvent(Horizon system) public KEvent(Horizon System)
{ {
ReadableEvent = new KReadableEvent(system, this); ReadableEvent = new KReadableEvent(System, this);
WritableEvent = new KWritableEvent(this); WritableEvent = new KWritableEvent(this);
} }
} }

View file

@ -4,14 +4,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
public KHandleEntry Next { get; set; } public KHandleEntry Next { get; set; }
public int Index { get; } public int Index { get; private set; }
public ushort HandleId { get; set; } public ushort HandleId { get; set; }
public object Obj { get; set; } public object Obj { get; set; }
public KHandleEntry(int index) public KHandleEntry(int Index)
{ {
Index = index; this.Index = Index;
} }
} }
} }

View file

@ -7,148 +7,148 @@ namespace Ryujinx.HLE.HOS.Kernel
private const int SelfThreadHandle = (0x1ffff << 15) | 0; private const int SelfThreadHandle = (0x1ffff << 15) | 0;
private const int SelfProcessHandle = (0x1ffff << 15) | 1; private const int SelfProcessHandle = (0x1ffff << 15) | 1;
private Horizon _system; private Horizon System;
private KHandleEntry[] _table; private KHandleEntry[] Table;
private KHandleEntry _tableHead; private KHandleEntry TableHead;
private KHandleEntry _nextFreeEntry; private KHandleEntry NextFreeEntry;
private int _activeSlotsCount; private int ActiveSlotsCount;
private int _size; private int Size;
private ushort _idCounter; private ushort IdCounter;
public KHandleTable(Horizon system) public KHandleTable(Horizon System)
{ {
_system = system; this.System = System;
} }
public KernelResult Initialize(int size) public KernelResult Initialize(int Size)
{ {
if ((uint)size > 1024) if ((uint)Size > 1024)
{ {
return KernelResult.OutOfMemory; return KernelResult.OutOfMemory;
} }
if (size < 1) if (Size < 1)
{ {
size = 1024; Size = 1024;
} }
_size = size; this.Size = Size;
_idCounter = 1; IdCounter = 1;
_table = new KHandleEntry[size]; Table = new KHandleEntry[Size];
_tableHead = new KHandleEntry(0); TableHead = new KHandleEntry(0);
KHandleEntry entry = _tableHead; KHandleEntry Entry = TableHead;
for (int index = 0; index < size; index++) for (int Index = 0; Index < Size; Index++)
{ {
_table[index] = entry; Table[Index] = Entry;
entry.Next = new KHandleEntry(index + 1); Entry.Next = new KHandleEntry(Index + 1);
entry = entry.Next; Entry = Entry.Next;
} }
_table[size - 1].Next = null; Table[Size - 1].Next = null;
_nextFreeEntry = _tableHead; NextFreeEntry = TableHead;
return KernelResult.Success; return KernelResult.Success;
} }
public KernelResult GenerateHandle(object obj, out int handle) public KernelResult GenerateHandle(object Obj, out int Handle)
{ {
handle = 0; Handle = 0;
lock (_table) lock (Table)
{ {
if (_activeSlotsCount >= _size) if (ActiveSlotsCount >= Size)
{ {
return KernelResult.HandleTableFull; return KernelResult.HandleTableFull;
} }
KHandleEntry entry = _nextFreeEntry; KHandleEntry Entry = NextFreeEntry;
_nextFreeEntry = entry.Next; NextFreeEntry = Entry.Next;
entry.Obj = obj; Entry.Obj = Obj;
entry.HandleId = _idCounter; Entry.HandleId = IdCounter;
_activeSlotsCount++; ActiveSlotsCount++;
handle = (int)((_idCounter << 15) & 0xffff8000) | entry.Index; Handle = (int)((IdCounter << 15) & (uint)0xffff8000) | Entry.Index;
if ((short)(_idCounter + 1) >= 0) if ((short)(IdCounter + 1) >= 0)
{ {
_idCounter++; IdCounter++;
} }
else else
{ {
_idCounter = 1; IdCounter = 1;
} }
} }
return KernelResult.Success; return KernelResult.Success;
} }
public bool CloseHandle(int handle) public bool CloseHandle(int Handle)
{ {
if ((handle >> 30) != 0 || if ((Handle >> 30) != 0 ||
handle == SelfThreadHandle || Handle == SelfThreadHandle ||
handle == SelfProcessHandle) Handle == SelfProcessHandle)
{ {
return false; return false;
} }
int index = (handle >> 0) & 0x7fff; int Index = (Handle >> 0) & 0x7fff;
int handleId = (handle >> 15); int HandleId = (Handle >> 15);
bool result = false; bool Result = false;
lock (_table) lock (Table)
{ {
if (handleId != 0 && index < _size) if (HandleId != 0 && Index < Size)
{ {
KHandleEntry entry = _table[index]; KHandleEntry Entry = Table[Index];
if (entry.Obj != null && entry.HandleId == handleId) if (Entry.Obj != null && Entry.HandleId == HandleId)
{ {
entry.Obj = null; Entry.Obj = null;
entry.Next = _nextFreeEntry; Entry.Next = NextFreeEntry;
_nextFreeEntry = entry; NextFreeEntry = Entry;
_activeSlotsCount--; ActiveSlotsCount--;
result = true; Result = true;
} }
} }
} }
return result; return Result;
} }
public T GetObject<T>(int handle) public T GetObject<T>(int Handle)
{ {
int index = (handle >> 0) & 0x7fff; int Index = (Handle >> 0) & 0x7fff;
int handleId = (handle >> 15); int HandleId = (Handle >> 15);
lock (_table) lock (Table)
{ {
if ((handle >> 30) == 0 && handleId != 0) if ((Handle >> 30) == 0 && HandleId != 0)
{ {
KHandleEntry entry = _table[index]; KHandleEntry Entry = Table[Index];
if (entry.HandleId == handleId && entry.Obj is T obj) if (Entry.HandleId == HandleId && Entry.Obj is T Obj)
{ {
return obj; return Obj;
} }
} }
} }
@ -156,49 +156,49 @@ namespace Ryujinx.HLE.HOS.Kernel
return default(T); return default(T);
} }
public KThread GetKThread(int handle) public KThread GetKThread(int Handle)
{ {
if (handle == SelfThreadHandle) if (Handle == SelfThreadHandle)
{ {
return _system.Scheduler.GetCurrentThread(); return System.Scheduler.GetCurrentThread();
} }
else else
{ {
return GetObject<KThread>(handle); return GetObject<KThread>(Handle);
} }
} }
public KProcess GetKProcess(int handle) public KProcess GetKProcess(int Handle)
{ {
if (handle == SelfProcessHandle) if (Handle == SelfProcessHandle)
{ {
return _system.Scheduler.GetCurrentProcess(); return System.Scheduler.GetCurrentProcess();
} }
else else
{ {
return GetObject<KProcess>(handle); return GetObject<KProcess>(Handle);
} }
} }
public void Destroy() public void Destroy()
{ {
lock (_table) lock (Table)
{ {
for (int index = 0; index < _size; index++) for (int Index = 0; Index < Size; Index++)
{ {
KHandleEntry entry = _table[index]; KHandleEntry Entry = Table[Index];
if (entry.Obj != null) if (Entry.Obj != null)
{ {
if (entry.Obj is IDisposable disposableObj) if (Entry.Obj is IDisposable DisposableObj)
{ {
disposableObj.Dispose(); DisposableObj.Dispose();
} }
entry.Obj = null; Entry.Obj = null;
entry.Next = _nextFreeEntry; Entry.Next = NextFreeEntry;
_nextFreeEntry = entry; NextFreeEntry = Entry;
} }
} }
} }

View file

@ -2,21 +2,21 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KMemoryArrange class KMemoryArrange
{ {
public KMemoryArrangeRegion Service { get; } public KMemoryArrangeRegion Service { get; private set; }
public KMemoryArrangeRegion NvServices { get; } public KMemoryArrangeRegion NvServices { get; private set; }
public KMemoryArrangeRegion Applet { get; } public KMemoryArrangeRegion Applet { get; private set; }
public KMemoryArrangeRegion Application { get; } public KMemoryArrangeRegion Application { get; private set; }
public KMemoryArrange( public KMemoryArrange(
KMemoryArrangeRegion service, KMemoryArrangeRegion Service,
KMemoryArrangeRegion nvServices, KMemoryArrangeRegion NvServices,
KMemoryArrangeRegion applet, KMemoryArrangeRegion Applet,
KMemoryArrangeRegion application) KMemoryArrangeRegion Application)
{ {
Service = service; this.Service = Service;
NvServices = nvServices; this.NvServices = NvServices;
Applet = applet; this.Applet = Applet;
Application = application; this.Application = Application;
} }
} }
} }

View file

@ -2,15 +2,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
struct KMemoryArrangeRegion struct KMemoryArrangeRegion
{ {
public ulong Address { get; } public ulong Address { get; private set; }
public ulong Size { get; } public ulong Size { get; private set; }
public ulong EndAddr => Address + Size; public ulong EndAddr => Address + Size;
public KMemoryArrangeRegion(ulong address, ulong size) public KMemoryArrangeRegion(ulong Address, ulong Size)
{ {
Address = address; this.Address = Address;
Size = size; this.Size = Size;
} }
} }
} }

View file

@ -13,26 +13,26 @@ namespace Ryujinx.HLE.HOS.Kernel
public int DeviceRefCount { get; set; } public int DeviceRefCount { get; set; }
public KMemoryBlock( public KMemoryBlock(
ulong baseAddress, ulong BaseAddress,
ulong pagesCount, ulong PagesCount,
MemoryState state, MemoryState State,
MemoryPermission permission, MemoryPermission Permission,
MemoryAttribute attribute) MemoryAttribute Attribute)
{ {
BaseAddress = baseAddress; this.BaseAddress = BaseAddress;
PagesCount = pagesCount; this.PagesCount = PagesCount;
State = state; this.State = State;
Attribute = attribute; this.Attribute = Attribute;
Permission = permission; this.Permission = Permission;
} }
public KMemoryInfo GetInfo() public KMemoryInfo GetInfo()
{ {
ulong size = PagesCount * KMemoryManager.PageSize; ulong Size = PagesCount * KMemoryManager.PageSize;
return new KMemoryInfo( return new KMemoryInfo(
BaseAddress, BaseAddress,
size, Size,
State, State,
Permission, Permission,
Attribute, Attribute,

View file

@ -2,18 +2,18 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KMemoryBlockAllocator class KMemoryBlockAllocator
{ {
private ulong _capacityElements; private ulong CapacityElements;
public int Count { get; set; } public int Count { get; set; }
public KMemoryBlockAllocator(ulong capacityElements) public KMemoryBlockAllocator(ulong CapacityElements)
{ {
_capacityElements = capacityElements; this.CapacityElements = CapacityElements;
} }
public bool CanAllocate(int count) public bool CanAllocate(int Count)
{ {
return (ulong)(Count + count) <= _capacityElements; return (ulong)(this.Count + Count) <= CapacityElements;
} }
} }
} }

View file

@ -2,32 +2,32 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
class KMemoryInfo class KMemoryInfo
{ {
public ulong Address { get; } public ulong Address { get; private set; }
public ulong Size { get; } public ulong Size { get; private set; }
public MemoryState State { get; } public MemoryState State { get; private set; }
public MemoryPermission Permission { get; } public MemoryPermission Permission { get; private set; }
public MemoryAttribute Attribute { get; } public MemoryAttribute Attribute { get; private set; }
public int IpcRefCount { get; } public int IpcRefCount { get; private set; }
public int DeviceRefCount { get; } public int DeviceRefCount { get; private set; }
public KMemoryInfo( public KMemoryInfo(
ulong address, ulong Address,
ulong size, ulong Size,
MemoryState state, MemoryState State,
MemoryPermission permission, MemoryPermission Permission,
MemoryAttribute attribute, MemoryAttribute Attribute,
int ipcRefCount, int IpcRefCount,
int deviceRefCount) int DeviceRefCount)
{ {
Address = address; this.Address = Address;
Size = size; this.Size = Size;
State = state; this.State = State;
Attribute = attribute; this.Attribute = Attribute;
Permission = permission; this.Permission = Permission;
IpcRefCount = ipcRefCount; this.IpcRefCount = IpcRefCount;
DeviceRefCount = deviceRefCount; this.DeviceRefCount = DeviceRefCount;
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -12,30 +12,30 @@ namespace Ryujinx.HLE.HOS.Kernel
public int Order; public int Order;
public int NextOrder; public int NextOrder;
public bool TryCoalesce(int index, int size) public bool TryCoalesce(int Index, int Size)
{ {
long mask = ((1L << size) - 1) << (index & 63); long Mask = ((1L << Size) - 1) << (Index & 63);
index /= 64; Index /= 64;
if ((mask & ~Masks[MaxLevel - 1][index]) != 0) if ((Mask & ~Masks[MaxLevel - 1][Index]) != 0)
{ {
return false; return false;
} }
Masks[MaxLevel - 1][index] &= ~mask; Masks[MaxLevel - 1][Index] &= ~Mask;
for (int level = MaxLevel - 2; level >= 0; level--, index /= 64) for (int Level = MaxLevel - 2; Level >= 0; Level--, Index /= 64)
{ {
Masks[level][index / 64] &= ~(1L << (index & 63)); Masks[Level][Index / 64] &= ~(1L << (Index & 63));
if (Masks[level][index / 64] != 0) if (Masks[Level][Index / 64] != 0)
{ {
break; break;
} }
} }
FreeCount -= (ulong)size; FreeCount -= (ulong)Size;
return true; return true;
} }

View file

@ -6,404 +6,404 @@ namespace Ryujinx.HLE.HOS.Kernel
{ {
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 }; private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
public ulong Address { get; } public ulong Address { get; private set; }
public ulong EndAddr { get; } public ulong EndAddr { get; private set; }
public ulong Size { get; } public ulong Size { get; private set; }
private int _blockOrdersCount; private int BlockOrdersCount;
private KMemoryRegionBlock[] _blocks; private KMemoryRegionBlock[] Blocks;
public KMemoryRegionManager(ulong address, ulong size, ulong endAddr) public KMemoryRegionManager(ulong Address, ulong Size, ulong EndAddr)
{ {
_blocks = new KMemoryRegionBlock[BlockOrders.Length]; Blocks = new KMemoryRegionBlock[BlockOrders.Length];
Address = address; this.Address = Address;
Size = size; this.Size = Size;
EndAddr = endAddr; this.EndAddr = EndAddr;
_blockOrdersCount = BlockOrders.Length; BlockOrdersCount = BlockOrders.Length;
for (int blockIndex = 0; blockIndex < _blockOrdersCount; blockIndex++) for (int BlockIndex = 0; BlockIndex < BlockOrdersCount; BlockIndex++)
{ {
_blocks[blockIndex] = new KMemoryRegionBlock(); Blocks[BlockIndex] = new KMemoryRegionBlock();
_blocks[blockIndex].Order = BlockOrders[blockIndex]; Blocks[BlockIndex].Order = BlockOrders[BlockIndex];
int nextOrder = blockIndex == _blockOrdersCount - 1 ? 0 : BlockOrders[blockIndex + 1]; int NextOrder = BlockIndex == BlockOrdersCount - 1 ? 0 : BlockOrders[BlockIndex + 1];
_blocks[blockIndex].NextOrder = nextOrder; Blocks[BlockIndex].NextOrder = NextOrder;
int currBlockSize = 1 << BlockOrders[blockIndex]; int CurrBlockSize = 1 << BlockOrders[BlockIndex];
int nextBlockSize = currBlockSize; int NextBlockSize = CurrBlockSize;
if (nextOrder != 0) if (NextOrder != 0)
{ {
nextBlockSize = 1 << nextOrder; NextBlockSize = 1 << NextOrder;
} }
ulong startAligned = BitUtils.AlignDown(address, nextBlockSize); ulong StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
ulong endAddrAligned = BitUtils.AlignDown(endAddr, currBlockSize); ulong EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
ulong sizeInBlocksTruncated = (endAddrAligned - startAligned) >> BlockOrders[blockIndex]; ulong SizeInBlocksTruncated = (EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
ulong endAddrRounded = BitUtils.AlignUp(address + size, nextBlockSize); ulong EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
ulong sizeInBlocksRounded = (endAddrRounded - startAligned) >> BlockOrders[blockIndex]; ulong SizeInBlocksRounded = (EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
_blocks[blockIndex].StartAligned = startAligned; Blocks[BlockIndex].StartAligned = StartAligned;
_blocks[blockIndex].SizeInBlocksTruncated = sizeInBlocksTruncated; Blocks[BlockIndex].SizeInBlocksTruncated = SizeInBlocksTruncated;
_blocks[blockIndex].SizeInBlocksRounded = sizeInBlocksRounded; Blocks[BlockIndex].SizeInBlocksRounded = SizeInBlocksRounded;
ulong currSizeInBlocks = sizeInBlocksRounded; ulong CurrSizeInBlocks = SizeInBlocksRounded;
int maxLevel = 0; int MaxLevel = 0;
do do
{ {
maxLevel++; MaxLevel++;
} }
while ((currSizeInBlocks /= 64) != 0); while ((CurrSizeInBlocks /= 64) != 0);
_blocks[blockIndex].MaxLevel = maxLevel; Blocks[BlockIndex].MaxLevel = MaxLevel;
_blocks[blockIndex].Masks = new long[maxLevel][]; Blocks[BlockIndex].Masks = new long[MaxLevel][];
currSizeInBlocks = sizeInBlocksRounded; CurrSizeInBlocks = SizeInBlocksRounded;
for (int level = maxLevel - 1; level >= 0; level--) for (int Level = MaxLevel - 1; Level >= 0; Level--)
{ {
currSizeInBlocks = (currSizeInBlocks + 63) / 64; CurrSizeInBlocks = (CurrSizeInBlocks + 63) / 64;
_blocks[blockIndex].Masks[level] = new long[currSizeInBlocks]; Blocks[BlockIndex].Masks[Level] = new long[CurrSizeInBlocks];
} }
} }
if (size != 0) if (Size != 0)
{ {
FreePages(address, size / KMemoryManager.PageSize); FreePages(Address, Size / KMemoryManager.PageSize);
} }
} }
public KernelResult AllocatePages(ulong pagesCount, bool backwards, out KPageList pageList) public KernelResult AllocatePages(ulong PagesCount, bool Backwards, out KPageList PageList)
{ {
lock (_blocks) lock (Blocks)
{ {
return AllocatePagesImpl(pagesCount, backwards, out pageList); return AllocatePagesImpl(PagesCount, Backwards, out PageList);
} }
} }
private KernelResult AllocatePagesImpl(ulong pagesCount, bool backwards, out KPageList pageList) private KernelResult AllocatePagesImpl(ulong PagesCount, bool Backwards, out KPageList PageList)
{ {
pageList = new KPageList(); PageList = new KPageList();
if (_blockOrdersCount > 0) if (BlockOrdersCount > 0)
{ {
if (GetFreePagesImpl() < pagesCount) if (GetFreePagesImpl() < PagesCount)
{ {
return KernelResult.OutOfMemory; return KernelResult.OutOfMemory;
} }
} }
else if (pagesCount != 0) else if (PagesCount != 0)
{ {
return KernelResult.OutOfMemory; return KernelResult.OutOfMemory;
} }
for (int blockIndex = _blockOrdersCount - 1; blockIndex >= 0; blockIndex--) for (int BlockIndex = BlockOrdersCount - 1; BlockIndex >= 0; BlockIndex--)
{ {
KMemoryRegionBlock block = _blocks[blockIndex]; KMemoryRegionBlock Block = Blocks[BlockIndex];
ulong bestFitBlockSize = 1UL << block.Order; ulong BestFitBlockSize = 1UL << Block.Order;
ulong blockPagesCount = bestFitBlockSize / KMemoryManager.PageSize; ulong BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
//Check if this is the best fit for this page size. //Check if this is the best fit for this page size.
//If so, try allocating as much requested pages as possible. //If so, try allocating as much requested pages as possible.
while (blockPagesCount <= pagesCount) while (BlockPagesCount <= PagesCount)
{ {
ulong address = 0; ulong Address = 0;
for (int currBlockIndex = blockIndex; for (int CurrBlockIndex = BlockIndex;
currBlockIndex < _blockOrdersCount && address == 0; CurrBlockIndex < BlockOrdersCount && Address == 0;
currBlockIndex++) CurrBlockIndex++)
{ {
block = _blocks[currBlockIndex]; Block = Blocks[CurrBlockIndex];
int index = 0; int Index = 0;
bool zeroMask = false; bool ZeroMask = false;
for (int level = 0; level < block.MaxLevel; level++) for (int Level = 0; Level < Block.MaxLevel; Level++)
{ {
long mask = block.Masks[level][index]; long Mask = Block.Masks[Level][Index];
if (mask == 0) if (Mask == 0)
{ {
zeroMask = true; ZeroMask = true;
break; break;
} }
if (backwards) if (Backwards)
{ {
index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask); Index = (Index * 64 + 63) - BitUtils.CountLeadingZeros64(Mask);
} }
else else
{ {
index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask)); Index = Index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(Mask));
} }
} }
if (block.SizeInBlocksTruncated <= (ulong)index || zeroMask) if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
{ {
continue; continue;
} }
block.FreeCount--; Block.FreeCount--;
int tempIdx = index; int TempIdx = Index;
for (int level = block.MaxLevel - 1; level >= 0; level--, tempIdx /= 64) for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, TempIdx /= 64)
{ {
block.Masks[level][tempIdx / 64] &= ~(1L << (tempIdx & 63)); Block.Masks[Level][TempIdx / 64] &= ~(1L << (TempIdx & 63));
if (block.Masks[level][tempIdx / 64] != 0) if (Block.Masks[Level][TempIdx / 64] != 0)
{ {
break; break;
} }
} }
address = block.StartAligned + ((ulong)index << block.Order); Address = Block.StartAligned + ((ulong)Index << Block.Order);
} }
for (int currBlockIndex = blockIndex; for (int CurrBlockIndex = BlockIndex;
currBlockIndex < _blockOrdersCount && address == 0; CurrBlockIndex < BlockOrdersCount && Address == 0;
currBlockIndex++) CurrBlockIndex++)
{ {
block = _blocks[currBlockIndex]; Block = Blocks[CurrBlockIndex];
int index = 0; int Index = 0;
bool zeroMask = false; bool ZeroMask = false;
for (int level = 0; level < block.MaxLevel; level++) for (int Level = 0; Level < Block.MaxLevel; Level++)
{ {
long mask = block.Masks[level][index]; long Mask = Block.Masks[Level][Index];
if (mask == 0) if (Mask == 0)
{ {
zeroMask = true; ZeroMask = true;
break; break;
} }
if (backwards) if (Backwards)
{ {
index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask)); Index = Index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(Mask));
} }
else else
{ {
index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask); Index = (Index * 64 + 63) - BitUtils.CountLeadingZeros64(Mask);
} }
} }
if (block.SizeInBlocksTruncated <= (ulong)index || zeroMask) if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
{ {
continue; continue;
} }
block.FreeCount--; Block.FreeCount--;
int tempIdx = index; int TempIdx = Index;
for (int level = block.MaxLevel - 1; level >= 0; level--, tempIdx /= 64) for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, TempIdx /= 64)
{ {
block.Masks[level][tempIdx / 64] &= ~(1L << (tempIdx & 63)); Block.Masks[Level][TempIdx / 64] &= ~(1L << (TempIdx & 63));
if (block.Masks[level][tempIdx / 64] != 0) if (Block.Masks[Level][TempIdx / 64] != 0)
{ {
break; break;
} }
} }
address = block.StartAligned + ((ulong)index << block.Order); Address = Block.StartAligned + ((ulong)Index << Block.Order);
} }
//The address being zero means that no free space was found on that order, //The address being zero means that no free space was found on that order,
//just give up and try with the next one. //just give up and try with the next one.
if (address == 0) if (Address == 0)
{ {
break; break;
} }
//If we are using a larger order than best fit, then we should //If we are using a larger order than best fit, then we should
//split it into smaller blocks. //split it into smaller blocks.
ulong firstFreeBlockSize = 1UL << block.Order; ulong FirstFreeBlockSize = 1UL << Block.Order;
if (firstFreeBlockSize > bestFitBlockSize) if (FirstFreeBlockSize > BestFitBlockSize)
{ {
FreePages(address + bestFitBlockSize, (firstFreeBlockSize - bestFitBlockSize) / KMemoryManager.PageSize); FreePages(Address + BestFitBlockSize, (FirstFreeBlockSize - BestFitBlockSize) / KMemoryManager.PageSize);
} }
//Add new allocated page(s) to the pages list. //Add new allocated page(s) to the pages list.
//If an error occurs, then free all allocated pages and fail. //If an error occurs, then free all allocated pages and fail.
KernelResult result = pageList.AddRange(address, blockPagesCount); KernelResult Result = PageList.AddRange(Address, BlockPagesCount);
if (result != KernelResult.Success) if (Result != KernelResult.Success)
{ {
FreePages(address, blockPagesCount); FreePages(Address, BlockPagesCount);
foreach (KPageNode pageNode in pageList) foreach (KPageNode PageNode in PageList)
{ {
FreePages(pageNode.Address, pageNode.PagesCount); FreePages(PageNode.Address, PageNode.PagesCount);
} }
return result; return Result;
} }
pagesCount -= blockPagesCount; PagesCount -= BlockPagesCount;
} }
} }
//Success case, all requested pages were allocated successfully. //Success case, all requested pages were allocated successfully.
if (pagesCount == 0) if (PagesCount == 0)
{ {
return KernelResult.Success; return KernelResult.Success;
} }
//Error case, free allocated pages and return out of memory. //Error case, free allocated pages and return out of memory.
foreach (KPageNode pageNode in pageList) foreach (KPageNode PageNode in PageList)
{ {
FreePages(pageNode.Address, pageNode.PagesCount); FreePages(PageNode.Address, PageNode.PagesCount);
} }
pageList = null; PageList = null;
return KernelResult.OutOfMemory; return KernelResult.OutOfMemory;
} }
public void FreePages(KPageList pageList) public void FreePages(KPageList PageList)
{ {
lock (_blocks) lock (Blocks)
{ {
foreach (KPageNode pageNode in pageList) foreach (KPageNode PageNode in PageList)
{ {
FreePages(pageNode.Address, pageNode.PagesCount); FreePages(PageNode.Address, PageNode.PagesCount);
} }
} }
} }
private void FreePages(ulong address, ulong pagesCount) private void FreePages(ulong Address, ulong PagesCount)
{ {
ulong endAddr = address + pagesCount * KMemoryManager.PageSize; ulong EndAddr = Address + PagesCount * KMemoryManager.PageSize;
int blockIndex = _blockOrdersCount - 1; int BlockIndex = BlockOrdersCount - 1;
ulong addressRounded = 0; ulong AddressRounded = 0;
ulong endAddrTruncated = 0; ulong EndAddrTruncated = 0;
for (; blockIndex >= 0; blockIndex--) for (; BlockIndex >= 0; BlockIndex--)
{ {
KMemoryRegionBlock allocInfo = _blocks[blockIndex]; KMemoryRegionBlock AllocInfo = Blocks[BlockIndex];
int blockSize = 1 << allocInfo.Order; int BlockSize = 1 << AllocInfo.Order;
addressRounded = BitUtils.AlignUp (address, blockSize); AddressRounded = BitUtils.AlignUp (Address, BlockSize);
endAddrTruncated = BitUtils.AlignDown(endAddr, blockSize); EndAddrTruncated = BitUtils.AlignDown(EndAddr, BlockSize);
if (addressRounded < endAddrTruncated) if (AddressRounded < EndAddrTruncated)
{ {
break; break;
} }
} }
void FreeRegion(ulong currAddress) void FreeRegion(ulong CurrAddress)
{ {
for (int currBlockIndex = blockIndex; for (int CurrBlockIndex = BlockIndex;
currBlockIndex < _blockOrdersCount && currAddress != 0; CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
currBlockIndex++) CurrBlockIndex++)
{ {
KMemoryRegionBlock block = _blocks[currBlockIndex]; KMemoryRegionBlock Block = Blocks[CurrBlockIndex];
block.FreeCount++; Block.FreeCount++;
ulong freedBlocks = (currAddress - block.StartAligned) >> block.Order; ulong FreedBlocks = (CurrAddress - Block.StartAligned) >> Block.Order;
int index = (int)freedBlocks; int Index = (int)FreedBlocks;
for (int level = block.MaxLevel - 1; level >= 0; level--, index /= 64) for (int Level = Block.MaxLevel - 1; Level >= 0; Level--, Index /= 64)
{ {
long mask = block.Masks[level][index / 64]; long Mask = Block.Masks[Level][Index / 64];
block.Masks[level][index / 64] = mask | (1L << (index & 63)); Block.Masks[Level][Index / 64] = Mask | (1L << (Index & 63));
if (mask != 0) if (Mask != 0)
{ {
break; break;
} }
} }
int blockSizeDelta = 1 << (block.NextOrder - block.Order); int BlockSizeDelta = 1 << (Block.NextOrder - Block.Order);
int freedBlocksTruncated = BitUtils.AlignDown((int)freedBlocks, blockSizeDelta); int FreedBlocksTruncated = BitUtils.AlignDown((int)FreedBlocks, BlockSizeDelta);
if (!block.TryCoalesce(freedBlocksTruncated, blockSizeDelta)) if (!Block.TryCoalesce(FreedBlocksTruncated, BlockSizeDelta))
{ {
break; break;
} }
currAddress = block.StartAligned + ((ulong)freedBlocksTruncated << block.Order); CurrAddress = Block.StartAligned + ((ulong)FreedBlocksTruncated << Block.Order);
} }
} }
//Free inside aligned region. //Free inside aligned region.
ulong baseAddress = addressRounded; ulong BaseAddress = AddressRounded;
while (baseAddress < endAddrTruncated) while (BaseAddress < EndAddrTruncated)
{ {
ulong blockSize = 1UL << _blocks[blockIndex].Order; ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
FreeRegion(baseAddress); FreeRegion(BaseAddress);
baseAddress += blockSize; BaseAddress += BlockSize;
} }
int nextBlockIndex = blockIndex - 1; int NextBlockIndex = BlockIndex - 1;
//Free region between Address and aligned region start. //Free region between Address and aligned region start.
baseAddress = addressRounded; BaseAddress = AddressRounded;
for (blockIndex = nextBlockIndex; blockIndex >= 0; blockIndex--) for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
{ {
ulong blockSize = 1UL << _blocks[blockIndex].Order; ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
while (baseAddress - blockSize >= address) while (BaseAddress - BlockSize >= Address)
{ {
baseAddress -= blockSize; BaseAddress -= BlockSize;
FreeRegion(baseAddress); FreeRegion(BaseAddress);
} }
} }
//Free region between aligned region end and End Address. //Free region between aligned region end and End Address.
baseAddress = endAddrTruncated; BaseAddress = EndAddrTruncated;
for (blockIndex = nextBlockIndex; blockIndex >= 0; blockIndex--) for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
{ {
ulong blockSize = 1UL << _blocks[blockIndex].Order; ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
while (baseAddress + blockSize <= endAddr) while (BaseAddress + BlockSize <= EndAddr)
{ {
FreeRegion(baseAddress); FreeRegion(BaseAddress);
baseAddress += blockSize; BaseAddress += BlockSize;
} }
} }
} }
public ulong GetFreePages() public ulong GetFreePages()
{ {
lock (_blocks) lock (Blocks)
{ {
return GetFreePagesImpl(); return GetFreePagesImpl();
} }
@ -411,18 +411,18 @@ namespace Ryujinx.HLE.HOS.Kernel
private ulong GetFreePagesImpl() private ulong GetFreePagesImpl()
{ {
ulong availablePages = 0; ulong AvailablePages = 0;
for (int blockIndex = 0; blockIndex < _blockOrdersCount; blockIndex++) for (int BlockIndex = 0; BlockIndex < BlockOrdersCount; BlockIndex++)
{ {
KMemoryRegionBlock block = _blocks[blockIndex]; KMemoryRegionBlock Block = Blocks[BlockIndex];
ulong blockPagesCount = (1UL << block.Order) / KMemoryManager.PageSize; ulong BlockPagesCount = (1UL << Block.Order) / KMemoryManager.PageSize;
availablePages += blockPagesCount * block.FreeCount; AvailablePages += BlockPagesCount * Block.FreeCount;
} }
return availablePages; return AvailablePages;
} }
} }
} }

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