mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-22 19:15:47 +00:00
UI: Add Skyrim, KAFTL & HW:AOC to RPC.
Minor code improvements and comment fixes.
This commit is contained in:
parent
280b94fc0c
commit
1800ecc1b4
13 changed files with 68 additions and 122 deletions
|
@ -8,7 +8,7 @@ namespace Ryujinx.Common
|
||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a <cref="ReadOnlySpan<int>" /> to this stream.
|
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
|
||||||
///
|
///
|
||||||
/// This default implementation converts each buffer value to a stack-allocated
|
/// 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[])" />.
|
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
|
||||||
|
@ -66,8 +66,8 @@ namespace Ryujinx.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// Writes a four-byte unsigned integer to this stream. The current position
|
/// Writes a four-byte unsigned integer to this stream. The current position
|
||||||
// of the stream is advanced by four.
|
/// of the stream is advanced by four.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream to be written to</param>
|
/// <param name="stream">The stream to be written to</param>
|
||||||
/// <param name="value">The value to be written</param>
|
/// <param name="value">The value to be written</param>
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace Ryujinx.Common
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static ulong XorShift64(ulong v64, int shift)
|
private static ulong XorShift64(ulong v64, int shift)
|
||||||
{
|
{
|
||||||
Debug.Assert(0 <= shift && shift < 64);
|
Debug.Assert(shift is >= 0 and < 64);
|
||||||
|
|
||||||
return v64 ^ (v64 >> shift);
|
return v64 ^ (v64 >> shift);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,18 @@ namespace Ryujinx.Common
|
||||||
{
|
{
|
||||||
public static class BitUtils
|
public static class BitUtils
|
||||||
{
|
{
|
||||||
public static T AlignUp<T>(T value, T size)
|
public static T AlignUp<T>(T value, T size) where T : IBinaryInteger<T>
|
||||||
where T : IBinaryInteger<T>
|
=> (value + (size - T.One)) & -size;
|
||||||
{
|
|
||||||
return (value + (size - T.One)) & -size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T AlignDown<T>(T value, T size)
|
public static T AlignDown<T>(T value, T size) where T : IBinaryInteger<T>
|
||||||
where T : IBinaryInteger<T>
|
=> value & -size;
|
||||||
{
|
|
||||||
return value & -size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T DivRoundUp<T>(T value, T dividend)
|
public static T DivRoundUp<T>(T value, T dividend) where T : IBinaryInteger<T>
|
||||||
where T : IBinaryInteger<T>
|
=> (value + (dividend - T.One)) / dividend;
|
||||||
{
|
|
||||||
return (value + (dividend - T.One)) / dividend;
|
public static int Pow2RoundDown(int value) => BitOperations.IsPow2(value) ? value : Pow2RoundUp(value) >> 1;
|
||||||
}
|
|
||||||
|
public static long ReverseBits64(long value) => (long)ReverseBits64((ulong)value);
|
||||||
|
|
||||||
public static int Pow2RoundUp(int value)
|
public static int Pow2RoundUp(int value)
|
||||||
{
|
{
|
||||||
|
@ -35,16 +30,6 @@ namespace Ryujinx.Common
|
||||||
return ++value;
|
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)
|
private static ulong ReverseBits64(ulong value)
|
||||||
{
|
{
|
||||||
value = ((value & 0xaaaaaaaaaaaaaaaa) >> 1) | ((value & 0x5555555555555555) << 1);
|
value = ((value & 0xaaaaaaaaaaaaaaaa) >> 1) | ((value & 0x5555555555555555) << 1);
|
||||||
|
|
|
@ -243,7 +243,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
||||||
// This call is expected to fail if we're running with a core profile,
|
// This call is expected to fail if we're running with a core profile,
|
||||||
// as this clamp target was deprecated, but that's fine as a core profile
|
// as this clamp target was deprecated, but that's fine as a core profile
|
||||||
// should already have the desired behaviour were outputs are not clamped.
|
// should already have the desired behaviour where outputs are not clamped.
|
||||||
GL.ClampColor(ClampColorTarget.ClampFragmentColor, ClampColorMode.False);
|
GL.ClampColor(ClampColorTarget.ClampFragmentColor, ClampColorMode.False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
if (subsetCount == 0)
|
if (subsetCount == 0)
|
||||||
{
|
{
|
||||||
// Mode is invalid, the spec mandates that hardware fills the block with
|
// Mode is invalid, the spec mandates that hardware fills the block with
|
||||||
// a opaque black color.
|
// an opaque black color.
|
||||||
for (int ty = 0; ty < h; ty++)
|
for (int ty = 0; ty < h; ty++)
|
||||||
{
|
{
|
||||||
int baseOffs = ty * width;
|
int baseOffs = ty * width;
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
private readonly BlockLinearLayout _layoutConverter;
|
private readonly BlockLinearLayout _layoutConverter;
|
||||||
|
|
||||||
// Variables for built in iteration.
|
// Variables for built-in iteration.
|
||||||
private int _yPart;
|
private int _yPart;
|
||||||
|
|
||||||
public OffsetCalculator(
|
public OffsetCalculator(
|
||||||
|
@ -73,69 +73,50 @@ namespace Ryujinx.Graphics.Texture
|
||||||
public int GetOffset(int x, int y)
|
public int GetOffset(int x, int y)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (_isLinear)
|
||||||
{
|
|
||||||
return x * _bytesPerPixel + y * _stride;
|
return x * _bytesPerPixel + y * _stride;
|
||||||
}
|
|
||||||
else
|
return _layoutConverter.GetOffset(x, y, 0);
|
||||||
{
|
|
||||||
return _layoutConverter.GetOffset(x, y, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetOffset(int x)
|
public int GetOffset(int x)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (_isLinear)
|
||||||
{
|
|
||||||
return x * _bytesPerPixel + _yPart;
|
return x * _bytesPerPixel + _yPart;
|
||||||
}
|
|
||||||
else
|
return _layoutConverter.GetOffset(x);
|
||||||
{
|
|
||||||
return _layoutConverter.GetOffset(x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetOffsetWithLineOffset64(int x)
|
public int GetOffsetWithLineOffset64(int x)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (_isLinear)
|
||||||
{
|
|
||||||
return x + _yPart;
|
return x + _yPart;
|
||||||
}
|
|
||||||
else
|
return _layoutConverter.GetOffsetWithLineOffset64(x);
|
||||||
{
|
|
||||||
return _layoutConverter.GetOffsetWithLineOffset64(x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public (int offset, int size) GetRectangleRange(int x, int y, int width, int height)
|
public (int offset, int size) GetRectangleRange(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (!_isLinear)
|
||||||
{
|
|
||||||
int start = y * Math.Abs(_stride) + x * _bytesPerPixel;
|
|
||||||
int end = (y + height - 1) * Math.Abs(_stride) + (x + width) * _bytesPerPixel;
|
|
||||||
return (y * _stride + x * _bytesPerPixel, end - start);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _layoutConverter.GetRectangleRange(x, y, width, height);
|
return _layoutConverter.GetRectangleRange(x, y, width, height);
|
||||||
}
|
|
||||||
|
int start = y * Math.Abs(_stride) + x * _bytesPerPixel;
|
||||||
|
int end = (y + height - 1) * Math.Abs(_stride) + (x + width) * _bytesPerPixel;
|
||||||
|
return (y * _stride + x * _bytesPerPixel, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LayoutMatches(OffsetCalculator other)
|
public bool LayoutMatches(OffsetCalculator other)
|
||||||
{
|
{
|
||||||
if (_isLinear)
|
if (_isLinear)
|
||||||
{
|
|
||||||
return other._isLinear &&
|
return other._isLinear &&
|
||||||
_width == other._width &&
|
_width == other._width &&
|
||||||
_height == other._height &&
|
_height == other._height &&
|
||||||
_stride == other._stride &&
|
_stride == other._stride &&
|
||||||
_bytesPerPixel == other._bytesPerPixel;
|
_bytesPerPixel == other._bytesPerPixel;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter);
|
||||||
return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.HLE.Generators
|
||||||
var name = GetFullName(className, context).Replace("global::", "");
|
var name = GetFullName(className, context).Replace("global::", "");
|
||||||
if (!name.StartsWith("Ryujinx.HLE.HOS.Services"))
|
if (!name.StartsWith("Ryujinx.HLE.HOS.Services"))
|
||||||
continue;
|
continue;
|
||||||
var constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax);
|
var constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax).ToArray();
|
||||||
|
|
||||||
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1))
|
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -15,7 +15,10 @@ namespace Ryujinx.UI.Common
|
||||||
{
|
{
|
||||||
public static Timestamps StartedAt { get; set; }
|
public static Timestamps StartedAt { get; set; }
|
||||||
|
|
||||||
private static readonly string _description = $"v{ReleaseInformation.Version} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}@{ReleaseInformation.BuildGitHash}";
|
private static readonly string _description = ReleaseInformation.IsValid
|
||||||
|
? $"v{ReleaseInformation.Version} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}@{ReleaseInformation.BuildGitHash}"
|
||||||
|
: "dev build";
|
||||||
|
|
||||||
private const string ApplicationId = "1293250299716173864";
|
private const string ApplicationId = "1293250299716173864";
|
||||||
|
|
||||||
private const int ApplicationByteLimit = 128;
|
private const int ApplicationByteLimit = 128;
|
||||||
|
@ -76,7 +79,7 @@ namespace Ryujinx.UI.Common
|
||||||
SmallImageText = TruncateToByteLength(_description)
|
SmallImageText = TruncateToByteLength(_description)
|
||||||
},
|
},
|
||||||
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
||||||
State = appMeta.LastPlayed.HasValue
|
State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5
|
||||||
? $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}"
|
? $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}"
|
||||||
: "Never played",
|
: "Never played",
|
||||||
Timestamps = Timestamps.Now
|
Timestamps = Timestamps.Now
|
||||||
|
@ -115,7 +118,8 @@ namespace Ryujinx.UI.Common
|
||||||
_discordClient?.Dispose();
|
_discordClient?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string[] _discordGameAssetKeys = [
|
private static readonly string[] _discordGameAssetKeys =
|
||||||
|
[
|
||||||
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
||||||
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
||||||
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
||||||
|
@ -145,9 +149,12 @@ namespace Ryujinx.UI.Common
|
||||||
|
|
||||||
"0100c2500fc20000", // Splatoon 3
|
"0100c2500fc20000", // Splatoon 3
|
||||||
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
||||||
|
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
||||||
"01007820196a6000", // Red Dead Redemption
|
"01007820196a6000", // Red Dead Redemption
|
||||||
"0100744001588000", // Cars 3: Driven to Win
|
"0100744001588000", // Cars 3: Driven to Win
|
||||||
|
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
||||||
"01006f8002326000", // Animal Crossing: New Horizons
|
"01006f8002326000", // Animal Crossing: New Horizons
|
||||||
|
"01004d300c5ae000", // Kirby and the Forgotten Land
|
||||||
"0100853015e86000", // No Man's Sky
|
"0100853015e86000", // No Man's Sky
|
||||||
"01008d100d43e000", // Saints Row IV
|
"01008d100d43e000", // Saints Row IV
|
||||||
"0100de600beee000", // Saints Row: The Third - The Full Package
|
"0100de600beee000", // Saints Row: The Third - The Full Package
|
||||||
|
|
|
@ -10,20 +10,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||||
|
|
||||||
protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
|
protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
|
||||||
{
|
{
|
||||||
var newValue = Value + e.Delta.Y * TickFrequency;
|
Value = Math.Clamp(Value + e.Delta.Y * TickFrequency, Minimum, Maximum);
|
||||||
|
|
||||||
if (newValue < Minimum)
|
|
||||||
{
|
|
||||||
Value = Minimum;
|
|
||||||
}
|
|
||||||
else if (newValue > Maximum)
|
|
||||||
{
|
|
||||||
Value = Maximum;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Value = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,16 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
primaryButtonResult);
|
primaryButtonResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static async Task<UserResult> CreateLocalizedConfirmationDialog(
|
||||||
|
string primaryText,
|
||||||
|
string secondaryText) =>
|
||||||
|
await CreateConfirmationDialog(
|
||||||
|
primaryText,
|
||||||
|
secondaryText,
|
||||||
|
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||||
|
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||||
|
LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
|
||||||
|
|
||||||
internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
|
internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
|
||||||
{
|
{
|
||||||
await ShowTextDialog(
|
await ShowTextDialog(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl
|
<UserControl
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
@ -22,13 +22,8 @@
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
Background="{DynamicResource ThemeContentBackgroundColor}"
|
Background="{DynamicResource ThemeContentBackgroundColor}"
|
||||||
DockPanel.Dock="Bottom"
|
DockPanel.Dock="Bottom"
|
||||||
IsVisible="{Binding ShowMenuAndStatusBar}">
|
IsVisible="{Binding ShowMenuAndStatusBar}"
|
||||||
<Grid.ColumnDefinitions>
|
ColumnDefinitions="Auto,Auto,*,Auto">
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
|
|
|
@ -50,10 +50,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
private void Button_OnClick(object sender, RoutedEventArgs e)
|
private void Button_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is Button { Tag: { } url })
|
if (sender is Button { Tag: string url })
|
||||||
{
|
OpenHelper.OpenUrl(url);
|
||||||
OpenHelper.OpenUrl(url.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AmiiboLabel_OnPointerPressed(object sender, PointerPressedEventArgs e)
|
private void AmiiboLabel_OnPointerPressed(object sender, PointerPressedEventArgs e)
|
||||||
|
|
|
@ -19,20 +19,12 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
private const int CutOffLuminosity = 64;
|
private const int CutOffLuminosity = 64;
|
||||||
|
|
||||||
private readonly struct PaletteColor
|
private readonly struct PaletteColor(int qck, byte r, byte g, byte b)
|
||||||
{
|
{
|
||||||
public int Qck { get; }
|
public int Qck { get; } = qck;
|
||||||
public byte R { get; }
|
public byte R { get; } = r;
|
||||||
public byte G { get; }
|
public byte G { get; } = g;
|
||||||
public byte B { get; }
|
public byte B { get; } = b;
|
||||||
|
|
||||||
public PaletteColor(int qck, byte r, byte g, byte b)
|
|
||||||
{
|
|
||||||
Qck = qck;
|
|
||||||
R = r;
|
|
||||||
G = g;
|
|
||||||
B = b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SKColor GetFilteredColor(SKBitmap image)
|
public static SKColor GetFilteredColor(SKBitmap image)
|
||||||
|
@ -164,16 +156,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int BalanceHitCount(int hitCount, int maxHitCount)
|
|
||||||
{
|
|
||||||
return (hitCount << 8) / maxHitCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetColorApproximateLuminosity(byte r, byte g, byte b)
|
|
||||||
{
|
|
||||||
return (r + g + b) / 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetColorSaturation(PaletteColor color)
|
private static int GetColorSaturation(PaletteColor color)
|
||||||
{
|
{
|
||||||
int cMax = Math.Max(Math.Max(color.R, color.G), color.B);
|
int cMax = Math.Max(Math.Max(color.R, color.G), color.B);
|
||||||
|
@ -188,10 +170,11 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
return (delta << 8) / cMax;
|
return (delta << 8) / cMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetColorValue(PaletteColor color)
|
private static int GetColorValue(PaletteColor color) => Math.Max(Math.Max(color.R, color.G), color.B);
|
||||||
{
|
|
||||||
return Math.Max(Math.Max(color.R, color.G), color.B);
|
private static int BalanceHitCount(int hitCount, int maxHitCount) => (hitCount << 8) / maxHitCount;
|
||||||
}
|
|
||||||
|
private static int GetColorApproximateLuminosity(byte r, byte g, byte b) => (r + g + b) / 3;
|
||||||
|
|
||||||
private static int GetQuantizedColorKey(byte r, byte g, byte b)
|
private static int GetQuantizedColorKey(byte r, byte g, byte b)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue