-- ===================================================================== -- 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