diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Common | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Common')
117 files changed, 0 insertions, 8808 deletions
diff --git a/Ryujinx.Common/AsyncWorkQueue.cs b/Ryujinx.Common/AsyncWorkQueue.cs deleted file mode 100644 index 80f8dcfe..00000000 --- a/Ryujinx.Common/AsyncWorkQueue.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading; - -namespace Ryujinx.Common -{ - public sealed class AsyncWorkQueue<T> : IDisposable - { - private readonly Thread _workerThread; - private readonly CancellationTokenSource _cts; - private readonly Action<T> _workerAction; - private readonly BlockingCollection<T> _queue; - - public bool IsCancellationRequested => _cts.IsCancellationRequested; - - public AsyncWorkQueue(Action<T> callback, string name = null) : this(callback, name, new BlockingCollection<T>()) - { - } - - public AsyncWorkQueue(Action<T> callback, string name, BlockingCollection<T> collection) - { - _cts = new CancellationTokenSource(); - _queue = collection; - _workerAction = callback; - _workerThread = new Thread(DoWork) { Name = name }; - - _workerThread.IsBackground = true; - _workerThread.Start(); - } - - private void DoWork() - { - try - { - foreach (var item in _queue.GetConsumingEnumerable(_cts.Token)) - { - _workerAction(item); - } - } - catch (OperationCanceledException) - { - } - } - - public void Cancel() - { - _cts.Cancel(); - } - - public void CancelAfter(int millisecondsDelay) - { - _cts.CancelAfter(millisecondsDelay); - } - - public void CancelAfter(TimeSpan delay) - { - _cts.CancelAfter(delay); - } - - public void Add(T workItem) - { - _queue.Add(workItem); - } - - public void Add(T workItem, CancellationToken cancellationToken) - { - _queue.Add(workItem, cancellationToken); - } - - public bool TryAdd(T workItem) - { - return _queue.TryAdd(workItem); - } - - public bool TryAdd(T workItem, int millisecondsDelay) - { - return _queue.TryAdd(workItem, millisecondsDelay); - } - - public bool TryAdd(T workItem, int millisecondsDelay, CancellationToken cancellationToken) - { - return _queue.TryAdd(workItem, millisecondsDelay, cancellationToken); - } - - public bool TryAdd(T workItem, TimeSpan timeout) - { - return _queue.TryAdd(workItem, timeout); - } - - public void Dispose() - { - _queue.CompleteAdding(); - _cts.Cancel(); - _workerThread.Join(); - - _queue.Dispose(); - _cts.Dispose(); - } - } -} diff --git a/Ryujinx.Common/Collections/IntervalTree.cs b/Ryujinx.Common/Collections/IntervalTree.cs deleted file mode 100644 index b5188cc7..00000000 --- a/Ryujinx.Common/Collections/IntervalTree.cs +++ /dev/null @@ -1,499 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Common.Collections -{ - /// <summary> - /// An Augmented Interval Tree based off of the "TreeDictionary"'s Red-Black Tree. Allows fast overlap checking of ranges. - /// </summary> - /// <typeparam name="K">Key</typeparam> - /// <typeparam name="V">Value</typeparam> - public class IntervalTree<K, V> : IntrusiveRedBlackTreeImpl<IntervalTreeNode<K, V>> where K : IComparable<K> - { - private const int ArrayGrowthSize = 32; - - #region Public Methods - - /// <summary> - /// Gets the values of the interval whose key is <paramref name="key"/>. - /// </summary> - /// <param name="key">Key of the node value to get</param> - /// <param name="overlaps">Overlaps array to place results in</param> - /// <returns>Number of values found</returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - public int Get(K key, ref V[] overlaps) - { - ArgumentNullException.ThrowIfNull(key); - - IntervalTreeNode<K, V> node = GetNode(key); - - if (node == null) - { - return 0; - } - - if (node.Values.Count > overlaps.Length) - { - Array.Resize(ref overlaps, node.Values.Count); - } - - int overlapsCount = 0; - foreach (RangeNode<K, V> value in node.Values) - { - overlaps[overlapsCount++] = value.Value; - } - - return overlapsCount; - } - - /// <summary> - /// Returns the values of the intervals whose start and end keys overlap the given range. - /// </summary> - /// <param name="start">Start of the range</param> - /// <param name="end">End of the range</param> - /// <param name="overlaps">Overlaps array to place results in</param> - /// <param name="overlapCount">Index to start writing results into the array. Defaults to 0</param> - /// <returns>Number of values found</returns> - /// <exception cref="ArgumentNullException"><paramref name="start"/> or <paramref name="end"/> is null</exception> - public int Get(K start, K end, ref V[] overlaps, int overlapCount = 0) - { - ArgumentNullException.ThrowIfNull(start); - ArgumentNullException.ThrowIfNull(end); - - GetValues(Root, start, end, ref overlaps, ref overlapCount); - - return overlapCount; - } - - /// <summary> - /// Adds a new interval into the tree whose start is <paramref name="start"/>, end is <paramref name="end"/> and value is <paramref name="value"/>. - /// </summary> - /// <param name="start">Start of the range to add</param> - /// <param name="end">End of the range to insert</param> - /// <param name="value">Value to add</param> - /// <exception cref="ArgumentNullException"><paramref name="start"/>, <paramref name="end"/> or <paramref name="value"/> are null</exception> - public void Add(K start, K end, V value) - { - ArgumentNullException.ThrowIfNull(start); - ArgumentNullException.ThrowIfNull(end); - ArgumentNullException.ThrowIfNull(value); - - Insert(start, end, value); - } - - /// <summary> - /// Removes the given <paramref name="value"/> from the tree, searching for it with <paramref name="key"/>. - /// </summary> - /// <param name="key">Key of the node to remove</param> - /// <param name="value">Value to remove</param> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - /// <returns>Number of deleted values</returns> - public int Remove(K key, V value) - { - ArgumentNullException.ThrowIfNull(key); - - int removed = Delete(key, value); - - Count -= removed; - - return removed; - } - - /// <summary> - /// Adds all the nodes in the dictionary into <paramref name="list"/>. - /// </summary> - /// <returns>A list of all RangeNodes sorted by Key Order</returns> - public List<RangeNode<K, V>> AsList() - { - List<RangeNode<K, V>> list = new List<RangeNode<K, V>>(); - - AddToList(Root, list); - - return list; - } - - #endregion - - #region Private Methods (BST) - - /// <summary> - /// Adds all RangeNodes that are children of or contained within <paramref name="node"/> into <paramref name="list"/>, in Key Order. - /// </summary> - /// <param name="node">The node to search for RangeNodes within</param> - /// <param name="list">The list to add RangeNodes to</param> - private void AddToList(IntervalTreeNode<K, V> node, List<RangeNode<K, V>> list) - { - if (node == null) - { - return; - } - - AddToList(node.Left, list); - - list.AddRange(node.Values); - - AddToList(node.Right, list); - } - - /// <summary> - /// Retrieve the node reference whose key is <paramref name="key"/>, or null if no such node exists. - /// </summary> - /// <param name="key">Key of the node to get</param> - /// <returns>Node reference in the tree</returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - private IntervalTreeNode<K, V> GetNode(K key) - { - ArgumentNullException.ThrowIfNull(key); - - IntervalTreeNode<K, V> node = Root; - while (node != null) - { - int cmp = key.CompareTo(node.Start); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - return node; - } - } - return null; - } - - /// <summary> - /// Retrieve all values that overlap the given start and end keys. - /// </summary> - /// <param name="start">Start of the range</param> - /// <param name="end">End of the range</param> - /// <param name="overlaps">Overlaps array to place results in</param> - /// <param name="overlapCount">Overlaps count to update</param> - private void GetValues(IntervalTreeNode<K, V> node, K start, K end, ref V[] overlaps, ref int overlapCount) - { - if (node == null || start.CompareTo(node.Max) >= 0) - { - return; - } - - GetValues(node.Left, start, end, ref overlaps, ref overlapCount); - - bool endsOnRight = end.CompareTo(node.Start) > 0; - if (endsOnRight) - { - if (start.CompareTo(node.End) < 0) - { - // Contains this node. Add overlaps to list. - foreach (RangeNode<K,V> overlap in node.Values) - { - if (start.CompareTo(overlap.End) < 0) - { - if (overlaps.Length >= overlapCount) - { - Array.Resize(ref overlaps, overlapCount + ArrayGrowthSize); - } - - overlaps[overlapCount++] = overlap.Value; - } - } - } - - GetValues(node.Right, start, end, ref overlaps, ref overlapCount); - } - } - - /// <summary> - /// Inserts a new node into the tree with a given <paramref name="start"/>, <paramref name="end"/> and <paramref name="value"/>. - /// </summary> - /// <param name="start">Start of the range to insert</param> - /// <param name="end">End of the range to insert</param> - /// <param name="value">Value to insert</param> - private void Insert(K start, K end, V value) - { - IntervalTreeNode<K, V> newNode = BSTInsert(start, end, value); - RestoreBalanceAfterInsertion(newNode); - } - - /// <summary> - /// Propagate an increase in max value starting at the given node, heading up the tree. - /// This should only be called if the max increases - not for rebalancing or removals. - /// </summary> - /// <param name="node">The node to start propagating from</param> - private void PropagateIncrease(IntervalTreeNode<K, V> node) - { - K max = node.Max; - IntervalTreeNode<K, V> ptr = node; - - while ((ptr = ptr.Parent) != null) - { - if (max.CompareTo(ptr.Max) > 0) - { - ptr.Max = max; - } - else - { - break; - } - } - } - - /// <summary> - /// Propagate recalculating max value starting at the given node, heading up the tree. - /// This fully recalculates the max value from all children when there is potential for it to decrease. - /// </summary> - /// <param name="node">The node to start propagating from</param> - private void PropagateFull(IntervalTreeNode<K, V> node) - { - IntervalTreeNode<K, V> ptr = node; - - do - { - K max = ptr.End; - - if (ptr.Left != null && ptr.Left.Max.CompareTo(max) > 0) - { - max = ptr.Left.Max; - } - - if (ptr.Right != null && ptr.Right.Max.CompareTo(max) > 0) - { - max = ptr.Right.Max; - } - - ptr.Max = max; - } while ((ptr = ptr.Parent) != null); - } - - /// <summary> - /// Insertion Mechanism for the interval tree. Similar to a BST insert, with the start of the range as the key. - /// Iterates the tree starting from the root and inserts a new node where all children in the left subtree are less than <paramref name="start"/>, and all children in the right subtree are greater than <paramref name="start"/>. - /// Each node can contain multiple values, and has an end address which is the maximum of all those values. - /// Post insertion, the "max" value of the node and all parents are updated. - /// </summary> - /// <param name="start">Start of the range to insert</param> - /// <param name="end">End of the range to insert</param> - /// <param name="value">Value to insert</param> - /// <returns>The inserted Node</returns> - private IntervalTreeNode<K, V> BSTInsert(K start, K end, V value) - { - IntervalTreeNode<K, V> parent = null; - IntervalTreeNode<K, V> node = Root; - - while (node != null) - { - parent = node; - int cmp = start.CompareTo(node.Start); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - node.Values.Add(new RangeNode<K, V>(start, end, value)); - - if (end.CompareTo(node.End) > 0) - { - node.End = end; - if (end.CompareTo(node.Max) > 0) - { - node.Max = end; - PropagateIncrease(node); - } - } - - Count++; - return node; - } - } - IntervalTreeNode<K, V> newNode = new IntervalTreeNode<K, V>(start, end, value, parent); - if (newNode.Parent == null) - { - Root = newNode; - } - else if (start.CompareTo(parent.Start) < 0) - { - parent.Left = newNode; - } - else - { - parent.Right = newNode; - } - - PropagateIncrease(newNode); - Count++; - return newNode; - } - - /// <summary> - /// Removes instances of <paramref name="value"> from the dictionary after searching for it with <paramref name="key">. - /// </summary> - /// <param name="key">Key to search for</param> - /// <param name="value">Value to delete</param> - /// <returns>Number of deleted values</returns> - private int Delete(K key, V value) - { - IntervalTreeNode<K, V> nodeToDelete = GetNode(key); - - if (nodeToDelete == null) - { - return 0; - } - - int removed = nodeToDelete.Values.RemoveAll(node => node.Value.Equals(value)); - - if (nodeToDelete.Values.Count > 0) - { - if (removed > 0) - { - nodeToDelete.End = nodeToDelete.Values.Max(node => node.End); - - // Recalculate max from children and new end. - PropagateFull(nodeToDelete); - } - - return removed; - } - - IntervalTreeNode<K, V> replacementNode; - - if (LeftOf(nodeToDelete) == null || RightOf(nodeToDelete) == null) - { - replacementNode = nodeToDelete; - } - else - { - replacementNode = PredecessorOf(nodeToDelete); - } - - IntervalTreeNode<K, V> tmp = LeftOf(replacementNode) ?? RightOf(replacementNode); - - if (tmp != null) - { - tmp.Parent = ParentOf(replacementNode); - } - - if (ParentOf(replacementNode) == null) - { - Root = tmp; - } - else if (replacementNode == LeftOf(ParentOf(replacementNode))) - { - ParentOf(replacementNode).Left = tmp; - } - else - { - ParentOf(replacementNode).Right = tmp; - } - - if (replacementNode != nodeToDelete) - { - nodeToDelete.Start = replacementNode.Start; - nodeToDelete.Values = replacementNode.Values; - nodeToDelete.End = replacementNode.End; - nodeToDelete.Max = replacementNode.Max; - } - - PropagateFull(replacementNode); - - if (tmp != null && ColorOf(replacementNode) == Black) - { - RestoreBalanceAfterRemoval(tmp); - } - - return removed; - } - - #endregion - - protected override void RotateLeft(IntervalTreeNode<K, V> node) - { - if (node != null) - { - base.RotateLeft(node); - - PropagateFull(node); - } - } - - protected override void RotateRight(IntervalTreeNode<K, V> node) - { - if (node != null) - { - base.RotateRight(node); - - PropagateFull(node); - } - } - - public bool ContainsKey(K key) - { - ArgumentNullException.ThrowIfNull(key); - - return GetNode(key) != null; - } - } - - /// <summary> - /// Represents a value and its start and end keys. - /// </summary> - /// <typeparam name="K"></typeparam> - /// <typeparam name="V"></typeparam> - public readonly struct RangeNode<K, V> - { - public readonly K Start; - public readonly K End; - public readonly V Value; - - public RangeNode(K start, K end, V value) - { - Start = start; - End = end; - Value = value; - } - } - - /// <summary> - /// Represents a node in the IntervalTree which contains start and end keys of type K, and a value of generic type V. - /// </summary> - /// <typeparam name="K">Key type of the node</typeparam> - /// <typeparam name="V">Value type of the node</typeparam> - public class IntervalTreeNode<K, V> : IntrusiveRedBlackTreeNode<IntervalTreeNode<K, V>> - { - /// <summary> - /// The start of the range. - /// </summary> - internal K Start; - - /// <summary> - /// The end of the range - maximum of all in the Values list. - /// </summary> - internal K End; - - /// <summary> - /// The maximum end value of this node and all its children. - /// </summary> - internal K Max; - - /// <summary> - /// Values contained on the node that shares a common Start value. - /// </summary> - internal List<RangeNode<K, V>> Values; - - internal IntervalTreeNode(K start, K end, V value, IntervalTreeNode<K, V> parent) - { - Start = start; - End = end; - Max = end; - Values = new List<RangeNode<K, V>> { new RangeNode<K, V>(start, end, value) }; - Parent = parent; - } - } -} diff --git a/Ryujinx.Common/Collections/IntrusiveRedBlackTree.cs b/Ryujinx.Common/Collections/IntrusiveRedBlackTree.cs deleted file mode 100644 index 0063d91e..00000000 --- a/Ryujinx.Common/Collections/IntrusiveRedBlackTree.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; - -namespace Ryujinx.Common.Collections -{ - /// <summary> - /// Tree that provides the ability for O(logN) lookups for keys that exist in the tree, and O(logN) lookups for keys immediately greater than or less than a specified key. - /// </summary> - /// <typeparam name="T">Derived node type</typeparam> - public class IntrusiveRedBlackTree<T> : IntrusiveRedBlackTreeImpl<T> where T : IntrusiveRedBlackTreeNode<T>, IComparable<T> - { - #region Public Methods - - /// <summary> - /// Adds a new node into the tree. - /// </summary> - /// <param name="node">Node to be added</param> - /// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception> - public void Add(T node) - { - ArgumentNullException.ThrowIfNull(node); - - Insert(node); - } - - /// <summary> - /// Removes a node from the tree. - /// </summary> - /// <param name="node">Note to be removed</param> - /// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception> - public void Remove(T node) - { - ArgumentNullException.ThrowIfNull(node); - - if (Delete(node) != null) - { - Count--; - } - } - - /// <summary> - /// Retrieve the node that is considered equal to the specified node by the comparator. - /// </summary> - /// <param name="searchNode">Node to compare with</param> - /// <returns>Node that is equal to <paramref name="searchNode"/></returns> - /// <exception cref="ArgumentNullException"><paramref name="searchNode"/> is null</exception> - public T GetNode(T searchNode) - { - ArgumentNullException.ThrowIfNull(searchNode); - - T node = Root; - while (node != null) - { - int cmp = searchNode.CompareTo(node); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - return node; - } - } - return null; - } - - #endregion - - #region Private Methods (BST) - - /// <summary> - /// Inserts a new node into the tree. - /// </summary> - /// <param name="node">Node to be inserted</param> - private void Insert(T node) - { - T newNode = BSTInsert(node); - RestoreBalanceAfterInsertion(newNode); - } - - /// <summary> - /// Insertion Mechanism for a Binary Search Tree (BST). - /// <br></br> - /// Iterates the tree starting from the root and inserts a new node - /// where all children in the left subtree are less than <paramref name="newNode"/>, - /// and all children in the right subtree are greater than <paramref name="newNode"/>. - /// </summary> - /// <param name="newNode">Node to be inserted</param> - /// <returns>The inserted Node</returns> - private T BSTInsert(T newNode) - { - T parent = null; - T node = Root; - - while (node != null) - { - parent = node; - int cmp = newNode.CompareTo(node); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - return node; - } - } - newNode.Parent = parent; - if (parent == null) - { - Root = newNode; - } - else if (newNode.CompareTo(parent) < 0) - { - parent.Left = newNode; - } - else - { - parent.Right = newNode; - } - Count++; - return newNode; - } - - /// <summary> - /// Removes <paramref name="nodeToDelete"/> from the tree, if it exists. - /// </summary> - /// <param name="nodeToDelete">Node to be removed</param> - /// <returns>The deleted Node</returns> - private T Delete(T nodeToDelete) - { - if (nodeToDelete == null) - { - return null; - } - - T old = nodeToDelete; - T child; - T parent; - bool color; - - if (LeftOf(nodeToDelete) == null) - { - child = RightOf(nodeToDelete); - } - else if (RightOf(nodeToDelete) == null) - { - child = LeftOf(nodeToDelete); - } - else - { - T element = Minimum(RightOf(nodeToDelete)); - - child = RightOf(element); - parent = ParentOf(element); - color = ColorOf(element); - - if (child != null) - { - child.Parent = parent; - } - - if (parent == null) - { - Root = child; - } - else if (element == LeftOf(parent)) - { - parent.Left = child; - } - else - { - parent.Right = child; - } - - if (ParentOf(element) == old) - { - parent = element; - } - - element.Color = old.Color; - element.Left = old.Left; - element.Right = old.Right; - element.Parent = old.Parent; - - if (ParentOf(old) == null) - { - Root = element; - } - else if (old == LeftOf(ParentOf(old))) - { - ParentOf(old).Left = element; - } - else - { - ParentOf(old).Right = element; - } - - LeftOf(old).Parent = element; - - if (RightOf(old) != null) - { - RightOf(old).Parent = element; - } - - if (child != null && color == Black) - { - RestoreBalanceAfterRemoval(child); - } - - return old; - } - - parent = ParentOf(nodeToDelete); - color = ColorOf(nodeToDelete); - - if (child != null) - { - child.Parent = parent; - } - - if (parent == null) - { - Root = child; - } - else if (nodeToDelete == LeftOf(parent)) - { - parent.Left = child; - } - else - { - parent.Right = child; - } - - if (child != null && color == Black) - { - RestoreBalanceAfterRemoval(child); - } - - return old; - } - - #endregion - } - - public static class IntrusiveRedBlackTreeExtensions - { - /// <summary> - /// Retrieve the node that is considered equal to the key by the comparator. - /// </summary> - /// <param name="tree">Tree to search at</param> - /// <param name="key">Key of the node to be found</param> - /// <returns>Node that is equal to <paramref name="key"/></returns> - public static N GetNodeByKey<N, K>(this IntrusiveRedBlackTree<N> tree, K key) - where N : IntrusiveRedBlackTreeNode<N>, IComparable<N>, IComparable<K> - where K : struct - { - N node = tree.RootNode; - while (node != null) - { - int cmp = node.CompareTo(key); - if (cmp < 0) - { - node = node.Right; - } - else if (cmp > 0) - { - node = node.Left; - } - else - { - return node; - } - } - return null; - } - } -} diff --git a/Ryujinx.Common/Collections/IntrusiveRedBlackTreeImpl.cs b/Ryujinx.Common/Collections/IntrusiveRedBlackTreeImpl.cs deleted file mode 100644 index bcb2e2a2..00000000 --- a/Ryujinx.Common/Collections/IntrusiveRedBlackTreeImpl.cs +++ /dev/null @@ -1,354 +0,0 @@ -using System; - -namespace Ryujinx.Common.Collections -{ - /// <summary> - /// Tree that provides the ability for O(logN) lookups for keys that exist in the tree, and O(logN) lookups for keys immediately greater than or less than a specified key. - /// </summary> - /// <typeparam name="T">Derived node type</typeparam> - public class IntrusiveRedBlackTreeImpl<T> where T : IntrusiveRedBlackTreeNode<T> - { - protected const bool Black = true; - protected const bool Red = false; - protected T Root = null; - - internal T RootNode => Root; - - /// <summary> - /// Number of nodes on the tree. - /// </summary> - public int Count { get; protected set; } - - /// <summary> - /// Removes all nodes on the tree. - /// </summary> - public void Clear() - { - Root = null; - Count = 0; - } - - /// <summary> - /// Finds the node whose key is immediately greater than <paramref name="node"/>. - /// </summary> - /// <param name="node">Node to find the successor of</param> - /// <returns>Successor of <paramref name="node"/></returns> - internal static T SuccessorOf(T node) - { - if (node.Right != null) - { - return Minimum(node.Right); - } - T parent = node.Parent; - while (parent != null && node == parent.Right) - { - node = parent; - parent = parent.Parent; - } - return parent; - } - - /// <summary> - /// Finds the node whose key is immediately less than <paramref name="node"/>. - /// </summary> - /// <param name="node">Node to find the predecessor of</param> - /// <returns>Predecessor of <paramref name="node"/></returns> - internal static T PredecessorOf(T node) - { - if (node.Left != null) - { - return Maximum(node.Left); - } - T parent = node.Parent; - while (parent != null && node == parent.Left) - { - node = parent; - parent = parent.Parent; - } - return parent; - } - - /// <summary> - /// Returns the node with the largest key where <paramref name="node"/> is considered the root node. - /// </summary> - /// <param name="node">Root node</param> - /// <returns>Node with the maximum key in the tree of <paramref name="node"/></returns> - protected static T Maximum(T node) - { - T tmp = node; - while (tmp.Right != null) - { - tmp = tmp.Right; - } - - return tmp; - } - - /// <summary> - /// Returns the node with the smallest key where <paramref name="node"/> is considered the root node. - /// </summary> - /// <param name="node">Root node</param> - /// <returns>Node with the minimum key in the tree of <paramref name="node"/></returns> - /// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception> - protected static T Minimum(T node) - { - ArgumentNullException.ThrowIfNull(node); - - T tmp = node; - while (tmp.Left != null) - { - tmp = tmp.Left; - } - - return tmp; - } - - protected void RestoreBalanceAfterRemoval(T balanceNode) - { - T ptr = balanceNode; - - while (ptr != Root && ColorOf(ptr) == Black) - { - if (ptr == LeftOf(ParentOf(ptr))) - { - T sibling = RightOf(ParentOf(ptr)); - - if (ColorOf(sibling) == Red) - { - SetColor(sibling, Black); - SetColor(ParentOf(ptr), Red); - RotateLeft(ParentOf(ptr)); - sibling = RightOf(ParentOf(ptr)); - } - if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black) - { - SetColor(sibling, Red); - ptr = ParentOf(ptr); - } - else - { - if (ColorOf(RightOf(sibling)) == Black) - { - SetColor(LeftOf(sibling), Black); - SetColor(sibling, Red); - RotateRight(sibling); - sibling = RightOf(ParentOf(ptr)); - } - SetColor(sibling, ColorOf(ParentOf(ptr))); - SetColor(ParentOf(ptr), Black); - SetColor(RightOf(sibling), Black); - RotateLeft(ParentOf(ptr)); - ptr = Root; - } - } - else - { - T sibling = LeftOf(ParentOf(ptr)); - - if (ColorOf(sibling) == Red) - { - SetColor(sibling, Black); - SetColor(ParentOf(ptr), Red); - RotateRight(ParentOf(ptr)); - sibling = LeftOf(ParentOf(ptr)); - } - if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black) - { - SetColor(sibling, Red); - ptr = ParentOf(ptr); - } - else - { - if (ColorOf(LeftOf(sibling)) == Black) - { - SetColor(RightOf(sibling), Black); - SetColor(sibling, Red); - RotateLeft(sibling); - sibling = LeftOf(ParentOf(ptr)); - } - SetColor(sibling, ColorOf(ParentOf(ptr))); - SetColor(ParentOf(ptr), Black); - SetColor(LeftOf(sibling), Black); - RotateRight(ParentOf(ptr)); - ptr = Root; - } - } - } - SetColor(ptr, Black); - } - - protected void RestoreBalanceAfterInsertion(T balanceNode) - { - SetColor(balanceNode, Red); - while (balanceNode != null && balanceNode != Root && ColorOf(ParentOf(balanceNode)) == Red) - { - if (ParentOf(balanceNode) == LeftOf(ParentOf(ParentOf(balanceNode)))) - { - T sibling = RightOf(ParentOf(ParentOf(balanceNode))); - - if (ColorOf(sibling) == Red) - { - SetColor(ParentOf(balanceNode), Black); - SetColor(sibling, Black); - SetColor(ParentOf(ParentOf(balanceNode)), Red); - balanceNode = ParentOf(ParentOf(balanceNode)); - } - else - { - if (balanceNode == RightOf(ParentOf(balanceNode))) - { - balanceNode = ParentOf(balanceNode); - RotateLeft(balanceNode); - } - SetColor(ParentOf(balanceNode), Black); - SetColor(ParentOf(ParentOf(balanceNode)), Red); - RotateRight(ParentOf(ParentOf(balanceNode))); - } - } - else - { - T sibling = LeftOf(ParentOf(ParentOf(balanceNode))); - - if (ColorOf(sibling) == Red) - { - SetColor(ParentOf(balanceNode), Black); - SetColor(sibling, Black); - SetColor(ParentOf(ParentOf(balanceNode)), Red); - balanceNode = ParentOf(ParentOf(balanceNode)); - } - else - { - if (balanceNode == LeftOf(ParentOf(balanceNode))) - { - balanceNode = ParentOf(balanceNode); - RotateRight(balanceNode); - } - SetColor(ParentOf(balanceNode), Black); - SetColor(ParentOf(ParentOf(balanceNode)), Red); - RotateLeft(ParentOf(ParentOf(balanceNode))); - } - } - } - SetColor(Root, Black); - } - - protected virtual void RotateLeft(T node) - { - if (node != null) - { - T right = RightOf(node); - node.Right = LeftOf(right); - if (node.Right != null) - { - node.Right.Parent = node; - } - T nodeParent = ParentOf(node); - right.Parent = nodeParent; - if (nodeParent == null) - { - Root = right; - } - else if (node == LeftOf(nodeParent)) - { - nodeParent.Left = right; - } - else - { - nodeParent.Right = right; - } - right.Left = node; - node.Parent = right; - } - } - - protected virtual void RotateRight(T node) - { - if (node != null) - { - T left = LeftOf(node); - node.Left = RightOf(left); - if (node.Left != null) - { - node.Left.Parent = node; - } - T nodeParent = ParentOf(node); - left.Parent = nodeParent; - if (nodeParent == null) - { - Root = left; - } - else if (node == RightOf(nodeParent)) - { - nodeParent.Right = left; - } - else - { - nodeParent.Left = left; - } - left.Right = node; - node.Parent = left; - } - } - - #region Safety-Methods - - // These methods save memory by allowing us to forego sentinel nil nodes, as well as serve as protection against NullReferenceExceptions. - - /// <summary> - /// Returns the color of <paramref name="node"/>, or Black if it is null. - /// </summary> - /// <param name="node">Node</param> - /// <returns>The boolean color of <paramref name="node"/>, or black if null</returns> - protected static bool ColorOf(T node) - { - return node == null || node.Color; - } - - /// <summary> - /// Sets the color of <paramref name="node"/> node to <paramref name="color"/>. - /// <br></br> - /// This method does nothing if <paramref name="node"/> is null. - /// </summary> - /// <param name="node">Node to set the color of</param> - /// <param name="color">Color (Boolean)</param> - protected static void SetColor(T node, bool color) - { - if (node != null) - { - node.Color = color; - } - } - - /// <summary> - /// This method returns the left node of <paramref name="node"/>, or null if <paramref name="node"/> is null. - /// </summary> - /// <param name="node">Node to retrieve the left child from</param> - /// <returns>Left child of <paramref name="node"/></returns> - protected static T LeftOf(T node) - { - return node?.Left; - } - - /// <summary> - /// This method returns the right node of <paramref name="node"/>, or null if <paramref name="node"/> is null. - /// </summary> - /// <param name="node">Node to retrieve the right child from</param> - /// <returns>Right child of <paramref name="node"/></returns> - protected static T RightOf(T node) - { - return node?.Right; - } - - /// <summary> - /// Returns the parent node of <paramref name="node"/>, or null if <paramref name="node"/> is null. - /// </summary> - /// <param name="node">Node to retrieve the parent from</param> - /// <returns>Parent of <paramref name="node"/></returns> - protected static T ParentOf(T node) - { - return node?.Parent; - } - - #endregion - } -} diff --git a/Ryujinx.Common/Collections/IntrusiveRedBlackTreeNode.cs b/Ryujinx.Common/Collections/IntrusiveRedBlackTreeNode.cs deleted file mode 100644 index 7143240d..00000000 --- a/Ryujinx.Common/Collections/IntrusiveRedBlackTreeNode.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Ryujinx.Common.Collections -{ - /// <summary> - /// Represents a node in the Red-Black Tree. - /// </summary> - public class IntrusiveRedBlackTreeNode<T> where T : IntrusiveRedBlackTreeNode<T> - { - internal bool Color = true; - internal T Left; - internal T Right; - internal T Parent; - - public T Predecessor => IntrusiveRedBlackTreeImpl<T>.PredecessorOf((T)this); - public T Successor => IntrusiveRedBlackTreeImpl<T>.SuccessorOf((T)this); - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Collections/TreeDictionary.cs b/Ryujinx.Common/Collections/TreeDictionary.cs deleted file mode 100644 index d118a30c..00000000 --- a/Ryujinx.Common/Collections/TreeDictionary.cs +++ /dev/null @@ -1,617 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -namespace Ryujinx.Common.Collections -{ - /// <summary> - /// Dictionary that provides the ability for O(logN) Lookups for keys that exist in the Dictionary, and O(logN) lookups for keys immediately greater than or less than a specified key. - /// </summary> - /// <typeparam name="K">Key</typeparam> - /// <typeparam name="V">Value</typeparam> - public class TreeDictionary<K, V> : IntrusiveRedBlackTreeImpl<Node<K, V>>, IDictionary<K, V> where K : IComparable<K> - { - #region Public Methods - - /// <summary> - /// Returns the value of the node whose key is <paramref name="key"/>, or the default value if no such node exists. - /// </summary> - /// <param name="key">Key of the node value to get</param> - /// <returns>Value associated w/ <paramref name="key"/></returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - public V Get(K key) - { - ArgumentNullException.ThrowIfNull(key); - - Node<K, V> node = GetNode(key); - - if (node == null) - { - return default; - } - - return node.Value; - } - - /// <summary> - /// Adds a new node into the tree whose key is <paramref name="key"/> key and value is <paramref name="value"/>. - /// <br></br> - /// <b>Note:</b> Adding the same key multiple times will cause the value for that key to be overwritten. - /// </summary> - /// <param name="key">Key of the node to add</param> - /// <param name="value">Value of the node to add</param> - /// <exception cref="ArgumentNullException"><paramref name="key"/> or <paramref name="value"/> are null</exception> - public void Add(K key, V value) - { - ArgumentNullException.ThrowIfNull(key); - ArgumentNullException.ThrowIfNull(value); - - Insert(key, value); - } - - /// <summary> - /// Removes the node whose key is <paramref name="key"/> from the tree. - /// </summary> - /// <param name="key">Key of the node to remove</param> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - public void Remove(K key) - { - ArgumentNullException.ThrowIfNull(key); - - if (Delete(key) != null) - { - Count--; - } - } - - /// <summary> - /// Returns the value whose key is equal to or immediately less than <paramref name="key"/>. - /// </summary> - /// <param name="key">Key for which to find the floor value of</param> - /// <returns>Key of node immediately less than <paramref name="key"/></returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - public K Floor(K key) - { - Node<K, V> node = FloorNode(key); - if (node != null) - { - return node.Key; - } - return default; - } - - /// <summary> - /// Returns the node whose key is equal to or immediately greater than <paramref name="key"/>. - /// </summary> - /// <param name="key">Key for which to find the ceiling node of</param> - /// <returns>Key of node immediately greater than <paramref name="key"/></returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - public K Ceiling(K key) - { - Node<K, V> node = CeilingNode(key); - if (node != null) - { - return node.Key; - } - return default; - } - - /// <summary> - /// Finds the value whose key is immediately greater than <paramref name="key"/>. - /// </summary> - /// <param name="key">Key to find the successor of</param> - /// <returns>Value</returns> - public K SuccessorOf(K key) - { - Node<K, V> node = GetNode(key); - if (node != null) - { - Node<K, V> successor = SuccessorOf(node); - - return successor != null ? successor.Key : default; - } - return default; - } - - /// <summary> - /// Finds the value whose key is immediately less than <paramref name="key"/>. - /// </summary> - /// <param name="key">Key to find the predecessor of</param> - /// <returns>Value</returns> - public K PredecessorOf(K key) - { - Node<K, V> node = GetNode(key); - if (node != null) - { - Node<K, V> predecessor = PredecessorOf(node); - - return predecessor != null ? predecessor.Key : default; - } - return default; - } - - /// <summary> - /// Adds all the nodes in the dictionary as key/value pairs into <paramref name="list"/>. - /// <br></br> - /// The key/value pairs will be added in Level Order. - /// </summary> - /// <param name="list">List to add the tree pairs into</param> - public List<KeyValuePair<K, V>> AsLevelOrderList() - { - List<KeyValuePair<K, V>> list = new List<KeyValuePair<K, V>>(); - - Queue<Node<K, V>> nodes = new Queue<Node<K, V>>(); - - if (this.Root != null) - { - nodes.Enqueue(this.Root); - } - while (nodes.TryDequeue(out Node<K, V> node)) - { - list.Add(new KeyValuePair<K, V>(node.Key, node.Value)); - if (node.Left != null) - { - nodes.Enqueue(node.Left); - } - if (node.Right != null) - { - nodes.Enqueue(node.Right); - } - } - return list; - } - - /// <summary> - /// Adds all the nodes in the dictionary into <paramref name="list"/>. - /// </summary> - /// <returns>A list of all KeyValuePairs sorted by Key Order</returns> - public List<KeyValuePair<K, V>> AsList() - { - List<KeyValuePair<K, V>> list = new List<KeyValuePair<K, V>>(); - - AddToList(Root, list); - - return list; - } - - #endregion - - #region Private Methods (BST) - - /// <summary> - /// Adds all nodes that are children of or contained within <paramref name="node"/> into <paramref name="list"/>, in Key Order. - /// </summary> - /// <param name="node">The node to search for nodes within</param> - /// <param name="list">The list to add node to</param> - private void AddToList(Node<K, V> node, List<KeyValuePair<K, V>> list) - { - if (node == null) - { - return; - } - - AddToList(node.Left, list); - - list.Add(new KeyValuePair<K, V>(node.Key, node.Value)); - - AddToList(node.Right, list); - } - - /// <summary> - /// Retrieve the node reference whose key is <paramref name="key"/>, or null if no such node exists. - /// </summary> - /// <param name="key">Key of the node to get</param> - /// <returns>Node reference in the tree</returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - private Node<K, V> GetNode(K key) - { - ArgumentNullException.ThrowIfNull(key); - - Node<K, V> node = Root; - while (node != null) - { - int cmp = key.CompareTo(node.Key); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - return node; - } - } - return null; - } - - /// <summary> - /// Inserts a new node into the tree whose key is <paramref name="key"/> and value is <paramref name="value"/>. - /// <br></br> - /// Adding the same key multiple times will overwrite the previous value. - /// </summary> - /// <param name="key">Key of the node to insert</param> - /// <param name="value">Value of the node to insert</param> - private void Insert(K key, V value) - { - Node<K, V> newNode = BSTInsert(key, value); - RestoreBalanceAfterInsertion(newNode); - } - - /// <summary> - /// Insertion Mechanism for a Binary Search Tree (BST). - /// <br></br> - /// Iterates the tree starting from the root and inserts a new node where all children in the left subtree are less than <paramref name="key"/>, and all children in the right subtree are greater than <paramref name="key"/>. - /// <br></br> - /// <b>Note: </b> If a node whose key is <paramref name="key"/> already exists, it's value will be overwritten. - /// </summary> - /// <param name="key">Key of the node to insert</param> - /// <param name="value">Value of the node to insert</param> - /// <returns>The inserted Node</returns> - private Node<K, V> BSTInsert(K key, V value) - { - Node<K, V> parent = null; - Node<K, V> node = Root; - - while (node != null) - { - parent = node; - int cmp = key.CompareTo(node.Key); - if (cmp < 0) - { - node = node.Left; - } - else if (cmp > 0) - { - node = node.Right; - } - else - { - node.Value = value; - return node; - } - } - Node<K, V> newNode = new Node<K, V>(key, value, parent); - if (newNode.Parent == null) - { - Root = newNode; - } - else if (key.CompareTo(parent.Key) < 0) - { - parent.Left = newNode; - } - else - { - parent.Right = newNode; - } - Count++; - return newNode; - } - - /// <summary> - /// Removes <paramref name="key"/> from the dictionary, if it exists. - /// </summary> - /// <param name="key">Key of the node to delete</param> - /// <returns>The deleted Node</returns> - private Node<K, V> Delete(K key) - { - // O(1) Retrieval - Node<K, V> nodeToDelete = GetNode(key); - - if (nodeToDelete == null) return null; - - Node<K, V> replacementNode; - - if (LeftOf(nodeToDelete) == null || RightOf(nodeToDelete) == null) - { - replacementNode = nodeToDelete; - } - else - { - replacementNode = PredecessorOf(nodeToDelete); - } - - Node<K, V> tmp = LeftOf(replacementNode) ?? RightOf(replacementNode); - - if (tmp != null) - { - tmp.Parent = ParentOf(replacementNode); - } - - if (ParentOf(replacementNode) == null) - { - Root = tmp; - } - else if (replacementNode == LeftOf(ParentOf(replacementNode))) - { - ParentOf(replacementNode).Left = tmp; - } - else - { - ParentOf(replacementNode).Right = tmp; - } - - if (replacementNode != nodeToDelete) - { - nodeToDelete.Key = replacementNode.Key; - nodeToDelete.Value = replacementNode.Value; - } - - if (tmp != null && ColorOf(replacementNode) == Black) - { - RestoreBalanceAfterRemoval(tmp); - } - - return replacementNode; - } - - /// <summary> - /// Returns the node whose key immediately less than or equal to <paramref name="key"/>. - /// </summary> - /// <param name="key">Key for which to find the floor node of</param> - /// <returns>Node whose key is immediately less than or equal to <paramref name="key"/>, or null if no such node is found.</returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - private Node<K, V> FloorNode(K key) - { - ArgumentNullException.ThrowIfNull(key); - - Node<K, V> tmp = Root; - - while (tmp != null) - { - int cmp = key.CompareTo(tmp.Key); - if (cmp > 0) - { - if (tmp.Right != null) - { - tmp = tmp.Right; - } - else - { - return tmp; - } - } - else if (cmp < 0) - { - if (tmp.Left != null) - { - tmp = tmp.Left; - } - else - { - Node<K, V> parent = tmp.Parent; - Node<K, V> ptr = tmp; - while (parent != null && ptr == parent.Left) - { - ptr = parent; - parent = parent.Parent; - } - return parent; - } - } - else - { - return tmp; - } - } - return null; - } - - /// <summary> - /// Returns the node whose key is immediately greater than or equal to than <paramref name="key"/>. - /// </summary> - /// <param name="key">Key for which to find the ceiling node of</param> - /// <returns>Node whose key is immediately greater than or equal to <paramref name="key"/>, or null if no such node is found.</returns> - /// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception> - private Node<K, V> CeilingNode(K key) - { - ArgumentNullException.ThrowIfNull(key); - - Node<K, V> tmp = Root; - - while (tmp != null) - { - int cmp = key.CompareTo(tmp.Key); - if (cmp < 0) - { - if (tmp.Left != null) - { - tmp = tmp.Left; - } - else - { - return tmp; - } - } - else if (cmp > 0) - { - if (tmp.Right != null) - { - tmp = tmp.Right; - } - else - { - Node<K, V> parent = tmp.Parent; - Node<K, V> ptr = tmp; - while (parent != null && ptr == parent.Right) - { - ptr = parent; - parent = parent.Parent; - } - return parent; - } - } - else - { - return tmp; - } - } - return null; - } - - #endregion - - #region Interface Implementations - - // Method descriptions are not provided as they are already included as part of the interface. - public bool ContainsKey(K key) - { - ArgumentNullException.ThrowIfNull(key); - - return GetNode(key) != null; - } - - bool IDictionary<K, V>.Remove(K key) - { - int count = Count; - Remove(key); - return count > Count; - } - - public bool TryGetValue(K key, [MaybeNullWhen(false)] out V value) - { - ArgumentNullException.ThrowIfNull(key); - - Node<K, V> node = GetNode(key); - value = node != null ? node.Value : default; - return node != null; - } - - public void Add(KeyValuePair<K, V> item) - { - ArgumentNullException.ThrowIfNull(item.Key); - - Add(item.Key, item.Value); - } - - public bool Contains(KeyValuePair<K, V> item) - { - if (item.Key == null) - { - return false; - } - - Node<K, V> node = GetNode(item.Key); - if (node != null) - { - return node.Key.Equals(item.Key) && node.Value.Equals(item.Value); - } - return false; - } - - public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) - { - if (arrayIndex < 0 || array.Length - arrayIndex < this.Count) - { - throw new ArgumentOutOfRangeException(nameof(arrayIndex)); - } - - SortedList<K, V> list = GetKeyValues(); - - int offset = 0; - - for (int i = arrayIndex; i < array.Length && offset < list.Count; i++) - { - array[i] = new KeyValuePair<K, V>(list.Keys[i], list.Values[i]); - offset++; - } - } - - public bool Remove(KeyValuePair<K, V> item) - { - Node<K, V> node = GetNode(item.Key); - - if (node == null) - { - return false; - } - - if (node.Value.Equals(item.Value)) - { - int count = Count; - Remove(item.Key); - return count > Count; - } - - return false; - } - - public IEnumerator<KeyValuePair<K, V>> GetEnumerator() - { - return GetKeyValues().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetKeyValues().GetEnumerator(); - } - - public ICollection<K> Keys => GetKeyValues().Keys; - - public ICollection<V> Values => GetKeyValues().Values; - - public bool IsReadOnly => false; - - public V this[K key] - { - get => Get(key); - set => Add(key, value); - } - - #endregion - - #region Private Interface Helper Methods - - /// <summary> - /// Returns a sorted list of all the node keys / values in the tree. - /// </summary> - /// <returns>List of node keys</returns> - private SortedList<K, V> GetKeyValues() - { - SortedList<K, V> set = new SortedList<K, V>(); - Queue<Node<K, V>> queue = new Queue<Node<K, V>>(); - if (Root != null) - { - queue.Enqueue(Root); - } - - while (queue.TryDequeue(out Node<K, V> node)) - { - set.Add(node.Key, node.Value); - if (null != node.Left) - { - queue.Enqueue(node.Left); - } - if (null != node.Right) - { - queue.Enqueue(node.Right); - } - } - - return set; - } - - #endregion - } - - /// <summary> - /// Represents a node in the TreeDictionary which contains a key and value of generic type K and V, respectively. - /// </summary> - /// <typeparam name="K">Key of the node</typeparam> - /// <typeparam name="V">Value of the node</typeparam> - public class Node<K, V> : IntrusiveRedBlackTreeNode<Node<K, V>> where K : IComparable<K> - { - internal K Key; - internal V Value; - - internal Node(K key, V value, Node<K, V> parent) - { - Key = key; - Value = value; - Parent = parent; - } - } -} diff --git a/Ryujinx.Common/Configuration/AntiAliasing.cs b/Ryujinx.Common/Configuration/AntiAliasing.cs deleted file mode 100644 index 159108ae..00000000 --- a/Ryujinx.Common/Configuration/AntiAliasing.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<AntiAliasing>))] - public enum AntiAliasing - { - None, - Fxaa, - SmaaLow, - SmaaMedium, - SmaaHigh, - SmaaUltra - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/AppDataManager.cs b/Ryujinx.Common/Configuration/AppDataManager.cs deleted file mode 100644 index d6e77843..00000000 --- a/Ryujinx.Common/Configuration/AppDataManager.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.IO; - -namespace Ryujinx.Common.Configuration -{ - public static class AppDataManager - { - public const string DefaultBaseDir = "Ryujinx"; - public const string DefaultPortableDir = "portable"; - - // The following 3 are always part of Base Directory - private const string GamesDir = "games"; - private const string ProfilesDir = "profiles"; - private const string KeysDir = "system"; - - public enum LaunchMode - { - UserProfile, - Portable, - Custom - } - - public static LaunchMode Mode { get; private set; } - - public static string BaseDirPath { get; private set; } - public static string GamesDirPath { get; private set; } - public static string ProfilesDirPath { get; private set; } - public static string KeysDirPath { get; private set; } - public static string KeysDirPathUser { get; } - - public const string DefaultNandDir = "bis"; - public const string DefaultSdcardDir = "sdcard"; - private const string DefaultModsDir = "mods"; - - public static string CustomModsPath { get; set; } - public static string CustomSdModsPath {get; set; } - public static string CustomNandPath { get; set; } // TODO: Actually implement this into VFS - public static string CustomSdCardPath { get; set; } // TODO: Actually implement this into VFS - - static AppDataManager() - { - KeysDirPathUser = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch"); - } - - public static void Initialize(string baseDirPath) - { - string appDataPath; - if (OperatingSystem.IsMacOS()) - { - appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Application Support"); - } - else - { - appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - } - - if (appDataPath.Length == 0) - { - appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - } - - string userProfilePath = Path.Combine(appDataPath, DefaultBaseDir); - string portablePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DefaultPortableDir); - - if (Directory.Exists(portablePath)) - { - BaseDirPath = portablePath; - Mode = LaunchMode.Portable; - } - else - { - BaseDirPath = userProfilePath; - Mode = LaunchMode.UserProfile; - } - - if (baseDirPath != null && baseDirPath != userProfilePath) - { - if (!Directory.Exists(baseDirPath)) - { - Logger.Error?.Print(LogClass.Application, $"Custom Data Directory '{baseDirPath}' does not exist. Falling back to {Mode}..."); - } - else - { - BaseDirPath = baseDirPath; - Mode = LaunchMode.Custom; - } - } - - BaseDirPath = Path.GetFullPath(BaseDirPath); // convert relative paths - - // NOTE: Moves the Ryujinx folder in `~/.config` to `~/Library/Application Support` if one is found - // and a Ryujinx folder does not already exist in Application Support. - // Also creates a symlink from `~/.config/Ryujinx` to `~/Library/Application Support/Ryujinx` to preserve backwards compatibility. - // This should be removed in the future. - if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile) - { - string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir); - if (Path.Exists(oldConfigPath) && !Path.Exists(BaseDirPath)) - { - CopyDirectory(oldConfigPath, BaseDirPath); - Directory.Delete(oldConfigPath, true); - Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath); - } - } - - SetupBasePaths(); - } - - private static void SetupBasePaths() - { - Directory.CreateDirectory(BaseDirPath); - Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir)); - Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir)); - Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir)); - } - - private static void CopyDirectory(string sourceDir, string destinationDir) - { - var dir = new DirectoryInfo(sourceDir); - - if (!dir.Exists) - { - throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}"); - } - - DirectoryInfo[] subDirs = dir.GetDirectories(); - Directory.CreateDirectory(destinationDir); - - foreach (FileInfo file in dir.GetFiles()) - { - if (file.Name == ".DS_Store") - { - continue; - } - - file.CopyTo(Path.Combine(destinationDir, file.Name)); - } - - foreach (DirectoryInfo subDir in subDirs) - { - CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name)); - } - } - - public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName; - public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName; - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/AspectRatioExtensions.cs b/Ryujinx.Common/Configuration/AspectRatioExtensions.cs deleted file mode 100644 index 5e97ed19..00000000 --- a/Ryujinx.Common/Configuration/AspectRatioExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<AspectRatio>))] - public enum AspectRatio - { - Fixed4x3, - Fixed16x9, - Fixed16x10, - Fixed21x9, - Fixed32x9, - Stretched - } - - public static class AspectRatioExtensions - { - public static float ToFloat(this AspectRatio aspectRatio) - { - return aspectRatio.ToFloatX() / aspectRatio.ToFloatY(); - } - - public static float ToFloatX(this AspectRatio aspectRatio) - { - return aspectRatio switch - { - AspectRatio.Fixed4x3 => 4.0f, - AspectRatio.Fixed16x9 => 16.0f, - AspectRatio.Fixed16x10 => 16.0f, - AspectRatio.Fixed21x9 => 21.0f, - AspectRatio.Fixed32x9 => 32.0f, - _ => 16.0f - }; - } - - public static float ToFloatY(this AspectRatio aspectRatio) - { - return aspectRatio switch - { - AspectRatio.Fixed4x3 => 3.0f, - AspectRatio.Fixed16x9 => 9.0f, - AspectRatio.Fixed16x10 => 10.0f, - AspectRatio.Fixed21x9 => 9.0f, - AspectRatio.Fixed32x9 => 9.0f, - _ => 9.0f - }; - } - - public static string ToText(this AspectRatio aspectRatio) - { - return aspectRatio switch - { - AspectRatio.Fixed4x3 => "4:3", - AspectRatio.Fixed16x9 => "16:9", - AspectRatio.Fixed16x10 => "16:10", - AspectRatio.Fixed21x9 => "21:9", - AspectRatio.Fixed32x9 => "32:9", - _ => "Stretched" - }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/BackendThreading.cs b/Ryujinx.Common/Configuration/BackendThreading.cs deleted file mode 100644 index 8833b3f0..00000000 --- a/Ryujinx.Common/Configuration/BackendThreading.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<BackendThreading>))] - public enum BackendThreading - { - Auto, - Off, - On - } -} diff --git a/Ryujinx.Common/Configuration/DownloadableContentContainer.cs b/Ryujinx.Common/Configuration/DownloadableContentContainer.cs deleted file mode 100644 index b6ae2f3f..00000000 --- a/Ryujinx.Common/Configuration/DownloadableContentContainer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - public struct DownloadableContentContainer - { - [JsonPropertyName("path")] - public string ContainerPath { get; set; } - [JsonPropertyName("dlc_nca_list")] - public List<DownloadableContentNca> DownloadableContentNcaList { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs b/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs deleted file mode 100644 index 132c45a4..00000000 --- a/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(List<DownloadableContentContainer>))] - public partial class DownloadableContentJsonSerializerContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/DownloadableContentNca.cs b/Ryujinx.Common/Configuration/DownloadableContentNca.cs deleted file mode 100644 index 80b67300..00000000 --- a/Ryujinx.Common/Configuration/DownloadableContentNca.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - public struct DownloadableContentNca - { - [JsonPropertyName("path")] - public string FullPath { get; set; } - [JsonPropertyName("title_id")] - public ulong TitleId { get; set; } - [JsonPropertyName("is_enabled")] - public bool Enabled { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/GraphicsBackend.cs b/Ryujinx.Common/Configuration/GraphicsBackend.cs deleted file mode 100644 index d74dd6e1..00000000 --- a/Ryujinx.Common/Configuration/GraphicsBackend.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))] - public enum GraphicsBackend - { - Vulkan, - OpenGl - } -} diff --git a/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs b/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs deleted file mode 100644 index ad12302a..00000000 --- a/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<GraphicsDebugLevel>))] - public enum GraphicsDebugLevel - { - None, - Error, - Slowdowns, - All - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs b/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs deleted file mode 100644 index ad1fa667..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - [JsonConverter(typeof(TypedStringEnumConverter<GamepadInputId>))] - public enum GamepadInputId : byte - { - Unbound, - A, - B, - X, - Y, - LeftStick, - RightStick, - LeftShoulder, - RightShoulder, - - // Likely axis - LeftTrigger, - // Likely axis - RightTrigger, - - DpadUp, - DpadDown, - DpadLeft, - DpadRight, - - // Special buttons - - Minus, - Plus, - - Back = Minus, - Start = Plus, - - Guide, - Misc1, - - // Xbox Elite paddle - Paddle1, - Paddle2, - Paddle3, - Paddle4, - - // PS5 touchpad button - Touchpad, - - // Virtual buttons for single joycon - SingleLeftTrigger0, - SingleRightTrigger0, - - SingleLeftTrigger1, - SingleRightTrigger1, - - Count - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs deleted file mode 100644 index d7f0e788..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Ryujinx.Common.Configuration.Hid.Controller.Motion; -using System; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - public class GenericControllerInputConfig<Button, Stick> : GenericInputConfigurationCommon<Button> where Button : unmanaged where Stick : unmanaged - { - [JsonIgnore] - private float _deadzoneLeft; - [JsonIgnore] - private float _deadzoneRight; - [JsonIgnore] - private float _triggerThreshold; - - /// <summary> - /// Left JoyCon Controller Stick Bindings - /// </summary> - public JoyconConfigControllerStick<Button, Stick> LeftJoyconStick { get; set; } - - /// <summary> - /// Right JoyCon Controller Stick Bindings - /// </summary> - public JoyconConfigControllerStick<Button, Stick> RightJoyconStick { get; set; } - - /// <summary> - /// Controller Left Analog Stick Deadzone - /// </summary> - public float DeadzoneLeft - { - get => _deadzoneLeft; set - { - _deadzoneLeft = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - /// <summary> - /// Controller Right Analog Stick Deadzone - /// </summary> - public float DeadzoneRight - { - get => _deadzoneRight; set - { - _deadzoneRight = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - /// <summary> - /// Controller Left Analog Stick Range - /// </summary> - public float RangeLeft { get; set; } - - /// <summary> - /// Controller Right Analog Stick Range - /// </summary> - public float RangeRight { get; set; } - - /// <summary> - /// Controller Trigger Threshold - /// </summary> - public float TriggerThreshold - { - get => _triggerThreshold; set - { - _triggerThreshold = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - /// <summary> - /// Controller Motion Settings - /// </summary> - public MotionConfigController Motion { get; set; } - - /// <summary> - /// Controller Rumble Settings - /// </summary> - public RumbleConfigController Rumble { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs b/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs deleted file mode 100644 index 869cff4f..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - public class JoyconConfigControllerStick<Button, Stick> where Button: unmanaged where Stick: unmanaged - { - public Stick Joystick { get; set; } - public bool InvertStickX { get; set; } - public bool InvertStickY { get; set; } - public bool Rotate90CW { get; set; } - public Button StickButton { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs deleted file mode 100644 index 2a5a73ff..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - public class CemuHookMotionConfigController : MotionConfigController - { - /// <summary> - /// Motion Controller Slot - /// </summary> - public int Slot { get; set; } - - /// <summary> - /// Motion Controller Alternative Slot, for RightJoyCon in Pair mode - /// </summary> - public int AltSlot { get; set; } - - /// <summary> - /// Mirror motion input in Pair mode - /// </summary> - public bool MirrorInput { get; set; } - - /// <summary> - /// Host address of the DSU Server - /// </summary> - public string DsuServerHost { get; set; } - - /// <summary> - /// Port of the DSU Server - /// </summary> - public int DsuServerPort { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs deleted file mode 100644 index 2b9e0af4..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Ryujinx.Common.Utilities; -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - class JsonMotionConfigControllerConverter : JsonConverter<MotionConfigController> - { - private static readonly MotionConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - - private static MotionInputBackendType GetMotionInputBackendType(ref Utf8JsonReader reader) - { - // Temporary reader to get the backend type - Utf8JsonReader tempReader = reader; - - MotionInputBackendType result = MotionInputBackendType.Invalid; - - while (tempReader.Read()) - { - // NOTE: We scan all properties ignoring the depth entirely on purpose. - // The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object. - // As such, this code will try to parse very field named "motion_backend" to the correct enum. - if (tempReader.TokenType == JsonTokenType.PropertyName) - { - string propertyName = tempReader.GetString(); - - if (propertyName.Equals("motion_backend")) - { - tempReader.Read(); - - if (tempReader.TokenType == JsonTokenType.String) - { - string backendTypeRaw = tempReader.GetString(); - - if (!Enum.TryParse(backendTypeRaw, out result)) - { - result = MotionInputBackendType.Invalid; - } - else - { - break; - } - } - } - } - } - - return result; - } - - public override MotionConfigController Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - MotionInputBackendType motionBackendType = GetMotionInputBackendType(ref reader); - - return motionBackendType switch - { - MotionInputBackendType.GamepadDriver => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardMotionConfigController), - MotionInputBackendType.CemuHook => JsonSerializer.Deserialize(ref reader, SerializerContext.CemuHookMotionConfigController), - _ => throw new InvalidOperationException($"Unknown backend type {motionBackendType}"), - }; - } - - public override void Write(Utf8JsonWriter writer, MotionConfigController value, JsonSerializerOptions options) - { - switch (value.MotionBackend) - { - case MotionInputBackendType.GamepadDriver: - JsonSerializer.Serialize(writer, value as StandardMotionConfigController, SerializerContext.StandardMotionConfigController); - break; - case MotionInputBackendType.CemuHook: - JsonSerializer.Serialize(writer, value as CemuHookMotionConfigController, SerializerContext.CemuHookMotionConfigController); - break; - default: - throw new ArgumentException($"Unknown motion backend type {value.MotionBackend}"); - } - } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs deleted file mode 100644 index 7636aa41..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - [JsonConverter(typeof(JsonMotionConfigControllerConverter))] - public class MotionConfigController - { - public MotionInputBackendType MotionBackend { get; set; } - - /// <summary> - /// Gyro Sensitivity - /// </summary> - public int Sensitivity { get; set; } - - /// <summary> - /// Gyro Deadzone - /// </summary> - public double GyroDeadzone { get; set; } - - /// <summary> - /// Enable Motion Controls - /// </summary> - public bool EnableMotion { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs deleted file mode 100644 index 5cd9e452..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(MotionConfigController))] - [JsonSerializable(typeof(CemuHookMotionConfigController))] - [JsonSerializable(typeof(StandardMotionConfigController))] - public partial class MotionConfigJsonSerializerContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs deleted file mode 100644 index c6551047..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - [JsonConverter(typeof(TypedStringEnumConverter<MotionInputBackendType>))] - public enum MotionInputBackendType : byte - { - Invalid, - GamepadDriver, - CemuHook - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs deleted file mode 100644 index df925444..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion -{ - public class StandardMotionConfigController : MotionConfigController { } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs deleted file mode 100644 index 48be4f13..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - public class RumbleConfigController - { - /// <summary> - /// Controller Strong Rumble Multiplier - /// </summary> - public float StrongRumble { get; set; } - - /// <summary> - /// Controller Weak Rumble Multiplier - /// </summary> - public float WeakRumble { get; set; } - - /// <summary> - /// Enable Rumble - /// </summary> - public bool EnableRumble { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs deleted file mode 100644 index 4154a42b..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - public class StandardControllerInputConfig : GenericControllerInputConfig<GamepadInputId, StickInputId> { } -} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs b/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs deleted file mode 100644 index 5fc4d1c8..00000000 --- a/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid.Controller -{ - [JsonConverter(typeof(TypedStringEnumConverter<StickInputId>))] - public enum StickInputId : byte - { - Unbound, - Left, - Right, - - Count - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/ControllerType.cs b/Ryujinx.Common/Configuration/Hid/ControllerType.cs deleted file mode 100644 index 70f811c8..00000000 --- a/Ryujinx.Common/Configuration/Hid/ControllerType.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Common.Utilities; -using System; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical - [Flags] - [JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))] - public enum ControllerType : int - { - None, - ProController = 1 << 0, - Handheld = 1 << 1, - JoyconPair = 1 << 2, - JoyconLeft = 1 << 3, - JoyconRight = 1 << 4, - Invalid = 1 << 5, - Pokeball = 1 << 6, - SystemExternal = 1 << 29, - System = 1 << 30 - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs b/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs deleted file mode 100644 index 3d43817e..00000000 --- a/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public class GenericInputConfigurationCommon<Button> : InputConfig where Button : unmanaged - { - /// <summary> - /// Left JoyCon Controller Bindings - /// </summary> - public LeftJoyconCommonConfig<Button> LeftJoycon { get; set; } - - /// <summary> - /// Right JoyCon Controller Bindings - /// </summary> - public RightJoyconCommonConfig<Button> RightJoycon { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/InputBackendType.cs b/Ryujinx.Common/Configuration/Hid/InputBackendType.cs deleted file mode 100644 index 1db3f570..00000000 --- a/Ryujinx.Common/Configuration/Hid/InputBackendType.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - [JsonConverter(typeof(TypedStringEnumConverter<InputBackendType>))] - public enum InputBackendType - { - Invalid, - WindowKeyboard, - GamepadSDL2, - } -} diff --git a/Ryujinx.Common/Configuration/Hid/InputConfig.cs b/Ryujinx.Common/Configuration/Hid/InputConfig.cs deleted file mode 100644 index 16c8f8e3..00000000 --- a/Ryujinx.Common/Configuration/Hid/InputConfig.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.ComponentModel; -using System.Runtime.CompilerServices; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - [JsonConverter(typeof(JsonInputConfigConverter))] - public class InputConfig : INotifyPropertyChanged - { - /// <summary> - /// The current version of the input file format - /// </summary> - public const int CurrentVersion = 1; - - public int Version { get; set; } - - public InputBackendType Backend { get; set; } - - /// <summary> - /// Controller id - /// </summary> - public string Id { get; set; } - - /// <summary> - /// Controller's Type - /// </summary> - public ControllerType ControllerType { get; set; } - - /// <summary> - /// Player's Index for the controller - /// </summary> - public PlayerIndex PlayerIndex { get; set; } - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs b/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs deleted file mode 100644 index 254c4feb..00000000 --- a/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Common.Configuration.Hid.Controller; -using Ryujinx.Common.Configuration.Hid.Keyboard; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(InputConfig))] - [JsonSerializable(typeof(StandardKeyboardInputConfig))] - [JsonSerializable(typeof(StandardControllerInputConfig))] - public partial class InputConfigJsonSerializerContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs b/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs deleted file mode 100644 index 08bbcbf1..00000000 --- a/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Ryujinx.Common.Configuration.Hid.Controller; -using Ryujinx.Common.Configuration.Hid.Keyboard; -using Ryujinx.Common.Utilities; -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - public class JsonInputConfigConverter : JsonConverter<InputConfig> - { - private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - - private static InputBackendType GetInputBackendType(ref Utf8JsonReader reader) - { - // Temporary reader to get the backend type - Utf8JsonReader tempReader = reader; - - InputBackendType result = InputBackendType.Invalid; - - while (tempReader.Read()) - { - // NOTE: We scan all properties ignoring the depth entirely on purpose. - // The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object. - // As such, this code will try to parse very field named "backend" to the correct enum. - if (tempReader.TokenType == JsonTokenType.PropertyName) - { - string propertyName = tempReader.GetString(); - - if (propertyName.Equals("backend")) - { - tempReader.Read(); - - if (tempReader.TokenType == JsonTokenType.String) - { - string backendTypeRaw = tempReader.GetString(); - - if (!Enum.TryParse(backendTypeRaw, out result)) - { - result = InputBackendType.Invalid; - } - else - { - break; - } - } - } - } - } - - return result; - } - - public override InputConfig Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - InputBackendType backendType = GetInputBackendType(ref reader); - - return backendType switch - { - InputBackendType.WindowKeyboard => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardKeyboardInputConfig), - InputBackendType.GamepadSDL2 => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardControllerInputConfig), - _ => throw new InvalidOperationException($"Unknown backend type {backendType}"), - }; - } - - public override void Write(Utf8JsonWriter writer, InputConfig value, JsonSerializerOptions options) - { - switch (value.Backend) - { - case InputBackendType.WindowKeyboard: - JsonSerializer.Serialize(writer, value as StandardKeyboardInputConfig, SerializerContext.StandardKeyboardInputConfig); - break; - case InputBackendType.GamepadSDL2: - JsonSerializer.Serialize(writer, value as StandardControllerInputConfig, SerializerContext.StandardControllerInputConfig); - break; - default: - throw new ArgumentException($"Unknown backend type {value.Backend}"); - } - } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Key.cs b/Ryujinx.Common/Configuration/Hid/Key.cs deleted file mode 100644 index 3501b8ae..00000000 --- a/Ryujinx.Common/Configuration/Hid/Key.cs +++ /dev/null @@ -1,143 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - [JsonConverter(typeof(TypedStringEnumConverter<Key>))] - public enum Key - { - Unknown, - ShiftLeft, - ShiftRight, - ControlLeft, - ControlRight, - AltLeft, - AltRight, - WinLeft, - WinRight, - Menu, - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - F9, - F10, - F11, - F12, - F13, - F14, - F15, - F16, - F17, - F18, - F19, - F20, - F21, - F22, - F23, - F24, - F25, - F26, - F27, - F28, - F29, - F30, - F31, - F32, - F33, - F34, - F35, - Up, - Down, - Left, - Right, - Enter, - Escape, - Space, - Tab, - BackSpace, - Insert, - Delete, - PageUp, - PageDown, - Home, - End, - CapsLock, - ScrollLock, - PrintScreen, - Pause, - NumLock, - Clear, - Keypad0, - Keypad1, - Keypad2, - Keypad3, - Keypad4, - Keypad5, - Keypad6, - Keypad7, - Keypad8, - Keypad9, - KeypadDivide, - KeypadMultiply, - KeypadSubtract, - KeypadAdd, - KeypadDecimal, - KeypadEnter, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - T, - U, - V, - W, - X, - Y, - Z, - Number0, - Number1, - Number2, - Number3, - Number4, - Number5, - Number6, - Number7, - Number8, - Number9, - Tilde, - Grave, - Minus, - Plus, - BracketLeft, - BracketRight, - Semicolon, - Quote, - Comma, - Period, - Slash, - BackSlash, - Unbound, - - Count - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs deleted file mode 100644 index b6c82c93..00000000 --- a/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard -{ - public class GenericKeyboardInputConfig<Key> : GenericInputConfigurationCommon<Key> where Key : unmanaged - { - /// <summary> - /// Left JoyCon Controller Stick Bindings - /// </summary> - public JoyconConfigKeyboardStick<Key> LeftJoyconStick { get; set; } - - /// <summary> - /// Right JoyCon Controller Stick Bindings - /// </summary> - public JoyconConfigKeyboardStick<Key> RightJoyconStick { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs deleted file mode 100644 index cadc17e8..00000000 --- a/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard -{ - public class JoyconConfigKeyboardStick<Key> where Key: unmanaged - { - public Key StickUp { get; set; } - public Key StickDown { get; set; } - public Key StickLeft { get; set; } - public Key StickRight { get; set; } - public Key StickButton { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs deleted file mode 100644 index 054d777d..00000000 --- a/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard -{ - public class StandardKeyboardInputConfig : GenericKeyboardInputConfig<Key> { } -} diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs deleted file mode 100644 index 1a10c2a5..00000000 --- a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - // NOTE: Please don't change this to struct. - // This breaks Avalonia's TwoWay binding, which makes us unable to save new KeyboardHotkeys. - public class KeyboardHotkeys - { - public Key ToggleVsync { get; set; } - public Key Screenshot { get; set; } - public Key ShowUi { get; set; } - public Key Pause { get; set; } - public Key ToggleMute { get; set; } - public Key ResScaleUp { get; set; } - public Key ResScaleDown { get; set; } - public Key VolumeUp { get; set; } - public Key VolumeDown { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs b/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs deleted file mode 100644 index a57240c4..00000000 --- a/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public class LeftJoyconCommonConfig<Button> - { - public Button ButtonMinus { get; set; } - public Button ButtonL { get; set; } - public Button ButtonZl { get; set; } - public Button ButtonSl { get; set; } - public Button ButtonSr { get; set; } - public Button DpadUp { get; set; } - public Button DpadDown { get; set; } - public Button DpadLeft { get; set; } - public Button DpadRight { get; set; } - } -} diff --git a/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs b/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs deleted file mode 100644 index dd6495d4..00000000 --- a/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration.Hid -{ - // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical - [JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))] - public enum PlayerIndex : int - { - Player1 = 0, - Player2 = 1, - Player3 = 2, - Player4 = 3, - Player5 = 4, - Player6 = 5, - Player7 = 6, - Player8 = 7, - Handheld = 8, - Unknown = 9, - Auto = 10 // Shouldn't be used directly - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs b/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs deleted file mode 100644 index ca2d0176..00000000 --- a/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public class RightJoyconCommonConfig<Button> - { - public Button ButtonPlus { get; set; } - public Button ButtonR { get; set; } - public Button ButtonZr { get; set; } - public Button ButtonSl { get; set; } - public Button ButtonSr { get; set; } - public Button ButtonX { get; set; } - public Button ButtonB { get; set; } - public Button ButtonY { get; set; } - public Button ButtonA { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/MemoryManagerMode.cs b/Ryujinx.Common/Configuration/MemoryManagerMode.cs deleted file mode 100644 index f10fd6f1..00000000 --- a/Ryujinx.Common/Configuration/MemoryManagerMode.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<MemoryManagerMode>))] - public enum MemoryManagerMode : byte - { - SoftwarePageTable, - HostMapped, - HostMappedUnsafe - } -} diff --git a/Ryujinx.Common/Configuration/ScalingFilter.cs b/Ryujinx.Common/Configuration/ScalingFilter.cs deleted file mode 100644 index e38c7d73..00000000 --- a/Ryujinx.Common/Configuration/ScalingFilter.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonConverter(typeof(TypedStringEnumConverter<ScalingFilter>))] - public enum ScalingFilter - { - Bilinear, - Nearest, - Fsr - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs b/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs deleted file mode 100644 index ea208e9c..00000000 --- a/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Common.Configuration -{ - public struct TitleUpdateMetadata - { - public string Selected { get; set; } - public List<string> Paths { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs b/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs deleted file mode 100644 index 5b661b87..00000000 --- a/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Configuration -{ - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(TitleUpdateMetadata))] - public partial class TitleUpdateMetadataJsonSerializerContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs deleted file mode 100644 index 21da6fc0..00000000 --- a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common -{ - public static class BinaryReaderExtensions - { - public unsafe static T ReadStruct<T>(this BinaryReader reader) - where T : unmanaged - { - return MemoryMarshal.Cast<byte, T>(reader.ReadBytes(Unsafe.SizeOf<T>()))[0]; - } - } -} diff --git a/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs b/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs deleted file mode 100644 index fddc8c1b..00000000 --- a/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common -{ - public static class BinaryWriterExtensions - { - public unsafe static void WriteStruct<T>(this BinaryWriter writer, T value) - where T : unmanaged - { - ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); - - writer.Write(data); - } - - public static void Write(this BinaryWriter writer, UInt128 value) - { - writer.Write((ulong)value); - writer.Write((ulong)(value >> 64)); - } - - public static void Write(this BinaryWriter writer, MemoryStream stream) - { - stream.CopyTo(writer.BaseStream); - } - } -} diff --git a/Ryujinx.Common/Extensions/StreamExtensions.cs b/Ryujinx.Common/Extensions/StreamExtensions.cs deleted file mode 100644 index f6fc870a..00000000 --- a/Ryujinx.Common/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.IO; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common -{ - public static class StreamExtensions - { - /// <summary> - /// Writes a <cref="ReadOnlySpan<int>" /> to this stream. - /// - /// This default implementation converts each buffer value to a stack-allocated - /// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="buffer">The buffer of values to be written</param> - public static void Write(this Stream stream, ReadOnlySpan<int> buffer) - { - if (buffer.Length == 0) - { - return; - } - - if (BitConverter.IsLittleEndian) - { - ReadOnlySpan<byte> byteBuffer = MemoryMarshal.Cast<int, byte>(buffer); - stream.Write(byteBuffer); - } - else - { - Span<byte> byteBuffer = stackalloc byte[sizeof(int)]; - - foreach (int value in buffer) - { - BinaryPrimitives.WriteInt32LittleEndian(byteBuffer, value); - stream.Write(byteBuffer); - } - } - } - - /// <summary> - /// Writes a four-byte signed integer to this stream. The current position - /// of the stream is advanced by four. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="value">The value to be written</param> - public static void Write(this Stream stream, int value) - { - Span<byte> buffer = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(buffer, value); - stream.Write(buffer); - } - - /// <summary> - /// Writes an eight-byte signed integer to this stream. The current position - /// of the stream is advanced by eight. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="value">The value to be written</param> - public static void Write(this Stream stream, long value) - { - Span<byte> buffer = stackalloc byte[sizeof(long)]; - BinaryPrimitives.WriteInt64LittleEndian(buffer, value); - stream.Write(buffer); - } - - /// <summary> - // Writes a four-byte unsigned integer to this stream. The current position - // of the stream is advanced by four. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="value">The value to be written</param> - public static void Write(this Stream stream, uint value) - { - Span<byte> buffer = stackalloc byte[sizeof(uint)]; - BinaryPrimitives.WriteUInt32LittleEndian(buffer, value); - stream.Write(buffer); - } - - /// <summary> - /// Writes an eight-byte unsigned integer to this stream. The current - /// position of the stream is advanced by eight. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="value">The value to be written</param> - public static void Write(this Stream stream, ulong value) - { - Span<byte> buffer = stackalloc byte[sizeof(ulong)]; - BinaryPrimitives.WriteUInt64LittleEndian(buffer, value); - stream.Write(buffer); - } - - /// <summary> - /// Writes the contents of source to stream by calling source.CopyTo(stream). - /// Provides consistency with other Stream.Write methods. - /// </summary> - /// <param name="stream">The stream to be written to</param> - /// <param name="source">The stream to be read from</param> - public static void Write(this Stream stream, Stream source) - { - source.CopyTo(stream); - } - - /// <summary> - /// Writes a sequence of bytes to the Stream. - /// </summary> - /// <param name="stream">The stream to be written to.</param> - /// <param name="value">The byte to be written</param> - /// <param name="count">The number of times the value should be written</param> - public static void WriteByte(this Stream stream, byte value, int count) - { - if (count <= 0) - { - return; - } - - const int BlockSize = 16; - - int blockCount = count / BlockSize; - if (blockCount > 0) - { - Span<byte> span = stackalloc byte[BlockSize]; - span.Fill(value); - for (int x = 0; x < blockCount; x++) - { - stream.Write(span); - } - } - - int nonBlockBytes = count % BlockSize; - for (int x = 0; x < nonBlockBytes; x++) - { - stream.WriteByte(value); - } - } - } -} diff --git a/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs b/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs deleted file mode 100644 index 3aabced7..00000000 --- a/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Ryujinx.Common.GraphicsDriver -{ - public static class DriverUtilities - { - public static void ToggleOGLThreading(bool enabled) - { - Environment.SetEnvironmentVariable("mesa_glthread", enabled.ToString().ToLower()); - Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0"); - - try - { - NVThreadedOptimization.SetThreadedOptimization(enabled); - } - catch - { - // NVAPI is not available, or couldn't change the application profile. - } - } - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs b/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs deleted file mode 100644 index 99eaa68f..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Common.GraphicsDriver.NVAPI -{ - enum Nvapi : uint - { - OglThreadControlId = 0x20C1221E, - - OglThreadControlDefault = 0, - OglThreadControlEnable = 1, - OglThreadControlDisable = 2 - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs b/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs deleted file mode 100644 index 6bbff2de..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Runtime.InteropServices; -using System.Text; - -namespace Ryujinx.Common.GraphicsDriver.NVAPI -{ - [StructLayout(LayoutKind.Sequential, Pack = 4)] - public unsafe struct NvapiUnicodeString - { - private fixed byte _data[4096]; - - public NvapiUnicodeString(string text) - { - Set(text); - } - - public string Get() - { - fixed (byte* data = _data) - { - string text = Encoding.Unicode.GetString(data, 4096); - - int index = text.IndexOf('\0'); - if (index > -1) - { - text = text.Remove(index); - } - - return text; - } - } - - public void Set(string text) - { - text += '\0'; - fixed (char* textPtr = text) - fixed (byte* data = _data) - { - int written = Encoding.Unicode.GetBytes(textPtr, text.Length, data, 4096); - } - } - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs b/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs deleted file mode 100644 index 8b472cd1..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.GraphicsDriver.NVAPI -{ - [StructLayout(LayoutKind.Sequential, Pack = 4)] - unsafe struct NvdrsApplicationV4 - { - public uint Version; - public uint IsPredefined; - public NvapiUnicodeString AppName; - public NvapiUnicodeString UserFriendlyName; - public NvapiUnicodeString Launcher; - public NvapiUnicodeString FileInFolder; - public uint Flags; - public NvapiUnicodeString CommandLine; - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs b/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs deleted file mode 100644 index f1bfee82..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.GraphicsDriver.NVAPI -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - unsafe struct NvdrsProfile - { - public uint Version; - public NvapiUnicodeString ProfileName; - public uint GpuSupport; - public uint IsPredefined; - public uint NumOfApps; - public uint NumOfSettings; - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs b/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs deleted file mode 100644 index ac188b35..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.GraphicsDriver.NVAPI -{ - enum NvdrsSettingType : uint - { - NvdrsDwordType, - NvdrsBinaryType, - NvdrsStringType, - NvdrsWstringType, - } - - enum NvdrsSettingLocation : uint - { - NvdrsCurrentProfileLocation, - NvdrsGlobalProfileLocation, - NvdrsBaseProfileLocation, - NvdrsDefaultProfileLocation, - } - - [StructLayout(LayoutKind.Explicit, Size = 0x3020)] - unsafe struct NvdrsSetting - { - [FieldOffset(0x0)] - public uint Version; - [FieldOffset(0x4)] - public NvapiUnicodeString SettingName; - [FieldOffset(0x1004)] - public Nvapi SettingId; - [FieldOffset(0x1008)] - public NvdrsSettingType SettingType; - [FieldOffset(0x100C)] - public NvdrsSettingLocation SettingLocation; - [FieldOffset(0x1010)] - public uint IsCurrentPredefined; - [FieldOffset(0x1014)] - public uint IsPredefinedValid; - - [FieldOffset(0x1018)] - public uint PredefinedValue; - [FieldOffset(0x1018)] - public NvapiUnicodeString PredefinedString; - - [FieldOffset(0x201C)] - public uint CurrentValue; - [FieldOffset(0x201C)] - public NvapiUnicodeString CurrentString; - } -} diff --git a/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs b/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs deleted file mode 100644 index c5be6e37..00000000 --- a/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs +++ /dev/null @@ -1,163 +0,0 @@ -using Ryujinx.Common.GraphicsDriver.NVAPI; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.GraphicsDriver -{ - static partial class NVThreadedOptimization - { - private const string ProfileName = "Ryujinx Nvidia Profile"; - - private const uint NvAPI_Initialize_ID = 0x0150E828; - private const uint NvAPI_DRS_CreateSession_ID = 0x0694D52E; - private const uint NvAPI_DRS_LoadSettings_ID = 0x375DBD6B; - private const uint NvAPI_DRS_FindProfileByName_ID = 0x7E4A9A0B; - private const uint NvAPI_DRS_CreateProfile_ID = 0x0CC176068; - private const uint NvAPI_DRS_CreateApplication_ID = 0x4347A9DE; - private const uint NvAPI_DRS_SetSetting_ID = 0x577DD202; - private const uint NvAPI_DRS_SaveSettings_ID = 0xFCBC7E14; - private const uint NvAPI_DRS_DestroySession_ID = 0x0DAD9CFF8; - - [LibraryImport("nvapi64")] - private static partial IntPtr nvapi_QueryInterface(uint id); - - private delegate int NvAPI_InitializeDelegate(); - private static NvAPI_InitializeDelegate NvAPI_Initialize; - - private delegate int NvAPI_DRS_CreateSessionDelegate(out IntPtr handle); - private static NvAPI_DRS_CreateSessionDelegate NvAPI_DRS_CreateSession; - - private delegate int NvAPI_DRS_LoadSettingsDelegate(IntPtr handle); - private static NvAPI_DRS_LoadSettingsDelegate NvAPI_DRS_LoadSettings; - - private delegate int NvAPI_DRS_FindProfileByNameDelegate(IntPtr handle, NvapiUnicodeString profileName, out IntPtr profileHandle); - private static NvAPI_DRS_FindProfileByNameDelegate NvAPI_DRS_FindProfileByName; - - private delegate int NvAPI_DRS_CreateProfileDelegate(IntPtr handle, ref NvdrsProfile profileInfo, out IntPtr profileHandle); - private static NvAPI_DRS_CreateProfileDelegate NvAPI_DRS_CreateProfile; - - private delegate int NvAPI_DRS_CreateApplicationDelegate(IntPtr handle, IntPtr profileHandle, ref NvdrsApplicationV4 app); - private static NvAPI_DRS_CreateApplicationDelegate NvAPI_DRS_CreateApplication; - - private delegate int NvAPI_DRS_SetSettingDelegate(IntPtr handle, IntPtr profileHandle, ref NvdrsSetting setting); - private static NvAPI_DRS_SetSettingDelegate NvAPI_DRS_SetSetting; - - private delegate int NvAPI_DRS_SaveSettingsDelegate(IntPtr handle); - private static NvAPI_DRS_SaveSettingsDelegate NvAPI_DRS_SaveSettings; - - private delegate int NvAPI_DRS_DestroySessionDelegate(IntPtr handle); - private static NvAPI_DRS_DestroySessionDelegate NvAPI_DRS_DestroySession; - - private static bool _initialized; - - private static void Check(int status) - { - if (status != 0) - { - throw new Exception($"NVAPI Error: {status}"); - } - } - - private static void Initialize() - { - if (!_initialized) - { - NvAPI_Initialize = NvAPI_Delegate<NvAPI_InitializeDelegate>(NvAPI_Initialize_ID); - - Check(NvAPI_Initialize()); - - NvAPI_DRS_CreateSession = NvAPI_Delegate<NvAPI_DRS_CreateSessionDelegate>(NvAPI_DRS_CreateSession_ID); - NvAPI_DRS_LoadSettings = NvAPI_Delegate<NvAPI_DRS_LoadSettingsDelegate>(NvAPI_DRS_LoadSettings_ID); - NvAPI_DRS_FindProfileByName = NvAPI_Delegate<NvAPI_DRS_FindProfileByNameDelegate>(NvAPI_DRS_FindProfileByName_ID); - NvAPI_DRS_CreateProfile = NvAPI_Delegate<NvAPI_DRS_CreateProfileDelegate>(NvAPI_DRS_CreateProfile_ID); - NvAPI_DRS_CreateApplication = NvAPI_Delegate<NvAPI_DRS_CreateApplicationDelegate>(NvAPI_DRS_CreateApplication_ID); - NvAPI_DRS_SetSetting = NvAPI_Delegate<NvAPI_DRS_SetSettingDelegate>(NvAPI_DRS_SetSetting_ID); - NvAPI_DRS_SaveSettings = NvAPI_Delegate<NvAPI_DRS_SaveSettingsDelegate>(NvAPI_DRS_SaveSettings_ID); - NvAPI_DRS_DestroySession = NvAPI_Delegate<NvAPI_DRS_DestroySessionDelegate>(NvAPI_DRS_DestroySession_ID); - - _initialized = true; - } - } - - private static uint MakeVersion<T>(uint version) where T : unmanaged - { - return (uint)Unsafe.SizeOf<T>() | version << 16; - } - - public static void SetThreadedOptimization(bool enabled) - { - Initialize(); - - uint targetValue = (uint)(enabled ? Nvapi.OglThreadControlEnable : Nvapi.OglThreadControlDisable); - - Check(NvAPI_Initialize()); - - Check(NvAPI_DRS_CreateSession(out IntPtr handle)); - - Check(NvAPI_DRS_LoadSettings(handle)); - - IntPtr profileHandle; - - // Check if the profile already exists. - - int status = NvAPI_DRS_FindProfileByName(handle, new NvapiUnicodeString(ProfileName), out profileHandle); - - if (status != 0) - { - NvdrsProfile profile = new NvdrsProfile { - Version = MakeVersion<NvdrsProfile>(1), - IsPredefined = 0, - GpuSupport = uint.MaxValue - }; - profile.ProfileName.Set(ProfileName); - Check(NvAPI_DRS_CreateProfile(handle, ref profile, out profileHandle)); - - NvdrsApplicationV4 application = new NvdrsApplicationV4 - { - Version = MakeVersion<NvdrsApplicationV4>(4), - IsPredefined = 0, - Flags = 3 // IsMetro, IsCommandLine - }; - application.AppName.Set("Ryujinx.exe"); - application.UserFriendlyName.Set("Ryujinx"); - application.Launcher.Set(""); - application.FileInFolder.Set(""); - - Check(NvAPI_DRS_CreateApplication(handle, profileHandle, ref application)); - } - - NvdrsSetting setting = new NvdrsSetting - { - Version = MakeVersion<NvdrsSetting>(1), - SettingId = Nvapi.OglThreadControlId, - SettingType = NvdrsSettingType.NvdrsDwordType, - SettingLocation = NvdrsSettingLocation.NvdrsCurrentProfileLocation, - IsCurrentPredefined = 0, - IsPredefinedValid = 0, - CurrentValue = targetValue, - PredefinedValue = targetValue - }; - - Check(NvAPI_DRS_SetSetting(handle, profileHandle, ref setting)); - - Check(NvAPI_DRS_SaveSettings(handle)); - - NvAPI_DRS_DestroySession(handle); - } - - private static T NvAPI_Delegate<T>(uint id) where T : class - { - IntPtr ptr = nvapi_QueryInterface(id); - - if (ptr != IntPtr.Zero) - { - return Marshal.GetDelegateForFunctionPointer<T>(ptr); - } - else - { - return null; - } - } - } -} diff --git a/Ryujinx.Common/Hash128.cs b/Ryujinx.Common/Hash128.cs deleted file mode 100644 index 04457bd0..00000000 --- a/Ryujinx.Common/Hash128.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common -{ - [StructLayout(LayoutKind.Sequential)] - public struct Hash128 : IEquatable<Hash128> - { - public ulong Low; - public ulong High; - - public Hash128(ulong low, ulong high) - { - Low = low; - High = high; - } - - public override string ToString() - { - return $"{High:x16}{Low:x16}"; - } - - public static bool operator ==(Hash128 x, Hash128 y) - { - return x.Equals(y); - } - - public static bool operator !=(Hash128 x, Hash128 y) - { - return !x.Equals(y); - } - - public override bool Equals(object obj) - { - return obj is Hash128 hash128 && Equals(hash128); - } - - public bool Equals(Hash128 cmpObj) - { - return Low == cmpObj.Low && High == cmpObj.High; - } - - public override int GetHashCode() - { - return HashCode.Combine(Low, High); - } - } -} diff --git a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs b/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs deleted file mode 100644 index 28a7d546..00000000 --- a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text; - -namespace Ryujinx.Common.Logging -{ - internal class DefaultLogFormatter : ILogFormatter - { - private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>(); - - public string Format(LogEventArgs args) - { - StringBuilder sb = StringBuilderPool.Allocate(); - - try - { - sb.Clear(); - - sb.Append($@"{args.Time:hh\:mm\:ss\.fff}"); - sb.Append($" |{args.Level.ToString()[0]}| "); - - if (args.ThreadName != null) - { - sb.Append(args.ThreadName); - sb.Append(' '); - } - - sb.Append(args.Message); - - if (args.Data is not null) - { - sb.Append(' '); - DynamicObjectFormatter.Format(sb, args.Data); - } - - return sb.ToString(); - } - finally - { - StringBuilderPool.Release(sb); - } - } - } -} diff --git a/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs b/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs deleted file mode 100644 index 5f15cc2a..00000000 --- a/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs +++ /dev/null @@ -1,84 +0,0 @@ -#nullable enable -using System; -using System.Reflection; -using System.Text; - -namespace Ryujinx.Common.Logging -{ - internal class DynamicObjectFormatter - { - private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>(); - - public static string? Format(object? dynamicObject) - { - if (dynamicObject is null) - { - return null; - } - - StringBuilder sb = StringBuilderPool.Allocate(); - - try - { - Format(sb, dynamicObject); - - return sb.ToString(); - } - finally - { - StringBuilderPool.Release(sb); - } - } - - public static void Format(StringBuilder sb, object? dynamicObject) - { - if (dynamicObject is null) - { - return; - } - - PropertyInfo[] props = dynamicObject.GetType().GetProperties(); - - sb.Append('{'); - - foreach (var prop in props) - { - sb.Append(prop.Name); - sb.Append(": "); - - if (typeof(Array).IsAssignableFrom(prop.PropertyType)) - { - Array? array = (Array?) prop.GetValue(dynamicObject); - - if (array is not null) - { - foreach (var item in array) - { - sb.Append(item); - sb.Append(", "); - } - - if (array.Length > 0) - { - sb.Remove(sb.Length - 2, 2); - } - } - } - else - { - sb.Append(prop.GetValue(dynamicObject)); - } - - sb.Append(" ; "); - } - - // We remove the final ';' from the string - if (props.Length > 0) - { - sb.Remove(sb.Length - 3, 3); - } - - sb.Append('}'); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs b/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs deleted file mode 100644 index 9a55bc6b..00000000 --- a/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Common.Logging -{ - interface ILogFormatter - { - string Format(LogEventArgs args); - } -} diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs deleted file mode 100644 index e62676cd..00000000 --- a/Ryujinx.Common/Logging/LogClass.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Logging -{ - [JsonConverter(typeof(TypedStringEnumConverter<LogClass>))] - public enum LogClass - { - Application, - Audio, - AudioRenderer, - Configuration, - Cpu, - Emulation, - FFmpeg, - Font, - Gpu, - Hid, - Host1x, - Kernel, - KernelIpc, - KernelScheduler, - KernelSvc, - Loader, - ModLoader, - Nvdec, - Ptc, - Service, - ServiceAcc, - ServiceAm, - ServiceApm, - ServiceAudio, - ServiceBcat, - ServiceBsd, - ServiceBtm, - ServiceCaps, - ServiceFatal, - ServiceFriend, - ServiceFs, - ServiceHid, - ServiceIrs, - ServiceLdn, - ServiceLdr, - ServiceLm, - ServiceMii, - ServiceMm, - ServiceMnpp, - ServiceNfc, - ServiceNfp, - ServiceNgct, - ServiceNifm, - ServiceNim, - ServiceNs, - ServiceNsd, - ServiceNtc, - ServiceNv, - ServiceOlsc, - ServicePctl, - ServicePcv, - ServicePl, - ServicePrepo, - ServicePsm, - ServicePtm, - ServiceSet, - ServiceSfdnsres, - ServiceSm, - ServiceSsl, - ServiceSss, - ServiceTime, - ServiceVi, - SurfaceFlinger, - TamperMachine, - Ui, - Vic - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/LogEventArgs.cs b/Ryujinx.Common/Logging/LogEventArgs.cs deleted file mode 100644 index a27af780..00000000 --- a/Ryujinx.Common/Logging/LogEventArgs.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace Ryujinx.Common.Logging -{ - public class LogEventArgs : EventArgs - { - public readonly LogLevel Level; - public readonly TimeSpan Time; - public readonly string ThreadName; - - public readonly string Message; - public readonly object Data; - - public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message, object data = null) - { - Level = level; - Time = time; - ThreadName = threadName; - Message = message; - Data = data; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/LogEventArgsJson.cs b/Ryujinx.Common/Logging/LogEventArgsJson.cs deleted file mode 100644 index 425b9766..00000000 --- a/Ryujinx.Common/Logging/LogEventArgsJson.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Logging -{ - internal class LogEventArgsJson - { - public LogLevel Level { get; } - public TimeSpan Time { get; } - public string ThreadName { get; } - - public string Message { get; } - public string Data { get; } - - [JsonConstructor] - public LogEventArgsJson(LogLevel level, TimeSpan time, string threadName, string message, string data = null) - { - Level = level; - Time = time; - ThreadName = threadName; - Message = message; - Data = data; - } - - public static LogEventArgsJson FromLogEventArgs(LogEventArgs args) - { - return new LogEventArgsJson(args.Level, args.Time, args.ThreadName, args.Message, DynamicObjectFormatter.Format(args.Data)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs b/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs deleted file mode 100644 index da21f11e..00000000 --- a/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Logging -{ - [JsonSerializable(typeof(LogEventArgsJson))] - internal partial class LogEventJsonSerializerContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/LogLevel.cs b/Ryujinx.Common/Logging/LogLevel.cs deleted file mode 100644 index 3786c756..00000000 --- a/Ryujinx.Common/Logging/LogLevel.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Logging -{ - [JsonConverter(typeof(TypedStringEnumConverter<LogLevel>))] - public enum LogLevel - { - Debug, - Stub, - Info, - Warning, - Error, - Guest, - AccessLog, - Notice, - Trace - } -} diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs deleted file mode 100644 index 4d48dd48..00000000 --- a/Ryujinx.Common/Logging/Logger.cs +++ /dev/null @@ -1,224 +0,0 @@ -using Ryujinx.Common.SystemInterop; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Threading; - -namespace Ryujinx.Common.Logging -{ - public static class Logger - { - private static readonly Stopwatch m_Time; - - private static readonly bool[] m_EnabledClasses; - - private static readonly List<ILogTarget> m_LogTargets; - - private static readonly StdErrAdapter _stdErrAdapter; - - public static event EventHandler<LogEventArgs> Updated; - - public readonly struct Log - { - internal readonly LogLevel Level; - - internal Log(LogLevel level) - { - Level = level; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PrintMsg(LogClass logClass, string message) - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, "", message))); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Print(LogClass logClass, string message, [CallerMemberName] string caller = "") - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, message))); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Print(LogClass logClass, string message, object data, [CallerMemberName] string caller = "") - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, message), data)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PrintStub(LogClass logClass, string message = "", [CallerMemberName] string caller = "") - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, "Stubbed. " + message))); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PrintStub(LogClass logClass, object data, [CallerMemberName] string caller = "") - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, "Stubbed."), data)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PrintStub(LogClass logClass, string message, object data, [CallerMemberName] string caller = "") - { - if (m_EnabledClasses[(int)logClass]) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, "Stubbed. " + message), data)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PrintRawMsg(string message) - { - Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, message)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static string FormatMessage(LogClass Class, string Caller, string Message) => $"{Class} {Caller}: {Message}"; - } - - public static Log? Debug { get; private set; } - public static Log? Info { get; private set; } - public static Log? Warning { get; private set; } - public static Log? Error { get; private set; } - public static Log? Guest { get; private set; } - public static Log? AccessLog { get; private set; } - public static Log? Stub { get; private set; } - public static Log? Trace { get; private set; } - public static Log Notice { get; } // Always enabled - - static Logger() - { - m_EnabledClasses = new bool[Enum.GetNames<LogClass>().Length]; - - for (int index = 0; index < m_EnabledClasses.Length; index++) - { - m_EnabledClasses[index] = true; - } - - m_LogTargets = new List<ILogTarget>(); - - m_Time = Stopwatch.StartNew(); - - // Logger should log to console by default - AddTarget(new AsyncLogTargetWrapper( - new ConsoleLogTarget("console"), - 1000, - AsyncLogTargetOverflowAction.Discard)); - - Notice = new Log(LogLevel.Notice); - - // Enable important log levels before configuration is loaded - Error = new Log(LogLevel.Error); - Warning = new Log(LogLevel.Warning); - Info = new Log(LogLevel.Info); - Trace = new Log(LogLevel.Trace); - - _stdErrAdapter = new StdErrAdapter(); - } - - public static void RestartTime() - { - m_Time.Restart(); - } - - private static ILogTarget GetTarget(string targetName) - { - foreach (var target in m_LogTargets) - { - if (target.Name.Equals(targetName)) - { - return target; - } - } - - return null; - } - - public static void AddTarget(ILogTarget target) - { - m_LogTargets.Add(target); - - Updated += target.Log; - } - - public static void RemoveTarget(string target) - { - ILogTarget logTarget = GetTarget(target); - - if (logTarget != null) - { - Updated -= logTarget.Log; - - m_LogTargets.Remove(logTarget); - - logTarget.Dispose(); - } - } - - public static void Shutdown() - { - Updated = null; - - _stdErrAdapter.Dispose(); - - foreach (var target in m_LogTargets) - { - target.Dispose(); - } - - m_LogTargets.Clear(); - } - - public static IReadOnlyCollection<LogLevel> GetEnabledLevels() - { - var logs = new Log?[] { Debug, Info, Warning, Error, Guest, AccessLog, Stub, Trace }; - List<LogLevel> levels = new List<LogLevel>(logs.Length); - foreach (var log in logs) - { - if (log.HasValue) - { - levels.Add(log.Value.Level); - } - } - - return levels; - } - - public static void SetEnable(LogLevel logLevel, bool enabled) - { - switch (logLevel) - { - case LogLevel.Debug : Debug = enabled ? new Log(LogLevel.Debug) : new Log?(); break; - case LogLevel.Info : Info = enabled ? new Log(LogLevel.Info) : new Log?(); break; - case LogLevel.Warning : Warning = enabled ? new Log(LogLevel.Warning) : new Log?(); break; - case LogLevel.Error : Error = enabled ? new Log(LogLevel.Error) : new Log?(); break; - case LogLevel.Guest : Guest = enabled ? new Log(LogLevel.Guest) : new Log?(); break; - case LogLevel.AccessLog : AccessLog = enabled ? new Log(LogLevel.AccessLog): new Log?(); break; - case LogLevel.Stub : Stub = enabled ? new Log(LogLevel.Stub) : new Log?(); break; - case LogLevel.Trace : Trace = enabled ? new Log(LogLevel.Trace) : new Log?(); break; - default: throw new ArgumentException("Unknown Log Level"); - } - } - - public static void SetEnable(LogClass logClass, bool enabled) - { - m_EnabledClasses[(int)logClass] = enabled; - } - } -} diff --git a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs b/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs deleted file mode 100644 index 43c62d31..00000000 --- a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading; - -namespace Ryujinx.Common.Logging -{ - public enum AsyncLogTargetOverflowAction - { - /// <summary> - /// Block until there's more room in the queue - /// </summary> - Block = 0, - - /// <summary> - /// Discard the overflowing item - /// </summary> - Discard = 1 - } - - public class AsyncLogTargetWrapper : ILogTarget - { - private ILogTarget _target; - - private Thread _messageThread; - - private BlockingCollection<LogEventArgs> _messageQueue; - - private readonly int _overflowTimeout; - - string ILogTarget.Name { get => _target.Name; } - - public AsyncLogTargetWrapper(ILogTarget target) - : this(target, -1, AsyncLogTargetOverflowAction.Block) - { } - - public AsyncLogTargetWrapper(ILogTarget target, int queueLimit, AsyncLogTargetOverflowAction overflowAction) - { - _target = target; - _messageQueue = new BlockingCollection<LogEventArgs>(queueLimit); - _overflowTimeout = overflowAction == AsyncLogTargetOverflowAction.Block ? -1 : 0; - - _messageThread = new Thread(() => { - while (!_messageQueue.IsCompleted) - { - try - { - _target.Log(this, _messageQueue.Take()); - } - catch (InvalidOperationException) - { - // IOE means that Take() was called on a completed collection. - // Some other thread can call CompleteAdding after we pass the - // IsCompleted check but before we call Take. - // We can simply catch the exception since the loop will break - // on the next iteration. - } - } - }); - - _messageThread.Name = "Logger.MessageThread"; - _messageThread.IsBackground = true; - _messageThread.Start(); - } - - public void Log(object sender, LogEventArgs e) - { - if (!_messageQueue.IsAddingCompleted) - { - _messageQueue.TryAdd(e, _overflowTimeout); - } - } - - public void Dispose() - { - _messageQueue.CompleteAdding(); - _messageThread.Join(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs b/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs deleted file mode 100644 index 7b77c4f2..00000000 --- a/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace Ryujinx.Common.Logging -{ - public class ConsoleLogTarget : ILogTarget - { - private readonly ILogFormatter _formatter; - - private readonly string _name; - - string ILogTarget.Name { get => _name; } - - private static ConsoleColor GetLogColor(LogLevel level) => level switch { - LogLevel.Info => ConsoleColor.White, - LogLevel.Warning => ConsoleColor.Yellow, - LogLevel.Error => ConsoleColor.Red, - LogLevel.Stub => ConsoleColor.DarkGray, - LogLevel.Notice => ConsoleColor.Cyan, - LogLevel.Trace => ConsoleColor.DarkCyan, - _ => ConsoleColor.Gray, - }; - - public ConsoleLogTarget(string name) - { - _formatter = new DefaultLogFormatter(); - _name = name; - } - - public void Log(object sender, LogEventArgs args) - { - Console.ForegroundColor = GetLogColor(args.Level); - Console.WriteLine(_formatter.Format(args)); - Console.ResetColor(); - } - - public void Dispose() - { - Console.ResetColor(); - } - } -} diff --git a/Ryujinx.Common/Logging/Targets/FileLogTarget.cs b/Ryujinx.Common/Logging/Targets/FileLogTarget.cs deleted file mode 100644 index 24dd6d17..00000000 --- a/Ryujinx.Common/Logging/Targets/FileLogTarget.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.IO; -using System.Linq; - -namespace Ryujinx.Common.Logging -{ - public class FileLogTarget : ILogTarget - { - private readonly StreamWriter _logWriter; - private readonly ILogFormatter _formatter; - private readonly string _name; - - string ILogTarget.Name { get => _name; } - - public FileLogTarget(string path, string name) - : this(path, name, FileShare.Read, FileMode.Append) - { } - - public FileLogTarget(string path, string name, FileShare fileShare, FileMode fileMode) - { - // Ensure directory is present - DirectoryInfo logDir = new DirectoryInfo(Path.Combine(path, "Logs")); - logDir.Create(); - - // Clean up old logs, should only keep 3 - FileInfo[] files = logDir.GetFiles("*.log").OrderBy((info => info.CreationTime)).ToArray(); - for (int i = 0; i < files.Length - 2; i++) - { - files[i].Delete(); - } - - string version = ReleaseInformation.GetVersion(); - - // Get path for the current time - path = Path.Combine(logDir.FullName, $"Ryujinx_{version}_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.log"); - - _name = name; - _logWriter = new StreamWriter(File.Open(path, fileMode, FileAccess.Write, fileShare)); - _formatter = new DefaultLogFormatter(); - } - - public void Log(object sender, LogEventArgs args) - { - _logWriter.WriteLine(_formatter.Format(args)); - _logWriter.Flush(); - } - - public void Dispose() - { - _logWriter.WriteLine("---- End of Log ----"); - _logWriter.Flush(); - _logWriter.Dispose(); - } - } -} diff --git a/Ryujinx.Common/Logging/Targets/ILogTarget.cs b/Ryujinx.Common/Logging/Targets/ILogTarget.cs deleted file mode 100644 index d4d26a93..00000000 --- a/Ryujinx.Common/Logging/Targets/ILogTarget.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Ryujinx.Common.Logging -{ - public interface ILogTarget : IDisposable - { - void Log(object sender, LogEventArgs args); - - string Name { get; } - } -} diff --git a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs b/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs deleted file mode 100644 index 06976433..00000000 --- a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Ryujinx.Common.Utilities; -using System.IO; - -namespace Ryujinx.Common.Logging -{ - public class JsonLogTarget : ILogTarget - { - private Stream _stream; - private bool _leaveOpen; - private string _name; - - string ILogTarget.Name { get => _name; } - - public JsonLogTarget(Stream stream, string name) - { - _stream = stream; - _name = name; - } - - public JsonLogTarget(Stream stream, bool leaveOpen) - { - _stream = stream; - _leaveOpen = leaveOpen; - } - - public void Log(object sender, LogEventArgs e) - { - var logEventArgsJson = LogEventArgsJson.FromLogEventArgs(e); - JsonHelper.SerializeToStream(_stream, logEventArgsJson, LogEventJsonSerializerContext.Default.LogEventArgsJson); - } - - public void Dispose() - { - if (!_leaveOpen) - { - _stream.Dispose(); - } - } - } -} diff --git a/Ryujinx.Common/Memory/ArrayPtr.cs b/Ryujinx.Common/Memory/ArrayPtr.cs deleted file mode 100644 index 9e95f75e..00000000 --- a/Ryujinx.Common/Memory/ArrayPtr.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// Represents an array of unmanaged resources. - /// </summary> - /// <typeparam name="T">Array element type</typeparam> - public unsafe struct ArrayPtr<T> : IEquatable<ArrayPtr<T>>, IArray<T> where T : unmanaged - { - private IntPtr _ptr; - - /// <summary> - /// Null pointer. - /// </summary> - public static ArrayPtr<T> Null => new ArrayPtr<T>() { _ptr = IntPtr.Zero }; - - /// <summary> - /// True if the pointer is null, false otherwise. - /// </summary> - public bool IsNull => _ptr == IntPtr.Zero; - - /// <summary> - /// Number of elements on the array. - /// </summary> - public int Length { get; } - - /// <summary> - /// Gets a reference to the item at the given index. - /// </summary> - /// <remarks> - /// No bounds checks are performed, this allows negative indexing, - /// but care must be taken if the index may be out of bounds. - /// </remarks> - /// <param name="index">Index of the element</param> - /// <returns>Reference to the element at the given index</returns> - public ref T this[int index] => ref Unsafe.AsRef<T>((T*)_ptr + index); - - /// <summary> - /// Creates a new array from a given reference. - /// </summary> - /// <remarks> - /// For data on the heap, proper pinning is necessary during - /// use. Failure to do so will result in memory corruption and crashes. - /// </remarks> - /// <param name="value">Reference of the first array element</param> - /// <param name="length">Number of elements on the array</param> - public ArrayPtr(ref T value, int length) - { - _ptr = (IntPtr)Unsafe.AsPointer(ref value); - Length = length; - } - - /// <summary> - /// Creates a new array from a given pointer. - /// </summary> - /// <param name="ptr">Array base pointer</param> - /// <param name="length">Number of elements on the array</param> - public ArrayPtr(T* ptr, int length) - { - _ptr = (IntPtr)ptr; - Length = length; - } - - /// <summary> - /// Creates a new array from a given pointer. - /// </summary> - /// <param name="ptr">Array base pointer</param> - /// <param name="length">Number of elements on the array</param> - public ArrayPtr(IntPtr ptr, int length) - { - _ptr = ptr; - Length = length; - } - - /// <summary> - /// Splits the array starting at the specified position. - /// </summary> - /// <param name="start">Index where the new array should start</param> - /// <returns>New array starting at the specified position</returns> - public ArrayPtr<T> Slice(int start) => new ArrayPtr<T>(ref this[start], Length - start); - - /// <summary> - /// Gets a span from the array. - /// </summary> - /// <returns>Span of the array</returns> - public Span<T> AsSpan() => Length == 0 ? Span<T>.Empty : MemoryMarshal.CreateSpan(ref this[0], Length); - - /// <summary> - /// Gets the array base pointer. - /// </summary> - /// <returns>Base pointer</returns> - public T* ToPointer() => (T*)_ptr; - - public override bool Equals(object obj) - { - return obj is ArrayPtr<T> other && Equals(other); - } - - public bool Equals([AllowNull] ArrayPtr<T> other) - { - return _ptr == other._ptr && Length == other.Length; - } - - public override int GetHashCode() - { - return HashCode.Combine(_ptr, Length); - } - - public static bool operator ==(ArrayPtr<T> left, ArrayPtr<T> right) - { - return left.Equals(right); - } - - public static bool operator !=(ArrayPtr<T> left, ArrayPtr<T> right) - { - return !(left == right); - } - } -} diff --git a/Ryujinx.Common/Memory/Box.cs b/Ryujinx.Common/Memory/Box.cs deleted file mode 100644 index 743cc31d..00000000 --- a/Ryujinx.Common/Memory/Box.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Common.Memory -{ - public class Box<T> where T : unmanaged - { - public T Data; - - public Box() - { - Data = new T(); - } - } -} diff --git a/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs b/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs deleted file mode 100644 index eda350bd..00000000 --- a/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Buffers; -using System.Threading; - -namespace Ryujinx.Common.Memory -{ - public sealed partial class ByteMemoryPool - { - /// <summary> - /// Represents a <see cref="IMemoryOwner{Byte}"/> that wraps an array rented from - /// <see cref="ArrayPool{Byte}.Shared"/> and exposes it as <see cref="Memory{Byte}"/> - /// with a length of the requested size. - /// </summary> - private sealed class ByteMemoryPoolBuffer : IMemoryOwner<byte> - { - private byte[] _array; - private readonly int _length; - - public ByteMemoryPoolBuffer(int length) - { - _array = ArrayPool<byte>.Shared.Rent(length); - _length = length; - } - - /// <summary> - /// Returns a <see cref="Memory{Byte}"/> belonging to this owner. - /// </summary> - public Memory<byte> Memory - { - get - { - byte[] array = _array; - - ObjectDisposedException.ThrowIf(array is null, this); - - return new Memory<byte>(array, 0, _length); - } - } - - public void Dispose() - { - var array = Interlocked.Exchange(ref _array, null); - - if (array != null) - { - ArrayPool<byte>.Shared.Return(array); - } - } - } - } -} diff --git a/Ryujinx.Common/Memory/ByteMemoryPool.cs b/Ryujinx.Common/Memory/ByteMemoryPool.cs deleted file mode 100644 index 2910f408..00000000 --- a/Ryujinx.Common/Memory/ByteMemoryPool.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Buffers; - -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// Provides a pool of re-usable byte array instances. - /// </summary> - public sealed partial class ByteMemoryPool - { - private static readonly ByteMemoryPool _shared = new ByteMemoryPool(); - - /// <summary> - /// Constructs a <see cref="ByteMemoryPool"/> instance. Private to force access through - /// the <see cref="ByteMemoryPool.Shared"/> instance. - /// </summary> - private ByteMemoryPool() - { - // No implementation - } - - /// <summary> - /// Retrieves a shared <see cref="ByteMemoryPool"/> instance. - /// </summary> - public static ByteMemoryPool Shared => _shared; - - /// <summary> - /// Returns the maximum buffer size supported by this pool. - /// </summary> - public int MaxBufferSize => Array.MaxLength; - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> Rent(long length) - => RentImpl(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> Rent(ulong length) - => RentImpl(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> Rent(int length) - => RentImpl(length); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> RentCleared(long length) - => RentCleared(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> RentCleared(ulong length) - => RentCleared(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public IMemoryOwner<byte> RentCleared(int length) - { - var buffer = RentImpl(length); - - buffer.Memory.Span.Clear(); - - return buffer; - } - - private static ByteMemoryPoolBuffer RentImpl(int length) - { - if ((uint)length > Array.MaxLength) - { - throw new ArgumentOutOfRangeException(nameof(length), length, null); - } - - return new ByteMemoryPoolBuffer(length); - } - } -} diff --git a/Ryujinx.Common/Memory/IArray.cs b/Ryujinx.Common/Memory/IArray.cs deleted file mode 100644 index 8f17fade..00000000 --- a/Ryujinx.Common/Memory/IArray.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// Array interface. - /// </summary> - /// <typeparam name="T">Element type</typeparam> - public interface IArray<T> where T : unmanaged - { - /// <summary> - /// Used to index the array. - /// </summary> - /// <param name="index">Element index</param> - /// <returns>Element at the specified index</returns> - ref T this[int index] { get; } - - /// <summary> - /// Number of elements on the array. - /// </summary> - int Length { get; } - } -} diff --git a/Ryujinx.Common/Memory/MemoryStreamManager.cs b/Ryujinx.Common/Memory/MemoryStreamManager.cs deleted file mode 100644 index 68b82999..00000000 --- a/Ryujinx.Common/Memory/MemoryStreamManager.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Microsoft.IO; -using System; - -namespace Ryujinx.Common.Memory -{ - public static class MemoryStreamManager - { - private static readonly RecyclableMemoryStreamManager _shared = new RecyclableMemoryStreamManager(); - - /// <summary> - /// We don't expose the <c>RecyclableMemoryStreamManager</c> directly because version 2.x - /// returns them as <c>MemoryStream</c>. This Shared class is here to a) offer only the GetStream() versions we use - /// and b) return them as <c>RecyclableMemoryStream</c> so we don't have to cast. - /// </summary> - public static class Shared - { - /// <summary> - /// Retrieve a new <c>MemoryStream</c> object with no tag and a default initial capacity. - /// </summary> - /// <returns>A <c>RecyclableMemoryStream</c></returns> - public static RecyclableMemoryStream GetStream() - => new RecyclableMemoryStream(_shared); - - /// <summary> - /// Retrieve a new <c>MemoryStream</c> object with the contents copied from the provided - /// buffer. The provided buffer is not wrapped or used after construction. - /// </summary> - /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> - /// <param name="buffer">The byte buffer to copy data from</param> - /// <returns>A <c>RecyclableMemoryStream</c></returns> - public static RecyclableMemoryStream GetStream(byte[] buffer) - => GetStream(Guid.NewGuid(), null, buffer, 0, buffer.Length); - - /// <summary> - /// Retrieve a new <c>MemoryStream</c> object with the given tag and with contents copied from the provided - /// buffer. The provided buffer is not wrapped or used after construction. - /// </summary> - /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> - /// <param name="buffer">The byte buffer to copy data from</param> - /// <returns>A <c>RecyclableMemoryStream</c></returns> - public static RecyclableMemoryStream GetStream(ReadOnlySpan<byte> buffer) - => GetStream(Guid.NewGuid(), null, buffer); - - /// <summary> - /// Retrieve a new <c>RecyclableMemoryStream</c> object with the given tag and with contents copied from the provided - /// buffer. The provided buffer is not wrapped or used after construction. - /// </summary> - /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> - /// <param name="id">A unique identifier which can be used to trace usages of the stream</param> - /// <param name="tag">A tag which can be used to track the source of the stream</param> - /// <param name="buffer">The byte buffer to copy data from</param> - /// <returns>A <c>RecyclableMemoryStream</c></returns> - public static RecyclableMemoryStream GetStream(Guid id, string tag, ReadOnlySpan<byte> buffer) - { - RecyclableMemoryStream stream = null; - try - { - stream = new RecyclableMemoryStream(_shared, id, tag, buffer.Length); - stream.Write(buffer); - stream.Position = 0; - return stream; - } - catch - { - stream?.Dispose(); - throw; - } - } - - /// <summary> - /// Retrieve a new <c>RecyclableMemoryStream</c> object with the given tag and with contents copied from the provided - /// buffer. The provided buffer is not wrapped or used after construction. - /// </summary> - /// <remarks>The new stream's position is set to the beginning of the stream when returned</remarks> - /// <param name="id">A unique identifier which can be used to trace usages of the stream</param> - /// <param name="tag">A tag which can be used to track the source of the stream</param> - /// <param name="buffer">The byte buffer to copy data from</param> - /// <param name="offset">The offset from the start of the buffer to copy from</param> - /// <param name="count">The number of bytes to copy from the buffer</param> - /// <returns>A <c>RecyclableMemoryStream</c></returns> - public static RecyclableMemoryStream GetStream(Guid id, string tag, byte[] buffer, int offset, int count) - { - RecyclableMemoryStream stream = null; - try - { - stream = new RecyclableMemoryStream(_shared, id, tag, count); - stream.Write(buffer, offset, count); - stream.Position = 0; - return stream; - } - catch - { - stream?.Dispose(); - throw; - } - } - } - } -} diff --git a/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs b/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs deleted file mode 100644 index 78eeb16f..00000000 --- a/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Runtime.InteropServices; -using System.Threading; - -using static Ryujinx.Common.Memory.PartialUnmaps.PartialUnmapHelpers; - -namespace Ryujinx.Common.Memory.PartialUnmaps -{ - /// <summary> - /// A simple implementation of a ReaderWriterLock which can be used from native code. - /// </summary> - [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct NativeReaderWriterLock - { - public int WriteLock; - public int ReaderCount; - - public static int WriteLockOffset; - public static int ReaderCountOffset; - - /// <summary> - /// Populates the field offsets for use when emitting native code. - /// </summary> - static NativeReaderWriterLock() - { - NativeReaderWriterLock instance = new NativeReaderWriterLock(); - - WriteLockOffset = OffsetOf(ref instance, ref instance.WriteLock); - ReaderCountOffset = OffsetOf(ref instance, ref instance.ReaderCount); - } - - /// <summary> - /// Acquires the reader lock. - /// </summary> - public void AcquireReaderLock() - { - // Must take write lock for a very short time to become a reader. - - while (Interlocked.CompareExchange(ref WriteLock, 1, 0) != 0) { } - - Interlocked.Increment(ref ReaderCount); - - Interlocked.Exchange(ref WriteLock, 0); - } - - /// <summary> - /// Releases the reader lock. - /// </summary> - public void ReleaseReaderLock() - { - Interlocked.Decrement(ref ReaderCount); - } - - /// <summary> - /// Upgrades to a writer lock. The reader lock is temporarily released while obtaining the writer lock. - /// </summary> - public void UpgradeToWriterLock() - { - // Prevent any more threads from entering reader. - // If the write lock is already taken, wait for it to not be taken. - - Interlocked.Decrement(ref ReaderCount); - - while (Interlocked.CompareExchange(ref WriteLock, 1, 0) != 0) { } - - // Wait for reader count to drop to 0, then take the lock again as the only reader. - - while (Interlocked.CompareExchange(ref ReaderCount, 1, 0) != 0) { } - } - - /// <summary> - /// Downgrades from a writer lock, back to a reader one. - /// </summary> - public void DowngradeFromWriterLock() - { - // Release the WriteLock. - - Interlocked.Exchange(ref WriteLock, 0); - } - } -} diff --git a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs b/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs deleted file mode 100644 index e650de06..00000000 --- a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Ryujinx.Common.Memory.PartialUnmaps -{ - static class PartialUnmapHelpers - { - /// <summary> - /// Calculates a byte offset of a given field within a struct. - /// </summary> - /// <typeparam name="T">Struct type</typeparam> - /// <typeparam name="T2">Field type</typeparam> - /// <param name="storage">Parent struct</param> - /// <param name="target">Field</param> - /// <returns>The byte offset of the given field in the given struct</returns> - public static int OffsetOf<T, T2>(ref T2 storage, ref T target) - { - return (int)Unsafe.ByteOffset(ref Unsafe.As<T2, T>(ref storage), ref target); - } - } -} diff --git a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs b/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs deleted file mode 100644 index 5b0bc07e..00000000 --- a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.Marshalling; -using System.Runtime.Versioning; -using System.Threading; - -using static Ryujinx.Common.Memory.PartialUnmaps.PartialUnmapHelpers; - -namespace Ryujinx.Common.Memory.PartialUnmaps -{ - /// <summary> - /// State for partial unmaps. Intended to be used on Windows. - /// </summary> - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public partial struct PartialUnmapState - { - public NativeReaderWriterLock PartialUnmapLock; - public int PartialUnmapsCount; - public ThreadLocalMap<int> LocalCounts; - - public readonly static int PartialUnmapLockOffset; - public readonly static int PartialUnmapsCountOffset; - public readonly static int LocalCountsOffset; - - public readonly static IntPtr GlobalState; - - [SupportedOSPlatform("windows")] - [LibraryImport("kernel32.dll")] - private static partial int GetCurrentThreadId(); - - [SupportedOSPlatform("windows")] - [LibraryImport("kernel32.dll", SetLastError = true)] - private static partial IntPtr OpenThread(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwThreadId); - - [SupportedOSPlatform("windows")] - [LibraryImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs (UnmanagedType.Bool)] - private static partial bool CloseHandle(IntPtr hObject); - - [SupportedOSPlatform("windows")] - [LibraryImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode); - - /// <summary> - /// Creates a global static PartialUnmapState and populates the field offsets. - /// </summary> - static unsafe PartialUnmapState() - { - PartialUnmapState instance = new PartialUnmapState(); - - PartialUnmapLockOffset = OffsetOf(ref instance, ref instance.PartialUnmapLock); - PartialUnmapsCountOffset = OffsetOf(ref instance, ref instance.PartialUnmapsCount); - LocalCountsOffset = OffsetOf(ref instance, ref instance.LocalCounts); - - int size = Unsafe.SizeOf<PartialUnmapState>(); - GlobalState = Marshal.AllocHGlobal(size); - Unsafe.InitBlockUnaligned((void*)GlobalState, 0, (uint)size); - } - - /// <summary> - /// Resets the global state. - /// </summary> - public static unsafe void Reset() - { - int size = Unsafe.SizeOf<PartialUnmapState>(); - Unsafe.InitBlockUnaligned((void*)GlobalState, 0, (uint)size); - } - - /// <summary> - /// Gets a reference to the global state. - /// </summary> - /// <returns>A reference to the global state</returns> - public static unsafe ref PartialUnmapState GetRef() - { - return ref Unsafe.AsRef<PartialUnmapState>((void*)GlobalState); - } - - /// <summary> - /// Checks if an access violation handler should retry execution due to a fault caused by partial unmap. - /// </summary> - /// <remarks> - /// Due to Windows limitations, <see cref="UnmapView"/> might need to unmap more memory than requested. - /// The additional memory that was unmapped is later remapped, however this leaves a time gap where the - /// memory might be accessed but is unmapped. Users of the API must compensate for that by catching the - /// access violation and retrying if it happened between the unmap and remap operation. - /// This method can be used to decide if retrying in such cases is necessary or not. - /// - /// This version of the function is not used, but serves as a reference for the native - /// implementation in ARMeilleure. - /// </remarks> - /// <returns>True if execution should be retried, false otherwise</returns> - [SupportedOSPlatform("windows")] - public bool RetryFromAccessViolation() - { - PartialUnmapLock.AcquireReaderLock(); - - int threadID = GetCurrentThreadId(); - int threadIndex = LocalCounts.GetOrReserve(threadID, 0); - - if (threadIndex == -1) - { - // Out of thread local space... try again later. - - PartialUnmapLock.ReleaseReaderLock(); - - return true; - } - - ref int threadLocalPartialUnmapsCount = ref LocalCounts.GetValue(threadIndex); - - bool retry = threadLocalPartialUnmapsCount != PartialUnmapsCount; - if (retry) - { - threadLocalPartialUnmapsCount = PartialUnmapsCount; - } - - PartialUnmapLock.ReleaseReaderLock(); - - return retry; - } - - /// <summary> - /// Iterates and trims threads in the thread -> count map that - /// are no longer active. - /// </summary> - [SupportedOSPlatform("windows")] - public void TrimThreads() - { - const uint ExitCodeStillActive = 259; - const int ThreadQueryInformation = 0x40; - - Span<int> ids = LocalCounts.ThreadIds.AsSpan(); - - for (int i = 0; i < ids.Length; i++) - { - int id = ids[i]; - - if (id != 0) - { - IntPtr handle = OpenThread(ThreadQueryInformation, false, (uint)id); - - if (handle == IntPtr.Zero) - { - Interlocked.CompareExchange(ref ids[i], 0, id); - } - else - { - GetExitCodeThread(handle, out uint exitCode); - - if (exitCode != ExitCodeStillActive) - { - Interlocked.CompareExchange(ref ids[i], 0, id); - } - - CloseHandle(handle); - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs b/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs deleted file mode 100644 index a3bd5be8..00000000 --- a/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Runtime.InteropServices; -using System.Threading; - -using static Ryujinx.Common.Memory.PartialUnmaps.PartialUnmapHelpers; - -namespace Ryujinx.Common.Memory.PartialUnmaps -{ - /// <summary> - /// A simple fixed size thread safe map that can be used from native code. - /// Integer thread IDs map to corresponding structs. - /// </summary> - /// <typeparam name="T">The value type for the map</typeparam> - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct ThreadLocalMap<T> where T : unmanaged - { - public const int MapSize = 20; - - public Array20<int> ThreadIds; - public Array20<T> Structs; - - public static int ThreadIdsOffset; - public static int StructsOffset; - - /// <summary> - /// Populates the field offsets for use when emitting native code. - /// </summary> - static ThreadLocalMap() - { - ThreadLocalMap<T> instance = new ThreadLocalMap<T>(); - - ThreadIdsOffset = OffsetOf(ref instance, ref instance.ThreadIds); - StructsOffset = OffsetOf(ref instance, ref instance.Structs); - } - - /// <summary> - /// Gets the index of a given thread ID in the map, or reserves one. - /// When reserving a struct, its value is set to the given initial value. - /// Returns -1 when there is no space to reserve a new entry. - /// </summary> - /// <param name="threadId">Thread ID to use as a key</param> - /// <param name="initial">Initial value of the associated struct.</param> - /// <returns>The index of the entry, or -1 if none</returns> - public int GetOrReserve(int threadId, T initial) - { - // Try get a match first. - - for (int i = 0; i < MapSize; i++) - { - int compare = Interlocked.CompareExchange(ref ThreadIds[i], threadId, threadId); - - if (compare == threadId) - { - return i; - } - } - - // Try get a free entry. Since the id is assumed to be unique to this thread, we know it doesn't exist yet. - - for (int i = 0; i < MapSize; i++) - { - int compare = Interlocked.CompareExchange(ref ThreadIds[i], threadId, 0); - - if (compare == 0) - { - Structs[i] = initial; - return i; - } - } - - return -1; - } - - /// <summary> - /// Gets the struct value for a given map entry. - /// </summary> - /// <param name="index">Index of the entry</param> - /// <returns>A reference to the struct value</returns> - public ref T GetValue(int index) - { - return ref Structs[index]; - } - - /// <summary> - /// Releases an entry from the map. - /// </summary> - /// <param name="index">Index of the entry to release</param> - public void Release(int index) - { - Interlocked.Exchange(ref ThreadIds[index], 0); - } - } -} diff --git a/Ryujinx.Common/Memory/Ptr.cs b/Ryujinx.Common/Memory/Ptr.cs deleted file mode 100644 index 66bcf569..00000000 --- a/Ryujinx.Common/Memory/Ptr.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// Represents a pointer to an unmanaged resource. - /// </summary> - /// <typeparam name="T">Type of the unmanaged resource</typeparam> - public unsafe struct Ptr<T> : IEquatable<Ptr<T>> where T : unmanaged - { - private IntPtr _ptr; - - /// <summary> - /// Null pointer. - /// </summary> - public static Ptr<T> Null => new Ptr<T>() { _ptr = IntPtr.Zero }; - - /// <summary> - /// True if the pointer is null, false otherwise. - /// </summary> - public bool IsNull => _ptr == IntPtr.Zero; - - /// <summary> - /// Gets a reference to the value. - /// </summary> - public ref T Value => ref Unsafe.AsRef<T>((void*)_ptr); - - /// <summary> - /// Creates a new pointer to an unmanaged resource. - /// </summary> - /// <remarks> - /// For data on the heap, proper pinning is necessary during - /// use. Failure to do so will result in memory corruption and crashes. - /// </remarks> - /// <param name="value">Reference to the unmanaged resource</param> - public Ptr(ref T value) - { - _ptr = (IntPtr)Unsafe.AsPointer(ref value); - } - - public override bool Equals(object obj) - { - return obj is Ptr<T> other && Equals(other); - } - - public bool Equals([AllowNull] Ptr<T> other) - { - return _ptr == other._ptr; - } - - public override int GetHashCode() - { - return _ptr.GetHashCode(); - } - - public static bool operator ==(Ptr<T> left, Ptr<T> right) - { - return left.Equals(right); - } - - public static bool operator !=(Ptr<T> left, Ptr<T> right) - { - return !(left == right); - } - } -} diff --git a/Ryujinx.Common/Memory/SpanOrArray.cs b/Ryujinx.Common/Memory/SpanOrArray.cs deleted file mode 100644 index a9798d27..00000000 --- a/Ryujinx.Common/Memory/SpanOrArray.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; - -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// A struct that can represent both a Span and Array. - /// This is useful to keep the Array representation when possible to avoid copies. - /// </summary> - /// <typeparam name="T">Element Type</typeparam> - public readonly ref struct SpanOrArray<T> where T : unmanaged - { - public readonly T[] Array; - public readonly ReadOnlySpan<T> Span; - - /// <summary> - /// Create a new SpanOrArray from an array. - /// </summary> - /// <param name="array">Array to store</param> - public SpanOrArray(T[] array) - { - Array = array; - Span = ReadOnlySpan<T>.Empty; - } - - /// <summary> - /// Create a new SpanOrArray from a readonly span. - /// </summary> - /// <param name="array">Span to store</param> - public SpanOrArray(ReadOnlySpan<T> span) - { - Array = null; - Span = span; - } - - /// <summary> - /// Return the contained array, or convert the span if necessary. - /// </summary> - /// <returns>An array containing the data</returns> - public T[] ToArray() - { - return Array ?? Span.ToArray(); - } - - /// <summary> - /// Return a ReadOnlySpan from either the array or ReadOnlySpan. - /// </summary> - /// <returns>A ReadOnlySpan containing the data</returns> - public ReadOnlySpan<T> AsSpan() - { - return Array ?? Span; - } - - /// <summary> - /// Cast an array to a SpanOrArray. - /// </summary> - /// <param name="array">Source array</param> - public static implicit operator SpanOrArray<T>(T[] array) - { - return new SpanOrArray<T>(array); - } - - /// <summary> - /// Cast a ReadOnlySpan to a SpanOrArray. - /// </summary> - /// <param name="span">Source ReadOnlySpan</param> - public static implicit operator SpanOrArray<T>(ReadOnlySpan<T> span) - { - return new SpanOrArray<T>(span); - } - - /// <summary> - /// Cast a Span to a SpanOrArray. - /// </summary> - /// <param name="span">Source Span</param> - public static implicit operator SpanOrArray<T>(Span<T> span) - { - return new SpanOrArray<T>(span); - } - - /// <summary> - /// Cast a SpanOrArray to a ReadOnlySpan - /// </summary> - /// <param name="spanOrArray">Source SpanOrArray</param> - public static implicit operator ReadOnlySpan<T>(SpanOrArray<T> spanOrArray) - { - return spanOrArray.AsSpan(); - } - } -} diff --git a/Ryujinx.Common/Memory/SpanReader.cs b/Ryujinx.Common/Memory/SpanReader.cs deleted file mode 100644 index 673932d0..00000000 --- a/Ryujinx.Common/Memory/SpanReader.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Memory -{ - public ref struct SpanReader - { - private ReadOnlySpan<byte> _input; - - public int Length => _input.Length; - - public SpanReader(ReadOnlySpan<byte> input) - { - _input = input; - } - - public T Read<T>() where T : unmanaged - { - T value = MemoryMarshal.Cast<byte, T>(_input)[0]; - - _input = _input.Slice(Unsafe.SizeOf<T>()); - - return value; - } - - public ReadOnlySpan<byte> GetSpan(int size) - { - ReadOnlySpan<byte> data = _input.Slice(0, size); - - _input = _input.Slice(size); - - return data; - } - - public ReadOnlySpan<byte> GetSpanSafe(int size) - { - return GetSpan((int)Math.Min((uint)_input.Length, (uint)size)); - } - - public T ReadAt<T>(int offset) where T : unmanaged - { - return MemoryMarshal.Cast<byte, T>(_input.Slice(offset))[0]; - } - - public ReadOnlySpan<byte> GetSpanAt(int offset, int size) - { - return _input.Slice(offset, size); - } - - public void Skip(int size) - { - _input = _input.Slice(size); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Memory/SpanWriter.cs b/Ryujinx.Common/Memory/SpanWriter.cs deleted file mode 100644 index 5c35569d..00000000 --- a/Ryujinx.Common/Memory/SpanWriter.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Memory -{ - public ref struct SpanWriter - { - private Span<byte> _output; - - public int Length => _output.Length; - - public SpanWriter(Span<byte> output) - { - _output = output; - } - - public void Write<T>(T value) where T : unmanaged - { - MemoryMarshal.Cast<byte, T>(_output)[0] = value; - _output = _output.Slice(Unsafe.SizeOf<T>()); - } - - public void Write(ReadOnlySpan<byte> data) - { - data.CopyTo(_output.Slice(0, data.Length)); - _output = _output.Slice(data.Length); - } - - public void WriteAt<T>(int offset, T value) where T : unmanaged - { - MemoryMarshal.Cast<byte, T>(_output.Slice(offset))[0] = value; - } - - public void WriteAt(int offset, ReadOnlySpan<byte> data) - { - data.CopyTo(_output.Slice(offset, data.Length)); - } - - public void Skip(int size) - { - _output = _output.Slice(size); - } - } -} diff --git a/Ryujinx.Common/Memory/StructArrayHelpers.cs b/Ryujinx.Common/Memory/StructArrayHelpers.cs deleted file mode 100644 index a039d04e..00000000 --- a/Ryujinx.Common/Memory/StructArrayHelpers.cs +++ /dev/null @@ -1,654 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Memory -{ - public struct Array1<T> : IArray<T> where T : unmanaged - { - T _e0; - public int Length => 1; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 1); - } - public struct Array2<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array1<T> _other; -#pragma warning restore CS0169 - public int Length => 2; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 2); - } - public struct Array3<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array2<T> _other; -#pragma warning restore CS0169 - public int Length => 3; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 3); - } - public struct Array4<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array3<T> _other; -#pragma warning restore CS0169 - public int Length => 4; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 4); - } - public struct Array5<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array4<T> _other; -#pragma warning restore CS0169 - public int Length => 5; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 5); - } - public struct Array6<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array5<T> _other; -#pragma warning restore CS0169 - public int Length => 6; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 6); - } - public struct Array7<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array6<T> _other; -#pragma warning restore CS0169 - public int Length => 7; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 7); - } - public struct Array8<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array7<T> _other; -#pragma warning restore CS0169 - public int Length => 8; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 8); - } - public struct Array9<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array8<T> _other; -#pragma warning restore CS0169 - public int Length => 9; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 9); - } - public struct Array10<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array9<T> _other; -#pragma warning restore CS0169 - public int Length => 10; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 10); - } - public struct Array11<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array10<T> _other; -#pragma warning restore CS0169 - public int Length => 11; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 11); - } - public struct Array12<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array11<T> _other; -#pragma warning restore CS0169 - public int Length => 12; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 12); - } - public struct Array13<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array12<T> _other; -#pragma warning restore CS0169 - public int Length => 13; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 13); - } - public struct Array14<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array13<T> _other; -#pragma warning restore CS0169 - public int Length => 14; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 14); - } - public struct Array15<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array14<T> _other; -#pragma warning restore CS0169 - public int Length => 15; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 15); - } - public struct Array16<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array15<T> _other; -#pragma warning restore CS0169 - public int Length => 16; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 16); - } - public struct Array17<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array16<T> _other; -#pragma warning restore CS0169 - public int Length => 17; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 17); - } - public struct Array18<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array17<T> _other; -#pragma warning restore CS0169 - public int Length => 18; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 18); - } - public struct Array19<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array18<T> _other; -#pragma warning restore CS0169 - public int Length => 19; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 19); - } - public struct Array20<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array19<T> _other; -#pragma warning restore CS0169 - public int Length => 20; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 20); - } - public struct Array21<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array20<T> _other; -#pragma warning restore CS0169 - public int Length => 21; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 21); - } - public struct Array22<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array21<T> _other; -#pragma warning restore CS0169 - public int Length => 22; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 22); - } - public struct Array23<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array22<T> _other; -#pragma warning restore CS0169 - public int Length => 23; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 23); - } - public struct Array24<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array23<T> _other; -#pragma warning restore CS0169 - public int Length => 24; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 24); - } - public struct Array25<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array24<T> _other; -#pragma warning restore CS0169 - public int Length => 25; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 25); - } - public struct Array26<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array25<T> _other; -#pragma warning restore CS0169 - public int Length => 26; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 26); - } - public struct Array27<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array26<T> _other; -#pragma warning restore CS0169 - public int Length => 27; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 27); - } - public struct Array28<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array27<T> _other; -#pragma warning restore CS0169 - public int Length => 28; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 28); - } - public struct Array29<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array28<T> _other; -#pragma warning restore CS0169 - public int Length => 29; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 29); - } - public struct Array30<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array29<T> _other; -#pragma warning restore CS0169 - public int Length => 30; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 30); - } - public struct Array31<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array30<T> _other; -#pragma warning restore CS0169 - public int Length => 31; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 31); - } - public struct Array32<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array31<T> _other; -#pragma warning restore CS0169 - public int Length => 32; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 32); - } - public struct Array33<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array32<T> _other; -#pragma warning restore CS0169 - public int Length => 33; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 33); - } - public struct Array34<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array33<T> _other; -#pragma warning restore CS0169 - public int Length => 34; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 34); - } - public struct Array35<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array34<T> _other; -#pragma warning restore CS0169 - public int Length => 35; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 35); - } - public struct Array36<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array35<T> _other; -#pragma warning restore CS0169 - public int Length => 36; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 36); - } - public struct Array37<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array36<T> _other; -#pragma warning restore CS0169 - public int Length => 37; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 37); - } - public struct Array38<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array37<T> _other; -#pragma warning restore CS0169 - public int Length => 38; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 38); - } - public struct Array39<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array38<T> _other; -#pragma warning restore CS0169 - public int Length => 39; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 39); - } - public struct Array40<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array39<T> _other; -#pragma warning restore CS0169 - public int Length => 40; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 40); - } - public struct Array41<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array40<T> _other; -#pragma warning restore CS0169 - public int Length => 41; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 41); - } - public struct Array42<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array41<T> _other; -#pragma warning restore CS0169 - public int Length => 42; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 42); - } - public struct Array43<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array42<T> _other; -#pragma warning restore CS0169 - public int Length => 43; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 43); - } - public struct Array44<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array43<T> _other; -#pragma warning restore CS0169 - public int Length => 44; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 44); - } - public struct Array45<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array44<T> _other; -#pragma warning restore CS0169 - public int Length => 45; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 45); - } - public struct Array46<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array45<T> _other; -#pragma warning restore CS0169 - public int Length => 46; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 46); - } - public struct Array47<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array46<T> _other; -#pragma warning restore CS0169 - public int Length => 47; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 47); - } - public struct Array48<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array47<T> _other; -#pragma warning restore CS0169 - public int Length => 48; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 48); - } - public struct Array49<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array48<T> _other; -#pragma warning restore CS0169 - public int Length => 49; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 49); - } - public struct Array50<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array49<T> _other; -#pragma warning restore CS0169 - public int Length => 50; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 50); - } - public struct Array51<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array50<T> _other; -#pragma warning restore CS0169 - public int Length => 51; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 51); - } - public struct Array52<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array51<T> _other; -#pragma warning restore CS0169 - public int Length => 52; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 52); - } - public struct Array53<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array52<T> _other; -#pragma warning restore CS0169 - public int Length => 53; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 53); - } - public struct Array54<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array53<T> _other; -#pragma warning restore CS0169 - public int Length => 54; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 54); - } - public struct Array55<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array54<T> _other; -#pragma warning restore CS0169 - public int Length => 55; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 55); - } - public struct Array56<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array55<T> _other; -#pragma warning restore CS0169 - public int Length => 56; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 56); - } - public struct Array57<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array56<T> _other; -#pragma warning restore CS0169 - public int Length => 57; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 57); - } - public struct Array58<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array57<T> _other; -#pragma warning restore CS0169 - public int Length => 58; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 58); - } - public struct Array59<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array58<T> _other; -#pragma warning restore CS0169 - public int Length => 59; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 59); - } - public struct Array60<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array59<T> _other; -#pragma warning restore CS0169 - public int Length => 60; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 60); - } - public struct Array61<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array60<T> _other; -#pragma warning restore CS0169 - public int Length => 61; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 61); - } - public struct Array62<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array61<T> _other; -#pragma warning restore CS0169 - public int Length => 62; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 62); - } - public struct Array63<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array62<T> _other; -#pragma warning restore CS0169 - public int Length => 63; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 63); - } - public struct Array64<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array63<T> _other; -#pragma warning restore CS0169 - public int Length => 64; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 64); - } - public struct Array73<T> : IArray<T> where T : unmanaged - { -#pragma warning disable CS0169 - T _e0; - Array64<T> _other; - Array8<T> _other2; -#pragma warning restore CS0169 - public int Length => 73; - public ref T this[int index] => ref AsSpan()[index]; - public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 73); - } -} diff --git a/Ryujinx.Common/Memory/StructByteArrayHelpers.cs b/Ryujinx.Common/Memory/StructByteArrayHelpers.cs deleted file mode 100644 index 8693f5b8..00000000 --- a/Ryujinx.Common/Memory/StructByteArrayHelpers.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Memory -{ - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray128 : IArray<byte> - { - private const int Size = 128; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } - - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray256 : IArray<byte> - { - private const int Size = 256; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } - - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray512 : IArray<byte> - { - private const int Size = 512; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } - - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray1024 : IArray<byte> - { - private const int Size = 1024; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } - - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray2048 : IArray<byte> - { - private const int Size = 2048; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } - - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] - public struct ByteArray4096 : IArray<byte> - { - private const int Size = 4096; - - byte _element; - - public int Length => Size; - public ref byte this[int index] => ref AsSpan()[index]; - public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); - } -} diff --git a/Ryujinx.Common/PerformanceCounter.cs b/Ryujinx.Common/PerformanceCounter.cs deleted file mode 100644 index 97ee23a2..00000000 --- a/Ryujinx.Common/PerformanceCounter.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Diagnostics; - -namespace Ryujinx.Common -{ - public static class PerformanceCounter - { - private static double _ticksToNs; - - /// <summary> - /// Represents the number of ticks in 1 day. - /// </summary> - public static long TicksPerDay { get; } - - /// <summary> - /// Represents the number of ticks in 1 hour. - /// </summary> - public static long TicksPerHour { get; } - - /// <summary> - /// Represents the number of ticks in 1 minute. - /// </summary> - public static long TicksPerMinute { get; } - - /// <summary> - /// Represents the number of ticks in 1 second. - /// </summary> - public static long TicksPerSecond { get; } - - /// <summary> - /// Represents the number of ticks in 1 millisecond. - /// </summary> - public static long TicksPerMillisecond { get; } - - /// <summary> - /// Gets the number of ticks elapsed since the system started. - /// </summary> - public static long ElapsedTicks - { - get - { - return Stopwatch.GetTimestamp(); - } - } - - /// <summary> - /// Gets the number of milliseconds elapsed since the system started. - /// </summary> - public static long ElapsedMilliseconds - { - get - { - long timestamp = Stopwatch.GetTimestamp(); - - return timestamp / TicksPerMillisecond; - } - } - - /// <summary> - /// Gets the number of nanoseconds elapsed since the system started. - /// </summary> - public static long ElapsedNanoseconds - { - get - { - long timestamp = Stopwatch.GetTimestamp(); - - return (long)(timestamp * _ticksToNs); - } - } - - static PerformanceCounter() - { - TicksPerMillisecond = Stopwatch.Frequency / 1000; - TicksPerSecond = Stopwatch.Frequency; - TicksPerMinute = TicksPerSecond * 60; - TicksPerHour = TicksPerMinute * 60; - TicksPerDay = TicksPerHour * 24; - - _ticksToNs = 1000000000.0 / Stopwatch.Frequency; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Pools/ObjectPool.cs b/Ryujinx.Common/Pools/ObjectPool.cs deleted file mode 100644 index e0bf5df6..00000000 --- a/Ryujinx.Common/Pools/ObjectPool.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Threading; - -namespace Ryujinx.Common -{ - public class ObjectPool<T> - where T : class - { - private T _firstItem; - private readonly T[] _items; - - private readonly Func<T> _factory; - - public ObjectPool(Func<T> factory, int size) - { - _items = new T[size - 1]; - _factory = factory; - } - - public T Allocate() - { - T instance = _firstItem; - - if (instance == null || instance != Interlocked.CompareExchange(ref _firstItem, null, instance)) - { - instance = AllocateInternal(); - } - - return instance; - } - - private T AllocateInternal() - { - T[] items = _items; - - for (int i = 0; i < items.Length; i++) - { - T instance = items[i]; - - if (instance != null && instance == Interlocked.CompareExchange(ref items[i], null, instance)) - { - return instance; - } - } - - return _factory(); - } - - public void Release(T obj) - { - if (_firstItem == null) - { - _firstItem = obj; - } - else - { - ReleaseInternal(obj); - } - } - - private void ReleaseInternal(T obj) - { - T[] items = _items; - - for (int i = 0; i < items.Length; i++) - { - if (items[i] == null) - { - items[i] = obj; - break; - } - } - } - } -} diff --git a/Ryujinx.Common/Pools/SharedPools.cs b/Ryujinx.Common/Pools/SharedPools.cs deleted file mode 100644 index b4860b85..00000000 --- a/Ryujinx.Common/Pools/SharedPools.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Common -{ - public static class SharedPools - { - private static class DefaultPool<T> - where T : class, new() - { - public static readonly ObjectPool<T> Instance = new ObjectPool<T>(() => new T(), 20); - } - - public static ObjectPool<T> Default<T>() - where T : class, new() - { - return DefaultPool<T>.Instance; - } - } -} diff --git a/Ryujinx.Common/Pools/ThreadStaticArray.cs b/Ryujinx.Common/Pools/ThreadStaticArray.cs deleted file mode 100644 index 21434a02..00000000 --- a/Ryujinx.Common/Pools/ThreadStaticArray.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace Ryujinx.Common.Pools -{ - public static class ThreadStaticArray<T> - { - [ThreadStatic] - private static T[] _array; - - public static ref T[] Get() - { - if (_array == null) - { - _array = new T[1]; - } - - return ref _array; - } - } -} diff --git a/Ryujinx.Common/ReactiveObject.cs b/Ryujinx.Common/ReactiveObject.cs deleted file mode 100644 index 44897f26..00000000 --- a/Ryujinx.Common/ReactiveObject.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Threading; - -namespace Ryujinx.Common -{ - public class ReactiveObject<T> - { - private ReaderWriterLock _readerWriterLock = new ReaderWriterLock(); - private bool _isInitialized = false; - private T _value; - - public event EventHandler<ReactiveEventArgs<T>> Event; - - public T Value - { - get - { - _readerWriterLock.AcquireReaderLock(Timeout.Infinite); - T value = _value; - _readerWriterLock.ReleaseReaderLock(); - - return value; - } - set - { - _readerWriterLock.AcquireWriterLock(Timeout.Infinite); - - T oldValue = _value; - - bool oldIsInitialized = _isInitialized; - - _isInitialized = true; - _value = value; - - _readerWriterLock.ReleaseWriterLock(); - - if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value)) - { - Event?.Invoke(this, new ReactiveEventArgs<T>(oldValue, value)); - } - } - } - - public static implicit operator T(ReactiveObject<T> obj) - { - return obj.Value; - } - } - - public class ReactiveEventArgs<T> - { - public T OldValue { get; } - public T NewValue { get; } - - public ReactiveEventArgs(T oldValue, T newValue) - { - OldValue = oldValue; - NewValue = newValue; - } - } -} diff --git a/Ryujinx.Common/ReferenceEqualityComparer.cs b/Ryujinx.Common/ReferenceEqualityComparer.cs deleted file mode 100644 index d8ec29d8..00000000 --- a/Ryujinx.Common/ReferenceEqualityComparer.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -namespace Ryujinx.Common -{ - public class ReferenceEqualityComparer<T> : IEqualityComparer<T> - where T : class - { - public bool Equals(T x, T y) - { - return x == y; - } - - public int GetHashCode([DisallowNull] T obj) - { - return obj.GetHashCode(); - } - } -} diff --git a/Ryujinx.Common/ReleaseInformation.cs b/Ryujinx.Common/ReleaseInformation.cs deleted file mode 100644 index 601c05b1..00000000 --- a/Ryujinx.Common/ReleaseInformation.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Ryujinx.Common.Configuration; -using System; -using System.Reflection; - -namespace Ryujinx.Common -{ - // DO NOT EDIT, filled by CI - public static class ReleaseInformation - { - private const string FlatHubChannelOwner = "flathub"; - - public static string BuildVersion = "%%RYUJINX_BUILD_VERSION%%"; - public static string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%"; - public static string ReleaseChannelName = "%%RYUJINX_TARGET_RELEASE_CHANNEL_NAME%%"; - public static string ReleaseChannelOwner = "%%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER%%"; - public static string ReleaseChannelRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_REPO%%"; - - public static bool IsValid() - { - return !BuildGitHash.StartsWith("%%") && - !ReleaseChannelName.StartsWith("%%") && - !ReleaseChannelOwner.StartsWith("%%") && - !ReleaseChannelRepo.StartsWith("%%"); - } - - public static bool IsFlatHubBuild() - { - return IsValid() && ReleaseChannelOwner.Equals(FlatHubChannelOwner); - } - - public static string GetVersion() - { - if (IsValid()) - { - return BuildVersion; - } - else - { - return Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion; - } - } - -#if FORCE_EXTERNAL_BASE_DIR - public static string GetBaseApplicationDirectory() - { - return AppDataManager.BaseDirPath; - } -#else - public static string GetBaseApplicationDirectory() - { - if (IsFlatHubBuild() || OperatingSystem.IsMacOS()) - { - return AppDataManager.BaseDirPath; - } - - return AppDomain.CurrentDomain.BaseDirectory; - } -#endif - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj deleted file mode 100644 index c02b11e0..00000000 --- a/Ryujinx.Common/Ryujinx.Common.csproj +++ /dev/null @@ -1,15 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.IO.RecyclableMemoryStream" /> - <PackageReference Include="MsgPack.Cli" /> - <PackageReference Include="System.Management" /> - </ItemGroup> - -</Project> diff --git a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs deleted file mode 100644 index b0c15e49..00000000 --- a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Runtime.Versioning; - -namespace Ryujinx.Common.SystemInfo -{ - [SupportedOSPlatform("linux")] - class LinuxSystemInfo : SystemInfo - { - internal LinuxSystemInfo() - { - string cpuName = GetCpuidCpuName(); - - if (cpuName == null) - { - var cpuDict = new Dictionary<string, string>(StringComparer.Ordinal) - { - ["model name"] = null, - ["Processor"] = null, - ["Hardware"] = null - }; - - ParseKeyValues("/proc/cpuinfo", cpuDict); - - cpuName = cpuDict["model name"] ?? cpuDict["Processor"] ?? cpuDict["Hardware"] ?? "Unknown"; - } - - var memDict = new Dictionary<string, string>(StringComparer.Ordinal) - { - ["MemTotal"] = null, - ["MemAvailable"] = null - }; - - ParseKeyValues("/proc/meminfo", memDict); - - // Entries are in KiB - ulong.TryParse(memDict["MemTotal"]?.Split(' ')[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong totalKiB); - ulong.TryParse(memDict["MemAvailable"]?.Split(' ')[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong availableKiB); - - CpuName = $"{cpuName} ; {LogicalCoreCount} logical"; - RamTotal = totalKiB * 1024; - RamAvailable = availableKiB * 1024; - } - - private static void ParseKeyValues(string filePath, Dictionary<string, string> itemDict) - { - if (!File.Exists(filePath)) - { - Logger.Error?.Print(LogClass.Application, $"File \"{filePath}\" not found"); - - return; - } - - int count = itemDict.Count; - - using (StreamReader file = new StreamReader(filePath)) - { - string line; - while ((line = file.ReadLine()) != null) - { - string[] kvPair = line.Split(':', 2, StringSplitOptions.TrimEntries); - - if (kvPair.Length < 2) continue; - - string key = kvPair[0]; - - if (itemDict.TryGetValue(key, out string value) && value == null) - { - itemDict[key] = kvPair[1]; - - if (--count <= 0) break; - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs b/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs deleted file mode 100644 index 06324a54..00000000 --- a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs +++ /dev/null @@ -1,157 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Text; - -namespace Ryujinx.Common.SystemInfo -{ - [SupportedOSPlatform("macos")] - partial class MacOSSystemInfo : SystemInfo - { - internal MacOSSystemInfo() - { - string cpuName = GetCpuidCpuName(); - - if (cpuName == null && sysctlbyname("machdep.cpu.brand_string", out cpuName) != 0) - { - cpuName = "Unknown"; - } - - ulong totalRAM = 0; - - if (sysctlbyname("hw.memsize", ref totalRAM) != 0) // Bytes - { - totalRAM = 0; - } - - CpuName = $"{cpuName} ; {LogicalCoreCount} logical"; - RamTotal = totalRAM; - RamAvailable = GetVMInfoAvailableMemory(); - } - - static ulong GetVMInfoAvailableMemory() - { - var port = mach_host_self(); - - uint pageSize = 0; - var result = host_page_size(port, ref pageSize); - - if (result != 0) - { - Logger.Error?.Print(LogClass.Application, $"Failed to query Available RAM. host_page_size() error = {result}"); - return 0; - } - - const int flavor = 4; // HOST_VM_INFO64 - uint count = (uint)(Marshal.SizeOf<VMStatistics64>() / sizeof(int)); // HOST_VM_INFO64_COUNT - VMStatistics64 stats = new(); - result = host_statistics64(port, flavor, ref stats, ref count); - - if (result != 0) - { - Logger.Error?.Print(LogClass.Application, $"Failed to query Available RAM. host_statistics64() error = {result}"); - return 0; - } - - return (ulong)(stats.FreeCount + stats.InactiveCount) * pageSize; - } - - private const string SystemLibraryName = "libSystem.dylib"; - - [LibraryImport(SystemLibraryName, SetLastError = true)] - private static partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize); - - private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize) - { - if (sysctlbyname(name, oldValue, ref oldSize, IntPtr.Zero, 0) == -1) - { - int err = Marshal.GetLastWin32Error(); - - Logger.Error?.Print(LogClass.Application, $"Cannot retrieve '{name}'. Error Code {err}"); - - return err; - } - - return 0; - } - - private static int sysctlbyname<T>(string name, ref T oldValue) - { - unsafe - { - ulong oldValueSize = (ulong)Unsafe.SizeOf<T>(); - - return sysctlbyname(name, (IntPtr)Unsafe.AsPointer(ref oldValue), ref oldValueSize); - } - } - - private static int sysctlbyname(string name, out string oldValue) - { - oldValue = default; - - ulong strSize = 0; - - int res = sysctlbyname(name, IntPtr.Zero, ref strSize); - - if (res == 0) - { - byte[] rawData = new byte[strSize]; - - unsafe - { - fixed (byte* rawDataPtr = rawData) - { - res = sysctlbyname(name, (IntPtr)rawDataPtr, ref strSize); - } - - if (res == 0) - { - oldValue = Encoding.ASCII.GetString(rawData); - } - } - } - - return res; - } - - [LibraryImport(SystemLibraryName, SetLastError = true)] - private static partial uint mach_host_self(); - - [LibraryImport(SystemLibraryName, SetLastError = true)] - private static partial int host_page_size(uint host, ref uint out_page_size); - - [StructLayout(LayoutKind.Sequential, Pack = 8)] - struct VMStatistics64 - { - public uint FreeCount; - public uint ActiveCount; - public uint InactiveCount; - public uint WireCount; - public ulong ZeroFillCount; - public ulong Reactivations; - public ulong Pageins; - public ulong Pageouts; - public ulong Faults; - public ulong CowFaults; - public ulong Lookups; - public ulong Hits; - public ulong Purges; - public uint PurgeableCount; - public uint SpeculativeCount; - public ulong Decompressions; - public ulong Compressions; - public ulong Swapins; - public ulong Swapouts; - public uint CompressorPageCount; - public uint ThrottledCount; - public uint ExternalPageCount; - public uint InternalPageCount; - public ulong TotalUncompressedPagesInCompressor; - } - - [LibraryImport(SystemLibraryName, SetLastError = true)] - private static partial int host_statistics64(uint host_priv, int host_flavor, ref VMStatistics64 host_info64_out, ref uint host_info64_outCnt); - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/SystemInfo.cs b/Ryujinx.Common/SystemInfo/SystemInfo.cs deleted file mode 100644 index e9ce3c58..00000000 --- a/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics.X86; -using System.Text; - -namespace Ryujinx.Common.SystemInfo -{ - public class SystemInfo - { - public string OsDescription { get; protected set; } - public string CpuName { get; protected set; } - public ulong RamTotal { get; protected set; } - public ulong RamAvailable { get; protected set; } - protected static int LogicalCoreCount => Environment.ProcessorCount; - - protected SystemInfo() - { - OsDescription = $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})"; - CpuName = "Unknown"; - } - - private static string ToMiBString(ulong bytesValue) => (bytesValue == 0) ? "Unknown" : $"{bytesValue / 1024 / 1024} MiB"; - - public void Print() - { - Logger.Notice.Print(LogClass.Application, $"Operating System: {OsDescription}"); - Logger.Notice.Print(LogClass.Application, $"CPU: {CpuName}"); - Logger.Notice.Print(LogClass.Application, $"RAM: Total {ToMiBString(RamTotal)} ; Available {ToMiBString(RamAvailable)}"); - } - - public static SystemInfo Gather() - { - if (OperatingSystem.IsWindows()) - { - return new WindowsSystemInfo(); - } - else if (OperatingSystem.IsLinux()) - { - return new LinuxSystemInfo(); - } - else if (OperatingSystem.IsMacOS()) - { - return new MacOSSystemInfo(); - } - else - { - Logger.Error?.Print(LogClass.Application, "SystemInfo unsupported on this platform"); - - return new SystemInfo(); - } - } - - // x86 exposes a 48 byte ASCII "CPU brand" string via CPUID leaves 0x80000002-0x80000004. - internal static string GetCpuidCpuName() - { - if (!X86Base.IsSupported) - { - return null; - } - - // Check if CPU supports the query - if ((uint)X86Base.CpuId(unchecked((int)0x80000000), 0).Eax < 0x80000004) - { - return null; - } - - int[] regs = new int[12]; - - for (uint i = 0; i < 3; ++i) - { - (regs[4 * i], regs[4 * i + 1], regs[4 * i + 2], regs[4 * i + 3]) = X86Base.CpuId((int)(0x80000002 + i), 0); - } - - string name = Encoding.ASCII.GetString(MemoryMarshal.Cast<int, byte>(regs)).Replace('\0', ' ').Trim(); - - return string.IsNullOrEmpty(name) ? null : name; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs deleted file mode 100644 index c3598a1e..00000000 --- a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Management; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Common.SystemInfo -{ - [SupportedOSPlatform("windows")] - partial class WindowsSystemInfo : SystemInfo - { - internal WindowsSystemInfo() - { - CpuName = $"{GetCpuidCpuName() ?? GetCpuNameWMI()} ; {LogicalCoreCount} logical"; // WMI is very slow - (RamTotal, RamAvailable) = GetMemoryStats(); - } - - private static (ulong Total, ulong Available) GetMemoryStats() - { - MemoryStatusEx memStatus = new MemoryStatusEx(); - if (GlobalMemoryStatusEx(ref memStatus)) - { - return (memStatus.TotalPhys, memStatus.AvailPhys); // Bytes - } - else - { - Logger.Error?.Print(LogClass.Application, $"GlobalMemoryStatusEx failed. Error {Marshal.GetLastWin32Error():X}"); - } - - return (0, 0); - } - - private static string GetCpuNameWMI() - { - ManagementObjectCollection cpuObjs = GetWMIObjects("root\\CIMV2", "SELECT * FROM Win32_Processor"); - - if (cpuObjs != null) - { - foreach (var cpuObj in cpuObjs) - { - return cpuObj["Name"].ToString().Trim(); - } - } - - return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim(); - } - - [StructLayout(LayoutKind.Sequential)] - private struct MemoryStatusEx - { - public uint Length; - public uint MemoryLoad; - public ulong TotalPhys; - public ulong AvailPhys; - public ulong TotalPageFile; - public ulong AvailPageFile; - public ulong TotalVirtual; - public ulong AvailVirtual; - public ulong AvailExtendedVirtual; - - public MemoryStatusEx() - { - Length = (uint)Marshal.SizeOf<MemoryStatusEx>(); - } - } - - [LibraryImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool GlobalMemoryStatusEx(ref MemoryStatusEx lpBuffer); - - private static ManagementObjectCollection GetWMIObjects(string scope, string query) - { - try - { - return new ManagementObjectSearcher(scope, query).Get(); - } - catch (PlatformNotSupportedException ex) - { - Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}"); - } - catch (COMException ex) - { - Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}"); - } - - return null; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/SystemInterop/DisplaySleep.cs b/Ryujinx.Common/SystemInterop/DisplaySleep.cs deleted file mode 100644 index 5a1f66f5..00000000 --- a/Ryujinx.Common/SystemInterop/DisplaySleep.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.SystemInterop -{ - public partial class DisplaySleep - { - [Flags] - enum EXECUTION_STATE : uint - { - ES_CONTINUOUS = 0x80000000, - ES_DISPLAY_REQUIRED = 0x00000002, - ES_SYSTEM_REQUIRED = 0x00000001 - } - - [LibraryImport("kernel32.dll", SetLastError = true)] - private static partial EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); - - static public void Prevent() - { - if (OperatingSystem.IsWindows()) - { - SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED); - } - } - - static public void Restore() - { - if (OperatingSystem.IsWindows()) - { - SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); - } - } - } -} diff --git a/Ryujinx.Common/SystemInterop/ForceDpiAware.cs b/Ryujinx.Common/SystemInterop/ForceDpiAware.cs deleted file mode 100644 index f17612a6..00000000 --- a/Ryujinx.Common/SystemInterop/ForceDpiAware.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Globalization; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.SystemInterop -{ - public static partial class ForceDpiAware - { - [LibraryImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool SetProcessDPIAware(); - - private const string X11LibraryName = "libX11.so.6"; - - [LibraryImport(X11LibraryName)] - private static partial IntPtr XOpenDisplay([MarshalAs(UnmanagedType.LPStr)] string display); - - [LibraryImport(X11LibraryName)] - private static partial IntPtr XGetDefault(IntPtr display, [MarshalAs(UnmanagedType.LPStr)] string program, [MarshalAs(UnmanagedType.LPStr)] string option); - - [LibraryImport(X11LibraryName)] - private static partial int XDisplayWidth(IntPtr display, int screenNumber); - - [LibraryImport(X11LibraryName)] - private static partial int XDisplayWidthMM(IntPtr display, int screenNumber); - - [LibraryImport(X11LibraryName)] - private static partial int XCloseDisplay(IntPtr display); - - private static readonly double _standardDpiScale = 96.0; - private static readonly double _maxScaleFactor = 1.25; - - /// <summary> - /// Marks the application as DPI-Aware when running on the Windows operating system. - /// </summary> - public static void Windows() - { - // Make process DPI aware for proper window sizing on high-res screens. - if (OperatingSystem.IsWindowsVersionAtLeast(6)) - { - SetProcessDPIAware(); - } - } - - public static double GetActualScaleFactor() - { - double userDpiScale = 96.0; - - try - { - if (OperatingSystem.IsWindows()) - { - userDpiScale = GdiPlusHelper.GetDpiX(IntPtr.Zero); - } - else if (OperatingSystem.IsLinux()) - { - string xdgSessionType = Environment.GetEnvironmentVariable("XDG_SESSION_TYPE")?.ToLower(); - - if (xdgSessionType == null || xdgSessionType == "x11") - { - IntPtr display = XOpenDisplay(null); - string dpiString = Marshal.PtrToStringAnsi(XGetDefault(display, "Xft", "dpi")); - if (dpiString == null || !double.TryParse(dpiString, NumberStyles.Any, CultureInfo.InvariantCulture, out userDpiScale)) - { - userDpiScale = (double)XDisplayWidth(display, 0) * 25.4 / (double)XDisplayWidthMM(display, 0); - } - XCloseDisplay(display); - } - else if (xdgSessionType == "wayland") - { - // TODO - Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: Wayland not yet supported"); - } - else - { - Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: Unrecognised XDG_SESSION_TYPE: {xdgSessionType}"); - } - } - } - catch (Exception e) - { - Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: {e.Message}"); - } - - return userDpiScale; - } - - public static double GetWindowScaleFactor() - { - double userDpiScale = GetActualScaleFactor(); - - return Math.Min(userDpiScale / _standardDpiScale, _maxScaleFactor); - } - } -} diff --git a/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs b/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs deleted file mode 100644 index 1001424d..00000000 --- a/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Common.SystemInterop -{ - [SupportedOSPlatform("windows")] - public static partial class GdiPlusHelper - { - private const string LibraryName = "gdiplus.dll"; - - private static readonly IntPtr _initToken; - - static GdiPlusHelper() - { - CheckStatus(GdiplusStartup(out _initToken, StartupInputEx.Default, out _)); - } - - private static void CheckStatus(int gdiStatus) - { - if (gdiStatus != 0) - { - throw new Exception($"GDI Status Error: {gdiStatus}"); - } - } - - private struct StartupInputEx - { - public int GdiplusVersion; - -#pragma warning disable CS0649 - public IntPtr DebugEventCallback; - public int SuppressBackgroundThread; - public int SuppressExternalCodecs; - public int StartupParameters; -#pragma warning restore CS0649 - - public static StartupInputEx Default => new StartupInputEx - { - // We assume Windows 8 and upper - GdiplusVersion = 2, - DebugEventCallback = IntPtr.Zero, - SuppressBackgroundThread = 0, - SuppressExternalCodecs = 0, - StartupParameters = 0, - }; - } - - private struct StartupOutput - { - public IntPtr NotificationHook; - public IntPtr NotificationUnhook; - } - - [LibraryImport(LibraryName)] - private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); - - [LibraryImport(LibraryName)] - private static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); - - [LibraryImport(LibraryName)] - private static partial int GdipDeleteGraphics(IntPtr graphics); - - [LibraryImport(LibraryName)] - private static partial int GdipGetDpiX(IntPtr graphics, out float dpi); - - public static float GetDpiX(IntPtr hwnd) - { - CheckStatus(GdipCreateFromHWND(hwnd, out IntPtr graphicsHandle)); - CheckStatus(GdipGetDpiX(graphicsHandle, out float result)); - CheckStatus(GdipDeleteGraphics(graphicsHandle)); - - return result; - } - } -} diff --git a/Ryujinx.Common/SystemInterop/StdErrAdapter.cs b/Ryujinx.Common/SystemInterop/StdErrAdapter.cs deleted file mode 100644 index b1ed7b68..00000000 --- a/Ryujinx.Common/SystemInterop/StdErrAdapter.cs +++ /dev/null @@ -1,109 +0,0 @@ -using Microsoft.Win32.SafeHandles; -using Ryujinx.Common.Logging; -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Threading; -using System.Threading.Tasks; - -namespace Ryujinx.Common.SystemInterop -{ - public partial class StdErrAdapter : IDisposable - { - private bool _disposable = false; - private Stream _pipeReader; - private Stream _pipeWriter; - private CancellationTokenSource _cancellationTokenSource; - private Task _worker; - - public StdErrAdapter() - { - if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) - { - RegisterPosix(); - } - } - - [SupportedOSPlatform("linux")] - [SupportedOSPlatform("macos")] - private void RegisterPosix() - { - const int stdErrFileno = 2; - - (int readFd, int writeFd) = MakePipe(); - dup2(writeFd, stdErrFileno); - - _pipeReader = CreateFileDescriptorStream(readFd); - _pipeWriter = CreateFileDescriptorStream(writeFd); - - _cancellationTokenSource = new CancellationTokenSource(); - _worker = Task.Run(async () => await EventWorkerAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); - _disposable = true; - } - - [SupportedOSPlatform("linux")] - [SupportedOSPlatform("macos")] - private async Task EventWorkerAsync(CancellationToken cancellationToken) - { - using TextReader reader = new StreamReader(_pipeReader, leaveOpen: true); - string line; - while (cancellationToken.IsCancellationRequested == false && (line = await reader.ReadLineAsync(cancellationToken)) != null) - { - Logger.Error?.PrintRawMsg(line); - } - } - - private void Dispose(bool disposing) - { - if (_disposable) - { - _disposable = false; - - if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) - { - _cancellationTokenSource.Cancel(); - _worker.Wait(0); - _pipeReader?.Close(); - _pipeWriter?.Close(); - } - } - } - - public void Dispose() - { - Dispose(true); - } - - [LibraryImport("libc", SetLastError = true)] - private static partial int dup2(int fd, int fd2); - - [LibraryImport("libc", SetLastError = true)] - private static partial int pipe(Span<int> pipefd); - - private static (int, int) MakePipe() - { - Span<int> pipefd = stackalloc int[2]; - - if (pipe(pipefd) == 0) - { - return (pipefd[0], pipefd[1]); - } - else - { - throw new(); - } - } - - [SupportedOSPlatform("linux")] - [SupportedOSPlatform("macos")] - private static Stream CreateFileDescriptorStream(int fd) - { - return new FileStream( - new SafeFileHandle((IntPtr)fd, ownsHandle: true), - FileAccess.ReadWrite - ); - } - - } -} diff --git a/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs b/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs deleted file mode 100644 index a4fbf0bd..00000000 --- a/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs +++ /dev/null @@ -1,114 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Common.SystemInterop -{ - /// <summary> - /// Handle Windows Multimedia timer resolution. - /// </summary> - [SupportedOSPlatform("windows")] - public partial class WindowsMultimediaTimerResolution : IDisposable - { - [StructLayout(LayoutKind.Sequential)] - public struct TimeCaps - { - public uint wPeriodMin; - public uint wPeriodMax; - }; - - [LibraryImport("winmm.dll", EntryPoint = "timeGetDevCaps", SetLastError = true)] - private static partial uint TimeGetDevCaps(ref TimeCaps timeCaps, uint sizeTimeCaps); - - [LibraryImport("winmm.dll", EntryPoint = "timeBeginPeriod")] - private static partial uint TimeBeginPeriod(uint uMilliseconds); - - [LibraryImport("winmm.dll", EntryPoint = "timeEndPeriod")] - private static partial uint TimeEndPeriod(uint uMilliseconds); - - private uint _targetResolutionInMilliseconds; - private bool _isActive; - - /// <summary> - /// Create a new <see cref="WindowsMultimediaTimerResolution"/> and activate the given resolution. - /// </summary> - /// <param name="targetResolutionInMilliseconds"></param> - public WindowsMultimediaTimerResolution(uint targetResolutionInMilliseconds) - { - _targetResolutionInMilliseconds = targetResolutionInMilliseconds; - - EnsureResolutionSupport(); - Activate(); - } - - private void EnsureResolutionSupport() - { - TimeCaps timeCaps = default; - - uint result = TimeGetDevCaps(ref timeCaps, (uint)Unsafe.SizeOf<TimeCaps>()); - - if (result != 0) - { - Logger.Notice.Print(LogClass.Application, $"timeGetDevCaps failed with result: {result}"); - } - else - { - uint supportedTargetResolutionInMilliseconds = Math.Min(Math.Max(timeCaps.wPeriodMin, _targetResolutionInMilliseconds), timeCaps.wPeriodMax); - - if (supportedTargetResolutionInMilliseconds != _targetResolutionInMilliseconds) - { - Logger.Notice.Print(LogClass.Application, $"Target resolution isn't supported by OS, using closest resolution: {supportedTargetResolutionInMilliseconds}ms"); - - _targetResolutionInMilliseconds = supportedTargetResolutionInMilliseconds; - } - } - } - - private void Activate() - { - uint result = TimeBeginPeriod(_targetResolutionInMilliseconds); - - if (result != 0) - { - Logger.Notice.Print(LogClass.Application, $"timeBeginPeriod failed with result: {result}"); - } - else - { - _isActive = true; - } - } - - private void Disable() - { - if (_isActive) - { - uint result = TimeEndPeriod(_targetResolutionInMilliseconds); - - if (result != 0) - { - Logger.Notice.Print(LogClass.Application, $"timeEndPeriod failed with result: {result}"); - } - else - { - _isActive = false; - } - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - Disable(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/BitUtils.cs b/Ryujinx.Common/Utilities/BitUtils.cs deleted file mode 100644 index f885ce84..00000000 --- a/Ryujinx.Common/Utilities/BitUtils.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Numerics; - -namespace Ryujinx.Common -{ - public static class BitUtils - { - public static T AlignUp<T>(T value, T size) - where T : IBinaryInteger<T> - { - return (value + (size - T.One)) & -size; - } - - public static T AlignDown<T>(T value, T size) - where T : IBinaryInteger<T> - { - return value & -size; - } - - public static T DivRoundUp<T>(T value, T dividend) - where T : IBinaryInteger<T> - { - return (value + (dividend - T.One)) / dividend; - } - - public static int Pow2RoundUp(int value) - { - value--; - - value |= (value >> 1); - value |= (value >> 2); - value |= (value >> 4); - value |= (value >> 8); - value |= (value >> 16); - - return ++value; - } - - public static int Pow2RoundDown(int value) - { - return BitOperations.IsPow2(value) ? value : Pow2RoundUp(value) >> 1; - } - - public static long ReverseBits64(long value) - { - return (long)ReverseBits64((ulong)value); - } - - private static ulong ReverseBits64(ulong value) - { - value = ((value & 0xaaaaaaaaaaaaaaaa) >> 1 ) | ((value & 0x5555555555555555) << 1 ); - value = ((value & 0xcccccccccccccccc) >> 2 ) | ((value & 0x3333333333333333) << 2 ); - value = ((value & 0xf0f0f0f0f0f0f0f0) >> 4 ) | ((value & 0x0f0f0f0f0f0f0f0f) << 4 ); - value = ((value & 0xff00ff00ff00ff00) >> 8 ) | ((value & 0x00ff00ff00ff00ff) << 8 ); - value = ((value & 0xffff0000ffff0000) >> 16) | ((value & 0x0000ffff0000ffff) << 16); - - return (value >> 32) | (value << 32); - } - } -} diff --git a/Ryujinx.Common/Utilities/BitfieldExtensions.cs b/Ryujinx.Common/Utilities/BitfieldExtensions.cs deleted file mode 100644 index ca429944..00000000 --- a/Ryujinx.Common/Utilities/BitfieldExtensions.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace Ryujinx.Common.Utilities -{ - public static class BitfieldExtensions - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool Extract<T>(this T value, int lsb) where T : IBinaryInteger<T> - { - int bitSize = Unsafe.SizeOf<T>() * 8; - lsb &= bitSize - 1; - - return !T.IsZero((value >>> lsb) & T.One); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Extract<T>(this T value, int lsb, int length) where T : IBinaryInteger<T> - { - int bitSize = Unsafe.SizeOf<T>() * 8; - lsb &= bitSize - 1; - - return (value >>> lsb) & (~T.Zero >>> (bitSize - length)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ExtractSx<T>(this T value, int lsb, int length) where T : IBinaryInteger<T> - { - int bitSize = Unsafe.SizeOf<T>() * 8; - int shift = lsb & (bitSize - 1); - - return (value << (bitSize - (shift + length))) >> (bitSize - length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Insert<T>(this T value, int lsb, bool toInsert) where T : IBinaryInteger<T> - { - int bitSize = Unsafe.SizeOf<T>() * 8; - lsb &= bitSize - 1; - - T mask = T.One << lsb; - - return (value & ~mask) | (toInsert ? mask : T.Zero); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Insert<T>(this T value, int lsb, int length, T toInsert) where T : IBinaryInteger<T> - { - int bitSize = Unsafe.SizeOf<T>() * 8; - lsb &= bitSize - 1; - - T mask = (~T.Zero >>> (bitSize - length)) << lsb; - - return (value & ~mask) | ((toInsert << lsb) & mask); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/Buffers.cs b/Ryujinx.Common/Utilities/Buffers.cs deleted file mode 100644 index d614bfc4..00000000 --- a/Ryujinx.Common/Utilities/Buffers.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Utilities -{ - [DebuggerDisplay("{ToString()}")] - [StructLayout(LayoutKind.Sequential, Size = 16)] - public struct Buffer16 - { - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1; - - public byte this[int i] - { - get => Bytes[i]; - set => Bytes[i] = value; - } - - public Span<byte> Bytes => SpanHelpers.AsByteSpan(ref this); - - // Prevent a defensive copy by changing the read-only in reference to a reference with Unsafe.AsRef() - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Span<byte>(in Buffer16 value) - { - return SpanHelpers.AsByteSpan(ref Unsafe.AsRef(in value)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator ReadOnlySpan<byte>(in Buffer16 value) - { - return SpanHelpers.AsReadOnlyByteSpan(ref Unsafe.AsRef(in value)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref T As<T>() where T : unmanaged - { - if (Unsafe.SizeOf<T>() > (uint)Unsafe.SizeOf<Buffer16>()) - { - throw new ArgumentException(); - } - - return ref MemoryMarshal.GetReference(AsSpan<T>()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span<T> AsSpan<T>() where T : unmanaged - { - return SpanHelpers.AsSpan<Buffer16, T>(ref this); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly ReadOnlySpan<T> AsReadOnlySpan<T>() where T : unmanaged - { - return SpanHelpers.AsReadOnlySpan<Buffer16, T>(ref Unsafe.AsRef(in this)); - } - } -} diff --git a/Ryujinx.Common/Utilities/CommonJsonContext.cs b/Ryujinx.Common/Utilities/CommonJsonContext.cs deleted file mode 100644 index d7b3f78c..00000000 --- a/Ryujinx.Common/Utilities/CommonJsonContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Utilities -{ - [JsonSerializable(typeof(string[]), TypeInfoPropertyName = "StringArray")] - [JsonSerializable(typeof(Dictionary<string, string>), TypeInfoPropertyName = "StringDictionary")] - public partial class CommonJsonContext : JsonSerializerContext - { - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/EmbeddedResources.cs b/Ryujinx.Common/Utilities/EmbeddedResources.cs deleted file mode 100644 index 22b55f16..00000000 --- a/Ryujinx.Common/Utilities/EmbeddedResources.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Ryujinx.Common.Memory; -using Ryujinx.Common.Utilities; -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; - -namespace Ryujinx.Common -{ - public static class EmbeddedResources - { - private readonly static Assembly ResourceAssembly; - - static EmbeddedResources() - { - ResourceAssembly = Assembly.GetAssembly(typeof(EmbeddedResources)); - } - - public static byte[] Read(string filename) - { - var (assembly, path) = ResolveManifestPath(filename); - - return Read(assembly, path); - } - - public static Task<byte[]> ReadAsync(string filename) - { - var (assembly, path) = ResolveManifestPath(filename); - - return ReadAsync(assembly, path); - } - - public static byte[] Read(Assembly assembly, string filename) - { - using (var stream = GetStream(assembly, filename)) - { - if (stream == null) - { - return null; - } - - return StreamUtils.StreamToBytes(stream); - } - } - - public async static Task<byte[]> ReadAsync(Assembly assembly, string filename) - { - using (var stream = GetStream(assembly, filename)) - { - if (stream == null) - { - return null; - } - - return await StreamUtils.StreamToBytesAsync(stream); - } - } - - public static string ReadAllText(string filename) - { - var (assembly, path) = ResolveManifestPath(filename); - - return ReadAllText(assembly, path); - } - - public static Task<string> ReadAllTextAsync(string filename) - { - var (assembly, path) = ResolveManifestPath(filename); - - return ReadAllTextAsync(assembly, path); - } - - public static string ReadAllText(Assembly assembly, string filename) - { - using (var stream = GetStream(assembly, filename)) - { - if (stream == null) - { - return null; - } - - using (var reader = new StreamReader(stream)) - { - return reader.ReadToEnd(); - } - } - } - - public async static Task<string> ReadAllTextAsync(Assembly assembly, string filename) - { - using (var stream = GetStream(assembly, filename)) - { - if (stream == null) - { - return null; - } - - using (var reader = new StreamReader(stream)) - { - return await reader.ReadToEndAsync(); - } - } - } - - public static Stream GetStream(string filename) - { - var (assembly, path) = ResolveManifestPath(filename); - - return GetStream(assembly, path); - } - - public static Stream GetStream(Assembly assembly, string filename) - { - var namespace_ = assembly.GetName().Name; - var manifestUri = namespace_ + "." + filename.Replace('/', '.'); - - var stream = assembly.GetManifestResourceStream(manifestUri); - - return stream; - } - - public static string[] GetAllAvailableResources(string path, string ext = "") - { - return ResolveManifestPath(path).Item1.GetManifestResourceNames() - .Where(r => r.EndsWith(ext)) - .ToArray(); - } - - private static (Assembly, string) ResolveManifestPath(string filename) - { - var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries); - - if (segments.Length >= 2) - { - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - if (assembly.GetName().Name == segments[0]) - { - return (assembly, segments[1]); - } - } - } - - return (ResourceAssembly, filename); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/HexUtils.cs b/Ryujinx.Common/Utilities/HexUtils.cs deleted file mode 100644 index 63587cea..00000000 --- a/Ryujinx.Common/Utilities/HexUtils.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Text; - -namespace Ryujinx.Common -{ - public static class HexUtils - { - private static readonly char[] HexChars = "0123456789ABCDEF".ToCharArray(); - - private const int HexTableColumnWidth = 8; - private const int HexTableColumnSpace = 3; - - // Modified for Ryujinx - // Original by Pascal Ganaye - CPOL License - // https://www.codeproject.com/Articles/36747/Quick-and-Dirty-HexDump-of-a-Byte-Array - public static string HexTable(byte[] bytes, int bytesPerLine = 16) - { - if (bytes == null) - { - return "<null>"; - } - - int bytesLength = bytes.Length; - - int firstHexColumn = - HexTableColumnWidth - + HexTableColumnSpace; - - int firstCharColumn = firstHexColumn - + bytesPerLine * HexTableColumnSpace - + (bytesPerLine - 1) / HexTableColumnWidth - + 2; - - int lineLength = firstCharColumn - + bytesPerLine - + Environment.NewLine.Length; - - char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); - - int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; - - StringBuilder result = new StringBuilder(expectedLines * lineLength); - - for (int i = 0; i < bytesLength; i += bytesPerLine) - { - line[0] = HexChars[(i >> 28) & 0xF]; - line[1] = HexChars[(i >> 24) & 0xF]; - line[2] = HexChars[(i >> 20) & 0xF]; - line[3] = HexChars[(i >> 16) & 0xF]; - line[4] = HexChars[(i >> 12) & 0xF]; - line[5] = HexChars[(i >> 8) & 0xF]; - line[6] = HexChars[(i >> 4) & 0xF]; - line[7] = HexChars[(i >> 0) & 0xF]; - - int hexColumn = firstHexColumn; - int charColumn = firstCharColumn; - - for (int j = 0; j < bytesPerLine; j++) - { - if (j > 0 && (j & 7) == 0) - { - hexColumn++; - } - - if (i + j >= bytesLength) - { - line[hexColumn] = ' '; - line[hexColumn + 1] = ' '; - line[charColumn] = ' '; - } - else - { - byte b = bytes[i + j]; - - line[hexColumn] = HexChars[(b >> 4) & 0xF]; - line[hexColumn + 1] = HexChars[b & 0xF]; - line[charColumn] = (b < 32 ? '·' : (char)b); - } - - hexColumn += 3; - charColumn++; - } - - result.Append(line); - } - - return result.ToString(); - } - } -} diff --git a/Ryujinx.Common/Utilities/JsonHelper.cs b/Ryujinx.Common/Utilities/JsonHelper.cs deleted file mode 100644 index 9a2d6f18..00000000 --- a/Ryujinx.Common/Utilities/JsonHelper.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.IO; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization.Metadata; - -namespace Ryujinx.Common.Utilities -{ - public class JsonHelper - { - private static readonly JsonNamingPolicy SnakeCasePolicy = new SnakeCaseNamingPolicy(); - private const int DefaultFileWriteBufferSize = 4096; - - /// <summary> - /// Creates new serializer options with default settings. - /// </summary> - /// <remarks> - /// It is REQUIRED for you to save returned options statically or as a part of static serializer context - /// in order to avoid performance issues. You can safely modify returned options for your case before storing. - /// </remarks> - public static JsonSerializerOptions GetDefaultSerializerOptions(bool indented = true) - { - JsonSerializerOptions options = new() - { - DictionaryKeyPolicy = SnakeCasePolicy, - PropertyNamingPolicy = SnakeCasePolicy, - WriteIndented = indented, - AllowTrailingCommas = true, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - return options; - } - - public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) - { - return JsonSerializer.Serialize(value, typeInfo); - } - - public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) - { - return JsonSerializer.Deserialize(value, typeInfo); - } - - public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo) - { - using FileStream file = File.Create(filePath, DefaultFileWriteBufferSize, FileOptions.WriteThrough); - JsonSerializer.Serialize(file, value, typeInfo); - } - - public static T DeserializeFromFile<T>(string filePath, JsonTypeInfo<T> typeInfo) - { - using FileStream file = File.OpenRead(filePath); - return JsonSerializer.Deserialize(file, typeInfo); - } - - public static void SerializeToStream<T>(Stream stream, T value, JsonTypeInfo<T> typeInfo) - { - JsonSerializer.Serialize(stream, value, typeInfo); - } - - private class SnakeCaseNamingPolicy : JsonNamingPolicy - { - public override string ConvertName(string name) - { - if (string.IsNullOrEmpty(name)) - { - return name; - } - - StringBuilder builder = new(); - - for (int i = 0; i < name.Length; i++) - { - char c = name[i]; - - if (char.IsUpper(c)) - { - if (i == 0 || char.IsUpper(name[i - 1])) - { - builder.Append(char.ToLowerInvariant(c)); - } - else - { - builder.Append('_'); - builder.Append(char.ToLowerInvariant(c)); - } - } - else - { - builder.Append(c); - } - } - - return builder.ToString(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs b/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs deleted file mode 100644 index 3714bec0..00000000 --- a/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs +++ /dev/null @@ -1,302 +0,0 @@ -using MsgPack; -using System; -using System.Text; - -namespace Ryujinx.Common.Utilities -{ - public static class MessagePackObjectFormatter - { - public static string ToString(this MessagePackObject obj, bool pretty) - { - if (pretty) - { - return Format(obj); - } - else - { - return obj.ToString(); - } - } - - public static string Format(MessagePackObject obj) - { - var builder = new IndentedStringBuilder(); - - FormatMsgPackObj(obj, builder); - - return builder.ToString(); - } - - private static void FormatMsgPackObj(MessagePackObject obj, IndentedStringBuilder builder) - { - if (obj.IsMap || obj.IsDictionary) - { - FormatMsgPackMap(obj, builder); - } - else if (obj.IsArray || obj.IsList) - { - FormatMsgPackArray(obj, builder); - } - else if (obj.IsNil) - { - builder.Append("null"); - } - else - { - var literal = obj.ToObject(); - - if (literal is String) - { - builder.AppendQuotedString(obj.AsStringUtf16()); - } - else if (literal is byte[] byteArray) - { - FormatByteArray(byteArray, builder); - } - else if (literal is MessagePackExtendedTypeObject extObject) - { - builder.Append('{'); - - // Indent - builder.IncreaseIndent() - .AppendLine(); - - // Print TypeCode field - builder.AppendQuotedString("TypeCode") - .Append(": ") - .Append(extObject.TypeCode) - .AppendLine(","); - - // Print Value field - builder.AppendQuotedString("Value") - .Append(": "); - - FormatByteArrayAsString(extObject.GetBody(), builder, true); - - // Unindent - builder.DecreaseIndent() - .AppendLine(); - - builder.Append('}'); - } - else - { - builder.Append(literal); - } - } - } - - private static void FormatByteArray(byte[] arr, IndentedStringBuilder builder) - { - builder.Append("[ "); - - foreach (var b in arr) - { - builder.Append("0x"); - builder.Append(ToHexChar(b >> 4)); - builder.Append(ToHexChar(b & 0xF)); - builder.Append(", "); - } - - // Remove trailing comma - builder.Remove(builder.Length - 2, 2); - - builder.Append(" ]"); - } - - private static void FormatByteArrayAsString(byte[] arr, IndentedStringBuilder builder, bool withPrefix) - { - builder.Append('"'); - - if (withPrefix) - { - builder.Append("0x"); - } - - foreach (var b in arr) - { - builder.Append(ToHexChar(b >> 4)); - builder.Append(ToHexChar(b & 0xF)); - } - - builder.Append('"'); - } - - private static void FormatMsgPackMap(MessagePackObject obj, IndentedStringBuilder builder) - { - var map = obj.AsDictionary(); - - builder.Append('{'); - - // Indent - builder.IncreaseIndent() - .AppendLine(); - - foreach (var item in map) - { - FormatMsgPackObj(item.Key, builder); - - builder.Append(": "); - - FormatMsgPackObj(item.Value, builder); - - builder.AppendLine(","); - } - - // Remove the trailing new line and comma - builder.TrimLastLine() - .Remove(builder.Length - 1, 1); - - // Unindent - builder.DecreaseIndent() - .AppendLine(); - - builder.Append('}'); - } - - private static void FormatMsgPackArray(MessagePackObject obj, IndentedStringBuilder builder) - { - var arr = obj.AsList(); - - builder.Append("[ "); - - foreach (var item in arr) - { - FormatMsgPackObj(item, builder); - - builder.Append(", "); - } - - // Remove trailing comma - builder.Remove(builder.Length - 2, 2); - - builder.Append(" ]"); - } - - private static char ToHexChar(int b) - { - if (b < 10) - { - return unchecked((char)('0' + b)); - } - else - { - return unchecked((char)('A' + (b - 10))); - } - } - - internal class IndentedStringBuilder - { - const string DefaultIndent = " "; - - private int _indentCount = 0; - private int _newLineIndex = 0; - private StringBuilder _builder; - - public string IndentString { get; set; } = DefaultIndent; - - public IndentedStringBuilder(StringBuilder builder) - { - _builder = builder; - } - - public IndentedStringBuilder() - : this(new StringBuilder()) - { } - - public IndentedStringBuilder(string str) - : this(new StringBuilder(str)) - { } - - public IndentedStringBuilder(int length) - : this(new StringBuilder(length)) - { } - - public int Length { get => _builder.Length; } - - public IndentedStringBuilder IncreaseIndent() - { - _indentCount++; - - return this; - } - - public IndentedStringBuilder DecreaseIndent() - { - _indentCount--; - - return this; - } - - public IndentedStringBuilder Append(char value) - { - _builder.Append(value); - - return this; - } - - public IndentedStringBuilder Append(string value) - { - _builder.Append(value); - - return this; - } - - public IndentedStringBuilder Append(object value) - { - this.Append(value.ToString()); - - return this; - } - - public IndentedStringBuilder AppendQuotedString(string value) - { - _builder.Append('"'); - _builder.Append(value); - _builder.Append('"'); - - return this; - } - - public IndentedStringBuilder AppendLine() - { - _newLineIndex = _builder.Length; - - _builder.AppendLine(); - - for (int i = 0; i < _indentCount; i++) - _builder.Append(IndentString); - - return this; - } - - public IndentedStringBuilder AppendLine(string value) - { - _builder.Append(value); - - this.AppendLine(); - - return this; - } - - public IndentedStringBuilder TrimLastLine() - { - _builder.Remove(_newLineIndex, _builder.Length - _newLineIndex); - - return this; - } - - public IndentedStringBuilder Remove(int startIndex, int length) - { - _builder.Remove(startIndex, length); - - return this; - } - - public override string ToString() - { - return _builder.ToString(); - } - } - } -} diff --git a/Ryujinx.Common/Utilities/NetworkHelpers.cs b/Ryujinx.Common/Utilities/NetworkHelpers.cs deleted file mode 100644 index b2f6f45d..00000000 --- a/Ryujinx.Common/Utilities/NetworkHelpers.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Net.NetworkInformation; - -namespace Ryujinx.Common.Utilities -{ - public static class NetworkHelpers - { - private static (IPInterfaceProperties, UnicastIPAddressInformation) GetLocalInterface(NetworkInterface adapter, bool isPreferred) - { - IPInterfaceProperties properties = adapter.GetIPProperties(); - - if (isPreferred || (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 0)) - { - foreach (UnicastIPAddressInformation info in properties.UnicastAddresses) - { - // Only accept an IPv4 address - if (info.Address.GetAddressBytes().Length == 4) - { - return (properties, info); - } - } - } - - return (null, null); - } - - public static (IPInterfaceProperties, UnicastIPAddressInformation) GetLocalInterface(string lanInterfaceId = "0") - { - if (!NetworkInterface.GetIsNetworkAvailable()) - { - return (null, null); - } - - IPInterfaceProperties targetProperties = null; - UnicastIPAddressInformation targetAddressInfo = null; - - NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); - - string guid = lanInterfaceId; - bool hasPreference = guid != "0"; - - foreach (NetworkInterface adapter in interfaces) - { - bool isPreferred = adapter.Id == guid; - - // Ignore loopback and non IPv4 capable interface. - if (isPreferred || (targetProperties == null && adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && adapter.Supports(NetworkInterfaceComponent.IPv4))) - { - (IPInterfaceProperties properties, UnicastIPAddressInformation info) = GetLocalInterface(adapter, isPreferred); - - if (properties != null) - { - targetProperties = properties; - targetAddressInfo = info; - - if (isPreferred || !hasPreference) - { - break; - } - } - } - } - - return (targetProperties, targetAddressInfo); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/SpanHelpers.cs b/Ryujinx.Common/Utilities/SpanHelpers.cs deleted file mode 100644 index 4765eab3..00000000 --- a/Ryujinx.Common/Utilities/SpanHelpers.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Common.Utilities -{ - public static class SpanHelpers - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<T> CreateSpan<T>(scoped ref T reference, int length) - { - return MemoryMarshal.CreateSpan(ref reference, length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<T> AsSpan<T>(scoped ref T reference) where T : unmanaged - { - return CreateSpan(ref reference, 1); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<TSpan> AsSpan<TStruct, TSpan>(scoped ref TStruct reference) - where TStruct : unmanaged where TSpan : unmanaged - { - return CreateSpan(ref Unsafe.As<TStruct, TSpan>(ref reference), - Unsafe.SizeOf<TStruct>() / Unsafe.SizeOf<TSpan>()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> AsByteSpan<T>(scoped ref T reference) where T : unmanaged - { - return CreateSpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan<T> CreateReadOnlySpan<T>(scoped ref T reference, int length) - { - return MemoryMarshal.CreateReadOnlySpan(ref reference, length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan<T> AsReadOnlySpan<T>(scoped ref T reference) where T : unmanaged - { - return CreateReadOnlySpan(ref reference, 1); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan<TSpan> AsReadOnlySpan<TStruct, TSpan>(scoped ref TStruct reference) - where TStruct : unmanaged where TSpan : unmanaged - { - return CreateReadOnlySpan(ref Unsafe.As<TStruct, TSpan>(ref reference), - Unsafe.SizeOf<TStruct>() / Unsafe.SizeOf<TSpan>()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan<byte> AsReadOnlyByteSpan<T>(scoped ref T reference) where T : unmanaged - { - return CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>()); - } - } -} diff --git a/Ryujinx.Common/Utilities/StreamUtils.cs b/Ryujinx.Common/Utilities/StreamUtils.cs deleted file mode 100644 index da97188d..00000000 --- a/Ryujinx.Common/Utilities/StreamUtils.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.IO; -using Ryujinx.Common.Memory; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Ryujinx.Common.Utilities -{ - public static class StreamUtils - { - public static byte[] StreamToBytes(Stream input) - { - using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) - { - input.CopyTo(stream); - - return stream.ToArray(); - } - } - - public static async Task<byte[]> StreamToBytesAsync(Stream input, CancellationToken cancellationToken = default) - { - using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) - { - await input.CopyToAsync(stream, cancellationToken); - - return stream.ToArray(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs b/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs deleted file mode 100644 index c0127dc4..00000000 --- a/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs +++ /dev/null @@ -1,34 +0,0 @@ -#nullable enable -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Ryujinx.Common.Utilities -{ - /// <summary> - /// Specifies that value of <see cref="TEnum"/> will be serialized as string in JSONs - /// </summary> - /// <remarks> - /// Trimming friendly alternative to <see cref="JsonStringEnumConverter"/>. - /// Get rid of this converter if dotnet supports similar functionality out of the box. - /// </remarks> - /// <typeparam name="TEnum">Type of enum to serialize</typeparam> - public sealed class TypedStringEnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum - { - public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var enumValue = reader.GetString(); - if (string.IsNullOrEmpty(enumValue)) - { - return default; - } - - return Enum.Parse<TEnum>(enumValue); - } - - public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.ToString()); - } - } -} diff --git a/Ryujinx.Common/Utilities/UInt128Utils.cs b/Ryujinx.Common/Utilities/UInt128Utils.cs deleted file mode 100644 index af8521b4..00000000 --- a/Ryujinx.Common/Utilities/UInt128Utils.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Globalization; - -namespace Ryujinx.Common.Utilities -{ - public static class UInt128Utils - { - public static UInt128 FromHex(string hex) - { - return new UInt128(ulong.Parse(hex.AsSpan(0, 16), NumberStyles.HexNumber), ulong.Parse(hex.AsSpan(16), NumberStyles.HexNumber)); - } - - public static UInt128 CreateRandom() - { - return new UInt128((ulong)Random.Shared.NextInt64(), (ulong)Random.Shared.NextInt64()); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/XXHash128.cs b/Ryujinx.Common/XXHash128.cs deleted file mode 100644 index edbc652f..00000000 --- a/Ryujinx.Common/XXHash128.cs +++ /dev/null @@ -1,537 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.Diagnostics; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace Ryujinx.Common -{ - public static class XXHash128 - { - private const int StripeLen = 64; - private const int AccNb = StripeLen / sizeof(ulong); - private const int SecretConsumeRate = 8; - private const int SecretLastAccStart = 7; - private const int SecretMergeAccsStart = 11; - private const int SecretSizeMin = 136; - private const int MidSizeStartOffset = 3; - private const int MidSizeLastOffset = 17; - - private const uint Prime32_1 = 0x9E3779B1U; - private const uint Prime32_2 = 0x85EBCA77U; - private const uint Prime32_3 = 0xC2B2AE3DU; - private const uint Prime32_4 = 0x27D4EB2FU; - private const uint Prime32_5 = 0x165667B1U; - - private const ulong Prime64_1 = 0x9E3779B185EBCA87UL; - private const ulong Prime64_2 = 0xC2B2AE3D27D4EB4FUL; - private const ulong Prime64_3 = 0x165667B19E3779F9UL; - private const ulong Prime64_4 = 0x85EBCA77C2B2AE63UL; - private const ulong Prime64_5 = 0x27D4EB2F165667C5UL; - - private static readonly ulong[] Xxh3InitAcc = new ulong[] - { - Prime32_3, - Prime64_1, - Prime64_2, - Prime64_3, - Prime64_4, - Prime32_2, - Prime64_5, - Prime32_1 - }; - - private static ReadOnlySpan<byte> Xxh3KSecret => new byte[] - { - 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, - 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, - 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, - 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, - 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, - 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, - 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, - 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, - 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, - 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, - 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, - 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Mult32To64(ulong x, ulong y) - { - return (ulong)(uint)x * (ulong)(uint)y; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Hash128 Mult64To128(ulong lhs, ulong rhs) - { - ulong high = Math.BigMul(lhs, rhs, out ulong low); - return new Hash128 - { - Low = low, - High = high - }; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Mul128Fold64(ulong lhs, ulong rhs) - { - Hash128 product = Mult64To128(lhs, rhs); - return product.Low ^ product.High; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong XorShift64(ulong v64, int shift) - { - Debug.Assert(0 <= shift && shift < 64); - return v64 ^ (v64 >> shift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Xxh3Avalanche(ulong h64) - { - h64 = XorShift64(h64, 37); - h64 *= 0x165667919E3779F9UL; - h64 = XorShift64(h64, 32); - return h64; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Xxh64Avalanche(ulong h64) - { - h64 ^= h64 >> 33; - h64 *= Prime64_2; - h64 ^= h64 >> 29; - h64 *= Prime64_3; - h64 ^= h64 >> 32; - return h64; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static void Xxh3Accumulate512(Span<ulong> acc, ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret) - { - if (Avx2.IsSupported) - { - fixed (ulong* pAcc = acc) - { - fixed (byte* pInput = input, pSecret = secret) - { - Vector256<ulong>* xAcc = (Vector256<ulong>*)pAcc; - Vector256<byte>* xInput = (Vector256<byte>*)pInput; - Vector256<byte>* xSecret = (Vector256<byte>*)pSecret; - - for (ulong i = 0; i < StripeLen / 32; i++) - { - Vector256<byte> dataVec = xInput[i]; - Vector256<byte> keyVec = xSecret[i]; - Vector256<byte> dataKey = Avx2.Xor(dataVec, keyVec); - Vector256<uint> dataKeyLo = Avx2.Shuffle(dataKey.AsUInt32(), 0b00110001); - Vector256<ulong> product = Avx2.Multiply(dataKey.AsUInt32(), dataKeyLo); - Vector256<uint> dataSwap = Avx2.Shuffle(dataVec.AsUInt32(), 0b01001110); - Vector256<ulong> sum = Avx2.Add(xAcc[i], dataSwap.AsUInt64()); - xAcc[i] = Avx2.Add(product, sum); - } - } - } - } - else if (Sse2.IsSupported) - { - fixed (ulong* pAcc = acc) - { - fixed (byte* pInput = input, pSecret = secret) - { - Vector128<ulong>* xAcc = (Vector128<ulong>*)pAcc; - Vector128<byte>* xInput = (Vector128<byte>*)pInput; - Vector128<byte>* xSecret = (Vector128<byte>*)pSecret; - - for (ulong i = 0; i < StripeLen / 16; i++) - { - Vector128<byte> dataVec = xInput[i]; - Vector128<byte> keyVec = xSecret[i]; - Vector128<byte> dataKey = Sse2.Xor(dataVec, keyVec); - Vector128<uint> dataKeyLo = Sse2.Shuffle(dataKey.AsUInt32(), 0b00110001); - Vector128<ulong> product = Sse2.Multiply(dataKey.AsUInt32(), dataKeyLo); - Vector128<uint> dataSwap = Sse2.Shuffle(dataVec.AsUInt32(), 0b01001110); - Vector128<ulong> sum = Sse2.Add(xAcc[i], dataSwap.AsUInt64()); - xAcc[i] = Sse2.Add(product, sum); - } - } - } - } - else - { - for (int i = 0; i < AccNb; i++) - { - ulong dataVal = BinaryPrimitives.ReadUInt64LittleEndian(input.Slice(i * sizeof(ulong))); - ulong dataKey = dataVal ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(i * sizeof(ulong))); - acc[i ^ 1] += dataVal; - acc[i] += Mult32To64((uint)dataKey, dataKey >> 32); - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static void Xxh3ScrambleAcc(Span<ulong> acc, ReadOnlySpan<byte> secret) - { - if (Avx2.IsSupported) - { - fixed (ulong* pAcc = acc) - { - fixed (byte* pSecret = secret) - { - Vector256<uint> prime32 = Vector256.Create(Prime32_1); - Vector256<ulong>* xAcc = (Vector256<ulong>*)pAcc; - Vector256<byte>* xSecret = (Vector256<byte>*)pSecret; - - for (ulong i = 0; i < StripeLen / 32; i++) - { - Vector256<ulong> accVec = xAcc[i]; - Vector256<ulong> shifted = Avx2.ShiftRightLogical(accVec, 47); - Vector256<ulong> dataVec = Avx2.Xor(accVec, shifted); - - Vector256<byte> keyVec = xSecret[i]; - Vector256<uint> dataKey = Avx2.Xor(dataVec.AsUInt32(), keyVec.AsUInt32()); - - Vector256<uint> dataKeyHi = Avx2.Shuffle(dataKey.AsUInt32(), 0b00110001); - Vector256<ulong> prodLo = Avx2.Multiply(dataKey, prime32); - Vector256<ulong> prodHi = Avx2.Multiply(dataKeyHi, prime32); - - xAcc[i] = Avx2.Add(prodLo, Avx2.ShiftLeftLogical(prodHi, 32)); - } - } - } - } - else if (Sse2.IsSupported) - { - fixed (ulong* pAcc = acc) - { - fixed (byte* pSecret = secret) - { - Vector128<uint> prime32 = Vector128.Create(Prime32_1); - Vector128<ulong>* xAcc = (Vector128<ulong>*)pAcc; - Vector128<byte>* xSecret = (Vector128<byte>*)pSecret; - - for (ulong i = 0; i < StripeLen / 16; i++) - { - Vector128<ulong> accVec = xAcc[i]; - Vector128<ulong> shifted = Sse2.ShiftRightLogical(accVec, 47); - Vector128<ulong> dataVec = Sse2.Xor(accVec, shifted); - - Vector128<byte> keyVec = xSecret[i]; - Vector128<uint> dataKey = Sse2.Xor(dataVec.AsUInt32(), keyVec.AsUInt32()); - - Vector128<uint> dataKeyHi = Sse2.Shuffle(dataKey.AsUInt32(), 0b00110001); - Vector128<ulong> prodLo = Sse2.Multiply(dataKey, prime32); - Vector128<ulong> prodHi = Sse2.Multiply(dataKeyHi, prime32); - - xAcc[i] = Sse2.Add(prodLo, Sse2.ShiftLeftLogical(prodHi, 32)); - } - } - } - } - else - { - for (int i = 0; i < AccNb; i++) - { - ulong key64 = BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(i * sizeof(ulong))); - ulong acc64 = acc[i]; - acc64 = XorShift64(acc64, 47); - acc64 ^= key64; - acc64 *= Prime32_1; - acc[i] = acc64; - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void Xxh3Accumulate(Span<ulong> acc, ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, int nbStripes) - { - for (int n = 0; n < nbStripes; n++) - { - ReadOnlySpan<byte> inData = input.Slice(n * StripeLen); - Xxh3Accumulate512(acc, inData, secret.Slice(n * SecretConsumeRate)); - } - } - - private static void Xxh3HashLongInternalLoop(Span<ulong> acc, ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret) - { - int nbStripesPerBlock = (secret.Length - StripeLen) / SecretConsumeRate; - int blockLen = StripeLen * nbStripesPerBlock; - int nbBlocks = (input.Length - 1) / blockLen; - - Debug.Assert(secret.Length >= SecretSizeMin); - - for (int n = 0; n < nbBlocks; n++) - { - Xxh3Accumulate(acc, input.Slice(n * blockLen), secret, nbStripesPerBlock); - Xxh3ScrambleAcc(acc, secret.Slice(secret.Length - StripeLen)); - } - - Debug.Assert(input.Length > StripeLen); - - int nbStripes = (input.Length - 1 - (blockLen * nbBlocks)) / StripeLen; - Debug.Assert(nbStripes <= (secret.Length / SecretConsumeRate)); - Xxh3Accumulate(acc, input.Slice(nbBlocks * blockLen), secret, nbStripes); - - ReadOnlySpan<byte> p = input.Slice(input.Length - StripeLen); - Xxh3Accumulate512(acc, p, secret.Slice(secret.Length - StripeLen - SecretLastAccStart)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Xxh3Mix2Accs(Span<ulong> acc, ReadOnlySpan<byte> secret) - { - return Mul128Fold64( - acc[0] ^ BinaryPrimitives.ReadUInt64LittleEndian(secret), - acc[1] ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(8))); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Xxh3MergeAccs(Span<ulong> acc, ReadOnlySpan<byte> secret, ulong start) - { - ulong result64 = start; - - for (int i = 0; i < 4; i++) - { - result64 += Xxh3Mix2Accs(acc.Slice(2 * i), secret.Slice(16 * i)); - } - - return Xxh3Avalanche(result64); - } - - [SkipLocalsInit] - private static Hash128 Xxh3HashLong128bInternal(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret) - { - Span<ulong> acc = stackalloc ulong[AccNb]; - Xxh3InitAcc.CopyTo(acc); - - Xxh3HashLongInternalLoop(acc, input, secret); - - Debug.Assert(acc.Length == 8); - Debug.Assert(secret.Length >= acc.Length * sizeof(ulong) + SecretMergeAccsStart); - - return new Hash128 - { - Low = Xxh3MergeAccs(acc, secret.Slice(SecretMergeAccsStart), (ulong)input.Length * Prime64_1), - High = Xxh3MergeAccs( - acc, - secret.Slice(secret.Length - acc.Length * sizeof(ulong) - SecretMergeAccsStart), - ~((ulong)input.Length * Prime64_2)) - }; - } - - private static Hash128 Xxh3Len1To3128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(1 <= input.Length && input.Length <= 3); - - byte c1 = input[0]; - byte c2 = input[input.Length >> 1]; - byte c3 = input[^1]; - - uint combinedL = ((uint)c1 << 16) | ((uint)c2 << 24) | c3 | ((uint)input.Length << 8); - uint combinedH = BitOperations.RotateLeft(BinaryPrimitives.ReverseEndianness(combinedL), 13); - ulong bitFlipL = (BinaryPrimitives.ReadUInt32LittleEndian(secret) ^ BinaryPrimitives.ReadUInt32LittleEndian(secret.Slice(4))) + seed; - ulong bitFlipH = (BinaryPrimitives.ReadUInt32LittleEndian(secret.Slice(8)) ^ BinaryPrimitives.ReadUInt32LittleEndian(secret.Slice(12))) - seed; - ulong keyedLo = combinedL ^ bitFlipL; - ulong keyedHi = combinedH ^ bitFlipH; - - return new Hash128 - { - Low = Xxh64Avalanche(keyedLo), - High = Xxh64Avalanche(keyedHi) - }; - } - - private static Hash128 Xxh3Len4To8128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(4 <= input.Length && input.Length <= 8); - - seed ^= BinaryPrimitives.ReverseEndianness((uint)seed) << 32; - - uint inputLo = BinaryPrimitives.ReadUInt32LittleEndian(input); - uint inputHi = BinaryPrimitives.ReadUInt32LittleEndian(input.Slice(input.Length - 4)); - ulong input64 = inputLo + ((ulong)inputHi << 32); - ulong bitFlip = (BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(16)) ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(24))) + seed; - ulong keyed = input64 ^ bitFlip; - - Hash128 m128 = Mult64To128(keyed, Prime64_1 + ((ulong)input.Length << 2)); - - m128.High += m128.Low << 1; - m128.Low ^= m128.High >> 3; - - m128.Low = XorShift64(m128.Low, 35); - m128.Low *= 0x9FB21C651E98DF25UL; - m128.Low = XorShift64(m128.Low, 28); - m128.High = Xxh3Avalanche(m128.High); - return m128; - } - - private static Hash128 Xxh3Len9To16128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(9 <= input.Length && input.Length <= 16); - - ulong bitFlipL = (BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(32)) ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(40))) - seed; - ulong bitFlipH = (BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(48)) ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(56))) + seed; - ulong inputLo = BinaryPrimitives.ReadUInt64LittleEndian(input); - ulong inputHi = BinaryPrimitives.ReadUInt64LittleEndian(input.Slice(input.Length - 8)); - - Hash128 m128 = Mult64To128(inputLo ^ inputHi ^ bitFlipL, Prime64_1); - m128.Low += ((ulong)input.Length - 1) << 54; - inputHi ^= bitFlipH; - m128.High += inputHi + Mult32To64((uint)inputHi, Prime32_2 - 1); - m128.Low ^= BinaryPrimitives.ReverseEndianness(m128.High); - - Hash128 h128 = Mult64To128(m128.Low, Prime64_2); - h128.High += m128.High * Prime64_2; - h128.Low = Xxh3Avalanche(h128.Low); - h128.High = Xxh3Avalanche(h128.High); - return h128; - } - - private static Hash128 Xxh3Len0To16128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(input.Length <= 16); - - if (input.Length > 8) - { - return Xxh3Len9To16128b(input, secret, seed); - } - else if (input.Length >= 4) - { - return Xxh3Len4To8128b(input, secret, seed); - } - else if (input.Length != 0) - { - return Xxh3Len1To3128b(input, secret, seed); - } - else - { - Hash128 h128 = new Hash128(); - ulong bitFlipL = BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(64)) ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(72)); - ulong bitFlipH = BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(80)) ^ BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(88)); - h128.Low = Xxh64Avalanche(seed ^ bitFlipL); - h128.High = Xxh64Avalanche(seed ^ bitFlipH); - return h128; - } - } - - private static ulong Xxh3Mix16b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - ulong inputLo = BinaryPrimitives.ReadUInt64LittleEndian(input); - ulong inputHi = BinaryPrimitives.ReadUInt64LittleEndian(input.Slice(8)); - return Mul128Fold64( - inputLo ^ (BinaryPrimitives.ReadUInt64LittleEndian(secret) + seed), - inputHi ^ (BinaryPrimitives.ReadUInt64LittleEndian(secret.Slice(8)) - seed)); - } - - private static Hash128 Xxh128Mix32b(Hash128 acc, ReadOnlySpan<byte> input, ReadOnlySpan<byte> input2, ReadOnlySpan<byte> secret, ulong seed) - { - acc.Low += Xxh3Mix16b(input, secret, seed); - acc.Low ^= BinaryPrimitives.ReadUInt64LittleEndian(input2) + BinaryPrimitives.ReadUInt64LittleEndian(input2.Slice(8)); - acc.High += Xxh3Mix16b(input2, secret.Slice(16), seed); - acc.High ^= BinaryPrimitives.ReadUInt64LittleEndian(input) + BinaryPrimitives.ReadUInt64LittleEndian(input.Slice(8)); - return acc; - } - - private static Hash128 Xxh3Len17To128128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(secret.Length >= SecretSizeMin); - Debug.Assert(16 < input.Length && input.Length <= 128); - - Hash128 acc = new Hash128 - { - Low = (ulong)input.Length * Prime64_1, - High = 0 - }; - - if (input.Length > 32) - { - if (input.Length > 64) - { - if (input.Length > 96) - { - acc = Xxh128Mix32b(acc, input.Slice(48), input.Slice(input.Length - 64), secret.Slice(96), seed); - } - acc = Xxh128Mix32b(acc, input.Slice(32), input.Slice(input.Length - 48), secret.Slice(64), seed); - } - acc = Xxh128Mix32b(acc, input.Slice(16), input.Slice(input.Length - 32), secret.Slice(32), seed); - } - acc = Xxh128Mix32b(acc, input, input.Slice(input.Length - 16), secret, seed); - - Hash128 h128 = new Hash128 - { - Low = acc.Low + acc.High, - High = acc.Low * Prime64_1 + acc.High * Prime64_4 + ((ulong)input.Length - seed) * Prime64_2 - }; - h128.Low = Xxh3Avalanche(h128.Low); - h128.High = 0UL - Xxh3Avalanche(h128.High); - return h128; - } - - private static Hash128 Xxh3Len129To240128b(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(secret.Length >= SecretSizeMin); - Debug.Assert(128 < input.Length && input.Length <= 240); - - Hash128 acc = new Hash128(); - - int nbRounds = input.Length / 32; - acc.Low = (ulong)input.Length * Prime64_1; - acc.High = 0; - - for (int i = 0; i < 4; i++) - { - acc = Xxh128Mix32b(acc, input.Slice(32 * i), input.Slice(32 * i + 16), secret.Slice(32 * i), seed); - } - - acc.Low = Xxh3Avalanche(acc.Low); - acc.High = Xxh3Avalanche(acc.High); - Debug.Assert(nbRounds >= 4); - - for (int i = 4; i < nbRounds; i++) - { - acc = Xxh128Mix32b(acc, input.Slice(32 * i), input.Slice(32 * i + 16), secret.Slice(MidSizeStartOffset + 32 * (i - 4)), seed); - } - - acc = Xxh128Mix32b(acc, input.Slice(input.Length - 16), input.Slice(input.Length - 32), secret.Slice(SecretSizeMin - MidSizeLastOffset - 16), 0UL - seed); - - Hash128 h128 = new Hash128 - { - Low = acc.Low + acc.High, - High = acc.Low * Prime64_1 + acc.High * Prime64_4 + ((ulong)input.Length - seed) * Prime64_2 - }; - h128.Low = Xxh3Avalanche(h128.Low); - h128.High = 0UL - Xxh3Avalanche(h128.High); - return h128; - } - - private static Hash128 Xxh3128bitsInternal(ReadOnlySpan<byte> input, ReadOnlySpan<byte> secret, ulong seed) - { - Debug.Assert(secret.Length >= SecretSizeMin); - - if (input.Length <= 16) - { - return Xxh3Len0To16128b(input, secret, seed); - } - else if (input.Length <= 128) - { - return Xxh3Len17To128128b(input, secret, seed); - } - else if (input.Length <= 240) - { - return Xxh3Len129To240128b(input, secret, seed); - } - else - { - return Xxh3HashLong128bInternal(input, secret); - } - } - - public static Hash128 ComputeHash(ReadOnlySpan<byte> input) - { - return Xxh3128bitsInternal(input, Xxh3KSecret, 0UL); - } - } -} |
