From 669fd8f0409c7e59cd8b664119b5b4ab6dc25173 Mon Sep 17 00:00:00 2001 From: Electron Date: Wed, 27 Mar 2019 19:41:49 +0100 Subject: [PATCH] Added steering and wheel slip Added steering in status bar and wheel slip in table; upgraded from Visual Studio 2013 to 2017; new release version 1.2.1. --- Helper.cpp | 14 +++-- Helper.h | 6 +- Readme.md | 2 +- Resource.h | Bin 4804 -> 4988 bytes Setup/Setup.vdproj | 76 +++--------------------- TMTelemetry.cpp | 125 ++++++++++++++++++++++++++++++++++----- TMTelemetry.exe.manifest | 2 +- TMTelemetry.h | 4 +- TMTelemetry.rc | Bin 14556 -> 14720 bytes TMTelemetry.vcxproj | 29 +++++---- x64/Setup/Setup64.vdproj | 78 +++--------------------- 11 files changed, 159 insertions(+), 177 deletions(-) diff --git a/Helper.cpp b/Helper.cpp index 924434a..b6a21f3 100644 --- a/Helper.cpp +++ b/Helper.cpp @@ -13,7 +13,7 @@ BOOL FormatTime(LPTSTR lpszTime, SIZE_T cchStringLen, int nTime) return FALSE; if (nTime <= 0) - _tcsncpy(lpszTime, TEXT("0:00.000"), cchStringLen); + lstrcpyn(lpszTime, TEXT("0:00.000"), (int)cchStringLen); else if (nTime < 3600000) { UINT uMinute = (nTime / 60000); @@ -54,7 +54,7 @@ BOOL GetFileName(HWND hWnd, LPTSTR lpszFileName, SIZE_T cchStringLen, LPDWORD lp TCHAR* pszInitialDir = szInitialDir; if (lpszFileName[0] != TEXT('\0')) { - _tcsncpy(pszInitialDir, lpszFileName, _countof(szInitialDir)); + lstrcpyn(pszInitialDir, lpszFileName, _countof(szInitialDir)); TCHAR* token = _tcsrchr(pszInitialDir, TEXT('\\')); if (token != NULL) pszInitialDir[token - szInitialDir] = TEXT('\0'); @@ -69,9 +69,9 @@ BOOL GetFileName(HWND hWnd, LPTSTR lpszFileName, SIZE_T cchStringLen, LPDWORD lp if (bSave) { if (lpszFileName[0] != TEXT('\0')) - _tcsncpy(szFile, lpszFileName, _countof(szFile)); + lstrcpyn(szFile, lpszFileName, _countof(szFile)); else - _tcsncpy(szFile, TEXT("*"), _countof(szFile)); + lstrcpyn(szFile, TEXT("*"), _countof(szFile)); TCHAR* token = _tcsrchr(szFile, TEXT('.')); if (token != NULL) szFile[token - szFile] = TEXT('\0'); @@ -111,7 +111,7 @@ BOOL GetFileName(HWND hWnd, LPTSTR lpszFileName, SIZE_T cchStringLen, LPDWORD lp if (bRet) { - _tcsncpy(lpszFileName, szFile, cchStringLen); + lstrcpyn(lpszFileName, szFile, (int)cchStringLen); *lpdwFilterIndex = of.nFilterIndex; } @@ -126,7 +126,7 @@ BOOL StatusBar_SetText(HWND hwndCtl, UINT uIndexType, LPCTSTR lpszText, BOOL bCe if (hwndCtl == NULL) return FALSE; - // Set ToolTip + // Set tooltip SendMessage(hwndCtl, SB_SETTIPTEXT, (WPARAM)LOBYTE(LOWORD(uIndexType)), (LPARAM)lpszText); if (!bCenter) @@ -413,6 +413,7 @@ int ListView_AddRaceText(HWND hwndCtl, int nRaceNumber, int nColumnWidth, LPCTST // If necessary, rename the header if the application // was started while a race was already in progress TCHAR szHeading[MAX_CONTROLTEXT]; + szHeading[0] = TEXT('\0'); LV_COLUMN col = { 0 }; col.mask = LVCF_TEXT; @@ -533,6 +534,7 @@ BOOL ListView_DeleteAllRaces(HWND hwndCtl) BOOL ListView_SaveAllItems(HWND hwndCtl, LPTSTR lpszFileName, BOOL bSaveAsCsv) { TCHAR szText[MAX_CONTROLTEXT]; + szText[0] = TEXT('\0'); if (hwndCtl == NULL) return FALSE; diff --git a/Helper.h b/Helper.h index 44cc291..50c8da9 100644 --- a/Helper.h +++ b/Helper.h @@ -29,8 +29,9 @@ const TCHAR szSpeedKmh[] = TEXT("%d km/h"); const TCHAR szSpeedMph[] = TEXT("%d mph"); const TCHAR szEngineRpm[] = TEXT("%.0f rpm"); const TCHAR szEngineCurGear[] = TEXT("Gear: %d"); -const TCHAR szGasPedal[] = TEXT("Throttle: %3.0f%%"); -const TCHAR szRumbleIntensity[] = TEXT("Rumble: %3.0f%%"); +const TCHAR szSteering[] = TEXT("Steering: %3.0f %%"); +const TCHAR szGasPedal[] = TEXT("Throttle: %3.0f %%"); +const TCHAR szRumbleIntensity[] = TEXT("Rumble: %3.0f %%"); const TCHAR szBraking[] = TEXT("Braking"); // List-view headings @@ -49,6 +50,7 @@ const TCHAR szRumbles[] = TEXT("Rumbles"); const TCHAR szGearchanges[] = TEXT("Gearchanges"); const TCHAR szBrakesUsed[] = TEXT("Brakes Used"); const TCHAR szFullspeed[] = TEXT("Fullspeed"); +const TCHAR szWheelSlip[] = TEXT("Wheel Slip"); // General functions BOOL FormatTime(LPTSTR lpszTime, SIZE_T cchStringLen, int nTime); diff --git a/Readme.md b/Readme.md index 5f774e6..308872c 100644 --- a/Readme.md +++ b/Readme.md @@ -10,4 +10,4 @@ The application does not log any data or perform any analyses. Also no gauges or The source code is provided as an example and should show how to access the game data via the [telemetry interface](https://wiki.xaseco.org/wiki/Telemetry_interface) of [Maniaplanet 4](https://www.maniaplanet.com/) or [Trackmania Turbo](https://www.ubisoft.com/en-gb/game/trackmania-turbo/). -It's a generic C/C++ Win32 desktop project created with Visual Studio 2013. Since no external libraries are used, the project should be built without problems. An older VS2005 project file (.vcproj) and two Visual Studio Installer projects for x86 and x64 are also included. +This is a generic C/C++ Win32 desktop project created with Visual Studio 2017. Since no external libraries are used, the project should be built without problems. An older VS2005 project file (.vcproj) and two Visual Studio Installer projects for x86 and x64 are also included. diff --git a/Resource.h b/Resource.h index b20176bd334a74cdc9ec58f5a109033c40881f87..52d52666c4fa0149d691da9eeb362e178056a6cf 100644 GIT binary patch delta 166 zcmX@2`bTZU1!m3=h9Cw<24@EE$&JkVlP9pVP3B|Knf!oRXL1^g%;a;-LX)jn^d=u- zk(=DcVl!EWRc`VFAYBHetypa)UjWimfV38y)Z_`QER){>+4F=rChy`9+U&w+z{wxZ z;KASuggy+xKDPYLxfnoSND GRs{fdd?F73 diff --git a/Setup/Setup.vdproj b/Setup/Setup.vdproj index 409db6f..ba94694 100644 --- a/Setup/Setup.vdproj +++ b/Setup/Setup.vdproj @@ -13,18 +13,6 @@ "SccProvider" = "8:" "Hierarchy" { - "Entry" - { - "MsmKey" = "8:_4CC65BCBC5E4BCEFC5CD50D2515A9741" - "OwnerKey" = "8:_E3461C036BF947D88556F74EC33D8DD0" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_5A4B9DAFE9768CBB38DC6AFA6DEF49E9" - "OwnerKey" = "8:_E3461C036BF947D88556F74EC33D8DD0" - "MsmSig" = "8:_UNDEFINED" - } "Entry" { "MsmKey" = "8:_E3461C036BF947D88556F74EC33D8DD0" @@ -58,11 +46,6 @@ "ComponentsUrl" = "8:" "Items" { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.4.5" - { - "Name" = "8:Windows Installer 4.5" - "ProductCode" = "8:Microsoft.Windows.Installer.4.5" - } } } } @@ -90,11 +73,6 @@ "ComponentsUrl" = "8:" "Items" { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.4.5" - { - "Name" = "8:Windows Installer 4.5" - "ProductCode" = "8:Microsoft.Windows.Installer.4.5" - } } } } @@ -118,46 +96,6 @@ } "File" { - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4CC65BCBC5E4BCEFC5CD50D2515A9741" - { - "SourcePath" = "8:UxTheme.dll" - "TargetName" = "8:UxTheme.dll" - "Tag" = "8:" - "Folder" = "8:_41029E7D8E6B4E77BA5BF125181A456D" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:4" - "Exclude" = "11:TRUE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5A4B9DAFE9768CBB38DC6AFA6DEF49E9" - { - "SourcePath" = "8:COMDLG32.dll" - "TargetName" = "8:COMDLG32.dll" - "Tag" = "8:" - "Folder" = "8:_41029E7D8E6B4E77BA5BF125181A456D" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:TRUE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } } "FileType" { @@ -221,15 +159,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:Telemetry Monitor" - "ProductCode" = "8:{04AB3FA0-7088-4EDC-AAB7-EC6D4A8255BE}" - "PackageCode" = "8:{026F0220-A0B9-43CC-B2D2-C638FB00272B}" + "ProductCode" = "8:{00160BFD-98BE-428E-AB3F-7EF3307A79CB}" + "PackageCode" = "8:{AB572D2F-0CB2-4142-B095-426F98383122}" "UpgradeCode" = "8:{0059BDD4-CAF2-4273-B4E2-4446D5CA3E27}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.2.0" + "ProductVersion" = "8:1.2.1" "Manufacturer" = "8:Electron" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:http://www.wolfgang-rolke.de/gbxdump/" @@ -237,7 +175,7 @@ "Subject" = "8:TrackMania Telemetry Monitor (32-bit)" "ARPCONTACT" = "8:Electron" "Keywords" = "8:Installer,MSI,TMTelemetry,x86" - "ARPCOMMENTS" = "8:Copyright (c) 2017, 2018 by Electron" + "ARPCOMMENTS" = "8:Copyright (c) 2017-2019 by Electron" "ARPURLINFOABOUT" = "8:http://www.wolfgang-rolke.de/gbxdump/" "ARPPRODUCTICON" = "8:_E3461C036BF947D88556F74EC33D8DD0" "ARPIconIndex" = "3:102" @@ -324,7 +262,7 @@ "Condition" = "8:" "Transitive" = "11:FALSE" "ValueTypes" = "3:3" - "Value" = "3:16352" + "Value" = "3:32736" } "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_7BCC539048DF4342AFC4C44B25DD3DE9" { @@ -505,7 +443,7 @@ "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" - "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017, 2018 by Electron" + "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017-2019 by Electron" "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } @@ -766,7 +704,7 @@ "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" - "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017, 2018 by Electron" + "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017-2019 by Electron" "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } diff --git a/TMTelemetry.cpp b/TMTelemetry.cpp index 79621dd..288d628 100644 --- a/TMTelemetry.cpp +++ b/TMTelemetry.cpp @@ -35,6 +35,7 @@ TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The main window class name HWND hwndListView = NULL; // List-view control handle HWND hwndStatusBar = NULL; // Status bar control handle +HWND hwndTBSteering = NULL; // Trackbar control handle HWND hwndPBThrottle = NULL; // First progress bar control handle HWND hwndPBRumble = NULL; // Second progress bar control handle Nat32 uHeaderVersion = ECurVersion; // STelemetry header version @@ -228,6 +229,9 @@ void DoTelemetry(STelemetry* pTelemetry) static Nat32 uFullspeedTime = 0; // Total time at full throttle static Nat32 uFullspeedTimestamp = 0; // Full throttle timestamp static BOOL bIsFullspeed = FALSE; // Are we going full throttle right now? + static Nat32 uWheelSlipTime = 0; // Total time of wheel slippage + static Nat32 uWheelSlipTimestamp = 0; // Wheel slip timestamp + static BOOL bIsSlipping = FALSE; // Is a wheel slipping right now? static Nat32 uMaxNbCheckpoints = 0; // Highest number of CPs per game client // Static variables to save the current values of the used telemetry data records: @@ -247,9 +251,11 @@ void DoTelemetry(STelemetry* pTelemetry) static Nat32 uVehicleSpeedMeter = (Nat32)-1; static int nVehicleEngineCurGear = -1; static float fVehicleEngineRpm = -1.0f; + static float fVehicleInputSteer = -2.0f; // -1.0 is a regular value static float fVehicleInputGasPedal = -1.0f; static float fVehicleRumbleIntensity = -1.0f; static Bool bVehicleInputIsBraking = (Bool)-1; + static Bool aWheelsIsSliping[4] = { (Bool)-1, (Bool)-1, (Bool)-1, (Bool)-1 }; // Test for updated telemetry data records if (pTelemetry->UpdateNumber == uUpdateNumber) @@ -282,6 +288,7 @@ void DoTelemetry(STelemetry* pTelemetry) uVehicleSpeedMeter = (Nat32)-1; nVehicleEngineCurGear = -1; fVehicleEngineRpm = -1.0f; + fVehicleInputSteer = -2.0f; // -1.0 is a regular value fVehicleInputGasPedal = -1.0f; fVehicleRumbleIntensity = -1.0f; bVehicleInputIsBraking = (Bool)-1; @@ -291,6 +298,11 @@ void DoTelemetry(STelemetry* pTelemetry) for (int i = SBP_RACESTATE; i <= SBP_BRAKING; i++) StatusBar_SetText(hwndStatusBar, i, TEXT("")); + if (hwndTBSteering != NULL) + { + SendMessage(hwndTBSteering, TBM_CLEARSEL, (WPARAM)TRUE, 0); + SendMessage(hwndTBSteering, TBM_SETPOS, (WPARAM)TRUE, 0); + } if (hwndPBThrottle != NULL) SendMessage(hwndPBThrottle, PBM_SETPOS, 0, 0); if (hwndPBRumble != NULL) @@ -338,6 +350,10 @@ void DoTelemetry(STelemetry* pTelemetry) bIsFullspeed = pTelemetry->Vehicle.InputGasPedal >= uFullspeedThreshold / 100.0f; uFullspeedTime = 0; uFullspeedTimestamp = pTelemetry->Vehicle.Timestamp; + bIsSlipping = pTelemetry->Vehicle.WheelsIsSliping[0] || pTelemetry->Vehicle.WheelsIsSliping[1] || + pTelemetry->Vehicle.WheelsIsSliping[2] || pTelemetry->Vehicle.WheelsIsSliping[3]; + uWheelSlipTime = 0; + uWheelSlipTimestamp = pTelemetry->Vehicle.Timestamp; uMaxNbCheckpoints = 0; // Add a new race to the list-view control and increment the number of attempts @@ -388,6 +404,8 @@ void DoTelemetry(STelemetry* pTelemetry) if (bIsFullspeed) uFullspeedTime += pTelemetry->Vehicle.Timestamp - uFullspeedTimestamp; + if (bIsSlipping) + uWheelSlipTime += pTelemetry->Vehicle.Timestamp - uWheelSlipTimestamp; } else if (bAutoDelete && ListView_DeleteRace(hwndListView, nRaceNumber) && nRaceNumber > 0) nRaceNumber--; @@ -418,7 +436,7 @@ void DoTelemetry(STelemetry* pTelemetry) MultiByteToWideChar(CP_UTF8, 0, szMapName, -1, szText, _countof(szText)); // If a new map name exists, update the file name for data export if (_tcslen(szText) > 0) - _tcsncpy(szFileName, szText, _countof(szFileName)); + lstrcpyn(szFileName, szText, _countof(szFileName)); StatusBar_SetText(hwndStatusBar, SBP_MAPNAME, szText); } @@ -515,16 +533,35 @@ void DoTelemetry(STelemetry* pTelemetry) nNbGearchanges++; } + // Steering + if (pTelemetry->Vehicle.InputSteer != fVehicleInputSteer) + { + fVehicleInputSteer = pTelemetry->Vehicle.InputSteer; + + if (hwndTBSteering != NULL) + { + LPARAM lPos = (LPARAM)(fVehicleInputSteer * 100.0); + SendMessage(hwndTBSteering, TBM_SETSELSTART, (WPARAM)TRUE, fVehicleInputSteer < 0.0f ? lPos : 0); + SendMessage(hwndTBSteering, TBM_SETSELEND, (WPARAM)TRUE, fVehicleInputSteer < 0.0f ? 0 : lPos); + SendMessage(hwndTBSteering, TBM_SETPOS, (WPARAM)TRUE, lPos); + } + else + { + _sntprintf(szText, _countof(szText), szSteering, fVehicleInputSteer * 100.0); + StatusBar_SetText(hwndStatusBar, SBP_STEERING, szText, TRUE); + } + } + // Gas pedal if (pTelemetry->Vehicle.InputGasPedal != fVehicleInputGasPedal) { fVehicleInputGasPedal = pTelemetry->Vehicle.InputGasPedal; if (hwndPBThrottle != NULL) - SendMessage(hwndPBThrottle, PBM_SETPOS, (WPARAM)((fVehicleInputGasPedal * 100.0f) + 0.5f), 0); + SendMessage(hwndPBThrottle, PBM_SETPOS, (WPARAM)((fVehicleInputGasPedal * 100.0) + 0.5), 0); else { - _sntprintf(szText, _countof(szText), szGasPedal, fVehicleInputGasPedal * 100.0f); + _sntprintf(szText, _countof(szText), szGasPedal, fVehicleInputGasPedal * 100.0); StatusBar_SetText(hwndStatusBar, SBP_THROTTLE, szText, TRUE); } @@ -548,16 +585,40 @@ void DoTelemetry(STelemetry* pTelemetry) } } + // Wheel slip + if (memcmp(&pTelemetry->Vehicle.WheelsIsSliping, &aWheelsIsSliping, sizeof(aWheelsIsSliping)) != 0) + { + memcpy(&aWheelsIsSliping, &pTelemetry->Vehicle.WheelsIsSliping, sizeof(aWheelsIsSliping)); + + // Determine the percentage of time per race in which at least one wheel is slipping. + if (aWheelsIsSliping[0] || aWheelsIsSliping[1] || aWheelsIsSliping[2] || aWheelsIsSliping[3]) + { + if (!bIsSlipping) + { + bIsSlipping = TRUE; + uWheelSlipTimestamp = pTelemetry->Vehicle.Timestamp; + } + } + else + { + if (bIsSlipping) + { + bIsSlipping = FALSE; + uWheelSlipTime += pTelemetry->Vehicle.Timestamp - uWheelSlipTimestamp; + } + } + } + // Rumble intensity if (pTelemetry->Vehicle.RumbleIntensity != fVehicleRumbleIntensity) { fVehicleRumbleIntensity = pTelemetry->Vehicle.RumbleIntensity; if (hwndPBRumble != NULL) - SendMessage(hwndPBRumble, PBM_SETPOS, (WPARAM)((fVehicleRumbleIntensity * 100.0f) + 0.5f), 0); + SendMessage(hwndPBRumble, PBM_SETPOS, (WPARAM)((fVehicleRumbleIntensity * 100.0) + 0.5), 0); else { - _sntprintf(szText, _countof(szText), szRumbleIntensity, fVehicleRumbleIntensity * 100.0f); + _sntprintf(szText, _countof(szText), szRumbleIntensity, fVehicleRumbleIntensity * 100.0); StatusBar_SetText(hwndStatusBar, SBP_RUMBLE, szText, TRUE); } @@ -586,15 +647,15 @@ void DoTelemetry(STelemetry* pTelemetry) // Determine the number of braking operations with at least one wheel on the ground. // BUGBUG: The transition between air braking and ground contact is not detected. - if (bVehicleInputIsBraking && (pTelemetry->Vehicle.WheelsIsGroundContact[0] | pTelemetry->Vehicle.WheelsIsGroundContact[1] | - pTelemetry->Vehicle.WheelsIsGroundContact[2] | pTelemetry->Vehicle.WheelsIsGroundContact[3])) + if (bVehicleInputIsBraking && (pTelemetry->Vehicle.WheelsIsGroundContact[0] || pTelemetry->Vehicle.WheelsIsGroundContact[1] || + pTelemetry->Vehicle.WheelsIsGroundContact[2] || pTelemetry->Vehicle.WheelsIsGroundContact[3])) nNbBrakesUsed++; } // Map UID if (strcmp(pTelemetry->Game.MapId, szMapId) != 0) { - strncpy(szMapId, pTelemetry->Game.MapId, _countof(szMapId)); + lstrcpynA(szMapId, pTelemetry->Game.MapId, _countof(szMapId)); // Clear all races after map changes if (strcmp(szMapId, "Unassigned") != 0) @@ -633,6 +694,9 @@ void DoTelemetry(STelemetry* pTelemetry) if (dwColumns & COL_FULLSPEED) ListView_AddRaceData(hwndListView, nRaceNumber, COLUMN_AUTOFIT, szFullspeed, TEXT("%d %%"), MulDiv(100, uFullspeedTime, uRaceTime)); + + if (dwColumns & COL_WHEELSLIP) + ListView_AddRaceData(hwndListView, nRaceNumber, COLUMN_AUTOFIT, szWheelSlip, TEXT("%d %%"), MulDiv(100, uWheelSlipTime, uRaceTime)); } } @@ -854,14 +918,24 @@ BOOL WndProc_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) SetWindowFont(hwndStatusBar, GetStockFont(DEFAULT_GUI_FONT), FALSE); // Set the number of parts and the coordinate of the right edge of each part - int aStatusBarParts[14] = { 125, 235, 385, 480, 555, 605, 650, 715, 790, 850, 940, 1030, 1090, -1 }; + int aStatusBarParts[15] = { 125, 235, 385, 480, 555, 605, 650, 715, 790, 850, 940, 1030, 1120, 1180, -1 }; SIZE_T uParts = _countof(aStatusBarParts); for (SIZE_T i = 0; i < (uParts - 1); i++) aStatusBarParts[i] = MulDiv(aStatusBarParts[i], nDpi, USER_DEFAULT_SCREEN_DPI); SendMessage(hwndStatusBar, SB_SETPARTS, uParts, (LPARAM)&aStatusBarParts); - // Create progress bar controls for throttle and rumble. + // Create trackbar and progress bar controls for steering, throttle and rumble. // These controls are optional. If an error occurs, the parent window should still be created. + if ((hwndTBSteering = CreateWindow(TRACKBAR_CLASS, TEXT(""), + WS_CHILD | WS_VISIBLE | WS_DISABLED | TBS_HORZ | TBS_BOTH | TBS_NOTICKS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH, + 0, 0, 0, 0, hwndStatusBar, (HMENU)ID_TRACKBAR, lpCreateStruct->hInstance, NULL)) != NULL) + { + SendMessage(hwndTBSteering, TBM_SETRANGEMIN, (WPARAM)FALSE, -100); + SendMessage(hwndTBSteering, TBM_SETRANGEMAX, (WPARAM)FALSE, 100); + SendMessage(hwndTBSteering, TBM_CLEARSEL, (WPARAM)FALSE, 0); + SendMessage(hwndTBSteering, TBM_SETPOS, (WPARAM)FALSE, 0); + } + if ((hwndPBThrottle = CreateWindow(PROGRESS_CLASS, TEXT(""), WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 0, 0, 0, 0, hwndStatusBar, (HMENU)ID_PROGRESS1, lpCreateStruct->hInstance, NULL)) != NULL) { @@ -1000,6 +1074,10 @@ void WndProc_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) dwColumns ^= COL_FULLSPEED; break; + case ID_VIEW_WHEELSLIP: + dwColumns ^= COL_WHEELSLIP; + break; + case ID_VIEW_AUTOFITCOLUMNS: ListView_AutoSizeAllColumns(hwndListView); break; @@ -1128,6 +1206,9 @@ void WndProc_OnInitMenuPopup(HWND hwnd, HMENU hMenu, UINT item, BOOL fSystemMenu uFlags = (dwColumns & COL_FULLSPEED) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(hMenu, ID_VIEW_FULLSPEED, MF_BYCOMMAND | uFlags); + uFlags = (dwColumns & COL_WHEELSLIP) ? MF_CHECKED : MF_UNCHECKED; + CheckMenuItem(hMenu, ID_VIEW_WHEELSLIP, MF_BYCOMMAND | uFlags); + uFlags = (ListView_GetColumnCount(hwndListView) > 0) ? MF_ENABLED : MF_DISABLED | MF_GRAYED; EnableMenuItem(hMenu, ID_VIEW_AUTOFITCOLUMNS, uFlags); break; @@ -1221,8 +1302,17 @@ void WndProc_OnSize(HWND hwnd, UINT state, int cx, int cy) // Forward this message to the status bar to automatically adjust its position and size FORWARD_WM_SIZE(hwndStatusBar, state, cx, cy, SendMessage); + GetWindowRect(hwndStatusBar, &rcStatusBar); + // Place the "Steering" trackbar in the part with index SBP_STEERING + if (hwndTBSteering != NULL && SendMessage(hwndStatusBar, SB_GETRECT, SBP_STEERING, (LPARAM)&rcPart)) + { + MoveWindow(hwndTBSteering, rcPart.left, rcPart.top, rcPart.right - rcPart.left - 1, + rcPart.bottom - rcPart.top - 1, TRUE); + SendMessage(hwndTBSteering, TBM_SETTHUMBLENGTH, rcPart.bottom - rcPart.top - 4, 0); + } + // Place the "Throttle" progress bar in the part with index SBP_THROTTLE if (hwndPBThrottle != NULL && SendMessage(hwndStatusBar, SB_GETRECT, SBP_THROTTLE, (LPARAM)&rcPart)) MoveWindow(hwndPBThrottle, rcPart.left, rcPart.top, rcPart.right - rcPart.left - 1, @@ -1249,6 +1339,8 @@ void WndProc_OnSysColorChange(HWND hwnd) // Forward this message to all common controls FORWARD_WM_SYSCOLORCHANGE(hwndListView, PostMessage); FORWARD_WM_SYSCOLORCHANGE(hwndStatusBar, PostMessage); + if (hwndTBSteering != NULL) + FORWARD_WM_SYSCOLORCHANGE(hwndTBSteering, PostMessage); if (hwndPBThrottle != NULL) FORWARD_WM_SYSCOLORCHANGE(hwndPBThrottle, PostMessage); if (hwndPBRumble != NULL) @@ -1288,15 +1380,18 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { case WM_INITDIALOG: { - TCHAR szText[256]; + TCHAR szText[MAX_CONTROLTEXT]; - _sntprintf(szText, _countof(szText), szFmtTmIfVer, uHeaderVersion); + _sntprintf(szText, _countof(szText) - 1, szFmtTmIfVer, uHeaderVersion); + szText[MAX_CONTROLTEXT-1] = TEXT('\0'); SetDlgItemText(hDlg, IDC_TELEMETRY_VERSION, szText); - _sntprintf(szText, _countof(szText), szFmtRumbleTh, uRumbleThreshold); + _sntprintf(szText, _countof(szText) - 1, szFmtRumbleTh, uRumbleThreshold); + szText[MAX_CONTROLTEXT - 1] = TEXT('\0'); SetDlgItemText(hDlg, IDC_RUMBLE_THRESHOLD, szText); - _sntprintf(szText, _countof(szText), szFmtThrottleTh, uFullspeedThreshold); + _sntprintf(szText, _countof(szText) - 1, szFmtThrottleTh, uFullspeedThreshold); + szText[MAX_CONTROLTEXT - 1] = TEXT('\0'); SetDlgItemText(hDlg, IDC_FULLSPEED_THRESHOLD, szText); } return (INT_PTR)TRUE; @@ -1327,6 +1422,8 @@ int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { TCHAR szSortText1[MAX_CONTROLTEXT]; TCHAR szSortText2[MAX_CONTROLTEXT]; + szSortText1[0] = TEXT('\0'); + szSortText2[0] = TEXT('\0'); ListView_GetItemText(hwndListView, lParam1, LOWORD(lParamSort), HIWORD(lParamSort) ? szSortText2 : szSortText1, MAX_CONTROLTEXT - 1); diff --git a/TMTelemetry.exe.manifest b/TMTelemetry.exe.manifest index be30c02..9d474b2 100644 --- a/TMTelemetry.exe.manifest +++ b/TMTelemetry.exe.manifest @@ -1,6 +1,6 @@ - + TMTelemetry diff --git a/TMTelemetry.h b/TMTelemetry.h index b8f2851..7b9df33 100644 --- a/TMTelemetry.h +++ b/TMTelemetry.h @@ -17,7 +17,8 @@ #define COL_GEARCHANGES 0x0800 #define COL_BRAKESUSED 0x1000 #define COL_FULLSPEED 0x2000 -#define COL_DEFAULT (COL_SECTORTIMES | COL_CHECKPOINTS | COL_RACETIME | COL_TOPSPEED | COL_RESPAWNS | COL_RUMBLES | COL_GEARCHANGES | COL_BRAKESUSED | COL_FULLSPEED) +#define COL_WHEELSLIP 0x4000 +#define COL_DEFAULT (COL_SECTORTIMES | COL_CHECKPOINTS | COL_RACETIME | COL_TOPSPEED | COL_RESPAWNS | COL_RUMBLES | COL_GEARCHANGES | COL_BRAKESUSED | COL_FULLSPEED | COL_WHEELSLIP) // Status bar part indices typedef enum _STATUSBAR_PART @@ -32,6 +33,7 @@ typedef enum _STATUSBAR_PART SBP_SPEEDMETER, SBP_ENGINERPM, SBP_CURGEAR, + SBP_STEERING, SBP_THROTTLE, SBP_RUMBLE, SBP_BRAKING, diff --git a/TMTelemetry.rc b/TMTelemetry.rc index dfe044c5cf40858a93b6c7dc2537635d2cd0ad23..f190981cb87f7b0d69f64325ab5b3020b2424cf9 100644 GIT binary patch delta 188 zcmcap*igJ-5BuaD>`j}^IAZuG3vjathcjd_qyk|Mg91Y^kj!K#n9MJ(KDj}LZE}Mk zmtZ)92ZJjR`T%8p7(5vQCMOD6PCg@SwfT(r33he^1|0??27}3g3i^{3j4gN-7z`Qo zfFgQ8T4{2wyyWD23T%_L6v{YtLF#~_mYY{AZ02G&1Zp&7FxZ@|Ey@h!fYcjI-l(fP Ud6nKegxblg6{I)U>Bn&b0Cj0CIRF3v delta 116 zcmZoDzEiki5BuZ;>~)iGX|37(j$;kqxeP~nR*PClP4PJP7csthpck4ucGwi2tBRM IJ_aV70P{;BL;wH) diff --git a/TMTelemetry.vcxproj b/TMTelemetry.vcxproj index 86ef075..68857c0 100644 --- a/TMTelemetry.vcxproj +++ b/TMTelemetry.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,31 +22,32 @@ {8B78BFBC-A1B6-4C44-8295-5F57717BF3C6} Win32Proj TMTelemetry + 10.0.17763.0 Application true - v120 + v141 Unicode Application true - v120 + v141 Unicode Application false - v120 + v141 true Unicode Application false - v120 + v141 true Unicode @@ -83,7 +84,7 @@ Use Level3 Disabled - WIN32;_DEBUG;_WINDOWS;_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true @@ -96,7 +97,7 @@ %(AdditionalManifestFiles) - _USING_V110_SDK71_;%(PreprocessorDefinitions) + %(PreprocessorDefinitions) @@ -104,7 +105,7 @@ Use Level3 Disabled - WIN32;_DEBUG;_WINDOWS;_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true @@ -117,7 +118,7 @@ %(AdditionalManifestFiles) - _USING_V110_SDK71_;%(PreprocessorDefinitions) + %(PreprocessorDefinitions) @@ -127,7 +128,7 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded Speed @@ -138,13 +139,14 @@ true true comctl32.lib;WinMM.Lib;Uxtheme.lib;%(AdditionalDependencies) + /PDBALTPATH:%_PDB% %(AdditionalOptions) PerMonitorHighDPIAware %(AdditionalManifestFiles) - _USING_V110_SDK71_;%(PreprocessorDefinitions) + %(PreprocessorDefinitions) @@ -154,7 +156,7 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded Speed @@ -165,13 +167,14 @@ true true comctl32.lib;WinMM.Lib;Uxtheme.lib;%(AdditionalDependencies) + /PDBALTPATH:%_PDB% %(AdditionalOptions) PerMonitorHighDPIAware %(AdditionalManifestFiles) - _USING_V110_SDK71_;%(PreprocessorDefinitions) + %(PreprocessorDefinitions) diff --git a/x64/Setup/Setup64.vdproj b/x64/Setup/Setup64.vdproj index 4f6c4d9..0ed6489 100644 --- a/x64/Setup/Setup64.vdproj +++ b/x64/Setup/Setup64.vdproj @@ -19,18 +19,6 @@ "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } - "Entry" - { - "MsmKey" = "8:_665FB403A6D4043E012DB9F6B0476849" - "OwnerKey" = "8:_65858AAF14D941598EF861AABF1E2E6B" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_DD522C5831B97ADF6D196D3D5C9B6CEB" - "OwnerKey" = "8:_65858AAF14D941598EF861AABF1E2E6B" - "MsmSig" = "8:_UNDEFINED" - } } "Configurations" { @@ -58,11 +46,6 @@ "ComponentsUrl" = "8:" "Items" { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.4.5" - { - "Name" = "8:Windows Installer 4.5" - "ProductCode" = "8:Microsoft.Windows.Installer.4.5" - } } } } @@ -90,11 +73,6 @@ "ComponentsUrl" = "8:" "Items" { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.4.5" - { - "Name" = "8:Windows Installer 4.5" - "ProductCode" = "8:Microsoft.Windows.Installer.4.5" - } } } } @@ -118,46 +96,6 @@ } "File" { - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_665FB403A6D4043E012DB9F6B0476849" - { - "SourcePath" = "8:UxTheme.dll" - "TargetName" = "8:UxTheme.dll" - "Tag" = "8:" - "Folder" = "8:_CC5F076D042B49EF8560C5B595324D12" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:4" - "Exclude" = "11:TRUE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DD522C5831B97ADF6D196D3D5C9B6CEB" - { - "SourcePath" = "8:COMDLG32.dll" - "TargetName" = "8:COMDLG32.dll" - "Tag" = "8:" - "Folder" = "8:_CC5F076D042B49EF8560C5B595324D12" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:TRUE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } } "FileType" { @@ -221,15 +159,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:Telemetry Monitor" - "ProductCode" = "8:{0944F553-25F9-45BF-9E03-674EBC7CC797}" - "PackageCode" = "8:{4DA28E79-8613-4A79-8ECA-4D24D1080213}" + "ProductCode" = "8:{00FE5A51-EEB8-4497-A5A6-3288D766DF63}" + "PackageCode" = "8:{7572FA07-79EA-4816-B2D7-30C4B111AFF2}" "UpgradeCode" = "8:{00BD5903-7DBA-499A-9EBA-FB56272E257D}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.2.0" + "ProductVersion" = "8:1.2.1" "Manufacturer" = "8:Electron" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:http://www.wolfgang-rolke.de/gbxdump/" @@ -237,7 +175,7 @@ "Subject" = "8:TrackMania Telemetry Monitor (64-bit)" "ARPCONTACT" = "8:Electron" "Keywords" = "8:Installer,MSI,TMTelemetry,x64" - "ARPCOMMENTS" = "8:Copyright (c) 2017, 2018 by Electron" + "ARPCOMMENTS" = "8:Copyright (c) 2017-2019 by Electron" "ARPURLINFOABOUT" = "8:http://www.wolfgang-rolke.de/gbxdump/" "ARPPRODUCTICON" = "8:_65858AAF14D941598EF861AABF1E2E6B" "ARPIconIndex" = "3:102" @@ -324,7 +262,7 @@ "Condition" = "8:" "Transitive" = "11:FALSE" "ValueTypes" = "3:3" - "Value" = "3:16352" + "Value" = "3:32736" } "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_34DE3363F08841DBAF0C61073B9C7C8D" { @@ -490,7 +428,7 @@ "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" - "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017, 2018 by Electron" + "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017-2019 by Electron" "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } @@ -597,7 +535,7 @@ "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" - "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017, 2018 by Electron" + "Value" = "8:TrackMania Telemetry Monitor, Copyright © 2017-2019 by Electron" "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } @@ -795,7 +733,7 @@ { "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_65858AAF14D941598EF861AABF1E2E6B" { - "SourcePath" = "8:" + "SourcePath" = "8:..\\Release\\TMTelemetry.exe" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_CC5F076D042B49EF8560C5B595324D12"