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);