mirror of https://github.com/mgba-emu/mgba.git
Res: Add script for doing fake analog input by PWM-ing the d-pad
This commit is contained in:
parent
4fdebd5dd5
commit
3a59d9cb83
|
@ -0,0 +1,77 @@
|
||||||
|
local state = {}
|
||||||
|
state.period = 4
|
||||||
|
state.phase = 0
|
||||||
|
state.x = 0
|
||||||
|
state.y = 0
|
||||||
|
|
||||||
|
function state.update()
|
||||||
|
state.phase = state.phase + 1
|
||||||
|
if state.phase == state.period then
|
||||||
|
state.phase = 0
|
||||||
|
end
|
||||||
|
if state.phase == 0 then
|
||||||
|
if input.activeGamepad then
|
||||||
|
local x = input.activeGamepad.axes[1] / 30000
|
||||||
|
local y = input.activeGamepad.axes[2] / 30000
|
||||||
|
-- Map the circle onto a square, since we don't
|
||||||
|
-- want to have a duty of 1/sqrt(2) on the angles
|
||||||
|
local theta = math.atan(y, x)
|
||||||
|
local r = math.sqrt(x * x + y * y)
|
||||||
|
if theta < math.pi * -3 / 4 then
|
||||||
|
r = -r / math.cos(theta)
|
||||||
|
elseif theta < math.pi * -1 / 4 then
|
||||||
|
r = -r / math.sin(theta)
|
||||||
|
elseif theta < math.pi * 1 / 4 then
|
||||||
|
r = r / math.cos(theta)
|
||||||
|
elseif theta < math.pi * 3 / 4 then
|
||||||
|
r = r / math.sin(theta)
|
||||||
|
elseif theta < math.pi * 5 / 4 then
|
||||||
|
r = -r / math.cos(theta)
|
||||||
|
end
|
||||||
|
state.x = math.cos(theta) * r
|
||||||
|
state.y = math.sin(theta) * r
|
||||||
|
else
|
||||||
|
state.x = 0
|
||||||
|
state.y = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function state.read()
|
||||||
|
emu:clearKeys(0xF0)
|
||||||
|
if math.floor(math.abs(state.x) * state.period) > state.phase then
|
||||||
|
if state.x > 0 then
|
||||||
|
emu:addKey(C.GB_KEY.RIGHT)
|
||||||
|
else
|
||||||
|
emu:addKey(C.GB_KEY.LEFT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if math.floor(math.abs(state.y) * state.period) > state.phase then
|
||||||
|
if state.y > 0 then
|
||||||
|
emu:addKey(C.GB_KEY.DOWN)
|
||||||
|
else
|
||||||
|
emu:addKey(C.GB_KEY.UP)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The duty cycle approach can confuse menus and the like,
|
||||||
|
-- so the POV hat setting should force a direction on
|
||||||
|
if input.activeGamepad and #input.activeGamepad.hats > 0 then
|
||||||
|
local hat = input.activeGamepad.hats[1]
|
||||||
|
if hat & C.INPUT_DIR.UP ~= 0 then
|
||||||
|
emu:addKey(C.GB_KEY.UP)
|
||||||
|
end
|
||||||
|
if hat & C.INPUT_DIR.DOWN ~= 0 then
|
||||||
|
emu:addKey(C.GB_KEY.DOWN)
|
||||||
|
end
|
||||||
|
if hat & C.INPUT_DIR.LEFT ~= 0 then
|
||||||
|
emu:addKey(C.GB_KEY.LEFT)
|
||||||
|
end
|
||||||
|
if hat & C.INPUT_DIR.RIGHT ~= 0 then
|
||||||
|
emu:addKey(C.GB_KEY.RIGHT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
callbacks:add("frame", state.update)
|
||||||
|
callbacks:add("keysRead", state.read)
|
Loading…
Reference in New Issue