PDA

View Full Version : PCARS SharedMemory API - Documentation/Reference?



Zearom
08-05-2015, 12:54
Hello everyone!

currently i want to add pcars support to my arduino based shifting light, but all links i found are redirecting to the the wmd-boards which are not available for non-wmd-members. On Github are only some non working drafts from old versions of the api…

Is somewhere a documentation or reference for the pcars shared memory api available?

Thx for your support!

Mad Al
08-05-2015, 13:15
Assuming this is now open for public consumption... basically mostly a cut and paste from the WMD

Desciption:
Shared memory (in pCars) is basically an in-memory file which contains lots of various real-time information about the game, ie- physics state, car speed, best lap time, wind direction, etc. It's currently updated every render frame. The purpose for this 'in memory file' is to share this real-time data with your external hardware. This could range from cockpit simulators, telemetry calculations, to additional info displays. So this is: literally "Created by you"


Here are the techy details....

The shared memory is implemented in the same way we did it 10+ years ago- using a Memory-Mapped file (easier understood as an in-memory file). In memory file is named "$pcars$".

It's updated every render frame, so this really depends on your user settings; ie; Resolution: 'Hz'.

It's turned off by default, and switched on via the Main Menu options screen, under 'Help&Options'->'Gameplay'->'Use Shared Memory'.

The data structure is defined in "SharedMemory.h" (below & attached here:SharedMemoryV5.rar). You should be able to simply drop it into a C/C++ project with little difficulty. Or instead you could refer to it as a guideline/map/template if you're using other languages.

.....


I've also added a version number to it, which we'll increment with future versions when appropriate.

Also, to make your lives a bit easier I've attached a small sample project (SMS_MemMap_SampleV5.rar), which just keeps printing a value from the data until you press ESC.

Below is the latest SharedMemory.h





/*************************************************************************************************
Description:
Storage structure for storing and updating shared memory

Copyright (c) MWL. All rights reserved.
*************************************************************************************************/

#ifndef _SHARED_MEMORY_HPP_
#define _SHARED_MEMORY_HPP_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTES:
//
// -The shared memory variables will be updated once per graphics frame.
//
// -Each variable comes with a UNIT, RANGE, and UNSET description where applicable.
// UNITS - Is the numeric form which a variable is stored in (e.g. KPH, Celsius)
// RANGE - Is the min-max ranges for a variable
// UNSET - Is the initialised/default/invalid value, depending on the variables usage
//
// -Constant/unchanging values are included in the data, such as 'maxRPM', 'fuelCapacity' - this is done to allow percentage calculations.
//
// -Also included are 12 unique enumerated types, to be used against the mentioned flag/state variables
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// *** Types ***

// Header version number to test against
enum
{
SHARED_MEMORY_VERSION = 5
};

// Maximum allowed length of string
enum
{
STRING_LENGTH_MAX = 64
};

// Maximum number of general participant information allowed to be stored in memory-mapped file
enum
{
STORED_PARTICIPANTS_MAX = 64
};

// Tyres
enum
{
TYRE_FRONT_LEFT = 0,
TYRE_FRONT_RIGHT,
TYRE_REAR_LEFT,
TYRE_REAR_RIGHT,
//--------------
TYRE_MAX
};

// Vector
enum
{
VEC_X = 0,
VEC_Y,
VEC_Z,
//-------------
VEC_MAX
};

// (Type#1) GameState (to be used with 'mGameState')
enum
{
GAME_EXITED = 0,
GAME_FRONT_END,
GAME_INGAME_PLAYING,
GAME_INGAME_PAUSED,
GAME_INGAME_RESTARTING,
GAME_INGAME_REPLAY,
GAME_FRONT_END_REPLAY,
//-------------
GAME_MAX
};

// (Type#2) Session state (to be used with 'mSessionState')
enum
{
SESSION_INVALID = 0,
SESSION_PRACTICE,
SESSION_TEST,
SESSION_QUALIFY,
SESSION_FORMATION_LAP,
SESSION_RACE,
SESSION_TIME_ATTACK,
//-------------
SESSION_MAX
};

// (Type#3) RaceState (to be used with 'mRaceState')
enum
{
RACESTATE_INVALID,
RACESTATE_NOT_STARTED,
RACESTATE_RACING,
RACESTATE_FINISHED,
RACESTATE_DISQUALIFIED,
RACESTATE_RETIRED,
RACESTATE_DNF,
//-------------
RACESTATE_MAX
};

// (Type#4) Current Sector (to be used with 'mCurrentSector')
enum
{
SECTOR_INVALID = 0,
SECTOR_START,
SECTOR_SECTOR1,
SECTOR_SECTOR2,
SECTOR_FINISH,
SECTOR_STOP,
//-------------
SECTOR_MAX
};

// (Type#5) Flag Colours (to be used with 'mHighestFlagColour')
enum
{
FLAG_COLOUR_NONE = 0, // Not used for actual flags, only for some query functions
FLAG_COLOUR_GREEN, // End of danger zone, or race started
FLAG_COLOUR_BLUE, // Faster car wants to overtake the participant
FLAG_COLOUR_WHITE, // Approaching a slow car
FLAG_COLOUR_YELLOW, // Danger on the racing surface itself
FLAG_COLOUR_DOUBLE_YELLOW, // Danger that wholly or partly blocks the racing surface
FLAG_COLOUR_BLACK, // Participant disqualified
FLAG_COLOUR_CHEQUERED, // Chequered flag
//-------------
FLAG_COLOUR_MAX
};

// (Type#6) Flag Reason (to be used with 'mHighestFlagReason')
enum
{
FLAG_REASON_NONE = 0,
FLAG_REASON_SOLO_CRASH,
FLAG_REASON_VEHICLE_CRASH,
FLAG_REASON_VEHICLE_OBSTRUCTION,
//-------------
FLAG_REASON_MAX
};

// (Type#7) Pit Mode (to be used with 'mPitMode')
enum
{
PIT_MODE_NONE = 0,
PIT_MODE_DRIVING_INTO_PITS,
PIT_MODE_IN_PIT,
PIT_MODE_DRIVING_OUT_OF_PITS,
PIT_MODE_IN_GARAGE,
//-------------
PIT_MODE_MAX
};

// (Type#8) Pit Stop Schedule (to be used with 'mPitSchedule')
enum
{
PIT_SCHEDULE_NONE = 0, // Nothing scheduled
PIT_SCHEDULE_STANDARD, // Used for standard pit sequence
PIT_SCHEDULE_DRIVE_THROUGH, // Used for drive-through penalty
PIT_SCHEDULE_STOP_GO, // Used for stop-go penalty
//-------------
PIT_SCHEDULE_MAX
};

// (Type#9) Car Flags (to be used with 'mCarFlags')
enum
{
CAR_HEADLIGHT = (1<<0),
CAR_ENGINE_ACTIVE = (1<<1),
CAR_ENGINE_WARNING = (1<<2),
CAR_SPEED_LIMITER = (1<<3),
CAR_ABS = (1<<4),
CAR_HANDBRAKE = (1<<5),
};

// (Type#10) Tyre Flags (to be used with 'mTyreFlags')
enum
{
TYRE_ATTACHED = (1<<0),
TYRE_INFLATED = (1<<1),
TYRE_IS_ON_GROUND = (1<<2),
};

// (Type#11) Terrain Materials (to be used with 'mTerrain')
enum
{
TERRAIN_ROAD = 0,
TERRAIN_LOW_GRIP_ROAD,
TERRAIN_BUMPY_ROAD1,
TERRAIN_BUMPY_ROAD2,
TERRAIN_BUMPY_ROAD3,
TERRAIN_MARBLES,
TERRAIN_GRASSY_BERMS,
TERRAIN_GRASS,
TERRAIN_GRAVEL,
TERRAIN_BUMPY_GRAVEL,
TERRAIN_RUMBLE_STRIPS,
TERRAIN_DRAINS,
TERRAIN_TYREWALLS,
TERRAIN_CEMENTWALLS,
TERRAIN_GUARDRAILS,
TERRAIN_SAND,
TERRAIN_BUMPY_SAND,
TERRAIN_DIRT,
TERRAIN_BUMPY_DIRT,
TERRAIN_DIRT_ROAD,
TERRAIN_BUMPY_DIRT_ROAD,
TERRAIN_PAVEMENT,
TERRAIN_DIRT_BANK,
TERRAIN_WOOD,
TERRAIN_DRY_VERGE,
TERRAIN_EXIT_RUMBLE_STRIPS,
TERRAIN_GRASSCRETE,
TERRAIN_LONG_GRASS,
TERRAIN_SLOPE_GRASS,
TERRAIN_COBBLES,
TERRAIN_SAND_ROAD,
TERRAIN_BAKED_CLAY,
TERRAIN_ASTROTURF,
TERRAIN_SNOWHALF,
TERRAIN_SNOWFULL,
TERRAIN_DAMAGED_ROAD1,
TERRAIN_TRAIN_TRACK_ROAD,
TERRAIN_BUMPYCOBBLES,
TERRAIN_ARIES_ONLY,
TERRAIN_ORION_ONLY,
TERRAIN_B1RUMBLES,
TERRAIN_B2RUMBLES,
TERRAIN_ROUGH_SAND_MEDIUM,
TERRAIN_ROUGH_SAND_HEAVY,

//-------------
TERRAIN_MAX
};

// (Type#12) Crash Damage State (to be used with 'mCrashState')
enum
{
CRASH_DAMAGE_NONE = 0,
CRASH_DAMAGE_OFFTRACK,
CRASH_DAMAGE_LARGE_PROP,
CRASH_DAMAGE_SPINNING,
CRASH_DAMAGE_ROLLING,
//-------------
CRASH_MAX
};

// (Type#13) ParticipantInfo struct (to be used with 'mParticipantInfo')
typedef struct
{
bool mIsActive;
char mName[STRING_LENGTH_MAX]; // [ string ]
float mWorldPosition[VEC_MAX]; // [ UNITS = World Space X Y Z ]
float mCurrentLapDistance; // [ UNITS = Metres ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
unsigned int mRacePosition; // [ RANGE = 1->... ] [ UNSET = 0 ]
unsigned int mLapsCompleted; // [ RANGE = 0->... ] [ UNSET = 0 ]
unsigned int mCurrentLap; // [ RANGE = 0->... ] [ UNSET = 0 ]
unsigned int mCurrentSector; // [ enum (Type#4) Current Sector ]
} ParticipantInfo;


// *** Shared Memory ***

typedef struct
{
// Version Number
unsigned int mVersion; // [ RANGE = 0->... ]
unsigned int mBuildVersionNumber; // [ RANGE = 0->... ] [ UNSET = 0 ]

// Game States
unsigned int mGameState; // [ enum (Type#1) Game state ]
unsigned int mSessionState; // [ enum (Type#2) Session state ]
unsigned int mRaceState; // [ enum (Type#3) Race State ]

// Participant Info
int mViewedParticipantIndex; // [ RANGE = 0->STORED_PARTICIPANTS_MAX ] [ UNSET = -1 ]
int mNumParticipants; // [ RANGE = 0->STORED_PARTICIPANTS_MAX ] [ UNSET = -1 ]
ParticipantInfo mParticipantInfo[STORED_PARTICIPANTS_MAX]; // [ struct (Type#13) ParticipantInfo struct ]

// Unfiltered Input
float mUnfilteredThrottle; // [ RANGE = 0.0f->1.0f ]
float mUnfilteredBrake; // [ RANGE = 0.0f->1.0f ]
float mUnfilteredSteering; // [ RANGE = -1.0f->1.0f ]
float mUnfilteredClutch; // [ RANGE = 0.0f->1.0f ]

// Vehicle information
char mCarName[STRING_LENGTH_MAX]; // [ string ]
char mCarClassName[STRING_LENGTH_MAX]; // [ string ]

// Event information
unsigned int mLapsInEvent; // [ RANGE = 0->... ] [ UNSET = 0 ]
char mTrackLocation[STRING_LENGTH_MAX]; // [ string ]
char mTrackVariation[STRING_LENGTH_MAX]; // [ string ]
float mTrackLength; // [ UNITS = Metres ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]

// Timings
bool mLapInvalidated; // [ UNITS = boolean ] [ RANGE = false->true ] [ UNSET = false ]
float mBestLapTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mLastLapTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mCurrentTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mSplitTimeAhead; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mSplitTimeBehind; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mSplitTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mEventTimeRemaining; // [ UNITS = milli-seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mPersonalFastestLapTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mWorldFastestLapTime; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mCurrentSector1Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mCurrentSector2Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mCurrentSector3Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mFastestSector1Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mFastestSector2Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mFastestSector3Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mPersonalFastestSector1Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mPersonalFastestSector2Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mPersonalFastestSector3Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mWorldFastestSector1Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mWorldFastestSector2Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
float mWorldFastestSector3Time; // [ UNITS = seconds ] [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]

// Flags
unsigned int mHighestFlagColour; // [ enum (Type#5) Flag Colour ]
unsigned int mHighestFlagReason; // [ enum (Type#6) Flag Reason ]

// Pit Info
unsigned int mPitMode; // [ enum (Type#7) Pit Mode ]
unsigned int mPitSchedule; // [ enum (Type#8) Pit Stop Schedule ]

// Car State
unsigned int mCarFlags; // [ enum (Type#9) Car Flags ]
float mOilTempCelsius; // [ UNITS = Celsius ] [ UNSET = 0.0f ]
float mOilPressureKPa; // [ UNITS = Kilopascal ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mWaterTempCelsius; // [ UNITS = Celsius ] [ UNSET = 0.0f ]
float mWaterPressureKPa; // [ UNITS = Kilopascal ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mFuelPressureKPa; // [ UNITS = Kilopascal ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mFuelLevel; // [ RANGE = 0.0f->1.0f ]
float mFuelCapacity; // [ UNITS = Liters ] [ RANGE = 0.0f->1.0f ] [ UNSET = 0.0f ]
float mSpeed; // [ UNITS = Metres per-second ] [ RANGE = 0.0f->... ]
float mRpm; // [ UNITS = Revolutions per minute ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mMaxRPM; // [ UNITS = Revolutions per minute ] [ RANGE = 0.0f->... ] [ UNSET = 0.0f ]
float mBrake; // [ RANGE = 0.0f->1.0f ]
float mThrottle; // [ RANGE = 0.0f->1.0f ]
float mClutch; // [ RANGE = 0.0f->1.0f ]
float mSteering; // [ RANGE = -1.0f->1.0f ]
int mGear; // [ RANGE = -1 (Reverse) 0 (Neutral) 1 (Gear 1) 2 (Gear 2) etc... ] [ UNSET = 0 (Neutral) ]
int mNumGears; // [ RANGE = 0->... ] [ UNSET = -1 ]
float mOdometerKM; // [ RANGE = 0.0f->... ] [ UNSET = -1.0f ]
bool mAntiLockActive; // [ UNITS = boolean ] [ RANGE = false->true ] [ UNSET = false ]
int mLastOpponentCollisionIndex; // [ RANGE = 0->STORED_PARTICIPANTS_MAX ] [ UNSET = -1 ]
float mLastOpponentCollisionMagnitude; // [ RANGE = 0.0f->... ]
bool mBoostActive; // [ UNITS = boolean ] [ RANGE = false->true ] [ UNSET = false ]
float mBoostAmount; // [ RANGE = 0.0f->100.0f ]

// Motion & Device Related
float mOrientation[VEC_MAX]; // [ UNITS = Euler Angles ]
float mLocalVelocity[VEC_MAX]; // [ UNITS = Metres per-second ]
float mWorldVelocity[VEC_MAX]; // [ UNITS = Metres per-second ]
float mAngularVelocity[VEC_MAX]; // [ UNITS = Radians per-second ]
float mLocalAcceleration[VEC_MAX]; // [ UNITS = Metres per-second ]
float mWorldAcceleration[VEC_MAX]; // [ UNITS = Metres per-second ]
float mExtentsCentre[VEC_MAX]; // [ UNITS = Local Space X Y Z ]

// Wheels / Tyres
unsigned int mTyreFlags[TYRE_MAX]; // [ enum (Type#10) Tyre Flags ]
unsigned int mTerrain[TYRE_MAX]; // [ enum (Type#11) Terrain Materials ]
float mTyreY[TYRE_MAX]; // [ UNITS = Local Space Y ]
float mTyreRPS[TYRE_MAX]; // [ UNITS = Revolutions per second ]
float mTyreSlipSpeed[TYRE_MAX]; // [ UNITS = Metres per-second ]
float mTyreTemp[TYRE_MAX]; // [ UNITS = Celsius ] [ UNSET = 0.0f ]
float mTyreGrip[TYRE_MAX]; // [ RANGE = 0.0f->1.0f ]
float mTyreHeightAboveGround[TYRE_MAX]; // [ UNITS = Local Space Y ]
float mTyreLateralStiffness[TYRE_MAX]; // [ UNITS = Lateral stiffness coefficient used in tyre deformation ]
float mTyreWear[TYRE_MAX]; // [ RANGE = 0.0f->1.0f ]
float mBrakeDamage[TYRE_MAX]; // [ RANGE = 0.0f->1.0f ]
float mSuspensionDamage[TYRE_MAX]; // [ RANGE = 0.0f->1.0f ]
float mBrakeTempCelsius[TYRE_MAX]; // [ UNITS = Celsius ]
float mTyreTreadTemp[TYRE_MAX]; // [ UNITS = Kelvin ]
float mTyreLayerTemp[TYRE_MAX]; // [ UNITS = Kelvin ]
float mTyreCarcassTemp[TYRE_MAX]; // [ UNITS = Kelvin ]
float mTyreRimTemp[TYRE_MAX]; // [ UNITS = Kelvin ]
float mTyreInternalAirTemp[TYRE_MAX]; // [ UNITS = Kelvin ]

// Car Damage
unsigned int mCrashState; // [ enum (Type#12) Crash Damage State ]
float mAeroDamage; // [ RANGE = 0.0f->1.0f ]
float mEngineDamage; // [ RANGE = 0.0f->1.0f ]

// Weather
float mAmbientTemperature; // [ UNITS = Celsius ] [ UNSET = 25.0f ]
float mTrackTemperature; // [ UNITS = Celsius ] [ UNSET = 30.0f ]
float mRainDensity; // [ UNITS = How much rain will fall ] [ RANGE = 0.0f->1.0f ]
float mWindSpeed; // [ RANGE = 0.0f->100.0f ] [ UNSET = 2.0f ]
float mWindDirectionX; // [ UNITS = Normalised Vector X ]
float mWindDirectionY; // [ UNITS = Normalised Vector Y ]
float mCloudBrightness; // [ RANGE = 0.0f->... ]
} SharedMemory;


#endif // _SHARED_MEMORY_HPP_

dohmien
27-05-2015, 10:00
Hello, I am also trying to code my application using the API but in the language that I use there is no memory-mapped file management.

To read the memory I have to give him pointers values of each data to recover.

For example for the pilot I have called to tell him to read the memory shared $ PCARS in possitionnant me on the 29th byte.

Is there a document with all these pointers addresses?

Sorry for the broken English google trad

Lars Rosenquist
27-05-2015, 10:34
There is only the documentation as mentioned above. You would have to calculate offsets yourself based on field type/byte size. Just curious: what language are you using? Maybe some other devs could help you out with a few pointers. :)

dohmien
27-05-2015, 11:28
I use windev.

I had also thought compute pointers but I did not know if the sharedmemory.h was official.

How do I read the sharedmemory.h file to find out what is the first pointer and order in memory?

mVersion would be the first 4 bytes and then mBuildVersionNumber?

MikeyTT
27-05-2015, 11:48
If you're looking at a managed language, I put together a demo app for the WMD members a while back.


... Thought I'd update it to the latest v5 of the API and also convert it to WPF. I've now made it read on a loop, instead of a keypress.

It's still very basic, but it does read the data pretty quickly. I've not added many comments yet, so if you have any questions please ask.

I've added it to BitBucket as a public resource: bitbucket pcars-api-demo (https://bitbucket.org/MikeyTT/pcars-api-demo/overview)

That should help you out if you're going down the C# route.

If you're after getting running quickly with an Arduino, I support serial sending of data in my vrHive app - shameless plug ;). It's only basic at the mo, but it does work. Ultimately I'll be running my dashes off an Arduino when I get the time to finalise it all.

dohmien
27-05-2015, 12:36
Hello,
What he actually miss it offsets of each data to read in the right place in the memory.
I do not know if it is possible to make a piece of code in C # or other out all the offsets in a file?

schigara
28-05-2015, 20:43
I support serial sending of data in my vrHive app - shameless plug ;). It's only basic at the mo, but it does work. Ultimately I'll be running my dashes off an Arduino when I get the time to finalise it all.

Mike, I love your vrHive app. I am guessing in the future you will make it work with other Sims like RF2, GSCE, AC? If so, what kind of time frame until it is compatible with other sims. Are you still in Chicago working?

MikeyTT
29-05-2015, 11:17
Mike, I love your vrHive app. I am guessing in the future you will make it work with other Sims like RF2, GSCE, AC? If so, what kind of time frame until it is compatible with other sims. Are you still in Chicago working?

I'm back home now, ta, it was just a week's conference. I'm flat out trying to fix a lot of the exception issues in the current version and changing the entire back-end on it, which is taking much longer than I would have liked (I started in December!!). My better half is away this weekend, so I'll get a full weekend of coding, which is good.

As for other games, then yes I was looking at AC support, and I do have part of that working at present, though it's taken a back seat to some of the other changes. I did briefly look at rF2, but I struggled to figure out how to get at the data (didn't look for long to be fair). Timeframe for AC/RF2 will be a while off. Once I've got the main update done, I've been working on a dash creator, so you can create/define your own dashes. I have a Win Phone app written, but I need the dash creator complete, before I can release that, so they will come together roughly the same time.

Unfortunately I have quite a busy day job, and travel a fair bit, so I don't get as much time coding as I would like. But it will come...

MikeyTT
29-05-2015, 11:34
Hello,
What he actually miss it offsets of each data to read in the right place in the memory.
I do not know if it is possible to make a piece of code in C # or other out all the offsets in a file?

I don't know why you would want to read each individual variable via the offset, assuming I'm understanding you correctly. Have a look at the C# demo app I put together, as that show you how to read the entire MMF into a struct. Then you can do what you want with that struct.

henrikl
21-02-2016, 14:10
Hi,

From the structure provided by Mad Al I am trying to read the MemoryMappedFile, but am receiving an error “The specified Type must be a struct containing no reference”
The error comes from the Function ReadMemoryMappedFile - a.Read(0, c)
How do I correct this error?

Thank you in advance,
Henrik


Private Function ReadMemoryMappedFile(ByVal Name As String) As Byte()

Try
Using MemoryFile As IO.MemoryMappedFiles.MemoryMappedFile =
IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(Name, IO.MemoryMappedFiles.MemoryMappedFileRights.ReadWrite)

Dim a As System.IO.MemoryMappedFiles.MemoryMappedViewAccessor
a = MemoryFile.CreateViewAccessor()

If a.CanRead = True Then
Dim c As New MMFContents
a.Read(0, c) 'Læser alle data fra position 0 ind i c
End Using ' MemoryFile

Catch exNoFile As IO.FileNotFoundException
Throw
Return Nothing

Catch ex As Exception
Throw

End Try

End Function

pock1910
24-02-2016, 18:03
I read the MemoryMappedFile with this code (C#):


private MemoryMappedFile mMemMapFile = null;

try
{ mMemMapFile = MemoryMappedFile.OpenExisting("$pcars$");
}
catch (Exception)
{ ...
}


if (mMemMapFile != null)
{
using (var SharedMemoryStreamView = mMemMapFile.CreateViewStream())
{
int pCarsDataSharedMemorySize = Marshal.SizeOf(typeof(SharedMemoryPCARS));
byte[] SharedMemoryReadBuffer = new byte[pCarsDataSharedMemorySize];

BinaryReader brSharedMemoryStream = new BinaryReader(SharedMemoryStreamView);
SharedMemoryReadBuffer = brSharedMemoryStream.ReadBytes(pCarsDataSharedMemorySize);
GCHandle handle = new GCHandle();
try
{ handle = GCHandle.Alloc(SharedMemoryReadBuffer, GCHandleType.Pinned);
}
catch (Exception e)
{ Tools.WriteLine("Fehler bei GCHandle.Alloc (SharedMemory) - Detail: " + e.Message);
Environment.Exit(0);
}
MMF = (SharedMemoryPCARS)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SharedMemoryPCARS));
handle.Free();
}
}

henrikl
25-02-2016, 09:22
Thank you very much pock1910. In the meantime I translated the code from MikeyTT, but I will for sure try yours too.

TylerDurden4321
07-09-2017, 17:15
I'm not a WMD member, so I have to ask here in the official forum:

Are there any new channels that the Project CARS 2 API will put through?
I'm especially interested in individual tire loads/normal forces, slip angles (slip ratios are put out already) and tire temps with three lanes per tire (inner/mid/outer) for camber setting or at least tire pressure.

Big thanks for any info in advance