Skip to content

Commit 9f9a869

Browse files
committed
Added lap counter
1 parent b8f7c72 commit 9f9a869

6 files changed

+149
-71
lines changed

DoTelemetry.cpp

+123-64
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
#include "dotelemetry.h"
55
#include "tmtelemetry.h"
66

7+
// Forward declarations
8+
BOOL IsRaceBeforeStart(STelemetryData* pTelemetry);
9+
BOOL IsRaceRunning(STelemetryData* pTelemetry);
10+
BOOL IsRaceFinished(STelemetryData* pTelemetry);
11+
712
// Processing of the telemetry data
813
void DoTelemetry(STelemetryData* pTelemetry)
914
{
1015
TCHAR szText[MAX_CONTROLTEXT];
1116
static int nRaceNumber = 0; // Number of attempts
17+
static Nat32 uLapCount = 0; // Current lap
1218
static BOOL bAddFinalColumns = FALSE; // Append some stats after the end of each race
1319

1420
// Static variables for storing values for the statistics:
@@ -95,9 +101,38 @@ void DoTelemetry(STelemetryData* pTelemetry)
95101
// Race state
96102
if (pTelemetry->Current.Race.State != pTelemetry->Previous.Race.State)
97103
{
98-
// Handle the start of a race (race state changes from "BeforeState" to "Running")
99-
if (pTelemetry->Previous.Race.State == STelemetry::ERaceState_BeforeState &&
100-
pTelemetry->Current.Race.State == STelemetry::ERaceState_Running)
104+
switch (pTelemetry->Current.Race.State)
105+
{
106+
case STelemetry::ERaceState_BeforeState:
107+
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceBeforeStart);
108+
break;
109+
110+
case STelemetry::ERaceState_Running:
111+
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceRunning);
112+
break;
113+
114+
case STelemetry::ERaceState_Finished:
115+
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceFinished);
116+
break;
117+
118+
//case STelemetry::ERaceState_Eliminated:
119+
// StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceEliminated);
120+
// break;
121+
122+
default:
123+
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, TEXT(""));
124+
}
125+
126+
// Handle the countdown
127+
if (IsRaceBeforeStart(pTelemetry))
128+
{
129+
// Reset the lap counter
130+
uLapCount = 0;
131+
StatusBar_SetLapCount(hwndStatusBar, SBP_LAPS, uLapCount, pTelemetry->Current.Race.NbLaps);
132+
}
133+
134+
// Handle the start of a race
135+
if (IsRaceRunning(pTelemetry))
101136
{
102137
uTopSpeed = 0;
103138
nNbGearchanges = 0;
@@ -116,6 +151,10 @@ void DoTelemetry(STelemetryData* pTelemetry)
116151
bIsSlipping = pTelemetry->Current.Vehicle.WheelsIsSliping[0] || pTelemetry->Current.Vehicle.WheelsIsSliping[1] ||
117152
pTelemetry->Current.Vehicle.WheelsIsSliping[2] || pTelemetry->Current.Vehicle.WheelsIsSliping[3];
118153

154+
// Set the lap counter to 1
155+
uLapCount = 1;
156+
StatusBar_SetLapCount(hwndStatusBar, SBP_LAPS, uLapCount, pTelemetry->Current.Race.NbLaps);
157+
119158
// Add a new race to the list-view control and increment the number of attempts
120159
if (ListView_AddRace(hwndListView, nRaceNumber + 1, COLUMN_AUTOFIT) != -1)
121160
nRaceNumber++;
@@ -158,10 +197,8 @@ void DoTelemetry(STelemetryData* pTelemetry)
158197
}
159198
}
160199

161-
// Handle the end of a race (race state changes from "Running" to "Finished" or "BeforeStart")
162-
if (pTelemetry->Previous.Race.State == STelemetry::ERaceState_Running &&
163-
(pTelemetry->Current.Race.State == STelemetry::ERaceState_Finished ||
164-
pTelemetry->Current.Race.State == STelemetry::ERaceState_BeforeState))
200+
// Handle the end of a race
201+
if (IsRaceFinished(pTelemetry))
165202
{
166203
// Test if the checkpoint count has increased to differ between finished and restart
167204
if (pTelemetry->Current.Race.NbCheckpoints > pTelemetry->Previous.Race.NbCheckpoints)
@@ -178,29 +215,59 @@ void DoTelemetry(STelemetryData* pTelemetry)
178215
nRaceNumber--;
179216
}
180217

181-
switch (pTelemetry->Current.Race.State)
218+
pTelemetry->Previous.Race.State = pTelemetry->Current.Race.State;
219+
}
220+
221+
// Number of checkpoints
222+
if (pTelemetry->Current.Race.NbCheckpoints != pTelemetry->Previous.Race.NbCheckpoints)
223+
{
224+
// Add the new checkpoint time to the list-view control
225+
Nat32 uCurrentNbCheckpoints = pTelemetry->Current.Race.NbCheckpoints;
226+
if (uCurrentNbCheckpoints > 0 && uCurrentNbCheckpoints <= _countof(pTelemetry->Current.Race.CheckpointTimes) &&
227+
uCurrentNbCheckpoints > uMaxNbCheckpoints)
182228
{
183-
case STelemetry::ERaceState_BeforeState:
184-
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceBeforeStart);
185-
break;
229+
if (dwColumns & COL_SECTORTIMES)
230+
ListView_AddSectorTime(hwndListView, nRaceNumber, COLUMN_AUTOFIT, uCurrentNbCheckpoints,
231+
pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 1],
232+
uCurrentNbCheckpoints >= 2 ? pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 2] : 0);
186233

187-
case STelemetry::ERaceState_Running:
188-
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceRunning);
189-
break;
234+
if (dwColumns & COL_CHECKPOINTS)
235+
ListView_AddCheckpointTime(hwndListView, nRaceNumber, COLUMN_AUTOFIT, uCurrentNbCheckpoints,
236+
pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 1]);
237+
}
190238

191-
case STelemetry::ERaceState_Finished:
192-
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceFinished);
193-
break;
239+
// Update the lap counter after crossing the start/finish line
240+
Nat32 uCurrentLap = uLapCount;
241+
Nat32 uNumberOfLaps = pTelemetry->Current.Race.NbLaps; // Could be zero
242+
Nat32 uCheckpointsPerLap = pTelemetry->Current.Race.NbCheckpointsPerLap; // Always 0 with Trackmania Turbo
243+
244+
if (uCheckpointsPerLap != 0)
245+
{
246+
uCurrentLap = uCurrentNbCheckpoints / uCheckpointsPerLap;
247+
// Correct the lap counter by one, except on restart and when crossing the finish line
248+
if (uCurrentNbCheckpoints != 0 && (uCurrentLap < uNumberOfLaps || uNumberOfLaps == 0))
249+
uCurrentLap++;
250+
// Keep the number of laps driven after the race is over
251+
if (uCurrentLap < uLapCount)
252+
uCurrentLap = uLapCount;
253+
}
254+
255+
if (uCurrentLap != uLapCount)
256+
{
257+
uLapCount = uCurrentLap;
258+
StatusBar_SetLapCount(hwndStatusBar, SBP_LAPS, uLapCount, uNumberOfLaps);
259+
}
194260

195-
//case STelemetry::ERaceState_Eliminated:
196-
// StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, szRaceEliminated);
197-
// break;
261+
// Update the checkpoint counter
262+
_sntprintf(szText, _countof(szText), szNbCheckpoints, uCurrentNbCheckpoints);
263+
StatusBar_SetText(hwndStatusBar, SBP_CHECKPOINTS, szText, TRUE);
198264

199-
default:
200-
StatusBar_SetText(hwndStatusBar, SBP_RACESTATE, TEXT(""));
201-
}
265+
// Here we have to store the highest number of checkpoints per game client so that
266+
// the list is not flooded with data when Maniaplanet and Turbo run simultaneously
267+
if (uCurrentNbCheckpoints > pTelemetry->Previous.Race.NbCheckpoints)
268+
uMaxNbCheckpoints = uCurrentNbCheckpoints;
202269

203-
pTelemetry->Previous.Race.State = pTelemetry->Current.Race.State;
270+
pTelemetry->Previous.Race.NbCheckpoints = uCurrentNbCheckpoints;
204271
}
205272

206273
// Map name
@@ -237,45 +304,6 @@ void DoTelemetry(STelemetryData* pTelemetry)
237304
pTelemetry->Previous.Race.Time = pTelemetry->Current.Race.Time;
238305
}
239306

240-
// Number of respawns
241-
if (pTelemetry->Current.Race.NbRespawns != pTelemetry->Previous.Race.NbRespawns)
242-
{
243-
_sntprintf(szText, _countof(szText), szNbRespawns, pTelemetry->Current.Race.NbRespawns);
244-
StatusBar_SetText(hwndStatusBar, SBP_RESPAWNS, szText, TRUE);
245-
246-
pTelemetry->Previous.Race.NbRespawns = pTelemetry->Current.Race.NbRespawns;
247-
}
248-
249-
// Number of checkpoints
250-
if (pTelemetry->Current.Race.NbCheckpoints != pTelemetry->Previous.Race.NbCheckpoints)
251-
{
252-
// Add the new checkpoint time to the list-view control
253-
Nat32 uCurrentNbCheckpoints = pTelemetry->Current.Race.NbCheckpoints;
254-
if (uCurrentNbCheckpoints > 0 && uCurrentNbCheckpoints <= _countof(pTelemetry->Current.Race.CheckpointTimes) &&
255-
uCurrentNbCheckpoints > uMaxNbCheckpoints)
256-
{
257-
// BUGBUG: It looks like we can't be sure that the checkpoint time was also already updated!
258-
if (dwColumns & COL_SECTORTIMES)
259-
ListView_AddSectorTime(hwndListView, nRaceNumber, COLUMN_AUTOFIT, uCurrentNbCheckpoints,
260-
pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 1],
261-
uCurrentNbCheckpoints >= 2 ? pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 2] : 0);
262-
263-
if (dwColumns & COL_CHECKPOINTS)
264-
ListView_AddCheckpointTime(hwndListView, nRaceNumber, COLUMN_AUTOFIT, uCurrentNbCheckpoints,
265-
pTelemetry->Current.Race.CheckpointTimes[uCurrentNbCheckpoints - 1]);
266-
}
267-
268-
// Here we have to store the highest number of checkpoints per game client so that
269-
// the list is not flooded with data when Maniaplanet and Turbo run simultaneously
270-
if (uCurrentNbCheckpoints > pTelemetry->Previous.Race.NbCheckpoints)
271-
uMaxNbCheckpoints = uCurrentNbCheckpoints;
272-
273-
_sntprintf(szText, _countof(szText), szNbCheckpoints, uCurrentNbCheckpoints);
274-
StatusBar_SetText(hwndStatusBar, SBP_CHECKPOINTS, szText, TRUE);
275-
276-
pTelemetry->Previous.Race.NbCheckpoints = uCurrentNbCheckpoints;
277-
}
278-
279307
// Speed
280308
if (pTelemetry->Current.Vehicle.SpeedMeter != pTelemetry->Previous.Vehicle.SpeedMeter)
281309
{
@@ -445,11 +473,17 @@ void DoTelemetry(STelemetryData* pTelemetry)
445473
// Map UID
446474
if (strcmp(pTelemetry->Current.Game.MapId, pTelemetry->Previous.Game.MapId) != 0)
447475
{
448-
// Clear all races after map change
449476
if (strcmp(pTelemetry->Current.Game.MapId, "Unassigned") != 0)
477+
{
478+
// Clear all races after map change
450479
if (ListView_DeleteAllRaces(hwndListView))
451480
nRaceNumber = 0;
452481

482+
// Reset the lap counter
483+
uLapCount = 0;
484+
StatusBar_SetLapCount(hwndStatusBar, SBP_LAPS, uLapCount, pTelemetry->Current.Race.NbLaps);
485+
}
486+
453487
lstrcpynA(pTelemetry->Previous.Game.MapId, pTelemetry->Current.Game.MapId, _countof(pTelemetry->Previous.Game.MapId));
454488
}
455489

@@ -512,6 +546,8 @@ void InitTelemetryData(STelemetryData* pTelemetry)
512546
pTelemetry->Previous.Race.Time = (Nat32)-2; // -1 is a regular value
513547
pTelemetry->Previous.Race.NbRespawns = (Nat32)-2; // -1 is a regular value
514548
pTelemetry->Previous.Race.NbCheckpoints = (Nat32)-1;
549+
pTelemetry->Previous.Race.NbCheckpointsPerLap = (Nat32)-1;
550+
pTelemetry->Previous.Race.NbLaps = (Nat32)-1;
515551

516552
pTelemetry->Previous.Vehicle.InputSteer = -2.0f; // -1.0 is a regular value
517553
pTelemetry->Previous.Vehicle.InputGasPedal = -1.0f;
@@ -525,3 +561,26 @@ void InitTelemetryData(STelemetryData* pTelemetry)
525561
pTelemetry->Previous.Vehicle.RumbleIntensity = -1.0f;
526562
pTelemetry->Previous.Vehicle.SpeedMeter = (Nat32)-1;
527563
}
564+
565+
// Checks if the countdown has just started (race state changes from "Finished" or "Running" to "BeforeStart")
566+
__inline BOOL IsRaceBeforeStart(STelemetryData* pTelemetry)
567+
{
568+
return ((pTelemetry->Previous.Race.State == STelemetry::ERaceState_Finished ||
569+
pTelemetry->Previous.Race.State == STelemetry::ERaceState_Running) &&
570+
pTelemetry->Current.Race.State == STelemetry::ERaceState_BeforeState);
571+
}
572+
573+
// Checks if the race has just started (race state changes from "BeforeStart" to "Running")
574+
__inline BOOL IsRaceRunning(STelemetryData* pTelemetry)
575+
{
576+
return (pTelemetry->Previous.Race.State == STelemetry::ERaceState_BeforeState &&
577+
pTelemetry->Current.Race.State == STelemetry::ERaceState_Running);
578+
}
579+
580+
// Checks if the race has just finished (race state changes from "Running" to "Finished" or "BeforeStart")
581+
__inline BOOL IsRaceFinished(STelemetryData* pTelemetry)
582+
{
583+
return (pTelemetry->Previous.Race.State == STelemetry::ERaceState_Running &&
584+
(pTelemetry->Current.Race.State == STelemetry::ERaceState_Finished ||
585+
pTelemetry->Current.Race.State == STelemetry::ERaceState_BeforeState));
586+
}

Helper.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ BOOL StatusBar_SetText(HWND hwndCtl, UINT uIndexType, LPCTSTR lpszText, BOOL bCe
139139
}
140140
}
141141

142+
BOOL StatusBar_SetLapCount(HWND hwndCtl, UINT uIndexType, UINT uCurrentLap, UINT uNumberOfLaps, BOOL bCenter)
143+
{
144+
TCHAR szText[MAX_CONTROLTEXT];
145+
146+
if (hwndCtl == NULL)
147+
return FALSE;
148+
149+
if (uNumberOfLaps == 0)
150+
_sntprintf(szText, _countof(szText), szCurLap, uCurrentLap);
151+
else
152+
_sntprintf(szText, _countof(szText), szNbLaps, uCurrentLap, uNumberOfLaps);
153+
154+
return StatusBar_SetText(hwndCtl, uIndexType, szText, bCenter);
155+
}
156+
142157

143158
void ListView_SelectAll(HWND hwndCtl)
144159
{

Helper.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const TCHAR szRaceBeforeStart[] = TEXT("Race: BeforeStart");
2424
const TCHAR szRaceRunning[] = TEXT("Race: Running");
2525
const TCHAR szRaceFinished[] = TEXT("Race: Finished");
2626
const TCHAR szRaceEliminated[] = TEXT("Race: Eliminated");
27-
const TCHAR szNbRespawns[] = TEXT("RSP: %d");
27+
const TCHAR szCurLap[] = TEXT("Lap: %d");
28+
const TCHAR szNbLaps[] = TEXT("Lap: %d/%d");
2829
const TCHAR szNbCheckpoints[] = TEXT("CP: %d");
2930
const TCHAR szSpeedKmh[] = TEXT("%d km/h");
3031
const TCHAR szSpeedMph[] = TEXT("%d mph");
@@ -59,6 +60,7 @@ BOOL GetFileName(HWND hDlg, LPTSTR lpszFileName, SIZE_T cchStringLen, LPDWORD lp
5960

6061
// Status bar functions
6162
BOOL StatusBar_SetText(HWND hwndCtl, UINT uIndexType, LPCTSTR lpszText, BOOL bCenter = FALSE);
63+
BOOL StatusBar_SetLapCount(HWND hwndCtl, UINT uIndexType, UINT uCurrentLap, UINT uNumberOfLaps, BOOL bCenter = TRUE);
6264

6365
// List-view functions
6466
void ListView_SelectAll(HWND hwndCtl);

TMTelemetry.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ BOOL WndProc_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
428428
SetWindowFont(hwndStatusBar, GetStockFont(DEFAULT_GUI_FONT), FALSE);
429429

430430
// Set the number of parts and the coordinate of the right edge of each part
431-
int aStatusBarParts[15] = { 125, 235, 385, 480, 555, 605, 650, 715, 790, 850, 940, 1030, 1120, 1180, -1 };
431+
int aStatusBarParts[15] = { 125, 235, 385, 480, 555, 620, 665, 730, 805, 865, 955, 1045, 1135, 1195, -1 };
432432
SIZE_T uParts = _countof(aStatusBarParts);
433433
for (SIZE_T i = 0; i < (uParts - 1); i++)
434434
aStatusBarParts[i] = MulDiv(aStatusBarParts[i], nDpi, USER_DEFAULT_SCREEN_DPI);

TMTelemetry.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ typedef enum _STATUSBAR_PART
3131
SBP_MAPNAME,
3232
SBP_PLAYERMODEL,
3333
SBP_RACETIME,
34-
SBP_RESPAWNS,
34+
SBP_LAPS,
3535
SBP_CHECKPOINTS,
3636
SBP_SPEEDMETER,
3737
SBP_ENGINERPM,

maniaplanet_telemetry.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct STelemetry {
3838
};
3939
struct SGameState {
4040
EGameState State;
41-
char GameplayVariant[64]; // environment name 'stadium' 'canyon', ....
41+
char GameplayVariant[64]; // player model 'StadiumCar', 'CanyonCar', ....
4242
char MapId[64];
4343
char MapName[256];
4444
char __future__[128];
@@ -49,14 +49,16 @@ struct STelemetry {
4949
Nat32 NbRespawns;
5050
Nat32 NbCheckpoints;
5151
Nat32 CheckpointTimes[125];
52-
char __future__[32];
52+
Nat32 NbCheckpointsPerLap; // new since Maniaplanet update 2019-10-10; not supported by Trackmania Turbo.
53+
Nat32 NbLaps; // new since Maniaplanet update 2019-10-10; not supported by Trackmania Turbo.
54+
char __future__[24];
5355
};
5456
struct SObjectState {
5557
Nat32 Timestamp;
5658
Nat32 DiscontinuityCount; // the number changes everytime the object is moved not continuously (== teleported).
5759
Quat Rotation;
58-
Vec3 Translation; // +x is "left", +y is "up", +z is "front"
59-
Vec3 Velocity; // (world velocity)
60+
Vec3 Translation; // +x is "left", +y is "up", +z is "front"
61+
Vec3 Velocity; // (world velocity)
6062
Nat32 LatestStableGroundContactTime;
6163
char __future__[32];
6264
};

0 commit comments

Comments
 (0)