Skip to content

Commit d8859fc

Browse files
authored
Add SOCD modes (#4)
1 parent a5c7857 commit d8859fc

12 files changed

Lines changed: 258 additions & 43 deletions

File tree

InputDisplay.sln.DotSettings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RT/@EntryIndexedValue">RT</s:String>
1414
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
1515
<s:Boolean x:Key="/Default/UserDictionary/Words/=Interactable/@EntryIndexedValue">True</s:Boolean>
16+
<s:Boolean x:Key="/Default/UserDictionary/Words/=SOCD/@EntryIndexedValue">True</s:Boolean>
1617
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tekken/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

assets/img/config.png

5.02 KB
Loading

src/InputDisplay/Config/Settings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public record SelectedTheme(
3434
public bool InvertHistory { get; set; } = false;
3535
public bool FramesAfter { get; set; } = false;
3636
public bool HideButtonRelease { get; set; }
37+
public SOCDMode SOCD { get; set; } = SOCDMode.Neutral;
3738
public bool ShortcutsEnabled { get; set; } = true;
3839
public int IconSize { get; set; } = 40;
3940
public int SpaceBetweenInputs { get; set; } = 2;
@@ -100,6 +101,7 @@ public void CopyFrom(Settings config)
100101
InputMap = config.InputMap;
101102
DirectionSpace = config.DirectionSpace;
102103
AutoCorrectMultiple = config.AutoCorrectMultiple;
104+
SOCD = config.SOCD;
103105
InvertHistory = config.InvertHistory;
104106
FramesAfter = config.FramesAfter;
105107
EnabledDirections = config.EnabledDirections;

src/InputDisplay/Config/Window/SettingsControls.cs

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ void SetMacroButton(ButtonName name, (int Row, int Col) pos)
288288
}
289289
}
290290

291-
292291
Widget BuildThemes()
293292
{
294293
Grid grid = new()
@@ -440,11 +439,11 @@ Widget BuildThemes()
440439
{
441440
var newTheme = (string)btnCombo.SelectedItem.Tag;
442441

443-
444442
config.CurrentTheme = config.CurrentTheme with
445443
{
446444
Buttons = newTheme,
447445
};
446+
448447
SaveConfig();
449448
RebuildMacroButtons();
450449
};
@@ -456,7 +455,7 @@ Widget BuildSettings()
456455
{
457456
Grid grid = new()
458457
{
459-
Margin = new(20),
458+
Margin = new(20, 10, 20, 15),
460459
VerticalAlignment = VerticalAlignment.Center,
461460
ColumnSpacing = 8,
462461
RowSpacing = 4,
@@ -490,19 +489,12 @@ Widget BuildSettings()
490489
AddCheck(1, 3, "Use Shortcuts", config.ShortcutsEnabled, check => config.ShortcutsEnabled = check);
491490
CreateDirectionsSourceBox(1, 4, "Dir.Sources");
492491

493-
AddNumeric(2, 0, "Input space", config.SpaceBetweenInputs, v => config.SpaceBetweenInputs = v);
494-
AddNumeric(2, 1, "Command space", config.SpaceBetweenCommands, v => config.SpaceBetweenCommands = v);
495-
AddNumeric(2, 2, "Direction space", config.DirectionSpace, v => config.DirectionSpace = v);
496-
AddNumeric(2, 3, "Icon size", config.IconSize, v => config.IconSize = v);
497-
498-
var backgroundColor = ColorPicker("Background color", config.ClearColor, c =>
499-
{
500-
config.ClearColor = c;
501-
SaveConfig();
502-
});
503-
Grid.SetColumn(backgroundColor, 2);
504-
Grid.SetRow(backgroundColor, 4);
505-
grid.Widgets.Add(backgroundColor);
492+
AddEnumCombo(2, 0, "SOCD", config.SOCD, item => config.SOCD = item);
493+
AddNumeric(2, 1, "Input space", config.SpaceBetweenInputs, v => config.SpaceBetweenInputs = v);
494+
AddNumeric(2, 2, "Command space", config.SpaceBetweenCommands, v => config.SpaceBetweenCommands = v);
495+
AddNumeric(2, 3, "Direction space", config.DirectionSpace, v => config.DirectionSpace = v);
496+
AddNumeric(2, 4, "Icon size", config.IconSize, v => config.IconSize = v);
497+
AddColorPicker(2, 5, "Background color", config.ClearColor, c => config.ClearColor = c);
506498

507499
return grid;
508500

@@ -563,6 +555,80 @@ void AddNumeric(int col, int row, string labelText, int value, Action<int> onCha
563555
Grid.SetRow(chk, row);
564556
grid.Widgets.Add(chk);
565557
}
558+
559+
void AddEnumCombo<T>(int col, int row, string labelText, T value, Action<T> onChange) where T : struct, Enum
560+
{
561+
var panel = EnumComboView(value, labelText, onChange);
562+
Grid.SetColumn(panel, col);
563+
Grid.SetRow(panel, row);
564+
grid.Widgets.Add(panel);
565+
}
566+
567+
void AddColorPicker(int col, int row, string labelText, Color value, Action<Color> onChange)
568+
{
569+
var backgroundColor = ColorPicker(labelText.ToFieldLabel(), value, newColor =>
570+
{
571+
onChange(newColor);
572+
SaveConfig();
573+
});
574+
Grid.SetColumn(backgroundColor, col);
575+
Grid.SetRow(backgroundColor, row);
576+
577+
grid.Widgets.Add(backgroundColor);
578+
}
579+
}
580+
581+
HorizontalStackPanel EnumComboView<T>(T value, string labelText, Action<T> onChange) where T : struct, Enum
582+
{
583+
ComboView enumCombo = new()
584+
{
585+
VerticalAlignment = VerticalAlignment.Center,
586+
};
587+
588+
var enums = Enum.GetValues<T>();
589+
for (var index = 0; index < enums.Length; index++)
590+
{
591+
var enumValue = enums[index];
592+
593+
enumCombo.Widgets.Add(
594+
new Label
595+
{
596+
Text = enumValue.ToString(),
597+
Tag = enumValue,
598+
VerticalAlignment = VerticalAlignment.Center,
599+
Margin = new(5, 0),
600+
}
601+
);
602+
603+
if (enumValue.Equals(value))
604+
enumCombo.SelectedIndex = index;
605+
}
606+
607+
HorizontalStackPanel panel = new()
608+
{
609+
Padding = new(4),
610+
};
611+
612+
Label label = new()
613+
{
614+
Text = labelText.ToFieldLabel(),
615+
VerticalAlignment = VerticalAlignment.Center,
616+
Margin = new(0, 0, 5, 0),
617+
};
618+
619+
panel.Widgets.Add(label);
620+
621+
enumCombo.SelectedIndexChanged += (_, _) =>
622+
{
623+
if (enumCombo is not { SelectedItem.Tag: T newValue })
624+
return;
625+
626+
onChange(newValue);
627+
SaveConfig();
628+
};
629+
630+
panel.Widgets.Add(enumCombo);
631+
return panel;
566632
}
567633

568634
CheckButton InputCheck(string labelText, bool isChecked, Action<bool> onClick)
@@ -672,7 +738,7 @@ HorizontalStackPanel ColorPicker(string labelText, Color color, Action<Color> on
672738
Color = current,
673739
};
674740

675-
dialog.Closed += (s, a) =>
741+
dialog.Closed += (_, _) =>
676742
{
677743
if (!dialog.Result) return;
678744
image.Tag = dialog.Color;

src/InputDisplay/Config/Window/SettingsGame.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ protected override void Update(GameTime gameTime)
9191
}
9292

9393
player.Update();
94-
gameInput.Update(player, Config.InputMap, Config.EnabledDirections);
94+
gameInput.Update(player, Config);
9595

9696
if (controls.MappingButton is null)
9797
{

src/InputDisplay/Inputs/Drawable/InputBuffer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class InputBuffer(Settings config)
1111

1212
public void Update(PlayerPad pad)
1313
{
14-
gameInput.Update(pad, config.InputMap, config.EnabledDirections);
14+
gameInput.Update(pad, config);
1515
var controllerState = gameInput.CurrentState;
1616

1717
if (Last is { } last)

src/InputDisplay/Inputs/Drawable/InputEntry.cs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using InputDisplay.Config;
23
using InputDisplay.Themes;
34

@@ -13,10 +14,11 @@ public class InputEntry
1314

1415
public void IncrementFrame() => HoldingFrames = Math.Min(HoldingFrames + 1, MaxHoldingFrames);
1516

16-
readonly HashSet<ButtonName> holding = new();
17-
readonly HashSet<ButtonName> pressed = new();
18-
readonly HashSet<ButtonName> fallback = new();
19-
readonly SortedSet<ButtonName> currentButtons = new();
17+
readonly HashSet<ButtonName> holding = [];
18+
readonly HashSet<ButtonName> pressed = [];
19+
readonly HashSet<ButtonName> fallback = [];
20+
readonly SortedSet<ButtonName> currentButtons = [];
21+
2022

2123
public void Draw(
2224
Settings config,
@@ -66,15 +68,29 @@ void DrawDirection()
6668
return;
6769
}
6870

69-
var step = commandDir * (config.IconSize + config.SpaceBetweenInputs + config.DirectionSpace);
71+
var step = commandDir * (config.IconSize + config.SpaceBetweenInputs);
72+
7073
if (
71-
(
72-
(config.ShowNeutralIcon && State.Stick.Direction is Direction.Neutral)
73-
|| State.Stick.Direction is not Direction.Neutral
74-
)
75-
&& theme.GetTexture(State.Stick.Direction) is { } dirTexture
74+
(config.ShowNeutralIcon && State.Stick.Direction is Direction.Neutral)
75+
|| State.Stick.Direction is not Direction.Neutral
7676
)
7777
{
78+
if (SOCD.IsSingle(config.SOCD, State.Stick.Direction))
79+
DrawDirectionComponent(State.Stick.Direction);
80+
else
81+
{
82+
foreach (var stickDir in SOCD.GetComponents(config.SOCD, State.Stick))
83+
DrawDirectionComponent(stickDir);
84+
}
85+
86+
offset += commandDir * config.DirectionSpace;
87+
}
88+
89+
void DrawDirectionComponent(Direction stickDirection)
90+
{
91+
if (theme.GetTexture(stickDirection) is not { } dirTexture)
92+
return;
93+
7894
var dirColor = State.Stick.Holding && config.ShadowHolding ? Color.LightGray : Color.White;
7995
Rectangle dirRect = new(
8096
(int)offset.X, (int)offset.Y,
@@ -181,3 +197,13 @@ void CheckButton(GameInput.Button button, ButtonName name)
181197
}
182198
}
183199
}
200+
201+
sealed class TimeEntry<T>(T value) : IComparable<TimeEntry<T>>
202+
{
203+
public T Value { get; } = value;
204+
public long Time { get; set; }
205+
206+
public void Update() => Time = Stopwatch.GetTimestamp();
207+
208+
public int CompareTo(TimeEntry<T>? other) => Time.CompareTo(other?.Time);
209+
}

src/InputDisplay/Inputs/GameInput.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ public readonly record struct Button(ButtonStatus Status)
3232
);
3333
}
3434

35-
public record struct Stick(Direction Direction, bool Holding);
35+
public record struct Stick(
36+
Direction Direction,
37+
Direction Raw,
38+
bool Holding
39+
);
3640

3741
public record struct State
3842
{
@@ -169,11 +173,12 @@ void UpdateButton(GamePadState state, Buttons padButton, ref Button button)
169173
}
170174
}
171175

172-
public void UpdateDirections(GamePadState state, Settings.DirectionSources sources)
176+
public void UpdateDirections(GamePadState state, SOCDMode socd, Settings.DirectionSources sources)
173177
{
174178
if (sources is Settings.DirectionSources.None)
175179
{
176180
currentState.Stick.Direction = Direction.Neutral;
181+
currentState.Stick.Raw = Direction.Neutral;
177182
currentState.Stick.Holding = false;
178183
return;
179184
}
@@ -209,21 +214,20 @@ public void UpdateDirections(GamePadState state, Settings.DirectionSources sourc
209214
state.IsButtonDown(Buttons.RightThumbstickRight)))
210215
direction |= Direction.Forward;
211216

212-
currentState.Stick.Holding = currentState.Stick.Direction == direction
213-
&& direction != Direction.Neutral;
214-
currentState.Stick.Direction = direction;
217+
currentState.Stick.Holding = currentState.Stick.Raw == direction && direction != Direction.Neutral;
218+
currentState.Stick.Direction = SOCD.Clean(socd, direction, currentState.Stick);
219+
currentState.Stick.Raw = direction;
215220
}
216221

217222
public void Update(
218223
PlayerPad pad,
219-
InputMap mapper,
220-
Settings.DirectionSources directionSources = Settings.DirectionSources.Default
224+
Settings config
221225
)
222226
{
223227
var state = pad.State;
224-
UpdateDirections(state, directionSources);
228+
UpdateDirections(state, config.SOCD, config.EnabledDirections);
225229

226-
var map = mapper.GetMappingOrDefault(pad.Identifier);
230+
var map = config.InputMap.GetMappingOrDefault(pad.Identifier);
227231
UpdateButton(state, map.LP, ref currentState.LP);
228232
UpdateButton(state, map.MP, ref currentState.MP);
229233
UpdateButton(state, map.HP, ref currentState.HP);

0 commit comments

Comments
 (0)