Skip to content

Commit c74931f

Browse files
Fix unexpected behavior when Ryujinx input configs were not ordered by player index
1 parent 254f035 commit c74931f

File tree

7 files changed

+80
-34
lines changed

7 files changed

+80
-34
lines changed

JoystickHelper/JoystickHelper.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<OutputType>Exe</OutputType>
8+
<AssemblyVersion>1.0.1</AssemblyVersion>
89
</PropertyGroup>
910

1011
<ItemGroup>

JoystickHelper/JoystickInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
public class JoystickInfo
44
{
55
public Guid SdlJoystickGuid { get; set; }
6+
public int SdlDeviceIndex { get; internal set; }
67

78
public override string ToString()
89
{
9-
return SdlJoystickGuid.ToString();
10+
return SdlDeviceIndex + "-" + SdlJoystickGuid.ToString();
1011
}
1112
}

JoystickHelper/Program.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ private static int RunConfigureRyujinx(ConfigureRyujinxOptions opts)
4040
var configJson = File.ReadAllText(context.ConfigPath);
4141
var joysticks = SdlHelper.GetConnectedJoysticks();
4242
var setResult = RyujinxConfigHelper.SetJoystickGuids(joysticks, configJson);
43-
File.WriteAllText(context.ConfigPath, setResult.ModifiedConfigJson);
44-
File.WriteAllText(context.LastSettingsPath, JsonSerializer.Serialize(new RyujinxLastSettings(setResult.SwappedJoysticks)));
43+
if (!String.IsNullOrEmpty(setResult.ModifiedConfigJson))
44+
{
45+
File.WriteAllText(context.ConfigPath, setResult.ModifiedConfigJson);
46+
File.WriteAllText(context.LastSettingsPath, JsonSerializer.Serialize(new RyujinxLastSettings(setResult.SwappedJoysticks)));
47+
48+
Log.Information("Ryujinx config file updated");
49+
}
4550
return 0;
4651
}
4752
catch (Exception ex)
@@ -65,7 +70,12 @@ private static int RunRevertRyujinx(RevertRyujinxOptions opts)
6570
var configJson = File.ReadAllText(context.ConfigPath);
6671
var joysticks = context.GetLastSettings().GetJoystickInfos();
6772
var setResult = RyujinxConfigHelper.SetJoystickGuids(joysticks, configJson);
68-
File.WriteAllText(context.ConfigPath, setResult.ModifiedConfigJson);
73+
if (!String.IsNullOrEmpty(setResult.ModifiedConfigJson))
74+
{
75+
File.WriteAllText(context.ConfigPath, setResult.ModifiedConfigJson);
76+
77+
Log.Information("Ryujinx config file updated");
78+
}
6979
return 0;
7080
}
7181
catch (Exception ex)

JoystickHelper/Ryujinx/RyujinxConfigHelper.cs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,53 +32,73 @@ public static SetJoysticksResult SetJoystickGuids(IList<JoystickInfo> joysticks,
3232
throw new InvalidRyujinxConfigException("Failed to deserialize the Ryujinx config json", ex);
3333
}
3434

35-
Log.Information("Found {count} input configs in Ryujinx config file", inputConfigs.Count);
35+
var inputConfigsToProcess = inputConfigs
36+
.Where(c => c["backend"]?.ToString() == "GamepadSDL2")
37+
.OrderBy(c => ParsePlayerIndex(c["player_index"]?.ToString()))
38+
.ToList();
3639

37-
for (int i = 0; i < inputConfigs.Count; i++)
40+
if (inputConfigsToProcess.Count == 0)
3841
{
39-
var inputConfig = inputConfigs[i];
40-
if (joysticks.Count - 1 >= i)
42+
Log.Warning("No inputs configured with GamepadSDL2 backend type were found in Ryujinx");
43+
return result;
44+
}
45+
46+
Log.Information("Found {count} SDL2 inputs configured in Ryujinx", inputConfigsToProcess.Count);
47+
48+
var inputConfigModified = false;
49+
50+
for (var i = 0; i < inputConfigsToProcess.Count; i++)
51+
{
52+
var inputConfig = inputConfigsToProcess[i];
53+
var playerIndex = inputConfig["player_index"]?.ToString();
54+
55+
if (i > joysticks.Count - 1)
4156
{
42-
var oldId = inputConfig["id"]?.ToString();
43-
var newId = $"{i}-{joysticks[i].SdlJoystickGuid}";
57+
Log.Information("No connected joystick available to swap for {playerIndex}", playerIndex);
58+
continue;
59+
}
4460

45-
if (newId != oldId)
46-
{
47-
inputConfig["id"] = newId;
61+
var oldId = inputConfig["id"]?.ToString();
62+
var newId = $"{joysticks[i].SdlDeviceIndex}-{joysticks[i].SdlJoystickGuid}";
4863

49-
if (IsValidRyujinxInputDeviceId(oldId))
50-
{
51-
result.SwappedJoysticks.Add(new SwappedJoystickResult { InputIndex = i, OldInputId = ConvertRyujinxInputDeviceIdToGuid(oldId) });
52-
}
64+
if (newId != oldId)
65+
{
66+
inputConfig["id"] = newId;
67+
inputConfigModified = true;
5368

54-
Log.Information("Swapped input #{index}: {oldId} >> {newId}", i, oldId, newId);
55-
}
56-
else
69+
if (IsValidRyujinxInputDeviceId(oldId))
5770
{
58-
Log.Information("No change needed for input #{index} ({oldId})", i, oldId);
71+
result.SwappedJoysticks.Add(new SwappedJoystickResult { OldRyujinxDeviceId = oldId });
5972
}
73+
74+
Log.Information("Swapped input {playerIndex}: {oldId} >> {newId}", playerIndex, oldId, newId);
6075
}
6176
else
6277
{
63-
Log.Information("No connected joystick available to swap for input #{index}", i);
78+
Log.Information("No change needed for input {playerIndex} ({oldId})", playerIndex, oldId);
6479
}
6580
}
6681

67-
result.ModifiedConfigJson = JsonConvert.SerializeObject(configData, Formatting.Indented);
82+
if (inputConfigModified)
83+
{
84+
result.ModifiedConfigJson = JsonConvert.SerializeObject(configData, Formatting.Indented);
85+
}
6886

6987
return result;
7088
}
7189

72-
public static bool IsValidRyujinxInputDeviceId(string? deviceId)
90+
private static int ParsePlayerIndex(string? jsonValue)
7391
{
74-
return deviceId != null && Regex.IsMatch(deviceId, @"\d-.+");
92+
if (String.IsNullOrEmpty(jsonValue) || !Regex.IsMatch(jsonValue, @"Player\d"))
93+
{
94+
throw new Exception($"PlayerIndex value did not match expected pattern: {jsonValue}");
95+
}
96+
97+
return int.Parse(Regex.Match(jsonValue, @"Player(\d)").Groups[1].Value);
7598
}
7699

77-
public static Guid ConvertRyujinxInputDeviceIdToGuid(string value)
100+
public static bool IsValidRyujinxInputDeviceId(string? deviceId)
78101
{
79-
if (!RyujinxConfigHelper.IsValidRyujinxInputDeviceId(value))
80-
throw new ArgumentException($"OldRyujinxInputId is not in the expected format: {value}");
81-
82-
return Guid.Parse(value.Substring(2));
102+
return deviceId != null && Regex.IsMatch(deviceId, @"\d-.+");
83103
}
84104
}

JoystickHelper/Ryujinx/RyujinxLastSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ public RyujinxLastSettings(List<SwappedJoystickResult>? swappedJoysticks = null)
1111

1212
internal IList<JoystickInfo> GetJoystickInfos()
1313
{
14-
return SwappedJoysticks.Select(j => new JoystickInfo { SdlJoystickGuid = j.OldInputId }).ToList();
14+
return SwappedJoysticks.Select(j => j.ToJoystickInfo()).Where(j => j != null).ToList();
1515
}
1616
}

JoystickHelper/Ryujinx/SetJoysticksResult.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,21 @@ public class SetJoysticksResult
1010

1111
public class SwappedJoystickResult
1212
{
13-
public int InputIndex { get; internal set; }
14-
public Guid OldInputId { get; set; }
13+
public string OldRyujinxDeviceId { get; set; }
14+
15+
public JoystickInfo ToJoystickInfo()
16+
{
17+
var match = Regex.Match(OldRyujinxDeviceId, @"(?<index>\d)-(?<guid>.+)");
18+
if (!match.Success)
19+
{
20+
return null;
21+
}
22+
23+
return new JoystickInfo
24+
{
25+
SdlJoystickGuid = Guid.Parse(match.Groups["guid"].Value),
26+
SdlDeviceIndex = int.Parse(match.Groups["index"].Value)
27+
};
28+
}
1529
}
1630
}

JoystickHelper/SdlHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static IList<JoystickInfo> GetConnectedJoysticks(int maxJoysticks = 4)
2828
}
2929
else
3030
{
31-
joysticks.Add(new JoystickInfo { SdlJoystickGuid = SDL.SDL_JoystickGetGUID(joystick) });
31+
joysticks.Add(new JoystickInfo { SdlJoystickGuid = SDL.SDL_JoystickGetGUID(joystick), SdlDeviceIndex = i });
3232
}
3333
}
3434

0 commit comments

Comments
 (0)