Created
September 11, 2014 04:18
-
-
Save shakesoda/a775635d21233c77ecc6 to your computer and use it in GitHub Desktop.
axis + face button -> letters. the guts of a controller keyboard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function gate(axis, num) | |
local function wrap(x) | |
return math.fmod(x, math.pi * 2) | |
end | |
if math.abs(axis.x) < 0.1 and math.abs(axis.y) < 0.1 then | |
return num + 1 | |
end | |
local angle = math.atan2(axis.y, axis.x) -- in radians | |
angle = wrap(math.pi * 3 - angle) -- CCW -> CW + half rotation | |
--print(axis.x, axis.y, angle) | |
-- offset to the left by half the width of a segment | |
local angle_offset = angle + ((math.pi * 2) / (num * 2)) | |
--print(angle_offset) | |
-- map to number of segments | |
local final_angle = angle_offset * (num / (math.pi * 2)) | |
--print(final_angle) | |
-- un-quantized output is useful for display. | |
return math.floor(final_angle) + 1, final_angle + 1 | |
end | |
-- This function is REALLY defensive because of how easy it is to screw up | |
-- key mappings when playing with different setups. | |
function chord(mapping, axis, face) | |
-- standard setup: 8x4. section #num_gates+1 is neutral. | |
local num_gates = 8 | |
local num_faces = 4 | |
assert(#mapping == num_gates + 1, "Invalid key map! Wrong number of sections.") | |
assert(axis ~= nil, "No axis!") | |
assert(axis.x ~= nil and axis.y ~= nil, "Axis needs x/y!") | |
assert(face ~= nil, "No face!") | |
assert(face >= 0, "Face in the wrong base! This data has become waste in your haste!") | |
-- gate the axis to one of 8 directions | |
local section = mapping[gate(axis, num_gates)] | |
assert(#section == num_faces, "Invalid key map! Wrong number of faces.") | |
return section[face] | |
end | |
-- mappings: in LURD order (CW from left) | |
local standard_map = { | |
{"e","t","a","o"}, -- left | |
{"i","n","s","r"}, | |
{"h","d","l","u"}, -- up | |
{"c","m","f","y"}, | |
{"w","g","p","b"}, -- right | |
{"v","k","x","q"}, | |
{"j","z","\'","\""}, -- down | |
{",","!","?","."}, | |
{":","(",")","/"} -- neutral | |
} | |
local tests = { | |
{ | |
map = standard_map, | |
axis = { x = -1, y = 0 }, | |
face = 1, | |
output = standard_map[1][1] | |
} | |
-- | |
, { | |
map = standard_map, | |
axis = { x = 1, y = 0 }, | |
face = 4, | |
output = standard_map[5][4] | |
}, { | |
map = standard_map, | |
axis = { x = 0, y = 1 }, | |
face = 3, | |
output = standard_map[3][3] | |
} | |
--]] | |
} | |
for i, test in ipairs(tests) do | |
local output = chord(standard_map, test.axis, test.face) | |
local str = "Test #" .. i .. ": " | |
if output ~= test.output then | |
print(str .. "FAILED. Expected " .. test.output .. ", but got " .. output .. "!") | |
else | |
print(str .. "PASSED. (" .. output .. ")") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment