Joypad.get reads what the user is pressing (the user's intentions) on some joypad. joypad.set replaces the user's intentions with the script's own when it next calls frameadvance trampling the user's choices.
Here's your button mashing script:
-- Script runs forever
while true do
-- push button
joypad.set(1, {A = true})
snes9x.frameadvance()
-- release button
joypad.set(1, {A = false})
snes9x.frameadvance()
end
And here's a more complicated example that involves a user-accessible Stop command using the Start (ha!) button
-- On/off rapid toggling of this variable
local status = true
while true do
-- Give the user an out by pressing start. This exits out of the loop
-- and since the script ends at that point, the script exits
if joypad.get(1)['start'] then
break
end
-- Press (or not) the A button. All other buttons are not pressed
-- and the user's input be damned.
joypad.set(1, {A = status})
-- Toggle toggle
status = not status
-- Next frame
snes9x.frameadvance()
end
amaurea: rather than saying the emulator "calls [the] main lua function", you should say it "resumes" the main function. The function is a coroutine and hence has the appearance of running as its own thread non-stop. In fact if the main function ever exits the script is unloaded. It can only be stopped/frozen at the frameadvance() function which may be executed in many different locations. I realize I'm being a bit asinine on a technicality but I want to make it clear how it works since it seems people are still confused.