API Game controller examples

Help creating logic scripts for Air Manager Instruments

Moderators: russ, Ralph

Post Reply
Message
Author
JackZ
Posts: 2267
Joined: Mon Feb 22, 2016 1:02 pm

API Game controller examples

#1 Post by JackZ »

Hello All

tried to use for the first time the Controller features of the API to send keypresses to an addon and found somewhat the example given in the Wiki rather confusing

I had to struggle through trial and errors to figure out how to address a specific controller.
I think that the Wiki should be more explicit for that matter.

The current example given affects only ONE callback whatever the controller, so in case of multiple controllers the same button number on different controller is used.

Code: Select all

function callback(type, index, value)
    print("type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

list = game_controller_list()

for k, v in pairs(list) do
    game_controller_add(v, callback)
end
Here's how I understand it (correct me if I am wrong):
Game controller list
game_controller_list String[] The array is a list of strings with all the game controllers. You can use an item in this list for the game_controller_add function.

Example:

Code: Select all

list = game_controller_list()

for k, v in pairs(list) do
    print("List index: "..k.." /Name of the Controller: "..v)
end
---------------------
game_controller_add

Example:

Code: Select all

function callback_controller_0(type, index, value) -- input from the controller 0
    print(list[0]..":type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
 -- insert functions to interact with the sim 
end

function callback_controller_1(type, index, value) -- input from the controller 1
    print(list[1].." :type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
    -- insert functions to interact with the sim 
end

list = game_controller_list()
-- for debug purposes you can uncomment these lines
-- for k, v in pairs(list) do
--     print("List index: "..k.." /Name of the Controller: "..v)
-- end

    game_controller_add("TCA Q-Eng 1&2", callback0) -- new controller added by name
    game_controller_add(list[1], callback1) -- new controller added by list reference
feedback appreciated.
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

SimPassion
Posts: 5340
Joined: Thu Jul 27, 2017 12:22 am

Re: API Game controller examples

#2 Post by SimPassion »

Hi Jacques

at first this :

Code: Select all

--====================================================================================
--								CHECK PURPOSE
--====================================================================================

function callback(type, index, value)
    print("type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

list = game_controller_list()

for k, v in pairs(list) do
	print("index = " .. k .. ", name = " .. v)
    -- game_controller_add(v, callback)
end
give me the following result

INFO - index = 1, name = T-Rudder
INFO - index = 2, name = Throttle - HOTAS Warthog
INFO - index = 3, name = 3Dconnexion KMJ Emulator
INFO - index = 0, name = Joystick - HOTAS Warthog

so if I want to interact with the T-Rudder only, I have to make it in the for ... do loop, the point is to build different callback functions based on each available device, for better separation, if this is expected :

simple snippet based on device name :

Code: Select all

--====================================================================================
--								CHECK PURPOSE
--====================================================================================

function trudder_callback(type, index, value)
    print("type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

list = game_controller_list()

for k, v in pairs(list) do
	-- print("index = " .. k .. ", name = " .. v)

	-- if k == 1 then	-- T-Rudder only
	
	-- or
	
	if v == "T-Rudder" then	-- T-Rudder only
		game_controller_add(v, trudder_callback)
	end
end
based on device index :

Code: Select all

--====================================================================================
--								CHECK PURPOSE
--====================================================================================

function trudder_callback(type, index, value)
    print("type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

list = game_controller_list()

for k, v in pairs(list) do
	-- print("index = " .. k .. ", name = " .. v)

	if k == 1 then	-- T-Rudder only
	
	-- or
	
	-- if v == "T-Rudder" then	-- T-Rudder only
		game_controller_add(v, trudder_callback)
	end
end
Last edited by SimPassion on Sun Apr 30, 2023 3:32 pm, edited 2 times in total.

SimPassion
Posts: 5340
Joined: Thu Jul 27, 2017 12:22 am

Re: API Game controller examples

#3 Post by SimPassion »

I guess something like this would fit :

Code: Select all


--====================================================================================
--								CHECK PURPOSE
--====================================================================================

-- INFO - index = 0, name = Joystick - HOTAS Warthog
-- INFO - index = 1, name = T-Rudder
-- INFO - index = 2, name = Throttle - HOTAS Warthog
-- INFO - index = 3, name = 3Dconnexion KMJ Emulator

str_devname0 = "Joystick - HOTAS Warthog"		-- to be edited as required
str_devname1 = "T-Rudder"				-- to be edited as required
str_devname2 = "Throttle - HOTAS Warthog"		-- to be edited as required
str_devname3 = "3Dconnexion KMJ Emulator"		-- to be edited as required
-- str_devnameN  .../...

list = game_controller_list()

function hwarthogstick_callback(type, index, value)
    print("DEV0 "..str_devname0.." type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

function trudder_callback(type, index, value)
    print("DEV1 "..str_devname1.." type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

function hwarthogthrot_callback(type, index, value)
    print("DEV2 "..str_devname2.." type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

function kmjemul3dconn_callback(type, index, value)
    print("DEV3 "..str_devname3.." type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

for k, v in pairs(list) do
	-- print("index = " .. k .. ", name = " .. v)

	if v ==  str_devname0 then	-- HOTAS Warthog Joystick only
		game_controller_add(v, hwarthogstick_callback)
	end
	if v == str_devname1 then	-- T-Rudder only
		game_controller_add(v, trudder_callback)
	end
	if v == str_devname2 then	-- HOTAS Warthog Throttle only
		game_controller_add(v, hwarthogthrot_callback)
	end
	if v == str_devname3 then	-- 3Dconn. KMJ Emul. only
		game_controller_add(v, kmjemul3dconn_callback)
	end
	-- if k == 0 then	-- HOTAS Warthog Joystick only
		-- game_controller_add(v, hwarthogstick_callback)
	-- end
	-- if k == 1 then	-- T-Rudder only
		-- game_controller_add(v, trudder_callback)
	-- end
	-- if k == 2 then	-- HOTAS Warthog Throttle only
		-- game_controller_add(v, hwarthogthrot_callback)
	-- end
	-- if k == 3 then	-- 3Dconn. KMJ Emul. only
		-- game_controller_add(v, kmjemul3dconn_callback)
	-- end
end
[EDIT1] Corrected callback functions names
[EDIT2] Enhanced for easier usage

This give me the following result :

image.png
Last edited by SimPassion on Sun Apr 30, 2023 3:29 pm, edited 4 times in total.

SimPassion
Posts: 5340
Joined: Thu Jul 27, 2017 12:22 am

Re: API Game controller examples

#4 Post by SimPassion »

FYI, it works in AM 4.1.6 and create this issue in AM 4.2 Beta 10, further it creates a CTD when stopping the instrument :

image.png

JackZ
Posts: 2267
Joined: Mon Feb 22, 2016 1:02 pm

Re: API Game controller examples

#5 Post by JackZ »

Hello @SimPassion

Thanks for diving into this.Your method works.

I found out that if you change/swap the physical USB ports the devices names are likely to change/get swapped. So it is strongly recommended to use the real name of the controller in the game_controller_add(), otherwise, the callbacks will be reversed/wrongly assigned.

Definitely think that in this very case, use of pairs(list) function is NOT the way to go for reliabilty but instead use of named controllers, unless you add the kind of code you suggested, but with alot of if/else.

So something like this will always work:

Code: Select all

function callback0(type, index, value)
    print("T.A320 pilot".." :type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end

function callback1(type, index, value)
    print("TCA Q-Eng 1&2".." :type = " .. type .. ", index = " .. index .. ", value = " .. tostring(value))
end


list = game_controller_list()
---------- Uncomment the following lines for debugging purposes
-- print (list)
-- for k, v in pairs(list) do
--     print("List index: "..k.." /Name of the Controller: "..v)
-- end

-- use names of the controller instead of list indexes to ensure consistency whatever the USB port the controller is plugged in
    game_controller_add("TCA Q-Eng 1&2", callback1) 
    game_controller_add("T.A320 Pilot", callback0)
All in all, @Ralph : definitely feel that the Wiki page should be updated to reflect this fact.
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

User avatar
Corjan
Posts: 2939
Joined: Thu Nov 19, 2015 9:04 am

Re: API Game controller examples

#6 Post by Corjan »

Hi,


HID devices are very generic, and thus, so is the AM API.

There can be an undefined number of buttons/axis, that ranges from controller to controller.

Also having something unique to consistantly define a certain controller is hard, right now the device name is used.
Windows does it by 'guessing' it is the same one if it is connected to the same hardware USB port after reboot/etc.

A HID device does not have a unique hardware identifier.


Corjan

User avatar
Corjan
Posts: 2939
Joined: Thu Nov 19, 2015 9:04 am

Re: API Game controller examples

#7 Post by Corjan »

SimPassion wrote: Sun Apr 30, 2023 2:55 pm FYI, it works in AM 4.1.6 and create this issue in AM 4.2 Beta 10, further it creates a CTD when stopping the instrument :
Fixed, will be part of next BETA,

Corjan

SimPassion
Posts: 5340
Joined: Thu Jul 27, 2017 12:22 am

Re: API Game controller examples

#8 Post by SimPassion »

Cool @Corjan 👍 Thanks for your answer and your work !

Post Reply