136 lines
3.4 KiB
Lua
136 lines
3.4 KiB
Lua
-- Input abstraction: normalises keyboard (classic dual-track / modern simplified)
|
|
-- and gamepad (always dual-stick) into a pair of track values in [-1, 1].
|
|
local Input = {}
|
|
|
|
local SETTINGS_FILE = "oma-tank_settings.dat"
|
|
local STICK_DEADZONE = 0.18
|
|
|
|
local mode = "modern"
|
|
local joystick = nil
|
|
|
|
local function clamp(v)
|
|
if v < -1 then return -1 end
|
|
if v > 1 then return 1 end
|
|
return v
|
|
end
|
|
|
|
local function keyPair(positive, negative)
|
|
local v = 0
|
|
if love.keyboard.isDown(positive) then v = v + 1 end
|
|
if love.keyboard.isDown(negative) then v = v - 1 end
|
|
return v
|
|
end
|
|
|
|
local function modernTracks()
|
|
-- Up/Down drive both tracks, Left/Right split them
|
|
local fwd = 0
|
|
if love.keyboard.isDown("up", "w") then fwd = fwd + 1 end
|
|
if love.keyboard.isDown("down", "s") then fwd = fwd - 1 end
|
|
|
|
local turn = 0
|
|
if love.keyboard.isDown("right", "d") then turn = turn + 1 end
|
|
if love.keyboard.isDown("left", "a") then turn = turn - 1 end
|
|
|
|
-- Reverse at 50% feel: matches the prior simplified control
|
|
if fwd < 0 then fwd = fwd * 0.5 end
|
|
|
|
local left = clamp(fwd + turn)
|
|
local right = clamp(fwd - turn)
|
|
return left, right
|
|
end
|
|
|
|
local function classicTracks()
|
|
-- W/S = left track, I/K = right track
|
|
local left = keyPair("w", "s")
|
|
local right = keyPair("i", "k")
|
|
return clamp(left), clamp(right)
|
|
end
|
|
|
|
local function applyDeadzone(v)
|
|
if math.abs(v) < STICK_DEADZONE then return 0 end
|
|
return v
|
|
end
|
|
|
|
local function gamepadTracks()
|
|
if not joystick then return 0, 0 end
|
|
-- Stick Y axis is positive down on most gamepads; flip so "forward" on the stick = +1
|
|
local left = -applyDeadzone(joystick:getGamepadAxis("lefty"))
|
|
local right = -applyDeadzone(joystick:getGamepadAxis("righty"))
|
|
return clamp(left), clamp(right)
|
|
end
|
|
|
|
function Input.tracks()
|
|
local kl, kr
|
|
if mode == "classic" then
|
|
kl, kr = classicTracks()
|
|
else
|
|
kl, kr = modernTracks()
|
|
end
|
|
local gl, gr = gamepadTracks()
|
|
-- If either source is pushing a stick, prefer gamepad values for that track
|
|
local left = (gl ~= 0) and gl or kl
|
|
local right = (gr ~= 0) and gr or kr
|
|
return left, right
|
|
end
|
|
|
|
function Input.setMode(newMode)
|
|
if newMode == "classic" or newMode == "modern" then
|
|
mode = newMode
|
|
Input.save()
|
|
end
|
|
end
|
|
|
|
function Input.getMode()
|
|
return mode
|
|
end
|
|
|
|
function Input.toggleMode()
|
|
mode = (mode == "classic") and "modern" or "classic"
|
|
Input.save()
|
|
end
|
|
|
|
function Input.label()
|
|
return (mode == "classic") and "CLASSIC DUAL-TRACK" or "MODERN SIMPLIFIED"
|
|
end
|
|
|
|
function Input.save()
|
|
pcall(function()
|
|
love.filesystem.write(SETTINGS_FILE, "mode=" .. mode .. "\n")
|
|
end)
|
|
end
|
|
|
|
function Input.load()
|
|
if love.filesystem.getInfo(SETTINGS_FILE) then
|
|
local ok, content = pcall(love.filesystem.read, SETTINGS_FILE)
|
|
if ok and content then
|
|
local m = content:match("mode=(%w+)")
|
|
if m == "classic" or m == "modern" then mode = m end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Input.attachJoystick()
|
|
local joysticks = love.joystick.getJoysticks()
|
|
for _, js in ipairs(joysticks) do
|
|
if js:isGamepad() then
|
|
joystick = js
|
|
return
|
|
end
|
|
end
|
|
joystick = nil
|
|
end
|
|
|
|
function Input.joystickAdded(js)
|
|
if js:isGamepad() and not joystick then
|
|
joystick = js
|
|
end
|
|
end
|
|
|
|
function Input.joystickRemoved(js)
|
|
if joystick == js then
|
|
joystick = nil
|
|
Input.attachJoystick()
|
|
end
|
|
end
|
|
|
|
return Input
|