Post subject: Lua manipulation of joypad
Joined: 12/9/2010
Posts: 3
Location: Falun, Sweden
Hi. I tinkered around a bit with the Lua scripts, and came up with an idea I tried to implement. The idea is to take the intersection between button presses on controller 1 and button presses on controller 2, and only pass that as the input to controller 1. In essence, both players has to play at the same time. But I ran into a problem: if I set the joypad of controller 1, the next frame I can only retrieve what I assigned to the joypad the previous frame (this is made clear in the documentation too). So, I was wondering, is it possible to access the raw input from both players, and not the joypad state as seen by the emulator? Here is my current script:
Language: lua

-- Filter out the input on a certain player function split(player, joypad) local ret = {} for k,v in pairs(joypad) do if k:sub(1,2) == player then ret[k:sub(4)]=v end end return ret end function intersection(p1, p2) local ret = {} for k,v in pairs(p1) do ret[k]= p1[k] and p2[k] end return ret end -- Make string from all pressed buttons function dump(o) local s = '' for k,v in pairs(o) do if v then s = s .. tostring(k) .. ' ' end end return s end while true do -- Read the current joypad state local pad = joypad.getimmediate() -- Split the input for player 1 and player 2 local p1 = split("P1", pad) local p2 = split("P2", pad) -- Find the intersection between the two local inter = intersection(p1, p2) -- Render some help text gui.drawText(0,10, "P1: " .. dump(p1), null, null, 10) gui.drawText(0,25, "P2: " .. dump(p2), null, null, 10) gui.drawText(0,40, "Out: " .. dump(inter), null, null, 10) -- Set joypad 1 to the intersection of the two joypad.set(inter, 1) emu.frameadvance() end
Thanks!
Geez... I've been gone a long time and not a single new post in the ZSNES forum... :'-(
Joined: 12/9/2010
Posts: 3
Location: Falun, Sweden
I've done quite some research by now, and asked several questions on IRC too, but I am still drawing up short. So far, it looks like the problem I have might be that you cannot really un-set button presses via the Lua script. This thread seems to suggest that there was some issues with passing false as a button press to the joypad.set method. The thread mentioned that the issue should be fixed soon, but I am not sure if that was ever done. Also, this Github issue mentions that joypad.set cannot be used to un-set buttons, which seems to be in line with my findings too. Both these sources are very old though, so I am not sure if these issues should have been fixed (or if they are even issues at all, it might be by design). Is it possible today to somehow un-set buttons pressed on the joypad?
Geez... I've been gone a long time and not a single new post in the ZSNES forum... :'-(
Joined: 12/9/2010
Posts: 3
Location: Falun, Sweden
After some detective work from zeromus (as reported in this thread) I got the script working as intended. My full script now is:
Language: lua

local reset = joypad.get(1) for k,v in pairs(reset) do reset[k] = "" end -- Set P1 to intersection of P1 and P2 event.onframestart( function() local p1 = joypad.get(1) local p2 = joypad.get(2) local consolidated = intersection(p1, p2) gui.drawText(0,10, "P1: " .. dump(p1)) gui.drawText(0,25, "P2: " .. dump(p2)) joypad.set(consolidated,1); end ) -- Reset P1 event.onframeend( function() joypad.set(reset, 1) end ) -- Set each button to pressed only if it is pressed by -- by both players function intersection(p1, p2) local ret = {} for k,v in pairs(p1) do ret[k] = p1[k] and p2[k] end return ret end -- Print all pressed buttons function dump(o) local s = '' for k,v in pairs(o) do if v then s = s .. tostring(k) .. ' ' end end return s end -- Main loop while true do emu.frameadvance() end
Geez... I've been gone a long time and not a single new post in the ZSNES forum... :'-(