CSP/Python Apps/New functions
CSP adds some new functions for Python apps, and here is the full list of them with argument names and return types. Each time function requires a vector argument, such as vec2, vec3 or vec4, you can pass either a corresponding amount of numbers directly, or pass them packed in a tuple.
See also official and inofficial python docs: https://assettocorsamods.net/threads/doc-python-doc.59/ Shared memory reference: https://assettocorsamods.net/threads/doc-shared-memory-reference.58/ A getting started guide: https://assettocorsamods.net/threads/getting-started-with-ac-app-developing.716/#post-2892
# Track controls:
def ac.ext_applyTrackConfig(config: str, flags: int):
# flags: 1<<0 for restore conditions, 1<<1 for partial update
def ac.ext_setTrackConditionInput(conditionName: str, value: float):
# Mirrors (requires Real Mirror enabled):
def ac.ext_mirrorLeft():
def ac.ext_mirrorRight():
def ac.ext_mirrorUp():
def ac.ext_mirrorDown():
def ac.ext_mirrorFovUp():
def ac.ext_mirrorFovDown():
def ac.ext_mirrorAspectRatioUp():
def ac.ext_mirrorAspectRatioDown():
def ac.ext_mirrorToggleMon():
def ac.ext_mirrorPrev():
def ac.ext_mirrorNext():
def ac.ext_mirrorCurrent() -> int:
def ac.ext_mirrorParams() -> (isMonitor: bool, fov: float, aspectMult: float, role: int, index: int):
# Flipping mirrors (available since 0.1.76, 1 for horizontal flip, 2 for vertical, 3 for both):
def ac.ext_mirrorGetFlip() -> int:
def ac.ext_mirrorSetFlip(flip: int) -> int:
# G27 LEDs:
def ac.ext_isG27Available() -> bool:
def ac.ext_setG27Thresholds(minRpm: float, maxRpm: float):
# General functions:
def ac.ext_patchVersion() -> str:
def ac.ext_patchVersionCode() -> int:
def ac.ext_weatherDebugText() -> str:
def ac.ext_setStrictMode(): # activates strict mode with better error reporting, recommended
def ac.ext_pauseWhenHidden(): # allows app to pause when itβs not active
def ac.ext_isAnyAppVisible() -> bool:
def ac.ext_isAppVisible(appName: str) -> bool:
def ac.ext_perfBegin(key: str?):
# starts measuring time
def ac.ext_perfEnd(key: str?) -> float:
# stops measuring time, returns time in milliseconds, shows it in Python Debug app
def ac.ext_loadIniFileAsJson(filename: str, includeDir0: str?, includeDir1: str?, includeDir2: str?) -> str:
# question mark means parameter is optional
def ac.ext_parseIniAsJson(iniData: str) -> str:
def ac.ext_getBaseAltitude() -> float:
def ac.ext_getAltitude(car: int) -> float:
def ac.ext_setDriverVisible(visible: bool, carIndex: int):
def ac.ext_setDoorsOpen(doorOpen: bool, carIndex: int):
def ac.ext_isExtendedPhysics(car: int) -> bool:
def ac.ext_getTyreGrain(car: int, tyre: int) -> float:
def ac.ext_getHeadlights(car: int) -> bool:
def ac.ext_getHandbrake(car: int) -> float:
def ac.ext_getTyreIsHot(car: int, tyre: int) -> bool:
def ac.ext_getTyreTempMult(car: int, tyre: int) -> float:
def ac.ext_getTyreBlister(car: int, tyre: int) -> float:
def ac.ext_getTyreFlatSpot(car: int, tyre: int) -> float:
def ac.ext_getTyreVirtualKM(car: int, tyre: int) -> float:
def ac.ext_getTyreCarcassTemp(car: int, tyre: int) -> float:
def ac.ext_getSuspensionTravel(corner: int) -> float: # ! broken until and including csp 0.1.77-prev80
def ac.ext_getDamperTravel(corner: int) -> float: # ! broken until and including csp 0.1.77-prev80
def ac.ext_getTcSetting1(car: int) -> int:
def ac.ext_getTcSetting2() -> int:
def ac.ext_getAeroSpeed() -> float:
def ac.ext_getDrag() -> float:
def ac.ext_getDownforce(selection: int) -> float:
def ac.ext_getStaticDeflection() -> float:
def ac.ext_getCurrentTorque() -> float:
def ac.ext_getBrakeCoreTemp(corner: int) -> float:
def ac.ext_getSteerTorque() -> float:
def ac.ext_getBrakeTorque(corner: int) -> float:
def ac.ext_getTireLoadedRadius(corner: int) -> float:
def ac.ext_isTripleScreenCamera() -> bool:
def ac.ext_isInVR() -> bool:
def ac.ext_getCameraDirection() -> vec3: # vec3 is a tuple with 3 elements
def ac.ext_getCameraPosition() -> vec3:
def ac.ext_setCameraPosition(pos: vec3):
def ac.ext_getCameraPositionAxis(axis: int) -> float:
def ac.ext_setCameraPositionAxis(axis: int, value: float):
def ac.ext_setCameraDirection(forward: vec3, up: vec3?):
def ac.ext_getCameraMatrix() -> mat4x4: # mat4x4 is a tuple with 16 elements
def ac.ext_getCameraRollRad() -> float: # rad means result is in radians
def ac.ext_getCameraPitchRad() -> float:
def ac.ext_getCameraYawRad() -> float:
def ac.ext_getCameraFov() -> float:
def ac.ext_setCameraFov(value: float):
def ac.ext_getCameraDofFactor() -> float:
def ac.ext_setCameraDofFactor(value: float):
def ac.ext_getCameraDofFocus() -> float:
def ac.ext_setCameraDofFocus(value: float):
def ac.ext_getCameraClipNear() -> float:
def ac.ext_setCameraClipNear(value: float):
def ac.ext_getCameraClipFar() -> float:
def ac.ext_setCameraClipFar(value: float):
def ac.ext_currentPpFilter() -> str:
def ac.ext_getReplayFrameMS() -> float: # frame time in ms
def ac.ext_getReplayFrames() -> int: # number of recorded frames
def ac.ext_getReplayPosition() -> int: # frame index
def ac.ext_setReplayPosition(frameIndex: int):
def ac.ext_getCurrentCamera() -> int:
def ac.ext_setCurrentCamera(mode: int):
def ac.ext_getCurrentDrivableCamera() -> int:
def ac.ext_setCurrentDrivableCamera(mode: int):
def ac.ext_getTrackCamerasNumber() -> int:
def ac.ext_getCurrentTrackCamera() -> int:
def ac.ext_setCurrentTrackCamera(setIndex: int):
def ac.ext_getAudioVolume() -> float:
def ac.ext_setAudioVolume(volume: float):
def ac.ext_getPreviousSectorTime() -> str:
def ac.ext_getCurrentSector() -> int:
def ac.ext_isButtonPressed(keyIndex: int) -> bool:
def ac.ext_isCtrlPressed() -> bool:
def ac.ext_isAltPressed() -> bool:
def ac.ext_isShiftPressed() -> bool:
def ac.ext_isJoystickButtonPressed(controllerIndex: int, buttonIndex: int) -> bool:
def ac.ext_getJoystickAxisValue(controllerIndex: int, axisIndex: int) -> float:
def ac.ext_getJoystickDpadValue(controllerIndex: int, dpadIndex: int) -> int:
def ac.ext_setClipboardData(text: str):
def ac.ext_isVirtualMirrorForced() -> bool:
def ac.ext_markLapAsSpoiled():
def ac.ext_getCameraPositionRelativeToCar() -> vec3:
def ac.ext_getCompassAngle(direction: vec3) -> float:
# turns direction into heading angle in degrees
def ac.ext_dirname() -> str:
# path to python app folder
def ac.ext_getSplineLength(splineIndex: int) -> float:
# 0 for main spline (so, length of the whole track), 1 for pits spline
def ac.ext_worldToSpline(splineIndex: int, worldPos: vec3) -> float:
def ac.ext_splineToWorld(splineIndex: int, splinePos: float) -> vec3:
def ac.ext_storeLua(key: str, value: float or string):
def ac.ext_loadLua(key: str) -> float or string:
def ac.ext_getStateAbs(carIndex: int) -> int:
def ac.ext_getStateAbsActive(carIndex: int) -> bool:
def ac.ext_getStateTc(carIndex: int) -> int:
def ac.ext_getStateTcActive(carIndex: int) -> bool:
def ac.ext_pauseFsWatching():
def ac.ext_resumeFsWatching():
def ac.ext_resetCar(): # resets car to the road invalidating lap
def ac.ext_takeAStepBack(): # moves car back invalidating lap
def ac.ext_weatherFxActive() -> bool:
def ac.ext_weatherTimeOffset(offset: float) -> bool:
def ac.ext_getWeatherTimeMult() -> float:
def ac.ext_setWeatherTimeMult(value: float):
def ac.ext_isVaoPatchLoaded() -> bool:
def ac.ext_vaoOnly():
def ac.ext_vaoNormalDebug():
def ac.ext_vaoDisable():
def ac.ext_vaoNormal():
def ac.ext_setVaoActive(active: bool):
def ac.ext_getWiperSpeedsNumber() -> int:
def ac.ext_getWiperSpeed() -> int:
def ac.ext_setWiperSpeed(wiperSpeed: int):
def ac.ext_getCameraProj() -> mat4x4:
def ac.ext_getCameraView() -> mat4x4:
def ac.ext_getLightsNum() -> int:
def ac.ext_getCarLightsNum() -> int:
def ac.ext_getTrackLightsNum() -> int:
def ac.ext_getLightsVisible() -> int:
def ac.ext_getCarLightsVisible() -> int:
def ac.ext_getTrackLightsVisible() -> int:
def ac.ext_getLightsMirrorVisible() -> int:
def ac.ext_getCarLightsMirrorVisible() -> int:
def ac.ext_getTrackLightsMirrorVisible() -> int:
def ac.ext_getAmbientMult() -> float:
def ac.ext_getAngleSpeed() -> float:
def ac.ext_debugLights(nameFilter: str, count: int, distance: float, mode: int):
# Extended render functions:
def ac.ext_glSetCullMode(mode: int):
# mode: 0 for front, 1 for back, 2 for no culling, 4 for wireframe, 7 for antialiased wireframe
def ac.ext_glSetBlendMode(mode: int):
# mode: 0 for opaque, 1 for alpha blend, 2 for alpha test, 4 for additive, 5 for multiplicative
def ac.ext_mirrorTexture() -> int:
# returns texture index which can be used the same as ac.createTexture()
def ac.ext_releaseMirrorTexture():
# call it for each call of ac.ext_mirrorTexture() when texture is no longer needed to re-activate
# real mirrors
def ac.ext_createRenderTarget(width: int, height: int, mips: bool) -> int:
# returns texture index, but also this number can be used to draw things to
def ac.ext_clearRenderTarget(rtIndex: int):
def ac.ext_generateMips(rtIndex: int):
def ac.ext_disposeRenderTarget(rtIndex: int):
def ac.ext_bindRenderTarget(rtIndex: int):
# starts drawing into render target
def ac.ext_restoreRenderTarget():
# restores original render target to continue drawing app to
def ac.ext_glSetTexture(textureIndex: int, slotIndex: int):
# binds texture
def ac.ext_glLoadPixelShader(filename: str) -> int:
# loads pixel shader (there is an example at the bottom of this post)
def ac.ext_glSetPixelShader(shaderIndex: int):
# custom shader will be used for further draw calls
def ac.ext_glResetPixelShader():
# reverts to original pixel shader
def ac.ext_glVertexTex(posUV: vec4):
# adds a new vertex with texture coordinates, use with ac.glBegin() and ac.glEnd()
# vec4 is a tuple with four values
def ac.ext_glTexCoord2f(uv: vec2):
# adds texture coordinates to previously added vertex
# vec2 is a tuple with two values
def ac.ext_glFontCreate(font: str, size: float, italic: int, weight: int) -> int:
def ac.ext_glFontColor(fontIndex: int, color: vec4):
def ac.ext_glFontUse(fontIndex: int, text: str, pos: vec2, scale: float, alignment: int):
# uses created font to draw some text
# alignment: 0 for left, 1 for right, 2 for center
Example shader for custom drawing
// Default AC texture samplers bound by default:
SamplerState samPoint : register(s2) {
Filter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};
SamplerState samLinear : register(s5) {
Filter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
struct VS_IN {
float4 PosH : SV_POSITION;
float4 Color : COLOR;
float2 Tex : TEXCOORD;
float3 Tangent : TANGENT;
};
// Regular texture to draw:
Texture2D txDiffuse : register(t0);
// Actual code:
float4 main(VS_IN pin) : SV_TARGET {
return 1 - txDiffuse.Sample(samLinear, pin.Tex); // simple inversion for an example
}