that was the approach I was thinking, I can get the speed in rads/sec from your plugin (I think Rf2 does simulate ABS - I can feel the pulsing in my motion sim when you brake very hard)
Hi Guys i have been making some progress - code is attached below for my Hello World App to talk to the memory map there are some odd things happening the first few variables are : mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves) mDeltaTime : double ;// # time since last update (seconds) mElapsedTime : double ;// # game session time mLapNumber : integer ;// # current lap number mLapStartET : double ;// # time this lap was started mVehicleName : array[0..63] of byte ; // # current vehicle name mTrackName : array[0..63] of byte ; // # current track name mPos : rF2Vec3 ; // # world position in meters should mID constantly change ? - the first 3 numbers seem to increment slowly but the last 3 are a bit random mDeltaTime - this number seem to stay the same is it to do with a previous lap time ? mElapsedTime - this number is jumping from a positive to a negative number mLapNumber - seems to stay at zero etc the Vehicle name and track Name seem to be padded with random characters in front and behind that change is this normal - or have I done something wrong ? (the mpos for track position x,y,z seems ok for example) ------------------------------------------------------------------------------------------------------------------------ unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) BtnRead: TButton; ListBox1: TListBox; Timer1: TTimer; Edit1: TEdit; Edit2: TEdit; Memo1: TMemo; Memo2: TMemo; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; procedure Button1Click(Sender: TObject); procedure BtnReadClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; type rF2Vec3 = Record x : double ; y : double ; z : double ; end ; type rF2Wheel = Record mSuspensionDeflection : double ;// # meters mRideHeight: double ;// # meters mSuspForce : double ;// # pushrod load in Newtons mBrakeTemp : double ;// # Celsius mBrakePressure : double ;// # currently 0.0-1.0, depending on driver input and brake balance; will convert to true brake pressure (kPa) in future mRotation : double ;// # radians/sec mLateralPatchVel : double ;// # lateral velocity at contact patch mLongitudinalPatchVel : double ;// # longitudinal velocity at contact patch mLateralGroundVel : double ;// # lateral velocity at contact patch mLongitudinalGroundVel : double ;// # longitudinal velocity at contact patch mCamber : double ;// # radians (positive is left for left-side wheels, right for right-side wheels) mLateralForce : double ; // # Newtons mLongitudinalForce : double ; // # Newtons mTireLoad : double ; // # Newtons mGripFract : double ; // # an approximation of what fraction of the contact patch is sliding mPressure : double ;// # kPa (tire pressure) mTemperature : array[0..3] of double ; // # Kelvin (subtract 273.15 to get Celsius), left/center/right (not to be confused with inside/center/outside!) mWear : double ; // # wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss mTerrainName : integer ; // # the material prefixes from the TDF file mSurfaceType : byte ; // # 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip, 6 = special mFlat : byte ;// # whether tire is flat mDetached : byte ; // # whether wheel is detached mStaticUndeflectedRadius : byte ;// # tire radius in centimeters mVerticalTireDeflection : double ;// # how much is tire deflected from its (speed-sensitive) radius mWheelYLocation : double ;// # wheel's y location relative to vehicle y location mToe : double ;// # current toe angle w.r.t. the vehicle mTireCarcassTemperature : double ;// # rough average of temperature samples from carcass (Kelvin) mTireInnerLayerTemperature : array[0..3] of double ; // # rough average of temperature samples from innermost layer of rubber (before carcass) (Kelvin) mExpansion : integer ;// # for future use end; type PRecordInfo = ^TRecordInfo; TRecordInfo = packed record mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves) mDeltaTime : double ;// # time since last update (seconds) mElapsedTime : double ;// # game session time mLapNumber : integer ;// # current lap number mLapStartET : double ;// # time this lap was started mVehicleName : array[0..63] of byte ; // # current vehicle name mTrackName : array[0..63] of byte ; // # current track name mPos : rF2Vec3 ; // # world position in meters mLocalVel : rF2Vec3 ; // # velocity (meters/sec) in local vehicle coordinates mLocalAccel : rF2Vec3 ; // # acceleration (meters/sec^2) in local vehicle coordinates mOri : array [0..2] of RF2Vec3 ; // , # rows of orientation matrix (use TelemQuat conversions if desired), also converts local mLocalRot : rF2Vec3 ; // # rotation (radians/sec) in local vehicle coordinates mLocalRotAccel : rF2Vec3 ; //), # rotational acceleration (radians/sec^2) in local vehicle coordinates mGear : integer ; // # -1=reverse, 0=neutral, 1+ = forward gears mEngineRPM : double ; // # engine RPM mEngineWaterTemp : double ; // # Celsius mEngineOilTemp : double ; // # Celsius mClutchRPM : double ; // # clutch RPM mUnfilteredThrottle : double ; // # ranges 0.0-1.0 mUnfilteredBrake : double ; // # ranges 0.0-1.0 mUnfilteredSteering : double ; // # ranges -1.0-1.0 (left to right) mUnfilteredClutch : double ; // # ranges 0.0-1.0 mFilteredThrottle : double ; // mFilteredBrake : double ;// # ranges 0.0-1.0 mFilteredSteering : double ; // # ranges -1.0-1.0 (left to right) mFilteredClutch : double ; // # ranges 0.0-1.0 mSteeringShaftTorque : double ; // # torque around steering shaft (used to be mSteeringArmForce, but that is not necessarily accurate for feedback purposes) mFront3rdDeflection : double ; // # deflection at front 3rd spring mRear3rdDeflection : double ; // # deflection at rear 3rd spring mFrontWingHeight : double ; // # front wing height mFrontRideHeight : double ; // # front ride height mRearRideHeight : double ; // # rear ride height mDrag : double ; // # drag mFrontDownforce : double ;// # front downforce mRearDownforce : double ;// # rear downforce mFuel : double ; // # amount of fuel (liters) mEngineMaxRPM : double ; // # rev limit mScheduledStops : byte ; // # number of scheduled pitstops mOverheating : byte ; // # whether overheating icon is shown mDetached : byte ; // # whether any parts (besides wheels) have been detached mHeadlights :byte ; // # whether headlights are on mDentSeverity : array [0..7] of integer ; // # dent severity at 8 locations around the car (0=none, 1=some, 2=more) mLastImpactET : double ; // # time of last impact mLastImpactMagnitude : double ; // # magnitude of last impact mLastImpactPos : rF2Vec3 ; // # location of last impact mEngineTorque : double ; // # current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it) mCurrentSector : integer ; // # the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002) mSpeedLimiter : byte ; // # whether speed limiter is on mMaxGears : byte ;// # maximum forward gears mFrontTireCompoundIndex : integer ;// # index within brand mRearTireCompoundIndex : integer ; // # index within brand mFuelCapacity : double ;// # capacity in liters mFrontFlapActivated : integer ;// # whether front flap is activated mRearFlapActivated : integer ; // # whether rear flap is activated mRearFlapLegalStatus : integer ; // # 0=disallowed, 1=criteria detected but not allowed quite yet, 2 = allowed mIgnitionStarter : integer ; // # 0=off 1=ignition 2 = ignition+starter mFrontTireCompoundName : array [0..17] of integer ; // # name of front tire compound mRearTireCompoundName : array [0..17] of integer ; // # name of rear tire compound mSpeedLimiterAvailable : integer ; // # whether speed limiter is available mAntiStallActivated : integer ; // # whether (hard) anti-stall is activated mUnused : integer ; // # mVisualSteeringWheelRange : double ; // # the *visual* steering wheel range mRearBrakeBias : double ; // # fraction of brakes on rear mTurboBoostPressure : double ; // # current turbo boost pressure if available mPhysicsToGraphicsOffset : array [0..2] of double ; // # offset from static CG to graphical center mPhysicalSteeringWheelRange : double ; // # the *physical* steering wheel range mExpansion : array [0..151] of integer ; // # for future use (note that the slot ID has been moved to mID above) mWheels : array[0..3] of rF2Wheel ; // # wheel info (front left, front right, rear left, rear right) end; var Form1: TForm1; FMappingHandle : THandle = 0; FRecordInfo : PRecordInfo= nil; FMappingName : String = '$rFactor2SMMP_Telemetry$'; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin //{ To Create a Mapping File } //FMappingHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TRecordInfo), @FMappingName[1]); //FRecordInfo := MapViewOfFile(FMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TRecordInfo)); //FRecordInfo.Field1 := 'Value 1'; //FRecordInfo.Field2 := 0; //FRecordInfo.Field3 := 1; end; procedure TForm1.BtnReadClick(Sender: TObject); var I : integer ; TempStr : String ; begin { To Open the Memory Map File } FMappingName := '$rFactor2SMMP_Telemetry$'; FMappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, false, @FMappingName[1]); { To Read the File Contents} FRecordInfo := MapViewOfFile(FMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TRecordInfo)); //edit1.Text := FRecordInfo^.Field1;//Read the Contents //edit2.Text := FRecordInfo^.Field2;//Read the Contents //edit3.Text := FRecordInfo^.Field3;//Read the Contents listbox1.Clear ; listbox1.Items.Add(inttoStr(FRecordInfo^.mID)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mLapNumber)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mGear)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mScheduledStops)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mOverheating)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mDetached)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mHeadlights)) ; listbox1.Items.Add(char(FRecordInfo^.mDentSeverity[0])) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mCurrentSector)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mSpeedLimiter)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mMaxGears)) ; listbox1.Items.Add(inttoStr(FRecordInfo^.mSpeedLimiterAvailable)) ; listbox1.Items.Add(floattoStr(FRecordInfo^.mEngineWaterTemp)) ; listbox1.Items.Add(floattoStr(FRecordInfo^.mEngineRPM)) ; TempStr := '' ; memo1.Text := '' ; for I := 0 to 63 do begin TempStr := Char(FRecordInfo^.mVehicleName) ; memo1.Text := Memo1.Text + char((FRecordInfo^.mVehicleName) ); end ; Edit1.Text := TempStr ; TempStr := '' ; memo2.Text := '' ; for I := 0 to 63 do begin TempStr := char(FRecordInfo^.mTrackName) ; memo2.Text := Memo2.Text + char((FRecordInfo^.mTrackName) ); end ; Edit2.Text := TempStr ; edit3.Text := floattostr(FRecordInfo^.mpos.x); edit4.text := floattoStr(FRecordInfo^.mpos.y); edit5.text := floattoStr(FRecordInfo^.mpos.z); end; procedure TForm1.Timer1Timer(Sender: TObject); begin BtnRead.Click ; end; end.
i did not get a reply to my last post - so i hope a video might spark a reply we are looking at the first few items of the memorymap mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves) mDeltaTime : double ;// # time since last update (seconds) mElapsedTime : double ;// # game session time mLapNumber : integer ;// # current lap number mLapStartET : double ;// # time this lap was started mVehicleName : array[0..63] of byte ; // # current vehicle name mTrackName : array[0..63] of byte ; // # current track name pls take a look at the video to see what i am talking about interestingly brake seems to come out as Engine rpm !
finally some progress ! by padding the memory map with an extra field of 8 bytes, the vehicle description and track name seem to line up and from that point forwards the data appears to correspond to the item it is supposed to be rpm etc etc ....... pad1 : array[0..7] of byte ; // mID : Integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves) mDeltaTime : double ;// # time since last update (seconds) mElapsedTime : double ;// mLapNumber : Integer ;// # current lap number mLapStartET : double ;// # time this lap was started mVehicleName : array[0..63] of byte ; // # current vehicle name mTrackName : array[0..63] of byte ; // # current track name mPos : rF2Vec3 ; // # world position in meters mLocalVel : rF2Vec3 ; // # velocity (meters/sec) in local vehicle coordinates mLocalAccel : rF2Vec3 ; // # acceleration (meters/sec^2) in local vehicle coordinates mOri : array [0..2] of RF2Vec3 ; // , # rows of orientation matrix (use TelemQuat conversions if desired), also converts local mLocalRot : rF2Vec3 ; // # rotation (radians/sec) in local vehicle coordinates mLocalRotAccel : rF2Vec3 ; //), # rotational acceleration (radians/sec^2) in local vehicle coordinates mGear : integer ; // # -1=reverse, 0=neutral, 1+ = forward gears mEngineRPM : double ; // # engine RPM etc etc so why did i have to add this pad to space the data out ?? I guess a delphi data type and a C++ data type are different in the number of bytes they use Any suggestion ?