diff --git a/GamesDat.Demo/Program.cs b/GamesDat.Demo/Program.cs index fc8f443..8fda38e 100644 --- a/GamesDat.Demo/Program.cs +++ b/GamesDat.Demo/Program.cs @@ -12,7 +12,7 @@ internal class Program { static async Task Main(string[] args) { - //await CaptureF1SessionAsync(); + await CaptureF1SessionAsync(); //await ReadF1Session("./sessions/f1_20260210_220103.bin"); } diff --git a/GamesDat/Telemetry/Sources/Formula1/F12025/Participant.cs b/GamesDat/Telemetry/Sources/Formula1/F12025/Participant.cs index 441d97d..ff5d482 100644 --- a/GamesDat/Telemetry/Sources/Formula1/F12025/Participant.cs +++ b/GamesDat/Telemetry/Sources/Formula1/F12025/Participant.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using System.Text; namespace GamesDat.Core.Telemetry.Sources.Formula1.F12025 { @@ -14,8 +15,8 @@ public struct Participant public byte m_raceNumber; // Race number of the car public byte m_nationality; // Nationality of the driver - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string m_name; // Name of participant in UTF-8 format – null terminated + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] m_name; // Name of participant in UTF-8 format – null terminated // Will be truncated with ... (U+2026) if too long public byte m_yourTelemetry; // The player's UDP setting, 0 = restricted, 1 = public public byte m_showOnlineNames; // The player's show online names setting, 0 = off, 1 = on @@ -26,5 +27,18 @@ public struct Participant [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public LiveryColour[] m_liveryColours; // Colours for the car + /// + /// Gets the participant name as a decoded UTF-8 string + /// + public readonly string Name + { + get + { + if (m_name == null) return string.Empty; + int length = Array.IndexOf(m_name, (byte)0); + if (length < 0) length = m_name.Length; + return Encoding.UTF8.GetString(m_name, 0, length); + } + } } } diff --git a/GamesDat/Telemetry/Sources/Formula1/F1TelemetryFrameExtensions.cs b/GamesDat/Telemetry/Sources/Formula1/F1TelemetryFrameExtensions.cs index cdf640b..706fe00 100644 --- a/GamesDat/Telemetry/Sources/Formula1/F1TelemetryFrameExtensions.cs +++ b/GamesDat/Telemetry/Sources/Formula1/F1TelemetryFrameExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace GamesDat.Core.Telemetry.Sources.Formula1 @@ -31,7 +32,8 @@ public static unsafe T GetPacket(this F1TelemetryFrame frame) where T : struc $"Packet data too small. Expected {expectedSize} bytes for {packetType.Name}, got {frame.DataLength}"); } - return Marshal.PtrToStructure((IntPtr)frame.RawData); + void* ptr = Unsafe.AsPointer(ref frame.RawData[0]); + return Marshal.PtrToStructure((IntPtr)ptr); } /// @@ -49,7 +51,8 @@ public static unsafe T GetPacket(this F1TelemetryFrame frame) where T : struc throw new InvalidOperationException($"Packet data too small. Expected {expectedSize} bytes for {packetType.Name}, got {frame.DataLength}"); } - var result = Marshal.PtrToStructure((IntPtr)frame.RawData, packetType); + void* ptr = Unsafe.AsPointer(ref frame.RawData[0]); + var result = Marshal.PtrToStructure((IntPtr)ptr, packetType); return result; } @@ -59,7 +62,8 @@ public static unsafe T GetPacket(this F1TelemetryFrame frame) where T : struc public static unsafe byte[] GetRawData(this F1TelemetryFrame frame) { var data = new byte[frame.DataLength]; - Marshal.Copy((IntPtr)frame.RawData, data, 0, frame.DataLength); + void* ptr = Unsafe.AsPointer(ref frame.RawData[0]); + Marshal.Copy((IntPtr)ptr, data, 0, frame.DataLength); return data; } }