SimulatorFans/Client/source/AssettoCorsa.SharedMemory.pas

334 lines
7.6 KiB
ObjectPascal

unit AssettoCorsa.SharedMemory;
interface
type
AC_STATUS = Integer;
TACStatus = AC_STATUS;
const
{ AC_STATUS }
AC_OFF = 0;
AC_REPLAY = 1;
AC_LIVE = 2;
AC_PAUSE = 3;
type
AC_SESSION_TYPE = Integer;
TACSessionType = AC_SESSION_TYPE;
const
{ AC_SESSION_TYPE }
AC_UNKNOWN = -1;
AC_PRACTICE = 0;
AC_QUALIFY = 1;
AC_RACE = 2;
AC_HOTLAP = 3;
AC_TIME_ATTACK = 4;
AC_DRIFT = 5;
AC_DRAG = 6;
type
AC_FLAG_TYPE = Integer;
TACFlagType = AC_FLAG_TYPE;
const
{ AC_FLAG_TYPE }
AC_NO_FLAG = 0;
AC_BLUE_FLAG = 1;
AC_YELLOW_FLAG = 2;
AC_BLACK_FLAG = 3;
AC_WHITE_FLAG = 4;
AC_CHECKERED_FLAG = 5;
AC_PENALTY_FLAG = 6;
type
TACSMPhysics = packed record
packetId: Integer;
gas: Single;
brake: Single;
fuel: Single;
gear: Integer;
rpms: Integer;
steerAngle: Single;
speedKmh: Single;
velocity: array[0..2] of Single;
accG: array[0..2] of Single;
wheelSlip: array[0..3] of Single;
wheelLoad: array[0..3] of Single;
wheelsPressure: array[0..3] of Single;
wheelAngularSpeed: array[0..3] of Single;
tyreWear: array[0..3] of Single;
tyreDirtyLevel: array[0..3] of Single;
tyreCoreTemperature: array[0..3] of Single;
camberRAD: array[0..3] of Single;
suspensionTravel: array[0..3] of Single;
drs: Single;
tc: Single;
heading: Single;
pitch: Single;
roll: Single;
cgHeight: Single;
carDamage: array[0..4] of Single;
umberOfTyresOut: Integer;
pitLimiterOn: Integer;
abs: Single;
kersCharge: Single;
kersInput: Single;
autoShifterOn: Integer;
rideHeigh: Single;
turboBoost: Single;
ballast: Single;
airDensity: Single;
airTemp: Single;
roadTemp: Single;
localAngularVelocity: array[0..2] of Single;
finalFF: Single;
performanceMeter: Single;
engineBrake: Integer;
ersRecoveryLevel: Integer;
ersPowerLevel: Integer;
ersHeatCharging: Integer;
ersIsCharging: Integer;
kersCurrentKJ: Single;
drsAvailable: Integer;
drsEnabled: Integer;
brakeTemp: array[0..3] of Single;
clutch: Single;
tyreTempI: array[0..3] of Single;
tyreTempM: array[0..3] of Single;
tyreTempO: array[0..3] of Single;
isAIControlled: Integer;
tyreContactPoint: array[0..3, 0..2] of Single;
tyreContactNormal: array[0..3, 0..2] of Single;
tyreContactHeading: array[0..3, 0..2] of Single;
brakeBias: Single;
end;
PACSMPhysics = ^TACSMPhysics;
TACSMGraphic = packed record
packetId: Integer;
status: TACStatus;
session: TACSessionType;
currentTime: array[0..14] of WideChar;
lastTime: array[0..14] of WideChar;
bestTime: array[0..14] of WideChar;
split: array[0..14] of WideChar;
completedLaps: Integer;
position: Integer;
iCurrentTime: Integer;
iLastTime: Integer;
iBestTime: Integer;
sessionTimeLeft: Single;
distanceTraveled: Single;
isInPit: Integer;
currentSectorIndex: Integer;
lastSectorTime: Integer;
numberOfLaps: Integer;
tyreCompound: array[0..32] of WideChar;
replayTimeMultiplier: Single;
normalizedCarPosition: Single;
carCoordinates: array[0..2] of Single;
penaltyTime: Single;
flag: TACFlagType;
idealLineOn: Integer;
isInPitLane: Integer;
surfaceGrip: Single;
end;
PACSMGraphic = ^TACSMGraphic;
TACSMStatic = packed record
smVersion: array[0..14] of WideChar;
acVersion: array[0..14] of WideChar;
// Session static info
numberOfSessions: Integer;
numCars: Integer;
carModel: array[0..32] of WideChar;
track: array[0..32] of WideChar;
playerName: array[0..32] of WideChar;
playerSurname: array[0..32] of WideChar;
playerNick: array[0..32] of WideChar;
sectorCount: Integer;
// Car static info
maxTorque: Single;
maxPower: Single;
maxRpm: Integer;
maxFuel: Single;
suspensionMaxTravel: array[0..3] of Single;
tyreRadius: array[0..3] of Single;
maxTurboBoost: Single;
deprecated_1: Single;
deprecated_2: Single;
penaltiesEnabled: Integer;
aidFuelRate: Single;
aidTireRate: Single;
aidMechanicalDamage: Single;
aidAllowTyreBlankets: Integer;
aidStability: Single;
aidAutoClutch: Integer;
aidAutoBlip: Integer;
hasDRS: Integer;
hasERS: Integer;
hasKERS: Integer;
kersMaxJ: Single;
engineBrakeSettingsCount: Integer;
ersPowerControllerCount: Integer;
trackSPlineLength: Single;
trackConfiguration: array[0..32] of WideChar;
ersMaxJ: Single;
end;
PACSMStatic = ^TACSMStatic;
const
ACSM_PHYSICS = 'Local\acpmf_physics';
ACSM_GRAPHICS = 'Local\acpmf_graphics';
ACSM_STATIC = 'Local\acpmf_static';
type
IAssettoCorsaSharedMemory = interface
['{D7C0E678-CB11-4C34-81EB-4AAD5737C44F}']
function GetPhysics(out APhysics: TACSMPhysics): Boolean;
function GetGraphic(out AGraphic: TACSMGraphic): Boolean;
function GetStatic(out AStatic: TACSMStatic): Boolean;
end;
function GetAssettoCorsaSharedMemory(): IAssettoCorsaSharedMemory;
implementation
uses
WinApi.Windows, System.SysUtils, System.Classes;
type
TACSMMapping = record
Handle: THandle;
Buffer: Pointer;
end;
TAssettoCorsaSharedMemory = class(TInterfacedObject, IAssettoCorsaSharedMemory)
private
FPhysicsMapping: TACSMMapping;
FGraphicMapping: TACSMMapping;
FStaticMapping: TACSMMapping;
protected
function OpenMapping(const AName: string; var AMapping: TACSMMapping; ASize: Integer): Boolean;
procedure CloseMapping(var AMapping: TACSMMapping);
public
destructor Destroy; override;
{ IACSM }
function GetPhysics(out APhysics: TACSMPhysics): Boolean;
function GetGraphic(out AGraphic: TACSMGraphic): Boolean;
function GetStatic(out AStatic: TACSMStatic): Boolean;
end;
function GetAssettoCorsaSharedMemory(): IAssettoCorsaSharedMemory;
begin
Result := TAssettoCorsaSharedMemory.Create;
end;
{ TACSM }
destructor TAssettoCorsaSharedMemory.Destroy;
begin
CloseMapping(FPhysicsMapping);
CloseMapping(FGraphicMapping);
CloseMapping(FStaticMapping);
inherited;
end;
function TAssettoCorsaSharedMemory.GetPhysics(out APhysics: TACSMPhysics): Boolean;
begin
Result := OpenMapping(ACSM_PHYSICS, FPhysicsMapping, SizeOf(TACSMPhysics));
if Result then
APhysics := PACSMPhysics(FPhysicsMapping.Buffer)^;
end;
function TAssettoCorsaSharedMemory.GetGraphic(out AGraphic: TACSMGraphic): Boolean;
begin
Result := OpenMapping(ACSM_GRAPHICS, FGraphicMapping, SizeOf(TACSMGraphic));
if Result then
AGraphic := PACSMGraphic(FGraphicMapping.Buffer)^;
end;
function TAssettoCorsaSharedMemory.GetStatic(out AStatic: TACSMStatic): Boolean;
begin
Result := OpenMapping(ACSM_STATIC, FStaticMapping, SizeOf(TACSMStatic));
if Result then
AStatic := PACSMStatic(FStaticMapping.Buffer)^;
end;
function TAssettoCorsaSharedMemory.OpenMapping(const AName: string; var AMapping: TACSMMapping; ASize: Integer): Boolean;
var
handle: THandle;
buffer: Pointer;
begin
if AMapping.Handle <> 0 then
begin
Result := True;
exit;
end;
Result := False;
handle := OpenFileMapping(FILE_MAP_READ, False, PChar(AName));
if handle = 0 then
Exit;
buffer := MapViewOfFile(handle, FILE_MAP_READ, 0, 0, ASize);
if Assigned(buffer) then
begin
AMapping.Handle := handle;
AMapping.Buffer := buffer;
Result := True;
end else
begin
CloseHandle(handle);
RaiseLastOSError;
end;
end;
procedure TAssettoCorsaSharedMemory.CloseMapping(var AMapping: TACSMMapping);
begin
if AMapping.Handle <> 0 then
begin
UnmapViewOfFile(AMapping.Buffer);
CloseHandle(AMapping.Handle);
end;
end;
end.