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 :-)