334 lines
7.6 KiB
ObjectPascal
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.
|