; For demonstration purposes let’s replace interior rear view mirror with a mirror with extra features:
; Hide original mirror mesh
[SHADER_REPLACEMENT_...]
MESHES = Extra_Mirror_SUB1
LAYER = 10
ACTIVE = $" read('csp/version', 0) >= 1709 "
; Create a new mirror mesh
[INCLUDE: common/displays.ini]
[DisplayShape]
MeshName = __mirror_display_mesh
ScreenScale = 256
ScreenAspectRatio = 0.5
MatrixType = TN
TreatTextureAsHDR = 1
P1 = -0.033037, 0.853015, 1.069863 ; four corners of new mirror
P2 = -0.109149, 0.844854, 1.013162 ; hold alt and click with objects inspector to get in-car coordinate
P3 = -0.109451, 0.773587, 1.023871 ; pro tip: with 0.1.76, hold Shift to get six digits after the delimiter
P4 = -0.033524, 0.781760, 1.080841
; And create dynamic texture. New mirror is going to have two modes, mirror with overlay and ABS/TC/brake bias control
[SCRIPTABLE_DISPLAY_...]
MESHES = __mirror_display_mesh
RESOLUTION = 512, 512
DISPLAY_POS = 0, 0
DISPLAY_SIZE = 512, 512
SKIP_FRAMES = 0 ; high refresh rate, it’s a mirror in a racing car after all (don’t use it for other displays though)
SCRIPT = '
-- Buttons on display
local displayMesh = display.interactiveMesh{ mesh = "Extra_Mirror_SUB0", resolution = vec2(512, 128) }
local btnModeSwitch = displayMesh.clicked(vec2(200, 7), vec2(45, 26))
local btnMenu = displayMesh.clicked(vec2(254, 7), vec2(45, 26))
local btnMinus = displayMesh.clicked(vec2(308, 7), vec2(45, 26), 0.15)
local btnPlus = displayMesh.clicked(vec2(363, 7), vec2(45, 26), 0.15)
local btnFasterMinus = displayMesh.clicked(vec2(308, 7), vec2(45, 26), 0.05)
local btnFasterPlus = displayMesh.clicked(vec2(363, 7), vec2(45, 26), 0.05)
local btnTurnOff = displayMesh.clicked(vec2(418, 7), vec2(45, 26))
-- Each mode will be drawn by its own function. Here is a function for mirror mode:
local brightnessMult = 1
local selectedOverlay = 1
local updateDelay = 0
local overlayText = ""
function modeMirror(dt)
-- Enable real mirror in this mode
ac.pauseRealMirror(1, false)
-- Firsly, draw mirror texture across whole thing
display.mirror{
pos = vec2(),
size = vec2(512, 512),
color = rgb(brightnessMult, brightnessMult, brightnessMult),
mirrorIndex = 1, -- for rear mirrors, specifices position of which mirror to use. 0 is for the leftmost
uvStart = vec2(0.343, 0), -- these coords are used only if real mirrors are disabled
uvEnd = vec2(0.658, 1) -- good thing to switch real mirrors on and off to make sure it all matches
}
-- And let’s just put current speed in the top left corner
if updateDelay <= 0 then
updateDelay = 0.5
overlayText = selectedOverlay == 1 and string.format("%.1f km/h", car.speedKmh)
or selectedOverlay == 2 and string.format("%.1f l", car.fuel)
or selectedOverlay == 3 and string.format("%.1f C", car.waterTemperature)
else
updateDelay = updateDelay - dt
end
display.text{
text = overlayText,
pos = vec2(40, 408),
color = rgb(0, 0, 0),
letter = vec2(24, 64),
font = "aria",
width = 432,
alignment = 1,
spacing = -6
}
if btnPlus() then brightnessMult = math.min(brightnessMult + 0.1, 1.2) end
if btnMinus() then brightnessMult = math.max(brightnessMult - 0.1, 0) end
if btnMenu() then
selectedOverlay = selectedOverlay + 1
if selectedOverlay == 4 then
selectedOverlay = 1
end
end
end
-- Second mode for customizing ABS and brake bias
local selectedItem = 1
function modeConfig(dt)
-- Disable real mirror in this mode
ac.pauseRealMirror(1, true)
local colorSelected = rgb(0, 0, 0)
local colorNotSelected = rgb(1, 1, 1)
if btnMenu() then
selectedItem = selectedItem == 1 and 2 or 1
end
display.rect{
pos = vec2(0, 40 + (selectedItem - 1) * 140),
size = vec2(512, 140),
color = rgb(0.2, 0.2, 0.2)
}
display.text{
text = car.absMode == 0 and "ABS: disabled" or string.format("ABS: %d/12", car.absMode),
pos = vec2(40, 70),
letter = vec2(24, 64),
color = rgb(1, 1, 1),
font = "aria",
}
display.horizontalBar{
pos = vec2(40, 70+68),
size = vec2(432, 8),
delta = 6,
activeColor = rgb(1, 1, 1),
inactiveColor = rgb(0.2, 0, 0),
total = 12,
active = car.absMode
}
local range = car.brakesBiasLimitUp - car.brakesBiasLimitDown
display.text{
text = string.format("Brake bias: %.1f%%", car.brakeBias * 100),
pos = vec2(40, 210),
letter = vec2(24, 64),
color = rgb(1, 1, 1),
font = "aria",
}
display.horizontalBar{
pos = vec2(40, 210+68),
size = vec2(432, 8),
delta = 1,
activeColor = rgb(1, 1, 1),
inactiveColor = rgb(0.2, 0, 0),
total = math.ceil(range / car.brakesBiasStep),
active = math.ceil((car.brakeBias - car.brakesBiasLimitDown) / car.brakesBiasStep)
}
if selectedItem == 1 then
if btnMinus() and car.absMode > 0 then ac.setABS(car.absMode - 1) end
if btnPlus() then ac.setABS(car.absMode + 1) end
else
if btnFasterMinus() then ac.setBrakeBias(car.brakeBias - car.brakesBiasStep) end
if btnFasterPlus() then ac.setBrakeBias(car.brakeBias + car.brakesBiasStep) end
end
end
-- Storing current mode in variable
local currentMode = modeMirror
local isTurnedOff = false
function update(dt)
if btnModeSwitch() then
currentMode = currentMode == modeMirror and modeConfig or modeMirror
isTurnedOff = false
end
if btnTurnOff() then
isTurnedOff = not isTurnedOff
end
if isTurnedOff then
ac.pauseRealMirror(1, true)
currentMode = modeMirror
else
currentMode(dt)
end
end'