├── .gitattributes ├── .gitignore ├── Include ├── InternalsPlugin.hpp ├── RFPluginObjects.hpp ├── rFactorSharedMemoryMap.hpp └── rfSharedStruct.hpp ├── LICENSE.txt ├── README.md ├── Source └── rFactorSharedMemoryMap.cpp └── Win32 ├── rFactorSharedMemoryMap.sln ├── rFactorSharedMemoryMap.vcxproj └── rFactorSharedMemoryMap.vcxproj.filters /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # ========================= 255 | # Operating System Files 256 | # ========================= 257 | 258 | # OSX 259 | # ========================= 260 | 261 | .DS_Store 262 | .AppleDouble 263 | .LSOverride 264 | 265 | # Thumbnails 266 | ._* 267 | 268 | # Files that might appear in the root of a volume 269 | .DocumentRevisions-V100 270 | .fseventsd 271 | .Spotlight-V100 272 | .TemporaryItems 273 | .Trashes 274 | .VolumeIcon.icns 275 | 276 | # Directories potentially created on remote AFP share 277 | .AppleDB 278 | .AppleDesktop 279 | Network Trash Folder 280 | Temporary Items 281 | .apdisk 282 | 283 | # Windows 284 | # ========================= 285 | 286 | # Windows image file caches 287 | Thumbs.db 288 | ehthumbs.db 289 | 290 | # Folder config file 291 | Desktop.ini 292 | 293 | # Recycle Bin used on file shares 294 | $RECYCLE.BIN/ 295 | 296 | # Windows Installer files 297 | *.cab 298 | *.msi 299 | *.msm 300 | *.msp 301 | 302 | # Windows shortcuts 303 | *.lnk 304 | -------------------------------------------------------------------------------- /Include/InternalsPlugin.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dallongo/rFactorSharedMemoryMap/afbac1d37d96c7f673c120290e7b487356ecef05/Include/InternalsPlugin.hpp -------------------------------------------------------------------------------- /Include/RFPluginObjects.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dallongo/rFactorSharedMemoryMap/afbac1d37d96c7f673c120290e7b487356ecef05/Include/RFPluginObjects.hpp -------------------------------------------------------------------------------- /Include/rFactorSharedMemoryMap.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | rfSharedMemoryMap.hpp 3 | by Dan Allongo (daniel.s.allongo@gmail.com) 4 | 5 | This remains largely unchanged from Example.hpp, except for a few additional 6 | private variables to track the current state of the memory map handle and buffer. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "InternalsPlugin.hpp" 12 | #include "rfSharedStruct.hpp" 13 | #include 14 | #include 15 | 16 | #define PLUGIN_NAME "rFactorSharedMemoryMap" 17 | 18 | // This is used for app to find out information about the plugin 19 | class InternalsPluginInfo : public PluginObjectInfo 20 | { 21 | public: 22 | 23 | // Constructor/destructor 24 | InternalsPluginInfo(); 25 | ~InternalsPluginInfo() {} 26 | 27 | // Derived from base class PluginObjectInfo 28 | virtual const char* GetName() const; 29 | virtual const char* GetFullName() const; 30 | virtual const char* GetDesc() const; 31 | virtual const unsigned GetType() const; 32 | virtual const char* GetSubType() const; 33 | virtual const unsigned GetVersion() const; 34 | virtual void* Create() const; 35 | 36 | private: 37 | 38 | char m_szFullName[128]; 39 | }; 40 | 41 | // internal state tracking 42 | struct internalVI { 43 | float lapDist; 44 | rfVec3 pos; 45 | rfVec3 localVel; 46 | rfVec3 localAccel; 47 | rfVec3 oriX; 48 | rfVec3 oriY; 49 | rfVec3 oriZ; 50 | rfVec3 localRot; 51 | rfVec3 localRotAccel; 52 | }; 53 | 54 | struct internalSI { 55 | float currentET; 56 | int numVehicles; 57 | char plrFileName[64]; 58 | internalVI vehicle[RF_SHARED_MEMORY_MAX_VSI_SIZE]; 59 | }; 60 | 61 | // This is used for the app to use the plugin for its intended purpose 62 | class SharedMemoryMapPlugin : public InternalsPluginV3 63 | { 64 | protected: 65 | 66 | const static char m_szName[]; 67 | const static char m_szSubType[]; 68 | const static unsigned m_uID; 69 | const static unsigned m_uVersion; 70 | 71 | public: 72 | 73 | // Constructor/destructor 74 | SharedMemoryMapPlugin() {} 75 | ~SharedMemoryMapPlugin() {} 76 | 77 | // Called from class InternalsPluginInfo to return specific information about plugin 78 | static const char * GetName() { return m_szName; } 79 | static const unsigned GetType() { return PO_INTERNALS; } 80 | static const char * GetSubType() { return m_szSubType; } 81 | static const unsigned GetVersion() { return m_uVersion; } 82 | 83 | // Derived from base class PluginObject 84 | void Destroy() { Shutdown(); } // poorly named ... doesn't destroy anything 85 | PluginObjectInfo * GetInfo(); 86 | unsigned GetPropertyCount() const { return 0; } 87 | PluginObjectProperty *GetProperty( const char * ) { return 0; } 88 | PluginObjectProperty *GetProperty( const unsigned ) { return 0; } 89 | 90 | // These are the functions derived from base class InternalsPlugin 91 | // that can be implemented. 92 | void Startup(); // game startup 93 | void Shutdown(); // game shutdown 94 | 95 | void EnterRealtime(); // entering realtime 96 | void ExitRealtime(); // exiting realtime 97 | 98 | void StartSession(); // session has started 99 | void EndSession(); // session has ended 100 | 101 | // GAME OUTPUT 102 | bool WantsTelemetryUpdates() { return( true ); } 103 | void UpdateTelemetry( const TelemInfoV2 &info ); 104 | 105 | bool WantsGraphicsUpdates() { return( false ); } 106 | void UpdateGraphics( const GraphicsInfoV2 &info ) {} 107 | 108 | // GAME INPUT 109 | bool HasHardwareInputs() { return( false ); } 110 | void UpdateHardware( const float fDT ) {} 111 | void EnableHardware() {} 112 | void DisableHardware() {} 113 | 114 | bool CheckHWControl( const char * const controlName, float &fRetVal ) { return( false ); } 115 | 116 | bool ForceFeedback( float &forceValue ) { return( false ); } 117 | 118 | // SCORING OUTPUT 119 | bool WantsScoringUpdates() { return( true ); } 120 | void UpdateScoring( const ScoringInfoV2 &info ); 121 | 122 | // COMMENTARY INPUT 123 | bool RequestCommentary( CommentaryRequestInfo &info ) { return( false ); } 124 | 125 | private: 126 | 127 | HANDLE hMap; 128 | rfShared* pBuf; 129 | bool mapped; 130 | float cDelta; 131 | clock_t cLastScoringUpdate; 132 | bool inRealtime; 133 | internalSI scoring; 134 | }; 135 | -------------------------------------------------------------------------------- /Include/rfSharedStruct.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | rfSharedStruct.hpp 3 | by Dan Allongo (daniel.s.allongo@gmail.com) 4 | 5 | This is the structure of the shared memory map 6 | It's nearly identical to the original structures specified in InternalsPlugin.hpp, 7 | but with pragma pack 1 specified to get the most compact representation. 8 | This means that you need to watch your types very closely! 9 | */ 10 | 11 | #pragma once 12 | 13 | #define RF_SHARED_MEMORY_NAME "$rFactorShared$" 14 | #define RF_SHARED_MEMORY_VERSION "3.0.0.0" 15 | #define RF_SHARED_MEMORY_MAX_VSI_SIZE 64 16 | #define RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR 0.02f 17 | #define RF_SHARED_MEMORY_ROT_SMOOTH_FACTOR 0.65f 18 | 19 | typedef enum { 20 | garage = 0, 21 | warmUp = 1, 22 | gridWalk = 2, 23 | formation = 3, 24 | countdown = 4, 25 | greenFlag = 5, 26 | fullCourseYellow = 6, 27 | sessionStopped = 7, 28 | sessionOver = 8 29 | } rfGamePhase; 30 | 31 | typedef enum { 32 | invalid = -1, 33 | noFlag = 0, 34 | pending = 1, 35 | pitClosed = 2, 36 | pitLeadLap = 3, 37 | pitOpen = 4, 38 | lastLap = 5, 39 | resume = 6, 40 | raceHalt = 7 41 | } rfYellowFlagState; 42 | 43 | typedef enum { 44 | dry = 0, 45 | wet = 1, 46 | grass = 2, 47 | dirt = 3, 48 | gravel = 4, 49 | kerb = 5 50 | } rfSurfaceType; 51 | 52 | typedef enum { 53 | sector3 = 0, 54 | sector1 = 1, 55 | sector2 = 2 56 | } rfSector; 57 | 58 | typedef enum { 59 | none = 0, 60 | finished = 1, 61 | dnf = 2, 62 | dq = 3 63 | } rfFinishStatus; 64 | 65 | typedef enum { 66 | nobody = -1, 67 | player = 0, 68 | ai = 1, 69 | remote = 2, 70 | replay = 3 71 | } rfControl; 72 | 73 | typedef enum { 74 | frontLeft = 0, 75 | frontRight = 1, 76 | rearLeft = 2, 77 | rearRight = 3 78 | } rfWheelIndex; 79 | 80 | #pragma pack(push, 1) 81 | 82 | // Our world coordinate system is left-handed, with +y pointing up. 83 | // The local vehicle coordinate system is as follows: 84 | // +x points out the left side of the car (from the driver's perspective) 85 | // +y points out the roof 86 | // +z points out the back of the car 87 | // Rotations are as follows: 88 | // +x pitches up 89 | // +y yaws to the right 90 | // +z rolls to the right 91 | 92 | struct rfVec3 { 93 | float x, y, z; 94 | }; 95 | 96 | struct rfWheel { 97 | float rotation; // radians/sec 98 | float suspensionDeflection; // meters 99 | float rideHeight; // meters 100 | float tireLoad; // Newtons 101 | float lateralForce; // Newtons 102 | float gripFract; // an approximation of what fraction of the contact patch is sliding 103 | float brakeTemp; // Celsius 104 | float pressure; // kPa 105 | float temperature[3]; // Celsius, left/center/right (not to be confused with inside/center/outside!) 106 | float wear; // wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss 107 | char terrainName[16]; // the material prefixes from the TDF file 108 | unsigned char surfaceType; // 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip 109 | bool flat; // whether tire is flat 110 | bool detached; // whether wheel is detached 111 | }; 112 | 113 | // scoring info only updates twice per second (values interpolated when deltaTime > 0)! 114 | struct rfVehicleInfo { 115 | char driverName[32]; // driver name 116 | short totalLaps; // laps completed 117 | signed char sector; // 0=sector3, 1=sector1, 2=sector2 (don't ask why) 118 | signed char finishStatus; // 0=none, 1=finished, 2=dnf, 3=dq 119 | float lapDist; // current distance around track 120 | float pathLateral; // lateral position with respect to *very approximate* "center" path 121 | float trackEdge; // track edge (w.r.t. "center" path) on same side of track as vehicle 122 | 123 | float bestSector1; // best sector 1 124 | float bestSector2; // best sector 2 (plus sector 1) 125 | float bestLapTime; // best lap time 126 | float lastSector1; // last sector 1 127 | float lastSector2; // last sector 2 (plus sector 1) 128 | float lastLapTime; // last lap time 129 | float curSector1; // current sector 1 if valid 130 | float curSector2; // current sector 2 (plus sector 1) if valid 131 | // no current laptime because it instantly becomes "last" 132 | 133 | short numPitstops; // number of pitstops made 134 | short numPenalties; // number of outstanding penalties 135 | bool isPlayer; // is this the player's vehicle 136 | signed char control; // who's in control: -1=nobody (shouldn't get this), 0=local player, 1=local AI, 2=remote, 3=replay (shouldn't get this) 137 | bool inPits; // between pit entrance and pit exit (not always accurate for remote vehicles) 138 | unsigned char place; // 1-based position 139 | char vehicleClass[32]; // vehicle class 140 | 141 | // Dash Indicators 142 | float timeBehindNext; // time behind vehicle in next higher place 143 | long lapsBehindNext; // laps behind vehicle in next higher place 144 | float timeBehindLeader; // time behind leader 145 | long lapsBehindLeader; // laps behind leader 146 | float lapStartET; // time this lap was started 147 | 148 | // Position and derivatives 149 | rfVec3 pos; // world position in meters 150 | 151 | float yaw; // rad, use (360-yaw*57.2978)%360 for heading in degrees 152 | float pitch; // rad 153 | float roll; // rad 154 | 155 | float speed; // meters/sec 156 | }; 157 | 158 | struct rfShared { 159 | char version[8]; // API version 160 | // Time 161 | float deltaTime; // time since last scoring update (seconds) 162 | long lapNumber; // current lap number 163 | float lapStartET; // time this lap was started 164 | char trackName[64]; // current track name 165 | 166 | // Position and derivatives 167 | rfVec3 pos; // world position in meters 168 | rfVec3 localVel; // velocity (meters/sec) in local vehicle coordinates 169 | rfVec3 localAccel; // acceleration (meters/sec^2) in local vehicle coordinates 170 | 171 | // Orientation and derivatives 172 | rfVec3 oriX; // top row of orientation matrix (also converts local vehicle vectors into world X using dot product) 173 | rfVec3 oriY; // mid row of orientation matrix (also converts local vehicle vectors into world Y using dot product) 174 | rfVec3 oriZ; // bot row of orientation matrix (also converts local vehicle vectors into world Z using dot product) 175 | rfVec3 localRot; // rotation (radians/sec) in local vehicle coordinates 176 | rfVec3 localRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates 177 | 178 | float speed; // meters/sec 179 | 180 | // Vehicle status 181 | long gear; // -1=reverse, 0=neutral, 1+=forward gears 182 | float engineRPM; // engine RPM 183 | float engineWaterTemp; // Celsius 184 | float engineOilTemp; // Celsius 185 | float clutchRPM; // clutch RPM 186 | 187 | // Driver input 188 | float unfilteredThrottle; // ranges 0.0-1.0 189 | float unfilteredBrake; // ranges 0.0-1.0 190 | float unfilteredSteering; // ranges -1.0-1.0 (left to right) 191 | float unfilteredClutch; // ranges 0.0-1.0 192 | 193 | // Misc 194 | float steeringArmForce; // force on steering arms 195 | // state/damage info 196 | float fuel; // amount of fuel (liters) 197 | float engineMaxRPM; // rev limit 198 | unsigned char scheduledStops; // number of scheduled pitstops 199 | bool overheating; // whether overheating icon is shown 200 | bool detached; // whether any parts (besides wheels) have been detached 201 | unsigned char dentSeverity[8];// dent severity at 8 locations around the car (0=none, 1=some, 2=more) 202 | float lastImpactET; // time of last impact 203 | float lastImpactMagnitude; // magnitude of last impact 204 | rfVec3 lastImpactPos; // location of last impact 205 | 206 | rfWheel wheel[4]; // wheel info (front left, front right, rear left, rear right) 207 | 208 | // scoring info only updates twice per second (values interpolated when deltaTime > 0)! 209 | long session; // current session 210 | float currentET; // current time 211 | float endET; // ending time 212 | long maxLaps; // maximum laps 213 | float lapDist; // distance around track 214 | 215 | long numVehicles; // current number of vehicles 216 | 217 | unsigned char gamePhase; 218 | 219 | signed char yellowFlagState; 220 | 221 | signed char sectorFlag[3]; // whether there are any local yellows at the moment in each sector (not sure if sector 0 is first or last, so test) 222 | unsigned char startLight; // start light frame (number depends on track) 223 | unsigned char numRedLights; // number of red lights in start sequence 224 | bool inRealtime; // in realtime as opposed to at the monitor 225 | char playerName[32]; // player name (including possible multiplayer override) 226 | 227 | // weather 228 | float ambientTemp; // temperature (Celsius) 229 | float trackTemp; // temperature (Celsius) 230 | rfVec3 wind; // wind speed 231 | 232 | rfVehicleInfo vehicle[RF_SHARED_MEMORY_MAX_VSI_SIZE]; // array of vehicle scoring info's 233 | }; 234 | 235 | #pragma pack(pop) 236 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rFactorSharedMemoryMap 2 | 3 | A plugin for rFactor 1-based sims to export the standard telemetry and scoring data structs to a shared memory mapped file handle. 4 | This allows external programs to access the sim data without affecting frame times in the simulator. 5 | 6 | Details of the shared memory map can be found in `Include\rfSharedStruct.hpp`. The plugin is based on the sample plugin code from ISI found at http://rfactor.net/web/rf1/devcorner/ and compiled using Visual Studio Community 2015. 7 | 8 | A sample application using Python to access the memory map can be found in https://github.com/dallongo/pySRD9c. 9 | 10 | ### Releases 11 | #### 2016-05-11 (v2.0.0.0) 12 | 13 | * Added Vehicle Info interpolation between Scoring updates 14 | * Changed meaning of deltaTime to be time since last Scoring update 15 | * Changed inRealtime to be set/unset by Enter/ExitRealtime methods 16 | * Added clean up before and after each session 17 | 18 | #### 2016-05-09 (v1.1.0.0) 19 | 20 | * Updated `rfVehicleInfo` to include acceleration and rotation vectors 21 | 22 | #### 2016-05-08 (v1.0.0.0) 23 | 24 | * Initial release 25 | -------------------------------------------------------------------------------- /Source/rFactorSharedMemoryMap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | rFactorSharedMemoryMap.cpp 3 | by Dan Allongo (daniel.s.allongo@gmail.com) 4 | 5 | Based on the ISI sample code found at http://rfactor.net/web/rf1/devcorner/ 6 | Provides a basic memory map export of the telemetry and scoring data 7 | The export is nearly 1:1 with redundant/gratuitous data removed from the 8 | vehicle info array and the addition of vehicle speed being pre-calculated 9 | since everyone needs that anyway. Position, rotation, and orientation are 10 | interpolated in between scoring updates (every 0.5 seconds). True raw values 11 | are given when deltaTime == 0. 12 | */ 13 | 14 | #include "rFactorSharedMemoryMap.hpp" 15 | #include 16 | #include 17 | 18 | 19 | // plugin information 20 | unsigned g_uPluginID = 0; 21 | char g_szPluginName[] = PLUGIN_NAME; 22 | unsigned g_uPluginVersion = 003; 23 | unsigned g_uPluginObjectCount = 1; 24 | InternalsPluginInfo g_PluginInfo; 25 | 26 | // interface to plugin information 27 | extern "C" __declspec(dllexport) 28 | const char* __cdecl GetPluginName() { return g_szPluginName; } 29 | 30 | extern "C" __declspec(dllexport) 31 | unsigned __cdecl GetPluginVersion() { return g_uPluginVersion; } 32 | 33 | extern "C" __declspec(dllexport) 34 | unsigned __cdecl GetPluginObjectCount() { return g_uPluginObjectCount; } 35 | 36 | // get the plugin-info object used to create the plugin. 37 | extern "C" __declspec(dllexport) 38 | PluginObjectInfo* __cdecl GetPluginObjectInfo( const unsigned uIndex ) { 39 | switch(uIndex) { 40 | case 0: 41 | return &g_PluginInfo; 42 | default: 43 | return 0; 44 | } 45 | } 46 | 47 | 48 | // InternalsPluginInfo class 49 | 50 | InternalsPluginInfo::InternalsPluginInfo() { 51 | // put together a name for this plugin 52 | sprintf( m_szFullName, "%s - %s", g_szPluginName, InternalsPluginInfo::GetName() ); 53 | } 54 | 55 | const char* InternalsPluginInfo::GetName() const { return SharedMemoryMapPlugin::GetName(); } 56 | const char* InternalsPluginInfo::GetFullName() const { return m_szFullName; } 57 | const char* InternalsPluginInfo::GetDesc() const { return g_szPluginName; } 58 | const unsigned InternalsPluginInfo::GetType() const { return SharedMemoryMapPlugin::GetType(); } 59 | const char* InternalsPluginInfo::GetSubType() const { return SharedMemoryMapPlugin::GetSubType(); } 60 | const unsigned InternalsPluginInfo::GetVersion() const { return SharedMemoryMapPlugin::GetVersion(); } 61 | void* InternalsPluginInfo::Create() const { return new SharedMemoryMapPlugin(); } 62 | 63 | 64 | // InternalsPlugin class 65 | 66 | const char SharedMemoryMapPlugin::m_szName[] = PLUGIN_NAME; 67 | const char SharedMemoryMapPlugin::m_szSubType[] = "Internals"; 68 | const unsigned SharedMemoryMapPlugin::m_uID = 1; 69 | const unsigned SharedMemoryMapPlugin::m_uVersion = 3; // set to 3 for InternalsPluginV3 functionality and added graphical and vehicle info 70 | 71 | PluginObjectInfo *SharedMemoryMapPlugin::GetInfo() { 72 | return &g_PluginInfo; 73 | } 74 | 75 | void SharedMemoryMapPlugin::Startup() { 76 | char tag[256] = {}; 77 | strcpy(tag, RF_SHARED_MEMORY_NAME); 78 | char exe[1024] = {}; 79 | GetModuleFileName(NULL, exe, sizeof(exe)); 80 | char pid[8] = {}; 81 | sprintf(pid, "%d", GetCurrentProcessId()); 82 | // append processId for dedicated server to allow multiple instances 83 | if (strstr(exe, "Dedicated.exe") != NULL) { 84 | strcat(tag, pid); 85 | } 86 | // init handle and try to create, read if existing 87 | hMap = INVALID_HANDLE_VALUE; 88 | hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(rfShared), TEXT(tag)); 89 | if (hMap == NULL) { 90 | if (GetLastError() == (DWORD)183) { 91 | hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, TEXT(tag)); 92 | if (hMap == NULL) { 93 | // unable to create or read existing 94 | mapped = FALSE; 95 | return; 96 | } 97 | } 98 | } 99 | pBuf = (rfShared*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(rfShared)); 100 | if (pBuf == NULL) { 101 | // failed to map memory buffer 102 | CloseHandle(hMap); 103 | mapped = FALSE; 104 | return; 105 | } 106 | mapped = TRUE; 107 | if (mapped) { 108 | memset(pBuf, 0, sizeof(rfShared)); 109 | strcpy(pBuf->version, RF_SHARED_MEMORY_VERSION); 110 | } 111 | return; 112 | } 113 | 114 | void SharedMemoryMapPlugin::Shutdown() { 115 | // release buffer and close handle 116 | if (mapped) { 117 | memset(pBuf, 0, sizeof(rfShared)); 118 | } 119 | if (pBuf) { 120 | UnmapViewOfFile(pBuf); 121 | } 122 | if (hMap) { 123 | CloseHandle(hMap); 124 | } 125 | mapped = FALSE; 126 | } 127 | 128 | void SharedMemoryMapPlugin::StartSession() { 129 | // zero-out buffer at start of session 130 | if (mapped) { 131 | memset(pBuf, 0, sizeof(rfShared)); 132 | strcpy(pBuf->version, RF_SHARED_MEMORY_VERSION); 133 | } 134 | cLastScoringUpdate = 0; 135 | cDelta = 0; 136 | scoring = { 0 }; 137 | } 138 | 139 | void SharedMemoryMapPlugin::EndSession() { 140 | // zero-out buffer at end of session 141 | StartSession(); 142 | } 143 | 144 | void SharedMemoryMapPlugin::EnterRealtime() { 145 | inRealtime = TRUE; 146 | } 147 | 148 | void SharedMemoryMapPlugin::ExitRealtime() { 149 | inRealtime = FALSE; 150 | } 151 | 152 | void SharedMemoryMapPlugin::UpdateTelemetry( const TelemInfoV2 &info ) { 153 | if (mapped) { 154 | // update clock delta 155 | cDelta = (float)(clock() - cLastScoringUpdate) / (float)CLOCKS_PER_SEC; 156 | 157 | // TelemInfoBase 158 | pBuf->deltaTime = cDelta; 159 | pBuf->lapNumber = info.mLapNumber; 160 | pBuf->lapStartET = info.mLapStartET; 161 | strcpy(pBuf->trackName, info.mTrackName); 162 | pBuf->pos = { info.mPos.x, info.mPos.y, info.mPos.z }; 163 | pBuf->localVel = { info.mLocalVel.x, info.mLocalVel.y, info.mLocalVel.z }; 164 | pBuf->localAccel = { info.mLocalAccel.x, info.mLocalAccel.y, info.mLocalAccel.z }; 165 | pBuf->oriX = { info.mOriX.x, info.mOriX.y, info.mOriX.z }; 166 | pBuf->oriY = { info.mOriY.x, info.mOriY.y, info.mOriY.z }; 167 | pBuf->oriZ = { info.mOriZ.x, info.mOriZ.y, info.mOriZ.z }; 168 | pBuf->localRot = { info.mLocalRot.x, info.mLocalRot.y, info.mLocalRot.z }; 169 | pBuf->localRotAccel = { info.mLocalRotAccel.x, info.mLocalRotAccel.y, info.mLocalRotAccel.z }; 170 | pBuf->speed = sqrtf((info.mLocalVel.x * info.mLocalVel.x) + 171 | (info.mLocalVel.y * info.mLocalVel.y) + 172 | (info.mLocalVel.z * info.mLocalVel.z)); 173 | pBuf->gear = info.mGear; 174 | pBuf->engineRPM = info.mEngineRPM; 175 | pBuf->engineWaterTemp = info.mEngineWaterTemp; 176 | pBuf->engineOilTemp = info.mEngineOilTemp; 177 | pBuf->clutchRPM = info.mClutchRPM; 178 | pBuf->unfilteredThrottle = info.mUnfilteredThrottle; 179 | pBuf->unfilteredBrake = info.mUnfilteredBrake; 180 | pBuf->unfilteredSteering = info.mUnfilteredSteering; 181 | pBuf->unfilteredClutch = info.mUnfilteredClutch; 182 | pBuf->steeringArmForce = info.mSteeringArmForce; 183 | 184 | // TelemInfoV2 185 | pBuf->fuel = info.mFuel; 186 | pBuf->engineMaxRPM = info.mEngineMaxRPM; 187 | pBuf->scheduledStops = info.mScheduledStops; 188 | pBuf->overheating = info.mOverheating; 189 | pBuf->detached = info.mDetached; 190 | for (int i = 0; i < 8; i++) { 191 | pBuf->dentSeverity[i] = info.mDentSeverity[i]; 192 | } 193 | pBuf->lastImpactET = info.mLastImpactET; 194 | pBuf->lastImpactMagnitude = info.mLastImpactMagnitude; 195 | pBuf->lastImpactPos = { info.mLastImpactPos.x, info.mLastImpactPos.y, info.mLastImpactPos.z }; 196 | 197 | for (int i = 0; i < 4; i++) { 198 | // TelemWheel 199 | pBuf->wheel[i].rotation = info.mWheel[i].mRotation; 200 | pBuf->wheel[i].suspensionDeflection = info.mWheel[i].mSuspensionDeflection; 201 | pBuf->wheel[i].rideHeight = info.mWheel[i].mRideHeight; 202 | pBuf->wheel[i].tireLoad = info.mWheel[i].mTireLoad; 203 | pBuf->wheel[i].lateralForce = info.mWheel[i].mLateralForce; 204 | pBuf->wheel[i].gripFract = info.mWheel[i].mGripFract; 205 | pBuf->wheel[i].brakeTemp = info.mWheel[i].mBrakeTemp; 206 | pBuf->wheel[i].pressure = info.mWheel[i].mPressure; 207 | for (int j = 0; j < 3; j++) { 208 | pBuf->wheel[i].temperature[j] = info.mWheel[i].mTemperature[j]; 209 | } 210 | 211 | //TelemWheelV2 212 | pBuf->wheel[i].wear = info.mWheel[i].mWear; 213 | strcpy(pBuf->wheel[i].terrainName, info.mWheel[i].mTerrainName); 214 | pBuf->wheel[i].surfaceType = info.mWheel[i].mSurfaceType; 215 | pBuf->wheel[i].flat = info.mWheel[i].mFlat; 216 | pBuf->wheel[i].detached = info.mWheel[i].mDetached; 217 | } 218 | 219 | // interpolation of scoring info 220 | if (cDelta > 0.0f && cDelta < 0.55f) { 221 | // ScoringInfoBase 222 | pBuf->currentET = scoring.currentET + cDelta; 223 | 224 | // ScoringInfoV2 225 | pBuf->inRealtime = inRealtime; 226 | 227 | for (int i = 0; i < RF_SHARED_MEMORY_MAX_VSI_SIZE; i++) { 228 | if (i < scoring.numVehicles) { 229 | // VehicleScoringInfoV2 230 | // applying 0.05x acceleration seems to help the interpolation 231 | rfVec3 localRotAccel = { scoring.vehicle[i].localRotAccel.x, scoring.vehicle[i].localRotAccel.y, scoring.vehicle[i].localRotAccel.z }; 232 | rfVec3 localAccel = { scoring.vehicle[i].localAccel.x, scoring.vehicle[i].localAccel.y, scoring.vehicle[i].localAccel.z }; 233 | rfVec3 localRot = { scoring.vehicle[i].localRot.x, scoring.vehicle[i].localRot.y, scoring.vehicle[i].localRot.z }; 234 | rfVec3 localVel = { scoring.vehicle[i].localVel.x, scoring.vehicle[i].localVel.y, scoring.vehicle[i].localVel.z }; 235 | 236 | localRot.x += localRotAccel.x * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 237 | localRot.y += localRotAccel.y * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 238 | localRot.z += localRotAccel.z * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 239 | 240 | localVel.x += localAccel.x * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 241 | localVel.y += localAccel.y * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 242 | localVel.z += localAccel.z * cDelta * RF_SHARED_MEMORY_ACC_SMOOTH_FACTOR; 243 | 244 | // rotate and normalize orientation vectors (normalizing shouldn't be necessary if this is correct) 245 | rfVec3 oriX = { scoring.vehicle[i].oriX.x, scoring.vehicle[i].oriX.y, scoring.vehicle[i].oriX.z }; 246 | rfVec3 oriY = { scoring.vehicle[i].oriY.x, scoring.vehicle[i].oriY.y, scoring.vehicle[i].oriY.z }; 247 | rfVec3 oriZ = { scoring.vehicle[i].oriZ.x, scoring.vehicle[i].oriZ.y, scoring.vehicle[i].oriZ.z }; 248 | rfVec3 wRot = { ((oriX.x * localRot.x) + (oriX.y * localRot.y) + (oriX.z * localRot.z)) * cDelta * RF_SHARED_MEMORY_ROT_SMOOTH_FACTOR, 249 | ((oriY.x * localRot.x) + (oriY.y * localRot.y) + (oriY.z * localRot.z)) * cDelta * RF_SHARED_MEMORY_ROT_SMOOTH_FACTOR, 250 | ((oriZ.x * localRot.x) + (oriZ.y * localRot.y) + (oriZ.z * localRot.z)) * cDelta * RF_SHARED_MEMORY_ROT_SMOOTH_FACTOR }; 251 | rfVec3 tmpX, tmpY, tmpZ; 252 | float tmpLen; 253 | 254 | // X 255 | // rotate by z 256 | tmpZ.x = oriX.x * cosf(wRot.z) - oriX.y * -sinf(wRot.z); 257 | tmpZ.y = oriX.x * -sinf(wRot.z) + oriX.y * cosf(wRot.z); 258 | tmpZ.z = oriX.z; 259 | // rotate by y 260 | tmpY.x = tmpZ.x * cosf(wRot.y) + tmpZ.z * -sinf(wRot.y); 261 | tmpY.y = tmpZ.y; 262 | tmpY.z = tmpZ.z * cosf(wRot.y) - tmpZ.x * -sinf(wRot.y); 263 | // rotate by x 264 | tmpX.x = tmpY.x; 265 | tmpX.y = tmpY.y * cosf(wRot.x) - tmpY.z * -sinf(wRot.x); 266 | tmpX.z = tmpY.y * -sinf(wRot.x) + tmpY.z * cosf(wRot.x); 267 | tmpLen = sqrtf(tmpX.x * tmpX.x + tmpX.y * tmpX.y + tmpX.z * tmpX.z); 268 | if (tmpLen > 0) { 269 | oriX = { tmpX.x / tmpLen, tmpX.y / tmpLen, tmpX.z / tmpLen }; 270 | } 271 | 272 | // Y 273 | // rotate by z 274 | tmpZ.x = oriY.x * cosf(wRot.z) - oriY.y * -sinf(wRot.z); 275 | tmpZ.y = oriY.x * -sinf(wRot.z) + oriY.y * cosf(wRot.z); 276 | tmpZ.z = oriY.z; 277 | // rotate by y 278 | tmpY.x = tmpZ.x * cosf(wRot.y) + tmpZ.z * -sinf(wRot.y); 279 | tmpY.y = tmpZ.y; 280 | tmpY.z = tmpZ.z * cosf(wRot.y) - tmpZ.x * -sinf(wRot.y); 281 | // rotate by x 282 | tmpX.x = tmpY.x; 283 | tmpX.y = tmpY.y * cosf(wRot.x) - tmpY.z * -sinf(wRot.x); 284 | tmpX.z = tmpY.y * -sinf(wRot.x) + tmpY.z * cosf(wRot.x); 285 | tmpLen = sqrtf(tmpX.x * tmpX.x + tmpX.y * tmpX.y + tmpX.z * tmpX.z); 286 | if (tmpLen > 0) { 287 | oriY = { tmpX.x / tmpLen, tmpX.y / tmpLen, tmpX.z / tmpLen }; 288 | } 289 | 290 | // Z 291 | // rotate by z 292 | tmpZ.x = oriZ.x * cosf(wRot.z) - oriZ.y * -sinf(wRot.z); 293 | tmpZ.y = oriZ.x * -sinf(wRot.z) + oriZ.y * cosf(wRot.z); 294 | tmpZ.z = oriZ.z; 295 | // rotate by y 296 | tmpY.x = tmpZ.x * cosf(wRot.y) + tmpZ.z * -sinf(wRot.y); 297 | tmpY.y = tmpZ.y; 298 | tmpY.z = tmpZ.z * cosf(wRot.y) - tmpZ.x * -sinf(wRot.y); 299 | // rotate by x 300 | tmpX.x = tmpY.x; 301 | tmpX.y = tmpY.y * cosf(wRot.x) - tmpY.z * -sinf(wRot.x); 302 | tmpX.z = tmpY.y * -sinf(wRot.x) + tmpY.z * cosf(wRot.x); 303 | tmpLen = sqrtf(tmpX.x * tmpX.x + tmpX.y * tmpX.y + tmpX.z * tmpX.z); 304 | if (tmpLen > 0) { 305 | oriZ = { tmpX.x / tmpLen, tmpX.y / tmpLen, tmpX.z / tmpLen }; 306 | } 307 | 308 | // position 309 | rfVec3 pos = { scoring.vehicle[i].pos.x, scoring.vehicle[i].pos.y, scoring.vehicle[i].pos.z }; 310 | pos.x += ((oriX.x * localVel.x) + (oriX.y * localVel.y) + (oriX.z * localVel.z)) * cDelta; 311 | pos.y += ((oriY.x * localVel.x) + (oriY.y * localVel.y) + (oriY.z * localVel.z)) * cDelta; 312 | pos.z += ((oriZ.x * localVel.x) + (oriZ.y * localVel.y) + (oriZ.z * localVel.z)) * cDelta; 313 | pBuf->vehicle[i].pos = { pos.x, pos.y, pos.z }; 314 | 315 | pBuf->vehicle[i].yaw = atan2f(oriZ.x, oriZ.z); 316 | pBuf->vehicle[i].pitch = atan2f(-oriY.z, sqrtf(oriX.z * oriX.z + oriZ.z * oriZ.z)); 317 | pBuf->vehicle[i].roll = atan2f(oriY.x, sqrtf(oriX.x * oriX.x + oriZ.x * oriZ.x)); 318 | 319 | // interpolate speed 320 | pBuf->vehicle[i].speed = sqrtf((localVel.x * localVel.x) + (localVel.y * localVel.y) + (localVel.z * localVel.z)); 321 | 322 | // VehicleScoringInfo 323 | pBuf->vehicle[i].lapDist = scoring.vehicle[i].lapDist - localVel.z * cDelta; 324 | 325 | continue; 326 | } 327 | } 328 | } 329 | } 330 | } 331 | 332 | void SharedMemoryMapPlugin::UpdateScoring( const ScoringInfoV2 &info ) { 333 | if (mapped) { 334 | cLastScoringUpdate = clock(); 335 | 336 | pBuf->deltaTime = 0; 337 | 338 | // update internal state 339 | scoring.currentET = info.mCurrentET; 340 | scoring.numVehicles = info.mNumVehicles; 341 | strcpy(scoring.plrFileName, info.mPlrFileName); 342 | for (int i = 0; i < RF_SHARED_MEMORY_MAX_VSI_SIZE; i++) { 343 | if (i < scoring.numVehicles) { 344 | scoring.vehicle[i].lapDist = info.mVehicle[i].mLapDist; 345 | scoring.vehicle[i].localAccel = { info.mVehicle[i].mLocalAccel.x, info.mVehicle[i].mLocalAccel.y, info.mVehicle[i].mLocalAccel.z }; 346 | scoring.vehicle[i].localRot = { info.mVehicle[i].mLocalRot.x, info.mVehicle[i].mLocalRot.y, info.mVehicle[i].mLocalRot.z }; 347 | scoring.vehicle[i].localRotAccel = { info.mVehicle[i].mLocalRotAccel.x, info.mVehicle[i].mLocalRotAccel.y, info.mVehicle[i].mLocalRotAccel.z }; 348 | scoring.vehicle[i].localVel = { info.mVehicle[i].mLocalVel.x, info.mVehicle[i].mLocalVel.y, info.mVehicle[i].mLocalVel.z }; 349 | scoring.vehicle[i].oriX = { info.mVehicle[i].mOriX.x, info.mVehicle[i].mOriX.y, info.mVehicle[i].mOriX.z }; 350 | scoring.vehicle[i].oriY = { info.mVehicle[i].mOriY.x, info.mVehicle[i].mOriY.y, info.mVehicle[i].mOriY.z }; 351 | scoring.vehicle[i].oriZ = { info.mVehicle[i].mOriZ.x, info.mVehicle[i].mOriZ.y, info.mVehicle[i].mOriZ.z }; 352 | scoring.vehicle[i].pos = { info.mVehicle[i].mPos.x, info.mVehicle[i].mPos.y, info.mVehicle[i].mPos.z }; 353 | continue; 354 | } 355 | scoring.vehicle[i] = { 0 }; 356 | } 357 | 358 | // ScoringInfoBase 359 | pBuf->session = info.mSession; 360 | pBuf->currentET = info.mCurrentET; 361 | pBuf->endET = info.mEndET; 362 | pBuf->maxLaps = info.mMaxLaps; 363 | pBuf->lapDist = info.mLapDist; 364 | pBuf->numVehicles = info.mNumVehicles; 365 | 366 | // ScoringInfoV2 367 | pBuf->gamePhase = info.mGamePhase; 368 | pBuf->yellowFlagState = info.mYellowFlagState; 369 | for (int i = 0; i < 3; i++) { 370 | pBuf->sectorFlag[i] = info.mSectorFlag[i]; 371 | } 372 | pBuf->startLight = info.mStartLight; 373 | pBuf->numRedLights = info.mNumRedLights; 374 | pBuf->inRealtime = inRealtime; 375 | strcpy(pBuf->playerName, info.mPlayerName); 376 | pBuf->ambientTemp = info.mAmbientTemp; 377 | pBuf->trackTemp = info.mTrackTemp; 378 | pBuf->wind = { info.mWind.x, info.mWind.y, info.mWind.z }; 379 | 380 | for (int i = 0; i < RF_SHARED_MEMORY_MAX_VSI_SIZE; i++) { 381 | if (i < info.mNumVehicles) { 382 | // VehicleScoringInfo 383 | strcpy(pBuf->vehicle[i].driverName, info.mVehicle[i].mDriverName); 384 | pBuf->vehicle[i].totalLaps = info.mVehicle[i].mTotalLaps; 385 | pBuf->vehicle[i].sector = info.mVehicle[i].mSector; 386 | pBuf->vehicle[i].finishStatus = info.mVehicle[i].mFinishStatus; 387 | pBuf->vehicle[i].lapDist = info.mVehicle[i].mLapDist; 388 | pBuf->vehicle[i].pathLateral = info.mVehicle[i].mPathLateral; 389 | pBuf->vehicle[i].trackEdge = info.mVehicle[i].mTrackEdge; 390 | pBuf->vehicle[i].bestSector1 = info.mVehicle[i].mBestSector1; 391 | pBuf->vehicle[i].bestSector2 = info.mVehicle[i].mBestSector2; 392 | pBuf->vehicle[i].bestLapTime = info.mVehicle[i].mBestLapTime; 393 | pBuf->vehicle[i].lastSector1 = info.mVehicle[i].mLastSector1; 394 | pBuf->vehicle[i].lastSector2 = info.mVehicle[i].mLastSector2; 395 | pBuf->vehicle[i].lastLapTime = info.mVehicle[i].mLastLapTime; 396 | pBuf->vehicle[i].curSector1 = info.mVehicle[i].mCurSector1; 397 | pBuf->vehicle[i].curSector2 = info.mVehicle[i].mCurSector2; 398 | pBuf->vehicle[i].numPitstops = info.mVehicle[i].mNumPitstops; 399 | pBuf->vehicle[i].numPenalties = info.mVehicle[i].mNumPenalties; 400 | 401 | // VehicleScoringInfoV2 402 | pBuf->vehicle[i].isPlayer = info.mVehicle[i].mIsPlayer; 403 | pBuf->vehicle[i].control = info.mVehicle[i].mControl; 404 | pBuf->vehicle[i].inPits = info.mVehicle[i].mInPits; 405 | pBuf->vehicle[i].place = info.mVehicle[i].mPlace; 406 | strcpy(pBuf->vehicle[i].vehicleClass, info.mVehicle[i].mVehicleClass); 407 | pBuf->vehicle[i].timeBehindNext = info.mVehicle[i].mTimeBehindNext; 408 | pBuf->vehicle[i].lapsBehindNext = info.mVehicle[i].mLapsBehindNext; 409 | pBuf->vehicle[i].timeBehindLeader = info.mVehicle[i].mTimeBehindLeader; 410 | pBuf->vehicle[i].lapsBehindLeader = info.mVehicle[i].mLapsBehindLeader; 411 | pBuf->vehicle[i].lapStartET = info.mVehicle[i].mLapStartET; 412 | pBuf->vehicle[i].pos = { info.mVehicle[i].mPos.x, info.mVehicle[i].mPos.y, info.mVehicle[i].mPos.z }; 413 | pBuf->vehicle[i].yaw = atan2f(info.mVehicle[i].mOriZ.x, info.mVehicle[i].mOriZ.z); 414 | pBuf->vehicle[i].pitch = atan2f(-info.mVehicle[i].mOriY.z, 415 | sqrtf(info.mVehicle[i].mOriX.z * info.mVehicle[i].mOriX.z + 416 | info.mVehicle[i].mOriZ.z * info.mVehicle[i].mOriZ.z)); 417 | pBuf->vehicle[i].roll = atan2f(info.mVehicle[i].mOriY.x, 418 | sqrtf(info.mVehicle[i].mOriX.x * info.mVehicle[i].mOriX.x + 419 | info.mVehicle[i].mOriZ.x * info.mVehicle[i].mOriZ.x)); 420 | pBuf->vehicle[i].speed = sqrtf((info.mVehicle[i].mLocalVel.x * info.mVehicle[i].mLocalVel.x) + 421 | (info.mVehicle[i].mLocalVel.y * info.mVehicle[i].mLocalVel.y) + 422 | (info.mVehicle[i].mLocalVel.z * info.mVehicle[i].mLocalVel.z)); 423 | continue; 424 | } 425 | pBuf->vehicle[i] = { 0 }; 426 | } 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /Win32/rFactorSharedMemoryMap.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rFactorSharedMemoryMap", "rFactorSharedMemoryMap.vcxproj", "{D0C09F9B-E1D6-4A04-B698-190F52BBA156}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|Win32.Build.0 = Debug|Win32 16 | {D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|Win32.ActiveCfg = Release|Win32 17 | {D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Win32/rFactorSharedMemoryMap.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D0C09F9B-E1D6-4A04-B698-190F52BBA156} 15 | rFactorSharedMemoryMap 16 | 17 | 18 | 19 | DynamicLibrary 20 | v140 21 | false 22 | MultiByte 23 | 24 | 25 | DynamicLibrary 26 | v140 27 | false 28 | MultiByte 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <_ProjectFileVersion>14.0.25123.0 44 | 45 | 46 | .\Release\ 47 | .\Release\ 48 | false 49 | 50 | 51 | .\Debug\ 52 | .\Debug\ 53 | true 54 | 55 | 56 | 57 | NDEBUG;%(PreprocessorDefinitions) 58 | true 59 | true 60 | Win32 61 | .\Release/rFactorSharedMemoryMap.tlb 62 | 63 | 64 | 65 | MaxSpeed 66 | OnlyExplicitInline 67 | ..\include;%(AdditionalIncludeDirectories) 68 | WIN32;NDEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 69 | true 70 | MultiThreaded 71 | 4Bytes 72 | true 73 | .\Release/rFactorSharedMemoryMap.pch 74 | .\Release/ 75 | .\Release/ 76 | .\Release/ 77 | Level3 78 | true 79 | FastCall 80 | 81 | 82 | NDEBUG;%(PreprocessorDefinitions) 83 | 0x0409 84 | 85 | 86 | .\Release/rFactorSharedMemoryMap.dll 87 | true 88 | .\Release/rFactorSharedMemoryMap.lib 89 | MachineX86 90 | 91 | 92 | true 93 | .\Release/rFactorSharedMemoryMap.bsc 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | _DEBUG;%(PreprocessorDefinitions) 103 | true 104 | true 105 | Win32 106 | .\Debug/rFactorSharedMemoryMap.tlb 107 | 108 | 109 | 110 | Disabled 111 | ..\include;%(AdditionalIncludeDirectories) 112 | WIN32;_DEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 113 | true 114 | EnableFastChecks 115 | MultiThreadedDebug 116 | 4Bytes 117 | .\Debug/rFactorSharedMemoryMap.pch 118 | .\Debug/ 119 | .\Debug/ 120 | .\Debug/ 121 | Level3 122 | true 123 | EditAndContinue 124 | FastCall 125 | 126 | 127 | _DEBUG;%(PreprocessorDefinitions) 128 | 0x0409 129 | 130 | 131 | .\Debug/rFactorSharedMemoryMap.dll 132 | true 133 | true 134 | .\Debug/rFactorSharedMemoryMap.pdb 135 | .\Debug/rFactorSharedMemoryMap.lib 136 | MachineX86 137 | 138 | 139 | true 140 | .\Debug/rFactorSharedMemoryMap.bsc 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /Win32/rFactorSharedMemoryMap.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {525d8b82-064f-44e3-b99e-69bee26097aa} 6 | cpp;c;cxx;rc;def;r;odl;idl;hpj;bat 7 | 8 | 9 | {bb2387d8-3694-45b8-a6e1-4988539c2279} 10 | h;hpp;hxx;hm;inl 11 | 12 | 13 | {330d6860-fa50-4e92-90ee-df26f5984c63} 14 | ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | --------------------------------------------------------------------------------