Adjust naming conventions and general refactoring in HLE Project (#527)

* Rename enum fields

* Naming conventions

* Remove unneeded ".this"

* Remove unneeded semicolons

* Remove unused Usings

* Don't use var

* Remove unneeded enum underlying types

* Explicitly label class visibility

* Remove unneeded @ prefixes

* Remove unneeded commas

* Remove unneeded if expressions

* Method doesn't use unsafe code

* Remove unneeded casts

* Initialized objects don't need an empty constructor

* Remove settings from DotSettings

* Revert "Explicitly label class visibility"

This reverts commit ad5eb5787c.

* Small changes

* Revert external enum renaming

* Changes from feedback

* Apply previous refactorings to the merged code
This commit is contained in:
Alex Barney 2018-12-06 05:16:24 -06:00 committed by gdkchan
parent 3615a70cae
commit fb1d9493a3
298 changed files with 12034 additions and 12037 deletions

View file

@ -9,107 +9,107 @@ namespace Ryujinx.HLE
public IntPtr RamPointer { get; private set; }
private unsafe byte* RamPtr;
private unsafe byte* _ramPtr;
public unsafe DeviceMemory()
{
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 *((byte*)(RamPtr + Position));
return *(_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)
{
*((byte*)(RamPtr + Position)) = Value;
*(_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);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
Marshal.FreeHGlobal(RamPointer);
}

View file

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

View file

@ -8,6 +8,6 @@ namespace Ryujinx.HLE.Exceptions
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
{
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>();
LocationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
SharedFontTitleDictionary = new Dictionary<string, long>()
_sharedFontTitleDictionary = new Dictionary<string, long>
{
{ "FontStandard", 0x0100000000000811 },
{ "FontChineseSimplified", 0x0100000000000814 },
{ "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended" , 0x0100000000000810 },
{ "FontNintendoExtended", 0x0100000000000810 }
};
this.Device = Device;
_device = device;
}
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 ContentPathString = null;
string RegisteredDirectory = null;
string contentDirectory = null;
string contentPathString = null;
string registeredDirectory = null;
try
{
ContentPathString = LocationHelper.GetContentRoot(StorageId);
ContentDirectory = LocationHelper.GetRealPath(Device.FileSystem, ContentPathString);
RegisteredDirectory = Path.Combine(ContentDirectory, "registered");
contentPathString = LocationHelper.GetContentRoot(storageId);
contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered");
}
catch (NotSupportedException NEx)
catch (NotSupportedException)
{
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 + ":",
NcaFile.Name.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
string switchPath = Path.Combine(contentPathString + ":",
ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's
SwitchPath = SwitchPath.Replace('\\', '/');
switchPath = switchPath.Replace('\\', '/');
LocationEntry Entry = new LocationEntry(SwitchPath,
LocationEntry entry = new LocationEntry(switchPath,
0,
(long)Nca.Header.TitleId,
Nca.Header.ContentType);
(long)nca.Header.TitleId,
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();
Nca.Dispose();
NcaFile.Dispose();
ncaFile.Close();
nca.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 + ":",
FilePath.Replace(ContentDirectory, string.Empty).TrimStart('\\'));
string switchPath = Path.Combine(contentPathString + ":",
filePath.Replace(contentDirectory, string.Empty).TrimStart('\\'));
// Change path format to switch's
SwitchPath = SwitchPath.Replace('\\', '/');
switchPath = switchPath.Replace('\\', '/');
LocationEntry Entry = new LocationEntry(SwitchPath,
LocationEntry entry = new LocationEntry(switchPath,
0,
(long)Nca.Header.TitleId,
Nca.Header.ContentType);
(long)nca.Header.TitleId,
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();
Nca.Dispose();
NcaFile.Dispose();
ncaFile.Close();
nca.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];
LinkedListNode<LocationEntry> LocationEntry = LocationList.First;
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
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);
long TitleId = (long)Content.Key.Item1;
ContentType ContentType = Content.Key.Item2;
StorageId Storage = GetInstalledStorage(TitleId, ContentType, StorageId);
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
long titleId = (long)content.Key.Item1;
ContentType contentType = content.Key.Item2;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
return Storage == StorageId;
return storage == storageId;
}
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();
}
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 ?
LocationHelper.GetStorageId(LocationEntry.ContentPath) : StorageId.None;
return locationEntry.ContentPath != null ?
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;
}
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;
}
StorageId StorageId = LocationHelper.GetStorageId(LocationEntry.ContentPath);
string InstalledPath = Device.FileSystem.SwitchPathToSystemPath(LocationEntry.ContentPath);
StorageId storageId = LocationHelper.GetStorageId(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);
Nca Nca = new Nca(Device.System.KeySet, File, false);
bool ContentCheck = Nca.Header.ContentType == ContentType;
FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, file, false);
bool contentCheck = nca.Header.ContentType == contentType;
Nca.Dispose();
File.Dispose();
nca.Dispose();
file.Dispose();
return ContentCheck;
return contentCheck;
}
}
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 =
LocationList.ToList().Find(x => x.TitleId == TitleId && x.ContentType == ContentType);
LocationEntry entry =
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,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using LibHac;
using LibHac;
namespace Ryujinx.HLE.FileSystem.Content
{
@ -12,17 +9,17 @@ namespace Ryujinx.HLE.FileSystem.Content
public long TitleId { get; private set; }
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)
{
this.ContentPath = ContentPath;
this.Flag = Flag;
this.TitleId = TitleId;
this.ContentType = ContentType;
ContentPath = contentPath;
Flag = flag;
TitleId = titleId;
ContentType = contentType;
}
public void SetFlag(int Flag)
public void SetFlag(int flag)
{
this.Flag = Flag;
Flag = flag;
}
}
}

View file

@ -7,30 +7,30 @@ namespace Ryujinx.HLE.FileSystem.Content
{
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:
return Path.Combine(FileSystem.GetBasePath(), SystemNandPath, "Contents");
return Path.Combine(fileSystem.GetBasePath(), SystemNandPath, "Contents");
case ContentPath.UserContent:
return Path.Combine(FileSystem.GetBasePath(), UserNandPath, "Contents");
return Path.Combine(fileSystem.GetBasePath(), UserNandPath, "Contents");
case ContentPath.SdCardContent:
return Path.Combine(FileSystem.GetSdCardPath(), "Nintendo", "Contents");
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents");
case ContentPath.System:
return Path.Combine(BasePath, SystemNandPath);
return Path.Combine(basePath, SystemNandPath);
case ContentPath.User:
return Path.Combine(BasePath, UserNandPath);
return Path.Combine(basePath, UserNandPath);
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:
return ContentPath.SystemContent;
@ -39,13 +39,13 @@ namespace Ryujinx.HLE.FileSystem.Content
case ContentStorageId.SdCard:
return ContentPath.SdCardContent;
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:
return ContentPath.SystemContent;
@ -54,15 +54,15 @@ namespace Ryujinx.HLE.FileSystem.Content
case StorageId.SdCard:
return ContentPath.SdCardContent;
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.System:

View file

@ -10,228 +10,228 @@ namespace Ryujinx.HLE.FileSystem
{
class FileSystemProvider : IFileSystemProvider
{
private readonly string BasePath;
private readonly string RootPath;
private readonly string _basePath;
private readonly string _rootPath;
public FileSystemProvider(string BasePath, string RootPath)
public FileSystemProvider(string basePath, string rootPath)
{
this.BasePath = BasePath;
this.RootPath = RootPath;
_basePath = basePath;
_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);
}
Directory.CreateDirectory(Name);
Directory.CreateDirectory(name);
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);
}
using (FileStream NewFile = File.Create(Name))
using (FileStream newFile = File.Create(name))
{
NewFile.SetLength(Size);
newFile.SetLength(size);
}
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);
}
Directory.Delete(DirName, Recursive);
Directory.Delete(dirName, recursive);
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);
}
else
{
File.Delete(Name);
File.Delete(name);
}
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);
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
FileInfo fileInfo = new FileInfo(file);
DirectoryEntry directoryEntry = new DirectoryEntry(file, DirectoryEntryType.File, fileInfo.Length);
Entries.Add(DirectoryEntry);
entries.Add(directoryEntry);
}
}
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);
DirectoryEntry DirectoryEntry = new DirectoryEntry(File, DirectoryEntryType.File, FileInfo.Length);
FileInfo fileInfo = new FileInfo(file);
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
{
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;
}
DirectoryInterface = null;
directoryInterface = null;
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;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(NewName);
CheckIfDescendentOfRootPath(oldName);
CheckIfDescendentOfRootPath(newName);
if (Directory.Exists(OldName))
if (Directory.Exists(oldName))
{
Directory.Move(OldName, NewName);
Directory.Move(oldName, newName);
}
else
{
@ -241,14 +241,14 @@ namespace Ryujinx.HLE.FileSystem
return 0;
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
CheckIfDescendentOfRootPath(OldName);
CheckIfDescendentOfRootPath(NewName);
CheckIfDescendentOfRootPath(oldName);
CheckIfDescendentOfRootPath(newName);
if (File.Exists(OldName))
if (File.Exists(oldName))
{
File.Move(OldName, NewName);
File.Move(oldName, newName);
}
else
{
@ -258,24 +258,24 @@ namespace Ryujinx.HLE.FileSystem
return 0;
}
public void CheckIfDescendentOfRootPath(string Path)
public void CheckIfDescendentOfRootPath(string path)
{
DirectoryInfo PathInfo = new DirectoryInfo(Path);
DirectoryInfo RootInfo = new DirectoryInfo(RootPath);
DirectoryInfo pathInfo = new DirectoryInfo(path);
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;
}
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,41 +1,40 @@
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.FspSrv;
using System;
namespace Ryujinx.HLE.FileSystem
{
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
{
private Pfs Pfs;
private Pfs _pfs;
public PFsProvider(Pfs Pfs)
public PFsProvider(Pfs pfs)
{
this.Pfs = Pfs;
_pfs = pfs;
}
public long CreateDirectory(string Name)
public long CreateDirectory(string name)
{
throw new NotSupportedException();
}
public long CreateFile(string Name, long Size)
public long CreateFile(string name, long size)
{
throw new NotSupportedException();
}
public long DeleteDirectory(string Name, bool Recursive)
public long DeleteDirectory(string name, bool recursive)
{
throw new NotSupportedException();
}
public long DeleteFile(string Name)
public long DeleteFile(string name)
{
throw new NotSupportedException();
}
public DirectoryEntry[] GetDirectories(string Path)
public DirectoryEntry[] GetDirectories(string path)
{
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;
}
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 == "/" ? true : false;
return name == "/";
}
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;
}
@ -111,34 +111,34 @@ namespace Ryujinx.HLE.FileSystem
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);
FileInterface = new IFile(Stream, Name);
Stream stream = _pfs.OpenFile(name);
fileInterface = new IFile(stream, name);
return 0;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
throw new NotSupportedException();
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
throw new NotSupportedException();
}
public void CheckIfOutsideBasePath(string Path)
public void CheckIfOutsideBasePath(string path)
{
throw new NotSupportedException();
}

View file

@ -12,150 +12,150 @@ namespace Ryujinx.HLE.FileSystem
{
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();
}
public long CreateFile(string Name, long Size)
public long CreateFile(string name, long size)
{
throw new NotSupportedException();
}
public long DeleteDirectory(string Name, bool Recursive)
public long DeleteDirectory(string name, bool recursive)
{
throw new NotSupportedException();
}
public long DeleteFile(string Name)
public long DeleteFile(string name)
{
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;
}
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;
}
DirectoryInterface = null;
directoryInterface = null;
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;
}
FileInterface = null;
fileInterface = null;
return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist);
}
public long RenameDirectory(string OldName, string NewName)
public long RenameDirectory(string oldName, string newName)
{
throw new NotSupportedException();
}
public long RenameFile(string OldName, string NewName)
public long RenameFile(string oldName, string newName)
{
throw new NotSupportedException();
}
public void CheckIfOutsideBasePath(string Path)
public void CheckIfOutsideBasePath(string path)
{
throw new NotSupportedException();
}

View file

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

View file

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

View file

@ -18,40 +18,40 @@ namespace Ryujinx.HLE.FileSystem
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 = 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
{
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 FullPath;
return fullPath;
}
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
@ -60,84 +60,84 @@ namespace Ryujinx.HLE.FileSystem
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 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, "");
int FirstSeparatorOffset = RawPath.IndexOf(Path.DirectorySeparatorChar);
string rawPath = systemPath.Replace(baseSystemPath, "");
int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar);
if (FirstSeparatorOffset == -1)
if (firstSeparatorOffset == -1)
{
return $"{RawPath}:/";
return $"{rawPath}:/";
}
string BasePath = RawPath.Substring(0, FirstSeparatorOffset);
string FileName = RawPath.Substring(FirstSeparatorOffset + 1);
string basePath = rawPath.Substring(0, firstSeparatorOffset);
string fileName = rawPath.Substring(firstSeparatorOffset + 1);
return $"{BasePath}:/{FileName}";
return $"{basePath}:/{fileName}";
}
return null;
}
private string MakeDirAndGetFullPath(string Dir)
private string MakeDirAndGetFullPath(string dir)
{
// Handles Common Switch Content Paths
switch (Dir)
switch (dir)
{
case ContentPath.SdCard:
case "@Sdcard":
Dir = SdCardPath;
dir = SdCardPath;
break;
case ContentPath.User:
Dir = UserNandPath;
dir = UserNandPath;
break;
case ContentPath.System:
Dir = SystemNandPath;
dir = SystemNandPath;
break;
case ContentPath.SdCardContent:
Dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
break;
case ContentPath.UserContent:
Dir = Path.Combine(UserNandPath, "Contents");
dir = Path.Combine(UserNandPath, "Contents");
break;
case ContentPath.SystemContent:
Dir = Path.Combine(SystemNandPath, "Contents");
dir = Path.Combine(SystemNandPath, "Contents");
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()
@ -147,9 +147,9 @@ namespace Ryujinx.HLE.FileSystem
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()

View file

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

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class ArrayType : BaseNode
{
private BaseNode Base;
private BaseNode DimensionExpression;
private string DimensionString;
private BaseNode _base;
private BaseNode _dimensionExpression;
private string _dimensionString;
public ArrayType(BaseNode Base, BaseNode DimensionExpression = null) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionExpression = DimensionExpression;
_base = Base;
_dimensionExpression = dimensionExpression;
}
public ArrayType(BaseNode Base, string DimensionString) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, string dimensionString) : base(NodeType.ArrayType)
{
this.Base = Base;
this.DimensionString = DimensionString;
_base = Base;
_dimensionString = dimensionString;
}
public override bool HasRightPart()
@ -30,30 +30,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
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 ].
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
{
CVQualifierType,
CvQualifierType,
SimpleReferenceType,
NameType,
EncodedFunction,
@ -62,22 +62,22 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public NodeType Type { get; protected set; }
public BaseNode(NodeType Type)
public BaseNode(NodeType type)
{
this.Type = Type;
Type = type;
}
public virtual void Print(TextWriter Writer)
public virtual void Print(TextWriter writer)
{
PrintLeft(Writer);
PrintLeft(writer);
if (HasRightPart())
{
PrintRight(Writer);
PrintRight(writer);
}
}
public abstract void PrintLeft(TextWriter Writer);
public abstract void PrintLeft(TextWriter writer);
public virtual bool HasRightPart()
{
@ -99,15 +99,15 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return null;
}
public virtual void PrintRight(TextWriter Writer) {}
public virtual void PrintRight(TextWriter writer) {}
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
{
private BaseNode LeftPart;
private string Name;
private BaseNode RightPart;
private BaseNode _leftPart;
private string _name;
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)
{
this.LeftPart = LeftPart;
this.Name = Name;
this.RightPart = RightPart;
_leftPart = leftPart;
_name = name;
_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("(");
LeftPart.Print(Writer);
Writer.Write(") ");
writer.Write("(");
_leftPart.Print(writer);
writer.Write(") ");
Writer.Write(Name);
writer.Write(_name);
Writer.Write(" (");
RightPart.Print(Writer);
Writer.Write(")");
writer.Write(" (");
_rightPart.Print(writer);
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
{
private BaseNode Element;
private BaseNode Expression;
private bool IsArrayExpression;
private BaseNode _element;
private BaseNode _expression;
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)
{
this.Element = Element;
this.Expression = Expression;
this.IsArrayExpression = IsArrayExpression;
_element = element;
_expression = expression;
_isArrayExpression = isArrayExpression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (IsArrayExpression)
if (_isArrayExpression)
{
Writer.Write("[");
Element.Print(Writer);
Writer.Write("]");
writer.Write("[");
_element.Print(writer);
writer.Write("]");
}
else
{
Writer.Write(".");
Element.Print(Writer);
writer.Write(".");
_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
{
private BaseNode FirstNode;
private BaseNode LastNode;
private BaseNode Expression;
private BaseNode _firstNode;
private BaseNode _lastNode;
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)
{
this.FirstNode = FirstNode;
this.LastNode = LastNode;
this.Expression = Expression;
_firstNode = firstNode;
_lastNode = lastNode;
_expression = expression;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("[");
FirstNode.Print(Writer);
Writer.Write(" ... ");
LastNode.Print(Writer);
Writer.Write("]");
writer.Write("[");
_firstNode.Print(writer);
writer.Write(" ... ");
_lastNode.Print(writer);
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
{
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)
{
this.Callee = Callee;
_callee = callee;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Callee.Print(Writer);
_callee.Print(writer);
Writer.Write("(");
Writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write(")");
writer.Write("(");
writer.Write(string.Join<BaseNode>(", ", Nodes.ToArray()));
writer.Write(")");
}
}
}

View file

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

View file

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

View file

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

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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 ");
Child.Print(Writer);
writer.Write("operator ");
Child.Print(writer);
}
}
}

View file

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

View file

@ -4,30 +4,30 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DeleteExpression : ParentNode
{
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
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)
{
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_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 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("~");
Child.PrintLeft(Writer);
writer.Write("~");
Child.PrintLeft(writer);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("throw(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -4,18 +4,18 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.Elaborated = Elaborated;
_elaborated = elaborated;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Elaborated);
Writer.Write(" ");
Child.Print(Writer);
writer.Write(_elaborated);
writer.Write(" ");
Child.Print(writer);
}
}
}

View file

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

View file

@ -4,36 +4,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class EncodedFunction : BaseNode
{
private BaseNode Name;
private BaseNode Params;
private BaseNode CV;
private BaseNode Ref;
private BaseNode Attrs;
private BaseNode Ret;
private BaseNode _name;
private BaseNode _params;
private BaseNode _cv;
private BaseNode _ref;
private BaseNode _attrs;
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)
{
this.Name = Name;
this.Params = Params;
this.CV = CV;
this.Ref = Ref;
this.Attrs = Attrs;
this.Ret = Ret;
_name = name;
_params = Params;
_cv = cv;
_ref = Ref;
_attrs = attrs;
_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;
}
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
{
private bool IsLeftFold;
private string OperatorName;
private BaseNode Expression;
private BaseNode Initializer;
private bool _isLeftFold;
private string _operatorName;
private BaseNode _expression;
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)
{
this.IsLeftFold = IsLeftFold;
this.OperatorName = OperatorName;
this.Expression = Expression;
this.Initializer = Initializer;
_isLeftFold = isLeftFold;
_operatorName = operatorName;
_expression = expression;
_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);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(IsLeftFold ? "... " : " ");
Writer.Write(OperatorName);
Writer.Write(!IsLeftFold ? " ..." : " ");
Expression.Print(Writer);
writer.Write(_isLeftFold ? "... " : " ");
writer.Write(_operatorName);
writer.Write(!_isLeftFold ? " ..." : " ");
_expression.Print(writer);
if (!IsLeftFold && Initializer != null)
if (!_isLeftFold && _initializer != null)
{
Initializer.Print(Writer);
Writer.Write(" ");
Writer.Write(OperatorName);
Writer.Write(" ");
_initializer.Print(writer);
writer.Write(" ");
writer.Write(_operatorName);
writer.Write(" ");
}
Writer.Write(")");
writer.Write(")");
}
}
}

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
// TODO: Compute inside the Demangler
public BaseNode Reference;
private int Index;
private int _index;
public ForwardTemplateReference(int Index) : base(NodeType.ForwardTemplateReference)
public ForwardTemplateReference(int index) : base(NodeType.ForwardTemplateReference)
{
this.Index = Index;
_index = index;
}
public override string GetName()
@ -18,14 +18,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
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()

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionParameter : BaseNode
{
private string Number;
private string _number;
public FunctionParameter(string Number) : base(NodeType.FunctionParameter)
public FunctionParameter(string number) : base(NodeType.FunctionParameter)
{
this.Number = Number;
_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
{
private BaseNode ReturnType;
private BaseNode Params;
private BaseNode CVQualifier;
private SimpleReferenceType ReferenceQualifier;
private BaseNode ExceptionSpec;
private BaseNode _returnType;
private BaseNode _params;
private BaseNode _cvQualifier;
private SimpleReferenceType _referenceQualifier;
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)
{
this.ReturnType = ReturnType;
this.Params = Params;
this.CVQualifier = CVQualifier;
this.ReferenceQualifier = ReferenceQualifier;
this.ExceptionSpec = ExceptionSpec;
_returnType = returnType;
_params = Params;
_cvQualifier = cvQualifier;
_referenceQualifier = referenceQualifier;
_exceptionSpec = exceptionSpec;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
ReturnType.PrintLeft(Writer);
Writer.Write(" ");
_returnType.PrintLeft(writer);
writer.Write(" ");
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
Writer.Write("(");
Params.Print(Writer);
Writer.Write(")");
writer.Write("(");
_params.Print(writer);
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(" ");
ReferenceQualifier.PrintQualifier(Writer);
writer.Write(" ");
_referenceQualifier.PrintQualifier(writer);
}
if (ExceptionSpec != null)
if (_exceptionSpec != null)
{
Writer.Write(" ");
ExceptionSpec.Print(Writer);
writer.Write(" ");
_exceptionSpec.Print(writer);
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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("::");
Child.Print(Writer);
writer.Write("::");
Child.Print(writer);
}
}
}

View file

@ -5,25 +5,25 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class InitListExpression : BaseNode
{
private BaseNode TypeNode;
private List<BaseNode> Nodes;
private BaseNode _typeNode;
private List<BaseNode> _nodes;
public InitListExpression(BaseNode TypeNode, List<BaseNode> Nodes) : base(NodeType.InitListExpression)
public InitListExpression(BaseNode typeNode, List<BaseNode> nodes) : base(NodeType.InitListExpression)
{
this.TypeNode = TypeNode;
this.Nodes = Nodes;
_typeNode = typeNode;
_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(string.Join<BaseNode>(", ", Nodes.ToArray()));
Writer.Write("}");
writer.Write("{");
writer.Write(string.Join<BaseNode>(", ", _nodes.ToArray()));
writer.Write("}");
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.Number = Number;
_number = number;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Number);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_number);
}
}
}

View file

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

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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 \"");
Child.PrintLeft(Writer);
Writer.Write("\"");
writer.Write("operator \"");
Child.PrintLeft(writer);
writer.Write("\"");
}
}
}

View file

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

View file

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

View file

@ -4,26 +4,26 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
public NameType(string NameValue) : base(NodeType.NameType)
public NameType(string nameValue) : base(NodeType.NameType)
{
this.NameValue = NameValue;
_nameValue = nameValue;
}
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
{
private BaseNode Prev;
private BaseNode TemplateArgument;
private BaseNode _prev;
private BaseNode _templateArgument;
public NameTypeWithTemplateArguments(BaseNode Prev, BaseNode TemplateArgument) : base(NodeType.NameTypeWithTemplateArguments)
public NameTypeWithTemplateArguments(BaseNode prev, BaseNode templateArgument) : base(NodeType.NameTypeWithTemplateArguments)
{
this.Prev = Prev;
this.TemplateArgument = TemplateArgument;
_prev = prev;
_templateArgument = templateArgument;
}
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);
TemplateArgument.Print(Writer);
_prev.Print(writer);
_templateArgument.Print(writer);
}
}
}

View file

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.Name = Name;
_name = name;
}
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);
Writer.Write("::");
Name.Print(Writer);
Child.Print(writer);
writer.Write("::");
_name.Print(writer);
}
}
}

View file

@ -4,51 +4,51 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class NewExpression : BaseNode
{
private NodeArray Expressions;
private BaseNode TypeNode;
private NodeArray Initializers;
private NodeArray _expressions;
private BaseNode _typeNode;
private NodeArray _initializers;
private bool IsGlobal;
private bool IsArrayExpression;
private bool _isGlobal;
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)
{
this.Expressions = Expressions;
this.TypeNode = TypeNode;
this.Initializers = Initializers;
_expressions = expressions;
_typeNode = typeNode;
_initializers = initializers;
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
_isGlobal = isGlobal;
_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("(");
Expressions.Print(Writer);
Writer.Write(")");
writer.Write("(");
_expressions.Print(writer);
writer.Write(")");
}
TypeNode.Print(Writer);
_typeNode.Print(writer);
if (Initializers.Nodes.Count != 0)
if (_initializers.Nodes.Count != 0)
{
Writer.Write("(");
Initializers.Print(Writer);
Writer.Write(")");
writer.Write("(");
_initializers.Print(writer);
writer.Write(")");
}
}
}

View file

@ -7,14 +7,14 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public List<BaseNode> Nodes { get; protected set; }
public NodeArray(List<BaseNode> Nodes) : base(NodeType.NodeArray)
public NodeArray(List<BaseNode> nodes) : base(NodeType.NodeArray)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public NodeArray(List<BaseNode> Nodes, NodeType Type) : base(Type)
public NodeArray(List<BaseNode> nodes, NodeType type) : base(type)
{
this.Nodes = Nodes;
Nodes = nodes;
}
public override bool IsArray()
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
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 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(");
Child.Print(Writer);
Writer.Write(")");
writer.Write("noexcept(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

@ -5,29 +5,29 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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()
{
foreach (BaseNode Node in Nodes)
foreach (BaseNode node in Nodes)
{
if (Node.HasRightPart())
if (node.HasRightPart())
{
return true;
}

View file

@ -4,20 +4,20 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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 (((PackedTemplateParameter)Child).Nodes.Count != 0)
{
Child.Print(Writer);
Child.Print(writer);
}
}
else
{
Writer.Write("...");
writer.Write("...");
}
}
}

View file

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

View file

@ -4,42 +4,42 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class PointerType : BaseNode
{
private BaseNode Child;
private BaseNode _child;
public PointerType(BaseNode Child) : base(NodeType.PointerType)
public PointerType(BaseNode child) : base(NodeType.PointerType)
{
this.Child = Child;
_child = child;
}
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);
if (Child.IsArray())
_child.PrintLeft(writer);
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
{
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)
{
this.Operator = Operator;
_operator = Operator;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
Writer.Write(Operator);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
writer.Write(_operator);
}
}
}

View file

@ -4,17 +4,17 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.PostfixQualifier = PostfixQualifier;
_postfixQualifier = postfixQualifier;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Child.Print(Writer);
Writer.Write(PostfixQualifier);
Child.Print(writer);
writer.Write(_postfixQualifier);
}
}
}

View file

@ -4,19 +4,19 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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)
{
this.Prefix = Prefix;
_prefix = prefix;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(Prefix);
Writer.Write("(");
Child.Print(Writer);
Writer.Write(")");
writer.Write(_prefix);
writer.Write("(");
Child.Print(writer);
writer.Write(")");
}
}
}

View file

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

View file

@ -2,7 +2,7 @@ using System.IO;
namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public enum CV
public enum Cv
{
None,
Const,
@ -17,41 +17,41 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
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)
{
this.Qualifier = Qualifier;
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)
{
Child.PrintLeft(Writer);
Child.PrintLeft(writer);
}
PrintQualifier(Writer);
PrintQualifier(writer);
}
public override bool HasRightPart()
@ -59,11 +59,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart();
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
if (Child != null)
{
Child.PrintRight(Writer);
Child.PrintRight(writer);
}
}
}
@ -72,36 +72,36 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public Reference Qualifier;
public SimpleReferenceType(Reference Qualifier, BaseNode Child) : base(NodeType.SimpleReferenceType, Child)
public SimpleReferenceType(Reference qualifier, BaseNode child) : base(NodeType.SimpleReferenceType, child)
{
this.Qualifier = Qualifier;
Qualifier = qualifier;
}
public void PrintQualifier(TextWriter Writer)
public void PrintQualifier(TextWriter writer)
{
if ((Qualifier & Reference.LValue) != 0)
{
Writer.Write("&");
writer.Write("&");
}
if ((Qualifier & Reference.RValue) != 0)
{
Writer.Write("&&");
writer.Write("&&");
}
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
if (Child != null)
{
Child.PrintLeft(Writer);
Child.PrintLeft(writer);
}
else if (Qualifier != Reference.None)
{
Writer.Write(" ");
writer.Write(" ");
}
PrintQualifier(Writer);
PrintQualifier(writer);
}
public override bool HasRightPart()
@ -109,11 +109,11 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return Child != null && Child.HasRightPart();
}
public override void PrintRight(TextWriter Writer)
public override void PrintRight(TextWriter writer)
{
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
{
private string Reference;
private BaseNode Child;
private string _reference;
private BaseNode _child;
public ReferenceType(string Reference, BaseNode Child) : base(NodeType.ReferenceType)
public ReferenceType(string reference, BaseNode child) : base(NodeType.ReferenceType)
{
this.Reference = Reference;
this.Child = Child;
_reference = reference;
_child = child;
}
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
{
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)
{
this.SpecialValue = SpecialValue;
_specialValue = specialValue;
}
public override void PrintLeft(TextWriter Writer)
public override void PrintLeft(TextWriter writer)
{
Writer.Write(SpecialValue);
Child.Print(Writer);
writer.Write(_specialValue);
Child.Print(writer);
}
}
}

View file

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

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
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::");
Child.Print(Writer);
writer.Write("std::");
Child.Print(writer);
}
}
}

View file

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

View file

@ -13,116 +13,116 @@ namespace Ryujinx.HLE.HOS.Font
{
class SharedFontManager
{
private Switch Device;
private Switch _device;
private long PhysicalAddress;
private long _physicalAddress;
private string FontsPath;
private string _fontsPath;
private struct FontInfo
{
public int Offset;
public int Size;
public FontInfo(int Offset, int Size)
public FontInfo(int offset, int size)
{
this.Offset = Offset;
this.Size = Size;
Offset = offset;
Size = size;
}
}
private Dictionary<SharedFontType, FontInfo> FontData;
private Dictionary<SharedFontType, FontInfo> _fontData;
public SharedFontManager(Switch Device, long PhysicalAddress)
public SharedFontManager(Switch device, long physicalAddress)
{
this.PhysicalAddress = PhysicalAddress;
_physicalAddress = physicalAddress;
this.Device = Device;
_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 FontPath = Device.FileSystem.SwitchPathToSystemPath(ContentPath);
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, ContentType.Data);
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
if(Name == "FontChineseSimplified")
if(name == "FontChineseSimplified")
{
FileIndex = 1;
fileIndex = 1;
}
FileStream NcaFileStream = new FileStream(FontPath, FileMode.Open, FileAccess.Read);
Nca Nca = new Nca(Device.System.KeySet, NcaFileStream, false);
NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Romfs Romfs = new Romfs(Nca.OpenSection(RomfsSection.SectionNum, false, Device.System.FsIntegrityCheckLevel));
Stream FontFile = Romfs.OpenFile(Romfs.Files[FileIndex]);
FileStream ncaFileStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(_device.System.KeySet, ncaFileStream, false);
NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
Romfs romfs = new Romfs(nca.OpenSection(romfsSection.SectionNum, false, _device.System.FsIntegrityCheckLevel));
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();
Nca.Dispose();
ncaFileStream.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
{
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.SimplifiedChinese, CreateFont("FontChineseSimplified") },
@ -132,39 +132,39 @@ namespace Ryujinx.HLE.HOS.Font
{ SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") }
};
if (FontOffset > Horizon.FontSize)
if (fontOffset > Horizon.FontSize)
{
throw new InvalidSystemResourceException(
$"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. " +
$"(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 Key = 0x49621806;
const int decMagic = 0x18029a7f;
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 + 4, EncryptedSize);
_device.Memory.WriteInt32(position + 0, decMagic);
_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
{
private ConcurrentDictionary<KProcess, IdDictionary> DictByProcess;
private ConcurrentDictionary<KProcess, IdDictionary> _dictByProcess;
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;
}
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);
}
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;
}
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;

View file

@ -8,70 +8,70 @@ namespace Ryujinx.HLE.HOS
public const string TemporaryNroSuffix = ".ryu_tmp.nro";
//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.
WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle);
WriteConfigEntry(memory, ref position, 1, 0, mainThreadHandle);
//NextLoadPath.
WriteConfigEntry(Memory, ref Position, 2, 0, Position + 0x200, Position + 0x400);
WriteConfigEntry(memory, ref position, 2, 0, position + 0x200, position + 0x400);
//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.
WriteConfigEntry(Memory, ref Position, 7);
WriteConfigEntry(memory, ref position, 7);
//EndOfList.
WriteConfigEntry(Memory, ref Position, 0);
WriteConfigEntry(memory, ref position, 0);
}
private static void WriteConfigEntry(
MemoryManager Memory,
ref long Position,
int Key,
int Flags = 0,
long Value0 = 0,
long Value1 = 0)
MemoryManager memory,
ref long position,
int key,
int flags = 0,
long value0 = 0,
long value1 = 0)
{
Memory.WriteInt32(Position + 0x00, Key);
Memory.WriteInt32(Position + 0x04, Flags);
Memory.WriteInt64(Position + 0x08, Value0);
Memory.WriteInt64(Position + 0x10, Value1);
memory.WriteInt32(position + 0x00, key);
memory.WriteInt32(position + 0x04, flags);
memory.WriteInt64(position + 0x08, value0);
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)
{
long Key = Memory.ReadInt64(Position);
long key = memory.ReadInt64(position);
if (Key == 2)
if (key == 2)
{
long Value0 = Memory.ReadInt64(Position + 0x08);
long Value1 = Memory.ReadInt64(Position + 0x10);
long value0 = memory.ReadInt64(position + 0x08);
long value1 = memory.ReadInt64(position + 0x10);
FileName = MemoryHelper.ReadAsciiString(Memory, Value0, Value1 - Value0);
fileName = MemoryHelper.ReadAsciiString(memory, value0, value1 - value0);
break;
}
else if (Key == 0)
else if (key == 0)
{
break;
}
Position += 0x18;
position += 0x18;
}
return FileName;
return fileName;
}
}
}

View file

@ -60,9 +60,9 @@ namespace Ryujinx.HLE.HOS
internal KContextIdManager ContextIdManager { get; private set; }
private long KipId;
private long ProcessId;
private long ThreadUid;
private long _kipId;
private long _processId;
private long _threadUid;
internal CountdownEvent ThreadCounter;
@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS
internal Keyset KeySet { get; private set; }
private bool HasStarted;
private bool _hasStarted;
public Nacp ControlData { get; set; }
@ -95,9 +95,9 @@ namespace Ryujinx.HLE.HOS
internal long HidBaseAddress { get; private set; }
public Horizon(Switch Device)
public Horizon(Switch device)
{
this.Device = Device;
Device = device;
State = new SystemStateMgr();
@ -125,8 +125,8 @@ namespace Ryujinx.HLE.HOS
ContextIdManager = new KContextIdManager();
KipId = InitialKipId;
ProcessId = InitialProcessId;
_kipId = InitialKipId;
_processId = InitialProcessId;
Scheduler.StartAutoPreemptionThread();
@ -140,90 +140,90 @@ namespace Ryujinx.HLE.HOS
//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.
KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.NvServices];
KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];
ulong HidPa = Region.Address;
ulong FontPa = Region.Address + HidSize;
ulong hidPa = region.Address;
ulong fontPa = region.Address + HidSize;
HidBaseAddress = (long)(HidPa - DramMemoryMap.DramBase);
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
KPageList HidPageList = new KPageList();
KPageList FontPageList = new KPageList();
KPageList hidPageList = new KPageList();
KPageList fontPageList = new KPageList();
HidPageList .AddRange(HidPa, HidSize / KMemoryManager.PageSize);
FontPageList.AddRange(FontPa, FontSize / KMemoryManager.PageSize);
hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize);
fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
HidSharedMem = new KSharedMemory(HidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(FontPageList, 0, 0, MemoryPermission.Read);
HidSharedMem = new KSharedMemory(hidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(fontPageList, 0, 0, MemoryPermission.Read);
AppletState = new AppletStateMgr(this);
AppletState.SetFocus(true);
Font = new SharedFontManager(Device, (long)(FontPa - DramMemoryMap.DramBase));
Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));
VsyncEvent = new KEvent(this);
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...");
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
{
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;
}
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!");
}
CurrentTitle = MetaData.ACI0.TitleId.ToString("x16");
CurrentTitle = metaData.Aci0.TitleId.ToString("x16");
LoadNso("rtld");
LoadNso("main");
@ -232,18 +232,18 @@ namespace Ryujinx.HLE.HOS
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");
@ -252,23 +252,23 @@ namespace Ryujinx.HLE.HOS
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");
}
Nca MainNca = null;
Nca PatchNca = null;
Nca ControlNca = null;
Nca mainNca = null;
Nca patchNca = 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))
{
@ -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");
}
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
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 ControlNca = null;
Nca mainNca = 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;
}
@ -384,100 +384,100 @@ namespace Ryujinx.HLE.HOS
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");
return;
}
Stream RomfsStream = MainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
Stream ExefsStream = MainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);
Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, 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");
return;
}
if (RomfsStream == null)
if (romfsStream == null)
{
Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
}
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...");
MetaData = new Npdm(Exefs.OpenFile("main.npdm"));
metaData = new Npdm(exefs.OpenFile("main.npdm"));
}
else
{
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;
}
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()
{
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))
{
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();
}
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!");
}
@ -489,67 +489,67 @@ namespace Ryujinx.HLE.HOS
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)new NxRelocatableObject(Input)
: (IExecutable)new NxStaticObject(Input);
IExecutable staticObject = isNro
? (IExecutable)new NxRelocatableObject(input)
: new NxStaticObject(input);
ProgramLoader.LoadStaticObjects(this, MetaData, new IExecutable[] { StaticObject });
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
}
}
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()
{
string KeyFile = null;
string TitleKeyFile = null;
string ConsoleKeyFile = null;
string keyFile = null;
string titleKeyFile = 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());
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 LocalTitleKeyFile = Path.Combine(BasePath, "title.keys");
string LocalConsoleKeyFile = Path.Combine(BasePath, "console.keys");
string localKeyFile = Path.Combine(basePath, "prod.keys");
string localTitleKeyFile = Path.Combine(basePath, "title.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()
{
return Interlocked.Increment(ref ThreadUid) - 1;
return Interlocked.Increment(ref _threadUid) - 1;
}
internal long GetKipId()
{
return Interlocked.Increment(ref KipId) - 1;
return Interlocked.Increment(ref _kipId) - 1;
}
internal long GetProcessId()
{
return Interlocked.Increment(ref ProcessId) - 1;
return Interlocked.Increment(ref _processId) - 1;
}
public void EnableMultiCoreScheduling()
{
if (!HasStarted)
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = true;
}
@ -584,7 +584,7 @@ namespace Ryujinx.HLE.HOS
public void DisableMultiCoreScheduling()
{
if (!HasStarted)
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = false;
}
@ -595,16 +595,16 @@ namespace Ryujinx.HLE.HOS
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing)
if (disposing)
{
//Force all threads to exit.
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
{
private ConcurrentDictionary<int, object> Objs;
private ConcurrentDictionary<int, object> _objs;
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();
}
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;
}
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);
}
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;
@ -63,11 +63,11 @@ namespace Ryujinx.HLE.HOS
public ICollection<object> Clear()
{
ICollection<object> Values = Objs.Values;
ICollection<object> values = _objs.Values;
Objs.Clear();
_objs.Clear();
return Values;
return values;
}
}
}

View file

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

View file

@ -12,80 +12,80 @@ namespace Ryujinx.HLE.HOS.Ipc
public int[] ToCopy { get; private set; }
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];
ToMove = new int[(Word >> 5) & 0xf];
ToCopy = new int[(word >> 1) & 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));
ToMove = Move ?? throw new ArgumentNullException(nameof(Move));
ToCopy = copy ?? throw new ArgumentNullException(nameof(copy));
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)
{
this.PId = PId;
PId = pId;
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()
{
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 |= (ToMove.Length & 0xf) << 5;
word |= (ToCopy.Length & 0xf) << 1;
word |= (ToMove.Length & 0xf) << 5;
Writer.Write(Word);
writer.Write(word);
if (HasPId)
{
Writer.Write((long)PId);
writer.Write(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
{
public static long IpcCall(
Switch Device,
KProcess Process,
MemoryManager Memory,
KSession Session,
IpcMessage Request,
long CmdPtr)
Switch device,
KProcess process,
MemoryManager memory,
KSession session,
IpcMessage request,
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 ||
Request.Type == IpcMessageType.RequestWithContext)
if (request.Type == IpcMessageType.Request ||
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(
Device,
Process,
Memory,
Session,
Request,
Response,
ReqReader,
ResWriter);
ServiceCtx context = new ServiceCtx(
device,
process,
memory,
session,
request,
response,
reqReader,
resWriter);
Session.Service.CallMethod(Context);
session.Service.CallMethod(context);
Response.RawData = ResMS.ToArray();
response.RawData = resMs.ToArray();
}
}
else if (Request.Type == IpcMessageType.Control ||
Request.Type == IpcMessageType.ControlWithContext)
else if (request.Type == IpcMessageType.Control ||
request.Type == IpcMessageType.ControlWithContext)
{
long Magic = ReqReader.ReadInt64();
long CmdId = ReqReader.ReadInt64();
long magic = reqReader.ReadInt64();
long cmdId = reqReader.ReadInt64();
switch (CmdId)
switch (cmdId)
{
case 0:
{
Request = FillResponse(Response, 0, Session.Service.ConvertToDomain());
request = FillResponse(response, 0, session.Service.ConvertToDomain());
break;
}
case 3:
{
Request = FillResponse(Response, 0, 0x500);
request = FillResponse(response, 0, 0x500);
break;
}
@ -71,73 +71,73 @@ namespace Ryujinx.HLE.HOS.Ipc
case 2:
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!");
}
Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
response.HandleDesc = IpcHandleDesc.MakeMove(handle);
Request = FillResponse(Response, 0);
request = FillResponse(response, 0);
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
}
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;
}
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(Result);
writer.Write(IpcMagic.Sfco);
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

@ -30,183 +30,185 @@ namespace Ryujinx.HLE.HOS.Ipc
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 Word1 = Reader.ReadInt32();
int word0 = reader.ReadInt32();
int word1 = reader.ReadInt32();
Type = (IpcMessageType)(Word0 & 0xffff);
Type = (IpcMessageType)(word0 & 0xffff);
int PtrBuffCount = (Word0 >> 16) & 0xf;
int SendBuffCount = (Word0 >> 20) & 0xf;
int RecvBuffCount = (Word0 >> 24) & 0xf;
int XchgBuffCount = (Word0 >> 28) & 0xf;
int ptrBuffCount = (word0 >> 16) & 0xf;
int sendBuffCount = (word0 >> 20) & 0xf;
int recvBuffCount = (word0 >> 24) & 0xf;
int xchgBuffCount = (word0 >> 28) & 0xf;
int RawDataSize = (Word1 >> 0) & 0x3ff;
int RecvListFlags = (Word1 >> 10) & 0xf;
bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
int rawDataSize = (word1 >> 0) & 0x3ff;
int recvListFlags = (word1 >> 10) & 0xf;
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(ReceiveBuff, RecvBuffCount);
ReadBuff(ExchangeBuff, XchgBuffCount);
ReadBuff(SendBuff, sendBuffCount);
ReadBuff(ReceiveBuff, recvBuffCount);
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 Word1;
int word0;
int word1;
Word0 = (int)Type;
Word0 |= (PtrBuff.Count & 0xf) << 16;
Word0 |= (SendBuff.Count & 0xf) << 20;
Word0 |= (ReceiveBuff.Count & 0xf) << 24;
Word0 |= (ExchangeBuff.Count & 0xf) << 28;
word0 = (int)Type;
word0 |= (PtrBuff.Count & 0xf) << 16;
word0 |= (SendBuff.Count & 0xf) << 20;
word0 |= (ReceiveBuff.Count & 0xf) << 24;
word0 |= (ExchangeBuff.Count & 0xf) << 28;
byte[] HandleData = new byte[0];
byte[] handleData = new byte[0];
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
//padding before Raw Data too, we need to subtract the size of this padding.
//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)
{
Word1 |= 1 << 31;
word1 |= 1 << 31;
}
Writer.Write(Word0);
Writer.Write(Word1);
Writer.Write(HandleData);
writer.Write(word0);
writer.Write(word1);
writer.Write(handleData);
MS.Seek(Pad0, SeekOrigin.Current);
ms.Seek(pad0, SeekOrigin.Current);
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;
}
public (long Position, long Size) GetBufferType0x21(int Index = 0)
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x21(int index = 0)
{
if (PtrBuff.Count > Index &&
PtrBuff[Index].Position != 0 &&
PtrBuff[Index].Size != 0)
if (PtrBuff.Count > index &&
PtrBuff[index].Position != 0 &&
PtrBuff[index].Size != 0)
{
return (PtrBuff[Index].Position, PtrBuff[Index].Size);
return (PtrBuff[index].Position, PtrBuff[index].Size);
}
if (SendBuff.Count > Index &&
SendBuff[Index].Position != 0 &&
SendBuff[Index].Size != 0)
if (SendBuff.Count > index &&
SendBuff[index].Position != 0 &&
SendBuff[index].Size != 0)
{
return (SendBuff[Index].Position, SendBuff[Index].Size);
return (SendBuff[index].Position, SendBuff[index].Size);
}
return (0, 0);
}
public (long Position, long Size) GetBufferType0x22(int Index = 0)
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x22(int index = 0)
{
if (RecvListBuff.Count > Index &&
RecvListBuff[Index].Position != 0 &&
RecvListBuff[Index].Size != 0)
if (RecvListBuff.Count > index &&
RecvListBuff[index].Position != 0 &&
RecvListBuff[index].Size != 0)
{
return (RecvListBuff[Index].Position, RecvListBuff[Index].Size);
return (RecvListBuff[index].Position, RecvListBuff[index].Size);
}
if (ReceiveBuff.Count > Index &&
ReceiveBuff[Index].Position != 0 &&
ReceiveBuff[Index].Size != 0)
if (ReceiveBuff.Count > index &&
ReceiveBuff[index].Position != 0 &&
ReceiveBuff[index].Size != 0)
{
return (ReceiveBuff[Index].Position, ReceiveBuff[Index].Size);
return (ReceiveBuff[index].Position, ReceiveBuff[index].Size);
}
return (0, 0);

View file

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

View file

@ -7,13 +7,13 @@ namespace Ryujinx.HLE.HOS.Ipc
public long Position { get; private set; }
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
{
delegate long ServiceProcessRequest(ServiceCtx Context);
delegate long ServiceProcessRequest(ServiceCtx context);
}

View file

@ -17,49 +17,49 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private ConcurrentDictionary<Thread, PausableThread> Threads;
private ConcurrentDictionary<Thread, PausableThread> _threads;
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.Dispose();
pausableThread.Event.Set();
pausableThread.Event.Dispose();
}
}
}

View file

@ -14,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private const int Mod0 = 'M' << 0 | 'O' << 8 | 'D' << 16 | '0' << 24;
private KProcess Owner;
private KProcess _owner;
private class Image
{
@ -22,130 +22,130 @@ namespace Ryujinx.HLE.HOS.Kernel
public ElfSymbol[] Symbols { get; private set; }
public Image(long BaseAddress, ElfSymbol[] Symbols)
public Image(long baseAddress, ElfSymbol[] symbols)
{
this.BaseAddress = BaseAddress;
this.Symbols = Symbols;
BaseAddress = baseAddress;
Symbols = symbols;
}
}
private List<Image> Images;
private List<Image> _images;
private int Loaded;
private int _loaded;
public HleProcessDebugger(KProcess Owner)
public HleProcessDebugger(KProcess owner)
{
this.Owner = Owner;
_owner = owner;
Images = new List<Image>();
_images = new List<Image>();
}
public void PrintGuestStackTrace(CpuThreadState ThreadState)
public void PrintGuestStackTrace(CpuThreadState threadState)
{
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
{
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 ||
!Owner.CpuMemory.IsMapped(FramePointer) ||
!Owner.CpuMemory.IsMapped(FramePointer + 8))
if ((framePointer & 7) != 0 ||
!_owner.CpuMemory.IsMapped(framePointer) ||
!_owner.CpuMemory.IsMapped(framePointer + 8))
{
break;
}
//Note: This is the return address, we need to subtract one instruction
//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 Right = Image.Symbols.Length - 1;
int left = 0;
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;
}
if ((ulong)Address < (ulong)Symbol.Value)
if ((ulong)address < (ulong)symbol.Value)
{
Right = Middle - 1;
right = middle - 1;
}
else
{
Left = Middle + 1;
left = middle + 1;
}
}
Name = null;
name = null;
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;
}
private string GetGuessedNsoNameFromIndex(int Index)
private string GetGuessedNsoNameFromIndex(int index)
{
if ((uint)Index > 11)
if ((uint)index > 11)
{
return "???";
}
if (Index == 0)
if (index == 0)
{
return "rtld";
}
else if (Index == 1)
else if (index == 1)
{
return "main";
}
else if (Index == GetImagesCount() - 1)
else if (index == GetImagesCount() - 1)
{
return "sdk";
}
else
{
return "subsdk" + (Index - 2);
return "subsdk" + (index - 2);
}
}
private int GetImagesCount()
{
lock (Images)
lock (_images)
{
return Images.Count;
return _images.Count;
}
}
private void EnsureLoaded()
{
if (Interlocked.CompareExchange(ref Loaded, 1, 0) == 0)
if (Interlocked.CompareExchange(ref _loaded, 1, 0) == 0)
{
ScanMemoryForTextSegments();
}
@ -196,115 +196,115 @@ namespace Ryujinx.HLE.HOS.Kernel
private void ScanMemoryForTextSegments()
{
ulong OldAddress = 0;
ulong Address = 0;
ulong oldAddress = 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;
}
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;
}
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;
}
long DynamicOffset = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
long BssStartOffset = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
long BssEndOffset = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
long EhHdrEndOffset = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
long ModObjOffset = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;
long dynamicOffset = memory.ReadInt32(mod0Offset + 0x4) + mod0Offset;
long bssStartOffset = memory.ReadInt32(mod0Offset + 0x8) + mod0Offset;
long bssEndOffset = memory.ReadInt32(mod0Offset + 0xc) + mod0Offset;
long ehHdrStartOffset = memory.ReadInt32(mod0Offset + 0x10) + mod0Offset;
long ehHdrEndOffset = memory.ReadInt32(mod0Offset + 0x14) + mod0Offset;
long modObjOffset = memory.ReadInt32(mod0Offset + 0x18) + mod0Offset;
while (true)
{
long TagVal = Memory.ReadInt64(DynamicOffset + 0);
long Value = Memory.ReadInt64(DynamicOffset + 8);
long tagVal = memory.ReadInt64(dynamicOffset + 0);
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;
}
Dynamic[Tag] = Value;
dynamic[tag] = value;
}
if (!Dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long StrTab) ||
!Dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long SymTab) ||
!Dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long SymEntSize))
if (!dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out long strTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out long symTab) ||
!dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out long symEntSize))
{
return;
}
long StrTblAddr = TextOffset + StrTab;
long SymTblAddr = TextOffset + SymTab;
long strTblAddr = textOffset + strTab;
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 Info = Memory.ReadByte (Address + 4);
int Other = Memory.ReadByte (Address + 5);
int SHIdx = Memory.ReadInt16(Address + 6);
long Value = Memory.ReadInt64(Address + 8);
long Size = Memory.ReadInt64(Address + 16);
int nameIndex = memory.ReadInt32(address + 0);
int info = memory.ReadByte (address + 4);
int other = memory.ReadByte (address + 5);
int shIdx = memory.ReadInt16(address + 6);
long value = memory.ReadInt64(address + 8);
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 int CurrentCore;
private int _currentCore;
public bool MultiCoreScheduling { get; set; }
public HleCoreManager CoreManager { get; private set; }
private bool KeepPreempting;
private bool _keepPreempting;
public void StartAutoPreemptionThread()
{
Thread PreemptionThread = new Thread(PreemptCurrentThread);
Thread preemptionThread = new Thread(PreemptCurrentThread);
KeepPreempting = true;
_keepPreempting = true;
PreemptionThread.Start();
preemptionThread.Start();
}
public void ContextSwitch()
@ -30,28 +30,28 @@ namespace Ryujinx.HLE.HOS.Kernel
{
if (MultiCoreScheduling)
{
int SelectedCount = 0;
int selectedCount = 0;
for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
for (int core = 0; core < 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);
}
else if (SelectedCount == 1)
else if (selectedCount == 1)
{
CoreManager.Set(Thread.CurrentThread);
}
@ -62,41 +62,41 @@ namespace Ryujinx.HLE.HOS.Kernel
}
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
//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;
}
CoreManager.Reset(CurrentThread.Context.Work);
CoreManager.Reset(currentThread.Context.Work);
}
//Advance current core and try picking a thread,
//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;
}
@ -104,7 +104,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//If nothing was running before, then we are on a "external"
//HLE thread, we don't need to wait.
if (!HasThreadExecuting)
if (!hasThreadExecuting)
{
return;
}
@ -119,13 +119,13 @@ namespace Ryujinx.HLE.HOS.Kernel
//Preempts current thread every 10 milliseconds on a round-robin fashion,
//when multi core scheduling is disabled, to try ensuring that all threads
//gets a chance to run.
while (KeepPreempting)
while (_keepPreempting)
{
lock (CoreContexts)
{
KThread CurrentThread = CoreContexts[CurrentCore].CurrentThread;
KThread currentThread = CoreContexts[_currentCore].CurrentThread;
CurrentThread?.Context.RequestInterrupt();
currentThread?.Context.RequestInterrupt();
}
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 Horizon System;
private Horizon _system;
public List<KThread> CondVarThreads;
public List<KThread> ArbiterThreads;
public KAddressArbiter(Horizon System)
public KAddressArbiter(Horizon system)
{
this.System = System;
_system = system;
CondVarThreads = 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.ObjSyncResult = 0;
currentThread.SignaledObj = null;
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;
}
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);
}
CurrentThread.MutexAddress = MutexAddress;
CurrentThread.ThreadHandleForUserMutex = RequesterHandle;
currentThread.MutexAddress = mutexAddress;
currentThread.ThreadHandleForUserMutex = requesterHandle;
MutexOwner.AddMutexWaiter(CurrentThread);
mutexOwner.AddMutexWaiter(currentThread);
CurrentThread.Reschedule(ThreadSchedState.Paused);
currentThread.Reschedule(ThreadSchedState.Paused);
System.CriticalSection.Leave();
System.CriticalSection.Enter();
_system.CriticalSection.Leave();
_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.ObjSyncResult = (int)Result;
newOwnerThread.SignaledObj = null;
newOwnerThread.ObjSyncResult = (int)result;
}
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return Result;
return result;
}
public long WaitProcessWideKeyAtomic(
long MutexAddress,
long CondVarAddress,
int ThreadHandle,
long Timeout)
long mutexAddress,
long condVarAddress,
int threadHandle,
long timeout)
{
System.CriticalSection.Enter();
_system.CriticalSection.Enter();
KThread CurrentThread = System.Scheduler.GetCurrentThread();
KThread currentThread = _system.Scheduler.GetCurrentThread();
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
if (CurrentThread.ShallBeTerminated ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
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.ThreadHandleForUserMutex = ThreadHandle;
CurrentThread.CondVarAddress = CondVarAddress;
currentThread.MutexAddress = mutexAddress;
currentThread.ThreadHandleForUserMutex = threadHandle;
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.ObjSyncResult = 0;
newOwnerThread.SignaledObj = null;
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 (Count >= 1 && --Count == 0)
if (count >= 1 && --count == 0)
{
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.
CurrentProcess.CpuMemory.ClearExclusive(0);
currentProcess.CpuMemory.ClearExclusive(0);
Requester.SignaledObj = null;
Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
requester.SignaledObj = null;
requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return null;
}
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.
CurrentProcess.CpuMemory.WriteInt32(Address, MutexValue | HasListenersMask);
currentProcess.CpuMemory.WriteInt32(address, mutexValue | HasListenersMask);
}
else
{
//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;
}
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.
Requester.SignaledObj = null;
Requester.ObjSyncResult = 0;
requester.SignaledObj = null;
requester.ObjSyncResult = 0;
Requester.ReleaseAndResume();
requester.ReleaseAndResume();
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.
MutexOwner.AddMutexWaiter(Requester);
mutexOwner.AddMutexWaiter(requester);
}
else
{
//Invalid mutex owner.
Requester.SignaledObj = null;
Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
requester.SignaledObj = null;
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 ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
}
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
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);
}
if (CurrentValue == Value)
if (currentValue == value)
{
if (Timeout == 0)
if (timeout == 0)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
}
CurrentThread.MutexAddress = Address;
CurrentThread.WaitingInArbitration = true;
currentThread.MutexAddress = address;
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);
}
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 ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
currentThread.SchedFlags == ThreadSchedState.TerminationPending)
{
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
}
CurrentThread.SignaledObj = null;
CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
currentThread.SignaledObj = null;
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.
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);
}
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;
}
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);
}
CurrentThread.MutexAddress = Address;
CurrentThread.WaitingInArbitration = true;
currentThread.MutexAddress = address;
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);
}
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;
}
}
if (NextIndex != -1)
if (nextIndex != -1)
{
Threads.Insert(NextIndex, Thread);
threads.Insert(nextIndex, thread);
}
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;
}
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);
}
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;
}
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);
}
WakeArbiterThreads(Address, Count);
WakeArbiterThreads(address, count);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
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
//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.
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;
}
}
if (WaitingCount > 0)
if (waitingCount > 0)
{
Offset = WaitingCount <= Count || Count <= 0 ? -1 : 0;
offset = waitingCount <= count || count <= 0 ? -1 : 0;
}
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);
}
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;
}
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);
}
WakeArbiterThreads(Address, Count);
WakeArbiterThreads(address, count);
System.CriticalSection.Leave();
_system.CriticalSection.Leave();
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 (Count >= 1 && --Count == 0)
if (count >= 1 && --count == 0)
{
break;
}
}
while (SignaledThreads.TryDequeue(out KThread Thread))
while (signaledThreads.TryDequeue(out KThread thread))
{
Thread.SignaledObj = null;
Thread.ObjSyncResult = 0;
thread.SignaledObj = null;
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;
public KAutoObject(Horizon System)
public KAutoObject(Horizon system)
{
this.System = System;
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;
}
@ -19,9 +19,9 @@ namespace Ryujinx.HLE.HOS.Kernel
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;
}
@ -29,11 +29,11 @@ namespace Ryujinx.HLE.HOS.Kernel
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;

View file

@ -2,30 +2,30 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KClientPort : KSynchronizationObject
{
private int SessionsCount;
private int CurrentCapacity;
private int MaxSessions;
private int _sessionsCount;
private int _currentCapacity;
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)
{
this.MaxSessions = MaxSessions;
this.Parent = Parent;
_maxSessions = maxSessions;
_parent = parent;
}
public new static KernelResult RemoveName(Horizon System, string Name)
public new static KernelResult RemoveName(Horizon system, string name)
{
KAutoObject FoundObj = KAutoObject.FindNamedObject(System, Name);
KAutoObject foundObj = FindNamedObject(system, name);
if (!(FoundObj is KClientPort))
if (!(foundObj is KClientPort))
{
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
{
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 ||
CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
if (currentThread.ShallBeTerminated ||
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
{
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 int[] IdMasks;
private int[] _idMasks;
private int NextFreeBitHint;
private int _nextFreeBitHint;
public KContextIdManager()
{
IdMasks = new int[IdMasksCount];
_idMasks = new int[IdMasksCount];
}
public int GetId()
{
lock (IdMasks)
lock (_idMasks)
{
int Id = 0;
int id = 0;
if (!TestBit(NextFreeBitHint))
if (!TestBit(_nextFreeBitHint))
{
Id = NextFreeBitHint;
id = _nextFreeBitHint;
}
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;
}
else if (Index == IdMasksCount - 1)
else if (index == IdMasksCount - 1)
{
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
{
private KScheduler Scheduler;
private KScheduler _scheduler;
private HleCoreManager CoreManager;
private HleCoreManager _coreManager;
public bool ContextSwitchNeeded { get; private set; }
@ -17,15 +17,15 @@ namespace Ryujinx.HLE.HOS.Kernel
public KThread CurrentThread { get; private set; }
public KThread SelectedThread { get; private set; }
public KCoreContext(KScheduler Scheduler, HleCoreManager CoreManager)
public KCoreContext(KScheduler scheduler, HleCoreManager coreManager)
{
this.Scheduler = Scheduler;
this.CoreManager = CoreManager;
_scheduler = scheduler;
_coreManager = coreManager;
}
public void SelectThread(KThread Thread)
public void SelectThread(KThread thread)
{
SelectedThread = Thread;
SelectedThread = thread;
if (SelectedThread != CurrentThread)
{
@ -43,10 +43,10 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null)
{
long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
long currentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = CurrentTime;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime;
}
}
@ -58,21 +58,21 @@ namespace Ryujinx.HLE.HOS.Kernel
if (CurrentThread != null)
{
CoreManager.Reset(CurrentThread.Context.Work);
_coreManager.Reset(CurrentThread.Context.Work);
}
CurrentThread = SelectedThread;
if (CurrentThread != null)
{
long CurrentTime = PerformanceCounter.ElapsedMilliseconds;
long currentTime = PerformanceCounter.ElapsedMilliseconds;
CurrentThread.TotalTimeRunning += CurrentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = CurrentTime;
CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime;
CurrentThread.LastScheduledTime = currentTime;
CurrentThread.ClearExclusive();
CoreManager.Set(CurrentThread.Context.Work);
_coreManager.Set(CurrentThread.Context.Work);
CurrentThread.Context.Execute();
}

View file

@ -5,15 +5,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KCriticalSection
{
private Horizon System;
private Horizon _system;
public object LockObj { get; private set; }
private int RecursionCount;
private int _recursionCount;
public KCriticalSection(Horizon System)
public KCriticalSection(Horizon system)
{
this.System = System;
_system = system;
LockObj = new object();
}
@ -22,53 +22,53 @@ namespace Ryujinx.HLE.HOS.Kernel
{
Monitor.Enter(LockObj);
RecursionCount++;
_recursionCount++;
}
public void Leave()
{
if (RecursionCount == 0)
if (_recursionCount == 0)
{
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);
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.
CoreContext.ContextSwitch();
coreContext.ContextSwitch();
}
else if (CurrentHleThread.IsCurrentThread())
else if (currentHleThread.IsCurrentThread())
{
//Thread running on the current core, context switch will block.
DoContextSwitch = true;
doContextSwitch = true;
}
else
{
//Thread running on another core, request a interrupt.
CurrentHleThread.RequestInterrupt();
currentHleThread.RequestInterrupt();
}
}
}
@ -76,7 +76,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
else
{
DoContextSwitch = true;
doContextSwitch = true;
}
}
else
@ -84,9 +84,9 @@ namespace Ryujinx.HLE.HOS.Kernel
Monitor.Exit(LockObj);
}
if (DoContextSwitch)
if (doContextSwitch)
{
System.Scheduler.ContextSwitch();
_system.Scheduler.ContextSwitch();
}
}
}

View file

@ -5,9 +5,9 @@ namespace Ryujinx.HLE.HOS.Kernel
public KReadableEvent ReadableEvent { get; private set; }
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);
}
}

View file

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

View file

@ -7,148 +7,148 @@ namespace Ryujinx.HLE.HOS.Kernel
private const int SelfThreadHandle = (0x1ffff << 15) | 0;
private const int SelfProcessHandle = (0x1ffff << 15) | 1;
private Horizon System;
private Horizon _system;
private KHandleEntry[] Table;
private KHandleEntry[] _table;
private KHandleEntry TableHead;
private KHandleEntry NextFreeEntry;
private KHandleEntry _tableHead;
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)
{
this.System = System;
_system = system;
}
public KernelResult Initialize(int Size)
public KernelResult Initialize(int size)
{
if ((uint)Size > 1024)
if ((uint)size > 1024)
{
return KernelResult.OutOfMemory;
}
if (Size < 1)
if (size < 1)
{
Size = 1024;
size = 1024;
}
this.Size = Size;
_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;
}
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;
}
KHandleEntry Entry = NextFreeEntry;
KHandleEntry entry = _nextFreeEntry;
NextFreeEntry = Entry.Next;
_nextFreeEntry = entry.Next;
Entry.Obj = Obj;
Entry.HandleId = IdCounter;
entry.Obj = obj;
entry.HandleId = _idCounter;
ActiveSlotsCount++;
_activeSlotsCount++;
Handle = (int)((IdCounter << 15) & (uint)0xffff8000) | Entry.Index;
handle = (int)((_idCounter << 15) & 0xffff8000) | entry.Index;
if ((short)(IdCounter + 1) >= 0)
if ((short)(_idCounter + 1) >= 0)
{
IdCounter++;
_idCounter++;
}
else
{
IdCounter = 1;
_idCounter = 1;
}
}
return KernelResult.Success;
}
public bool CloseHandle(int Handle)
public bool CloseHandle(int handle)
{
if ((Handle >> 30) != 0 ||
Handle == SelfThreadHandle ||
Handle == SelfProcessHandle)
if ((handle >> 30) != 0 ||
handle == SelfThreadHandle ||
handle == SelfProcessHandle)
{
return false;
}
int Index = (Handle >> 0) & 0x7fff;
int HandleId = (Handle >> 15);
int index = (handle >> 0) & 0x7fff;
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.Next = NextFreeEntry;
entry.Obj = null;
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 HandleId = (Handle >> 15);
int index = (handle >> 0) & 0x7fff;
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);
}
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
{
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
{
return GetObject<KProcess>(Handle);
return GetObject<KProcess>(handle);
}
}
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.Next = NextFreeEntry;
entry.Obj = null;
entry.Next = _nextFreeEntry;
NextFreeEntry = Entry;
_nextFreeEntry = entry;
}
}
}

View file

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

View file

@ -7,10 +7,10 @@ namespace Ryujinx.HLE.HOS.Kernel
public ulong EndAddr => Address + Size;
public KMemoryArrangeRegion(ulong Address, ulong Size)
public KMemoryArrangeRegion(ulong address, ulong size)
{
this.Address = Address;
this.Size = Size;
Address = address;
Size = size;
}
}
}

View file

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

View file

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

View file

@ -13,21 +13,21 @@ namespace Ryujinx.HLE.HOS.Kernel
public int DeviceRefCount { get; private set; }
public KMemoryInfo(
ulong Address,
ulong Size,
MemoryState State,
MemoryPermission Permission,
MemoryAttribute Attribute,
int IpcRefCount,
int DeviceRefCount)
ulong address,
ulong size,
MemoryState state,
MemoryPermission permission,
MemoryAttribute attribute,
int ipcRefCount,
int deviceRefCount)
{
this.Address = Address;
this.Size = Size;
this.State = State;
this.Attribute = Attribute;
this.Permission = Permission;
this.IpcRefCount = IpcRefCount;
this.DeviceRefCount = DeviceRefCount;
Address = address;
Size = size;
State = state;
Attribute = attribute;
Permission = permission;
IpcRefCount = ipcRefCount;
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 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;
}
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;
}
}
FreeCount -= (ulong)Size;
FreeCount -= (ulong)size;
return true;
}

View file

@ -10,400 +10,400 @@ namespace Ryujinx.HLE.HOS.Kernel
public ulong EndAddr { get; private set; }
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];
this.Address = Address;
this.Size = Size;
this.EndAddr = EndAddr;
Address = address;
Size = size;
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 NextBlockSize = CurrBlockSize;
int currBlockSize = 1 << BlockOrders[blockIndex];
int nextBlockSize = currBlockSize;
if (NextOrder != 0)
if (nextOrder != 0)
{
NextBlockSize = 1 << NextOrder;
nextBlockSize = 1 << nextOrder;
}
ulong StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
ulong EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
ulong startAligned = BitUtils.AlignDown(address, nextBlockSize);
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].SizeInBlocksTruncated = SizeInBlocksTruncated;
Blocks[BlockIndex].SizeInBlocksRounded = SizeInBlocksRounded;
_blocks[blockIndex].StartAligned = startAligned;
_blocks[blockIndex].SizeInBlocksTruncated = sizeInBlocksTruncated;
_blocks[blockIndex].SizeInBlocksRounded = sizeInBlocksRounded;
ulong CurrSizeInBlocks = SizeInBlocksRounded;
ulong currSizeInBlocks = sizeInBlocksRounded;
int MaxLevel = 0;
int maxLevel = 0;
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;
}
}
else if (PagesCount != 0)
else if (pagesCount != 0)
{
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.
//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;
CurrBlockIndex < BlockOrdersCount && Address == 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && address == 0;
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;
}
if (Backwards)
if (backwards)
{
Index = (Index * 64 + 63) - BitUtils.CountLeadingZeros64(Mask);
index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask);
}
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;
}
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;
}
}
Address = Block.StartAligned + ((ulong)Index << Block.Order);
address = block.StartAligned + ((ulong)index << block.Order);
}
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && Address == 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && address == 0;
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;
}
if (Backwards)
if (backwards)
{
Index = Index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(Mask));
index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask));
}
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;
}
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;
}
}
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,
//just give up and try with the next one.
if (Address == 0)
if (address == 0)
{
break;
}
//If we are using a larger order than best fit, then we should
//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.
//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.
if (PagesCount == 0)
if (pagesCount == 0)
{
return KernelResult.Success;
}
//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;
}
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 EndAddrTruncated = 0;
ulong addressRounded = 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);
EndAddrTruncated = BitUtils.AlignDown(EndAddr, BlockSize);
addressRounded = BitUtils.AlignUp (address, blockSize);
endAddrTruncated = BitUtils.AlignDown(endAddr, blockSize);
if (AddressRounded < EndAddrTruncated)
if (addressRounded < endAddrTruncated)
{
break;
}
}
void FreeRegion(ulong CurrAddress)
void FreeRegion(ulong currAddress)
{
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
CurrBlockIndex++)
for (int currBlockIndex = blockIndex;
currBlockIndex < _blockOrdersCount && currAddress != 0;
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;
}
}
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;
}
CurrAddress = Block.StartAligned + ((ulong)FreedBlocksTruncated << Block.Order);
currAddress = block.StartAligned + ((ulong)freedBlocksTruncated << block.Order);
}
}
//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.
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.
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()
{
lock (Blocks)
lock (_blocks)
{
return GetFreePagesImpl();
}
@ -411,18 +411,18 @@ namespace Ryujinx.HLE.HOS.Kernel
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