Skip to content

Commit

Permalink
Merge pull request #248 from RiddleTime/dev
Browse files Browse the repository at this point in the history
2.2.4.2
Race Element:
- Fixed crash when ACC Liveries were not installed.

iRacing:
- Lap Delta Bar HUD is enabled again.
  • Loading branch information
RiddleTime authored Jan 29, 2025
2 parents 34ffa74 + 3f4bbdf commit 9b70c5d
Show file tree
Hide file tree
Showing 28 changed files with 1,892 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ public struct StructVector3
public float Y;
public float Z;

public override string ToString() => $"X: {X}, Y: {Y}, Z: {Z}";
public override readonly string ToString() => $"X: {X}, Y: {Y}, Z: {Z}";
}

/// <summary>The following members change at each graphic step. They all refer to the player’s car</summary>
Expand Down
1 change: 1 addition & 0 deletions Race Element.Data/Games/iRacing/IRacingDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ private void OnTelemetryData()


SessionData.Instance.LapDeltaToSessionBestLapMs = _iRacingSDK.Data.GetFloat(lapDeltaToSessionBestLapDatum);
localCar.Timing.LapTimeDeltaBestMS = (int)(SessionData.Instance.LapDeltaToSessionBestLapMs * 1000.0);

SessionData.Instance.Weather.AirTemperature = _iRacingSDK.Data.GetFloat(airTempDatum);
SessionData.Instance.Weather.AirVelocity = _iRacingSDK.Data.GetFloat(windVelDatum) * 3.6f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace RaceElement.HUD.Common.Overlays.Driving.LapDeltaBar;
Version = 1,
OverlayType = OverlayType.Drive,
OverlayCategory = OverlayCategory.Lap,
Game = Game.RaceRoom,
Game = Game.RaceRoom | Game.iRacing,
Authors = ["Reinier Klarenberg", "Dirk Wolf"])]
internal sealed class LapDeltaOverlay : CommonAbstractOverlay
{
Expand Down
5 changes: 1 addition & 4 deletions Race Element.HUD.Common/Overlays/Pitwall/DSX/DsxOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ internal sealed class DsxOverlay : CommonAbstractOverlay

internal UdpClient _client;
internal IPEndPoint _endPoint;
private DateTime _timeSent;

public DsxOverlay(Rectangle rectangle) : base(rectangle, "DSX")
{
Expand Down Expand Up @@ -86,7 +85,6 @@ internal void Send(DsxPacket data)

var requestData = Encoding.ASCII.GetBytes(packet);
_client?.Send(requestData, requestData.Length, _endPoint);
_timeSent = DateTime.Now;
}

private ServerResponse? Receive()
Expand All @@ -109,9 +107,8 @@ private void HandleResponse(ServerResponse response)
Debug.WriteLine("===================================================================");

Debug.WriteLine($"Status: {response.Status}");
TimeSpan Timespan = DateTime.Now - _timeSent;
// First send shows high Milliseconds response time for some reason
Debug.WriteLine($"Time Received: {response.TimeReceived}, took: {Timespan.TotalMilliseconds} to receive response from DSX");
//Debug.WriteLine($"Time Received: {response.TimeReceived}, took: {Timespan.TotalMilliseconds} to receive response from DSX");
Debug.WriteLine($"isControllerConnected: {response.isControllerConnected}");
Debug.WriteLine($"BatteryLevel: {response.BatteryLevel}");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using static RaceElement.HUD.Common.Overlays.Pitwall.DSX.Resources;

using static RaceElement.HUD.Common.Overlays.Pitwall.DSX.Resources;

namespace RaceElement.HUD.Common.Overlays.Pitwall.DSX;
internal static class DsxPacketExtensions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using RaceElement.HUD.Overlay.Configuration;

namespace RaceElement.HUD.Common.Overlays.Pitwall.DualSenseInternal;

internal sealed class DsiConfiguration : OverlayConfiguration
{
public DsiConfiguration()
{
GenericConfiguration.AlwaysOnTop = false;
GenericConfiguration.Window = false;
GenericConfiguration.Opacity = 1.0f;
GenericConfiguration.AllowRescale = false;
}


[ConfigGrouping("Brake Slip", "Adjust the slip effect whilst applying the brakes.")]
public BrakeSlipHaptics BrakeSlip { get; init; } = new();
public sealed class BrakeSlipHaptics
{
/// <summary>
/// The brake in percentage (divide by 100f if you want 0-1 value)
/// </summary>
[ToolTip("The minimum brake percentage before any effects are applied. See this like a deadzone.")]
[FloatRange(0.1f, 99f, 0.1f, 1)]
public float BrakeThreshold { get; init; } = 3f;

[FloatRange(0.05f, 6f, 0.002f, 3)]
public float FrontSlipThreshold { get; init; } = 0.25f;

[FloatRange(0.05f, 6f, 0.002f, 3)]
public float RearSlipThreshold { get; init; } = 0.25f;

[ToolTip("Higher is stronger dynamic feedback.")]
[IntRange(5, 8, 1)]
public int FeedbackStrength { get; init; } = 7;

[ToolTip("Sets the min frequency of the vibration effect in the trigger.")]
[IntRange(1, 10, 1)]
public int MinFrequency { get; init; } = 3;

[ToolTip("Sets the max frequency of the vibration effect in the trigger.")]
[IntRange(20, 150, 1)]
public int MaxFrequency { get; init; } = 85;

[ToolTip("Change the amplitude(strength) of the vibration effect in the trigger.")]
[IntRange(5, 8, 1)]
public int Amplitude { get; init; } = 8;
}

[ConfigGrouping("Throttle Slip", "Adjust the slip effect whilst applying the throttle.\nModify the threshold to increase or decrease sensitivity in different situations.")]
public ThrottleSlipHaptics ThrottleSlip { get; init; } = new();
public sealed class ThrottleSlipHaptics
{
/// <summary>
/// The throttle in percentage (divide by 100f if you want 0-1 value)
/// </summary>
[ToolTip("The minimum throttle percentage before any effects are applied. See this like a deadzone.")]
[FloatRange(0.1f, 99f, 0.1f, 1)]
public float ThrottleThreshold { get; init; } = 3f;

[ToolTip("Decrease this treshold to increase the sensitivity when the front wheels slip (understeer).")]
[FloatRange(0.05f, 6f, 0.002f, 3)]
public float FrontSlipThreshold { get; init; } = 0.35f;

[ToolTip("Decrease this treshold to increase the sensitivity when the rear wheels slip (oversteer).")]
[FloatRange(0.05f, 10f, 0.002f, 3)]
public float RearSlipThreshold { get; init; } = 0.25f;

[ToolTip("Higher is stronger dynamic feedback.")]
[IntRange(5, 8, 1)]
public int FeedbackStrength { get; init; } = 8;

[ToolTip("Sets the min frequency of the vibration effect in the trigger.")]
[IntRange(1, 10, 1)]
public int MinFrequency { get; init; } = 6;

[ToolTip("Sets the max frequency of the vibration effect in the trigger.")]
[IntRange(20, 150, 1)]
public int MaxFrequency { get; init; } = 96;

[ToolTip("Change the amplitude(strength) of the vibration effect in the trigger.")]
[IntRange(5, 8, 1)]
public int Amplitude { get; init; } = 7;
}

[ConfigGrouping("DSX UDP", "Adjust the port DSX uses, 6969 is default.")]
public UdpConfig UDP { get; init; } = new UdpConfig();
public sealed class UdpConfig
{
[ToolTip("Adjust the port used by DSX, 6969 is default.")]
[IntRange(0, 65535, 1)]
public int Port { get; init; } = 6969;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using DualSenseAPI;
using RaceElement.Core.Jobs.Loop;

namespace RaceElement.HUD.Common.Overlays.Pitwall.DualSenseInternal;

internal sealed class DsiJob(DsiOverlay overlay) : AbstractLoopJob
{
private DualSense? _controller;

public override void BeforeRun()
{
DualSense[] available = DualSense.EnumerateControllers().ToArray();
if (available != null && available.Length > 0)
{
_controller = available.First();
_controller.Acquire();
}
}
public sealed override void RunAction()
{
if (_controller == null || !overlay.ShouldRender()) return;


//_controller.OutputState.RightRumble = 0.5f;
//_controller.OutputState.L2Effect = new TriggerEffect.Continuous(0, 0.8f);
//_controller.ReadWriteOnce();

TriggerHaptics.HandleAcceleration(overlay._config, _controller);


TriggerHaptics.HandleBraking(overlay._config, _controller);

}

public override void AfterCancel()
{
if (_controller != null)
{
SetDefaultFeedback();
_controller?.Release();
}
}

private void SetDefaultFeedback()
{
_controller.OutputState.RightRumble = 0f;
_controller.OutputState.LeftRumble = 0f;
_controller.OutputState.L2Effect = TriggerEffect.Default;
_controller.OutputState.R2Effect = TriggerEffect.Default;
_controller.ReadWriteOnce();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using RaceElement.Data.Games;
using RaceElement.HUD.Overlay.Internal;
using System.Diagnostics;
using System.Drawing;

namespace RaceElement.HUD.Common.Overlays.Pitwall.DualSenseInternal;

#if DEBUG
[Overlay(Name = "DSI",
Description = "Adds active triggers for the DualSense Controller.",
OverlayCategory = OverlayCategory.Inputs,
OverlayType = OverlayType.Drive,
Game = Game.RaceRoom | Game.AssettoCorsa1 | Game.AssettoCorsaEvo,
Authors = ["Reinier Klarenberg"]
)]
#endif
internal sealed class DsiOverlay : CommonAbstractOverlay
{
internal readonly DsiConfiguration _config = new();
private DsiJob _dsiJob;

public DsiOverlay(Rectangle rectangle) : base(rectangle, "DSI")
{
Width = 1; Height = 1;
RefreshRateHz = 1;
AllowReposition = false;
}

public sealed override void BeforeStart()
{
if (IsPreviewing) return;

_dsiJob = new DsiJob(this) { IntervalMillis = 1000 / 200 };
_dsiJob.Run();
}
public sealed override void BeforeStop()
{
if (IsPreviewing) return;

_dsiJob?.CancelJoin();
}

public sealed override bool ShouldRender() => true;// DefaultShouldRender() && !IsPreviewing;

public sealed override void Render(Graphics g) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using DualSenseAPI;
using RaceElement.Data.Common;
using RaceElement.Util.SystemExtensions;

namespace RaceElement.HUD.Common.Overlays.Pitwall.DualSenseInternal;

internal static class TriggerHaptics
{
public static void HandleBraking(DsiConfiguration config, DualSense ds)
{
int controllerIndex = 0;

// TODO: add either an option to threshold it on brake input or based on some curve?
if (SimDataProvider.LocalCar.Inputs.Brake > config.BrakeSlip.BrakeThreshold / 100f)
{
float[] slipRatios = SimDataProvider.LocalCar.Tyres.SlipRatio;

if (slipRatios.Length == 0)
{
ds.OutputState.L2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
return;
}

if (slipRatios.Length == 4)
{
float slipRatioFront = Math.Max(slipRatios[0], slipRatios[1]);
float slipRatioRear = Math.Max(slipRatios[2], slipRatios[3]);

// TODO: add option for front and rear ratio threshold.
if (slipRatioFront > config.BrakeSlip.FrontSlipThreshold || slipRatioRear > config.BrakeSlip.RearSlipThreshold)
{
float frontslipCoefecient = slipRatioFront * 4f;
frontslipCoefecient.ClipMax(10);

float rearSlipCoefecient = slipRatioFront * 2f;
rearSlipCoefecient.ClipMax(7.5f);


float magicValue = frontslipCoefecient + rearSlipCoefecient;
float percentage = magicValue * 1.0f / 17.5f;

if (percentage >= 0.05f)
{
//ds.OutputState.L2Effect = new TriggerEffect.Continuous(0, percentage);
//ds.ReadWriteOnce();
//Thread.Sleep((int)(1000 / 200f * 4));
}

int freq = (int)(config.BrakeSlip.MaxFrequency * percentage);
freq.ClipMin(config.BrakeSlip.MinFrequency);
ds.OutputState.L2Effect = new TriggerEffect.Vibrate((byte)freq, config.BrakeSlip.Amplitude, config.BrakeSlip.Amplitude, config.BrakeSlip.Amplitude, true);
ds.ReadWriteOnce();
}
}
else
{
ds.OutputState.L2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
}
}
else
{
ds.OutputState.L2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
}
}

public static void HandleAcceleration(DsiConfiguration config, DualSense ds)
{
int controllerIndex = 0;

if (SimDataProvider.LocalCar.Inputs.Throttle > config.ThrottleSlip.ThrottleThreshold / 100f)
{
float[] slipRatios = SimDataProvider.LocalCar.Tyres.SlipRatio;
if (slipRatios.Length == 0)
{
ds.OutputState.R2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
return;
}

if (slipRatios.Length == 4)
{
float slipRatioFront = Math.Max(slipRatios[0], slipRatios[1]);
float slipRatioRear = Math.Max(slipRatios[2], slipRatios[3]);

if (slipRatioFront > config.ThrottleSlip.FrontSlipThreshold || slipRatioRear > config.ThrottleSlip.RearSlipThreshold)
{
float frontslipCoefecient = slipRatioFront * 3f;
frontslipCoefecient.ClipMax(5);
float rearSlipCoefecient = slipRatioFront * 5f;
rearSlipCoefecient.ClipMax(7.5f);

float magicValue = frontslipCoefecient + rearSlipCoefecient;
float percentage = magicValue * 1.0f / 12.5f;

if (percentage >= 0.05f)
{
//ds.OutputState.R2Effect = new TriggerEffect.Continuous(0, percentage);
//ds.ReadWriteOnce();
Thread.Sleep((int)(1000 / 200f * 4));
}

int freq = (int)(config.ThrottleSlip.MaxFrequency * percentage);
freq.ClipMin(config.ThrottleSlip.MinFrequency);
ds.OutputState.R2Effect = new TriggerEffect.Vibrate((byte)freq, config.ThrottleSlip.Amplitude, config.ThrottleSlip.Amplitude, config.ThrottleSlip.Amplitude, true);
ds.ReadWriteOnce();
}
else
{
ds.OutputState.R2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
}
}
}
else
{
ds.OutputState.R2Effect = TriggerEffect.Default;
ds.ReadWriteOnce();
}
}
}
1 change: 1 addition & 0 deletions Race Element.HUD.Common/Race Element.HUD.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<PackageReference Include="System.Speech" Version="9.0.1" />
<PackageReference Include="TwitchLib.Client" Version="3.3.1" />
<ProjectReference Include="..\Race Element.Data\Race Element.Data.csproj" />
<ProjectReference Include="..\Race_Element.Hardware\Race Element.Hardware.csproj" />
<ProjectReference Include="..\Race_Element.HUD\Race Element.HUD.csproj" />
</ItemGroup>

Expand Down
Loading

0 comments on commit 9b70c5d

Please sign in to comment.