Last active
October 2, 2025 17:13
-
-
Save lucasteles/ce2bff2ceebae2f96247fd9bd6ad0ba2 to your computer and use it in GitHub Desktop.
C# Enum player input viewer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Flags] | |
public enum PlayerInput : ushort | |
{ | |
None = 0, | |
Up = 1 << 0, | |
Down = 1 << 1, | |
Left = 1 << 2, | |
Right = 1 << 3, | |
UpLeft = Up | Left, | |
UpRight = Up | Right, | |
DownLeft = Down | Left, | |
DownRight = Down | Right, | |
P1 = 1 << 4, | |
P2 = 1 << 5, | |
P3 = 1 << 6, | |
K1 = 1 << 7, | |
K2 = 1 << 8, | |
K3 = 1 << 9, | |
Macro1 = 1 << 10, | |
Macro2 = 1 << 11, | |
Select = 1 << 13, | |
Start = 1 << 14, | |
} | |
public static class PlayerInputExtensions | |
{ | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static PlayerInput Set(this PlayerInput flags, in PlayerInput flag, bool value) => | |
value ? flags | flag : flags & ~flag; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static PlayerInput Unflag(this PlayerInput flags, in PlayerInput flag) => | |
flags.Set(in flag, false); | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static PlayerInput Flag(this PlayerInput flags, in PlayerInput flag) => | |
flags.Set(in flag, true); | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static bool HasAll(this PlayerInput pressed, in PlayerInput input) => (pressed & input) == input; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static bool HasAny(this PlayerInput pressed, in PlayerInput input) => (pressed & input) is not PlayerInput.None; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Text; | |
public class PlayerInputView(PlayerInput input = PlayerInput.None) | |
{ | |
public PlayerInput Input = input; | |
public void Reset() => Input = PlayerInput.None; | |
public bool IsEmpty => Input is PlayerInput.None; | |
public static implicit operator PlayerInput(PlayerInputView @this) => @this.Input; | |
public static implicit operator PlayerInputView(PlayerInput padButtons) => new(padButtons); | |
public bool Up | |
{ | |
get => Input.HasAll(PlayerInput.Up); | |
set => Input = Input.Set(PlayerInput.Up, value); | |
} | |
public bool Down | |
{ | |
get => Input.HasAll(PlayerInput.Down); | |
set => Input = Input.Set(PlayerInput.Down, value); | |
} | |
public bool Left | |
{ | |
get => Input.HasAll(PlayerInput.Left); | |
set => Input = Input.Set(PlayerInput.Left, value); | |
} | |
public bool Right | |
{ | |
get => Input.HasAll(PlayerInput.Right); | |
set => Input = Input.Set(PlayerInput.Right, value); | |
} | |
public bool LP | |
{ | |
get => Input.HasAll(PlayerInput.P1); | |
set => Input = Input.Set(PlayerInput.P1, value); | |
} | |
public bool MP | |
{ | |
get => Input.HasAll(PlayerInput.P2); | |
set => Input = Input.Set(PlayerInput.P2, value); | |
} | |
public bool HP | |
{ | |
get => Input.HasAll(PlayerInput.P3); | |
set => Input = Input.Set(PlayerInput.P3, value); | |
} | |
public bool LK | |
{ | |
get => Input.HasAll(PlayerInput.K1); | |
set => Input = Input.Set(PlayerInput.K1, value); | |
} | |
public bool MK | |
{ | |
get => Input.HasAll(PlayerInput.K2); | |
set => Input = Input.Set(PlayerInput.K2, value); | |
} | |
public bool HK | |
{ | |
get => Input.HasAll(PlayerInput.K3); | |
set => Input = Input.Set(PlayerInput.K3, value); | |
} | |
public bool Macro1 | |
{ | |
get => Input.HasAll(PlayerInput.Macro1); | |
set => Input = Input.Set(PlayerInput.Macro1, value); | |
} | |
public bool Macro2 | |
{ | |
get => Input.HasAll(PlayerInput.Macro2); | |
set => Input = Input.Set(PlayerInput.Macro2, value); | |
} | |
public bool Select | |
{ | |
get => Input.HasAll(PlayerInput.Select); | |
set => Input = Input.Set(PlayerInput.Select, value); | |
} | |
public bool Start | |
{ | |
get => Input.HasAll(PlayerInput.Start); | |
set => Input = Input.Set(PlayerInput.Start, value); | |
} | |
public bool UpLeft | |
{ | |
get => Input.HasAll(PlayerInput.UpLeft); | |
set => Input = Input.Set(PlayerInput.UpLeft, value); | |
} | |
public bool UpRight | |
{ | |
get => Input.HasAll(PlayerInput.UpRight); | |
set => Input = Input.Set(PlayerInput.UpRight, value); | |
} | |
public bool DownLeft | |
{ | |
get => Input.HasAll(PlayerInput.DownLeft); | |
set => Input = Input.Set(PlayerInput.DownLeft, value); | |
} | |
public bool DownRight | |
{ | |
get => Input.HasAll(PlayerInput.DownRight); | |
set => Input = Input.Set(PlayerInput.DownRight, value); | |
} | |
const char Sep = ' '; | |
public void Append(StringBuilder builder) | |
{ | |
AppendDir(builder); | |
builder.Append(Sep); | |
AppendButton(builder); | |
} | |
public void AppendInverted(StringBuilder builder) | |
{ | |
AppendButton(builder); | |
builder.Append(Sep); | |
AppendDir(builder); | |
} | |
void AppendButton(StringBuilder builder) | |
{ | |
if (LP) | |
{ | |
builder.Append(nameof(LP)); | |
builder.Append(Sep); | |
} | |
if (MP) | |
{ | |
builder.Append(nameof(MP)); | |
builder.Append(Sep); | |
} | |
if (HP) | |
{ | |
builder.Append(nameof(HP)); | |
builder.Append(Sep); | |
} | |
if (LK) | |
{ | |
builder.Append(nameof(LK)); | |
builder.Append(Sep); | |
} | |
if (MK) | |
{ | |
builder.Append(nameof(MK)); | |
builder.Append(Sep); | |
} | |
if (HK) | |
{ | |
builder.Append(nameof(HK)); | |
builder.Append(Sep); | |
} | |
if (Macro1) | |
{ | |
builder.Append(PlayerInput.Macro1); | |
builder.Append(Sep); | |
} | |
if (Macro1) | |
{ | |
builder.Append(PlayerInput.Macro2); | |
builder.Append(Sep); | |
} | |
if (Start) | |
{ | |
builder.Append(nameof(Start)); | |
builder.Append(Sep); | |
} | |
if (Select) | |
{ | |
builder.Append(nameof(Select)); | |
builder.Append(Sep); | |
} | |
} | |
void AppendDir(StringBuilder builder) | |
{ | |
Span<char> dpad = stackalloc char[4]; | |
if (Left) dpad[0] = '←'; | |
if (Up) dpad[1] = '↑'; | |
if (Down) dpad[2] = '↓'; | |
if (Right) dpad[3] = '→'; | |
var dir = dpad switch | |
{ | |
['\0', '↑', '\0', '→'] => '↗', | |
['←', '↑', '\0', '\0'] => '↖', | |
['←', '\0', '↓', '\0'] => '↙', | |
['\0', '\0', '↓', '→'] => '↘', | |
['\0', '\0', '\0', '\0'] => 'N', | |
_ => '\0', | |
}; | |
if (dir != '\0') | |
builder.Append(dir); | |
else | |
for (var i = 0; i < dpad.Length; i++) | |
{ | |
dir = dpad[i]; | |
if (dir != '\0') | |
builder.Append(dir); | |
} | |
} | |
public string ToString(bool inverted) | |
{ | |
StringBuilder builder = new(); | |
if (inverted) | |
AppendInverted(builder); | |
else | |
Append(builder); | |
return builder.ToString(); | |
} | |
public override string ToString() => ToString(false); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment