I thought I'd see if I could do something with lua and coroutines to feed keystrokes with delays.

So I create a lua coroutine to pump keystrokes from a buffer. It's called every frame and calls coroutine.yield() when it's done.

After a normal keystroke, it delays 3 frames. After a cr, it will delay 5*60 frames.

What's kind of cool about lua coroutines is that you can call them with parameters if you like. So to add text I call the coroutine with a parameter.

Just an experiment...


Code

-- you must initialize these globals or the routine won't work, any error in the coroutine kills it so coroutine.status is dead

keyfeed_buffer = ""
keydelay = -1
keyfeed_buffer_pos = 1

normalkeydelay = 3
crkeydelay = 5 * 60

function keyboard_feeder()
 while 1 do
   --print("going to yield")
   newparam = coroutine.yield()
   --print ("keyboard_feeder_coroutine")
   if newparam == nil then

      --print("keydelay" .. keydelay)
      if keydelay < 0 then  -- get the next character

      nextkeytofeed = string.sub(keyfeed_buffer,keyfeed_buffer_pos,keyfeed_buffer_pos)
      keyfeed_buffer_pos = keyfeed_buffer_pos+1
      emu.keypost(nextkeytofeed)
      
      if nextkeytofeed == "" then keydelay = -1; keyfeed_buffer  = ""; keyfeed_buffer_pos = 1
      elseif nextkeytofeed == "\n" then keydelay = crkeydelay
      else keydelay = normalkeydelay
      end

      else
         keydelay = keydelay -1
      end
   else 
      -- print("adding " .. newparam .. " to buffer");
      keyfeed_buffer=keyfeed_buffer .. newparam; 
      -- print(keyfeed_buffer);
   end -- if
 end -- while
end -- function


function call_keyboard_feeder()
   --print ("call keyboard feeder")
   coroutine.resume(keyboard_feeder_coroutine)
   --print ("done call keyboard feeder")
end

function add_text(newtext)
   coroutine.resume(keyboard_feeder_coroutine,newtext)
end

function register_keyboard_feeder()
   keyboard_feeder_coroutine=coroutine.create(keyboard_feeder)
   table.insert(dispatch_list,call_keyboard_feeder)   
end


dispatch_list = { }

function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end

if already_registered_frame_dispatcher == nil then
   emu.register_frame(frame_dispatcher);
   already_registered_frame_dispatcher = 1
end

function cld()
dispatch_list = {}
end

print("type cld(); to stop a runaway dispatch");

cld()
register_keyboard_feeder()

add_text("this is a test of the emergency broadcast system.\n")
add_text("this is only a test.\n")
add_text("FEEDING 255 CHARACTERS.\n")
for i=1,255 do add_text(string.char(string.byte("0")+i%10)) end
add_text("\n")
add_text("That's 255 characters\n")