Initial commit

This commit is contained in:
Michael Hübner 2022-02-09 14:27:02 +01:00
commit 5e07bfa54a
11 changed files with 2295 additions and 0 deletions

86
.gitignore vendored Normal file
View file

@ -0,0 +1,86 @@
# Created by https://www.toptal.com/developers/gitignore/api/c++,windows,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=c++,windows,visualstudiocode
### C++ ###
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# Support for Project snippet scope
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/c++,windows,visualstudiocode

23
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,23 @@
{
"files.associations": {
"cmath": "cpp",
"bit": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
"limits": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"xstddef": "cpp",
"xtr1common": "cpp",
"xutility": "cpp",
"xstring": "cpp"
}
}

82
Include/Example.hpp Normal file
View file

@ -0,0 +1,82 @@
//ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
//Ý Þ
//Ý Module: Internals Example Header File Þ
//Ý Þ
//Ý Description: Declarations for the Internals Example Plugin Þ
//Ý Þ
//Ý Þ
//Ý This source code module, and all information, data, and algorithms Þ
//Ý associated with it, are part of CUBE technology (tm). Þ
//Ý PROPRIETARY AND CONFIDENTIAL Þ
//Ý Copyright (c) 1996-2014 Image Space Incorporated. All rights reserved. Þ
//Ý Þ
//Ý Þ
//Ý Change history: Þ
//Ý tag.2005.11.30: created Þ
//Ý Þ
//ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
#ifndef _INTERNALS_EXAMPLE_H
#define _INTERNALS_EXAMPLE_H
#include "InternalsPlugin.hpp"
// This is used for the app to use the plugin for its intended purpose
class ExampleInternalsPlugin : public InternalsPluginV01 // REMINDER: exported function GetPluginVersion() should return 1 if you are deriving from this InternalsPluginV01, 2 for InternalsPluginV02, etc.
{
public:
// Constructor/destructor
ExampleInternalsPlugin() {}
~ExampleInternalsPlugin() {}
// These are the functions derived from base class InternalsPlugin
// that can be implemented.
void Startup( long version ); // game startup
void Shutdown(); // game shutdown
void EnterRealtime(); // entering realtime
void ExitRealtime(); // exiting realtime
void StartSession(); // session has started
void EndSession(); // session has ended
// GAME OUTPUT
long WantsTelemetryUpdates() { return( 1 ); } // CHANGE TO 1 TO ENABLE TELEMETRY EXAMPLE!
void UpdateTelemetry( const TelemInfoV01 &info );
bool WantsGraphicsUpdates() { return( false ); } // CHANGE TO TRUE TO ENABLE GRAPHICS EXAMPLE!
void UpdateGraphics( const GraphicsInfoV01 &info );
// GAME INPUT
bool HasHardwareInputs() { return( false ); } // CHANGE TO TRUE TO ENABLE HARDWARE EXAMPLE!
void UpdateHardware( const double fDT ) { mET += fDT; } // update the hardware with the time between frames
void EnableHardware() { mEnabled = true; } // message from game to enable hardware
void DisableHardware() { mEnabled = false; } // message from game to disable hardware
// See if the plugin wants to take over a hardware control. If the plugin takes over the
// control, this method returns true and sets the value of the double pointed to by the
// second arg. Otherwise, it returns false and leaves the double unmodified.
bool CheckHWControl( const char * const controlName, double &fRetVal );
bool ForceFeedback( double &forceValue ); // SEE FUNCTION BODY TO ENABLE FORCE EXAMPLE
// SCORING OUTPUT
bool WantsScoringUpdates() { return( false ); } // CHANGE TO TRUE TO ENABLE SCORING EXAMPLE!
void UpdateScoring( const ScoringInfoV01 &info );
// COMMENTARY INPUT
bool RequestCommentary( CommentaryRequestInfoV01 &info ); // SEE FUNCTION BODY TO ENABLE COMMENTARY EXAMPLE
private:
void WriteToAllExampleOutputFiles( const char * const openStr, const char * const msg );
double mET; // needed for the hardware example
bool mEnabled; // needed for the hardware example
};
#endif // _INTERNALS_EXAMPLE_H

958
Include/InternalsPlugin.hpp Normal file
View file

@ -0,0 +1,958 @@
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F> <20>
//<2F> Module: Header file for internals plugin <20>
//<2F> <20>
//<2F> Description: Interface declarations for internals plugin <20>
//<2F> <20>
//<2F> This source code module, and all information, data, and algorithms <20>
//<2F> associated with it, are part of isiMotor Technology (tm). <20>
//<2F> PROPRIETARY AND CONFIDENTIAL <20>
//<2F> Copyright (c) 1996-2015 Image Space Incorporated. All rights reserved. <20>
//<2F> <20>
//<2F> Change history: <20>
//<2F> tag.2005.11.29: created <20>
//<2F> <20>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifndef _INTERNALS_PLUGIN_HPP_
#define _INTERNALS_PLUGIN_HPP_
#include "PluginObjects.hpp" // base class for plugin objects to derive from
// #include <cmath> // for sqrt()
// #include <windows.h> // for HWND
struct HWND
{
int d;
};
double sqrt(double d) {
return d;
}
// rF and plugins must agree on structure packing, so set it explicitly here ... whatever the current
// packing is will be restored at the end of this include with another #pragma.
#pragma pack(push, 4)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//<2F> Version01 Structures <20>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct TelemVect3
{
double x, y, z;
void Set(const double a, const double b, const double c)
{
x = a;
y = b;
z = c;
}
// Allowed to reference as [0], [1], or [2], instead of .x, .y, or .z, respectively
double &operator[](long i) { return ((&x)[i]); }
const double &operator[](long i) const { return ((&x)[i]); }
};
struct TelemQuat
{
double w, x, y, z;
// Convert this quaternion to a matrix
void ConvertQuatToMat(TelemVect3 ori[3]) const
{
const double x2 = x + x;
const double xx = x * x2;
const double y2 = y + y;
const double yy = y * y2;
const double z2 = z + z;
const double zz = z * z2;
const double xz = x * z2;
const double xy = x * y2;
const double wy = w * y2;
const double wx = w * x2;
const double wz = w * z2;
const double yz = y * z2;
ori[0][0] = (double)1.0 - (yy + zz);
ori[0][1] = xy - wz;
ori[0][2] = xz + wy;
ori[1][0] = xy + wz;
ori[1][1] = (double)1.0 - (xx + zz);
ori[1][2] = yz - wx;
ori[2][0] = xz - wy;
ori[2][1] = yz + wx;
ori[2][2] = (double)1.0 - (xx + yy);
}
// Convert a matrix to this quaternion
void ConvertMatToQuat(const TelemVect3 ori[3])
{
const double trace = ori[0][0] + ori[1][1] + ori[2][2] + (double)1.0;
if (trace > 0.0625f)
{
const double sqrtTrace = sqrt(trace);
const double s = (double)0.5 / sqrtTrace;
w = (double)0.5 * sqrtTrace;
x = (ori[2][1] - ori[1][2]) * s;
y = (ori[0][2] - ori[2][0]) * s;
z = (ori[1][0] - ori[0][1]) * s;
}
else if ((ori[0][0] > ori[1][1]) && (ori[0][0] > ori[2][2]))
{
const double sqrtTrace = sqrt((double)1.0 + ori[0][0] - ori[1][1] - ori[2][2]);
const double s = (double)0.5 / sqrtTrace;
w = (ori[2][1] - ori[1][2]) * s;
x = (double)0.5 * sqrtTrace;
y = (ori[0][1] + ori[1][0]) * s;
z = (ori[0][2] + ori[2][0]) * s;
}
else if (ori[1][1] > ori[2][2])
{
const double sqrtTrace = sqrt((double)1.0 + ori[1][1] - ori[0][0] - ori[2][2]);
const double s = (double)0.5 / sqrtTrace;
w = (ori[0][2] - ori[2][0]) * s;
x = (ori[0][1] + ori[1][0]) * s;
y = (double)0.5 * sqrtTrace;
z = (ori[1][2] + ori[2][1]) * s;
}
else
{
const double sqrtTrace = sqrt((double)1.0 + ori[2][2] - ori[0][0] - ori[1][1]);
const double s = (double)0.5 / sqrtTrace;
w = (ori[1][0] - ori[0][1]) * s;
x = (ori[0][2] + ori[2][0]) * s;
y = (ori[1][2] + ori[2][1]) * s;
z = (double)0.5 * sqrtTrace;
}
}
};
struct TelemWheelV01
{
double mSuspensionDeflection; // meters
double mRideHeight; // meters
double mSuspForce; // pushrod load in Newtons
double mBrakeTemp; // Celsius
double mBrakePressure; // currently 0.0-1.0, depending on driver input and brake balance; will convert to true brake pressure (kPa) in future
double mRotation; // radians/sec
double mLateralPatchVel; // lateral velocity at contact patch
double mLongitudinalPatchVel; // longitudinal velocity at contact patch
double mLateralGroundVel; // lateral velocity at contact patch
double mLongitudinalGroundVel; // longitudinal velocity at contact patch
double mCamber; // radians (positive is left for left-side wheels, right for right-side wheels)
double mLateralForce; // Newtons
double mLongitudinalForce; // Newtons
double mTireLoad; // Newtons
double mGripFract; // an approximation of what fraction of the contact patch is sliding
double mPressure; // kPa (tire pressure)
double mTemperature[3]; // Kelvin (subtract 273.15 to get Celsius), left/center/right (not to be confused with inside/center/outside!)
double mWear; // wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss
char mTerrainName[16]; // the material prefixes from the TDF file
unsigned char mSurfaceType; // 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip, 6=special
bool mFlat; // whether tire is flat
bool mDetached; // whether wheel is detached
double mVerticalTireDeflection; // how much is tire deflected from its (speed-sensitive) radius
double mWheelYLocation; // wheel's y location relative to vehicle y location
double mToe; // current toe angle w.r.t. the vehicle
double mTireCarcassTemperature; // rough average of temperature samples from carcass (Kelvin)
double mTireInnerLayerTemperature[3]; // rough average of temperature samples from innermost layer of rubber (before carcass) (Kelvin)
unsigned char mExpansion[24]; // for future use
};
// Our world coordinate system is left-handed, with +y pointing up.
// The local vehicle coordinate system is as follows:
// +x points out the left side of the car (from the driver's perspective)
// +y points out the roof
// +z points out the back of the car
// Rotations are as follows:
// +x pitches up
// +y yaws to the right
// +z rolls to the right
// Note that ISO vehicle coordinates (+x forward, +y right, +z upward) are
// right-handed. If you are using that system, be sure to negate any rotation
// or torque data because things rotate in the opposite direction. In other
// words, a -z velocity in rFactor is a +x velocity in ISO, but a -z rotation
// in rFactor is a -x rotation in ISO!!!
struct TelemInfoV01
{
// Time
long mID; // slot ID (note that it can be re-used in multiplayer after someone leaves)
double mDeltaTime; // time since last update (seconds)
double mElapsedTime; // game session time
long mLapNumber; // current lap number
double mLapStartET; // time this lap was started
char mVehicleName[64]; // current vehicle name
char mTrackName[64]; // current track name
// Position and derivatives
TelemVect3 mPos; // world position in meters
TelemVect3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates
TelemVect3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates
// Orientation and derivatives
TelemVect3 mOri[3]; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local
// vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively
TelemVect3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates
TelemVect3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates
// Vehicle status
long mGear; // -1=reverse, 0=neutral, 1+=forward gears
double mEngineRPM; // engine RPM
double mEngineWaterTemp; // Celsius
double mEngineOilTemp; // Celsius
double mClutchRPM; // clutch RPM
// Driver input
double mUnfilteredThrottle; // ranges 0.0-1.0
double mUnfilteredBrake; // ranges 0.0-1.0
double mUnfilteredSteering; // ranges -1.0-1.0 (left to right)
double mUnfilteredClutch; // ranges 0.0-1.0
// Filtered input (various adjustments for rev or speed limiting, TC, ABS?, speed sensitive steering, clutch work for semi-automatic shifting, etc.)
double mFilteredThrottle; // ranges 0.0-1.0
double mFilteredBrake; // ranges 0.0-1.0
double mFilteredSteering; // ranges -1.0-1.0 (left to right)
double mFilteredClutch; // ranges 0.0-1.0
// Misc
double mSteeringShaftTorque; // torque around steering shaft (used to be mSteeringArmForce, but that is not necessarily accurate for feedback purposes)
double mFront3rdDeflection; // deflection at front 3rd spring
double mRear3rdDeflection; // deflection at rear 3rd spring
// Aerodynamics
double mFrontWingHeight; // front wing height
double mFrontRideHeight; // front ride height
double mRearRideHeight; // rear ride height
double mDrag; // drag
double mFrontDownforce; // front downforce
double mRearDownforce; // rear downforce
// State/damage info
double mFuel; // amount of fuel (liters)
double mEngineMaxRPM; // rev limit
unsigned char mScheduledStops; // number of scheduled pitstops
bool mOverheating; // whether overheating icon is shown
bool mDetached; // whether any parts (besides wheels) have been detached
bool mHeadlights; // whether headlights are on
unsigned char mDentSeverity[8]; // dent severity at 8 locations around the car (0=none, 1=some, 2=more)
double mLastImpactET; // time of last impact
double mLastImpactMagnitude; // magnitude of last impact
TelemVect3 mLastImpactPos; // location of last impact
// Expanded
double mEngineTorque; // current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it)
long mCurrentSector; // the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002)
unsigned char mSpeedLimiter; // whether speed limiter is on
unsigned char mMaxGears; // maximum forward gears
unsigned char mFrontTireCompoundIndex; // index within brand
unsigned char mRearTireCompoundIndex; // index within brand
double mFuelCapacity; // capacity in liters
unsigned char mFrontFlapActivated; // whether front flap is activated
unsigned char mRearFlapActivated; // whether rear flap is activated
unsigned char mRearFlapLegalStatus; // 0=disallowed, 1=criteria detected but not allowed quite yet, 2=allowed
unsigned char mIgnitionStarter; // 0=off 1=ignition 2=ignition+starter
char mFrontTireCompoundName[18]; // name of front tire compound
char mRearTireCompoundName[18]; // name of rear tire compound
unsigned char mSpeedLimiterAvailable; // whether speed limiter is available
unsigned char mAntiStallActivated; // whether (hard) anti-stall is activated
unsigned char mUnused[2]; //
float mVisualSteeringWheelRange; // the *visual* steering wheel range
double mRearBrakeBias; // fraction of brakes on rear
double mTurboBoostPressure; // current turbo boost pressure if available
float mPhysicsToGraphicsOffset[3]; // offset from static CG to graphical center
float mPhysicalSteeringWheelRange; // the *physical* steering wheel range
// Future use
unsigned char mExpansion[152]; // for future use (note that the slot ID has been moved to mID above)
// keeping this at the end of the structure to make it easier to replace in future versions
TelemWheelV01 mWheel[4]; // wheel info (front left, front right, rear left, rear right)
};
struct GraphicsInfoV01
{
TelemVect3 mCamPos; // camera position
TelemVect3 mCamOri[3]; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local
HWND mHWND; // app handle
double mAmbientRed;
double mAmbientGreen;
double mAmbientBlue;
};
struct GraphicsInfoV02 : public GraphicsInfoV01
{
long mID; // slot ID being viewed (-1 if invalid)
// Camera types (some of these may only be used for *setting* the camera type in WantsToViewVehicle())
// 0 = TV cockpit
// 1 = cockpit
// 2 = nosecam
// 3 = swingman
// 4 = trackside (nearest)
// 5 = onboard000
// :
// :
// 1004 = onboard999
// 1005+ = (currently unsupported, in the future may be able to set/get specific trackside camera)
long mCameraType; // see above comments for possible values
unsigned char mExpansion[128]; // for future use (possibly camera name)
};
struct CameraControlInfoV01
{
// Cameras
long mID; // slot ID to view
long mCameraType; // see GraphicsInfoV02 comments for values
// Replays (note that these are asynchronous)
bool mReplayActive; // This variable is an *input* filled with whether the replay is currently active (as opposed to realtime).
bool mReplayUnused; //
unsigned char mReplayCommand; // 0=do nothing, 1=begin, 2=end, 3=rewind, 4=fast backwards, 5=backwards, 6=slow backwards, 7=stop, 8=slow play, 9=play, 10=fast play, 11=fast forward
bool mReplaySetTime; // Whether to skip to the following replay time:
float mReplaySeconds; // The replay time in seconds to skip to (note: the current replay maximum ET is passed into this variable in case you need it)
//
unsigned char mExpansion[120]; // for future use (possibly camera name & positions/orientations)
};
struct MessageInfoV01
{
char mText[128]; // message to display
unsigned char mDestination; // 0 = message center, 1 = chat (can be used for multiplayer chat commands)
unsigned char mTranslate; // 0 = do not attempt to translate, 1 = attempt to translate
unsigned char mExpansion[126]; // for future use (possibly what color, what font, and seconds to display)
};
struct VehicleScoringInfoV01
{
long mID; // slot ID (note that it can be re-used in multiplayer after someone leaves)
char mDriverName[32]; // driver name
char mVehicleName[64]; // vehicle name
short mTotalLaps; // laps completed
signed char mSector; // 0=sector3, 1=sector1, 2=sector2 (don't ask why)
signed char mFinishStatus; // 0=none, 1=finished, 2=dnf, 3=dq
double mLapDist; // current distance around track
double mPathLateral; // lateral position with respect to *very approximate* "center" path
double mTrackEdge; // track edge (w.r.t. "center" path) on same side of track as vehicle
double mBestSector1; // best sector 1
double mBestSector2; // best sector 2 (plus sector 1)
double mBestLapTime; // best lap time
double mLastSector1; // last sector 1
double mLastSector2; // last sector 2 (plus sector 1)
double mLastLapTime; // last lap time
double mCurSector1; // current sector 1 if valid
double mCurSector2; // current sector 2 (plus sector 1) if valid
// no current laptime because it instantly becomes "last"
short mNumPitstops; // number of pitstops made
short mNumPenalties; // number of outstanding penalties
bool mIsPlayer; // is this the player's vehicle
signed char mControl; // who's in control: -1=nobody (shouldn't get this), 0=local player, 1=local AI, 2=remote, 3=replay (shouldn't get this)
bool mInPits; // between pit entrance and pit exit (not always accurate for remote vehicles)
unsigned char mPlace; // 1-based position
char mVehicleClass[32]; // vehicle class
// Dash Indicators
double mTimeBehindNext; // time behind vehicle in next higher place
long mLapsBehindNext; // laps behind vehicle in next higher place
double mTimeBehindLeader; // time behind leader
long mLapsBehindLeader; // laps behind leader
double mLapStartET; // time this lap was started
// Position and derivatives
TelemVect3 mPos; // world position in meters
TelemVect3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates
TelemVect3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates
// Orientation and derivatives
TelemVect3 mOri[3]; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local
// vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively
TelemVect3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates
TelemVect3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates
// tag.2012.03.01 - stopped casting some of these so variables now have names and mExpansion has shrunk, overall size and old data locations should be same
unsigned char mHeadlights; // status of headlights
unsigned char mPitState; // 0=none, 1=request, 2=entering, 3=stopped, 4=exiting
unsigned char mServerScored; // whether this vehicle is being scored by server (could be off in qualifying or racing heats)
unsigned char mIndividualPhase; // game phases (described below) plus 9=after formation, 10=under yellow, 11=under blue (not used)
long mQualification; // 1-based, can be -1 when invalid
double mTimeIntoLap; // estimated time into lap
double mEstimatedLapTime; // estimated laptime used for 'time behind' and 'time into lap' (note: this may changed based on vehicle and setup!?)
char mPitGroup[24]; // pit group (same as team name unless pit is shared)
unsigned char mFlag; // primary flag being shown to vehicle (currently only 0=green or 6=blue)
bool mUnderYellow; // whether this car has taken a full-course caution flag at the start/finish line
unsigned char mCountLapFlag; // 0 = do not count lap or time, 1 = count lap but not time, 2 = count lap and time
bool mInGarageStall; // appears to be within the correct garage stall
unsigned char mUpgradePack[16]; // Coded upgrades
// Future use
// tag.2012.04.06 - SEE ABOVE!
unsigned char mExpansion[60]; // for future use
};
struct ScoringInfoV01
{
char mTrackName[64]; // current track name
long mSession; // current session (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race)
double mCurrentET; // current time
double mEndET; // ending time
long mMaxLaps; // maximum laps
double mLapDist; // distance around track
char *mResultsStream; // results stream additions since last update (newline-delimited and NULL-terminated)
long mNumVehicles; // current number of vehicles
// Game phases:
// 0 Before session has begun
// 1 Reconnaissance laps (race only)
// 2 Grid walk-through (race only)
// 3 Formation lap (race only)
// 4 Starting-light countdown has begun (race only)
// 5 Green flag
// 6 Full course yellow / safety car
// 7 Session stopped
// 8 Session over
unsigned char mGamePhase;
// Yellow flag states (applies to full-course only)
// -1 Invalid
// 0 None
// 1 Pending
// 2 Pits closed
// 3 Pit lead lap
// 4 Pits open
// 5 Last lap
// 6 Resume
// 7 Race halt (not currently used)
signed char mYellowFlagState;
signed char mSectorFlag[3]; // whether there are any local yellows at the moment in each sector (not sure if sector 0 is first or last, so test)
unsigned char mStartLight; // start light frame (number depends on track)
unsigned char mNumRedLights; // number of red lights in start sequence
bool mInRealtime; // in realtime as opposed to at the monitor
char mPlayerName[32]; // player name (including possible multiplayer override)
char mPlrFileName[64]; // may be encoded to be a legal filename
// weather
double mDarkCloud; // cloud darkness? 0.0-1.0
double mRaining; // raining severity 0.0-1.0
double mAmbientTemp; // temperature (Celsius)
double mTrackTemp; // temperature (Celsius)
TelemVect3 mWind; // wind speed
double mMinPathWetness; // minimum wetness on main path 0.0-1.0
double mMaxPathWetness; // maximum wetness on main path 0.0-1.0
// Future use
unsigned char mExpansion[256];
// keeping this at the end of the structure to make it easier to replace in future versions
VehicleScoringInfoV01 *mVehicle; // array of vehicle scoring info's
};
struct CommentaryRequestInfoV01
{
char mName[32]; // one of the event names in the commentary INI file
double mInput1; // first value to pass in (if any)
double mInput2; // first value to pass in (if any)
double mInput3; // first value to pass in (if any)
bool mSkipChecks; // ignores commentary detail and random probability of event
// constructor (for noobs, this just helps make sure everything is initialized to something reasonable)
CommentaryRequestInfoV01()
{
mName[0] = 0;
mInput1 = 0.0;
mInput2 = 0.0;
mInput3 = 0.0;
mSkipChecks = false;
}
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//<2F> Version02 Structures <20>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct PhysicsOptionsV01
{
unsigned char mTractionControl; // 0 (off) - 3 (high)
unsigned char mAntiLockBrakes; // 0 (off) - 2 (high)
unsigned char mStabilityControl; // 0 (off) - 2 (high)
unsigned char mAutoShift; // 0 (off), 1 (upshifts), 2 (downshifts), 3 (all)
unsigned char mAutoClutch; // 0 (off), 1 (on)
unsigned char mInvulnerable; // 0 (off), 1 (on)
unsigned char mOppositeLock; // 0 (off), 1 (on)
unsigned char mSteeringHelp; // 0 (off) - 3 (high)
unsigned char mBrakingHelp; // 0 (off) - 2 (high)
unsigned char mSpinRecovery; // 0 (off), 1 (on)
unsigned char mAutoPit; // 0 (off), 1 (on)
unsigned char mAutoLift; // 0 (off), 1 (on)
unsigned char mAutoBlip; // 0 (off), 1 (on)
unsigned char mFuelMult; // fuel multiplier (0x-7x)
unsigned char mTireMult; // tire wear multiplier (0x-7x)
unsigned char mMechFail; // mechanical failure setting; 0 (off), 1 (normal), 2 (timescaled)
unsigned char mAllowPitcrewPush; // 0 (off), 1 (on)
unsigned char mRepeatShifts; // accidental repeat shift prevention (0-5; see PLR file)
unsigned char mHoldClutch; // for auto-shifters at start of race: 0 (off), 1 (on)
unsigned char mAutoReverse; // 0 (off), 1 (on)
unsigned char mAlternateNeutral; // Whether shifting up and down simultaneously equals neutral
// tag.2014.06.09 - yes these are new, but no they don't change the size of the structure nor the address of the other variables in it (because we're just using the existing padding)
unsigned char mAIControl; // Whether player vehicle is currently under AI control
unsigned char mUnused1; //
unsigned char mUnused2; //
float mManualShiftOverrideTime; // time before auto-shifting can resume after recent manual shift
float mAutoShiftOverrideTime; // time before manual shifting can resume after recent auto shift
float mSpeedSensitiveSteering; // 0.0 (off) - 1.0
float mSteerRatioSpeed; // speed (m/s) under which lock gets expanded to full
};
struct EnvironmentInfoV01
{
// TEMPORARY buffers (you should copy them if needed for later use) containing various paths that may be needed. Each of these
// could be relative ("UserData\") or full ("C:\BlahBlah\rFactorProduct\UserData\").
// mPath[ 0 ] points to the UserData directory.
// mPath[ 1 ] points to the CustomPluginOptions.JSON filename.
// mPath[ 2 ] points to the latest results file
// (in the future, we may add paths for the current garage setup, fully upgraded physics files, etc., any other requests?)
const char *mPath[16];
unsigned char mExpansion[256]; // future use
};
struct ScreenInfoV01
{
HWND mAppWindow; // Application window handle
void *mDevice; // Cast type to LPDIRECT3DDEVICE9
void *mRenderTarget; // Cast type to LPDIRECT3DTEXTURE9
long mDriver; // Current video driver index
long mWidth; // Screen width
long mHeight; // Screen height
long mPixelFormat; // Pixel format
long mRefreshRate; // Refresh rate
long mWindowed; // Really just a boolean whether we are in windowed mode
long mOptionsWidth; // Width dimension of screen portion used by UI
long mOptionsHeight; // Height dimension of screen portion used by UI
long mOptionsLeft; // Horizontal starting coordinate of screen portion used by UI
long mOptionsUpper; // Vertical starting coordinate of screen portion used by UI
unsigned char mOptionsLocation; // 0=main UI, 1=track loading, 2=monitor, 3=on track
char mOptionsPage[31]; // the name of the options page
unsigned char mExpansion[224]; // future use
};
struct CustomControlInfoV01
{
// The name passed through CheckHWControl() will be the mUntranslatedName prepended with an underscore (e.g. "Track Map Toggle" -> "_Track Map Toggle")
char mUntranslatedName[64]; // name of the control that will show up in UI (but translated if available)
long mRepeat; // 0=registers once per hit, 1=registers once, waits briefly, then starts repeating quickly, 2=registers as long as key is down
unsigned char mExpansion[64]; // future use
};
struct WeatherControlInfoV01
{
// The current conditions are passed in with the API call. The following ET (Elapsed Time) value should typically be far
// enough in the future that it can be interpolated smoothly, and allow clouds time to roll in before rain starts. In
// other words you probably shouldn't have mCloudiness and mRaining suddenly change from 0.0 to 1.0 and expect that
// to happen in a few seconds without looking crazy.
double mET; // when you want this weather to take effect
// mRaining[1][1] is at the origin (2013.12.19 - and currently the only implemented node), while the others
// are spaced at <trackNodeSize> meters where <trackNodeSize> is the maximum absolute value of a track vertex
// coordinate (and is passed into the API call).
double mRaining[3][3]; // rain (0.0-1.0) at different nodes
double mCloudiness; // general cloudiness (0.0=clear to 1.0=dark), will be automatically overridden to help ensure clouds exist over rainy areas
double mAmbientTempK; // ambient temperature (Kelvin)
double mWindMaxSpeed; // maximum speed of wind (ground speed, but it affects how fast the clouds move, too)
bool mApplyCloudinessInstantly; // preferably we roll the new clouds in, but you can instantly change them now
bool mUnused1; //
bool mUnused2; //
bool mUnused3; //
unsigned char mExpansion[508]; // future use (humidity, pressure, air density, etc.)
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//<2F> Version07 Structures <20>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct CustomVariableV01
{
char mCaption[128]; // Name of variable. This will be used for storage. In the future, this may also be used in the UI (after attempting to translate).
long mNumSettings; // Number of available settings. The special value 0 should be used for types that have limitless possibilities, which will be treated as a string type.
long mCurrentSetting; // Current setting (also the default setting when returned in GetCustomVariable()). This is zero-based, so: ( 0 <= mCurrentSetting < mNumSettings )
// future expansion
unsigned char mExpansion[256];
};
struct CustomSettingV01
{
char mName[128]; // Enumerated name of setting (only used if CustomVariableV01::mNumSettings > 0). This will be stored in the JSON file for informational purposes only. It may also possibly be used in the UI in the future.
};
struct MultiSessionParticipantV01
{
// input only
long mID; // slot ID (if loaded) or -1 (if currently disconnected)
char mDriverName[32]; // driver name
char mVehicleName[64]; // vehicle name
unsigned char mUpgradePack[16]; // coded upgrades
float mBestPracticeTime; // best practice time
long mQualParticipantIndex; // once qualifying begins, this becomes valid and ranks participants according to practice time if possible
float mQualificationTime[4]; // best qualification time in up to 4 qual sessions
float mFinalRacePlace[4]; // final race place in up to 4 race sessions
float mFinalRaceTime[4]; // final race time in up to 4 race sessions
// input/output
bool mServerScored; // whether vehicle is allowed to participate in current session
long mGridPosition; // 1-based grid position for current race session (or upcoming race session if it is currently warmup), or -1 if currently disconnected
// long mPitIndex;
// long mGarageIndex;
// future expansion
unsigned char mExpansion[128];
};
struct MultiSessionRulesV01
{
// input only
long mSession; // current session (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race)
long mSpecialSlotID; // slot ID of someone who just joined, or -2 requesting to update qual order, or -1 (default/general)
char mTrackType[32]; // track type from GDB
long mNumParticipants; // number of participants (vehicles)
// input/output
MultiSessionParticipantV01 *mParticipant; // array of partipants (vehicles)
long mNumQualSessions; // number of qualifying sessions configured
long mNumRaceSessions; // number of race sessions configured
long mMaxLaps; // maximum laps allowed in current session (LONG_MAX = unlimited) (note: cannot currently edit in *race* sessions)
long mMaxSeconds; // maximum time allowed in current session (LONG_MAX = unlimited) (note: cannot currently edit in *race* sessions)
char mName[32]; // untranslated name override for session (please use mixed case here, it should get uppercased if necessary)
// future expansion
unsigned char mExpansion[256];
};
enum TrackRulesCommandV01 //
{
TRCMD_ADD_FROM_TRACK = 0, // crossed s/f line for first time after full-course yellow was called
TRCMD_ADD_FROM_PIT, // exited pit during full-course yellow
TRCMD_ADD_FROM_UNDQ, // during a full-course yellow, the admin reversed a disqualification
TRCMD_REMOVE_TO_PIT, // entered pit during full-course yellow
TRCMD_REMOVE_TO_DNF, // vehicle DNF'd during full-course yellow
TRCMD_REMOVE_TO_DQ, // vehicle DQ'd during full-course yellow
TRCMD_REMOVE_TO_UNLOADED, // vehicle unloaded (possibly kicked out or banned) during full-course yellow
TRCMD_MOVE_TO_BACK, // misbehavior during full-course yellow, resulting in the penalty of being moved to the back of their current line
TRCMD_LONGEST_LINE, // misbehavior during full-course yellow, resulting in the penalty of being moved to the back of the longest line
//------------------
TRCMD_MAXIMUM // should be last
};
struct TrackRulesActionV01
{
// input only
TrackRulesCommandV01 mCommand; // recommended action
long mID; // slot ID if applicable
double mET; // elapsed time that event occurred, if applicable
};
enum TrackRulesColumnV01
{
TRCOL_LEFT_LANE = 0, // left (inside)
TRCOL_MIDLEFT_LANE, // mid-left
TRCOL_MIDDLE_LANE, // middle
TRCOL_MIDRIGHT_LANE, // mid-right
TRCOL_RIGHT_LANE, // right (outside)
//------------------
TRCOL_MAX_LANES, // should be after the valid static lane choices
//------------------
TRCOL_INVALID = TRCOL_MAX_LANES, // currently invalid (hasn't crossed line or in pits/garage)
TRCOL_FREECHOICE, // free choice (dynamically chosen by driver)
TRCOL_PENDING, // depends on another participant's free choice (dynamically set after another driver chooses)
//------------------
TRCOL_MAXIMUM // should be last
};
struct TrackRulesParticipantV01
{
// input only
long mID; // slot ID
short mFrozenOrder; // 0-based place when caution came out (not valid for formation laps)
short mPlace; // 1-based place (typically used for the initialization of the formation lap track order)
float mYellowSeverity; // a rating of how much this vehicle is contributing to a yellow flag (the sum of all vehicles is compared to TrackRulesV01::mSafetyCarThreshold)
double mCurrentRelativeDistance; // equal to ( ( ScoringInfoV01::mLapDist * this->mRelativeLaps ) + VehicleScoringInfoV01::mLapDist )
// input/output
long mRelativeLaps; // current formation/caution laps relative to safety car (should generally be zero except when safety car crosses s/f line); this can be decremented to implement 'wave around' or 'beneficiary rule' (a.k.a. 'lucky dog' or 'free pass')
TrackRulesColumnV01 mColumnAssignment; // which column (line/lane) that participant is supposed to be in
long mPositionAssignment; // 0-based position within column (line/lane) that participant is supposed to be located at (-1 is invalid)
bool mAllowedToPit; // whether the rules allow this particular vehicle to enter pits right now
bool mUnused[3]; //
double mGoalRelativeDistance; // calculated based on where the leader is, and adjusted by the desired column spacing and the column/position assignments
char mMessage[96]; // a message for this participant to explain what is going on (untranslated; it will get run through translator on client machines)
// future expansion
unsigned char mExpansion[192];
};
enum TrackRulesStageV01 //
{
TRSTAGE_FORMATION_INIT = 0, // initialization of the formation lap
TRSTAGE_FORMATION_UPDATE, // update of the formation lap
TRSTAGE_NORMAL, // normal (non-yellow) update
TRSTAGE_CAUTION_INIT, // initialization of a full-course yellow
TRSTAGE_CAUTION_UPDATE, // update of a full-course yellow
//------------------
TRSTAGE_MAXIMUM // should be last
};
struct TrackRulesV01
{
// input only
double mCurrentET; // current time
TrackRulesStageV01 mStage; // current stage
TrackRulesColumnV01 mPoleColumn; // column assignment where pole position seems to be located
long mNumActions; // number of recent actions
TrackRulesActionV01 *mAction; // array of recent actions
long mNumParticipants; // number of participants (vehicles)
bool mYellowFlagDetected; // whether yellow flag was requested or sum of participant mYellowSeverity's exceeds mSafetyCarThreshold
bool mYellowFlagLapsWasOverridden; // whether mYellowFlagLaps (below) is an admin request
bool mSafetyCarExists; // whether safety car even exists
bool mSafetyCarActive; // whether safety car is active
long mSafetyCarLaps; // number of laps
float mSafetyCarThreshold; // the threshold at which a safety car is called out (compared to the sum of TrackRulesParticipantV01::mYellowSeverity for each vehicle)
double mSafetyCarLapDist; // safety car lap distance
float mSafetyCarLapDistAtStart; // where the safety car starts from
float mPitLaneStartDist; // where the waypoint branch to the pits breaks off (this may not be perfectly accurate)
float mTeleportLapDist; // the front of the teleport locations (a useful first guess as to where to throw the green flag)
// future input expansion
unsigned char mInputExpansion[256];
// input/output
signed char mYellowFlagState; // see ScoringInfoV01 for values
short mYellowFlagLaps; // suggested number of laps to run under yellow (may be passed in with admin command)
long mSafetyCarInstruction; // 0=no change, 1=go active, 2=head for pits
float mSafetyCarSpeed; // maximum speed at which to drive
float mSafetyCarMinimumSpacing; // minimum spacing behind safety car (-1 to indicate no limit)
float mSafetyCarMaximumSpacing; // maximum spacing behind safety car (-1 to indicate no limit)
float mMinimumColumnSpacing; // minimum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced)
float mMaximumColumnSpacing; // maximum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced)
float mMinimumSpeed; // minimum speed that anybody should be driving (-1 to indicate no limit)
float mMaximumSpeed; // maximum speed that anybody should be driving (-1 to indicate no limit)
char mMessage[96]; // a message for everybody to explain what is going on (which will get run through translator on client machines)
TrackRulesParticipantV01 *mParticipant; // array of partipants (vehicles)
// future input/output expansion
unsigned char mInputOutputExpansion[256];
};
struct PitMenuV01
{
long mCategoryIndex; // index of the current category
char mCategoryName[32]; // name of the current category (untranslated)
long mChoiceIndex; // index of the current choice (within the current category)
char mChoiceString[32]; // name of the current choice (may have some translated words)
long mNumChoices; // total number of choices (0 <= mChoiceIndex < mNumChoices)
unsigned char mExpansion[256]; // for future use
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//<2F> Plugin classes used to access internals <20>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Note: use class InternalsPluginV01 and have exported function GetPluginVersion() return 1, or
// use class InternalsPluginV02 and have exported function GetPluginVersion() return 2, etc.
class InternalsPlugin : public PluginObject
{
public:
// General internals methods
InternalsPlugin() {}
virtual ~InternalsPlugin() {}
// GAME FLOW NOTIFICATIONS
virtual void Startup(long version) {} // sim startup with version * 1000
virtual void Shutdown() {} // sim shutdown
virtual void Load() {} // scene/track load
virtual void Unload() {} // scene/track unload
virtual void StartSession() {} // session started
virtual void EndSession() {} // session ended
virtual void EnterRealtime() {} // entering realtime (where the vehicle can be driven)
virtual void ExitRealtime() {} // exiting realtime
// SCORING OUTPUT
virtual bool WantsScoringUpdates() { return (false); } // whether we want scoring updates
virtual void UpdateScoring(const ScoringInfoV01 &info) {} // update plugin with scoring info (approximately five times per second)
// GAME OUTPUT
virtual long WantsTelemetryUpdates() { return (0); } // whether we want telemetry updates (0=no 1=player-only 2=all vehicles)
virtual void UpdateTelemetry(const TelemInfoV01 &info) {} // update plugin with telemetry info
virtual bool WantsGraphicsUpdates() { return (false); } // whether we want graphics updates
virtual void UpdateGraphics(const GraphicsInfoV01 &info) {} // update plugin with graphics info
// COMMENTARY INPUT
virtual bool RequestCommentary(CommentaryRequestInfoV01 &info) { return (false); } // to use our commentary event system, fill in data and return true
// GAME INPUT
virtual bool HasHardwareInputs() { return (false); } // whether plugin has hardware plugins
virtual void UpdateHardware(const double fDT) {} // update the hardware with the time between frames
virtual void EnableHardware() {} // message from game to enable hardware
virtual void DisableHardware() {} // message from game to disable hardware
// See if the plugin wants to take over a hardware control. If the plugin takes over the
// control, this method returns true and sets the value of the double pointed to by the
// second arg. Otherwise, it returns false and leaves the double unmodified.
virtual bool CheckHWControl(const char *const controlName, double &fRetVal) { return false; }
virtual bool ForceFeedback(double &forceValue) { return (false); } // alternate force feedback computation - return true if editing the value
// ERROR FEEDBACK
virtual void Error(const char *const msg) {} // Called with explanation message if there was some sort of error in a plugin callback
};
class InternalsPluginV01 : public InternalsPlugin // Version 01 is the exact same as the original
{
// REMINDER: exported function GetPluginVersion() should return 1 if you are deriving from this InternalsPluginV01!
};
class InternalsPluginV02 : public InternalsPluginV01 // V02 contains everything from V01 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 2 if you are deriving from this InternalsPluginV02!
public:
// This function is called occasionally
virtual void SetPhysicsOptions(PhysicsOptionsV01 &options) {}
};
class InternalsPluginV03 : public InternalsPluginV02 // V03 contains everything from V02 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 3 if you are deriving from this InternalsPluginV03!
public:
virtual unsigned char WantsToViewVehicle(CameraControlInfoV01 &camControl) { return (0); } // return values: 0=do nothing, 1=set ID and camera type, 2=replay controls, 3=both
// EXTENDED GAME OUTPUT
virtual void UpdateGraphics(const GraphicsInfoV02 &info) {} // update plugin with extended graphics info
// MESSAGE BOX INPUT
virtual bool WantsToDisplayMessage(MessageInfoV01 &msgInfo) { return (false); } // set message and return true
};
class InternalsPluginV04 : public InternalsPluginV03 // V04 contains everything from V03 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 4 if you are deriving from this InternalsPluginV04!
public:
// EXTENDED GAME FLOW NOTIFICATIONS
virtual void SetEnvironment(const EnvironmentInfoV01 &info) {} // may be called whenever the environment changes
};
class InternalsPluginV05 : public InternalsPluginV04 // V05 contains everything from V04 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 5 if you are deriving from this InternalsPluginV05!
public:
// SCREEN INFO NOTIFICATIONS
virtual void InitScreen(const ScreenInfoV01 &info) {} // Now happens right after graphics device initialization
virtual void UninitScreen(const ScreenInfoV01 &info) {} // Now happens right before graphics device uninitialization
virtual void DeactivateScreen(const ScreenInfoV01 &info) {} // Window deactivation
virtual void ReactivateScreen(const ScreenInfoV01 &info) {} // Window reactivation
virtual void RenderScreenBeforeOverlays(const ScreenInfoV01 &info) {} // before rFactor overlays
virtual void RenderScreenAfterOverlays(const ScreenInfoV01 &info) {} // after rFactor overlays
virtual void PreReset(const ScreenInfoV01 &info) {} // after detecting device lost but before resetting
virtual void PostReset(const ScreenInfoV01 &info) {} // after resetting
// CUSTOM CONTROLS
virtual bool InitCustomControl(CustomControlInfoV01 &info) { return (false); } // called repeatedly at startup until false is returned
};
class InternalsPluginV06 : public InternalsPluginV05 // V06 contains everything from V05 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 6 if you are deriving from this InternalsPluginV06!
public:
// CONDITIONS CONTROL
virtual bool WantsWeatherAccess() { return (false); } // change to true in order to read or write weather with AccessWeather() call:
virtual bool AccessWeather(double trackNodeSize, WeatherControlInfoV01 &info) { return (false); } // current weather is passed in; return true if you want to change it
// ADDITIONAL GAMEFLOW NOTIFICATIONS
virtual void ThreadStarted(long type) {} // called just after a primary thread is started (type is 0=multimedia or 1=simulation)
virtual void ThreadStopping(long type) {} // called just before a primary thread is stopped (type is 0=multimedia or 1=simulation)
};
class InternalsPluginV07 : public InternalsPluginV06 // V07 contains everything from V06 plus the following:
{
// REMINDER: exported function GetPluginVersion() should return 7 if you are deriving from this InternalsPluginV07!
public:
// CUSTOM PLUGIN VARIABLES
// This relatively simple feature allows plugins to store settings in a shared location without doing their own
// file I/O. Direct UI support may also be added in the future so that end users can control plugin settings within
// rFactor. But for now, users can access the data in UserData\Player\CustomPluginOptions.JSON.
// Plugins should only access these variables through this interface, though:
virtual bool GetCustomVariable(long i, CustomVariableV01 &var) { return (false); } // At startup, this will be called with increasing index (starting at zero) until false is returned. Feel free to add/remove/rearrange the variables when updating your plugin; the index does not have to be consistent from run to run.
virtual void AccessCustomVariable(CustomVariableV01 &var) {} // This will be called at startup, shutdown, and any time that the variable is changed (within the UI).
virtual void GetCustomVariableSetting(CustomVariableV01 &var, long i, CustomSettingV01 &setting) {} // This gets the name of each possible setting for a given variable.
// SCORING CONTROL (only available in single-player or on multiplayer server)
virtual bool WantsMultiSessionRulesAccess() { return (false); } // change to true in order to read or write multi-session rules
virtual bool AccessMultiSessionRules(MultiSessionRulesV01 &info) { return (false); } // current internal rules passed in; return true if you want to change them
virtual bool WantsTrackRulesAccess() { return (false); } // change to true in order to read or write track order (during formation or caution laps)
virtual bool AccessTrackRules(TrackRulesV01 &info) { return (false); } // current track order passed in; return true if you want to change it (note: this will be called immediately after UpdateScoring() when appropriate)
// PIT MENU INFO (currently, the only way to edit the pit menu is to use this in conjunction with CheckHWControl())
virtual bool WantsPitMenuAccess() { return (false); } // change to true in order to view pit menu info
virtual bool AccessPitMenu(PitMenuV01 &info) { return (false); } // currently, the return code should always be false (because we may allow more direct editing in the future)
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// See #pragma at top of file
#pragma pack(pop)
#endif // _INTERNALS_PLUGIN_HPP_

82
Include/PluginObjects.hpp Normal file
View file

@ -0,0 +1,82 @@
//ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
//Ý Þ
//Ý Module: Header file for plugin object types Þ
//Ý Þ
//Ý Description: interface declarations for plugin objects Þ
//Ý Þ
//Ý This source code module, and all information, data, and algorithms Þ
//Ý associated with it, are part of isiMotor Technology (tm). Þ
//Ý PROPRIETARY AND CONFIDENTIAL Þ
//Ý Copyright (c) 1996-2013 Image Space Incorporated. All rights reserved. Þ
//Ý Þ
//Ý Change history: Þ
//Ý tag.2008.02.15: created Þ
//Ý Þ
//ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
#ifndef _PLUGIN_OBJECTS_HPP_
#define _PLUGIN_OBJECTS_HPP_
// rF currently uses 4-byte packing ... whatever the current packing is will
// be restored at the end of this include with another #pragma.
#pragma pack( push, 4 )
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³ types of plugins ³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
enum PluginObjectType
{
PO_INVALID = -1,
//-------------------
PO_GAMESTATS = 0,
PO_NCPLUGIN = 1,
PO_IVIBE = 2,
PO_INTERNALS = 3,
PO_RFONLINE = 4,
//-------------------
PO_MAXIMUM
};
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³ PluginObject ³
//³ - interface used by plugin classes. ³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
class PluginObject
{
private:
class PluginInfo *mInfo; // used by main executable to obtain info about the plugin that implements this object
public:
void SetInfo( class PluginInfo *p ) { mInfo = p; } // used by main executable
class PluginInfo *GetInfo() const { return( mInfo ); } // used by main executable
class PluginInfo *GetInfo() { return( mInfo ); } // used by main executable
};
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³ typedefs for dll functions - easier to use a typedef than to type ³
//³ out the crazy syntax for declaring and casting function pointers ³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
typedef const char * ( __cdecl *GETPLUGINNAME )();
typedef PluginObjectType ( __cdecl *GETPLUGINTYPE )();
typedef int ( __cdecl *GETPLUGINVERSION )();
typedef PluginObject * ( __cdecl *CREATEPLUGINOBJECT )();
typedef void ( __cdecl *DESTROYPLUGINOBJECT )( PluginObject *obj );
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
// See #pragma at top of file
#pragma pack( pop )
#endif // _PLUGIN_OBJECTS_HPP_

43
Include/RFServer.hpp Normal file
View file

@ -0,0 +1,43 @@
#ifndef _RF_SERVER_H
#define _RF_SERVER_H
#include "InternalsPlugin.hpp"
#include "Socket.hpp"
// This is used for the app to use the plugin for its intended purpose
class RFServerPlugin : public InternalsPluginV07 // REMINDER: exported function GetPluginVersion() should return 1 if you are deriving from this InternalsPluginV01, 2 for InternalsPluginV02, etc.
{
public:
// Constructor/destructor
RFServerPlugin();
~RFServerPlugin();
// These are the functions derived from base class InternalsPlugin
// that can be implemented.
void Startup(long version); // game startup
void Shutdown(); // game shutdown
void EnterRealtime(); // entering realtime
void ExitRealtime(); // exiting realtime
void StartSession(); // session has started
void EndSession(); // session has ended
// GAME OUTPUT
long WantsTelemetryUpdates() { return (1); } // CHANGE TO 1 TO ENABLE TELEMETRY EXAMPLE!
void UpdateTelemetry(const TelemInfoV01 &info);
// SCORING OUTPUT
bool WantsScoringUpdates() { return (false); } // CHANGE TO TRUE TO ENABLE SCORING EXAMPLE!
void UpdateScoring(const ScoringInfoV01 &info);
bool WantsPitMenuAccess() { return (true); }
bool AccessPitMenu(PitMenuV01 &info);
private:
Socket *socket;
};
#endif // _RF_SERVER_H

92
Include/Socket.hpp Normal file
View file

@ -0,0 +1,92 @@
#ifndef _SOCKET_HPP_
#define _SOCKET_HPP_
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <stdexcept>
#pragma comment(lib, "Ws2_32.lib")
class Socket
{
private:
SOCKET serverSocket;
struct sockaddr_in SenderAddr;
int SenderAddrSize;
public:
Socket(short port)
{
int SenderAddrSize = sizeof(SenderAddr);
WSADATA wsaData;
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (res != NO_ERROR)
{
throw std::runtime_error("WSAStartup failed");
}
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serverSocket == INVALID_SOCKET)
{
throw std::runtime_error("socket creation failed: " + WSAGetLastError());
}
// Non blocking setting
u_long val = 1; // 0: blocking, 1: non-blocking
ioctlsocket(serverSocket, FIONBIO, &val);
// Bind the socket to any address and the specified port.
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(serverSocket, (SOCKADDR *)&serverAddr, sizeof(serverAddr)))
{
throw std::runtime_error("binding socket failed: " + WSAGetLastError());
}
}
~Socket()
{
closesocket(serverSocket);
WSACleanup();
}
std::string receive()
{
int bytes_received;
char serverBuf[1025];
int serverBufLen = 1024;
bytes_received = recvfrom(serverSocket, serverBuf, serverBufLen, 0 /* no flags*/, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
if (bytes_received == SOCKET_ERROR)
{
throw std::runtime_error("receive failed: " + WSAGetLastError());
}
serverBuf[bytes_received] = '\0';
std::string msg(serverBuf);
return msg;
}
void send(std::string msg)
{
if (msg.length() > 1024)
{
throw std::runtime_error("msg is too long: " + msg.length());
}
int sendResult = sendto(serverSocket, (const char *)&msg, msg.length(), 0, (SOCKADDR *)&SenderAddr, SenderAddrSize);
if (sendResult == SOCKET_ERROR)
{
throw std::runtime_error("send failed: " + WSAGetLastError());
}
}
private:
};
#endif // _SOCKET_HPP_

383
Source/Example.cpp Normal file
View file

@ -0,0 +1,383 @@
//ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
//Ý Þ
//Ý Module: Internals Example Source File Þ
//Ý Þ
//Ý Description: Declarations for the Internals Example Plugin Þ
//Ý Þ
//Ý Þ
//Ý This source code module, and all information, data, and algorithms Þ
//Ý associated with it, are part of CUBE technology (tm). Þ
//Ý PROPRIETARY AND CONFIDENTIAL Þ
//Ý Copyright (c) 1996-2014 Image Space Incorporated. All rights reserved. Þ
//Ý Þ
//Ý Þ
//Ý Change history: Þ
//Ý tag.2005.11.30: created Þ
//Ý Þ
//ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
#include "Example.hpp" // corresponding header file
#include <math.h> // for atan2, sqrt
#include <stdio.h> // for sample output
// plugin information
extern "C" __declspec( dllexport )
const char * __cdecl GetPluginName() { return( "ExamplePlugin - 2008.02.13" ); }
extern "C" __declspec( dllexport )
PluginObjectType __cdecl GetPluginType() { return( PO_INTERNALS ); }
extern "C" __declspec( dllexport )
int __cdecl GetPluginVersion() { return( 1 ); } // InternalsPluginV01 functionality (if you change this return value, you must derive from the appropriate class!)
extern "C" __declspec( dllexport )
PluginObject * __cdecl CreatePluginObject() { return( (PluginObject *) new ExampleInternalsPlugin ); }
extern "C" __declspec( dllexport )
void __cdecl DestroyPluginObject( PluginObject *obj ) { delete( (ExampleInternalsPlugin *) obj ); }
// ExampleInternalsPlugin class
void ExampleInternalsPlugin::WriteToAllExampleOutputFiles( const char * const openStr, const char * const msg )
{
FILE *fo;
fo = fopen( "ExampleInternalsTelemetryOutput.txt", openStr );
if( fo != NULL )
{
fprintf( fo, "%s\n", msg );
fclose( fo );
}
fo = fopen( "ExampleInternalsGraphicsOutput.txt", openStr );
if( fo != NULL )
{
fprintf( fo, "%s\n", msg );
fclose( fo );
}
fo = fopen( "ExampleInternalsScoringOutput.txt", openStr );
if( fo != NULL )
{
fprintf( fo, "%s\n", msg );
fclose( fo );
}
}
void ExampleInternalsPlugin::Startup( long version )
{
char temp[80];
sprintf( temp, "-STARTUP- (version %.3f)", (float) version / 1000.0f );
// Open ports, read configs, whatever you need to do. For now, I'll just clear out the
// example output data files.
WriteToAllExampleOutputFiles( "w", temp );
// default HW control enabled to true
mEnabled = true;
}
void ExampleInternalsPlugin::Shutdown()
{
WriteToAllExampleOutputFiles( "a", "-SHUTDOWN-" );
}
void ExampleInternalsPlugin::StartSession()
{
WriteToAllExampleOutputFiles( "a", "--STARTSESSION--" );
}
void ExampleInternalsPlugin::EndSession()
{
WriteToAllExampleOutputFiles( "a", "--ENDSESSION--" );
}
void ExampleInternalsPlugin::EnterRealtime()
{
// start up timer every time we enter realtime
mET = 0.0;
WriteToAllExampleOutputFiles( "a", "---ENTERREALTIME---" );
}
void ExampleInternalsPlugin::ExitRealtime()
{
WriteToAllExampleOutputFiles( "a", "---EXITREALTIME---" );
}
void ExampleInternalsPlugin::UpdateTelemetry( const TelemInfoV01 &info )
{
// Use the incoming data, for now I'll just write some of it to a file to a) make sure it
// is working, and b) explain the coordinate system a little bit (see header for more info)
FILE *fo = fopen( "ExampleInternalsTelemetryOutput.txt", "a" );
if( fo != NULL )
{
// Delta time is variable, as we send out the info once per frame
fprintf( fo, "DT=%.4f ET=%.4f\n", info.mDeltaTime, info.mElapsedTime );
fprintf( fo, "Lap=%d StartET=%.3f\n", info.mLapNumber, info.mLapStartET );
fprintf( fo, "Vehicle=%s\n", info.mVehicleName );
fprintf( fo, "Track=%s\n", info.mTrackName );
fprintf( fo, "Pos=(%.3f,%.3f,%.3f)\n", info.mPos.x, info.mPos.y, info.mPos.z );
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
fprintf( fo, "LocalVel=(%.2f,%.2f,%.2f)\n", info.mLocalVel.x, info.mLocalVel.y, info.mLocalVel.z );
fprintf( fo, "LocalAccel=(%.1f,%.1f,%.1f)\n", info.mLocalAccel.x, info.mLocalAccel.y, info.mLocalAccel.z );
// Orientation matrix is left-handed
fprintf( fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[0].x, info.mOri[0].y, info.mOri[0].z );
fprintf( fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[1].x, info.mOri[1].y, info.mOri[1].z );
fprintf( fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[2].x, info.mOri[2].y, info.mOri[2].z );
fprintf( fo, "LocalRot=(%.3f,%.3f,%.3f)\n", info.mLocalRot.x, info.mLocalRot.y, info.mLocalRot.z );
fprintf( fo, "LocalRotAccel=(%.2f,%.2f,%.2f)\n", info.mLocalRotAccel.x, info.mLocalRotAccel.y, info.mLocalRotAccel.z );
// Vehicle status
fprintf( fo, "Gear=%d RPM=%.1f RevLimit=%.1f\n", info.mGear, info.mEngineRPM, info.mEngineMaxRPM );
fprintf( fo, "Water=%.1f Oil=%.1f\n", info.mEngineWaterTemp, info.mEngineOilTemp );
fprintf( fo, "ClutchRPM=%.1f\n", info.mClutchRPM );
// Driver input
fprintf( fo, "UnfilteredThrottle=%.1f%%\n", 100.0 * info.mUnfilteredThrottle );
fprintf( fo, "UnfilteredBrake=%.1f%%\n", 100.0 * info.mUnfilteredBrake );
fprintf( fo, "UnfilteredSteering=%.1f%%\n", 100.0 * info.mUnfilteredSteering );
fprintf( fo, "UnfilteredClutch=%.1f%%\n", 100.0 * info.mUnfilteredClutch );
// Filtered input
fprintf( fo, "FilteredThrottle=%.1f%%\n", 100.0 * info.mFilteredThrottle );
fprintf( fo, "FilteredBrake=%.1f%%\n", 100.0 * info.mFilteredBrake );
fprintf( fo, "FilteredSteering=%.1f%%\n", 100.0 * info.mFilteredSteering );
fprintf( fo, "FilteredClutch=%.1f%%\n", 100.0 * info.mFilteredClutch );
// Misc
fprintf( fo, "SteeringShaftTorque=%.1f\n", info.mSteeringShaftTorque );
fprintf( fo, "Front3rdDeflection=%.3f Rear3rdDeflection=%.3f\n", info.mFront3rdDeflection, info.mRear3rdDeflection );
// Aerodynamics
fprintf( fo, "FrontWingHeight=%.3f FrontRideHeight=%.3f RearRideHeight=%.3f\n", info.mFrontWingHeight, info.mFrontRideHeight, info.mRearRideHeight );
fprintf( fo, "Drag=%.1f FrontDownforce=%.1f RearDownforce=%.1f\n", info.mDrag, info.mFrontDownforce, info.mRearDownforce );
// Other
fprintf( fo, "Fuel=%.1f ScheduledStops=%d Overheating=%d Detached=%d\n", info.mFuel, info.mScheduledStops, info.mOverheating, info.mDetached );
fprintf( fo, "Dents=(%d,%d,%d,%d,%d,%d,%d,%d)\n", info.mDentSeverity[0], info.mDentSeverity[1], info.mDentSeverity[2], info.mDentSeverity[3],
info.mDentSeverity[4], info.mDentSeverity[5], info.mDentSeverity[6], info.mDentSeverity[7] );
fprintf( fo, "LastImpactET=%.1f Mag=%.1f, Pos=(%.1f,%.1f,%.1f)\n", info.mLastImpactET, info.mLastImpactMagnitude,
info.mLastImpactPos.x, info.mLastImpactPos.y, info.mLastImpactPos.z );
// Wheels
for( long i = 0; i < 4; ++i )
{
const TelemWheelV01 &wheel = info.mWheel[i];
fprintf( fo, "Wheel=%s\n", (i==0)?"FrontLeft":(i==1)?"FrontRight":(i==2)?"RearLeft":"RearRight" );
fprintf( fo, " SuspensionDeflection=%.3f RideHeight=%.3f\n", wheel.mSuspensionDeflection, wheel.mRideHeight );
fprintf( fo, " SuspForce=%.1f BrakeTemp=%.1f BrakePressure=%.3f\n", wheel.mSuspForce, wheel.mBrakeTemp, wheel.mBrakePressure );
fprintf( fo, " ForwardRotation=%.1f Camber=%.3f\n", -wheel.mRotation, wheel.mCamber );
fprintf( fo, " LateralPatchVel=%.2f LongitudinalPatchVel=%.2f\n", wheel.mLateralPatchVel, wheel.mLongitudinalPatchVel );
fprintf( fo, " LateralGroundVel=%.2f LongitudinalGroundVel=%.2f\n", wheel.mLateralGroundVel, wheel.mLongitudinalGroundVel );
fprintf( fo, " LateralForce=%.1f LongitudinalForce=%.1f\n", wheel.mLateralForce, wheel.mLongitudinalForce );
fprintf( fo, " TireLoad=%.1f GripFract=%.3f TirePressure=%.1f\n", wheel.mTireLoad, wheel.mGripFract, wheel.mPressure );
fprintf( fo, " TireTemp(l/c/r)=%.1f/%.1f/%.1f\n", wheel.mTemperature[0], wheel.mTemperature[1], wheel.mTemperature[2] );
fprintf( fo, " Wear=%.3f TerrainName=%s SurfaceType=%d\n", wheel.mWear, wheel.mTerrainName, wheel.mSurfaceType );
fprintf( fo, " Flat=%d Detached=%d\n", wheel.mFlat, wheel.mDetached );
}
// Compute some auxiliary info based on the above
TelemVect3 forwardVector = { -info.mOri[0].z, -info.mOri[1].z, -info.mOri[2].z };
TelemVect3 leftVector = { info.mOri[0].x, info.mOri[1].x, info.mOri[2].x };
// These are normalized vectors, and remember that our world Y coordinate is up. So you can
// determine the current pitch and roll (w.r.t. the world x-z plane) as follows:
const double pitch = atan2( forwardVector.y, sqrt( ( forwardVector.x * forwardVector.x ) + ( forwardVector.z * forwardVector.z ) ) );
const double roll = atan2( leftVector.y, sqrt( ( leftVector.x * leftVector.x ) + ( leftVector.z * leftVector.z ) ) );
const double radsToDeg = 57.296;
fprintf( fo, "Pitch = %.1f deg, Roll = %.1f deg\n", pitch * radsToDeg, roll * radsToDeg );
const double metersPerSec = sqrt( ( info.mLocalVel.x * info.mLocalVel.x ) +
( info.mLocalVel.y * info.mLocalVel.y ) +
( info.mLocalVel.z * info.mLocalVel.z ) );
fprintf( fo, "Speed = %.1f KPH, %.1f MPH\n\n", metersPerSec * 3.6, metersPerSec * 2.237 );
// Close file
fclose( fo );
}
}
void ExampleInternalsPlugin::UpdateGraphics( const GraphicsInfoV01 &info )
{
// Use the incoming data, for now I'll just write some of it to a file to a) make sure it
// is working, and b) explain the coordinate system a little bit (see header for more info)
FILE *fo = fopen( "ExampleInternalsGraphicsOutput.txt", "a" );
if( fo != NULL )
{
// Print stuff
fprintf( fo, "CamPos=(%.1f,%.1f,%.1f)\n", info.mCamPos.x, info.mCamPos.y, info.mCamPos.z );
fprintf( fo, "CamOri[0]=(%.1f,%.1f,%.1f)\n", info.mCamOri[0].x, info.mCamOri[0].y, info.mCamOri[0].z );
fprintf( fo, "CamOri[1]=(%.1f,%.1f,%.1f)\n", info.mCamOri[1].x, info.mCamOri[1].y, info.mCamOri[1].z );
fprintf( fo, "CamOri[2]=(%.1f,%.1f,%.1f)\n", info.mCamOri[2].x, info.mCamOri[2].y, info.mCamOri[2].z );
fprintf( fo, "HWND=%d\n", info.mHWND );
fprintf( fo, "Ambient Color=(%.1f,%.1f,%.1f)\n\n", info.mAmbientRed, info.mAmbientGreen, info.mAmbientBlue );
// Close file
fclose( fo );
}
}
bool ExampleInternalsPlugin::CheckHWControl( const char * const controlName, double &fRetVal )
{
// only if enabled, of course
if( !mEnabled )
return( false );
// Note that incoming value is the game's computation, in case you're interested.
// Sorry, no control allowed over actual vehicle inputs ... would be too easy to cheat!
// However, you can still look at the values.
// Note: since the game calls this function every frame for every available control, you might consider
// doing a binary search if you are checking more than 7 or 8 strings, just to keep the speed up.
if( _stricmp( controlName, "LookLeft" ) == 0 )
{
const double headSwitcheroo = fmod( mET, 2.0 );
if( headSwitcheroo < 0.5 )
fRetVal = 1.0;
else
fRetVal = 0.0;
return( true );
}
else if( _stricmp( controlName, "LookRight" ) == 0 )
{
const double headSwitcheroo = fmod( mET, 2.0 );
if( ( headSwitcheroo > 1.0 ) && ( headSwitcheroo < 1.5 ) )
fRetVal = 1.0;
else
fRetVal = 0.0;
return( true );
}
return( false );
}
bool ExampleInternalsPlugin::ForceFeedback( double &forceValue )
{
// Note that incoming value is the game's computation, in case you're interested.
#if 0 // enable to log it out (note that this is a very very slow implementation)
FILE *fo = fopen( "FFB.txt", "a" );
if( fo != NULL )
{
fprintf( fo, "\nFFB=%.4f", forceValue );
fclose( fo );
}
#endif
// CHANGE COMMENTS TO ENABLE FORCE EXAMPLE
return( false );
// I think the bounds are -11500 to 11500 ...
// forceValue = 11500.0 * sinf( mET );
// return( true );
}
void ExampleInternalsPlugin::UpdateScoring( const ScoringInfoV01 &info )
{
// Note: function is called twice per second now (instead of once per second in previous versions)
FILE *fo = fopen( "ExampleInternalsScoringOutput.txt", "a" );
if( fo != NULL )
{
// Print general scoring info
fprintf( fo, "TrackName=%s\n", info.mTrackName );
fprintf( fo, "Session=%d NumVehicles=%d CurET=%.3f\n", info.mSession, info.mNumVehicles, info.mCurrentET );
fprintf( fo, "EndET=%.3f MaxLaps=%d LapDist=%.1f\n", info.mEndET, info.mMaxLaps, info.mLapDist );
// Note that only one plugin can use the stream (by enabling scoring updates) ... sorry if any clashes result
fprintf( fo, "START STREAM\n" );
const char *ptr = info.mResultsStream;
while( *ptr != NULL )
fputc( *ptr++, fo );
fprintf( fo, "END STREAM\n" );
// New version 2 stuff
fprintf( fo, "GamePhase=%d YellowFlagState=%d SectorFlags=(%d,%d,%d)\n", info.mGamePhase, info.mYellowFlagState,
info.mSectorFlag[0], info.mSectorFlag[1], info.mSectorFlag[2] );
fprintf( fo, "InRealtime=%d StartLight=%d NumRedLights=%d\n", info.mInRealtime, info.mStartLight, info.mNumRedLights );
fprintf( fo, "PlayerName=%s PlrFileName=%s\n", info.mPlayerName, info.mPlrFileName );
fprintf( fo, "DarkCloud=%.2f Raining=%.2f AmbientTemp=%.1f TrackTemp=%.1f\n", info.mDarkCloud, info.mRaining, info.mAmbientTemp, info.mTrackTemp );
fprintf( fo, "Wind=(%.1f,%.1f,%.1f) MinPathWetness=%.2f MaxPathWetness=%.2f\n", info.mWind.x, info.mWind.y, info.mWind.z, info.mMinPathWetness, info.mMaxPathWetness );
// Print vehicle info
for( long i = 0; i < info.mNumVehicles; ++i )
{
VehicleScoringInfoV01 &vinfo = info.mVehicle[ i ];
fprintf( fo, "Driver %d: %s\n", i, vinfo.mDriverName );
fprintf( fo, " ID=%d Vehicle=%s\n", vinfo.mID, vinfo.mVehicleName );
fprintf( fo, " Laps=%d Sector=%d FinishStatus=%d\n", vinfo.mTotalLaps, vinfo.mSector, vinfo.mFinishStatus );
fprintf( fo, " LapDist=%.1f PathLat=%.2f RelevantTrackEdge=%.2f\n", vinfo.mLapDist, vinfo.mPathLateral, vinfo.mTrackEdge );
fprintf( fo, " Best=(%.3f, %.3f, %.3f)\n", vinfo.mBestSector1, vinfo.mBestSector2, vinfo.mBestLapTime );
fprintf( fo, " Last=(%.3f, %.3f, %.3f)\n", vinfo.mLastSector1, vinfo.mLastSector2, vinfo.mLastLapTime );
fprintf( fo, " Current Sector 1 = %.3f, Current Sector 2 = %.3f\n", vinfo.mCurSector1, vinfo.mCurSector2 );
fprintf( fo, " Pitstops=%d, Penalties=%d\n", vinfo.mNumPitstops, vinfo.mNumPenalties );
// New version 2 stuff
fprintf( fo, " IsPlayer=%d Control=%d InPits=%d LapStartET=%.3f\n", vinfo.mIsPlayer, vinfo.mControl, vinfo.mInPits, vinfo.mLapStartET );
fprintf( fo, " Place=%d VehicleClass=%s\n", vinfo.mPlace, vinfo.mVehicleClass );
fprintf( fo, " TimeBehindNext=%.3f LapsBehindNext=%d\n", vinfo.mTimeBehindNext, vinfo.mLapsBehindNext );
fprintf( fo, " TimeBehindLeader=%.3f LapsBehindLeader=%d\n", vinfo.mTimeBehindLeader, vinfo.mLapsBehindLeader );
fprintf( fo, " Pos=(%.3f,%.3f,%.3f)\n", vinfo.mPos.x, vinfo.mPos.y, vinfo.mPos.z );
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
fprintf( fo, " LocalVel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalVel.x, vinfo.mLocalVel.y, vinfo.mLocalVel.z );
fprintf( fo, " LocalAccel=(%.1f,%.1f,%.1f)\n", vinfo.mLocalAccel.x, vinfo.mLocalAccel.y, vinfo.mLocalAccel.z );
// Orientation matrix is left-handed
fprintf( fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[0].x, vinfo.mOri[0].y, vinfo.mOri[0].z );
fprintf( fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[1].x, vinfo.mOri[1].y, vinfo.mOri[1].z );
fprintf( fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[2].x, vinfo.mOri[2].y, vinfo.mOri[2].z );
fprintf( fo, " LocalRot=(%.3f,%.3f,%.3f)\n", vinfo.mLocalRot.x, vinfo.mLocalRot.y, vinfo.mLocalRot.z );
fprintf( fo, " LocalRotAccel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalRotAccel.x, vinfo.mLocalRotAccel.y, vinfo.mLocalRotAccel.z );
}
// Delimit sections
fprintf( fo, "\n" );
// Close file
fclose( fo );
}
}
bool ExampleInternalsPlugin::RequestCommentary( CommentaryRequestInfoV01 &info )
{
// COMMENT OUT TO ENABLE EXAMPLE
return( false );
// only if enabled, of course
if( !mEnabled )
return( false );
// Note: function is called twice per second
// Say green flag event for no particular reason every 20 seconds ...
const double timeMod20 = fmod( mET, 20.0 );
if( timeMod20 > 19.0 )
{
strcpy( info.mName, "GreenFlag" );
info.mInput1 = 0.0;
info.mInput2 = 0.0;
info.mInput3 = 0.0;
info.mSkipChecks = true;
return( true );
}
return( false );
}

238
Source/RFServer.cpp Normal file
View file

@ -0,0 +1,238 @@
#include "RFServer.hpp" // corresponding header file
#include <math.h> // for atan2, sqrt
#include <stdio.h> // for sample output
#include <sstream>
// plugin information
extern "C" __declspec(dllexport)
const char *__cdecl GetPluginName() { return ("rF Server Plugin"); }
extern "C" __declspec(dllexport)
PluginObjectType __cdecl GetPluginType() { return (PO_INTERNALS); }
extern "C" __declspec(dllexport) int __cdecl GetPluginVersion() { return (7); } // InternalsPluginV07 functionality
extern "C" __declspec(dllexport)
PluginObject *__cdecl CreatePluginObject() { return ((PluginObject *)new RFServerPlugin); }
extern "C" __declspec(dllexport) void __cdecl DestroyPluginObject(PluginObject *obj) { delete ((RFServerPlugin *)obj); }
// RFServerPlugin class
RFServerPlugin::RFServerPlugin()
{
socket = new Socket(6262);
}
RFServerPlugin::~RFServerPlugin()
{
delete socket;
}
void RFServerPlugin::Startup(long version)
{
}
void RFServerPlugin::Shutdown()
{
}
void RFServerPlugin::StartSession()
{
}
void RFServerPlugin::EndSession()
{
}
void RFServerPlugin::EnterRealtime()
{
}
void RFServerPlugin::ExitRealtime()
{
}
void RFServerPlugin::UpdateTelemetry(const TelemInfoV01 &info)
{
// Use the incoming data, for now I'll just write some of it to a file to a) make sure it
// is working, and b) explain the coordinate system a little bit (see header for more info)
FILE *fo = fopen("ExampleInternalsTelemetryOutput.txt", "a");
if (fo != NULL)
{
// Delta time is variable, as we send out the info once per frame
fprintf(fo, "DT=%.4f ET=%.4f\n", info.mDeltaTime, info.mElapsedTime);
fprintf(fo, "Lap=%d StartET=%.3f\n", info.mLapNumber, info.mLapStartET);
fprintf(fo, "Vehicle=%s\n", info.mVehicleName);
fprintf(fo, "Track=%s\n", info.mTrackName);
fprintf(fo, "Pos=(%.3f,%.3f,%.3f)\n", info.mPos.x, info.mPos.y, info.mPos.z);
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
fprintf(fo, "LocalVel=(%.2f,%.2f,%.2f)\n", info.mLocalVel.x, info.mLocalVel.y, info.mLocalVel.z);
fprintf(fo, "LocalAccel=(%.1f,%.1f,%.1f)\n", info.mLocalAccel.x, info.mLocalAccel.y, info.mLocalAccel.z);
// Orientation matrix is left-handed
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[0].x, info.mOri[0].y, info.mOri[0].z);
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[1].x, info.mOri[1].y, info.mOri[1].z);
fprintf(fo, "[%6.3f,%6.3f,%6.3f]\n", info.mOri[2].x, info.mOri[2].y, info.mOri[2].z);
fprintf(fo, "LocalRot=(%.3f,%.3f,%.3f)\n", info.mLocalRot.x, info.mLocalRot.y, info.mLocalRot.z);
fprintf(fo, "LocalRotAccel=(%.2f,%.2f,%.2f)\n", info.mLocalRotAccel.x, info.mLocalRotAccel.y, info.mLocalRotAccel.z);
// Vehicle status
fprintf(fo, "Gear=%d RPM=%.1f RevLimit=%.1f\n", info.mGear, info.mEngineRPM, info.mEngineMaxRPM);
fprintf(fo, "Water=%.1f Oil=%.1f\n", info.mEngineWaterTemp, info.mEngineOilTemp);
fprintf(fo, "ClutchRPM=%.1f\n", info.mClutchRPM);
// Driver input
fprintf(fo, "UnfilteredThrottle=%.1f%%\n", 100.0 * info.mUnfilteredThrottle);
fprintf(fo, "UnfilteredBrake=%.1f%%\n", 100.0 * info.mUnfilteredBrake);
fprintf(fo, "UnfilteredSteering=%.1f%%\n", 100.0 * info.mUnfilteredSteering);
fprintf(fo, "UnfilteredClutch=%.1f%%\n", 100.0 * info.mUnfilteredClutch);
// Filtered input
fprintf(fo, "FilteredThrottle=%.1f%%\n", 100.0 * info.mFilteredThrottle);
fprintf(fo, "FilteredBrake=%.1f%%\n", 100.0 * info.mFilteredBrake);
fprintf(fo, "FilteredSteering=%.1f%%\n", 100.0 * info.mFilteredSteering);
fprintf(fo, "FilteredClutch=%.1f%%\n", 100.0 * info.mFilteredClutch);
// Misc
fprintf(fo, "SteeringShaftTorque=%.1f\n", info.mSteeringShaftTorque);
fprintf(fo, "Front3rdDeflection=%.3f Rear3rdDeflection=%.3f\n", info.mFront3rdDeflection, info.mRear3rdDeflection);
// Aerodynamics
fprintf(fo, "FrontWingHeight=%.3f FrontRideHeight=%.3f RearRideHeight=%.3f\n", info.mFrontWingHeight, info.mFrontRideHeight, info.mRearRideHeight);
fprintf(fo, "Drag=%.1f FrontDownforce=%.1f RearDownforce=%.1f\n", info.mDrag, info.mFrontDownforce, info.mRearDownforce);
// Other
fprintf(fo, "Fuel=%.1f ScheduledStops=%d Overheating=%d Detached=%d\n", info.mFuel, info.mScheduledStops, info.mOverheating, info.mDetached);
fprintf(fo, "Dents=(%d,%d,%d,%d,%d,%d,%d,%d)\n", info.mDentSeverity[0], info.mDentSeverity[1], info.mDentSeverity[2], info.mDentSeverity[3],
info.mDentSeverity[4], info.mDentSeverity[5], info.mDentSeverity[6], info.mDentSeverity[7]);
fprintf(fo, "LastImpactET=%.1f Mag=%.1f, Pos=(%.1f,%.1f,%.1f)\n", info.mLastImpactET, info.mLastImpactMagnitude,
info.mLastImpactPos.x, info.mLastImpactPos.y, info.mLastImpactPos.z);
// Wheels
for (long i = 0; i < 4; ++i)
{
const TelemWheelV01 &wheel = info.mWheel[i];
fprintf(fo, "Wheel=%s\n", (i == 0) ? "FrontLeft" : (i == 1) ? "FrontRight"
: (i == 2) ? "RearLeft"
: "RearRight");
fprintf(fo, " SuspensionDeflection=%.3f RideHeight=%.3f\n", wheel.mSuspensionDeflection, wheel.mRideHeight);
fprintf(fo, " SuspForce=%.1f BrakeTemp=%.1f BrakePressure=%.3f\n", wheel.mSuspForce, wheel.mBrakeTemp, wheel.mBrakePressure);
fprintf(fo, " ForwardRotation=%.1f Camber=%.3f\n", -wheel.mRotation, wheel.mCamber);
fprintf(fo, " LateralPatchVel=%.2f LongitudinalPatchVel=%.2f\n", wheel.mLateralPatchVel, wheel.mLongitudinalPatchVel);
fprintf(fo, " LateralGroundVel=%.2f LongitudinalGroundVel=%.2f\n", wheel.mLateralGroundVel, wheel.mLongitudinalGroundVel);
fprintf(fo, " LateralForce=%.1f LongitudinalForce=%.1f\n", wheel.mLateralForce, wheel.mLongitudinalForce);
fprintf(fo, " TireLoad=%.1f GripFract=%.3f TirePressure=%.1f\n", wheel.mTireLoad, wheel.mGripFract, wheel.mPressure);
fprintf(fo, " TireTemp(l/c/r)=%.1f/%.1f/%.1f\n", wheel.mTemperature[0], wheel.mTemperature[1], wheel.mTemperature[2]);
fprintf(fo, " Wear=%.3f TerrainName=%s SurfaceType=%d\n", wheel.mWear, wheel.mTerrainName, wheel.mSurfaceType);
fprintf(fo, " Flat=%d Detached=%d\n", wheel.mFlat, wheel.mDetached);
}
// Compute some auxiliary info based on the above
TelemVect3 forwardVector = {-info.mOri[0].z, -info.mOri[1].z, -info.mOri[2].z};
TelemVect3 leftVector = {info.mOri[0].x, info.mOri[1].x, info.mOri[2].x};
// These are normalized vectors, and remember that our world Y coordinate is up. So you can
// determine the current pitch and roll (w.r.t. the world x-z plane) as follows:
const double pitch = atan2(forwardVector.y, sqrt((forwardVector.x * forwardVector.x) + (forwardVector.z * forwardVector.z)));
const double roll = atan2(leftVector.y, sqrt((leftVector.x * leftVector.x) + (leftVector.z * leftVector.z)));
const double radsToDeg = 57.296;
fprintf(fo, "Pitch = %.1f deg, Roll = %.1f deg\n", pitch * radsToDeg, roll * radsToDeg);
const double metersPerSec = sqrt((info.mLocalVel.x * info.mLocalVel.x) +
(info.mLocalVel.y * info.mLocalVel.y) +
(info.mLocalVel.z * info.mLocalVel.z));
fprintf(fo, "Speed = %.1f KPH, %.1f MPH\n\n", metersPerSec * 3.6, metersPerSec * 2.237);
// Close file
fclose(fo);
}
}
std::string format_float(double d, int precision)
{
std::stringstream sstream;
sstream << d;
sstream.precision(precision);
return sstream.str();
}
void RFServerPlugin::UpdateScoring(const ScoringInfoV01 &info)
{
std::string msg = "[";
msg += info.mMaxLaps + ";";
msg += format_float(info.mLapDist, 1) + ";";
msg +=
// Note: function is called twice per second now (instead of once per second in previous versions)
FILE *fo = fopen("ExampleInternalsScoringOutput.txt", "a");
if (fo != NULL)
{
// Print general scoring info
fprintf(fo, "TrackName=%s\n", info.mTrackName);
fprintf(fo, "Session=%d NumVehicles=%d CurET=%.3f\n", info.mSession, info.mNumVehicles, info.mCurrentET);
fprintf(fo, "EndET=%.3f MaxLaps=%d LapDist=%.1f\n", info.mEndET, info.mMaxLaps, info.mLapDist);
// Note that only one plugin can use the stream (by enabling scoring updates) ... sorry if any clashes result
fprintf(fo, "START STREAM\n");
const char *ptr = info.mResultsStream;
while (*ptr != NULL)
fputc(*ptr++, fo);
fprintf(fo, "END STREAM\n");
// New version 2 stuff
fprintf(fo, "GamePhase=%d YellowFlagState=%d SectorFlags=(%d,%d,%d)\n", info.mGamePhase, info.mYellowFlagState,
info.mSectorFlag[0], info.mSectorFlag[1], info.mSectorFlag[2]);
fprintf(fo, "InRealtime=%d StartLight=%d NumRedLights=%d\n", info.mInRealtime, info.mStartLight, info.mNumRedLights);
fprintf(fo, "PlayerName=%s PlrFileName=%s\n", info.mPlayerName, info.mPlrFileName);
fprintf(fo, "DarkCloud=%.2f Raining=%.2f AmbientTemp=%.1f TrackTemp=%.1f\n", info.mDarkCloud, info.mRaining, info.mAmbientTemp, info.mTrackTemp);
fprintf(fo, "Wind=(%.1f,%.1f,%.1f) MinPathWetness=%.2f MaxPathWetness=%.2f\n", info.mWind.x, info.mWind.y, info.mWind.z, info.mMinPathWetness, info.mMaxPathWetness);
// Print vehicle info
for (long i = 0; i < info.mNumVehicles; ++i)
{
VehicleScoringInfoV01 &vinfo = info.mVehicle[i];
fprintf(fo, "Driver %d: %s\n", i, vinfo.mDriverName);
fprintf(fo, " ID=%d Vehicle=%s\n", vinfo.mID, vinfo.mVehicleName);
fprintf(fo, " Laps=%d Sector=%d FinishStatus=%d\n", vinfo.mTotalLaps, vinfo.mSector, vinfo.mFinishStatus);
fprintf(fo, " LapDist=%.1f PathLat=%.2f RelevantTrackEdge=%.2f\n", vinfo.mLapDist, vinfo.mPathLateral, vinfo.mTrackEdge);
fprintf(fo, " Best=(%.3f, %.3f, %.3f)\n", vinfo.mBestSector1, vinfo.mBestSector2, vinfo.mBestLapTime);
fprintf(fo, " Last=(%.3f, %.3f, %.3f)\n", vinfo.mLastSector1, vinfo.mLastSector2, vinfo.mLastLapTime);
fprintf(fo, " Current Sector 1 = %.3f, Current Sector 2 = %.3f\n", vinfo.mCurSector1, vinfo.mCurSector2);
fprintf(fo, " Pitstops=%d, Penalties=%d\n", vinfo.mNumPitstops, vinfo.mNumPenalties);
// New version 2 stuff
fprintf(fo, " IsPlayer=%d Control=%d InPits=%d LapStartET=%.3f\n", vinfo.mIsPlayer, vinfo.mControl, vinfo.mInPits, vinfo.mLapStartET);
fprintf(fo, " Place=%d VehicleClass=%s\n", vinfo.mPlace, vinfo.mVehicleClass);
fprintf(fo, " TimeBehindNext=%.3f LapsBehindNext=%d\n", vinfo.mTimeBehindNext, vinfo.mLapsBehindNext);
fprintf(fo, " TimeBehindLeader=%.3f LapsBehindLeader=%d\n", vinfo.mTimeBehindLeader, vinfo.mLapsBehindLeader);
fprintf(fo, " Pos=(%.3f,%.3f,%.3f)\n", vinfo.mPos.x, vinfo.mPos.y, vinfo.mPos.z);
// Forward is roughly in the -z direction (although current pitch of car may cause some y-direction velocity)
fprintf(fo, " LocalVel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalVel.x, vinfo.mLocalVel.y, vinfo.mLocalVel.z);
fprintf(fo, " LocalAccel=(%.1f,%.1f,%.1f)\n", vinfo.mLocalAccel.x, vinfo.mLocalAccel.y, vinfo.mLocalAccel.z);
// Orientation matrix is left-handed
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[0].x, vinfo.mOri[0].y, vinfo.mOri[0].z);
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[1].x, vinfo.mOri[1].y, vinfo.mOri[1].z);
fprintf(fo, " [%6.3f,%6.3f,%6.3f]\n", vinfo.mOri[2].x, vinfo.mOri[2].y, vinfo.mOri[2].z);
fprintf(fo, " LocalRot=(%.3f,%.3f,%.3f)\n", vinfo.mLocalRot.x, vinfo.mLocalRot.y, vinfo.mLocalRot.z);
fprintf(fo, " LocalRotAccel=(%.2f,%.2f,%.2f)\n", vinfo.mLocalRotAccel.x, vinfo.mLocalRotAccel.y, vinfo.mLocalRotAccel.z);
}
// Delimit sections
fprintf(fo, "\n");
// Close file
fclose(fo);
}
}
bool RFServerPlugin::AccessPitMenu(PitMenuV01 &info)
{
return false;
}

26
VC11/InternalsPlugin.sln Normal file
View file

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InternalsPlugin", "InternalsPlugin.vcxproj", "{D0C09F9B-E1D6-4A04-B698-190F52BBA156}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|Win32.ActiveCfg = Debug|Win32
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|Win32.Build.0 = Debug|Win32
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|x64.ActiveCfg = Debug|x64
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Debug|x64.Build.0 = Debug|x64
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|Win32.ActiveCfg = Release|Win32
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|Win32.Build.0 = Release|Win32
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|x64.ActiveCfg = Release|x64
{D0C09F9B-E1D6-4A04-B698-190F52BBA156}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,282 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D0C09F9B-E1D6-4A04-B698-190F52BBA156}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/InternalsPlugin.tlb</TypeLibraryName>
<HeaderFileName />
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\InternalsPlugin.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
<ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
<ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(Platform)\$(Configuration)\InternalsPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ImportLibrary>$(Platform)\$(Configuration)\InternalsPlugin.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ProgramDatabaseFile>$(Platform)\$(Configuration)\InternalsPlugin.pdb</ProgramDatabaseFile>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/InternalsPlugin.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command />
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Release/InternalsPlugin.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\InternalsPlugin.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
<ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
<ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(Platform)\$(Configuration)\InternalsPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ImportLibrary>$(Platform)\$(Configuration)\InternalsPlugin.lib</ImportLibrary>
<ProgramDatabaseFile>$(Platform)\$(Configuration)\InternalsPlugin.pdb</ProgramDatabaseFile>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/InternalsPlugin.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/InternalsPlugin.tlb</TypeLibraryName>
<HeaderFileName />
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\InternalsPlugin.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
<ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
<ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(Platform)\$(Configuration)\InternalsPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(Platform)\$(Configuration)\InternalsPlugin.pdb</ProgramDatabaseFile>
<ImportLibrary>$(Platform)\$(Configuration)\InternalsPlugin.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/InternalsPlugin.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command />
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Debug/InternalsPlugin.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;INTERNALSPLUGIN_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\InternalsPlugin.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
<ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
<ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(Platform)\$(Configuration)\InternalsPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(Platform)\$(Configuration)\InternalsPlugin.pdb</ProgramDatabaseFile>
<ImportLibrary>$(Platform)\$(Configuration)\InternalsPlugin.lib</ImportLibrary>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/InternalsPlugin.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Source\Example.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Include\Example.hpp" />
<ClInclude Include="..\Include\InternalsPlugin.hpp" />
<ClInclude Include="..\Include\PluginObjects.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>