I finally have a Steam Deck!
The issue with raw gamepad input was that gui scripts don’t receive it, but regular scripts do. Armed with this knowledge, I recreated a utility similar to what @britzl mentioned. This is me partially mapping my old Xbox controller:
Regrettably, I just don’t seem to get any input from the Steam Deck - other than an unexpected gamepad name:
For reference, this is the script I use to gather mappings. Might be useful for other situations:
--pre-hash
local GAMEPAD_LSTICK_LEFT = hash("gamepad_lstick_left")
local GAMEPAD_LSTICK_RIGHT = hash("gamepad_lstick_right")
local GAMEPAD_LSTICK_DOWN = hash("gamepad_lstick_down")
local GAMEPAD_LSTICK_UP = hash("gamepad_lstick_up")
local GAMEPAD_LSTICK_CLICK = hash("gamepad_lstick_click")
local GAMEPAD_LTRIGGER = hash("gamepad_ltrigger")
local GAMEPAD_LSHOULDER = hash("gamepad_lshoulder")
local GAMEPAD_LPAD_LEFT = hash("gamepad_lpad_left")
local GAMEPAD_LPAD_RIGHT = hash("gamepad_lpad_right")
local GAMEPAD_LPAD_DOWN = hash("gamepad_lpad_down")
local GAMEPAD_LPAD_UP = hash("gamepad_lpad_up")
local GAMEPAD_RSTICK_LEFT = hash("gamepad_rstick_left")
local GAMEPAD_RSTICK_RIGHT = hash("gamepad_rstick_right")
local GAMEPAD_RSTICK_DOWN = hash("gamepad_rstick_down")
local GAMEPAD_RSTICK_UP = hash("gamepad_rstick_up")
local GAMEPAD_RSTICK_CLICK = hash("gamepad_rstick_click")
local GAMEPAD_RTRIGGER = hash("gamepad_rtrigger")
local GAMEPAD_RSHOULDER = hash("gamepad_rshoulder")
local GAMEPAD_RPAD_LEFT = hash("gamepad_rpad_left")
local GAMEPAD_RPAD_RIGHT = hash("gamepad_rpad_right")
local GAMEPAD_RPAD_DOWN = hash("gamepad_rpad_down")
local GAMEPAD_RPAD_UP = hash("gamepad_rpad_up")
local GAMEPAD_START = hash("gamepad_start")
local GAMEPAD_BACK = hash("gamepad_back")
local GAMEPAD_GUIDE = hash("gamepad_guide")
local hash_to_text = {
[GAMEPAD_LSTICK_LEFT] = "GAMEPAD_LSTICK_LEFT",
[GAMEPAD_LSTICK_RIGHT] = "GAMEPAD_LSTICK_RIGHT",
[GAMEPAD_LSTICK_DOWN] = "GAMEPAD_LSTICK_DOWN",
[GAMEPAD_LSTICK_UP] = "GAMEPAD_LSTICK_UP",
[GAMEPAD_LSTICK_CLICK] = "GAMEPAD_LSTICK_CLICK",
[GAMEPAD_LTRIGGER] = "GAMEPAD_LTRIGGER",
[GAMEPAD_LSHOULDER] = "GAMEPAD_LSHOULDER",
[GAMEPAD_LPAD_LEFT] = "GAMEPAD_LPAD_LEFT",
[GAMEPAD_LPAD_RIGHT] = "GAMEPAD_LPAD_RIGHT",
[GAMEPAD_LPAD_DOWN] = "GAMEPAD_LPAD_DOWN",
[GAMEPAD_LPAD_UP] = "GAMEPAD_LPAD_UP",
[GAMEPAD_RSTICK_LEFT] = "GAMEPAD_RSTICK_LEFT",
[GAMEPAD_RSTICK_RIGHT] = "GAMEPAD_RSTICK_RIGHT",
[GAMEPAD_RSTICK_DOWN] = "GAMEPAD_RSTICK_DOWN",
[GAMEPAD_RSTICK_UP] = "GAMEPAD_RSTICK_UP",
[GAMEPAD_RSTICK_CLICK] = "GAMEPAD_RSTICK_CLICK",
[GAMEPAD_RTRIGGER] = "GAMEPAD_RTRIGGER",
[GAMEPAD_RSHOULDER] = "GAMEPAD_RSHOULDER",
[GAMEPAD_RPAD_LEFT] = "GAMEPAD_RPAD_LEFT",
[GAMEPAD_RPAD_RIGHT] = "GAMEPAD_RPAD_RIGHT",
[GAMEPAD_RPAD_DOWN] = "GAMEPAD_RPAD_DOWN",
[GAMEPAD_RPAD_UP] = "GAMEPAD_RPAD_UP",
[GAMEPAD_START] = "GAMEPAD_START",
[GAMEPAD_BACK] = "GAMEPAD_BACK",
[GAMEPAD_GUIDE] = "GAMEPAD_GUIDE",
}
function init(self)
msg.post(".", "acquire_input_focus")
self.data = {}
self.formatted_data = {}
end
function update(self, dt)
if self.gamepad_name then
label.set_text("#gamepad_name", "Gamepad name: " .. self.gamepad_name)
else
label.set_text("#gamepad_name", "No gamepad detected.")
end
local txt = ""
for name, data in pairs(self.data) do
txt = txt .. name .. " type: " .. data.type .. " index: " .. data.index .. "\n"
end
label.set_text("#mapping", txt)
self.formatted_data = {}
for name, data in pairs(self.data) do
if data.type == "GAMEPAD_TYPE_HAT" then
table.insert(self.formatted_data, "map { input: " .. name .. " type: " .. data.type .. " index: 0 hat_mask: " .. data.index .. " }")
elseif data.type == "GAMEPAD_TYPE_AXIS" then
--this needs "mod" details, do manually
table.insert(self.formatted_data, "map { input: " .. name .. " type: " .. data.type .. " index: " .. data.index .. " }")
else
table.insert(self.formatted_data, "map { input: " .. name .. " type: " .. data.type .. " index: " .. data.index .. " }")
end
end
pprint(self.formatted_data)
end
function on_input(self, action_id, action)
if action_id == hash("gamepad_connected") then
self.gamepad_name = action.gamepad_name
end
if action_id == hash("gamepad_raw") then
self.previous_raw = action
else
if action.pressed then
if not self.previous_raw then
return
end
--is it a button?
for i, state in pairs(self.previous_raw.gamepad_buttons) do
if state == 1 then
self.data[hash_to_text[action_id]] = {type = "GAMEPAD_TYPE_BUTTON", index = i}
break
end
end
--is it an axis?
local largest_state = 0
local largest_i = nil
for i, state in pairs(self.previous_raw.gamepad_axis) do
state = math.abs(state)
if state > 0.5 then
if state > largest_state then
largest_state = state
largest_i = i
end
end
end
if largest_i then
self.data[hash_to_text[action_id]] = {type = "GAMEPAD_TYPE_AXIS", index = largest_i}
end
--is it a hat?
for i, state in pairs(self.previous_raw.gamepad_hats) do
if state == 1 then
self.data[hash_to_text[action_id]] = {type = "GAMEPAD_TYPE_HAT", index = i}
break
end
end
end
end
end
I think the axis detection needs some work because I use math.abs() when I actually think there are supposed to be negative values.
I’m at a loss as to how to move forward at this point!