use crate::core::SharedMemoryReader;
use crate::datatypes::{CarDamage, ContactPoint, Vector3f, Wheels};
use crate::maps::PhysicsMap;
use crate::Result;
pub fn parse_physics_map(reader: &SharedMemoryReader) -> Result<PhysicsMap> {
let mut _offset = 0;
macro_rules! read_value {
($type:ty) => {{
let value = reader.read_at::<$type>(_offset)?;
_offset += std::mem::size_of::<$type>();
value
}};
}
macro_rules! read_array {
($type:ty, $count:expr) => {{
let values = reader.read_array_at::<$type>(_offset, $count)?;
_offset += std::mem::size_of::<$type>() * $count;
values
}};
}
let read_vector3f = |offset: &mut usize| -> Result<Vector3f> {
let values = reader.read_array_at::<f32>(*offset, 3)?;
*offset += std::mem::size_of::<f32>() * 3;
Ok(Vector3f::new(values[0], values[1], values[2]))
};
let read_wheels = |offset: &mut usize| -> Result<Wheels> {
let values = reader.read_array_at::<f32>(*offset, 4)?;
*offset += std::mem::size_of::<f32>() * 4;
Ok(Wheels::new(values[0], values[1], values[2], values[3]))
};
let read_contact_point = |offset: &mut usize| -> Result<ContactPoint> {
let mut points = [[0.0f32; 3]; 4];
for i in 0..4 {
let values = reader.read_array_at::<f32>(*offset, 3)?;
*offset += std::mem::size_of::<f32>() * 3;
points[i] = [values[0], values[1], values[2]];
}
Ok(ContactPoint::from_nested_array(points))
};
let packet_id = read_value!(i32);
let gas = read_value!(f32);
let brake = read_value!(f32);
let fuel = read_value!(f32);
let gear = read_value!(i32);
let rpm = read_value!(i32);
let steer_angle = read_value!(f32);
let speed_kmh = read_value!(f32);
let velocity = read_vector3f(&mut _offset)?;
let g_force = read_vector3f(&mut _offset)?;
let wheel_slip = read_wheels(&mut _offset)?;
let _wheel_load = read_wheels(&mut _offset)?; let wheel_pressure = read_wheels(&mut _offset)?;
let wheel_angular_speed = read_wheels(&mut _offset)?;
let _tyre_wear = read_wheels(&mut _offset)?; let _tyre_dirty_level = read_wheels(&mut _offset)?; let tyre_core_temp = read_wheels(&mut _offset)?;
let _camber_rad = read_wheels(&mut _offset)?; let suspension_travel = read_wheels(&mut _offset)?;
let _drs = read_value!(i32);
let tc = read_value!(f32);
let heading = read_value!(f32);
let pitch = read_value!(f32);
let roll = read_value!(f32);
let _cg_height = read_value!(f32);
let damage_values = read_array!(f32, 5);
let car_damage = CarDamage::from([
damage_values[0],
damage_values[1],
damage_values[2],
damage_values[3],
damage_values[4],
]);
let _number_of_tyres_out = read_value!(i32); let pit_limiter_on = read_value!(i32) != 0;
let abs = read_value!(f32);
let _kers_charge = read_value!(f32);
let _kers_input = read_value!(f32);
let autoshifter_on = read_value!(i32) != 0;
let _ride_height = read_array!(f32, 2); let turbo_boost = read_value!(f32);
let _ballast = read_value!(f32); let _air_density = read_value!(f32); let air_temp = read_value!(f32);
let road_temp = read_value!(f32);
let local_angular_vel = read_vector3f(&mut _offset)?;
let final_ff = read_value!(f32);
let _performance_meter = read_value!(f32);
let _engine_brake = read_value!(i32);
let _ers_recovery_level = read_value!(i32);
let _ers_power_level = read_value!(i32);
let _ers_heat_charging = read_value!(i32);
let _ers_is_charging = read_value!(i32);
let _kers_current_kj = read_value!(f32);
let _drs_available = read_value!(i32);
let _drs_enabled = read_value!(i32);
let brake_temp = read_wheels(&mut _offset)?;
let clutch = read_value!(f32);
let _tyre_temp_i = read_wheels(&mut _offset)?;
let _tyre_temp_m = read_wheels(&mut _offset)?;
let _tyre_temp_o = read_wheels(&mut _offset)?;
let is_ai_controlled = read_value!(i32) != 0;
let tyre_contact_point = read_contact_point(&mut _offset)?;
let tyre_contact_normal = read_contact_point(&mut _offset)?;
let tyre_contact_heading = read_contact_point(&mut _offset)?;
let brake_bias = read_value!(f32);
let local_velocity = read_vector3f(&mut _offset)?;
let _p2p_activation = read_value!(i32);
let _p2p_status = read_value!(i32);
let _current_max_rpm = read_value!(i32);
let _mz = read_wheels(&mut _offset)?;
let _fz = read_wheels(&mut _offset)?;
let _my = read_wheels(&mut _offset)?;
let slip_ratio = read_wheels(&mut _offset)?;
let slip_angle = read_wheels(&mut _offset)?;
let _tc_in_action = read_value!(i32); let _abs_in_action = read_value!(i32); let suspension_damage = read_wheels(&mut _offset)?;
let _tyre_temp = read_wheels(&mut _offset)?; let water_temp = read_value!(f32);
let brake_pressure = read_wheels(&mut _offset)?;
let front_brake_compound = read_value!(i32);
let rear_brake_compound = read_value!(i32);
let pad_life = read_wheels(&mut _offset)?;
let disc_life = read_wheels(&mut _offset)?;
let ignition_on = read_value!(i32) != 0;
let starter_engine_on = read_value!(i32) != 0;
let is_engine_running = read_value!(i32) != 0;
let kerb_vibration = read_value!(f32);
let slip_vibration = read_value!(f32);
let g_vibration = read_value!(f32);
let abs_vibration = read_value!(f32);
Ok(PhysicsMap {
packet_id,
gas,
brake,
clutch,
steer_angle,
gear,
rpm,
autoshifter_on,
ignition_on,
starter_engine_on,
is_engine_running,
speed_kmh,
velocity,
local_velocity,
local_angular_vel,
g_force,
heading,
pitch,
roll,
final_ff,
wheel_slip,
wheel_pressure,
wheel_angular_speed,
tyre_core_temp,
suspension_travel,
brake_temp,
brake_pressure,
suspension_damage,
slip_ratio,
slip_angle,
pad_life,
disc_life,
front_brake_compound,
rear_brake_compound,
tyre_contact_point,
tyre_contact_normal,
tyre_contact_heading,
fuel,
tc,
abs,
pit_limiter_on,
turbo_boost,
air_temp,
road_temp,
water_temp,
car_damage,
is_ai_controlled,
brake_bias,
kerb_vibration,
slip_vibration,
g_vibration,
abs_vibration,
})
}