There are no binary relational operators in the Lua language, but you can write your programs in such a way that you don't need it.
I think your system is a bit complicated, but I'll try it. Let me summarize it: Most sequences are combos of the form: "key press 1", "key release 1", "key press 2", "key release 2" (where "1" and "2" are arbitrary keys, like cross, circle, up etc.). Some special characters, like space and backspace, are only a sequence of "key press 1", "key release 1". The shift modifier is the up-key, which has to be pressed while holding the first key of a combo. For example the sequence "triangle press", "triangle release", "square press", "square release" produces a "r", but the sequence "triangle press", "up press", "up release", "triangle release", "square press", "square release" produces a "R" (the squence "triangle press", "up press", "triangle release", "up release", "square press", "square release" is valid, too, but the sequence "triangle press", "up press", "triangle release", "square press", "square release", "up release" produces nothing, until you add the sequence "square press", "square release", but this looks like unintended behaviour in your program (version 0.50a)).
Some special sequences are used for switching the group. The start group is group 1, where the above sequences are used. You can switch to group 2 with the sequence "up press", "cross press", "cross release", "up release" (there is a bug, I think: when I switch the group, the last directional key is interpreted as the first key press/release sequence of the new sequence instead of starting with an empty sequence, e.g. if I'm in group 2, the sequence "up press", "cross press", "cross release", "up release", "triangle press", "triangle release" produces a "v", which normally is produces with the sequence "up press", "up release", "triangle press", "triangle release"). In group 2 for example the sequence "right press", "right release", "square press", "square release" produces a "k" (while in group 1 the same sequence produces a "m").
Ok, how can you implement it in Lua? I think the easiest way, and to avoid unintended behaviour, would be to list all sequences and which action should be executed for it. One nice feature of Lua is, that you can use functions as values, this simplifies the code:
Code: Select all
black = Color.new(0, 0, 0);
white = Color.new(255, 255, 255);
-- group 1 tree (with underscore are key release events)
group1 = {
cross = { char = " ", code = 32 },
triangle = {
_triangle = { square = { _square = { char = "r", code = 1 }}},
up = { _up = { _triangle = { square = { _square = { char = "R", code = 2 }}}}}
},
up = { cross = { _cross = { _up = { group = "group2" }}}}
}
-- group 2 tree
group2 = {
right = {
_right = { square = { _square = { char = "k", code = 3 }}},
},
up = { cross = { _cross = { _up = { group = "group1" }}}}
}
-- mapping from control name to control function
controlFunctions = {
up = Controls.up, down = Controls.down, left = Controls.left, right = Controls.right,
cross = Controls.cross, circle = Controls.circle, square = Controls.square, triangle = Controls.triangle
}
-- current pressed controls, initialized to false
pressedControls = {}
for name, _ in controlFunctions do
pressedControls[name] = false
end
-- current selected group
currentGroup = group1
-- current root within current selected group
currentRoot = currentGroup
-- current text position
x = 0
-- create an empty white image
canvas = Image.createEmpty(480, 272)
canvas:clear(white)
-- main loop
while true do
-- read button states
pad = Controls.read()
-- check every button
for name, testFunction in controlFunctions do
selected = currentRoot
check = false
-- check one button
if testFunction(pad) then
if not pressedControls[name] then
-- if key press event, go down the group tree
selected = selected[name]
pressedControls[name] = true
check = true
end
else
if pressedControls[name] then
-- if key release event, go down the group tree
selected = selected["_" .. name]
pressedControls[name] = false
check = true
end
end
-- if some button changed its state, check if group tree leaf is reached
if check then
if selected then
if selected.char then
-- char leaf reached, print it
canvas:print(x, 0, selected.char)
x = x + 8
currentRoot = currentGroup
elseif selected.group then
-- group leaf reached, change group
currentGroup = _G[selected.group]
currentRoot = currentGroup
else
-- not a leaf, set current root to next group branch
currentRoot = selected
end
else
-- sequence not found, start again at root of current group
currentRoot = currentGroup
end
end
end
-- update screen
screen:blit(0, 0, canvas, 0, 0, canvas:width(), canvas:height(), false)
screen.waitVblankStart()
screen.flip()
-- program end, if start was pressed
if pad:start() then break end
end
With this code the sequence "triangle press", "triangle release", "square press", "square release", "triangle press", "up press", "up release", "triangle release", "square press", "square release", "up press", "cross press", "cross release", "up release", "right press", "right release", "square press", "square release" produces the string "rRk".
Of course, you don't have to write the low-level group trees yourself, use some more Lua code to generate it from higher-level descriptions of your protocol. And you can write some tree dumping code for debugging.
An interesting idea could be to use the different time when to press and release the key, for example "cross press", "down press", "cross release", "down release" could have a different meaning than "cross press", "down press", "down release", "cross release". This enhances the number of possible inputs with fewer keys, and makes the system even more unusable :-)