diff --git a/.changeset/every-actors-ring.md b/.changeset/every-actors-ring.md new file mode 100644 index 0000000..c5f472b --- /dev/null +++ b/.changeset/every-actors-ring.md @@ -0,0 +1,5 @@ +--- +"@irsdk-node/native": major +--- + +Updated SDK implementation to latest (v1.19). diff --git a/.changeset/vast-boxes-remain.md b/.changeset/vast-boxes-remain.md new file mode 100644 index 0000000..d9e16ef --- /dev/null +++ b/.changeset/vast-boxes-remain.md @@ -0,0 +1,12 @@ +--- +"@irsdk-node/types": major +--- + +Update types to match latest SDK implementation (v1.19). +- Improved inline tsdoc comments for better in-IDE documentation. +- Adds `UNLIMITED_LAPS_COUNT` and `UNLIMITED_TIME_VALUE` constants. +- Adds `StatusField` enum. +- Re-implements/exposes `VarTypes` enum for telemetry variable types, adds `VarType` utility type. +- Adds `VarTypeBytes`, `TrackSurface`, `TrackWetness`, `IncidentFlags`, `IncidentFlagMask`, `EngineWarnings`, `CameraState` enums. +- Added `GlobalFlags.DqScoringInvalid` option to `GlobalFlags`. +- Added `PitCommand.ChangeTireCompound` option to `PitCommand`. diff --git a/.gitignore b/.gitignore index 705ccb0..4e73ead 100644 --- a/.gitignore +++ b/.gitignore @@ -7,13 +7,11 @@ out # TS incremental build info *.tsbuildinfo -# Swap the comments on the following lines if you don't wish to use zero-installs -# Documentation here: https://yarnpkg.com/features/zero-installs -# !/.yarn/cache -/.pnp.* - # Dependencies node_modules # Coverage coverage + +# Visual studio stuff +.vs/ diff --git a/packages/irsdk-node-native/README.md b/packages/irsdk-node-native/README.md index 7cefe77..99ad06f 100644 --- a/packages/irsdk-node-native/README.md +++ b/packages/irsdk-node-native/README.md @@ -1,5 +1,7 @@ # @irsdk-node/native +_Currently using **iRacing SDK v1.19**. You can see the latest version of the SDK [on the forums](https://forums.iracing.com/discussion/62/iracing-sdk/p1)._ + This is the native bindings package for irsdk-node. This provides near 1:1 bindings to the C++ iRacing SDK, and is consumed as an optional dependency of [irsdk-node](https://github.com/bengsfort/irsdk-node/tree/main/packages/irsdk-node), which provides a handy little wrapper around the API to make it nicer to use and avoid boilerplating. While you can use this package directly, it is highly recommended to use the [irsdk-node](https://github.com/bengsfort/irsdk-node/tree/main/packages/irsdk-node) package instead. Types for the data exposed via this package can be used independently via [@irsdk-node/types](https://github.com/bengsfort/irsdk-node/tree/main/packages/irsdk-node-native) as well. diff --git a/packages/irsdk-node-native/lib/irsdk_client.cpp b/packages/irsdk-node-native/lib/irsdk_client.cpp index 97277e1..3be32a7 100644 --- a/packages/irsdk-node-native/lib/irsdk_client.cpp +++ b/packages/irsdk-node-native/lib/irsdk_client.cpp @@ -4,14 +4,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of iRacing.com Motorsport Simulations nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -44,13 +44,13 @@ irsdkClient& irsdkClient::instance() bool irsdkClient::waitForData(int timeoutMS) { // wait for start of session or new data - if(irsdk_waitForDataReady(timeoutMS, m_data) && irsdk_getHeader()) + if (irsdk_waitForDataReady(timeoutMS, m_data) && irsdk_getHeader()) { // if new connection, or data changed lenght then init - if(!m_data || m_nData != irsdk_getHeader()->bufLen) + if (!m_data || m_nData != irsdk_getHeader()->bufLen) { // allocate memory to hold incoming data from sim - if(m_data) delete [] m_data; + if (m_data) delete[] m_data; m_nData = irsdk_getHeader()->bufLen; m_data = new char[m_nData]; @@ -61,19 +61,19 @@ bool irsdkClient::waitForData(int timeoutMS) m_lastSessionCt = -1; // and try to fill in the data - if(irsdk_getNewData(m_data)) + if (irsdk_getNewData(m_data)) return true; } - else if(m_data) + else if (m_data) { // else we are allready initialized, and data is ready for processing return true; } } - else if(!isConnected()) + else if (!isConnected()) { // else session ended - if(m_data) + if (m_data) delete[] m_data; m_data = NULL; @@ -87,7 +87,7 @@ bool irsdkClient::waitForData(int timeoutMS) void irsdkClient::shutdown() { irsdk_shutdown(); - if(m_data) + if (m_data) delete[] m_data; m_data = NULL; @@ -100,9 +100,9 @@ bool irsdkClient::isConnected() return m_data != NULL && irsdk_isConnected(); } -int irsdkClient::getVarIdx(const char*name) +int irsdkClient::getVarIdx(const char* name) { - if(isConnected()) + if (isConnected()) { return irsdk_varNameToIndex(name); } @@ -112,10 +112,10 @@ int irsdkClient::getVarIdx(const char*name) int /*irsdk_VarType*/ irsdkClient::getVarType(int idx) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { return vh->type; } @@ -131,10 +131,10 @@ int /*irsdk_VarType*/ irsdkClient::getVarType(int idx) int irsdkClient::getVarCount(int idx) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { return vh->count; } @@ -150,36 +150,36 @@ int irsdkClient::getVarCount(int idx) bool irsdkClient::getVarBool(int idx, int entry) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { - if(entry >= 0 && entry < vh->count) + if (entry >= 0 && entry < vh->count) { - const char * data = m_data + vh->offset; - switch(vh->type) + const char* data = m_data + vh->offset; + switch (vh->type) { - // 1 byte + // 1 byte case irsdk_char: case irsdk_bool: return (((const char*)data)[entry]) != 0; break; - // 4 bytes + // 4 bytes case irsdk_int: case irsdk_bitField: return (((const int*)data)[entry]) != 0; break; - - // test float/double for greater than 1.0 so that - // we have a chance of this being usefull - // technically there is no right conversion... + + // test float/double for greater than 1.0 so that + // we have a chance of this being usefull + // technically there is no right conversion... case irsdk_float: return (((const float*)data)[entry]) >= 1.0f; break; - // 8 bytes + // 8 bytes case irsdk_double: return (((const double*)data)[entry]) >= 1.0; break; @@ -203,33 +203,33 @@ bool irsdkClient::getVarBool(int idx, int entry) int irsdkClient::getVarInt(int idx, int entry) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { - if(entry >= 0 && entry < vh->count) + if (entry >= 0 && entry < vh->count) { - const char * data = m_data + vh->offset; - switch(vh->type) + const char* data = m_data + vh->offset; + switch (vh->type) { - // 1 byte + // 1 byte case irsdk_char: case irsdk_bool: return (int)(((const char*)data)[entry]); break; - // 4 bytes + // 4 bytes case irsdk_int: case irsdk_bitField: return (int)(((const int*)data)[entry]); break; - + case irsdk_float: return (int)(((const float*)data)[entry]); break; - // 8 bytes + // 8 bytes case irsdk_double: return (int)(((const double*)data)[entry]); break; @@ -253,33 +253,33 @@ int irsdkClient::getVarInt(int idx, int entry) float irsdkClient::getVarFloat(int idx, int entry) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { - if(entry >= 0 && entry < vh->count) + if (entry >= 0 && entry < vh->count) { - const char * data = m_data + vh->offset; - switch(vh->type) + const char* data = m_data + vh->offset; + switch (vh->type) { - // 1 byte + // 1 byte case irsdk_char: case irsdk_bool: return (float)(((const char*)data)[entry]); break; - // 4 bytes + // 4 bytes case irsdk_int: case irsdk_bitField: return (float)(((const int*)data)[entry]); break; - + case irsdk_float: return (float)(((const float*)data)[entry]); break; - // 8 bytes + // 8 bytes case irsdk_double: return (float)(((const double*)data)[entry]); break; @@ -303,33 +303,33 @@ float irsdkClient::getVarFloat(int idx, int entry) double irsdkClient::getVarDouble(int idx, int entry) { - if(isConnected()) + if (isConnected()) { - const irsdk_varHeader *vh = irsdk_getVarHeaderEntry(idx); - if(vh) + const irsdk_varHeader* vh = irsdk_getVarHeaderEntry(idx); + if (vh) { - if(entry >= 0 && entry < vh->count) + if (entry >= 0 && entry < vh->count) { - const char * data = m_data + vh->offset; - switch(vh->type) + const char* data = m_data + vh->offset; + switch (vh->type) { - // 1 byte + // 1 byte case irsdk_char: case irsdk_bool: return (double)(((const char*)data)[entry]); break; - // 4 bytes + // 4 bytes case irsdk_int: case irsdk_bitField: return (double)(((const int*)data)[entry]); break; - + case irsdk_float: return (double)(((const float*)data)[entry]); break; - // 8 bytes + // 8 bytes case irsdk_double: return (double)(((const double*)data)[entry]); break; @@ -352,31 +352,31 @@ double irsdkClient::getVarDouble(int idx, int entry) } //path is in the form of "DriverInfo:Drivers:CarIdx:{%d}UserName:" -int irsdkClient::getSessionStrVal(const char *path, char *val, int valLen) +int irsdkClient::getSessionStrVal(const char* path, char* val, int valLen) { - if(isConnected() && path && val && valLen > 0) + if (isConnected() && path && val && valLen > 0) { // track changes in string - m_lastSessionCt = getSessionCt(); + m_lastSessionCt = getSessionCt(); - const char *tVal = NULL; + const char* tVal = NULL; int tValLen = 0; - if(parseYaml(irsdk_getSessionInfoStr(), path, &tVal, &tValLen)) + if (parseYaml(irsdk_getSessionInfoStr(), path, &tVal, &tValLen)) { // dont overflow out buffer int len = tValLen; - if(len > valLen) - len = valLen; + if (len > (valLen - 1)) // reserve space for null termination + len = (valLen - 1); // copy what we can, even if buffer too small memcpy(val, tVal, len); val[len] = '\0'; // origional string has no null termination... // if buffer was big enough, return success - if(valLen >= tValLen) + if ((valLen - 1) >= tValLen) return 1; else // return size of buffer needed - return -tValLen; + return -(tValLen + 1); } } @@ -384,12 +384,12 @@ int irsdkClient::getSessionStrVal(const char *path, char *val, int valLen) } // get the whole string -const char* irsdkClient::getSessionStr() -{ - if(isConnected()) +const char* irsdkClient::getSessionStr() +{ + if (isConnected()) { - m_lastSessionCt = getSessionCt(); - return irsdk_getSessionInfoStr(); + m_lastSessionCt = getSessionCt(); + return irsdk_getSessionInfoStr(); } return NULL; @@ -405,23 +405,23 @@ irsdkCVar::irsdkCVar() m_name[0] = '\0'; } -irsdkCVar::irsdkCVar(const char *name) +irsdkCVar::irsdkCVar(const char* name) { m_name[0] = '\0'; setVarName(name); } -void irsdkCVar::setVarName(const char *name) +void irsdkCVar::setVarName(const char* name) { - if(!name || 0 != strncmp(name, m_name, sizeof(m_name))) + if (!name || 0 != strncmp(name, m_name, sizeof(m_name))) { m_idx = -1; m_statusID = -1; - if(name) + if (name) { strncpy(m_name, name, max_string); - m_name[max_string-1] = '\0'; + m_name[max_string - 1] = '\0'; } else m_name[0] = '\0'; @@ -430,9 +430,9 @@ void irsdkCVar::setVarName(const char *name) bool irsdkCVar::checkIdx() { - if(irsdkClient::instance().isConnected()) + if (irsdkClient::instance().isConnected()) { - if(m_statusID != irsdkClient::instance().getStatusID()) + if (m_statusID != irsdkClient::instance().getStatusID()) { m_statusID = irsdkClient::instance().getStatusID(); m_idx = irsdkClient::instance().getVarIdx(m_name); @@ -446,14 +446,14 @@ bool irsdkCVar::checkIdx() int /*irsdk_VarType*/ irsdkCVar::getType() { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarType(m_idx); return 0; } int irsdkCVar::getCount() { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarCount(m_idx); return 0; } @@ -467,28 +467,28 @@ bool irsdkCVar::isValid() bool irsdkCVar::getBool(int entry) { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarBool(m_idx, entry); return false; } int irsdkCVar::getInt(int entry) { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarInt(m_idx, entry); return 0; } float irsdkCVar::getFloat(int entry) { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarFloat(m_idx, entry); return 0.0f; } double irsdkCVar::getDouble(int entry) { - if(checkIdx()) + if (checkIdx()) return irsdkClient::instance().getVarDouble(m_idx, entry); return 0.0; } diff --git a/packages/irsdk-node-native/lib/irsdk_client.h b/packages/irsdk-node-native/lib/irsdk_client.h index 2969e29..bcfba37 100644 --- a/packages/irsdk-node-native/lib/irsdk_client.h +++ b/packages/irsdk-node-native/lib/irsdk_client.h @@ -4,14 +4,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of iRacing.com Motorsport Simulations nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -43,30 +43,30 @@ class irsdkClient bool isConnected(); int getStatusID() { return m_statusID; } - int getVarIdx(const char*name); + int getVarIdx(const char* name); // what is the base type of the data // returns irsdk_VarType as int so we don't depend on irsdk_defines.h int getVarType(int idx); - int getVarType(const char *name) { return getVarType(getVarIdx(name)); } + int getVarType(const char* name) { return getVarType(getVarIdx(name)); } // how many elements in array, or 1 if not an array int getVarCount(int idx); - int getVarCount(const char *name) { return getVarCount(getVarIdx(name)); } + int getVarCount(const char* name) { return getVarCount(getVarIdx(name)); } // idx is the variables index, entry is the array offset, or 0 if not an array element // will convert data to requested type bool getVarBool(int idx, int entry = 0); - bool getVarBool(const char *name, int entry = 0) { return getVarBool(getVarIdx(name), entry); } + bool getVarBool(const char* name, int entry = 0) { return getVarBool(getVarIdx(name), entry); } int getVarInt(int idx, int entry = 0); - int getVarInt(const char *name, int entry = 0) { return getVarInt(getVarIdx(name), entry); } - + int getVarInt(const char* name, int entry = 0) { return getVarInt(getVarIdx(name), entry); } + float getVarFloat(int idx, int entry = 0); - float getVarFloat(const char *name, int entry = 0) { return getVarFloat(getVarIdx(name), entry); } + float getVarFloat(const char* name, int entry = 0) { return getVarFloat(getVarIdx(name), entry); } double getVarDouble(int idx, int entry = 0); - double getVarDouble(const char *name, int entry = 0) { return getVarDouble(getVarIdx(name), entry); } + double getVarDouble(const char* name, int entry = 0) { return getVarDouble(getVarIdx(name), entry); } //--- @@ -74,14 +74,14 @@ class irsdkClient int getSessionCt() { return irsdk_getSessionInfoStrUpdate(); } // has string changed since we last read any values from it - bool wasSessionStrUpdated() { return m_lastSessionCt != getSessionCt(); } + bool wasSessionStrUpdated() { return m_lastSessionCt != getSessionCt(); } // pars string for individual value, 1 success, 0 failure, -n minimum buffer size //****Note, this is a linear parser, so it is slow! - int getSessionStrVal(const char *path, char *val, int valLen); + int getSessionStrVal(const char* path, char* val, int valLen); // get the whole string - const char *getSessionStr(); + const char* getSessionStr(); protected: @@ -96,13 +96,13 @@ class irsdkClient void shutdown(); - char *m_data; + char* m_data; int m_nData; int m_statusID; int m_lastSessionCt; - static irsdkClient *m_instance; + static irsdkClient* m_instance; }; @@ -112,9 +112,9 @@ class irsdkCVar { public: irsdkCVar(); - irsdkCVar(const char *name); + irsdkCVar(const char* name); - void setVarName(const char *name); + void setVarName(const char* name); // returns irsdk_VarType as int so we don't depend on irsdk_defines.h int getType(); diff --git a/packages/irsdk-node-native/lib/irsdk_defines.h b/packages/irsdk-node-native/lib/irsdk_defines.h index 55f0d2c..27b142d 100644 --- a/packages/irsdk-node-native/lib/irsdk_defines.h +++ b/packages/irsdk-node-native/lib/irsdk_defines.h @@ -84,13 +84,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include static const _TCHAR IRSDK_DATAVALIDEVENTNAME[] = _T("Local\\IRSDKDataValidEvent"); -static const _TCHAR IRSDK_MEMMAPFILENAME[] = _T("Local\\IRSDKMemMapFileName"); -static const _TCHAR IRSDK_BROADCASTMSGNAME[] = _T("IRSDK_BROADCASTMSG"); +static const _TCHAR IRSDK_MEMMAPFILENAME[] = _T("Local\\IRSDKMemMapFileName"); +static const _TCHAR IRSDK_BROADCASTMSGNAME[] = _T("IRSDK_BROADCASTMSG"); static const int IRSDK_MAX_BUFS = 4; static const int IRSDK_MAX_STRING = 32; // descriptions can be longer than max_string! -static const int IRSDK_MAX_DESC = 64; +static const int IRSDK_MAX_DESC = 64; // define markers for unlimited session lap and time static const int IRSDK_UNLIMITED_LAPS = 32767; @@ -134,60 +134,16 @@ static const int irsdk_VarTypeBytes[irsdk_ETCount] = 8 // irsdk_double }; -// bit fields -enum irsdk_EngineWarnings -{ - irsdk_waterTempWarning = 0x01, - irsdk_fuelPressureWarning = 0x02, - irsdk_oilPressureWarning = 0x04, - irsdk_engineStalled = 0x08, - irsdk_pitSpeedLimiter = 0x10, - irsdk_revLimiterActive = 0x20, - irsdk_oilTempWarning = 0x40, -}; - -// global flags -enum irsdk_Flags -{ - // global flags - irsdk_checkered = 0x00000001, - irsdk_white = 0x00000002, - irsdk_green = 0x00000004, - irsdk_yellow = 0x00000008, - irsdk_red = 0x00000010, - irsdk_blue = 0x00000020, - irsdk_debris = 0x00000040, - irsdk_crossed = 0x00000080, - irsdk_yellowWaving = 0x00000100, - irsdk_oneLapToGreen = 0x00000200, - irsdk_greenHeld = 0x00000400, - irsdk_tenToGo = 0x00000800, - irsdk_fiveToGo = 0x00001000, - irsdk_randomWaving = 0x00002000, - irsdk_caution = 0x00004000, - irsdk_cautionWaving = 0x00008000, - - // drivers black flags - irsdk_black = 0x00010000, - irsdk_disqualify = 0x00020000, - irsdk_servicible = 0x00040000, // car is allowed service (not a flag) - irsdk_furled = 0x00080000, - irsdk_repair = 0x00100000, - - // start lights - irsdk_startHidden = 0x10000000, - irsdk_startReady = 0x20000000, - irsdk_startSet = 0x40000000, - irsdk_startGo = 0x80000000, -}; - +//--- // status enum irsdk_TrkLoc { irsdk_NotInWorld = -1, - irsdk_OffTrack, + irsdk_OffTrack = 0, irsdk_InPitStall, + // This indicates the lead in to pit road, as well as the pit road itself (where speed limits are enforced) + // if you just want to know that your on the pit road surface look at the live value 'OnPitRoad' irsdk_AproachingPits, irsdk_OnTrack }; @@ -240,7 +196,7 @@ enum irsdk_SessionState enum irsdk_CarLeftRight { - irsdk_LROff, + irsdk_LROff = 0, irsdk_LRClear, // no cars around us. irsdk_LRCarLeft, // there is a car to our left. irsdk_LRCarRight, // there is a car to our right. @@ -249,6 +205,124 @@ enum irsdk_CarLeftRight irsdk_LR2CarsRight // there are two cars to our right. }; +enum irsdk_PitSvStatus +{ + // status + irsdk_PitSvNone = 0, + irsdk_PitSvInProgress, + irsdk_PitSvComplete, + + // errors + irsdk_PitSvTooFarLeft = 100, + irsdk_PitSvTooFarRight, + irsdk_PitSvTooFarForward, + irsdk_PitSvTooFarBack, + irsdk_PitSvBadAngle, + irsdk_PitSvCantFixThat, +}; + +enum irsdk_PaceMode +{ + irsdk_PaceModeSingleFileStart = 0, + irsdk_PaceModeDoubleFileStart, + irsdk_PaceModeSingleFileRestart, + irsdk_PaceModeDoubleFileRestart, + irsdk_PaceModeNotPacing, +}; + +enum irsdk_TrackWetness +{ + irsdk_TrackWetness_UNKNOWN = 0, + irsdk_TrackWetness_Dry, + irsdk_TrackWetness_MostlyDry, + irsdk_TrackWetness_VeryLightlyWet, + irsdk_TrackWetness_LightlyWet, + irsdk_TrackWetness_ModeratelyWet, + irsdk_TrackWetness_VeryWet, + irsdk_TrackWetness_ExtremelyWet +}; + +enum irsdk_IncidentFlags +{ + // first byte is incident report flag + // only one of these will be used + irsdk_Incident_RepNoReport = 0x0000, // no penalty + irsdk_Incident_RepOutOfControl = 0x0001, // "Loss of Control (2x)" + irsdk_Incident_RepOffTrack = 0x0002, // "Off Track (1x)" + irsdk_Incident_RepOffTrackOngoing = 0x0003, // not currently sent + irsdk_Incident_RepContactWithWorld = 0x0004, // "Contact (0x)" + irsdk_Incident_RepCollisionWithWorld = 0x0005, // "Contact (2x)" + irsdk_Incident_RepCollisionWithWorldOngoing = 0x0006, // not currently sent + irsdk_Incident_RepContactWithCar = 0x0007, // "Car Contact (0x)" + irsdk_Incident_RepCollisionWithCar = 0x0008, // "Car Contact (4x)" + + // second byte is incident penalty + // only one of these will be used + irsdk_Incident_PenNoReport = 0x0000, // no penalty + irsdk_Incident_PenZeroX = 0x0100, // 0x + irsdk_Incident_PenOneX = 0x0200, // 1x + irsdk_Incident_PenTwoX = 0x0300, // 2x + irsdk_Incident_PenFourX = 0x0400, // 4x + + // not enums, used to seperate the above incident report field + // from the incident penalty field + IRSDK_INCIDENT_REP_MASK = 0x000000FF, + IRSDK_INCIDENT_PEN_MASK = 0x0000FF00, +}; + +//--- + +// bit fields +enum irsdk_EngineWarnings +{ + irsdk_waterTempWarning = 0x0001, + irsdk_fuelPressureWarning = 0x0002, + irsdk_oilPressureWarning = 0x0004, + irsdk_engineStalled = 0x0008, + irsdk_pitSpeedLimiter = 0x0010, + irsdk_revLimiterActive = 0x0020, + irsdk_oilTempWarning = 0x0040, + + irsdk_mandRepNeeded = 0x0080, // car needs mandatory repairs + irsdk_optRepNeeded = 0x0100, // car needs optional repairs +}; + +// global flags +enum irsdk_Flags +{ + // global flags + irsdk_checkered = 0x00000001, + irsdk_white = 0x00000002, + irsdk_green = 0x00000004, + irsdk_yellow = 0x00000008, + irsdk_red = 0x00000010, + irsdk_blue = 0x00000020, + irsdk_debris = 0x00000040, + irsdk_crossed = 0x00000080, + irsdk_yellowWaving = 0x00000100, + irsdk_oneLapToGreen = 0x00000200, + irsdk_greenHeld = 0x00000400, + irsdk_tenToGo = 0x00000800, + irsdk_fiveToGo = 0x00001000, + irsdk_randomWaving = 0x00002000, + irsdk_caution = 0x00004000, + irsdk_cautionWaving = 0x00008000, + + // drivers black flags + irsdk_black = 0x00010000, + irsdk_disqualify = 0x00020000, + irsdk_servicible = 0x00040000, // car is allowed service (not a flag) + irsdk_furled = 0x00080000, + irsdk_repair = 0x00100000, + irsdk_dqScoringInvalid = 0x00200000, // car is disqualified and scoring is disabled + + // start lights + irsdk_startHidden = 0x10000000, + irsdk_startReady = 0x20000000, + irsdk_startSet = 0x40000000, + irsdk_startGo = 0x80000000, +}; + enum irsdk_CameraState { irsdk_IsSessionScreen = 0x0001, // the camera tool can only be activated if viewing the session screen (out of car) @@ -276,36 +350,11 @@ enum irsdk_PitSvFlags irsdk_FastRepair = 0x0040 }; -enum irsdk_PitSvStatus -{ - // status - irsdk_PitSvNone = 0, - irsdk_PitSvInProgress, - irsdk_PitSvComplete, - - // errors - irsdk_PitSvTooFarLeft = 100, - irsdk_PitSvTooFarRight, - irsdk_PitSvTooFarForward, - irsdk_PitSvTooFarBack, - irsdk_PitSvBadAngle, - irsdk_PitSvCantFixThat, -}; - -enum irsdk_PaceMode -{ - irsdk_PaceModeSingleFileStart = 0, - irsdk_PaceModeDoubleFileStart, - irsdk_PaceModeSingleFileRestart, - irsdk_PaceModeDoubleFileRestart, - irsdk_PaceModeNotPacing, -}; - enum irsdk_PaceFlags { - irsdk_PaceFlagsEndOfLine = 0x01, - irsdk_PaceFlagsFreePass = 0x02, - irsdk_PaceFlagsWavedAround = 0x04, + irsdk_PaceFlagsEndOfLine = 0x0001, + irsdk_PaceFlagsFreePass = 0x0002, + irsdk_PaceFlagsWavedAround = 0x0004, }; //---- @@ -361,6 +410,10 @@ struct irsdk_header int numBuf; // <= IRSDK_MAX_BUFS (3 for now) int bufLen; // length in bytes for one line + //****ToDo, add these in + //int curBufTickCount; // stashed copy of the current tickCount, can read this to see if new data is available + //byte curBuf; // index of the most recently written buffer (0 to IRSDK_MAX_BUFS-1) + //byte pad1[3]; // 16 byte align int pad1[2]; // (16 byte align) irsdk_varBuf varBuf[IRSDK_MAX_BUFS]; // buffers of data being written to }; @@ -400,13 +453,13 @@ int irsdk_varNameToOffset(const char *name); // Remote controll the sim by sending these windows messages // camera and replay commands only work when you are out of your car, // pit commands only work when in your car -enum irsdk_BroadcastMsg +enum irsdk_BroadcastMsg { irsdk_BroadcastCamSwitchPos = 0, // car position, group, camera irsdk_BroadcastCamSwitchNum, // driver #, group, camera irsdk_BroadcastCamSetState, // irsdk_CameraState, unused, unused irsdk_BroadcastReplaySetPlaySpeed, // speed, slowMotion, unused - irskd_BroadcastReplaySetPlayPosition, // irsdk_RpyPosMode, Frame Number (high, low) + irsdk_BroadcastReplaySetPlayPosition, // irsdk_RpyPosMode, Frame Number (high, low) irsdk_BroadcastReplaySearch, // irsdk_RpySrchMode, unused, unused irsdk_BroadcastReplaySetState, // irsdk_RpyStateMode, unused, unused irsdk_BroadcastReloadTextures, // irsdk_ReloadTexturesMode, carIdx, unused @@ -441,6 +494,7 @@ enum irsdk_PitCommandMode // this only works when the driver is in the car irsdk_PitCommand_ClearWS, // Uncheck Clean the winshield checkbox irsdk_PitCommand_ClearFR, // Uncheck request a fast repair irsdk_PitCommand_ClearFuel, // Uncheck add fuel + irsdk_PitCommand_TC, // Change tire compound }; enum irsdk_TelemCommandMode // You can call this any time, but telemtry only records when driver is in there car diff --git a/packages/irsdk-node-native/lib/irsdk_diskclient.cpp b/packages/irsdk-node-native/lib/irsdk_diskclient.cpp new file mode 100644 index 0000000..bb8fc96 --- /dev/null +++ b/packages/irsdk-node-native/lib/irsdk_diskclient.cpp @@ -0,0 +1,997 @@ +/* +Copyright (c) 2013, iRacing.com Motorsport Simulations, LLC. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include +#include "irsdk_defines.h" +#include "yaml_parser.h" +#include "irsdk_diskclient.h" + +#pragma warning(disable:4996) + +irsdkDiskClient::irsdkDiskClient() + : m_ibtFile(NULL) + , m_sessionInfoString(NULL) + , m_varHeaders(NULL) + , m_varBuf(NULL) + , m_ibtFileSize(0) +{ + memset(&m_header, 0, sizeof(m_header)); + memset(&m_diskSubHeader, 0, sizeof(m_diskSubHeader)); +} + +irsdkDiskClient::irsdkDiskClient(const char *path) + : m_ibtFile(NULL) + , m_sessionInfoString(NULL) + , m_varHeaders(NULL) + , m_varBuf(NULL) + , m_ibtFileSize(0) +{ + memset(&m_header, 0, sizeof(m_header)); + memset(&m_diskSubHeader, 0, sizeof(m_diskSubHeader)); + + openFile(path); +} + +bool irsdkDiskClient::openFile(const char *path) +{ + closeFile(); + + m_ibtFile = fopen(path, "rb"); + if(m_ibtFile) + { + // work out file size on disk + fseek(m_ibtFile, 0L, SEEK_END); + m_ibtFileSize = ftell(m_ibtFile); + fseek(m_ibtFile, 0L, SEEK_SET); + + if(fread(&m_header, 1, sizeof(m_header), m_ibtFile) == sizeof(m_header)) + { + if(fread(&m_diskSubHeader, 1, sizeof(m_diskSubHeader), m_ibtFile) == sizeof(m_diskSubHeader)) + { + m_sessionInfoString = new char[m_header.sessionInfoLen]; + if(m_sessionInfoString) + { + fseek(m_ibtFile, m_header.sessionInfoOffset, SEEK_SET); + if(fread(m_sessionInfoString, 1, m_header.sessionInfoLen, m_ibtFile) == (size_t)m_header.sessionInfoLen) + { + m_sessionInfoString[m_header.sessionInfoLen-1] = '\0'; + + m_varHeaders = new irsdk_varHeader[m_header.numVars]; + if(m_varHeaders) + { + fseek(m_ibtFile, m_header.varHeaderOffset, SEEK_SET); + size_t len = m_header.numVars * sizeof(irsdk_varHeader); + if(fread(m_varHeaders, 1, len, m_ibtFile) == len) + { + m_varBuf = new char[m_header.bufLen]; + if(m_varBuf) + { + fseek(m_ibtFile, m_header.varBuf[0].bufOffset, SEEK_SET); + + return true; + + //delete [] m_varBuf; + //m_varBuf = NULL; + } + } + + delete [] m_varHeaders; + m_varHeaders = NULL; + } + } + + delete [] m_sessionInfoString; + m_sessionInfoString = NULL; + } + } + } + fclose(m_ibtFile); + m_ibtFile = NULL; + } + + return false; +} + +void irsdkDiskClient::closeFile() +{ + if(m_varBuf) + delete [] m_varBuf; + m_varBuf = NULL; + + if(m_varHeaders) + delete [] m_varHeaders; + m_varHeaders = NULL; + + if(m_sessionInfoString) + delete [] m_sessionInfoString; + m_sessionInfoString = NULL; + + if(m_ibtFile) + fclose(m_ibtFile); + m_ibtFile = NULL; + + m_ibtFileSize = 0; +} + +bool irsdkDiskClient::getNextData() +{ + if(m_ibtFile) + return fread(m_varBuf, 1, m_header.bufLen, m_ibtFile) == (size_t)m_header.bufLen; + + return false; +} + +// return how many variables this .ibt file has in the header +int irsdkDiskClient::getNumVars() +{ + if(m_ibtFile) + return m_header.numVars; + + return -1; +} + +int irsdkDiskClient::getVarIdx(const char *name) +{ + if(m_ibtFile && name) + { + for(int idx=0; idx= 0 && idx < m_header.numVars) + { + return (irsdk_VarType)m_varHeaders[idx].type; + } + + //invalid variable index + assert(false); + } + + return irsdk_char; +} + +// get info on the var +const char* irsdkDiskClient::getVarName(int idx) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].name; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +const char* irsdkDiskClient::getVarDesc(int idx) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].desc; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +const char* irsdkDiskClient::getVarUnit(int idx) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].unit; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +int irsdkDiskClient::getVarCount(int idx) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].count; + } + + //invalid variable index + assert(false); + } + + return 0; +} + +bool irsdkDiskClient::getVarBool(int idx, int entry) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + const char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + return (((const char*)data)[entry]) != 0; + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + return (((const int*)data)[entry]) != 0; + break; + + // test float/double for greater than 1.0 so that + // we have a chance of this being usefull + // technically there is no right conversion... + case irsdk_float: + return (((const float*)data)[entry]) >= 1.0f; + break; + + // 8 bytes + case irsdk_double: + return (((const double*)data)[entry]) >= 1.0; + break; + } + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return false; +} + +int irsdkDiskClient::getVarInt(int idx, int entry) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + const char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + return (int)(((const char*)data)[entry]); + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + return (int)(((const int*)data)[entry]); + break; + + case irsdk_float: + return (int)(((const float*)data)[entry]); + break; + + // 8 bytes + case irsdk_double: + return (int)(((const double*)data)[entry]); + break; + } + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return 0; +} + +float irsdkDiskClient::getVarFloat(int idx, int entry) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + const char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + return (float)(((const char*)data)[entry]); + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + return (float)(((const int*)data)[entry]); + break; + + case irsdk_float: + return (float)(((const float*)data)[entry]); + break; + + // 8 bytes + case irsdk_double: + return (float)(((const double*)data)[entry]); + break; + } + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return 0.0f; +} + +double irsdkDiskClient::getVarDouble(int idx, int entry) +{ + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + const char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + return (double)(((const char*)data)[entry]); + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + return (double)(((const int*)data)[entry]); + break; + + case irsdk_float: + return (double)(((const float*)data)[entry]); + break; + + // 8 bytes + case irsdk_double: + return (double)(((const double*)data)[entry]); + break; + } + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return 0.0; +} + +//path is in the form of "DriverInfo:Drivers:CarIdx:{%d}UserName:" +int irsdkDiskClient::getSessionStrVal(const char *path, char *val, int valLen) +{ + if(m_ibtFile && path && val && valLen > 0) + { + const char *tVal = NULL; + int tValLen = 0; + if(parseYaml(m_sessionInfoString, path, &tVal, &tValLen)) + { + // dont overflow out buffer + int len = tValLen; + if(len > valLen) + len = valLen; + + // copy what we can, even if buffer too small + memcpy(val, tVal, len); + val[len] = '\0'; // origional string has no null termination... + + // if buffer was big enough, return success + if(valLen >= tValLen) + return 1; + else // return size of buffer needed + return -tValLen; + } + } + + return 0; +} + +//----------------- + +irsdkDiskWriter::irsdkDiskWriter() +{ + initialize(); +} + +irsdkDiskWriter::irsdkDiskWriter(const char *path) +{ + initialize(); + + openFile(path); +} + +void irsdkDiskWriter::initialize() +{ + memset(&m_header, 0, sizeof(m_header)); + memset(&m_diskSubHeader, 0, sizeof(m_diskSubHeader)); + memset(&m_sessionInfoString, 0, sizeof(m_sessionInfoString)); + memset(&m_varHeaders, 0, sizeof(m_varHeaders)); + memset(m_varBuf, 0, sizeof(m_varBuf)); + + m_ibtFile = NULL; + m_diskSubHeaderOffset = 0; + m_isHeaderFinalized = false; + + // default initialization of header + m_header.ver = IRSDK_VER; + m_header.status = irsdk_stConnected; + m_header.tickRate = 60; + m_header.sessionInfoUpdate = 0; + m_header.numBuf = 1; + m_header.varBuf[0].tickCount = 0; + + // fake up yaml string, in case we don't add one later + sprintf(m_sessionInfoString, "---\n...\n"); +} + +bool irsdkDiskWriter::openFile(const char *path) +{ + assert(m_ibtFile == NULL); + + m_ibtFile = fopen(path, "wb"); + if(m_ibtFile) + { + //****FixMe, is this needed? + m_diskSubHeaderOffset = 0; + m_isHeaderFinalized = false; + + return true; + } + + return false; +} + +void irsdkDiskWriter::closeFile() +{ + if(m_ibtFile) + { + fseek(m_ibtFile, m_diskSubHeaderOffset, SEEK_SET); + fwrite(&m_diskSubHeader, 1, sizeof(m_diskSubHeader), m_ibtFile); + fclose(m_ibtFile); + } + m_ibtFile = NULL; +} + +int getSizeOfVarType(const irsdk_VarType type) +{ + switch(type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: return 1; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + case irsdk_float: return 4; + + // 8 bytes + case irsdk_double: return 8; + + default: + assert(false); + return 1; + } +} + +int irsdkDiskWriter::addNewVariable(const char *name, const char *desc, const char *unit, const irsdk_VarType type, int count) +{ + assert(m_ibtFile); + assert(!m_isHeaderFinalized); + assert(count >= 1); + + if(m_ibtFile && !m_isHeaderFinalized) + { + // room for the variable? + if(m_header.numVars < MAX_VAR_COUNT && + (m_header.bufLen + count) < MAX_VAR_BUF_SIZE) + { + int idx = m_header.numVars; + m_header.numVars++; + + m_varHeaders[idx].type = type; // irsdk_VarType + m_varHeaders[idx].offset = m_header.bufLen; // offset fron start of buffer row + m_varHeaders[idx].count = count; // number of entrys (array) + m_header.bufLen += count * getSizeOfVarType(type); + + m_varHeaders[idx].countAsTime = false; + + strncpy(m_varHeaders[idx].name, name, sizeof(char) * IRSDK_MAX_STRING); + strncpy(m_varHeaders[idx].desc, desc, sizeof(char) * IRSDK_MAX_DESC); + strncpy(m_varHeaders[idx].unit, unit, sizeof(char) * IRSDK_MAX_STRING); // something like "kg/m^2" + + return idx; + } + } + + return -1; // bogus index +} + +void irsdkDiskWriter::finalizeHeader() +{ + assert(m_ibtFile); + assert(!m_isHeaderFinalized); + + if(m_ibtFile && !m_isHeaderFinalized) + { + int offset = 0; + + // main header + offset += sizeof(m_header); + + // sub header is written out at end of session + m_diskSubHeaderOffset = offset; + offset += sizeof(m_diskSubHeader); + + // pointer to var definitions + m_header.varHeaderOffset = offset; + offset += m_header.numVars * sizeof(irsdk_varHeader); + + // pointer to session info string + m_header.sessionInfoLen = (int)strlen(m_sessionInfoString); + m_header.sessionInfoOffset = offset; + offset += m_header.sessionInfoLen; + + // pointer to start of buffered data + m_header.varBuf[0].bufOffset = offset; + + fwrite(&m_header, 1, sizeof(m_header), m_ibtFile); + fwrite(&m_diskSubHeader, 1, sizeof(m_diskSubHeader), m_ibtFile); + fwrite(&m_varHeaders, 1, m_header.numVars * sizeof(irsdk_varHeader), m_ibtFile); + fwrite(m_sessionInfoString, 1, m_header.sessionInfoLen, m_ibtFile); + + if(ftell(m_ibtFile) != m_header.varBuf[0].bufOffset) + printf("ERROR: m_ibtFile pointer mismach: %d != %d\n", ftell(m_ibtFile), m_header.varBuf[0].bufOffset); + + m_isHeaderFinalized = true; + } +} + +// write next line to file and clear buffers +void irsdkDiskWriter::writeLine() +{ + assert(m_ibtFile); + assert(m_isHeaderFinalized); + + if(m_ibtFile && m_isHeaderFinalized) + { + fwrite(m_varBuf, 1, m_header.bufLen, m_ibtFile); + m_diskSubHeader.sessionRecordCount++; + + // zero out data so we are ready for the next line + memset(m_varBuf, 0, sizeof(m_varBuf)); + } +} + +// return how many variables this .ibt file has in the header +int irsdkDiskWriter::getNumVars() +{ + assert(m_ibtFile); + + if(m_ibtFile) + return m_header.numVars; + + return -1; +} + +int irsdkDiskWriter::getVarIdx(const char *name) +{ + assert(m_ibtFile); + assert(name); + + if(m_ibtFile && name) + { + for(int idx=0; idx= 0 && idx < m_header.numVars) + { + return (irsdk_VarType)m_varHeaders[idx].type; + } + + //invalid variable index + assert(false); + } + + return irsdk_char; +} + +// get info on the var +const char* irsdkDiskWriter::getVarName(int idx) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].name; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +const char* irsdkDiskWriter::getVarDesc(int idx) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].desc; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +const char* irsdkDiskWriter::getVarUnit(int idx) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].unit; + } + + //invalid variable index + assert(false); + } + + return NULL; +} + +int irsdkDiskWriter::getVarCount(int idx) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + return m_varHeaders[idx].count; + } + + //invalid variable index + assert(false); + } + + return 0; +} + +//--- + +bool irsdkDiskWriter::setVar(bool val, int idx, int entry) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + ((char*)data)[entry] = val; + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + ((int*)data)[entry] = (int)val; + break; + + // technically there is no right conversion... + case irsdk_float: + ((float*)data)[entry] = (float)val; + break; + + // 8 bytes + case irsdk_double: + ((double*)data)[entry] = (double)val; + break; + } + + return true; + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return false; +} + +bool irsdkDiskWriter::setVar(int val, int idx, int entry) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + ((char*)data)[entry] = (bool)val; + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + ((int*)data)[entry] = (int)val; + break; + + case irsdk_float: + ((float*)data)[entry] = (float)val; + break; + + // 8 bytes + case irsdk_double: + ((double*)data)[entry] = (double)val; + break; + } + + return true; + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return false; +} + +bool irsdkDiskWriter::setVar(float val, int idx, int entry) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + ((char*)data)[entry] = (bool)val; + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + ((int*)data)[entry] = (int)val; + break; + + case irsdk_float: + ((float*)data)[entry] = (float)val; + break; + + // 8 bytes + case irsdk_double: + ((double*)data)[entry] = (double)val; + break; + } + + return true; + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return false; +} + +bool irsdkDiskWriter::setVar(double val, int idx, int entry) +{ + assert(m_ibtFile); + + if(m_ibtFile) + { + if(idx >= 0 && idx < m_header.numVars) + { + if(entry >= 0 && entry < m_varHeaders[idx].count) + { + char * data = m_varBuf + m_varHeaders[idx].offset; + switch(m_varHeaders[idx].type) + { + // 1 byte + case irsdk_char: + case irsdk_bool: + ((char*)data)[entry] = (bool)val; + break; + + // 4 bytes + case irsdk_int: + case irsdk_bitField: + ((int*)data)[entry] = (int)val; + break; + + case irsdk_float: + ((float*)data)[entry] = (float)val; + break; + + // 8 bytes + case irsdk_double: + ((double*)data)[entry] = (double)val; + break; + } + + return true; + } + else + { + // invalid offset + assert(false); + } + } + else + { + //invalid variable index + assert(false); + } + } + + return false; +} diff --git a/packages/irsdk-node-native/lib/irsdk_diskclient.h b/packages/irsdk-node-native/lib/irsdk_diskclient.h new file mode 100644 index 0000000..7d15e0d --- /dev/null +++ b/packages/irsdk-node-native/lib/irsdk_diskclient.h @@ -0,0 +1,205 @@ +/* +Copyright (c) 2013, iRacing.com Motorsport Simulations, LLC. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef IRSDKDISKCLIENT_H +#define IRSDKDISKCLIENT_H + +// A C++ wrapper around the irsdk calls that takes care of reading a .ibt file + +//****FixMe, rename to irsdkDiskReader +class irsdkDiskClient +{ +public: + + irsdkDiskClient(); + irsdkDiskClient(const char *path); + ~irsdkDiskClient() { closeFile(); } + + bool isFileOpen() { return m_ibtFile != NULL; } + bool openFile(const char *path); + void closeFile(); + + // read next line out of file + bool getNextData(); //****Note, should be called readLine(); + int getDataCount() { return m_diskSubHeader.sessionRecordCount; } + + // return how many variables this .ibt file has in the header + int getNumVars(); + + int getVarIdx(const char *name); + + // get info on the var + const char* getVarName(int idx); + const char* getVarDesc(int idx); + const char* getVarUnit(int idx); + + // what is the base type of the data + irsdk_VarType getVarType(int idx); + irsdk_VarType getVarType(const char *name) { return getVarType(getVarIdx(name)); } + + // how many elements in array, or 1 if not an array + int getVarCount(int idx); + int getVarCount(const char *name) { return getVarCount(getVarIdx(name)); } + + // idx is the variables index, entry is the array offset, or 0 if not an array element + // will convert data to requested type + bool getVarBool(int idx, int entry = 0); + bool getVarBool(const char *name, int entry = 0) { return getVarBool(getVarIdx(name), entry); } + + int getVarInt(int idx, int entry = 0); + int getVarInt(const char *name, int entry = 0) { return getVarInt(getVarIdx(name), entry); } + + float getVarFloat(int idx, int entry = 0); + float getVarFloat(const char *name, int entry = 0) { return getVarFloat(getVarIdx(name), entry); } + + double getVarDouble(int idx, int entry = 0); + double getVarDouble(const char *name, int entry = 0) { return getVarDouble(getVarIdx(name), entry); } + + // 1 success, 0 failure, -n minimum buffer size + int getSessionStrVal(const char *path, char *val, int valLen); + // get the whole string + const char *getSessionStr() { return m_sessionInfoString; } + + // we track session time and lap count in the disk sub header + time_t getSessionStartDate() { return m_diskSubHeader.sessionStartDate; } + double getSessionStartTime_s() { return m_diskSubHeader.sessionStartTime; } + double getSessionEndTime_s() { return m_diskSubHeader.sessionEndTime; } + int getSessionLapCount() { return m_diskSubHeader.sessionLapCount; } + + long getFileSize() { return m_ibtFileSize; } + +protected: + + irsdk_header m_header; + irsdk_diskSubHeader m_diskSubHeader; + + char *m_sessionInfoString; + irsdk_varHeader *m_varHeaders; + char *m_varBuf; + + FILE *m_ibtFile; + long m_ibtFileSize; +}; + +class irsdkDiskWriter +{ +public: + + irsdkDiskWriter(); + irsdkDiskWriter(const char *path); + ~irsdkDiskWriter() { closeFile(); } + + bool isFileOpen() { return m_ibtFile != NULL; } + bool openFile(const char *path); + void closeFile(); + + int addNewVariable(const char *name, const char *desc, const char *unit, const irsdk_VarType type, int count = 1); + bool isHeaderFinalized() { return m_isHeaderFinalized; } + void finalizeHeader(); + + // write next line to file and clear buffers + void writeLine(); + int getDataCount() { return m_diskSubHeader.sessionRecordCount; } + + // return how many variables this .ibt file has in the header + int getNumVars(); + + int getVarIdx(const char *name); + + // get info on the var + const char* getVarName(int idx); + const char* getVarDesc(int idx); + const char* getVarUnit(int idx); + + // what is the base type of the data + irsdk_VarType getVarType(int idx); + irsdk_VarType getVarType(const char *name) { return getVarType(getVarIdx(name)); } + + // how many elements in array, or 1 if not an array + int getVarCount(int idx); + int getVarCount(const char *name) { return getVarCount(getVarIdx(name)); } + + // idx is the variables index, entry is the array offset, or 0 if not an array element + // will convert data to requested type + bool setVar(bool val, int idx, int entry = 0); + bool setVar(bool val, const char *name, int entry = 0) { return setVar(val, getVarIdx(name), entry); } + + bool setVar(int val, int idx, int entry = 0); + bool setVar(int val, const char *name, int entry = 0) { return setVar(val, getVarIdx(name), entry); } + + bool setVar(float val, int idx, int entry = 0); + bool setVar(float val, const char *name, int entry = 0) { return setVar(val, getVarIdx(name), entry); } + + bool setVar(double val, int idx, int entry = 0); + bool setVar(double val, const char *name, int entry = 0) { return setVar(val, getVarIdx(name), entry); } + + // get the whole string + char* getSessionStr() { return m_sessionInfoString; } + void setSessionStr(const char* str) + { + strncpy_s(m_sessionInfoString, str, MAX_SESSIONSTR_LEN); + m_sessionInfoString[MAX_SESSIONSTR_LEN-1] = '\0'; + } + + // we track session time and lap count in the disk sub header + time_t getSessionStartDate() { return m_diskSubHeader.sessionStartDate; } + void setSessionStartDate(const time_t date) { m_diskSubHeader.sessionStartDate = date; } + + double getSessionStartTime_s() { return m_diskSubHeader.sessionStartTime; } + void setSessionStartTime_s(const double time) { m_diskSubHeader.sessionStartTime = time; } + + double getSessionEndTime_s() { return m_diskSubHeader.sessionEndTime; } + void setSessionEndTime_s(const double time) { m_diskSubHeader.sessionEndTime = time; } + + int getSessionLapCount() { return m_diskSubHeader.sessionLapCount; } + void setSessionLapCount(const int lap) { m_diskSubHeader.sessionLapCount = lap; } + + int getTickRate() { return m_header.tickRate; } + void setTickRate(int rate) { m_header.tickRate = rate; } + +protected: + + void initialize(); + + irsdk_header m_header; + irsdk_diskSubHeader m_diskSubHeader; + int m_diskSubHeaderOffset; + bool m_isHeaderFinalized; + + //****Note, for now static allocate our buffers + // could easily aquire these at creation time + const static int MAX_SESSIONSTR_LEN = 1048576; + const static int MAX_VAR_COUNT = 1000; + const static int MAX_VAR_BUF_SIZE = MAX_VAR_COUNT * 32; + + char m_sessionInfoString[MAX_SESSIONSTR_LEN]; + irsdk_varHeader m_varHeaders[MAX_VAR_COUNT]; + char m_varBuf[MAX_VAR_BUF_SIZE]; + + FILE *m_ibtFile; +}; +#endif // IRSDKDISKCLIENT_H diff --git a/packages/irsdk-node-native/lib/irsdk_node.cc b/packages/irsdk-node-native/lib/irsdk_node.cc index dd8c3db..638b83d 100644 --- a/packages/irsdk-node-native/lib/irsdk_node.cc +++ b/packages/irsdk-node-native/lib/irsdk_node.cc @@ -227,7 +227,7 @@ Napi::Value iRacingSdkNode::BroadcastMessage(const Napi::CallbackInfo &info) case irsdk_BroadcastPitCommand: // arg1 == irsdk_PitCommandMode case irsdk_BroadcastFFBCommand: // arg1 == irsdk_FFBCommandMode case irsdk_BroadcastReplaySearchSessionTime: - case irskd_BroadcastReplaySetPlayPosition: + case irsdk_BroadcastReplaySetPlayPosition: if (this->_loggingEnabled) printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %f)\n", msgType, arg1, (float)arg2.FloatValue()); irsdk_broadcastMsg(msgType, arg1, (float)arg2.FloatValue()); diff --git a/packages/irsdk-node-native/lib/irsdk_utils.cpp b/packages/irsdk-node-native/lib/irsdk_utils.cpp index f807651..2362a4b 100644 --- a/packages/irsdk-node-native/lib/irsdk_utils.cpp +++ b/packages/irsdk-node-native/lib/irsdk_utils.cpp @@ -4,14 +4,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of iRacing.com Motorsport Simulations nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -56,8 +56,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. static HANDLE hDataValidEvent = NULL; static HANDLE hMemMapFile = NULL; -static const char *pSharedMem = NULL; -static const irsdk_header *pHeader = NULL; +static const char* pSharedMem = NULL; +static const irsdk_header* pHeader = NULL; static int lastTickCount = INT_MAX; static bool isInitialized = false; @@ -69,30 +69,30 @@ static time_t lastValidTime = 0; bool irsdk_startup() { - if(!hMemMapFile) + if (!hMemMapFile) { - hMemMapFile = OpenFileMapping( FILE_MAP_READ, FALSE, IRSDK_MEMMAPFILENAME); + hMemMapFile = OpenFileMapping(FILE_MAP_READ, FALSE, IRSDK_MEMMAPFILENAME); lastTickCount = INT_MAX; } - if(hMemMapFile) + if (hMemMapFile) { - if(!pSharedMem) + if (!pSharedMem) { - pSharedMem = (const char *)MapViewOfFile(hMemMapFile, FILE_MAP_READ, 0, 0, 0); - pHeader = (irsdk_header *)pSharedMem; + pSharedMem = (const char*)MapViewOfFile(hMemMapFile, FILE_MAP_READ, 0, 0, 0); + pHeader = (irsdk_header*)pSharedMem; lastTickCount = INT_MAX; } - if(pSharedMem) + if (pSharedMem) { - if(!hDataValidEvent) + if (!hDataValidEvent) { hDataValidEvent = OpenEvent(SYNCHRONIZE, false, IRSDK_DATAVALIDEVENTNAME); lastTickCount = INT_MAX; } - if(hDataValidEvent) + if (hDataValidEvent) { isInitialized = true; return isInitialized; @@ -109,13 +109,13 @@ bool irsdk_startup() void irsdk_shutdown() { - if(hDataValidEvent) + if (hDataValidEvent) CloseHandle(hDataValidEvent); - if(pSharedMem) + if (pSharedMem) UnmapViewOfFile(pSharedMem); - if(hMemMapFile) + if (hMemMapFile) CloseHandle(hMemMapFile); hDataValidEvent = NULL; @@ -127,38 +127,38 @@ void irsdk_shutdown() lastTickCount = INT_MAX; } -bool irsdk_getNewData(char *data) +bool irsdk_getNewData(char* data) { - if(isInitialized || irsdk_startup()) + if (isInitialized || irsdk_startup()) { #ifdef _MSC_VER _ASSERTE(NULL != pHeader); #endif // if sim is not active, then no new data - if(!(pHeader->status & irsdk_stConnected)) + if (!(pHeader->status & irsdk_stConnected)) { lastTickCount = INT_MAX; return false; } int latest = 0; - for(int i=1; inumBuf; i++) - if(pHeader->varBuf[latest].tickCount < pHeader->varBuf[i].tickCount) - latest = i; + for (int i = 1; i < pHeader->numBuf; i++) + if (pHeader->varBuf[latest].tickCount < pHeader->varBuf[i].tickCount) + latest = i; // if newer than last recieved, than report new data - if(lastTickCount < pHeader->varBuf[latest].tickCount) + if (lastTickCount < pHeader->varBuf[latest].tickCount) { // if asked to retrieve the data - if(data) + if (data) { // try twice to get the data out - for(int count = 0; count < 2; count++) + for (int count = 0; count < 2; count++) { - int curTickCount = pHeader->varBuf[latest].tickCount; + int curTickCount = pHeader->varBuf[latest].tickCount; memcpy(data, pSharedMem + pHeader->varBuf[latest].bufOffset, pHeader->bufLen); - if(curTickCount == pHeader->varBuf[latest].tickCount) + if (curTickCount == pHeader->varBuf[latest].tickCount) { lastTickCount = curTickCount; lastValidTime = time(NULL); @@ -170,15 +170,15 @@ bool irsdk_getNewData(char *data) } else { - lastTickCount = pHeader->varBuf[latest].tickCount; + lastTickCount = pHeader->varBuf[latest].tickCount; lastValidTime = time(NULL); return true; } } // if older than last recieved, than reset, we probably disconnected - else if(lastTickCount > pHeader->varBuf[latest].tickCount) + else if (lastTickCount > pHeader->varBuf[latest].tickCount) { - lastTickCount = pHeader->varBuf[latest].tickCount; + lastTickCount = pHeader->varBuf[latest].tickCount; return false; } // else the same, and nothing changed this tick @@ -188,30 +188,30 @@ bool irsdk_getNewData(char *data) } -bool irsdk_waitForDataReady(int timeOut, char *data) +bool irsdk_waitForDataReady(int timeOut, char* data) { #ifdef _MSC_VER _ASSERTE(timeOut >= 0); #endif - if(isInitialized || irsdk_startup()) + if (isInitialized || irsdk_startup()) { // just to be sure, check before we sleep - if(irsdk_getNewData(data)) + if (irsdk_getNewData(data)) return true; // sleep till signaled WaitForSingleObject(hDataValidEvent, timeOut); // we woke up, so check for data - if(irsdk_getNewData(data)) + if (irsdk_getNewData(data)) return true; else return false; } // sleep if error - if(timeOut > 0) + if (timeOut > 0) Sleep(timeOut); return false; @@ -219,7 +219,7 @@ bool irsdk_waitForDataReady(int timeOut, char *data) bool irsdk_isConnected() { - if(isInitialized) + if (isInitialized) { int elapsed = (int)difftime(time(NULL), lastValidTime); return (pHeader->status & irsdk_stConnected) > 0 && elapsed < timeout; @@ -228,9 +228,9 @@ bool irsdk_isConnected() return false; } -const irsdk_header *irsdk_getHeader() +const irsdk_header* irsdk_getHeader() { - if(isInitialized) + if (isInitialized) { return pHeader; } @@ -241,9 +241,9 @@ const irsdk_header *irsdk_getHeader() // direct access to the data buffer // Warnign! This buffer is volitile so read it out fast! // Use the cached copy from irsdk_waitForDataReady() or irsdk_getNewData() instead -const char *irsdk_getData(int index) +const char* irsdk_getData(int index) { - if(isInitialized) + if (isInitialized) { return pSharedMem + pHeader->varBuf[index].bufOffset; } @@ -251,9 +251,9 @@ const char *irsdk_getData(int index) return NULL; } -const char *irsdk_getSessionInfoStr() +const char* irsdk_getSessionInfoStr() { - if(isInitialized) + if (isInitialized) { return pSharedMem + pHeader->sessionInfoOffset; } @@ -262,27 +262,27 @@ const char *irsdk_getSessionInfoStr() int irsdk_getSessionInfoStrUpdate() { - if(isInitialized) + if (isInitialized) { return pHeader->sessionInfoUpdate; } return -1; } -const irsdk_varHeader *irsdk_getVarHeaderPtr() +const irsdk_varHeader* irsdk_getVarHeaderPtr() { - if(isInitialized) + if (isInitialized) { return ((irsdk_varHeader*)(pSharedMem + pHeader->varHeaderOffset)); } return NULL; } -const irsdk_varHeader *irsdk_getVarHeaderEntry(int index) +const irsdk_varHeader* irsdk_getVarHeaderEntry(int index) { - if(isInitialized) + if (isInitialized) { - if(index >= 0 && index < pHeader->numVars) + if (index >= 0 && index < pHeader->numVars) { return &((irsdk_varHeader*)(pSharedMem + pHeader->varHeaderOffset))[index]; } @@ -291,16 +291,16 @@ const irsdk_varHeader *irsdk_getVarHeaderEntry(int index) } // Note: this is a linear search, so cache the results -int irsdk_varNameToIndex(const char *name) +int irsdk_varNameToIndex(const char* name) { - const irsdk_varHeader *pVar; + const irsdk_varHeader* pVar; - if(name) + if (name) { - for(int index=0; indexnumVars; index++) + for (int index = 0; index < pHeader->numVars; index++) { pVar = irsdk_getVarHeaderEntry(index); - if(pVar && 0 == strncmp(name, pVar->name, IRSDK_MAX_STRING)) + if (pVar && 0 == strncmp(name, pVar->name, IRSDK_MAX_STRING)) { return index; } @@ -310,16 +310,16 @@ int irsdk_varNameToIndex(const char *name) return -1; } -int irsdk_varNameToOffset(const char *name) +int irsdk_varNameToOffset(const char* name) { - const irsdk_varHeader *pVar; + const irsdk_varHeader* pVar; - if(name) + if (name) { - for(int index=0; indexnumVars; index++) + for (int index = 0; index < pHeader->numVars; index++) { pVar = irsdk_getVarHeaderEntry(index); - if(pVar && 0 == strncmp(name, pVar->name, IRSDK_MAX_STRING)) + if (pVar && 0 == strncmp(name, pVar->name, IRSDK_MAX_STRING)) { return pVar->offset; } @@ -331,14 +331,14 @@ int irsdk_varNameToOffset(const char *name) unsigned int irsdk_getBroadcastMsgID() { - static unsigned int msgId = RegisterWindowMessage(IRSDK_BROADCASTMSGNAME); + static unsigned int msgId = RegisterWindowMessage(IRSDK_BROADCASTMSGNAME); return msgId; } void irsdk_broadcastMsg(irsdk_BroadcastMsg msg, int var1, int var2, int var3) { - irsdk_broadcastMsg(msg, var1, static_castMAKELONG(var2, var3)); + irsdk_broadcastMsg(msg, var1, (int)MAKELONG(var2, var3)); } void irsdk_broadcastMsg(irsdk_BroadcastMsg msg, int var1, float var2) @@ -353,7 +353,7 @@ void irsdk_broadcastMsg(irsdk_BroadcastMsg msg, int var1, int var2) { static unsigned int msgId = irsdk_getBroadcastMsgID(); - if(msgId && msg >= 0 && msg < irsdk_BroadcastLast) + if (msgId && msg >= 0 && msg < irsdk_BroadcastLast) { SendNotifyMessage(HWND_BROADCAST, msgId, MAKELONG(msg, var1), var2); } @@ -363,14 +363,14 @@ int irsdk_padCarNum(int num, int zero) { int retVal = num; int numPlace = 1; - if(num > 99) + if (num > 99) numPlace = 3; - else if(num > 9) + else if (num > 9) numPlace = 2; - if(zero) + if (zero) { numPlace += zero; - retVal = num + 1000*numPlace; + retVal = num + 1000 * numPlace; } return retVal; diff --git a/packages/irsdk-node-native/lib/yaml_parser.cpp b/packages/irsdk-node-native/lib/yaml_parser.cpp index 5d66ba9..8affb31 100644 --- a/packages/irsdk-node-native/lib/yaml_parser.cpp +++ b/packages/irsdk-node-native/lib/yaml_parser.cpp @@ -4,14 +4,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of iRacing.com Motorsport Simulations nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of iRacing.com Motorsport Simulations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -37,9 +37,9 @@ enum yaml_state { }; // super simple YAML parser -bool parseYaml(const char *data, const char* path, const char **val, int *len) +bool parseYaml(const char* data, const char* path, const char** val, int* len) { - if(data && path && val && len) + if (data && path && val && len) { // make sure we set this to something *val = NULL; @@ -48,39 +48,39 @@ bool parseYaml(const char *data, const char* path, const char **val, int *len) int depth = 0; yaml_state state = space; - const char *keystr = NULL; + const char* keystr = NULL; int keylen = 0; - const char *valuestr = NULL; + const char* valuestr = NULL; int valuelen = 0; - const char *pathptr = path; + const char* pathptr = path; int pathdepth = 0; - while(*data) + while (*data) { - switch(*data) + switch (*data) { case ' ': - if(state == newline) + if (state == newline) state = space; - if(state == space) + if (state == space) depth++; - else if(state == key) + else if (state == key) keylen++; - else if(state == value) + else if (state == value) valuelen++; break; case '-': - if(state == newline) + if (state == newline) state = space; - if(state == space) + if (state == space) depth++; - else if(state == key) + else if (state == key) keylen++; - else if(state == value) + else if (state == value) valuelen++; - else if(state == keysep) + else if (state == keysep) { state = value; valuestr = data; @@ -88,50 +88,50 @@ bool parseYaml(const char *data, const char* path, const char **val, int *len) } break; case ':': - if(state == key) + if (state == key) { state = keysep; keylen++; } - else if(state == keysep) + else if (state == keysep) { state = value; valuestr = data; } - else if(state == value) + else if (state == value) valuelen++; break; case '\n': case '\r': - if(state != newline) + if (state != newline) { - if(depth < pathdepth) + if (depth < pathdepth) { return false; } - else if(keylen && 0 == strncmp(keystr, pathptr, keylen)) + else if (keylen && 0 == strncmp(keystr, pathptr, keylen)) { bool found = true; //do we need to test the value? - if(*(pathptr+keylen) == '{') + if (*(pathptr + keylen) == '{') { //search for closing brace - int pathvaluelen = keylen + 1; - while(*(pathptr+pathvaluelen) && *(pathptr+pathvaluelen) != '}') - pathvaluelen++; + int pathvaluelen = keylen + 1; + while (*(pathptr + pathvaluelen) && *(pathptr + pathvaluelen) != '}') + pathvaluelen++; - if(valuelen == pathvaluelen - (keylen+1) && 0 == strncmp(valuestr, (pathptr+keylen+1), valuelen)) + if (valuelen == pathvaluelen - (keylen + 1) && 0 == strncmp(valuestr, (pathptr + keylen + 1), valuelen)) pathptr += valuelen + 2; else found = false; } - if(found) + if (found) { pathptr += keylen; pathdepth = depth; - if(*pathptr == '\0') + if (*pathptr == '\0') { *val = valuestr; *len = valuelen; @@ -147,21 +147,21 @@ bool parseYaml(const char *data, const char* path, const char **val, int *len) state = newline; break; default: - if(state == space || state == newline) + if (state == space || state == newline) { state = key; keystr = data; keylen = 0; //redundant? } - else if(state == keysep) + else if (state == keysep) { state = value; valuestr = data; valuelen = 0; //redundant? } - if(state == key) + if (state == key) keylen++; - if(state == value) + if (state == value) valuelen++; break; } diff --git a/packages/irsdk-node-native/lib/yaml_parser.h b/packages/irsdk-node-native/lib/yaml_parser.h index 6abcf78..7e6192b 100644 --- a/packages/irsdk-node-native/lib/yaml_parser.h +++ b/packages/irsdk-node-native/lib/yaml_parser.h @@ -29,6 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define YAML_PARSER_H // super simple YAML parser -bool parseYaml(const char *data, const char* path, const char **val, int *len); +bool parseYaml(const char* data, const char* path, const char** val, int* len); #endif //YAML_PARSER_H diff --git a/packages/irsdk-node-types/README.md b/packages/irsdk-node-types/README.md index 527e5dd..4b9cfdc 100644 --- a/packages/irsdk-node-types/README.md +++ b/packages/irsdk-node-types/README.md @@ -1,5 +1,7 @@ # @irsdk-node/types +_Types implemented for **iRacing SDK v1.19**. You can see the latest version of the SDK [on the forums](https://forums.iracing.com/discussion/62/iracing-sdk/p1)._ + This package provides TypeScript type definitions and enums that match the data structures and API's of the iRacing SDK, as well as a generated list of telemetry variables available from the SDK. If you are using `irsdk-node`, you do not need to import this package directly as it gets re-exported via `irsdk-node`. diff --git a/packages/irsdk-node-types/src/defines.ts b/packages/irsdk-node-types/src/defines.ts new file mode 100644 index 0000000..d7fd9a9 --- /dev/null +++ b/packages/irsdk-node-types/src/defines.ts @@ -0,0 +1,637 @@ +// irsdk_defines.h mapping module. +// +// The schemas in this module should be defined in the same order as in the +// sdk header file. This makes it easier to update and maintain. +// +// TODO: Try to map each flag to their respective Telemetry variable. + +// --- Constants + +/** Value used to indicate unlimited laps in a session. */ +export const UNLIMITED_LAPS_COUNT = 32767; + +/** Value used to indicate unlimited time in a session. */ +export const UNLIMITED_TIME_VALUE = 604800; + +// --- Utility + +export enum StatusField { + Connected = 1, +} + +/** + * Telemetry Variable type map. + * Maps human-friendly names to the number ID for a telemetry variable. + * + * Represents irsdk_VarType + */ +export enum VarTypes { + Character = 0, + Boolean, + Integer, + BitField, + Float, + Double, + ETCount, +} + +interface VarTypesMap { + [VarTypes.Character]: string; + [VarTypes.Boolean]: boolean; + [VarTypes.Integer]: number; + [VarTypes.BitField]: number; + [VarTypes.Float]: number; + [VarTypes.Double]: number; + [VarTypes.ETCount]: never; +} + +/** + * Utility type for getting the Typescript type of a telemetry variable type. + */ +export type VarType = VarTypesMap[T]; + +/** + * The number of bytes making up each telemetry variable type (VarTypes). + * + * Represents irsdk_VarTypeBytes + */ +export const VarTypeBytes = { + [VarTypes.Character]: 1, + [VarTypes.Boolean]: 1, + + [VarTypes.Integer]: 4, + [VarTypes.BitField]: 4, + [VarTypes.Float]: 4, + + [VarTypes.Double]: 4, + [VarTypes.ETCount]: VarTypes.ETCount, +} as const; + +// --- Flags + +/** + * Maps the general location within the world a car/driver might be. + * + * Represents irsdk_TrkLoc + */ +export enum TrackLocation { + NotInWorld = -1, + OffTrack = 0, + InPitStall, + /** + * Indicates the lead in to pit road, as well as pit road itself (where limits + * are enforced). If you just want to know that your on the pit road surface, + * look at the 'OnPitRoad' telemetry variable. + */ + ApproachingPits, + OnTrack, +} + +/** + * Maps the track surfaces. + * + * Represents irsdk_TrkSurf + */ +export enum TrackSurface { + SurfaceNotInWorld = -1, + UndefinedMaterial = 0, + + Asphalt1Material, + Asphalt2Material, + Asphalt3Material, + Asphalt4Material, + Concrete1Material, + Concrete2Material, + RacingDirt1Material, + RacingDirt2Material, + Paint1Material, + Paint2Material, + Rumble1Material, + Rumble2Material, + Rumble3Material, + Rumble4Material, + + Grass1Material, + Grass2Material, + Grass3Material, + Grass4Material, + Dirt1Material, + Dirt2Material, + Dirt3Material, + Dirt4Material, + SandMaterial, + Gravel1Material, + Gravel2Material, + GrasscreteMaterial, + AstroturfMaterial, +} + +/** + * The state of the sim session. + * + * Represents irsdk_SessionState + */ +export enum SessionState { + Invalid = 0, + GetInCar, + Warmup, + ParadeLaps, + Racing, + Checkered, + CoolDown, +} + +/** + * Indicator for cars being around a driver. + * + * Represents irsdk_CarLeftRight + */ +export enum CarLeftRight { + Off, + Clear, + CarLeft, + CarRight, + /** Cars on both sides */ + CarLeftRight, + /** 2 cars to our left */ + Cars2Left, + /** 2 cars to our right */ + Cars2Right, +} + +/** + * Indicator of pit stop status. + * + * Represents irsdk_PitSvStatus + */ +export enum PitSvStatus { + // Status + None = 0, + /** There is a pit stop in progress. */ + InProgress, + /** The pit stop has ended. */ + Complete, + + // Errors + /** The driver is too far left of the pit box. */ + TooFarLeft = 100, + /** The driver is too far right of the pit box. */ + TooFarRight, + /** The driver is too far forward from the pit box. */ + TooFarForward, + /** The driver is too far back from the pit box. */ + TooFarBack, + /** The driver stopped at an invalid angle for the pit box. */ + BadAngle, + /** The car cannot be fixed. */ + CantFixThat, +} + +/** + * Indicates the mode being used when the pace car is out. + * + * Represents irsdk_PaceMode + */ +export enum PaceMode { + SingleFileStart = 0, + DoubleFileStart, + SingleFileRestart, + DoubleFileRestart, + NotPacing, +} + +/** + * Indicates track wetness. Used with the `TrackWetness` telemetry variable. + * + * Represents irsdk_TrackWetness + */ +export enum TrackWetness { + UNKNOWN = 0, + Dry, + MostlyDry, + VeryLightlyWet, + LightlyWet, + ModeratelyWet, + VeryWet, + ExtremelyWet, +} + +/** + * Bit flags for describing incidents. These can be used to extract info about + * an incident in the sim. + * + * - The first byte indicates the incident type. ('Report' values) + * - Second byte indicates the penalty. ('Penalty' values) + * + * To separate these, use a mask from the `IncidentFlagMask` enum. + * + * Represents irsdk_IncidentFlags + */ +export enum IncidentFlags { + NoReport = 0x0000, + + // first byte is incident report flag + // only one of these will be used + /** "Loss of Control (2x)" */ + ReportOutOfControl = 0x0001, + /** "Off Track (1x)" */ + ReportOffTrack = 0x0002, + /** not currently sent */ + ReportOffTrackOngoing = 0x0003, + /** "Contact (0x)" */ + ReportContactWithWorld = 0x0004, + /** "Contact (2x)" */ + ReportCollisionWithWorld = 0x0005, + /** not currently sent */ + ReportCollisionWithWorldOngoing = 0x0006, + /** "Car Contact (0x)" */ + ReportContactWithCar = 0x0007, + /** "Car Contact (4x)" */ + ReportCollisionWithCar = 0x0008, + + // second byte is incident penalty + // only one of these will be used + /** 0x */ + PenaltyZeroX = 0x0100, + /** 1x */ + PenaltyOneX = 0x0200, + /** 2x */ + PenaltyTwoX = 0x0300, + /** 4x */ + PenaltyFourX = 0x0400, +} + +/** + * Masks which can be used to separate the report and penalty information from + * `IncidentFlags` values. + * Represents *_MASK values from `irsdkIncidentFlags` + */ +export enum IncidentFlagMask { + Report = 0x000000ff, + Penalty = 0x0000ff00, +} + +/** + * Flags indicating an engine warning. + * Represents `irsdk_EngineWarnings` + */ +export enum EngineWarnings { + WaterTempWarning = 0x0001, + FuelPressureWarning = 0x0002, + OilPressureWarning = 0x0004, + EngineStalled = 0x0008, + PitSpeedLimiter = 0x0010, + RevLimiterActive = 0x0020, + OilTempWarning = 0x0040, + + /** Car needs mandatory repairs */ + MandatoryRepairsNeeded = 0x0080, + /** Car needs optional repairs */ + OptionalRepairsNeeded = 0x0100, +} + +/** + * Flags indicating session state. + * Represents `irsdk_Flags`. + */ +export enum GlobalFlags { + /** Global - Checkered flag active */ + Checkered = 0x00000001, + /** Global - White flag active */ + White = 0x00000002, + /** Global - Green flag active */ + Green = 0x00000004, + /** Global - Yellow flag active */ + Yellow = 0x00000008, + /** Global - Red flag active */ + Red = 0x00000010, + /** Global - Blue flag active */ + Blue = 0x00000020, + /** Global - Debris on track */ + Debris = 0x00000040, + /** Global - Crossed flag active */ + Crossed = 0x00000080, + /** Global - Yellow flag waving */ + YellowWaving = 0x00000100, + /** Global - One lap left until green */ + OneLapToGreen = 0x00000200, + /** Global - Green flag held */ + GreenHeld = 0x00000400, + /** Global - Ten more laps left */ + TenToGo = 0x00000800, + /** Global - Five laps left */ + FiveToGo = 0x00001000, + /** Global - Random waving active */ + RandomWaving = 0x00002000, + /** Global - Caution flag active */ + Caution = 0x00004000, + /** Global - Caution flag being waved */ + CautionWaving = 0x00008000, + + /** Driver black flags - black flag for driver */ + Black = 0x00010000, + /** Driver black flags - driver disqualified */ + Disqualify = 0x00020000, + /** Driver black flags - car is allowed */ + Servicible = 0x00040000, + /** Driver black flags - Furled flag */ + Furled = 0x00080000, + /** Driver black flags - car must be repaired */ + Repair = 0x00100000, + /** Driver black flags - car is disqualified and scoring is disabled */ + DqScoringInvalid = 0x00200000, + + /** Start lights - Lights hidden */ + StartHidden = 0x10000000, + /** Start lights - Lights ready */ + StartReady = 0x20000000, + /** Start lights - Lights set */ + StartSet = 0x40000000, + /** Start lights - Lights go */ + StartGo = 0x80000000, +} + +/** + * Flag representing the current camera state. + * Represents `irsdk_CameraState`. + */ +export enum CameraState { + /** the camera tool can only be activated if viewing the session screen (out of car) */ + IsSessionScreen = 0x0001, + /** the scenic camera is active (no focus car) */ + IsScenicActive = 0x0002, + /** CAN be changed with a broadcast message */ + CamToolActive = 0x0004, + /** CAN be changed with a broadcast message */ + UIHidden = 0x0008, + /** CAN be changed with a broadcast message */ + UseAutoShotSelection = 0x0010, + /** CAN be changed with a broadcast message */ + UseTemporaryEdits = 0x0020, + /** CAN be changed with a broadcast message */ + UseKeyAcceleration = 0x0040, + /** CAN be changed with a broadcast message */ + UseKey10xAcceleration = 0x0080, + /** CAN be changed with a broadcast message */ + UseMouseAimMode = 0x0100, +} + +/** + * Flag representing the changes to be done during a pit stop. + * Represents `irsdk_PitSvFlags` + */ +export enum PitSvFlags { + /** Left front tire */ + LFTireChange = 0x0001, + /** Right front tire */ + RFTireChange = 0x0002, + /** Left rear tire */ + LRTireChange = 0x0004, + /** Right rear tire */ + RRTireChange = 0x0008, + + /** Re-fuel */ + FuelFill = 0x0010, + /** Tearoff windshield */ + WindshieldTearoff = 0x0020, + /** Fast repair */ + FastRepair = 0x0040, +} + +/** + * Flags representing pacing states. + * Represents `irsdk_PaceFlags` + */ +export enum PaceFlags { + /** Catch up to the end of the line */ + EndOfLine = 0x0001, + /** Free to pass */ + FreePass = 0x0002, + /** Waved around */ + WavedAround = 0x0004, +} + +// --- SDK Commands + +/** + * Messages for controlling the sim via the SDK. + * + * - Camera and replay commands only work outside of the car. + * - Pit commands only work when in the car. + * + * Represents `irsdk_BroadcastMsg` + */ +export enum BroadcastMessages { + /** Switch the camera position. (Requires being outside of the car.) */ + CameraSwitchPos = 0, + /** Switch the driver number to follow. (Requires being outside of the car.) */ + CameraSwitchNum, + /** Change the camera state. (Requires being outside of the car.) */ + CameraSetState, + /** Change the play speed of a replay. (Requires being outside of the car.) */ + ReplaySetPlaySpeed, + /** Jump to a different part of the replay. (Requires being outside of the car.) */ + ReplaySetPlayPosition, + /** Enter replay search mode. (Requires being outside of the car.) */ + ReplaySearch, + /** Change the replay state. (Requires being outside of the car.) */ + ReplaySetState, + /** Trigger a texture reload. */ + ReloadTextures, + /** Broadcast a chat command. */ + ChatCommand, + /** Broadcast a pit command. (Requires being in the car.) */ + PitCommand, + /** Broadcast a telemetry command. */ + TelemCommand, + /** Broadcast a force feedback command. */ + FFBCommand, + /** Trigger searching to a replay time. (Requires being outside of the car.) */ + ReplaySearchSessionTime, + /** Trigger video capture. */ + VideoCapture, + /** Unused placeholder - do not use! */ + UnusedPlaceholder, +} + +/** + * Available chat command modes, to be used with message broadcasting. + * Represents `irsdk_ChatCommandMode`. + */ +export enum ChatCommand { + /** Number from 1-15, representing the chat macros. */ + Macro = 0, + /** Open up new chat window. */ + BeginChat, + /** Reply to last private chat. */ + Reply, + /** Close chat. */ + Cancel, +} + +/** + * Available pit command modes, to be used with message broadcasting. Only works + * when the driver is in the car! + * Represents `irsdk_PitCommandMode` + */ +export enum PitCommand { + /** Clear all pit checkboxes */ + Clear = 0, + /** Clean the winshield, using one tear off */ + WS, + /** + * Add fuel, optionally specify the amount to add in liters or pass '0' to use + * existing amount + */ + Fuel, + /** + * Change the left front tire, optionally specifying the pressure in KPa or + * pass '0' to use existing pressure + */ + LF, + /** right front */ + RF, + /** left rear */ + LR, + /** right rear */ + RR, + /** Clear tire pit checkboxes */ + ClearTires, + /** Request a fast repair */ + FR, + /** Uncheck Clean the windshield checkbox */ + ClearWS, + /** Uncheck request a fast repair */ + ClearFR, + /** Uncheck add fuel */ + ClearFuel, + /** Change tire compound */ + ChangeTireCompound, +} + +/** + * Available telemetry command modes, to be used with message broadcasting. + * This can be called at any time, but telemetry only records when driver is in + * the car. + * Represents `irsdk_TelemCommandMode` + */ +export enum TelemetryCommand { + /** Turn telemetry recording off */ + Stop = 0, + /** Turn telemetry recording on */ + Start, + /** Write current file to disk and start a new one */ + Restart, +} + +/** + * Available replay state commands, to be used with message broadcasting. Only + * usable outside of the car. + * Represents `irsdk_RpyStateMode` + */ +export enum ReplayStateCommand { + /** clear any data in the replay tape */ + EraseTape = 0, + /** Unused placeholder - do not use! */ + Last, +} + +/** + * Available texture reload commands, to be used with message broadcasting. + * Represents `irsdk_ReloadTexturesMode` + */ +export enum ReloadTexturesCommand { + /** reload all textures */ + All = 0, + /** reload only textures for the specific car index */ + CarIndex, +} + +/** + * Available replay search commands, to be used with message broadcasting. Only + * usable outside of the car. + * Represents `irsdk_RpySrchMode` + */ +export enum ReplaySearchCommand { + /** Start of session */ + ToStart = 0, + /** End of session */ + ToEnd, + /** Previous session */ + PrevSession, + /** Next session */ + NextSession, + /** Previous lap */ + PrevLap, + /** Next lap */ + NextLap, + /** Previous frame */ + PrevFrame, + /** Next frame */ + NextFrame, + /** Previous incident */ + PrevIncident, + /** Next incident */ + NextIncident, + /** Unused placeholder - do not use! */ + UnusedPlaceholder, +} + +/** + * Available replay positioning commands, to be used with message broadcasting. + * Only usable outside of the car. + * Represents `irsdk_RpyPosMode` + */ +export enum ReplayPositionCommand { + /** Beginning of the replay */ + Begin = 0, + /** Current position in the replay */ + Current, + /** End of the replay */ + End, + /** Unused placeholder - do not use! */ + UnusedPlaceholder, +} + +/** + * Available force-feedback commands, to be used with message broadcasting. + * Represents `irsdk_FFBCommandMode` + */ +export enum FFBCommand { + /** Set the maximum force when mapping steering torque force to direct input units (float in Nm) */ + MaxForce = 0, + /** Unused placeholder - do not use! */ + UnusedPlaceholder, +} + +/** + * Used with BroadcastMessages.CameraSwitchPos and BroadcastMessages.CameraSwitchNum. + * Pass these in for the first parameter to select the 'focus at' types in the camera system. + * Represents `irsdk_csMode` + */ +export enum CameraFocusCommand { + FocusAtIncident = -3, + FocusAtLeader = -2, + FocusAtExiting = -1, + /** When using .FocusAtDriver, add the car number to it to specify which car. */ + FocusAtDriver = 0, +} + +/** + * Available video capture commands, to be used with message broadcasting. + * Represents `irsdk_VideoCaptureMode` + */ +export enum VideoCaptureCommand { + /** save a screenshot to disk */ + TriggerScreenShot = 0, + /** start capturing video */ + StartVideoCapture, + /** stop capturing video */ + EndVideoCapture, + /** toggle video capture on/off */ + ToggleVideoCapture, + /** show video timer in upper left corner of display */ + ShowVideoTimer, + /** hide video timer */ + HideVideoTimer, +} diff --git a/packages/irsdk-node-types/src/enums.ts b/packages/irsdk-node-types/src/enums.ts deleted file mode 100644 index 485e151..0000000 --- a/packages/irsdk-node-types/src/enums.ts +++ /dev/null @@ -1,303 +0,0 @@ -export enum SessionState { - Invalid = 0, - GetInCar, - Warmup, - ParadeLaps, - Racing, - Checkered, - CoolDown, -} - -export enum GlobalFlags { - // Global - Checkered = 0x00000001, - White = 0x00000002, - Green = 0x00000004, - Yellow = 0x00000008, - Red = 0x00000010, - Blue = 0x00000020, - Debris = 0x00000040, - Crossed = 0x00000080, - YellowWaving = 0x00000100, - OneLapToGreen = 0x00000200, - GreenHeld = 0x00000400, - TenToGo = 0x00000800, - FiveToGo = 0x00001000, - RandomWaving = 0x00002000, - Caution = 0x00004000, - CautionWaving = 0x00008000, - - // Drivers black flags - Black = 0x00010000, - Disqualify = 0x00020000, - Servicible = 0x00040000, - Furled = 0x00080000, - Repair = 0x00100000, - - // Start lights - StartHidden = 0x10000000, - StartReady = 0x20000000, - StartSet = 0x40000000, - StartGo = 0x80000000, -} - -export enum PitSvFlags { - LFTireChange = 0x0001, - RFTireChange = 0x0002, - LRTireChange = 0x0004, - RRTireChange = 0x0008, - // Non-tires - FuelFill = 0x0010, - WindshieldTearoff = 0x0020, - FastRepair = 0x0040, -} - -export enum PitSvStatus { - // Status - None = 0, - InProgress, - Complete, - - // Errors - TooFarLeft = 100, - TooFarRight, - TooFarForward, - TooFarBack, - BadAngle, - CantFixThat, -} - -export enum PaceMode { - SingleFileStart = 0, - DoubleFileStart, - SingleFileRestart, - DoubleFileRestart, - NotPacing, -} - -export enum PaceFlags { - EndOfLine = 0x01, - FreePass = 0x02, - WavedAround = 0x04, -} - -export enum CarLeftRight { - Off, - /** No cars around us */ - Clear, - /** Car to our left */ - CarLeft, - /** Car to our right */ - CarRight, - /** Cars on both sides */ - CarLeftRight, - /** 2 cars to our left */ - Cars2Left, - /** 2 cars to our right */ - Cars2Right, -} - -export enum TrackLocation { - NotInWorld = -1, - OffTrack, - InPitStall, - ApproachingPits, - OnTrack, -} - -// Enums -export interface VarTypes { - 0: string; - 1: boolean; - 2: number; - 3: number; - 4: number; - 5: number; -} - -export enum BroadcastMessages { - /** Switch the camera position. */ - CameraSwitchPos = 0, - /** Switch the driver number to follow. */ - CameraSwitchNum, - /** Change the camera state. */ - CameraSetState, - /** Change the play speed of a replay. */ - ReplaySetPlaySpeed, - /** Jump to a different part of the replay. */ - ReplaySetPlayPosition, - /** Enter replay search mode. */ - ReplaySearch, - /** Change the replay state. */ - ReplaySetState, - /** Trigger a texture reload. */ - ReloadTextures, - /** Broadcast a chat command. */ - ChatCommand, - /** Broadcast a pit command. */ - PitCommand, - /** Broadcast a telemetry command. */ - TelemCommand, - /** Broadcast a force feedback command. */ - FFBCommand, - /** Trigger searching to a replay time. */ - ReplaySearchSessionTime, - /** Trigger video capture. */ - VideoCapture, - /** Unused. */ - Last, -} - -export enum CameraState { - /** the camera tool can only be activated if viewing the session screen (out of car) */ - irsdk_IsSessionScreen = 0x0001, - /** the scenic camera is active (no focus car) */ - irsdk_IsScenicActive = 0x0002, - /** CAN be changed with a broadcast message */ - irsdk_CamToolActive = 0x0004, - /** CAN be changed with a broadcast message */ - irsdk_UIHidden = 0x0008, - /** CAN be changed with a broadcast message */ - irsdk_UseAutoShotSelection = 0x0010, - /** CAN be changed with a broadcast message */ - irsdk_UseTemporaryEdits = 0x0020, - /** CAN be changed with a broadcast message */ - irsdk_UseKeyAcceleration = 0x0040, - /** CAN be changed with a broadcast message */ - irsdk_UseKey10xAcceleration = 0x0080, - /** CAN be changed with a broadcast message */ - irsdk_UseMouseAimMode = 0x0100, -} - -export enum ChatCommand { - /** Number from 1-15, representing the chat macros. */ - Macro = 0, - /** Open up new chat window. */ - BeginChat, - /** Reply to last private chat. */ - Reply, - /** Close chat. */ - Cancel, -} - -/** Only works when the driver is in the car! */ -export enum PitCommand { - /** Clear all pit checkboxes */ - Clear = 0, - /** Clean the winshield, using one tear off */ - WS, - /** Add fuel, optionally specify the amount to add in liters or pass '0' to use existing amount */ - Fuel, - /** Change the left front tire, optionally specifying the pressure in KPa or pass '0' to use existing pressure */ - LF, - /** right front */ - RF, - /** left rear */ - LR, - /** right rear */ - RR, - /** Clear tire pit checkboxes */ - ClearTires, - /** Request a fast repair */ - FR, - /** Uncheck Clean the windshield checkbox */ - ClearWS, - /** Uncheck request a fast repair */ - ClearFR, - /** Uncheck add fuel */ - ClearFuel, -} - -export enum TelemetryCommand { - /** Turn telemetry recording off */ - Stop = 0, - /** Turn telemetry recording on */ - Start, - /** Write current file to disk and start a new one */ - Restart, -} - -export enum ReplayStateCommand { - /** clear any data in the replay tape */ - EraseTape = 0, - /** unused place holder */ - Last, -} - -export enum ReloadTexturesCommand { - /** reload all textures */ - All = 0, - /** reload only textures for the specific car index */ - CarIndex, -} - -export enum ReplaySearchCommand { - /** Start of session */ - ToStart = 0, - /** End of session */ - ToEnd, - /** Previous session */ - PrevSession, - /** Next session */ - NextSession, - /** Previous lap */ - PrevLap, - /** Next lap */ - NextLap, - /** Previous frame */ - PrevFrame, - /** Next frame */ - NextFrame, - /** Previous incident */ - PrevIncident, - /** Next incident */ - NextIncident, - /** Unused */ - Last, -} - -export enum ReplayPositionCommand { - /** Beginning of the replay */ - Begin = 0, - /** Current position in the replay */ - Current, - /** End of the replay */ - End, - /** Unused */ - Last, -} - -export enum FFBCommand { - /** Set the maximum force when mapping steering torque force to direct input units (float in Nm) */ - MaxForce = 0, - /** Unused */ - Last, -} - -/** - * Used with BroadcastMessages.CameraSwitchPos and BroadcastMessages.CameraSwitchNum. - * Pass these in for the first parameter to select the 'focus at' types in the camera system. - * @todo: Not sure this will work with TS like it does in C++ :D - */ -export enum CameraFocusCommand { - FocusAtIncident = -3, - FocusAtLeader = -2, - FocusAtExiting = -1, - /** FocusAtDriver + car number... */ - FocusAtDriver = 0, -} - -export enum VideoCaptureCommand { - /** save a screenshot to disk */ - TriggerScreenShot = 0, - /** start capturing video */ - StartVideoCapture, - /** stop capturing video */ - EndVideoCapture, - /** toggle video capture on/off */ - ToggleVideoCapture, - /** show video timer in upper left corner of display */ - ShowVideoTimer, - /** hide video timer */ - HideVideoTimer, -} diff --git a/packages/irsdk-node-types/src/index.ts b/packages/irsdk-node-types/src/index.ts index 1ab062e..e4db901 100644 --- a/packages/irsdk-node-types/src/index.ts +++ b/packages/irsdk-node-types/src/index.ts @@ -1,4 +1,4 @@ -export * from './enums.js'; +export * from './defines.js'; export type * from './camera-info.js'; export type * from './driver-info.js'; export type * from './radio-info.js'; diff --git a/packages/irsdk-node-types/src/weekend-info.ts b/packages/irsdk-node-types/src/weekend-info.ts index f5298eb..9b209ea 100644 --- a/packages/irsdk-node-types/src/weekend-info.ts +++ b/packages/irsdk-node-types/src/weekend-info.ts @@ -52,6 +52,18 @@ export interface WeekendInfo { TrackPitSpeedLimit: string; TrackType: string; TrackDirection: string; + /** + * Can be one of the following: + * + * - Classic Specified / Dynamic Sky + * - Classic Generated / Dynamic Sky + * - Classic Specified / Static Sky + * - Classic Generated / Static Sky + * - Realistic + * - Static + * - Timeline + * - Unknown + */ TrackWeatherType: string; TrackSkies: string; TrackSurfaceTemp: string;