mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-08-11 20:57:47 +02:00
UI: Compatibility List Viewer
This commit is contained in:
152
src/Ryujinx/Utilities/Compat/CompatibilityCsv.cs
Normal file
152
src/Ryujinx/Utilities/Compat/CompatibilityCsv.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using Gommon;
|
||||
using nietras.SeparatedValues;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.Ava.Utilities.Compat
|
||||
{
|
||||
public class CompatibilityCsv
|
||||
{
|
||||
public static CompatibilityCsv Shared { get; set; }
|
||||
|
||||
public CompatibilityCsv(SepReader reader)
|
||||
{
|
||||
var entries = new List<CompatibilityEntry>();
|
||||
|
||||
foreach (var row in reader)
|
||||
{
|
||||
entries.Add(new CompatibilityEntry(reader.Header, row));
|
||||
}
|
||||
|
||||
Entries = entries.Where(x => x.Status != null)
|
||||
.OrderBy(it => it.GameName).ToArray();
|
||||
}
|
||||
|
||||
public CompatibilityEntry[] Entries { get; }
|
||||
}
|
||||
|
||||
public class CompatibilityEntry
|
||||
{
|
||||
public CompatibilityEntry(SepReaderHeader header, SepReader.Row row)
|
||||
{
|
||||
IssueNumber = row[header.IndexOf("issue_number")].Parse<int>();
|
||||
|
||||
var titleIdRow = row[header.IndexOf("extracted_game_id")].ToString();
|
||||
if (!string.IsNullOrEmpty(titleIdRow))
|
||||
TitleId = titleIdRow;
|
||||
|
||||
var issueTitleRow = row[header.IndexOf("issue_title")].ToString();
|
||||
if (TitleId.HasValue)
|
||||
issueTitleRow = issueTitleRow.ReplaceIgnoreCase($" - {TitleId}", string.Empty);
|
||||
|
||||
GameName = issueTitleRow.Trim().Trim('"');
|
||||
|
||||
IssueLabels = row[header.IndexOf("issue_labels")].ToString().Split(';');
|
||||
Status = row[header.IndexOf("extracted_status")].ToString().ToLower() switch
|
||||
{
|
||||
"playable" => LocaleKeys.CompatibilityListPlayable,
|
||||
"ingame" => LocaleKeys.CompatibilityListIngame,
|
||||
"menus" => LocaleKeys.CompatibilityListMenus,
|
||||
"boots" => LocaleKeys.CompatibilityListBoots,
|
||||
"nothing" => LocaleKeys.CompatibilityListNothing,
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (row[header.IndexOf("last_event_date")].TryParse<DateTime>(out var dt))
|
||||
LastEvent = dt;
|
||||
|
||||
if (row[header.IndexOf("events_count")].TryParse<int>(out var eventsCount))
|
||||
EventCount = eventsCount;
|
||||
}
|
||||
|
||||
public int IssueNumber { get; }
|
||||
public string GameName { get; }
|
||||
public Optional<string> TitleId { get; }
|
||||
public string[] IssueLabels { get; }
|
||||
public LocaleKeys? Status { get; }
|
||||
public DateTime LastEvent { get; }
|
||||
public int EventCount { get; }
|
||||
|
||||
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
||||
public string FormattedTitleId => TitleId.OrElse(new string(' ', 16));
|
||||
|
||||
public string FormattedIssueLabels => IssueLabels
|
||||
.Where(it => !it.StartsWithIgnoreCase("status"))
|
||||
.Select(FormatLabelName)
|
||||
.JoinToString(", ");
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder("CompatibilityEntry: {");
|
||||
sb.Append($"{nameof(IssueNumber)}={IssueNumber}, ");
|
||||
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
|
||||
sb.Append($"{nameof(TitleId)}={TitleId}, ");
|
||||
sb.Append($"{nameof(IssueLabels)}=\"{IssueLabels}\", ");
|
||||
sb.Append($"{nameof(Status)}=\"{Status}\", ");
|
||||
sb.Append($"{nameof(LastEvent)}=\"{LastEvent}\", ");
|
||||
sb.Append($"{nameof(EventCount)}={EventCount}");
|
||||
sb.Append('}');
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string FormatLabelName(string labelName) => labelName.ToLower() switch
|
||||
{
|
||||
"audio" => "Audio",
|
||||
"bug" => "Bug",
|
||||
"cpu" => "CPU",
|
||||
"gpu" => "GPU",
|
||||
"gui" => "GUI",
|
||||
"help wanted" => "Help Wanted",
|
||||
"horizon" => "Horizon",
|
||||
"infra" => "Project Infra",
|
||||
"invalid" => "Invalid",
|
||||
"kernel" => "Kernel",
|
||||
"ldn" => "LDN",
|
||||
"linux" => "Linux",
|
||||
"macos" => "macOS",
|
||||
"question" => "Question",
|
||||
"windows" => "Windows",
|
||||
"graphics-backend:opengl" => "Graphics: OpenGL",
|
||||
"graphics-backend:vulkan" => "Graphics: Vulkan",
|
||||
"ldn-works" => "LDN Works",
|
||||
"ldn-untested" => "LDN Untested",
|
||||
"ldn-broken" => "LDN Broken",
|
||||
"ldn-partial" => "Partial LDN",
|
||||
"nvdec" => "NVDEC",
|
||||
"services" => "NX Services",
|
||||
"services-horizon" => "Horizon OS Services",
|
||||
"slow" => "Runs Slow",
|
||||
"crash" => "Crashes",
|
||||
"deadlock" => "Deadlock",
|
||||
"regression" => "Regression",
|
||||
"opengl" => "OpenGL",
|
||||
"opengl-backend-bug" => "OpenGL Backend Bug",
|
||||
"vulkan-backend-bug" => "Vulkan Backend Bug",
|
||||
"mac-bug" => "Mac-specific Bug(s)",
|
||||
"amd-vendor-bug" => "AMD GPU Bug",
|
||||
"intel-vendor-bug" => "Intel GPU Bug",
|
||||
"loader-allocator" => "Loader Allocator",
|
||||
"audout" => "AudOut",
|
||||
"32-bit" => "32-bit Game",
|
||||
"UE4" => "Unreal Engine 4",
|
||||
"homebrew" => "Homebrew Content",
|
||||
"online-broken" => "Online Broken",
|
||||
_ => Capitalize(labelName)
|
||||
};
|
||||
|
||||
public static string Capitalize(string value)
|
||||
{
|
||||
if (value == string.Empty)
|
||||
return string.Empty;
|
||||
|
||||
var firstChar = value[0];
|
||||
var rest = value[1..];
|
||||
|
||||
return $"{char.ToUpper(firstChar)}{rest}";
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user