Thrustmaster F488 challenge Add On USB Device Capabilities
15 RPM LED
Buttons Mapping
Functions
init()
getmodule()
terminate()
getdeviceinfo()
setrpmled()
showme() or sendreport()
setbrightness()
setwheelangle()
startinputlistener()
stopinputlistener()
getinputdata()
Initialization
init() function
init() initialize the device extension
thrustmaster.init()
getmodule() function
getmodule() is used to register the module with zCube core engine (included in zCube runtime app or z3engine DLL)
both functions init() and getmodule() are required to initialize zCube core engine, see the example below.
thrustmaster.getmodule()
Example To Initialize the Thrustmaster device (z3thrustmaster device extension)
-- load core engine and create the global z3e instance,
-- if not already created by zCube Runtime
if z3e == nil then z3e = require("z3engine") end
-- load device extension and create the thrustmaster instance
local thrustmaster = require("z3thrustmaster")
-- init core
z3e.init()
-- init thrustmaster device
if thrustmaster.init() then
-- register main module
z3e.mainmodule(thrustmaster.getmodule())
-- your script here
-- end of script
thrustmaster.terminate()
end
terminate() function
Use terminate() when you no longer need the extension just before quitting or at the end of script.
This function closes the win32 COM library, stop listening inputs and unloads all services loaded by the extension if needed. It is mandatory to call it with z3thrustmaster device extension to cleanup COM library.
-- end of script
thrustmaster.terminate()
getdeviceinfo(selector) function
get device information and capabilities
-- SELECTOR STRING
-- ---------------------------------------------------------------------------
--[[
"version"
]]
-- return version as string
-- example:
local z3dll_vers = thrustmaster.getdeviceinfo("version")
--[[
"name"
]]
-- return name of extension as string
-- example:
local device_name = thrustmaster.getdeviceinfo("name")
--[[
"type"
]]
-- return the class number of the device (see the device type class)
-- example:
local class_num = thrustmaster.getdeviceinfo("type")
--[[
"ticks"
]]
-- return number of ticks elapsed since PC startup
-- example:
-- if thrustmaster.getdeviceinfo("ticks") > old_tick then print("time elapsed!") end
-- DEVICE CAPABILITIES
-- ---------------------------------------------------------------------------
--[[
"panel count"
]]
-- return number of digits panels supported by the device 0 or 1 or 2
-- example:
local max_panels = thrustmaster.getdeviceinfo("panel count")
--[[
"digits"
]]
-- return the number of digits in each panel 6 or 4 or 3, 0 if not supported
-- example:
local num_digits = thrustmaster.getdeviceinfo("digits")
--[[
"gear"
]]
-- return 1 if central gear digit is present, 0 if not supported
-- example:
local isGearPresent = thrustmaster.getdeviceinfo("gear")
--[[
"max rpm led"
]]
-- return the max number of RPM LED allowed, 0 if not supported
-- example:
local max_rpm_leds = thrustmaster.getdeviceinfo("max rpm led")
--[[
"max warning led"
]]
-- return the max number of external LED allowed, 0 if not supported
-- example:
local max_warn_leds = thrustmaster.getdeviceinfo("max warning led")
--[[
"max external led"
]]
-- return the max number of external LED allowed, 0 if not supported
-- example:
local max_ext_leds = thrustmaster.getdeviceinfo("max external led")
--[[
"product id"
]]
-- return the max number of external LED allowed, 0 if not supported
-- example:
local prod_id = thrustmaster.getdeviceinfo("product id")
--[[
"vendor id"
]]
-- return the max number of external LED allowed, 0 if not supported
-- example:
local vend_id = thrustmaster.getdeviceinfo("vendor id")
--[[
"brightness"
]]
-- return the max brightness value of your device, 0 if not supported
-- example:
local max_brightness = thrustmaster.getdeviceinfo("brightness")
--[[
"max wheel angle"
]]
or ["max dor"]
-- return max degrees of rotation (DOR) of your steering wheel (i.e. 900) or 0 if this is unsupported
-- example:
local max_dor = thrustmaster.getdeviceinfo("max wheel angle")
--[[
"min wheel angle"
]]
or ["min dor"]
-- return the minimum degrees of rotation (DOR) of your steering wheel (i.e. 40) or 0 if this is unsupported
-- example:
local min_dor = thrustmaster.getdeviceinfo("min wheel angle")
--[[
"wheel angle"
]]
or ["dor"]
-- return the current degrees of rotation (DOR) of your steering wheel (i.e. 40) or 0 if this is unsupported
-- example:
local current_dor = thrustmaster.getdeviceinfo("wheel angle")
--[[
"analog"
]]
-- return number of axes supported or 0
-- example:
local ax_count = thrustmaster.getdeviceinfo("analog")
--[[
"digital"
]]
-- return number of buttons supported or 0
-- example:
local btn_count = thrustmaster.getdeviceinfo("digital")
setrpmled(integer, integer) function
toggle the state of one RPM LED, param 1 is the index of the LED and param 2 is the state of LED 0 (OFF) or 1 (ON). Use getdeviceinfo(“max rpm led”) to get the maximum number of RPM led of your device.
-- initialization
if z3e == nil then z3e = require("z3engine") end
z3e.init()
local thrustmaster = require "z3thrustmaster"
if thrustmaster.init() then
-- register main module
z3e.mainmodule(thrustmaster.getmodule())
-- get the number of RPM LED
local max_rpm_leds = thrustmaster.getdeviceinfo("max rpm led")
-- loop forward and backward to lit up/down each LED
fori=1,max_rpm_leds do
-- turn on
thrustmaster.setrpmled(i,1)
thrustmaster.showme()
z3e.sleep(50)
end
fori=max_rpm_leds,1,-1 do
-- turn off
thrustmaster.setrpmled(i,0)
thrustmaster.showme()
z3e.sleep(50)
end
end
-- end of script
thrustmaster.terminate()
showme() function
show the result onto your device (send the usb report)
fori=1,6 do
thrustmaster.setwarningled(i,0)
thrustmaster.showme()
z3e.sleep(200)
end
sendreport() function
same as showme() function
fori=1,6 do
thrustmaster.setwarningled(i,0)
thrustmaster.sendreport()
z3e.sleep(200)
end
setbrightness(integer) function
set the britghtness of your device (LED and Digit)
if z3e == nil then z3e = require("z3engine") end
z3e.init()
local thrustmaster= require "z3thrustmaster"
if thrustmaster.init() then
-- register main module
z3e.mainmodule(thrustmaster.getmodule())
-- brightness
local max_brightness = thrustmaster.getdeviceinfo("brightness")
if max_brightness >=100 then
thrustmaster.setbrightness(100) end
end
end
setwheelangle(integer) function
set the wheel angle or DOR of your steering wheel (degrees of rotation maximum). Use getdeviceinfo(“max wheel angle”), getdeviceinfo(“min wheel angle”) to get the wheel angle capabilities of your device.
-- ---------------------------------------------------
-- test steering wheel angle
-- this example uses the zCube UI API of the z3 runtime to display
-- a dialog asking the wheel angle to set
-- degrees of rotation (DOR) or wheel andgle supported?
-- return maxt wheel angle otherwise nil or 0 if not supported
local max_rotation = dev.getdeviceinfo("max wheel angle")
if max_rotation == nil then max_rotation = 0 end
if isZ3Runtime and max_rotation>0 then
-- get the min wheel angle value
local min_rotation = dev.getdeviceinfo("min wheel angle")
-- get current wheel angle value
local current_dor = dev.getdeviceinfo("wheel angle")
-- setup the dialog
local result = z3e.z3settingsbox("create", "Change Wheel Angle (DOR)", 210, 80)
if result == 0 then
-- selector "okbutton"
-- params (minimum 2): left, top [, width=50, height=14]
z3e.z3settingsbox("okbutton", 90, 54)
-- selector "cancelbutton"
-- params (minimum 2): left, top [, width=50, height=14]
z3e.z3settingsbox("cancelbutton", 145, 54)
-- edit number with 400 default value
local id_control1 = z3e.z3settingsbox("editnumber"
, "Enter Wheel Anngle from "..min_rotation.." to "..max_rotation
, 130, 24, min_rotation, max_rotation, current_dor )
-- selector "domodal" or "showdialog" to show the dialog
-- params: id of controls
-- return = -1 (fist param) if canceled and fill all params if OK
local param1 = z3e.z3settingsbox("domodal", id_control1)
-- result
-- before apply, check result, is value changed and if in correct range
-- convert string to number
local dor = param1+0
if dor ~= 0 and dor ~= current_dor
and dor>=min_rotation and dor<=max_rotation then
dev.setdor(dor)
end
end
end
startinputlistener() function
start the control input (button or axis) detection of your device.
thrustmaster.startinputlistener()
stopinputlistener() function
stop the detection of control input (button or axis).
thrustmaster.stopinputlistener()
deviceType, ctrlType, ctrlIndex, value, isNew = getinputdata() function
get button pressed or axis value information.
Return
the device type
input type button (1) or axis / switch (0)
index of button pressed or axis triggered
value is the current value of axis or button down >0; button up = 0
isNew is true if this is a new input event
use startinputlistener() function before polling inputs state with getinputdata()
-- getinputdata example
-- getting button pressed while LED
-- and digits are updated on the display
if z3e == nil then z3e = require("z3engine") end
-- device
local thrustmaster = require("z3thrustmaster")
-- init z³ engine
z3e.init()
if thrustmaster.init() == true then
-- register main module
z3e.mainmodule(thrustmaster.getmodule())
local max_rpm_leds=thrustmaster.getdeviceinfo("max rpm led")
co = coroutine.create( function ()
for i = 0, max_rpm_leds do
-- print("LED:", i)
thrustmaster.setrpmled(i, 1) -- lit up led
thrustmaster.sendreport()
z3e.sleep(250)
coroutine.yield()
end
for i = 0, max_rpm_leds do
-- print("LED:", max_rpm_leds-i)
thrustmaster.setrpmled(max_rpm_leds-i, 0)
thrustmaster.sendreport()
z3e.sleep(250)
coroutine.yield()
end
isRunning = false
end)
isRunning = true
thrustmaster.startinputlistener()
-- main loop
while isRunning and z3e.getinfo("is running") do
-- call main function
coroutine.resume(co)
-- get buttons, switches, axes status
deviceType, ctrlType, ctrlPos, value, isNew = thrustmaster.getinputdata()
-- is it a new input control report
if isNew then
print(deviceType, ctrlType, ctrlIndex, value, isNew)
if ctrlType == 1 and ctrlIndex==2 then
-- lit up warning LED 1 if button 2 is pressed
thrustmaster.setwarningled(1,value)
thrustmaster.sendreport()
end
end
z3e.sleep(1)
end
end
-- end of script
thrustmaster.terminate()
zCube Thrustmaster Full Example
-- #####################################################################
-- # sample script to test device
-- # for zCUBE Engine Lua extension module
-- # Copyright (c)2022 by Zappadoc - All Rights Reserved.
-- # https://www.eksimracing.org
-- This source code, module, lib and all information, data, and algorithms
-- associated with it are subject to change without notice.
-- Change history:
-- 2022.01.30: created - zappadoc
-- License
-- https://www.eksimracing.org/terms-conditions
-- DISCLAIMER:
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- All product names are trademarks or registered trademarks of their respective holders.
-- #####################################################################
if z3e == nil then z3e = require("z3engine") end
z3e.init()
-- replace z3thrustmaster extension to your display device
local dev = require("z3thrustmaster")
if dev.init() then
-- register main module
z3e.mainmodule(dev.getmodule())
print("Start Testing...")
dev.startinputlistener()
-- ---------------------------------------------------
-- constants
local z3vers = z3e.getinfo("version")
-- is UI functions present?
local z3api = z3e.getinfo("engine")
isZ3Runtime = false
if z3api == "extended" then isZ3Runtime = true end
-- device capabilities
local dev_name = dev.getdeviceinfo("name")
local dev_vendid = dev.getdeviceinfo("vendor id")
local dev_prodid = dev.getdeviceinfo("product id")
-- inputs
local btns = dev.getdeviceinfo("digital")
local sw = dev.getdeviceinfo("analog")
-- LED
local max_rpm_leds = dev.getdeviceinfo("max rpm led")
local max_warn_leds = dev.getdeviceinfo("max warning led")
local max_ext_leds = dev.getdeviceinfo("max external led")
-- brigthness
local max_brightness = dev.getdeviceinfo("brightness")
-- gear and panels
local isGearPresent = dev.getdeviceinfo("gear")
local max_digits = 0
if dev.getdeviceinfo("panel count") >= 1 then max_digits = dev.getdeviceinfo("digits") end
-- ---------------------------------------------------
-- test steering wheel angle
-- degrees of rotation (DOR) or wheel andgle supported?
-- return nil or 0 if not supported
local max_rotation = dev.getdeviceinfo("max wheel angle")
if max_rotation == nil then max_rotation = 0 end
-- example set the rotation to 400°
if isZ3Runtime and max_rotation>0 then
local min_rotation = dev.getdeviceinfo("min wheel angle")
local current_dor = dev.getdeviceinfo("wheel angle")
local result = z3e.z3settingsbox("create", "Change Wheel Angle (DOR)", 210, 80)
if result == 0 then
-- selector "okbutton"
-- params (minimum 2): left, top [, width=50, height=14]
z3e.z3settingsbox("okbutton", 90, 54)
-- selector "cancelbutton"
-- params (minimum 2): left, top [, width=50, height=14]
z3e.z3settingsbox("cancelbutton", 145, 54)
-- edit number with 400 default value
local id_control1 = z3e.z3settingsbox("editnumber", "Enter Wheel Anngle from "..min_rotation.." to "..max_rotation, 130, 24, min_rotation, max_rotation, current_dor )
-- selector "domodal" or "showdialog" to show the dialog
-- params: id of controls
-- return = -1 (fist param) if canceled and fill all params if OK
local param1 = z3e.z3settingsbox("domodal", id_control1)
-- result
-- before apply, check result, is value changed and if in correct range
local dor = param1+0
if dor ~= 0 and dor ~= current_dor and dor>=min_rotation and dor<=max_rotation then
dev.setdor(dor)
end
end
end
-- ---------------------------------------------------
-- Local functions
--
local function checkCharsTable()
if isGearPresent > 0 then
for i=1,254 do
dev.setgear(string.char(i))
dev.showme()
print(i)
os.execute("pause") -- work best with Windows console not in VS Code
end
end
end
-- checkCharsTable() -- explore the chars table of your device
-- ---------------------------------------------------
-- toggle LED functions
local function toggleLeds(type, state)
if max_rpm_leds>0 and type == 1 then
for i=1,max_rpm_leds do
dev.setrpmled(i, state)
end
end
if max_warn_leds>0 and type == 2 then
for i=1,max_warn_leds do
dev.setrpmled(i, state)
end
end
if max_ext_leds>0 and type == 3 then
for i=1,max_ext_leds do
dev.setrpmled(i, state)
end
end
dev.showme()
end
-- toggle RPM LED
local function toggleRPMLeds(state)
toggleLeds(1, state)
end
-- toggle Warning LED
local function toggleWarnLeds(state)
toggleLeds(2, state)
end
-- toggle external LED
local function toggleExtLeds(state)
toggleLeds(3, state)
end
-- toggle external LED
local function toggleAllLeds(state)
toggleRPMLeds(0)
toggleWarnLeds(0)
toggleExtLeds(0)
end
-- ---------------------------------------------------
-- empty gear, digits and turn off LED
local function clearDisplay()
if isGearPresent > 0 then dev.setgear(" ",false) end
if max_digits==3 then dev.setcentralpanel(" ") end
if max_digits==4 then dev.setleftpanel(" ") dev.setrightpanel(" ") end
if max_digits==6 then dev.setleftpanel(" ") dev.setrightpanel(" ") end
toggleAllLeds(0)
dev.showme()
end
-- ---------------------------------------------------
-- init brightness
if max_brightness >=100 then
if string.find(dev_name, "z3sli", 1) ~= nil then
dev.setbrightness(200)
else dev.setbrightness(100) end
end
-- init gear
if isGearPresent > 0 then
dev.setgear("-")
dev.showme()
end
for i=1,max_rpm_leds do
dev.setrpmled(i,1)
if isGearPresent > 0 then
if(i>9) then
dev.setgear(i-10,true)
else
dev.setgear(i)
end
end
dev.showme()
z3e.sleep(200)
end
for i=max_rpm_leds,1,-1 do
dev.setrpmled(i,0)
if isGearPresent > 0 then
if(i>9) then
dev.setgear(i-10,true)
else
dev.setgear(i)
end
end
dev.showme()
z3e.sleep(200)
end
-- turn on RPM LED
toggleRPMLeds(1)
z3e.sleep(100)
-- init panels
if max_digits==3 then
dev.setcentralpanel("888")
elseif max_digits==4 then
dev.setleftpanel("8888")
dev.setrightpanel("-Z3-")
elseif max_digits==6 then
dev.setleftpanel("888888")
dev.setrightpanel(" ZCubE")
end
dev.showme()
z3e.sleep(250)
-- brightness stuff
if max_brightness>0 then
dev.setbrightness(max_brightness)
if isGearPresent > 0 then
dev.setgear("_",true)
dev.showme()
end
-- decrease
print("Decrease Brightness...")
for i=max_brightness,1,-1 do
if max_digits==3 then dev.setcentralpanel(string.format("%03d",i)) dev.showme()
elseif max_digits==4 then dev.setleftpanel(string.format("%03d ",i)) dev.setrightpanel("DOWN") dev.showme()
elseif max_digits==6 then dev.setleftpanel(string.format(" %03d ",i)) dev.setrightpanel("888888") dev.showme()
else print("Decrease Brightness..."..i) end
dev.setbrightness(i)
z3e.sleep(10)
end
z3e.sleep(1000)
if isGearPresent > 0 then
if string.find(dev_name, "z3sli", 1) ~= nil then dev.setgear("\126",true) -- bodnar racing display only
else dev.setgear("-",true) end
dev.showme()
end
-- increase
print("Increase Brightness...")
for i=1,max_brightness do
if max_digits==3 then dev.setcentralpanel(string.format("%03d",i)) dev.showme()
elseif max_digits==4 then dev.setleftpanel(string.format("%03d ",i)) dev.setrightpanel(" UP ") dev.showme()
elseif max_digits==6 then dev.setleftpanel(string.format(" %03d ",i)) dev.setrightpanel("--UP--") dev.showme()
else print("Decrease Brightness..."..i) end
dev.setbrightness(i)
z3e.sleep(10)
end
if string.find(dev_name, "z3sli", 1) ~= nil then
dev.setbrightness(200)
else dev.setbrightness(100) end
clearDisplay()
end
-- warning/marshal LED
if max_warn_leds > 0 then
print("Warning LED...")
local mwl = (max_warn_leds / 2)
for i=1,mwl do
dev.setwarningled(i, 1)
dev.setwarningled((max_warn_leds+1)-i, 1)
dev.showme()
z3e.sleep(400)
end
for i=1,mwl do
dev.setwarningled((mwl+1)-i, 0)
dev.setwarningled(mwl+i, 0)
dev.showme()
z3e.sleep(400)
end
end
-- external LED
if max_ext_leds > 0 then
print("External LED...")
for i=1,max_ext_leds do
dev.setexternalled(i, 1)
dev.showme()
z3e.sleep(400)
end
for i=max_ext_leds,1,-1 do
dev.setexternalled(i, 0)
dev.showme()
z3e.sleep(400)
end
end
-- turn off ALL LED
toggleAllLeds(0)
else
print("Device Error!\n- device not connected (connect your device)\n- or license not found (register your device)\n- or the default device (SLIPRO) is not found (change the script with the correct zCube extension!")
end
-- notify device extension
dev.terminate()
print("Test Done!")
Minimal Script
-- minimal script for Thrustmaster F488 Chalenge Ed.
if z3e == nil then local z3e = require(“z3engine”) end
local dev = require("z3thrustmaster")
-- init core
z3e.init()
-- init device
if dev.init() then
-- register main module
z3e.mainmodule(dev.getmodule())
-- your custom script here
dev.terminate()
end
Minimal Event Driven Script (zCube Runtime)
-- minimal script for Thrustmaster F488 Challenge Edition device
if z3e == nil then local z3e = require(“z3engine”) end
local dev = require("z3thrustmaster")
-- init core
z3e.init()
local isRunning = false
function z3open()
-- z3open even at startup
-- init device
if dev.init() then
-- register main module
z3e.mainmodule(dev.getmodule())
isRunning = true
-- your custom script here
else
print("Device Error!\n- device not connected (connect your device)\n- or license not found (register your device)!")
end
end
function z3loop()
-- your main loop
if isRunning then
-- your custom script here
end
end
function z3close()
-- z3close event when app quit
isRunning = false
-- your custom script here
dev.terminate()
end