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

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

View file

@ -7,109 +7,109 @@ namespace Ryujinx.HLE
{
public const long RamSize = 4L * 1024 * 1024 * 1024;
public IntPtr RamPointer { get; }
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 *(_ramPtr + position);
return *((byte*)(RamPtr + Position));
}
public unsafe ushort ReadUInt16(long position)
public unsafe ushort ReadUInt16(long Position)
{
return *((ushort*)(_ramPtr + position));
return *((ushort*)(RamPtr + Position));
}
public unsafe uint ReadUInt32(long position)
public unsafe uint ReadUInt32(long Position)
{
return *((uint*)(_ramPtr + position));
return *((uint*)(RamPtr + Position));
}
public unsafe ulong ReadUInt64(long position)
public unsafe ulong ReadUInt64(long Position)
{
return *((ulong*)(_ramPtr + position));
return *((ulong*)(RamPtr + Position));
}
public void WriteSByte(long position, sbyte value)
public void WriteSByte(long Position, sbyte Value)
{
WriteByte(position, (byte)value);
WriteByte(Position, (byte)Value);
}
public void WriteInt16(long position, short value)
public void WriteInt16(long Position, short Value)
{
WriteUInt16(position, (ushort)value);
WriteUInt16(Position, (ushort)Value);
}
public void WriteInt32(long position, int value)
public void WriteInt32(long Position, int Value)
{
WriteUInt32(position, (uint)value);
WriteUInt32(Position, (uint)Value);
}
public void WriteInt64(long position, long value)
public void WriteInt64(long Position, long Value)
{
WriteUInt64(position, (ulong)value);
WriteUInt64(Position, (ulong)Value);
}
public unsafe void WriteByte(long position, byte value)
public unsafe void WriteByte(long Position, byte Value)
{
*(_ramPtr + position) = value;
*((byte*)(RamPtr + Position)) = Value;
}
public unsafe void WriteUInt16(long position, ushort value)
public unsafe void WriteUInt16(long Position, ushort Value)
{
*((ushort*)(_ramPtr + position)) = value;
*((ushort*)(RamPtr + Position)) = Value;
}
public unsafe void WriteUInt32(long position, uint value)
public unsafe void WriteUInt32(long Position, uint Value)
{
*((uint*)(_ramPtr + position)) = value;
*((uint*)(RamPtr + Position)) = Value;
}
public unsafe void WriteUInt64(long position, ulong value)
public unsafe void WriteUInt64(long Position, ulong Value)
{
*((ulong*)(_ramPtr + position)) = value;
*((ulong*)(RamPtr + Position)) = Value;
}
public void FillWithZeros(long position, int size)
public void FillWithZeros(long Position, int Size)
{
int size8 = size & ~(8 - 1);
int Size8 = Size & ~(8 - 1);
for (int offs = 0; offs < size8; offs += 8)
for (int Offs = 0; Offs < Size8; Offs += 8)
{
WriteInt64(position + offs, 0);
WriteInt64(Position + Offs, 0);
}
for (int offs = size8; offs < (size - size8); offs++)
for (int Offs = Size8; Offs < (Size - Size8); Offs++)
{
WriteByte(position + offs, 0);
WriteByte(Position + Offs, 0);
}
}
@ -118,7 +118,7 @@ namespace Ryujinx.HLE
Dispose(true);
}
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 message) : base(message) { }
public InvalidNpdmException(string ExMsg) : base(ExMsg) { }
}
}

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 },
};
_device = device;
this.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)
catch (NotSupportedException NEx)
{
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,25 +1,28 @@
using LibHac;
using System;
using System.Collections.Generic;
using System.Text;
using LibHac;
namespace Ryujinx.HLE.FileSystem.Content
{
public struct LocationEntry
{
public string ContentPath { get; }
public string ContentPath { get; private set; }
public int Flag { get; private set; }
public long TitleId { get; }
public ContentType ContentType { get; }
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)
{
ContentPath = contentPath;
Flag = flag;
TitleId = titleId;
ContentType = contentType;
this.ContentPath = ContentPath;
this.Flag = Flag;
this.TitleId = TitleId;
this.ContentType = ContentType;
}
public void SetFlag(int flag)
public void SetFlag(int Flag)
{
Flag = flag;
this.Flag = Flag;
}
}
}

View file

@ -7,30 +7,30 @@ namespace Ryujinx.HLE.FileSystem.Content
{
internal static class LocationHelper
{
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)
{
_basePath = basePath;
_rootPath = rootPath;
this.BasePath = BasePath;
this.RootPath = RootPath;
CheckIfDescendentOfRootPath(basePath);
CheckIfDescendentOfRootPath(BasePath);
}
public long CreateDirectory(string name)
public long CreateDirectory(string Name)
{
CheckIfDescendentOfRootPath(name);
CheckIfDescendentOfRootPath(Name);
if (Directory.Exists(name))
if (Directory.Exists(Name))
{
return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists);
}
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,40 +1,41 @@
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)
{
_pfs = pfs;
this.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 == "/";
return Name == "/" ? true : false;
}
public bool FileExists(string name)
public bool FileExists(string Name)
{
name = name.TrimStart('/');
Name = Name.TrimStart('/');
return _pfs.FileExists(name);
return Pfs.FileExists(Name);
}
public long OpenDirectory(string name, int filterFlags, out IDirectory directoryInterface)
public long OpenDirectory(string Name, int FilterFlags, out IDirectory DirectoryInterface)
{
if (name == "/")
if (Name == "/")
{
directoryInterface = new IDirectory(name, filterFlags, this);
DirectoryInterface = new IDirectory(Name, FilterFlags, this);
return 0;
}
@ -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

@ -4,25 +4,25 @@ namespace Ryujinx.HLE.FileSystem
{
struct SaveInfo
{
public long TitleId { get; }
public long SaveId { get; }
public UInt128 UserId { get; }
public long TitleId { get; private set; }
public long SaveId { get; private set; }
public UInt128 UserId { get; private set; }
public SaveDataType SaveDataType { get; }
public SaveSpaceId SaveSpaceId { get; }
public SaveDataType SaveDataType { get; private set; }
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)
{
TitleId = titleId;
UserId = userId;
SaveId = saveId;
SaveDataType = saveDataType;
SaveSpaceId = saveSpaceId;
this.TitleId = TitleId;
this.UserId = UserId;
this.SaveId = SaveId;
this.SaveDataType = SaveDataType;
this.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)
{
_leftNode = leftNode;
_subscript = subscript;
this.LeftNode = LeftNode;
this.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)
{
_base = Base;
_dimensionExpression = dimensionExpression;
this.Base = Base;
this.DimensionExpression = DimensionExpression;
}
public ArrayType(BaseNode Base, string dimensionString) : base(NodeType.ArrayType)
public ArrayType(BaseNode Base, string DimensionString) : base(NodeType.ArrayType)
{
_base = Base;
_dimensionString = dimensionString;
this.Base = Base;
this.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)
{
Type = type;
this.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)
{
_leftPart = leftPart;
_name = name;
_rightPart = rightPart;
this.LeftPart = LeftPart;
this.Name = Name;
this.RightPart = RightPart;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_name.Equals(">"))
if (Name.Equals(">"))
{
writer.Write("(");
Writer.Write("(");
}
writer.Write("(");
_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)
{
_element = element;
_expression = expression;
_isArrayExpression = isArrayExpression;
this.Element = Element;
this.Expression = Expression;
this.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)
{
_firstNode = firstNode;
_lastNode = lastNode;
_expression = expression;
this.FirstNode = FirstNode;
this.LastNode = LastNode;
this.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)
{
_callee = callee;
this.Callee = Callee;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
_callee.Print(writer);
Callee.Print(Writer);
writer.Write("(");
writer.Write(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)
{
_kind = kind;
_to = to;
_from = from;
this.Kind = Kind;
this.To = To;
this.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)
{
_thenNode = thenNode;
_conditionNode = conditionNode;
_elseNode = elseNode;
this.ThenNode = ThenNode;
this.ConditionNode = ConditionNode;
this.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)
{
_typeNode = typeNode;
_expressions = expressions;
this.TypeNode = TypeNode;
this.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)
{
_isDestructor = isDestructor;
this.IsDestructor = IsDestructor;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_isDestructor)
if (IsDestructor)
{
writer.Write("~");
Writer.Write("~");
}
writer.Write(Child.GetName());
Writer.Write(Child.GetName());
}
}
}

View file

@ -4,21 +4,21 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class CtorVtableSpecialName : BaseNode
{
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)
{
_firstType = firstType;
_secondType = secondType;
this.FirstType = FirstType;
this.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)
{
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_isGlobal)
if (IsGlobal)
{
writer.Write("::");
Writer.Write("::");
}
writer.Write("delete");
Writer.Write("delete");
if (_isArrayExpression)
if (IsArrayExpression)
{
writer.Write("[] ");
Writer.Write("[] ");
}
Child.Print(writer);
Child.Print(Writer);
}
}
}

View file

@ -4,12 +4,12 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class DtorName : ParentNode
{
public 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)
{
_elaborated = elaborated;
this.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)
{
_prefix = prefix;
_expression = expression;
_postfix = postfix;
this.Prefix = Prefix;
this.Expression = Expression;
this.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)
{
_name = name;
_params = Params;
_cv = cv;
_ref = Ref;
_attrs = attrs;
_ret = ret;
this.Name = Name;
this.Params = Params;
this.CV = CV;
this.Ref = Ref;
this.Attrs = Attrs;
this.Ret = Ret;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_ret != null)
if (Ret != null)
{
_ret.PrintLeft(writer);
Ret.PrintLeft(Writer);
if (!_ret.HasRightPart())
if (!Ret.HasRightPart())
{
writer.Write(" ");
Writer.Write(" ");
}
}
_name.Print(writer);
Name.Print(Writer);
}
@ -42,35 +42,35 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
return true;
}
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)
{
_isLeftFold = isLeftFold;
_operatorName = operatorName;
_expression = expression;
_initializer = initializer;
this.IsLeftFold = IsLeftFold;
this.OperatorName = OperatorName;
this.Expression = Expression;
this.Initializer = Initializer;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
writer.Write("(");
Writer.Write("(");
if (_isLeftFold && _initializer != null)
if (IsLeftFold && Initializer != null)
{
_initializer.Print(writer);
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)
{
_index = index;
this.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)
{
_number = number;
this.Number = Number;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
writer.Write("fp ");
Writer.Write("fp ");
if (_number != null)
if (Number != null)
{
writer.Write(_number);
Writer.Write(Number);
}
}
}

View file

@ -4,47 +4,47 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class FunctionType : BaseNode
{
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)
{
_returnType = returnType;
_params = Params;
_cvQualifier = cvQualifier;
_referenceQualifier = referenceQualifier;
_exceptionSpec = exceptionSpec;
this.ReturnType = ReturnType;
this.Params = Params;
this.CVQualifier = CVQualifier;
this.ReferenceQualifier = ReferenceQualifier;
this.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)
{
_typeNode = typeNode;
_nodes = nodes;
this.TypeNode = TypeNode;
this.Nodes = Nodes;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_typeNode != null)
if (TypeNode != null)
{
_typeNode.Print(writer);
TypeNode.Print(Writer);
}
writer.Write("{");
writer.Write(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)
{
_number = number;
this.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 _literalName;
private string _literalValue;
private string LitteralName;
private string LitteralValue;
public IntegerLiteral(string literalName, string literalValue) : base(NodeType.IntegerLiteral)
public IntegerLiteral(string LitteralName, string LitteralValue) : base(NodeType.IntegerLiteral)
{
_literalValue = literalValue;
_literalName = literalName;
this.LitteralValue = LitteralValue;
this.LitteralName = LitteralName;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_literalName.Length > 3)
if (LitteralName.Length > 3)
{
writer.Write("(");
writer.Write(_literalName);
writer.Write(")");
Writer.Write("(");
Writer.Write(LitteralName);
Writer.Write(")");
}
if (_literalValue[0] == 'n')
if (LitteralValue[0] == 'n')
{
writer.Write("-");
writer.Write(_literalValue.Substring(1));
Writer.Write("-");
Writer.Write(LitteralValue.Substring(1));
}
else
{
writer.Write(_literalValue);
Writer.Write(LitteralValue);
}
if (_literalName.Length <= 3)
if (LitteralName.Length <= 3)
{
writer.Write(_literalName);
Writer.Write(LitteralName);
}
}
}

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{
public class LiteralOperator : ParentNode
{
public 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)
{
_encoding = encoding;
_entity = entity;
this.Encoding = Encoding;
this.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)
{
_leftNode = leftNode;
_kind = kind;
_rightNode = rightNode;
this.LeftNode = LeftNode;
this.Kind = Kind;
this.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)
{
_nameValue = nameValue;
this.NameValue = NameValue;
}
public NameType(string nameValue) : base(NodeType.NameType)
public NameType(string NameValue) : base(NodeType.NameType)
{
_nameValue = nameValue;
this.NameValue = NameValue;
}
public override string GetName()
{
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)
{
_prev = prev;
_templateArgument = templateArgument;
this.Prev = Prev;
this.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)
{
_name = name;
this.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)
{
_expressions = expressions;
_typeNode = typeNode;
_initializers = initializers;
this.Expressions = Expressions;
this.TypeNode = TypeNode;
this.Initializers = Initializers;
_isGlobal = isGlobal;
_isArrayExpression = isArrayExpression;
this.IsGlobal = IsGlobal;
this.IsArrayExpression = IsArrayExpression;
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (_isGlobal)
if (IsGlobal)
{
writer.Write("::operator ");
Writer.Write("::operator ");
}
writer.Write("new ");
Writer.Write("new ");
if (_isArrayExpression)
if (IsArrayExpression)
{
writer.Write("[] ");
Writer.Write("[] ");
}
if (_expressions.Nodes.Count != 0)
if (Expressions.Nodes.Count != 0)
{
writer.Write("(");
_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)
{
Nodes = nodes;
this.Nodes = Nodes;
}
public NodeArray(List<BaseNode> nodes, NodeType type) : base(type)
public NodeArray(List<BaseNode> Nodes, NodeType Type) : base(Type)
{
Nodes = nodes;
this.Nodes = Nodes;
}
public override bool IsArray()
@ -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

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

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)
{
_child = child;
this.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)
{
_operator = Operator;
this.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)
{
_postfixQualifier = postfixQualifier;
this.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)
{
_prefix = prefix;
this.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)
{
_qualifier = qualifier;
_name = name;
this.Qualifier = Qualifier;
this.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)
{
Qualifier = qualifier;
this.Qualifier = Qualifier;
}
public void PrintQualifier(TextWriter writer)
public void PrintQualifier(TextWriter Writer)
{
if ((Qualifier & Cv.Const) != 0)
if ((Qualifier & CV.Const) != 0)
{
writer.Write(" const");
Writer.Write(" const");
}
if ((Qualifier & Cv.Volatile) != 0)
if ((Qualifier & CV.Volatile) != 0)
{
writer.Write(" volatile");
Writer.Write(" volatile");
}
if ((Qualifier & Cv.Restricted) != 0)
if ((Qualifier & CV.Restricted) != 0)
{
writer.Write(" restrict");
Writer.Write(" restrict");
}
}
public override void PrintLeft(TextWriter writer)
public override void PrintLeft(TextWriter Writer)
{
if (Child != null)
{
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)
{
Qualifier = qualifier;
this.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)
{
_reference = reference;
_child = child;
this.Reference = Reference;
this.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)
{
_specialValue = specialValue;
this.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)
{
_specialSubstitutionKey = specialSubstitutionKey;
this.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)
{
_expression = expression;
this.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,
DebugMonitor = 7,
Debug_Monitor = 7,
Lr = 8,
Loader = 9,
IpcCommandInterface = 10,
Ipc = 11,
IPC_Command_Interface = 10,
IPC = 11,
Pm = 15,
Ns = 16,
Socket = 17,
Htc = 18,
NcmContent = 20,
Ncm_Content = 20,
Sm = 21,
RoUserland = 22,
RO_Userland = 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,
PlayReport = 129,
Play_Report = 129,
Ahid = 130,
Qlaunch = 132,
Pcv = 133,
@ -64,23 +64,23 @@ namespace Ryujinx.HLE.HOS
Ec = 144,
ETicket = 145,
Ngc = 146,
ErrorReport = 147,
Error_Report = 147,
Apm = 148,
Profiler = 150,
ErrorUpload = 151,
Error_Upload = 151,
Audio = 153,
Npns = 154,
NpnsHttpStream = 155,
Npns_Http_Stream = 155,
Arp = 157,
Swkbd = 158,
Boot = 159,
NfcMifare = 161,
UserlandAssert = 162,
Nfc_Mifare = 161,
Userland_Assert = 162,
Fatal = 163,
NimShop = 164,
Nim_Shop = 164,
Spsm = 165,
Bgtc = 167,
UserlandCrash = 168,
Userland_Crash = 168,
SRepo = 180,
Dauth = 181,
Hid = 202,
@ -92,10 +92,10 @@ namespace Ryujinx.HLE.HOS
Web = 210,
Grc = 212,
Migration = 216,
MigrationLdcServer = 217,
GeneralWebApplet = 800,
WifiWebAuthApplet = 809,
WhitelistedApplet = 810,
Migration_Ldc_Server = 217,
General_Web_Applet = 800,
Wifi_Web_Auth_Applet = 809,
Whitelisted_Applet = 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)
{
Offset = offset;
Size = size;
this.Offset = Offset;
this.Size = Size;
}
}
private Dictionary<SharedFontType, FontInfo> _fontData;
private Dictionary<SharedFontType, FontInfo> FontData;
public SharedFontManager(Switch device, long physicalAddress)
public SharedFontManager(Switch Device, long PhysicalAddress)
{
_physicalAddress = physicalAddress;
this.PhysicalAddress = PhysicalAddress;
_device = device;
this.Device = Device;
_fontsPath = Path.Combine(device.FileSystem.GetSystemPath(), "fonts");
FontsPath = Path.Combine(Device.FileSystem.GetSystemPath(), "fonts");
}
public void EnsureInitialized(ContentManager contentManager)
public void EnsureInitialized(ContentManager ContentManager)
{
if (_fontData == null)
if (FontData == null)
{
_device.Memory.FillWithZeros(_physicalAddress, Horizon.FontSize);
Device.Memory.FillWithZeros(PhysicalAddress, Horizon.FontSize);
uint fontOffset = 0;
uint FontOffset = 0;
FontInfo CreateFont(string name)
FontInfo CreateFont(string Name)
{
if (contentManager.TryGetFontTitle(name, out long fontTitle))
if (ContentManager.TryGetFontTitle(Name, out long FontTitle))
{
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, ContentType.Data);
string 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

@ -35,34 +35,34 @@ namespace Ryujinx.HLE.HOS
internal long PrivilegedProcessLowestId { get; set; } = 1;
internal long PrivilegedProcessHighestId { get; set; } = 8;
internal Switch Device { get; }
internal Switch Device { get; private set; }
public SystemStateMgr State { get; }
public SystemStateMgr State { get; private set; }
internal bool KernelInitialized { get; }
internal bool KernelInitialized { get; private set; }
internal KResourceLimit ResourceLimit { get; }
internal KResourceLimit ResourceLimit { get; private set; }
internal KMemoryRegionManager[] MemoryRegions { get; }
internal KMemoryRegionManager[] MemoryRegions { get; private set; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; private set; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; private set; }
internal KSlabHeap UserSlabHeapPages { get; }
internal KSlabHeap UserSlabHeapPages { get; private set; }
internal KCriticalSection CriticalSection { get; }
internal KCriticalSection CriticalSection { get; private set; }
internal KScheduler Scheduler { get; }
internal KScheduler Scheduler { get; private set; }
internal KTimeManager TimeManager { get; }
internal KTimeManager TimeManager { get; private set; }
internal KSynchronization Synchronization { get; }
internal KSynchronization Synchronization { get; private set; }
internal KContextIdManager ContextIdManager { get; }
internal KContextIdManager ContextIdManager { get; private set; }
private long _kipId;
private long _processId;
private long _threadUid;
private long KipId;
private long ProcessId;
private long ThreadUid;
internal CountdownEvent ThreadCounter;
@ -72,20 +72,20 @@ namespace Ryujinx.HLE.HOS
internal bool EnableVersionChecks { get; private set; }
internal AppletStateMgr AppletState { get; }
internal AppletStateMgr AppletState { get; private set; }
internal KSharedMemory HidSharedMem { get; }
internal KSharedMemory FontSharedMem { get; }
internal KSharedMemory HidSharedMem { get; private set; }
internal KSharedMemory FontSharedMem { get; private set; }
internal SharedFontManager Font { get; }
internal SharedFontManager Font { get; private set; }
internal ContentManager ContentManager { get; }
internal ContentManager ContentManager { get; private set; }
internal KEvent VsyncEvent { get; }
internal KEvent VsyncEvent { get; private set; }
internal Keyset KeySet { get; private set; }
private bool _hasStarted;
private bool HasStarted;
public Nacp ControlData { get; set; }
@ -93,11 +93,11 @@ namespace Ryujinx.HLE.HOS
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
internal long HidBaseAddress { get; }
internal long HidBaseAddress { get; private set; }
public Horizon(Switch device)
public Horizon(Switch Device)
{
Device = device;
this.Device = Device;
State = new SystemStateMgr();
@ -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)
: new NxStaticObject(input);
IExecutable StaticObject = IsNro
? (IExecutable)new NxRelocatableObject(Input)
: (IExecutable)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

@ -4,24 +4,24 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcBuffDesc
{
public long Position { get; }
public long Size { get; }
public int Flags { get; }
public long Position { get; private set; }
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

@ -5,87 +5,87 @@ namespace Ryujinx.HLE.HOS.Ipc
{
class IpcHandleDesc
{
public bool HasPId { get; }
public bool HasPId { get; private set; }
public long PId { get; }
public long PId { get; private set; }
public int[] ToCopy { get; }
public int[] ToMove { get; }
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)
{
PId = pId;
this.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(PId);
Writer.Write((long)PId);
}
foreach (int handle in ToCopy)
foreach (int Handle in ToCopy)
{
writer.Write(handle);
Writer.Write(Handle);
}
foreach (int handle in ToMove)
foreach (int Handle in ToMove)
{
writer.Write(handle);
Writer.Write(Handle);
}
return ms.ToArray();
return MS.ToArray();
}
}
}

View file

@ -8,61 +8,61 @@ namespace Ryujinx.HLE.HOS.Ipc
static class IpcHandler
{
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

@ -9,13 +9,13 @@ namespace Ryujinx.HLE.HOS.Ipc
public IpcHandleDesc HandleDesc { get; set; }
public List<IpcPtrBuffDesc> PtrBuff { get; }
public List<IpcBuffDesc> SendBuff { get; }
public List<IpcBuffDesc> ReceiveBuff { get; }
public List<IpcBuffDesc> ExchangeBuff { get; }
public List<IpcRecvListBuffDesc> RecvListBuff { get; }
public List<IpcPtrBuffDesc> PtrBuff { get; private set; }
public List<IpcBuffDesc> SendBuff { get; private set; }
public List<IpcBuffDesc> ReceiveBuff { get; private set; }
public List<IpcBuffDesc> ExchangeBuff { get; private set; }
public List<IpcRecvListBuffDesc> RecvListBuff { get; private set; }
public List<int> ObjectIds { get; }
public List<int> ObjectIds { get; private set; }
public byte[] RawData { get; set; }
@ -30,185 +30,183 @@ 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;
}
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x21(int index = 0)
public (long Position, long Size) GetBufferType0x21(int Index = 0)
{
if (PtrBuff.Count > index &&
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);
}
// ReSharper disable once InconsistentNaming
public (long Position, long Size) GetBufferType0x22(int index = 0)
public (long Position, long Size) GetBufferType0x22(int Index = 0)
{
if (RecvListBuff.Count > index &&
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

@ -4,23 +4,23 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcPtrBuffDesc
{
public long Position { get; }
public int Index { get; }
public long Size { get; }
public long Position { get; private set; }
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

@ -4,16 +4,16 @@ namespace Ryujinx.HLE.HOS.Ipc
{
struct IpcRecvListBuffDesc
{
public long Position { get; }
public long Size { get; }
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

@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private class PausableThread
{
public ManualResetEvent Event { get; }
public ManualResetEvent Event { get; private set; }
public bool IsExiting { get; set; }
@ -17,49 +17,49 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private ConcurrentDictionary<Thread, PausableThread> _threads;
private ConcurrentDictionary<Thread, PausableThread> Threads;
public HleCoreManager()
{
_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,138 +14,138 @@ 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
{
public long BaseAddress { get; }
public long BaseAddress { get; private set; }
public ElfSymbol[] Symbols { get; }
public ElfSymbol[] Symbols { get; private set; }
public Image(long baseAddress, ElfSymbol[] symbols)
public Image(long BaseAddress, ElfSymbol[] Symbols)
{
BaseAddress = baseAddress;
Symbols = symbols;
this.BaseAddress = BaseAddress;
this.Symbols = Symbols;
}
}
private List<Image> _images;
private List<Image> Images;
private int _loaded;
private int Loaded;
public HleProcessDebugger(KProcess owner)
public HleProcessDebugger(KProcess Owner)
{
_owner = owner;
this.Owner = Owner;
_images = new List<Image>();
Images = new List<Image>();
}
public void PrintGuestStackTrace(CpuThreadState threadState)
public void PrintGuestStackTrace(CpuThreadState ThreadState)
{
EnsureLoaded();
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; }
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 < CpuCoresCount; core++)
for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++)
{
KCoreContext coreContext = CoreContexts[core];
KCoreContext CoreContext = CoreContexts[Core];
if (coreContext.ContextSwitchNeeded && (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false))
if (CoreContext.ContextSwitchNeeded && (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false))
{
coreContext.ContextSwitch();
CoreContext.ContextSwitch();
}
if (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false)
if (CoreContext.CurrentThread?.Context.IsCurrentThread() ?? false)
{
selectedCount++;
SelectedCount++;
}
}
if (selectedCount == 0)
if (SelectedCount == 0)
{
CoreManager.Reset(Thread.CurrentThread);
}
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)
{
_system = system;
this.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)
{
System = system;
this.System = System;
}
public virtual KernelResult SetName(string name)
public virtual KernelResult SetName(string Name)
{
if (!System.AutoObjectNames.TryAdd(name, this))
if (!System.AutoObjectNames.TryAdd(Name, this))
{
return KernelResult.InvalidState;
}
@ -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)
{
_maxSessions = maxSessions;
_parent = parent;
this.MaxSessions = MaxSessions;
this.Parent = Parent;
}
public new static KernelResult RemoveName(Horizon system, string name)
public new static KernelResult RemoveName(Horizon System, string Name)
{
KAutoObject foundObj = FindNamedObject(system, name);
KAutoObject FoundObj = KAutoObject.FindNamedObject(System, Name);
if (!(foundObj is KClientPort))
if (!(FoundObj is KClientPort))
{
return KernelResult.NotFound;
}
return 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)
{
_scheduler = scheduler;
_coreManager = coreManager;
this.Scheduler = Scheduler;
this.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; }
public object LockObj { get; private set; }
private int _recursionCount;
private int RecursionCount;
public KCriticalSection(Horizon system)
public KCriticalSection(Horizon System)
{
_system = system;
this.System = System;
LockObj = new object();
}
@ -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

@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KEvent
{
public KReadableEvent ReadableEvent { get; }
public KWritableEvent WritableEvent { get; }
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

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

View file

@ -7,148 +7,148 @@ namespace Ryujinx.HLE.HOS.Kernel
private const int SelfThreadHandle = (0x1ffff << 15) | 0;
private const int 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)
{
_system = system;
this.System = System;
}
public KernelResult Initialize(int size)
public KernelResult Initialize(int Size)
{
if ((uint)size > 1024)
if ((uint)Size > 1024)
{
return KernelResult.OutOfMemory;
}
if (size < 1)
if (Size < 1)
{
size = 1024;
Size = 1024;
}
_size = size;
this.Size = Size;
_idCounter = 1;
IdCounter = 1;
_table = new KHandleEntry[size];
Table = new KHandleEntry[Size];
_tableHead = new KHandleEntry(0);
TableHead = new KHandleEntry(0);
KHandleEntry entry = _tableHead;
KHandleEntry Entry = TableHead;
for (int index = 0; index < size; index++)
for (int Index = 0; Index < Size; Index++)
{
_table[index] = entry;
Table[Index] = Entry;
entry.Next = new KHandleEntry(index + 1);
Entry.Next = new KHandleEntry(Index + 1);
entry = entry.Next;
Entry = Entry.Next;
}
_table[size - 1].Next = null;
Table[Size - 1].Next = null;
_nextFreeEntry = _tableHead;
NextFreeEntry = TableHead;
return KernelResult.Success;
}
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) & 0xffff8000) | entry.Index;
Handle = (int)((IdCounter << 15) & (uint)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

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

View file

@ -2,15 +2,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
struct KMemoryArrangeRegion
{
public ulong Address { get; }
public ulong Size { get; }
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public ulong EndAddr => Address + Size;
public KMemoryArrangeRegion(ulong address, ulong size)
public KMemoryArrangeRegion(ulong Address, ulong Size)
{
Address = address;
Size = size;
this.Address = Address;
this.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)
{
BaseAddress = baseAddress;
PagesCount = pagesCount;
State = state;
Attribute = attribute;
Permission = permission;
this.BaseAddress = BaseAddress;
this.PagesCount = PagesCount;
this.State = State;
this.Attribute = Attribute;
this.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)
{
_capacityElements = capacityElements;
this.CapacityElements = CapacityElements;
}
public bool CanAllocate(int count)
public bool CanAllocate(int Count)
{
return (ulong)(Count + count) <= _capacityElements;
return (ulong)(this.Count + Count) <= CapacityElements;
}
}
}

View file

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

File diff suppressed because it is too large Load diff

View file

@ -12,30 +12,30 @@ namespace Ryujinx.HLE.HOS.Kernel
public int Order;
public int 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

@ -6,404 +6,404 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
public ulong Address { get; }
public ulong EndAddr { get; }
public ulong Size { get; }
public ulong Address { get; private set; }
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];
Address = address;
Size = size;
EndAddr = endAddr;
this.Address = Address;
this.Size = Size;
this.EndAddr = EndAddr;
_blockOrdersCount = BlockOrders.Length;
BlockOrdersCount = BlockOrders.Length;
for (int blockIndex = 0; blockIndex < _blockOrdersCount; blockIndex++)
for (int BlockIndex = 0; BlockIndex < BlockOrdersCount; BlockIndex++)
{
_blocks[blockIndex] = new KMemoryRegionBlock();
Blocks[BlockIndex] = new KMemoryRegionBlock();
_blocks[blockIndex].Order = BlockOrders[blockIndex];
Blocks[BlockIndex].Order = BlockOrders[BlockIndex];
int nextOrder = blockIndex == _blockOrdersCount - 1 ? 0 : BlockOrders[blockIndex + 1];
int NextOrder = BlockIndex == BlockOrdersCount - 1 ? 0 : BlockOrders[BlockIndex + 1];
_blocks[blockIndex].NextOrder = nextOrder;
Blocks[BlockIndex].NextOrder = NextOrder;
int currBlockSize = 1 << BlockOrders[blockIndex];
int 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