#include /* If compiled as C++, extern "C" must be added to declaration of functions to export X+ is right, Y+ is top and Z+ is forward. */ typedef struct { char m_szCarName[100]; float m_fIdleRPM; /* estimated */ float m_fMaxRPM; int m_iNumLimiters; float m_afLimiter[2]; char m_szCategory[100]; char m_szTrackName[100]; } SPluginsCarEvent_t; typedef struct { int m_iSession; /* 0 = testing; 1 = practice; 2 = qualify; 3 = warmup; 4 = race */ int m_iConditions; /* 0 = sunny; 1 = cloudy; 2 = rainy */ float m_fAirTemperature; /* degrees Celsius */ float m_fTrackTemperature; /* degrees Celsius */ } SPluginsCarSession_t; typedef struct { float m_fRPM; int m_iGear; float m_fSpeedometer; /* meters/second */ float m_fPosX,m_fPosY,m_fPosZ; /* world position of a reference point attached to chassis ( not CG ) */ float m_fVelocityX,m_fVelocityY,m_fVelocityZ; /* velocity of CG in world coordinates. meters/second */ float m_fAccelerationX,m_fAccelerationY,m_fAccelerationZ; /* acceleration of CG local to chassis rotation, expressed in G ( 9.81 m/s2 ) and averaged over the latest 40ms */ float m_aafRot[3][3]; /* rotation matrix of the chassis */ float m_fYaw,m_fPitch,m_fRoll; /* degrees, -180 to 180 */ float m_afSuspNormLength[4]; /* normalized suspension length. 0 = front left; 1 = front right; 2 = rear left; 3 = rear right */ float m_fThrottle; /* 0 to 1 */ float m_fBrake; /* 0 to 1 */ float m_fClutch; /* 0 to 1 */ } SPluginsCarData_t; typedef struct { int m_iLapTime; /* milliseconds */ int m_iBest; int m_iLapNum; } SPluginsCarLap_t; __declspec(dllexport) char *GetModID() { return "wrs"; } __declspec(dllexport) int Version() { return 3; } FILE *g_hTestLog; /* called when software is started */ __declspec(dllexport) void Startup() { g_hTestLog = fopen("wrs_log.txt","wt"); if (g_hTestLog) { fprintf(g_hTestLog,"Startup\n"); } } /* called when software is closed */ __declspec(dllexport) void Shutdown() { if (g_hTestLog) { fprintf(g_hTestLog,"Shutdown\n"); fclose(g_hTestLog); g_hTestLog = NULL; } } /* called when event is initialized */ __declspec(dllexport) void EventInit(void *_pData,int _iDataSize) { SPluginsCarEvent_t *psEventData; psEventData = (SPluginsCarEvent_t*)_pData; if (g_hTestLog) { int i; fprintf(g_hTestLog,"Event init\n"); fprintf(g_hTestLog,"Car: %s\n",psEventData->m_szCarName); fprintf(g_hTestLog,"Idle RPM: %d\n",(int)psEventData->m_fIdleRPM); for (i=0; i < psEventData->m_iNumLimiters; i++) fprintf(g_hTestLog,"Limiter%d: %d\n",i+1,(int)psEventData->m_afLimiter[i]); fprintf(g_hTestLog,"Max RPM: %d\n",(int)psEventData->m_fMaxRPM); fprintf(g_hTestLog,"Category: %s\n",psEventData->m_szCategory); fprintf(g_hTestLog,"Track: %s\n",psEventData->m_szTrackName); } } /* called when car goes to track */ __declspec(dllexport) void RunInit(void *_pData,int _iDataSize) { SPluginsCarSession_t *psSessionData; psSessionData = (SPluginsCarSession_t*)_pData; if (g_hTestLog) { fprintf(g_hTestLog,"Run init\n"); switch (psSessionData->m_iSession) { case 0: fprintf(g_hTestLog,"Testing\n"); break; case 1: fprintf(g_hTestLog,"Practice\n"); break; case 2: fprintf(g_hTestLog,"Qualify\n"); break; case 3: fprintf(g_hTestLog,"Warmup\n"); break; case 4: fprintf(g_hTestLog,"Race\n"); break; } switch (psSessionData->m_iConditions) { case 0: fprintf(g_hTestLog,"Sunny\n"); break; case 1: fprintf(g_hTestLog,"Cloudy\n"); break; case 2: fprintf(g_hTestLog,"Rainy\n"); break; } fprintf(g_hTestLog,"Air temp: %f; Track temp: %f\n",psSessionData->m_fAirTemperature,psSessionData->m_fTrackTemperature); } } /* called when car leaves the track */ __declspec(dllexport) void RunDeinit() { if (g_hTestLog) { fprintf(g_hTestLog,"Run deinit\n"); } } /* called when simulation is started / resumed */ __declspec(dllexport) void RunStart() { if (g_hTestLog) { fprintf(g_hTestLog,"Run start\n"); } } /* called when simulation is paused */ __declspec(dllexport) void RunStop() { if (g_hTestLog) { fprintf(g_hTestLog,"Run stop\n"); } } /* called every rendering frame */ __declspec(dllexport) void RunData(void *_pData,int _iDataSize) { SPluginsCarData_t *psCarData; psCarData = (SPluginsCarData_t*)_pData; if (g_hTestLog) { int i; fprintf(g_hTestLog,"RPM: %d\n",(int)psCarData->m_fRPM); fprintf(g_hTestLog,"Gear: %d\n",psCarData->m_iGear); fprintf(g_hTestLog,"Throttle: %d%%\n",(int)(psCarData->m_fThrottle * 100)); fprintf(g_hTestLog,"Brake: %d%%\n",(int)(psCarData->m_fBrake * 100)); fprintf(g_hTestLog,"Clutch: %d%%\n",(int)(psCarData->m_fClutch * 100)); fprintf(g_hTestLog,"Yaw: %f Pitch: %f Roll: %f\n",psCarData->m_fYaw,psCarData->m_fPitch,psCarData->m_fRoll); for (i=0; i < 4; i++) { fprintf(g_hTestLog,"susp%d: %f\n",i,psCarData->m_afSuspNormLength[i]); } fprintf(g_hTestLog,"Speed: %d km/h\n",(int)(psCarData->m_fSpeedometer * 3.6)); } } /* called when a new lap is recorded */ __declspec(dllexport) void RunLap(void *_pData,int _iDataSize) { SPluginsCarLap_t *psLapData; psLapData = (SPluginsCarLap_t*)_pData; if (g_hTestLog) { int iMinutes; int iSeconds; int iMilliseconds; iMinutes = psLapData->m_iLapTime / 60000; iSeconds = (psLapData->m_iLapTime / 1000) % 60; iMilliseconds = psLapData->m_iLapTime % 1000; if (iMinutes) fprintf(g_hTestLog,"New lap: %d'%02d.%03d\n",iMinutes,iSeconds,iMilliseconds); else fprintf(g_hTestLog,"New lap: %d.%03d\n",iSeconds,iMilliseconds); } }