Skip to content

Instantly share code, notes, and snippets.

@bradland

bradland/pcars_net.rb

Last active Dec 20, 2015
Embed
What would you like to do?
require 'bindata'
# Record definition
class PCarsNet < BinData::Record
endian :little
uint16 :build_version_number # 0
uint8 :packet_type # 2
bit4 :session_state # 3
bit4 :game_state # 3
int8 :viewed_participant_index # 4
int8 :num_participants # 5
uint8 :unfiltered_throttle # 6
uint8 :unfiltered_brake # 7
int8 :unfiltered_steering # 8
uint8 :unfiltered_clutch # 9
bit3 :boost_active
bit1 :anti_lock_active
bit1 :lap_invalidated
bit3 :race_state
# uint8 :race_state_flags # 10
uint8 :laps_in_event # 11
float :best_lap_time # 12
float :last_lap_time # 16
float :current_time # 20
float :split_time_ahead # 24
float :split_time_behind # 28
float :split_time # 32
float :event_time_remaining # 36
float :personal_fastest_lap_time # 40
float :world_fastest_lap_time # 44
float :current_sector1_time # 48
float :current_sector2_time # 52
float :current_sector3_time # 56
float :fastest_sector1_time # 60
float :fastest_sector2_time # 64
float :fastest_sector3_time # 68
float :personal_fastest_sector1_time # 72
float :personal_fastest_sector2_time # 76
float :personal_fastest_sector3_time # 80
float :world_fastest_sector1_time # 84
float :world_fastest_sector2_time # 88
float :world_fastest_sector3_time # 92
uint16 :joy_pad # 96
uint8 :highest_flag # 98
uint8 :pit_mode_schedule # 99
int16 :oil_temp_celsius # 100
uint16 :oil_pressure_k_pa # 102
int16 :water_temp_celsius # 104
uint16 :water_pressure_kpa # 106
uint16 :fuel_pressure_kpa # 108
uint8 :car_flags # 110
uint8 :fuel_capacity # 111
uint8 :brake # 112
uint8 :throttle # 113
uint8 :clutch # 114
int8 :steering # 115
float :fuel_level # 116
float :speed # 120
uint16 :rpm # 124
uint16 :max_rpm # 126
uint8 :gear_num_gears # 128
uint8 :boost_amount # 129
int8 :enforced_pit_stop_lap # 130
uint8 :crash_state # 131
float :odometer_km # 132
float :orientation # 136
float :local_velocity # 148
float :world_velocity # 160
float :angular_velocity # 172
float :local_acceleration # 184
float :world_acceleration # 196
float :extents_centre # 208
uint8 :tyre_flags # 220
uint8 :terrain # 224
float :tyre_y # 228
float :tyre_rps # 244
float :tyre_slip_speed # 260
uint8 :tyre_temp # 276
uint8 :tyre_grip # 280
float :tyre_height_above_ground # 284
float :tyre_lateral_stiffness # 300
uint8 :tyre_wear # 316
uint8 :brake_damage # 320
uint8 :suspension_damage # 324
int16 :brake_temp_celsius # 328
uint16 :tyre_tread_temp # 336
uint16 :tyre_layer_temp # 344
uint16 :tyre_carcass_temp # 352
uint16 :tyre_rim_temp # 360
uint16 :tyre_internal_air_temp # 368
float :wheel_local_position_y # 376
float :ride_height # 392
float :suspension_travel # 408
float :suspension_velocity # 424
uint16 :air_pressure # 440
float :engine_speed # 448
float :engine_torque # 452
uint8 :aero_damage # 456
uint8 :engine_damage # 457
int8 :ambient_temperature # 458
int8 :track_temperature # 459
uint8 :rain_density # 460
int8 :wind_speed # 461
int8 :wind_direction_x # 462
int8 :wind_direction_y # 463
# sParticipantInfo :participant_info # 464
# float :track_length # 1360
# uint8 :wings # 1364
# uint8 :d_pad # 1366
end
struct sParticipantInfo
{
s16 sWorldPosition[3]; // 0
u16 sCurrentLapDistance; // 6
u8 sRacePosition; // 8
u8 sLapsCompleted; // 9
u8 sCurrentLap; // 10
u8 sSector; // 11
f32 sLastSectorTime; // 14
// 16
};
struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sCarName[64]; // 3
char sCarClassName[64]; // 131
char sTrackLocation[64]; // 195
char sTrackVariation[64]; // 259
char sName[16][64]; // 323
// 1347
};
struct sParticipantInfoStringsAdditional
{
static const u32 sPacketSize = 1028;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
u8 sOffset; // 3
char sName[16][64]; // 4
// 1028
};
struct sTelemetryData
{
static const u32 sPacketSize = 1367;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
// Game states
u8 sGameSessionState; // 3
// Participant info
s8 sViewedParticipantIndex; // 4
s8 sNumParticipants; // 5
// Unfiltered input
u8 sUnfilteredThrottle; // 6
u8 sUnfilteredBrake; // 7
s8 sUnfilteredSteering; // 8
u8 sUnfilteredClutch; // 9
u8 sRaceStateFlags; // 10
// Event information
u8 sLapsInEvent; // 11
// Timings
f32 sBestLapTime; // 12
f32 sLastLapTime; // 16
f32 sCurrentTime; // 20
f32 sSplitTimeAhead; // 24
f32 sSplitTimeBehind; // 28
f32 sSplitTime; // 32
f32 sEventTimeRemaining; // 36
f32 sPersonalFastestLapTime; // 40
f32 sWorldFastestLapTime; // 44
f32 sCurrentSector1Time; // 48
f32 sCurrentSector2Time; // 52
f32 sCurrentSector3Time; // 56
f32 sFastestSector1Time; // 60
f32 sFastestSector2Time; // 64
f32 sFastestSector3Time; // 68
f32 sPersonalFastestSector1Time; // 72
f32 sPersonalFastestSector2Time; // 76
f32 sPersonalFastestSector3Time; // 80
f32 sWorldFastestSector1Time; // 84
f32 sWorldFastestSector2Time; // 88
f32 sWorldFastestSector3Time; // 92
u16 sJoyPad; // 96
// Flags
u8 sHighestFlag; // 98
// Pit info
u8 sPitModeSchedule; // 99
// Car state
s16 sOilTempCelsius; // 100
u16 sOilPressureKPa; // 102
s16 sWaterTempCelsius; // 104
u16 sWaterPressureKpa; // 106
u16 sFuelPressureKpa; // 108
u8 sCarFlags; // 110
u8 sFuelCapacity; // 111
u8 sBrake; // 112
u8 sThrottle; // 113
u8 sClutch; // 114
s8 sSteering; // 115
f32 sFuelLevel; // 116
f32 sSpeed; // 120
u16 sRpm; // 124
u16 sMaxRpm; // 126
u8 sGearNumGears; // 128
u8 sBoostAmount; // 129
s8 sEnforcedPitStopLap; // 130
u8 sCrashState; // 131
f32 sOdometerKM; // 132
f32 sOrientation[3]; // 136
f32 sLocalVelocity[3]; // 148
f32 sWorldVelocity[3]; // 160
f32 sAngularVelocity[3]; // 172
f32 sLocalAcceleration[3]; // 184
f32 sWorldAcceleration[3]; // 196
f32 sExtentsCentre[3]; // 208
// Wheels / Tyres
u8 sTyreFlags[4]; // 220
u8 sTerrain[4]; // 224
f32 sTyreY[4]; // 228
f32 sTyreRPS[4]; // 244
f32 sTyreSlipSpeed[4]; // 260
u8 sTyreTemp[4]; // 276
u8 sTyreGrip[4]; // 280
f32 sTyreHeightAboveGround[4]; // 284
f32 sTyreLateralStiffness[4]; // 300
u8 sTyreWear[4]; // 316
u8 sBrakeDamage[4]; // 320
u8 sSuspensionDamage[4]; // 324
s16 sBrakeTempCelsius[4]; // 328
u16 sTyreTreadTemp[4]; // 336
u16 sTyreLayerTemp[4]; // 344
u16 sTyreCarcassTemp[4]; // 352
u16 sTyreRimTemp[4]; // 360
u16 sTyreInternalAirTemp[4]; // 368
f32 sWheelLocalPositionY[4]; // 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
u16 sAirPressure[4]; // 440
// Extras
f32 sEngineSpeed; // 448
f32 sEngineTorque; // 452
// Car damage
u8 sAeroDamage; // 456
u8 sEngineDamage; // 457
// Weather
s8 sAmbientTemperature; // 458
s8 sTrackTemperature; // 459
u8 sRainDensity; // 460
s8 sWindSpeed; // 461
s8 sWindDirectionX; // 462
s8 sWindDirectionY; // 463
sParticipantInfo sParticipantInfo[56]; // 464
// 56*16=896
f32 sTrackLength; // 1360
u8 sWings[2]; // 1364
u8 sDPad; // 1366
// 1368 struct is padded to
};
mBuildVersionNumber=mTelemetryData.sBuildVersionNumber=(u16)pMemory->mBuildVersionNumber; // u32->u16
mTelemetryData.sPacketType=0|((mCount&63)<<2); // Packet type | (sequence<<2)
// Game state
mTelemetryData.sGameSessionState=((u8)pMemory->mGameState)|(((u8)pMemory->mSessionState)<<4); // (enum 3 bits/enum 3 bits)->u8
mTelemetryData.sRaceStateFlags=((u8)pMemory->mRaceState) | // (enum 3 bits)->u8
(pMemory->mLapInvalidated?8:0)|(pMemory->mAntiLockActive?16:0)|(pMemory->mBoostActive?32:0); // (bool/bool/bool)->u8
// Participant info
mTelemetryData.sViewedParticipantIndex=(s8)pMemory->mViewedParticipantIndex; // s32->s8
mTelemetryData.sNumParticipants=(s8)pMemory->mNumParticipants; // s32->s8
// Unfiltered input
mTelemetryData.sUnfilteredThrottle=(u8)(Clamp(pMemory->mUnfilteredThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredBrake=(u8)(Clamp(pMemory->mUnfilteredBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredSteering=(s8)(Clamp(pMemory->mUnfilteredSteering, -1.0f, 1.0f)*127.0f); // f32->s8
mTelemetryData.sUnfilteredClutch=(u8)(Clamp(pMemory->mUnfilteredClutch, 0.0f, 1.0f)*255.0f); // f32->u8
// Event information
mTelemetryData.sTrackLength=(f32)pMemory->mTrackLength; // f32->f32
mTelemetryData.sLapsInEvent=(u8)min(pMemory->mLapsInEvent,255); // u32->u8
// Timings
mTelemetryData.sBestLapTime=pMemory->mBestLapTime; // f32->f32
mTelemetryData.sLastLapTime=pMemory->mLastLapTime; // f32->f32
mTelemetryData.sCurrentTime=pMemory->mCurrentTime; // f32->f32
mTelemetryData.sSplitTimeAhead=pMemory->mSplitTimeAhead; // f32->f32
mTelemetryData.sSplitTimeBehind=pMemory->mSplitTimeBehind; // f32->f32
mTelemetryData.sSplitTime=pMemory->mSplitTime; // f32->f32
mTelemetryData.sEventTimeRemaining=pMemory->mEventTimeRemaining; // f32->f32
mTelemetryData.sPersonalFastestLapTime=pMemory->mPersonalFastestLapTime; // f32->f32
mTelemetryData.sWorldFastestLapTime=pMemory->mWorldFastestLapTime; // f32->f32
mTelemetryData.sCurrentSector1Time=pMemory->mCurrentSector1Time; // f32->f32
mTelemetryData.sCurrentSector2Time=pMemory->mCurrentSector2Time; // f32->f32
mTelemetryData.sCurrentSector3Time=pMemory->mCurrentSector3Time; // f32->f32
mTelemetryData.sFastestSector1Time=pMemory->mFastestSector1Time; // f32->f32
mTelemetryData.sFastestSector2Time=pMemory->mFastestSector2Time; // f32->f32
mTelemetryData.sFastestSector3Time=pMemory->mFastestSector3Time; // f32->f32
mTelemetryData.sPersonalFastestSector1Time=pMemory->mPersonalFastestSector1Time; // f32->f32
mTelemetryData.sPersonalFastestSector2Time=pMemory->mPersonalFastestSector2Time; // f32->f32
mTelemetryData.sPersonalFastestSector3Time=pMemory->mPersonalFastestSector3Time; // f32->f32
mTelemetryData.sWorldFastestSector1Time=pMemory->mWorldFastestSector1Time; // f32->f32
mTelemetryData.sWorldFastestSector2Time=pMemory->mWorldFastestSector2Time; // f32->f32
mTelemetryData.sWorldFastestSector3Time=pMemory->mWorldFastestSector3Time; // f32->f32
// Flags
mTelemetryData.sHighestFlag=((u8)pMemory->mHighestFlagColour) | (((u8)pMemory->mHighestFlagReason)<<4); // (enum 3 bits/enum 2 bits)
// Pit info
mTelemetryData.sPitModeSchedule=((u8)pMemory->mPitMode) | (((u8)pMemory->mPitSchedule)<<4); // (enum 3 bits/enum 2 bits)
// Car state
mTelemetryData.sCarFlags=(u8)pMemory->mCarFlags; // enum->u8
mTelemetryData.sOilTempCelsius=(s16)pMemory->mOilTempCelsius; // f32->s16
mTelemetryData.sOilPressureKPa=(u16)pMemory->mOilPressureKPa; // f32->u16
mTelemetryData.sWaterTempCelsius=(s16)pMemory->mWaterTempCelsius; // f32->s16
mTelemetryData.sWaterPressureKpa=(u16)pMemory->mWaterPressureKPa; // f32->u16
mTelemetryData.sFuelPressureKpa=(u16)pMemory->mFuelPressureKPa; // f32->u16
mTelemetryData.sFuelCapacity=(u8)pMemory->mFuelCapacity; // f32->u8
mTelemetryData.sBrake=(u8)(Clamp(pMemory->mBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sFuelLevel=pMemory->mFuelLevel; // f32->f32
mTelemetryData.sSpeed=pMemory->mSpeed; // f32->f32
mTelemetryData.sRpm=(u16)pMemory->mRpm; // f32->u16
mTelemetryData.sMaxRpm=(u16)pMemory->mMaxRPM; // f32->u16
mTelemetryData.sThrottle=(u8)(Clamp(pMemory->mThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sClutch=(u8)(Clamp(pMemory->mClutch, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSteering=(s8)(Clamp(pMemory->mSteering, -1.0f, 1.0f)*127.0f); // f32->s8
u8 gear=pMemory->mGear<0?0x0f:min((u8)(pMemory->mGear&0xff), 7);
u8 numGears=max((u8)(pMemory->mNumGears&0xff), 0);
mTelemetryData.sGearNumGears=(gear&0x0f)|((numGears&0x0f)<<4); // s32/s32->u8
mTelemetryData.sOdometerKM=pMemory->mOdometerKM; // f32->f32
mTelemetryData.sBoostAmount=(u8)pMemory->mBoostAmount; // f32->u8
mTelemetryData.sOrientation[0]=pMemory->mOrientation[0]; // f32->f32
mTelemetryData.sOrientation[1]=pMemory->mOrientation[1]; // f32->f32
mTelemetryData.sOrientation[2]=pMemory->mOrientation[2]; // f32->f32
mTelemetryData.sLocalVelocity[0]=pMemory->mLocalVelocity[0]; // f32->f32
mTelemetryData.sLocalVelocity[1]=pMemory->mLocalVelocity[1]; // f32->f32
mTelemetryData.sLocalVelocity[2]=pMemory->mLocalVelocity[2]; // f32->f32
mTelemetryData.sWorldVelocity[0]=pMemory->mWorldVelocity[0]; // f32->f32
mTelemetryData.sWorldVelocity[1]=pMemory->mWorldVelocity[1]; // f32->f32
mTelemetryData.sWorldVelocity[2]=pMemory->mWorldVelocity[2]; // f32->f32
mTelemetryData.sAngularVelocity[0]=pMemory->mAngularVelocity[0]; // f32->f32
mTelemetryData.sAngularVelocity[1]=pMemory->mAngularVelocity[1]; // f32->f32
mTelemetryData.sAngularVelocity[2]=pMemory->mAngularVelocity[2]; // f32->f32
mTelemetryData.sLocalAcceleration[0]=pMemory->mLocalAcceleration[0]; // f32->f32
mTelemetryData.sLocalAcceleration[1]=pMemory->mLocalAcceleration[1]; // f32->f32
mTelemetryData.sLocalAcceleration[2]=pMemory->mLocalAcceleration[2]; // f32->f32
mTelemetryData.sWorldAcceleration[0]=pMemory->mWorldAcceleration[0]; // f32->f32
mTelemetryData.sWorldAcceleration[1]=pMemory->mWorldAcceleration[1]; // f32->f32
mTelemetryData.sWorldAcceleration[2]=pMemory->mWorldAcceleration[2]; // f32->f32
mTelemetryData.sExtentsCentre[0]=pMemory->mExtentsCentre[0]; // f32->f32
mTelemetryData.sExtentsCentre[1]=pMemory->mExtentsCentre[1]; // f32->f32
mTelemetryData.sExtentsCentre[2]=pMemory->mExtentsCentre[2]; // f32->f32
// Wheels / Tyres
u32 i;
for (i=0;i<4;i++)
{
mTelemetryData.sTyreFlags[i]=(u8)pMemory->mTyreFlags[i]; // (enum 3 bits)->u8
mTelemetryData.sTerrain[i]=(u8)pMemory->mTerrain[i]; // (enum 6 bits)->u8
mTelemetryData.sTyreY[i]=pMemory->mTyreY[i]; // f32->f32
mTelemetryData.sTyreRPS[i]=pMemory->mTyreRPS[i]; // f32->f32
mTelemetryData.sTyreSlipSpeed[i]=pMemory->mTyreSlipSpeed[i]; // f32->f32
mTelemetryData.sTyreTemp[i]=(u8)Clamp(pMemory->mTyreTemp[i], 0.0f, 255.0f); // f32->u8
mTelemetryData.sTyreGrip[i]=(u8)Clamp(pMemory->mTyreGrip[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sTyreHeightAboveGround[i]=pMemory->mTyreHeightAboveGround[i]; // f32->f32
mTelemetryData.sTyreLateralStiffness[i]=pMemory->mTyreLateralStiffness[i]; // f32->f32
mTelemetryData.sTyreWear[i]=(u8)(Clamp(pMemory->mTyreWear[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeDamage[i]=(u8)(Clamp(pMemory->mBrakeDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSuspensionDamage[i]=(u8)(Clamp(pMemory->mSuspensionDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeTempCelsius[i]=(s16)pMemory->mBrakeTempCelsius[i]; // f32->s16
mTelemetryData.sTyreTreadTemp[i]=(u16)pMemory->mTyreTreadTemp[i]; // f32->u16
mTelemetryData.sTyreLayerTemp[i]=(u16)pMemory->mTyreLayerTemp[i]; // f32->u16
mTelemetryData.sTyreCarcassTemp[i]=(u16)pMemory->mTyreCarcassTemp[i]; // f32->u16
mTelemetryData.sTyreRimTemp[i]=(u16)pMemory->mTyreRimTemp[i]; // f32->u16
mTelemetryData.sTyreInternalAirTemp[i]=(u16)pMemory->mTyreInternalAirTemp[i]; // f32->u16
mTelemetryData.sWheelLocalPositionY[i]=pMemoryExtras->mWheelLocalPositionY[i]; // f32->f32
mTelemetryData.sRideHeight[i]=pMemoryExtras->mRideHeight[i]; // f32->f32
mTelemetryData.sSuspensionTravel[i]=pMemoryExtras->mSuspensionTravel[i]; // f32->f32
mTelemetryData.sSuspensionVelocity[i]=pMemoryExtras->mSuspensionVelocity[i]; // f32->f32
mTelemetryData.sAirPressure[i]=pMemoryExtras->mAirPressure[i]; // f32->u16
}
// Extras
mTelemetryData.sEngineSpeed=pMemoryExtras->mEngineSpeed; // f32->f32
mTelemetryData.sEngineTorque=pMemoryExtras->mEngineTorque; // f32->f32
mTelemetryData.sWings[0]=pMemoryExtras->mWings[0]; // f32->u8
mTelemetryData.sWings[1]=pMemoryExtras->mWings[1]; // f32->u8
mTelemetryData.sEnforcedPitStopLap=(s8)pMemoryExtras->mEnforcedPitStopLap; // S32->s8
//Car damage
mTelemetryData.sCrashState=(u8)pMemory->mCrashState; // (enum 3 bits)->u8
mTelemetryData.sAeroDamage=(u8)(Clamp(pMemory->mAeroDamage, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sEngineDamage=(u8)(Clamp(pMemory->mEngineDamage, 0.0f, 1.0f)*255.0f); // f32->u8
// Weather
mTelemetryData.sAmbientTemperature=(s8)Clamp(pMemory->mAmbientTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sTrackTemperature=(s8)Clamp(pMemory->mTrackTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sRainDensity=(u8)(Clamp(pMemory->mRainDensity, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sWindSpeed=(u8)(Clamp(pMemory->mWindSpeed*0.5f, 0.0f, 255.0f)); // f32->u8
mTelemetryData.sWindDirectionX=(s8)Clamp(pMemory->mWindDirectionX*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sWindDirectionY=(s8)Clamp(pMemory->mWindDirectionY*127.0f, -127.0f, 127.0f); // f32->s8
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 56);i++)
{
mTelemetryData.sParticipantInfo[i].sWorldPosition[0]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[0], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[1]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[1], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[2]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[2], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sCurrentLapDistance=(u16)min(pMemory->mParticipantInfo[i].mCurrentLapDistance, 65535.0f); // f32->u16
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?128:0); // u32+bool->u8 (top bit is active)
mTelemetryData.sParticipantInfo[i].sLapsCompleted=((u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 127))|(pMemoryExtras->mLapInvalidated[i]?128:0); // u32+bool->u8 (top bit is lap invalidated)
mTelemetryData.sParticipantInfo[i].sCurrentLap=(u8)min(pMemory->mParticipantInfo[i].mCurrentLap, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sSector=(u8)pMemory->mParticipantInfo[i].mCurrentSector; // (enum 3 bits)->u8
// Extra accuracy bits for x/z
u32 x=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[0]*4.0f))&3;
u32 z=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[2]*4.0f))&3;
mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|((u8)x<<6)|((u8)z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8
mTelemetryData.sParticipantInfo[i].sLastSectorTime=pMemoryExtras->mLastSectorTime[i]; // f32->f32
}
mTelemetryData.sJoyPad=(u16)JOYPAD BUTTON MASK
mTelemetryData.sDPad=(u8)JOYPAD DPAD MASK
// This packet below is sent less often
BStrcpy(mParticipantStrings.sCarName, 64, pMemory->mCarName);
BStrcpy(mParticipantStrings.sCarClassName, 64, pMemory->mCarClassName);
BStrcpy(mParticipantStrings.sTrackLocation, 64, pMemory->mTrackLocation);
BStrcpy(mParticipantStrings.sTrackVariation, 64, pMemory->mTrackVariation);
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 16);i++)
{
BStrcpy(mParticipantStrings.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStrings.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStrings.sPacketType=1|((mCount&63)<<2); // Packet type | (sequence<<2)
// These extra packets are sent if participants>16
for (groups of 16)
{
BStrcpy(mParticipantStringsAdditional.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStringsAdditional.sOffset=(u8) //OFFSET IN 16's, so 1st packet of this type offset will be 16, 2nd 32 etc
mParticipantStringsAdditional.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStringsAdditional.sPacketType=2|((mCount&63)<<2); // Packet type | (sequence<<2)
#!/usr/bin/env ruby
require 'socket'
# This is where the stream dump will be written.
DUMP_FILE = 'data/pcars.dump'
BasicSocket.do_not_reverse_lookup = true
# Create our socket
client = UDPSocket.new
client.bind('0.0.0.0', 5606)
# Buffer that we'll dump to the dump file on SIGINT.
buffer = ""
begin
loop do
# Get data in 1024 byte chunks.
data, addr = client.recvfrom(1024)
buffer << data
end
rescue Interrupt
File.open DUMP_FILE, 'wb' do |file|
file.write buffer
end
puts "Exiting..."
end
client.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.