Files
sbox-public/engine/Sandbox.Engine/Systems/Input/Controller/Controller.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

139 lines
4.0 KiB
C#

using NativeEngine;
namespace Sandbox;
internal sealed partial class Controller
{
private Color[] ControllerColors = new[]
{
Color.Red,
Color.Green,
Color.Blue,
Color.White
};
[ConCmd( "controller_debug", ConVarFlags.Protected )]
public static void ControllerDebug()
{
Log.Info( "---------------------------------------------------------------------------" );
Log.Info( $"Detected {Controller.All.Count()} controllers" );
foreach ( var controller in Controller.All )
{
Log.Info( $" > {controller.ControllerType}, Handle: {controller.SDLHandle}, Device ID: {controller.DeviceId}" );
}
Log.Info( "---------------------------------------------------------------------------" );
}
public int SDLHandle { get; init; }
public int DeviceId { get; init; }
internal Controller( int joystickHandle, int deviceHandle )
{
SDLHandle = joystickHandle;
DeviceId = deviceHandle;
InputContext = Input.Context.Create( $"GameController:{SDLHandle}" );
ControllerType = NativeEngine.SDLGameController.GetControllerType( SDLHandle );
var id = joystickHandle % 4;
LEDColor = ControllerColors[id];
}
public override string ToString()
{
return $"{ControllerType} ({DeviceId})";
}
/// <summary>
/// Gets a sensor reading from the device's gyroscope (if it has one)
/// </summary>
public Angles Gyroscope
{
get
{
var vec = NativeEngine.SDLGameController.GetGyroscope( SDLHandle );
return new Angles( vec.x, vec.y, vec.z );
}
}
/// <summary>
/// Gets a sensor reading from the device's accelerometer (if it has one)
/// </summary>
public Vector3 Accelerometer => NativeEngine.SDLGameController.GetAccelerometer( SDLHandle );
private Color32 ledColor = Color.White;
/// <summary>
/// Sets the color of the gamepad if supported
/// </summary>
public Color32 LEDColor
{
get => ledColor;
set
{
if ( NativeEngine.SDLGameController.SetLEDColor( SDLHandle, value.r, value.g, value.b ) )
{
ledColor = value;
}
}
}
/// <summary>
/// What type of controller is this?
/// </summary>
public GameControllerType ControllerType { get; init; }
/// <summary>
/// Which glyph vendor are we using for this controller?
/// - default "The default vendor type, which uses Xbox glyphs"
/// - playstation
/// - switch
/// </summary>
public string GlyphVendor
{
get => ControllerType switch
{
>= GameControllerType.Xbox360 and <= GameControllerType.XboxOne => "xbox",
>= GameControllerType.PS3 and <= GameControllerType.PS4 => "playstation",
GameControllerType.PS5 => "playstation",
GameControllerType.SwitchPro => "switch",
_ => "xbox"
};
}
/// <summary>
/// Rumbles the controller.
/// </summary>
/// <param name="leftMotor">The speed of the left motor, between 0 and 0xFFFF</param>
/// <param name="rightMotor">The speed of the right motor, between 0 and 0xFFFF</param>
/// <param name="duration">The duration of the vibration in ms</param>
public void Rumble( int leftMotor, int rightMotor, int duration )
{
// Log.Trace( $"Trying to rumble {leftMotor}, {rightMotor}" );
NativeEngine.SDLGameController.Rumble( SDLHandle, leftMotor, rightMotor, duration );
}
/// <summary>
/// Rumbles the controller's triggers (if supported)
/// </summary>
/// <param name="leftTrigger">The speed of the left trigger motor, between 0 and 0xFFFF</param>
/// <param name="rightTrigger">The speed of the right trigger motor, between 0 and 0xFFFF</param>
/// <param name="duration">The duration of the vibration in ms</param>
public void RumbleTriggers( int leftTrigger, int rightTrigger, int duration )
{
// Log.Trace( $"Trying to rumble triggers {leftTrigger}, {rightTrigger}" );
NativeEngine.SDLGameController.RumbleTriggers( SDLHandle, leftTrigger, rightTrigger, duration );
}
/// <summary>
/// Stops all rumble and haptic events on this controller.
/// </summary>
public void StopAllHaptics()
{
// Calling with 0 intensity stops any rumbling
NativeEngine.SDLGameController.Rumble( SDLHandle, 0, 0, 0 );
NativeEngine.SDLGameController.RumbleTriggers( SDLHandle, 0, 0, 0 );
ActiveHapticEffect = null;
}
}