Log In  

Hii picoerss!

first time posting here.

Anyways after a couple year hiatus doing things on pico 8 I read about new serial communication with outside processes;

So I wandered if anyone has done any trials communicating pico-8 with something like nodejs. I don't if I should simulate gpio pins (don't know if that can be done in x86) or is there another approach. I know about prevous work simulating gpios on html exports but I couldn't find something similar in a non-web enviroment.

I've been researching P2P protocols like ssb and dat and it would be awesome to be able to connect those protocols to pico8 and build small p2p apps in it (just being able to exchange small strings between pico8 and nodejs would suffice, I think...)

P#79103 2020-07-09 23:14 ( Edited 2020-07-10 03:05)

Well, I was able to communicate with nodejs spawning pico8 inside nodejs and hooking directly to stdin and stdout

const {spawn} = require('child_process')
const pico8 = spawn('pico8')

pico8.stdout.on('data', d =>{
  console.log(d.toString())
})

//writing a string
pico8.stdin.write(Buffer.from('hi from nodejs',ascii))

Then from pico8 I can do:

--write a single number
poke(0x4300, num)
-- or a string
for i=0,#string do
  poke(0x4300+i, string[i]) --string as an array of charcodes
end
--and then if its a number, to send it
serial(0x805,0x4300,1)
--if its a string
serial(0x805,0x4300,#string + 1) -- I don't know why it always sends a 0 at the beggining...

For listening in messages from stdin I can do something like:

serial(0x804,0x4300,sizeOfStringIExpect)-- I know the size of the string that I'm recieving. 
-- would be nice to check arbitrary bytes to avoid having to know size beforehand without risk of crashing....

while(peek(root+i) ~= 0) do
  char = chr(peek(0x4300+i))
  str=str .. char
  i+=1
end

Anyways, this kinda works, except its pretty unstable for sending and recieving strings of arbitrary size, (specially recieving and parsing on the pico8 side and getting to know peek, poke and serial)

I guess there must be a more generic way to this...

P#79112 2020-07-10 05:23

Getting a little bit further.

So, I put some effort on recieving strings through pico-8's stdin. For now I've managed to solve it setting a fixed size buffer length of 16bits and split any string in several 16bit buffers, and sending them one at a time. From the pico-8 side its just a matter of reading Serial 16bits at a time inside a while loop and checking if the value read is nil to know if its the end of the whole string.

//Dado un string devuelvo un arr de nBuffers de nLength 
function getFixedSizeBufferArray(string, bufLength){
  var mainBuf = Buffer.from(string, 'ascii')
  //2. cuantos buffers de tamaño fijo (bufLength) necesitas??
  var nBuffs = Math.ceil(mainBuf.length/bufLength)
  //3. array de buffers
  var buffs = []

  for(let i = 0; i < nBuffs; i++){
    //4. Alojo un buffer de 16bits
    let buf = Buffer.alloc(bufLength)
    //5. Copio los 16bits de data correspondiente al nuevo buffer
    mainBuf.copy(buf, 0, i*bufLength, (i*bufLength) + bufLength)
    buffs.push(buf)
  }

  return buffs
}

function sendMsg(str){
  var bufs = getFixedSizeBufferArray(str,16)
  for(buf of bufs){
    pico8.stdin.write(buf)
  }
}
function readbstr(n)
    finished = false
    while(not finished) do
        --leo 16bits stdin
        serial(0x804,0x4300,n)
        --itero y mando al str
        for i=0,n-1 do
            char = chr(peek(0x4300+i))
            --si llegue al final 
            if char == nil then
                finished = true
                break
            end
            str=str .. char
        end
    end

    return str
end
P#79172 2020-07-11 20:14

[Please log in to post a comment]