71 lines
2.4 KiB
Lua
71 lines
2.4 KiB
Lua
-- =====================================================================
|
|
-- lib-core.input — Action-Mapping + Direction-Vector (P.0)
|
|
-- See: meta/docs/superpowers/specs/2026-05-09-p0-lib-input-design.md
|
|
--
|
|
-- Scope: action-mapping (key-arrays per action) + direction-vector helper.
|
|
-- DEPRECATED-MVP for: mouse-button actions, gamepad bindings, action-
|
|
-- context-stack, key-rebinding config, modifier-combos, analog-axis,
|
|
-- was_action_released edge.
|
|
-- =====================================================================
|
|
|
|
local bindings = {} -- action_name -> array of key-codes
|
|
|
|
local M = {}
|
|
|
|
function M.bind(action_name, keys)
|
|
if type(action_name) ~= "string" then
|
|
error("input.bind: action_name must be a string")
|
|
end
|
|
if type(keys) ~= "table" or #keys == 0 then
|
|
error(string.format("input.bind: keys must be a non-empty array of key-codes (action '%s')",
|
|
action_name))
|
|
end
|
|
bindings[action_name] = keys
|
|
end
|
|
|
|
function M.unbind(action_name)
|
|
bindings[action_name] = nil
|
|
end
|
|
|
|
function M.is_action_down(action_name)
|
|
local keys = bindings[action_name]
|
|
if not keys then return false end
|
|
for _, k in ipairs(keys) do
|
|
if engine.input.is_key_down(k) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function M.was_action_pressed(action_name)
|
|
local keys = bindings[action_name]
|
|
if not keys then return false end
|
|
for _, k in ipairs(keys) do
|
|
if engine.input.was_pressed(k) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Direction-vector helper: returns {x, y} in {-1, 0, +1} each axis.
|
|
-- Y-down-positive per Sporel pixel-convention (ADR-0031).
|
|
function M.direction(left_action, right_action, up_action, down_action)
|
|
local x = (M.is_action_down(right_action) and 1 or 0)
|
|
- (M.is_action_down(left_action) and 1 or 0)
|
|
local y = (M.is_action_down(down_action) and 1 or 0)
|
|
- (M.is_action_down(up_action) and 1 or 0)
|
|
return { x = x, y = y }
|
|
end
|
|
|
|
function M.action_count()
|
|
local n = 0
|
|
for _ in pairs(bindings) do n = n + 1 end
|
|
return n
|
|
end
|
|
|
|
-- DEPRECATED-MVP: bind_mouse(action, button) -- mouse-button slice
|
|
-- DEPRECATED-MVP: bind_gamepad(action, ...) -- gamepad slice
|
|
-- DEPRECATED-MVP: push_context(name) / pop_context() -- action-context-stack
|
|
-- DEPRECATED-MVP: load_bindings_from_config(path) -- key-rebinding slice
|
|
-- DEPRECATED-MVP: was_action_released(action) -- lift-detection slice
|
|
|
|
return M
|