diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index c3f023764..9d63b14bb 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -377,6 +377,13 @@ AssettoCorsaView.xaml + + + + FormulaOne2017View.xaml + + + @@ -881,6 +888,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017DataModel.cs b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017DataModel.cs new file mode 100644 index 000000000..3d036f77d --- /dev/null +++ b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017DataModel.cs @@ -0,0 +1,89 @@ +using System.Runtime.InteropServices; +using Artemis.Modules.Abstract; +using MoonSharp.Interpreter; + +namespace Artemis.Modules.Games.FormulaOne2017 +{ + [MoonSharpUserData] + public class FormulaOne2017DataModel : ModuleDataModel + { + public FormulaOne2017DataModel() + { + } + + [StructLayout(LayoutKind.Sequential)] + public struct UdpPacketData + { + public float m_time; // Total seconds driven from start line + public float m_lapTime; // Total seconds of current lap + public float m_lapDistance; // Total distance through lap in meters + public float m_totalDistance; // Total distance driven from start line + public float m_x; // World space position + public float m_y; // World space position + public float m_z; // World space position + public float m_speed; // Meters/sec + public float m_xv; // Velocity in world space + public float m_yv; // Velocity in world space + public float m_zv; // Velocity in world space + public float m_xr; // World space right direction + public float m_yr; // World space right direction + public float m_zr; // World space right direction + public float m_xd; // World space forward direction + public float m_yd; // World space forward direction + public float m_zd; // World space forward direction + public float m_susp_pos_bl; // + public float m_susp_pos_br; // + public float m_susp_pos_fl; // + public float m_susp_pos_fr; // + public float m_susp_vel_bl; // + public float m_susp_vel_br; // + public float m_susp_vel_fl; // + public float m_susp_vel_fr; // + public float m_wheel_speed_bl; // + public float m_wheel_speed_br; // + public float m_wheel_speed_fl; // + public float m_wheel_speed_fr; // + public float m_throttle; // Throttle input + public float m_steer; // Steering input (-1 left to +1 right) + public float m_brake; // Brake input + public float m_clutch; // Clutch input + public float m_gear; // 0 - R | 1 - N | 2-9 - 1-8 + public float m_gforce_lat; // Lateral G's + public float m_gforce_lon; // Longiitude G's + public float m_lap; // Current lap number + public float m_engineRate; // Engine RPM + public float m_sli_pro_native_support; // SLI Pro support + public float m_car_position; // car race position + public float m_kers_level; // kers energy left + public float m_kers_max_level; // kers maximum energy + public float m_drs; // 0 = off, 1 = on + public float m_traction_control; // 0 (off) - 2 (high) + public float m_anti_lock_brakes; // 0 (off) - 1 (on) + public float m_fuel_in_tank; // current fuel mass + public float m_fuel_capacity; // fuel capacity + public float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area + public float m_sector; // 0 = sector1, 1 = sector2; 2 = sector3 + public float m_sector1_time; // time of sector1 (or 0) + public float m_sector2_time; // time of sector2 (or 0) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] m_brakes_temp; // brakes temperature (centigrade) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public float[] m_wheels_pressure; // wheels pressure PSI + public float m_team_info; // team ID + public float m_total_laps; // total number of laps in this race + public float m_track_size; // track size meters + public float m_last_lap_time; // last lap time + public float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in + public float m_idle_rpm; // cars idle RPM + public float m_max_gears; // maximum number of gears + public float m_sessionType; // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race + public float m_drsAllowed; // 0 = not allowed, 1 = allowed, -1 = invalid / unknown + public float m_track_number; // -1 for unknown, 0-21 for tracks + public float m_vehicleFIAFlags; // -1 = invalid/unknown, 0 = none, 1 = green, 2 = blue, 3 = yellow, 4 = red + } + + public float Rpm { get; set; } + public float MaxRpm { get; set; } + public float IdleRpm { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Model.cs b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Model.cs new file mode 100644 index 000000000..31d10f66b --- /dev/null +++ b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Model.cs @@ -0,0 +1,69 @@ +using System; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Artemis.DAL; +using Artemis.Managers; +using Artemis.Modules.Abstract; + +namespace Artemis.Modules.Games.FormulaOne2017 +{ + public class FormulaOne2017Model : ModuleModel + { + private UdpClient _udpListener; + private bool _mustListen; + + public FormulaOne2017Model(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager) + { + Settings = SettingsProvider.Load(); + DataModel = new FormulaOne2017DataModel(); + ProcessNames.Add("F1_2017"); + } + + public override string Name => "FormulaOne2017"; + public override bool IsOverlay => false; + public override bool IsBoundToProcess => true; + + public override void Update() + { + } + + public override void Enable() + { + _mustListen = true; + Task.Run(async () => + { + using (var udpClient = new UdpClient(20777)) + { + string loggingEvent = ""; + while (_mustListen) + { + //IPEndPoint object will allow us to read datagrams sent from any source. + var receivedResults = await udpClient.ReceiveAsync(); + HandleGameData(receivedResults); + } + } + }); + base.Enable(); + } + + private void HandleGameData(UdpReceiveResult receivedResults) + { + var dataModel = (FormulaOne2017DataModel) DataModel; + var pinnedPacket = GCHandle.Alloc(receivedResults.Buffer, GCHandleType.Pinned); + var msg = (FormulaOne2017DataModel.UdpPacketData) Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(FormulaOne2017DataModel.UdpPacketData)); + pinnedPacket.Free(); + + dataModel.Rpm = msg.m_engineRate; + dataModel.MaxRpm = msg.m_max_rpm; + dataModel.IdleRpm = msg.m_idle_rpm; + } + + public override void Dispose() + { + _mustListen = false; + base.Dispose(); + } + } +} diff --git a/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Settings.cs b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Settings.cs new file mode 100644 index 000000000..47e68c6bc --- /dev/null +++ b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017Settings.cs @@ -0,0 +1,8 @@ +using Artemis.Modules.Abstract; + +namespace Artemis.Modules.Games.FormulaOne2017 +{ + public class FormulaOne2017Settings : ModuleSettings + { + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017View.xaml b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017View.xaml new file mode 100644 index 000000000..c758c77f2 --- /dev/null +++ b/Artemis/Artemis/Modules/Games/FormulaOne2017/FormulaOne2017View.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +