diff --git a/Framework/Input/Controller.cs b/Framework/Input/Controller.cs
index 2657c9e..79bf933 100644
--- a/Framework/Input/Controller.cs
+++ b/Framework/Input/Controller.cs
@@ -27,6 +27,39 @@ public class Controller
///
public bool IsGamepad { get; private set; } = false;
+ ///
+ /// The Type of Gamepad
+ ///
+ public GamepadTypes GamepadType { get; private set; } = GamepadTypes.Unknown;
+
+ ///
+ /// The Gamepad Provider
+ ///
+ public GamepadProviders GamepadProvider => GamepadType switch
+ {
+ GamepadTypes.Unknown => GamepadProviders.Unknown,
+ GamepadTypes.Xbox360 => GamepadProviders.Xbox,
+ GamepadTypes.XboxOne => GamepadProviders.Xbox,
+ GamepadTypes.PS3 => GamepadProviders.PlayStation,
+ GamepadTypes.PS4 => GamepadProviders.PlayStation,
+ GamepadTypes.NintendoSwitchPro => GamepadProviders.Nintendo,
+ GamepadTypes.Virtual => GamepadProviders.Unknown,
+ GamepadTypes.PS5 => GamepadProviders.PlayStation,
+ GamepadTypes.AmazonLuna => GamepadProviders.Unknown,
+ GamepadTypes.GoogleStadia => GamepadProviders.Unknown,
+ GamepadTypes.NVidiaShield => GamepadProviders.Unknown,
+ GamepadTypes.NintendoSwitchJoyconLeft => GamepadProviders.Nintendo,
+ GamepadTypes.NintendoSwitchJoyconRight => GamepadProviders.Nintendo,
+ GamepadTypes.NintendoSwitchJoyconPair => GamepadProviders.Nintendo,
+ _ => GamepadProviders.Unknown
+ };
+
+ ///
+ /// The Gamepad type, if known.
+ ///
+ [Obsolete("Use GamepadType or GamepadProvider instead")]
+ public Gamepads Gamepad => Gamepads.Xbox;
+
///
/// Number of Buttons
///
@@ -59,12 +92,13 @@ public class Controller
internal readonly float[] axis = new float[MaxAxis];
internal readonly TimeSpan[] axisTimestamp = new TimeSpan[MaxAxis];
- internal void Connect(string name, int buttonCount, int axisCount, bool isGamepad, ushort vendor, ushort product, ushort version)
+ internal void Connect(string name, int buttonCount, int axisCount, bool isGamepad, GamepadTypes type, ushort vendor, ushort product, ushort version)
{
Name = name;
Buttons = Math.Min(buttonCount, MaxButtons);
Axes = Math.Min(axisCount, MaxAxis);
IsGamepad = isGamepad;
+ GamepadType = type;
Connected = true;
Vendor = vendor;
Product = product;
@@ -76,6 +110,7 @@ internal void Disconnect()
Name = "Unknown";
Connected = false;
IsGamepad = false;
+ GamepadType = GamepadTypes.Unknown;
Buttons = 0;
Axes = 0;
Vendor = 0;
@@ -115,30 +150,6 @@ internal void Copy(Controller other)
Array.Copy(other.axisTimestamp, 0, axisTimestamp, 0, axis.Length);
}
- ///
- /// The Gamepad type, if known.
- ///
- public Gamepads Gamepad
- {
- get
- {
- var vendor = ((Vendor >> 8) & 0x00FF) | ((Vendor << 8) & 0xFF00);
- var product = ((Product >> 8) & 0x00FF) | ((Product << 8) & 0xFF00);
- var id = (vendor << 16) | product;
-
- if (id == 0x4c05c405 || id == 0x4c05cc09)
- return Gamepads.DualShock4;
-
- if (id == 0x4c05e60c)
- return Gamepads.DualSense;
-
- if (id == 0x7e050920 || id == 0x7e053003)
- return Gamepads.Nintendo;
-
- return Gamepads.Xbox;
- }
- }
-
public bool Pressed(int buttonIndex) => buttonIndex >= 0 && buttonIndex < MaxButtons && pressed[buttonIndex];
public bool Pressed(Buttons button) => Pressed((int)button);
diff --git a/Framework/Input/GamepadTypes.cs b/Framework/Input/GamepadTypes.cs
new file mode 100644
index 0000000..f837b0c
--- /dev/null
+++ b/Framework/Input/GamepadTypes.cs
@@ -0,0 +1,47 @@
+namespace Foster.Framework;
+
+///
+/// Type of Gamepads
+/// This is a 1-1 mapping with SDL_GameControllerType:
+/// https://github.com/libsdl-org/SDL/blob/release-2.30.x/include/SDL_gamecontroller.h#L61
+///
+public enum GamepadTypes
+{
+ Unknown = 0,
+ Xbox360,
+ XboxOne,
+ PS3,
+ PS4,
+ NintendoSwitchPro,
+ Virtual,
+ PS5,
+ AmazonLuna,
+ GoogleStadia,
+ NVidiaShield,
+ NintendoSwitchJoyconLeft,
+ NintendoSwitchJoyconRight,
+ NintendoSwitchJoyconPair,
+}
+
+///
+/// Types of GamePad Providers
+///
+public enum GamepadProviders
+{
+ Unknown,
+ Xbox,
+ PlayStation,
+ Nintendo
+}
+
+///
+/// Known popular gamepad types
+///
+[Obsolete("Use GamepadTypes or GamepadProviders instead")]
+public enum Gamepads
+{
+ Xbox,
+ DualShock4,
+ DualSense,
+ Nintendo
+}
\ No newline at end of file
diff --git a/Framework/Input/Gamepads.cs b/Framework/Input/Gamepads.cs
deleted file mode 100644
index 28f816c..0000000
--- a/Framework/Input/Gamepads.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Foster.Framework;
-
-///
-/// Known popular gamepad types
-///
-public enum Gamepads
-{
- Xbox,
- DualShock4,
- DualSense,
- Nintendo
-}
diff --git a/Framework/Input/Input.cs b/Framework/Input/Input.cs
index 4e78f49..201c83a 100644
--- a/Framework/Input/Input.cs
+++ b/Framework/Input/Input.cs
@@ -219,6 +219,7 @@ internal static unsafe void OnFosterEvent(in Platform.FosterEvent ev)
ev.Controller.ButtonCount,
ev.Controller.AxisCount,
ev.Controller.IsGamepad != 0,
+ ev.Controller.GamepadType,
ev.Controller.Vendor,
ev.Controller.Product,
ev.Controller.Version
diff --git a/Framework/Platform.cs b/Framework/Platform.cs
index 4611432..2a86594 100644
--- a/Framework/Platform.cs
+++ b/Framework/Platform.cs
@@ -80,6 +80,7 @@ public struct ControllerEvent
public int ButtonCount;
public int AxisCount;
public byte IsGamepad;
+ public GamepadTypes GamepadType;
public ushort Vendor;
public ushort Product;
public ushort Version;
diff --git a/Platform/include/foster_platform.h b/Platform/include/foster_platform.h
index 69bb6c2..313af09 100644
--- a/Platform/include/foster_platform.h
+++ b/Platform/include/foster_platform.h
@@ -262,6 +262,26 @@ typedef enum FosterAxis
FOSTER_AXIS_RIGHT_TRIGGER = 5
} FosterAxis;
+// intentionally a 1-1 mapping with SDL's SDL_GameControllerType:
+// https://github.com/libsdl-org/SDL/blob/release-2.30.x/include/SDL_gamecontroller.h#L61
+typedef enum FosterGamepadTypes
+{
+ FOSTER_GAMEPAD_TYPE_UNKNOWN = 0,
+ FOSTER_GAMEPAD_TYPE_XBOX360,
+ FOSTER_GAMEPAD_TYPE_XBOXONE,
+ FOSTER_GAMEPAD_TYPE_PS3,
+ FOSTER_GAMEPAD_TYPE_PS4,
+ FOSTER_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO,
+ FOSTER_GAMEPAD_TYPE_VIRTUAL,
+ FOSTER_GAMEPAD_TYPE_PS5,
+ FOSTER_GAMEPAD_TYPE_AMAZON_LUNA,
+ FOSTER_GAMEPAD_TYPE_GOOGLE_STADIA,
+ FOSTER_GAMEPAD_TYPE_NVIDIA_SHIELD,
+ FOSTER_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT,
+ FOSTER_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT,
+ FOSTER_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR,
+} FosterGamepadTypes;
+
typedef enum FosterCompare
{
FOSTER_COMPARE_NONE,
@@ -469,6 +489,7 @@ typedef union FosterEvent
int buttonCount;
int axisCount;
FosterBool isGamepad;
+ FosterGamepadTypes gamepadType;
uint16_t vendor;
uint16_t product;
uint16_t version;
diff --git a/Platform/libs/lib64/libFosterPlatform.so b/Platform/libs/lib64/libFosterPlatform.so
index 1c0ca16..721d228 100755
Binary files a/Platform/libs/lib64/libFosterPlatform.so and b/Platform/libs/lib64/libFosterPlatform.so differ
diff --git a/Platform/src/foster_platform.c b/Platform/src/foster_platform.c
index db2d732..92cc833 100644
--- a/Platform/src/foster_platform.c
+++ b/Platform/src/foster_platform.c
@@ -236,6 +236,7 @@ FosterBool FosterPollEvents(FosterEvent* output)
output->controller.index = index;
output->controller.name = SDL_JoystickName(ptr);
output->controller.isGamepad = 0;
+ output->controller.gamepadType = FOSTER_GAMEPAD_TYPE_UNKNOWN;
output->controller.buttonCount = SDL_JoystickNumButtons(ptr);
output->controller.axisCount = SDL_JoystickNumAxes(ptr);
output->controller.vendor = SDL_JoystickGetVendor(ptr);
@@ -291,6 +292,7 @@ FosterBool FosterPollEvents(FosterEvent* output)
output->controller.buttonCount = 15;
output->controller.axisCount = 6;
output->controller.isGamepad = 1;
+ output->controller.gamepadType = (FosterGamepadTypes)SDL_GameControllerGetType(ptr);
output->controller.vendor = SDL_GameControllerGetVendor(ptr);
output->controller.product = SDL_GameControllerGetProduct(ptr);
output->controller.version = SDL_GameControllerGetProductVersion(ptr);