Log In  
Page:
1
2

@zep Thanks for the clarification on PCM! For streaming via wavetable nodes - will there be some form of synchronization available to make sure timing lines up?

P#124568 2023-01-19 20:29

@zep That's great, thanks!

By the way, I saw what you said about split. Here's an implementation that has a convert parameter akin to PICO-8:

function split(str, sep, convert) -- Based on https://stackoverflow.com/a/7615129
    local t = {}

    str = tostring(str)
    sep = sep or ","
    convert = (convert == nil and true) or convert

    for v in gmatch(str, "([^" .. sep .. "]+)") do
        insert(t, (convert and tonumber(v)) or v)
    end

    return t
end

I'm working on a complete re-implementation of the PICO-8 API within Picotron. If there are any PICO-8 functions you'd like help bringing over, let me know!

P#124580 2023-01-19 23:19
1

Hi @zep.

Glad to help. Another problem though. The screen seems a bit small now.

This is the frame I get running on Google Chrome, with no option to make the work screen bigger.

Is anyone else getting this small size ?

P#124583 2023-01-20 02:20 ( Edited 2023-01-20 02:51)

Bug report: crash when copy/pasting a huge block of text/code (> 1mb).

p64_playground_7.js:1 exception thrown: RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds
    at wasm://wasm/0020d80a:wasm-function[640]:0x6b6e9
    at wasm://wasm/0020d80a:wasm-function[496]:0x5badc
    at wasm://wasm/0020d80a:wasm-function[857]:0x7e841
    at Module.dynCall_v (https://www.lexaloffle.com/play/p64_playground_7.js:1:1225527)
    at browserIterationFunc (https://www.lexaloffle.com/play/p64_playground_7.js:1:1154454)
    at Object.runIter (https://www.lexaloffle.com/play/p64_playground_7.js:1:1157507)
    at Browser_mainLoop_runner (https://www.lexaloffle.com/play/p64_playground_7.js:1:1155976)
P#124604 2023-01-20 22:13

Hey @zep. I found a temporary solution for the small frame in Google Chrome.

Press CTRL and the "=" key (next to the backspace) until you get a perfect double-triple pixel size that fits your screen.

If you guys are experimenting, press CTRL and 0 (zero) to reset your viewing size.

P#124605 2023-01-20 22:57 ( Edited 2023-01-20 22:58)

I recently started having an issue with the code editor, about 3 days ago.

I am unable to paste in code that is more than roughly 20 lines or so.
When I open the playground and try pasting in my code, it instead pastes in zxc.
If i delete that, then it changes to pasting in nothing.
Whenever I press Ctrl+V I see the mouse cursor flicker and lag from about a frame, which indicates that something is definitely happening, but nothing actually gets pasted in.

I checked the Firefox dev console to see if it shows me anything, and this is what I see.
https://gyazo.com/9aa01dcf2bec802f72b1524c4105b5f7
After that, pasting in anything (both small or big) adds 2 new lines to the console.
They are @@ navigator.clipboard.readText not found -- reading from codo_textarea and @@ get_clipboard_text called.
The only difference between pasting in small and big is that the second line appears once when successful, but 10 times when not.

Other than that, I've also noticed that Ctrl + Key combinations are pretty wack sometimes.
Ctrl+R sometimes also does Ctrl+V before running the application, which modifies code and crashes it.
Ctrl+V sometimes pastes my clipboard 4 times instead of only once, and a few times it didn't paste in anything at all (even when my clipboard was small).
Ctrl+A also runs Ctrl+V and/or Ctrl+R from time to time.

I checked both Firefox and Chrome, and everything is the same between them.
If you want to debug stuff with me to possibly find the issues, then you can contact me on Discord or by email.
My tag is SoundsDotZip#1143 and my email address is [email protected]

P#124630 2023-01-21 14:23
1

@zep said:
> There is still a difference with PICO-8 though: once a colour has been made transparent with palt(col, true), any remapping for that colour is lost and so palt(col, false) will revert to mapping to itself (i.e. palt(col, false) is the same as pal(col, col)).

I was kind of worried this sort of issue would arise from merging color writing and transparency into the blend tables.

I wonder if it would be better to have both the blend table and a single 64-bit hardware register somewhere that basically acted as a palette colorkey. This would be synonymous with the old PICO-8 palt() booleans. You could still technically accomplish 100% transparency / 100% opacity with the blend tables, but palt() would toggle bits in this register instead of rewriting a row in the table.

It'd make handling transparency changes more efficient host-side, though it'd necessitate one extra test/branch per pixel of course, but the savings of not having to run the src/dst through the 2D lookup table and then having to re-write the pixel as the same color it already is might offset that. It's basically an early-out, a stencil based on color, just like modern GPUs early out if the depth stencil (aka z-buffer) test fails and they don't bother doing the fragment shading for the pixel.

P#124733 2023-01-23 20:12 ( Edited 2023-01-23 20:21)

@Felice The thing I'm more irritated by is when you try to draw a black shape and it does nothing. The palt issue is a minor one and I can see how it can trip you up if you're used to it remembering the previous pal setting, but I don't see the need for it myself. (Usually, when I want to draw black on a sprite, I use pal(i,0) rather than making a different color transparent and black opaque, as I think it's more token efficient.) But whereas in PICO-8 it would ignore palt for shape statements, rather often in Picotron, I draw a black circle and then wonder for half an hour trying to figure out why the ₣¥€₭ doesn't it work??? before I figure out that I might as well have been dipping my digital paintbrush with nothing before wiping it on the virtual canvas. Of course, now that I'm used to it I now know to use color #32 instead, but it still tripped me up far more than palt destroying the previous color ever could. (Though, I'll admit that I am an amateur programmer so take my opinion with a grain of salt.)

P#124790 2023-01-24 21:25
4

MINESWEEPER


I have done it! I have made a recreation of Minesweeper in Picotron, meaning this is technically the first game for Picotron.

{-EDIT: As has been pointed out below, this may not be the first game made for Picotron. It is, however, as far as I (and others) can tell the first game released for Picotron. While I was editing this post, I also added some comments next to the adjustables to recreate the difficulty settings for the original game.-}

To load it in Picotron:

  • Paste the following code into the code editor:

    -- Minesweeper (v2)
    -- By: Kai
    --
    -- GFX decoder
    function decode(str)
    return userdata(chr(91,103,102,120,93)..str..chr(91,47,103,122,120,93))
    end
    --
    -- GFX: faces
    smile=decode"101077777777777777767666666666666665766660000006666576660aaaaaa066657660aaaaaaaa0665760aa00aa00aa065760aa00aa00aa065760aa00aa00aa065760aaaaaaaaaa065760aaaaaaaaaa065760aa0aaaa0aa0657660aa0000aa066576660aaaaaa06665766660000006666576666666666666656555555555555555"
    curious=decode"101077777777777777767666666666666665766660000006666576660aaaaaa066657660aaaaaaaa0665760aa00aa00aa065760aa00aa00aa065760aa00aa00aa065760aaaaaaaaaa065760aaaaaaaaaa065760aaaa00aaaa0657660aaa00aaa066576660aaaaaa06665766660000006666576666666666666656555555555555555"
    frown=decode"101077777777777777767666666666666665766660000006666576660aaaaaa066657660aaaaaaaa0665760aa0aaaa0aa065760aaa0aa0aaa065760aa0aaaa0aa065760aaaaaaaaaa065760aaa0000aaa065760aa0aaaa0aa0657660aaaaaaaa066576660aaaaaa06665766660000006666576666666666666656555555555555555"
    cool=decode"101077777777777777767666666666666665766660000006666576660aaaaaa066657660aaaaaaaa0665760a000aa000a0657600000000000065760a000aa000a065760aaaaaaaaaa065760aa0aaaa0aa065760aaa0000aaa0657660aaaaaaaa066576660aaaaaa06665766660000006666576666666666666656555555555555555"
    -- GFX: tiles
    boom=decode"08088888888m8686868m8855588m8656568m8855588m8686868m8888888mmmmmmmmm"
    block=decode"08087777776m7666665m7666665m7666665m7666665m7666665m6555555mmmmmmmmm"
    empty=decode"0808kkkkkkkmk444444mk444444mk444444mk444444mk444444mk444444mmmmmmmmm"
    flag=decode"08087777776m7668665m7688665m7888665m766i665m76iii65m6555555mmmmmmmmm"
    mine=decode"0808kkkkkkkmk646464mk455544mk656564mk455544mk646464mk444444mmmmmmmmm"
    falseflag=decode"08087777778m7662685m7622865m7228665m768i665m78iii65m8555555mmmmmmmmm"
    -- GFX: numbers
    numbercols={12,27,24,16,2,17,13,32} numbers={
    decode"08080077700007777000777770000077700000777000007770007777777000000000",
    decode"08087777777077000770000007707777777077000000777777707777777000000000",
    decode"08087777777077000770000007700077777000000770770007707777777000000000",
    decode"08087000077070000770700007707777777000000770000007700000077000000000",
    decode"08087777777077000000770000007777777000000770000007707777777000000000",
    decode"08087777777077000000770000007777777077000770770007707777777000000000",
    decode"08087777777000000770000007700000077000000770000007700000077000000000",
    decode"08087777777070000770700007707777777070000770700007707777777000000000"}
    --
    -- adjustables
    -- beginner: 9x9/10
    -- intermediate: 16x16/40
    -- expert: 30x16/99
    width=10 -- min: 7 | max: 59-60
    height=10 -- min: 1 | max: 31-32
    mines=10 -- idealy ~10-20% of total tiles
    --
    -- other setup
    lmb=0
    dead=false
    won=false
    start=true
    remainingmines=mines
    timer=0
    --
    -- data format:
    -- bit 0: mine
    -- bit 1: uncovered
    -- bit 2: flagged
    -- bit 3: unused (?)
    -- bit 4: unused (?)
    -- bit 5: unused (?)
    -- bit 6: unused (?)
    -- bit 7: unused (?)
    --
    minefield=userdata("u8",width,height)
    --
    -- debug: randomized test board
    --for x=0,width-1 do
        --for y=0,height-1 do
            --set(minefield,x,y,flr(rnd(2)))
        --end
    --end
    --dead=true
    -- /debug
    --
    function place_mines(cx,cy)
    local candidates={}
    for x=0,width-1 do
        for y=0,height-1 do
            if (abs(x-cx)>1 or abs(y-cy)>1) add(candidates,{x,y})
        end
    end
    for i=1,mines do
        local position=candidates[flr(rnd(#candidates))+1]
        set(minefield,position[1],position[2],1)
        del(candidates,position)
    end
    end
    --
    function bit(n,b,c)
    if type(c)=="boolean" then
        return c and n|2^b or n&255-2^b
    else
        return n&2^b>0
    end
    end
    --
    function uncover(tx,ty)
    if (bit(get(minefield,tx,ty),1)) return
    set(minefield,tx,ty,get(minefield,tx,ty)+2)
    local nearbymine
    for xdelta=-1,1 do
        for ydelta=-1,1 do
            if (bit(get(minefield,tx+xdelta,ty+ydelta),0)) nearbymine=true
        end
    end
    if not nearbymine then
        for xdelta=-1,1 do
            for ydelta=-1,1 do
                local x=tx+xdelta
                local y=ty+ydelta
                if (x==mid(0,x,width-1) and y==mid(0,y,height-1) and not bit(get(minefield,x,y),1) and not bit(get(minefield,x,y),2)) uncover(x,y)
            end
        end
    elseif bit(get(minefield,tx,ty),0) then
        dead=true
    end
    end
    --
    function _draw()
    mx,my,mb=get_mouse()
    mbp=mb&~lmb -- mb pressed
    lmb=mb -- last mb
    if (not (dead or won or start)) timer=min(timer+1/60,999)
    local tx=(mx-1)\8
    local ty=(my-20)\8
    if tx==mid(0,tx,width-1) and ty==mid(0,ty,height-1) and not dead and not won then
        -- on grid
        if bit(mbp,0) and not bit(get(minefield,tx,ty),1) and not bit(get(minefield,tx,ty),2) then
            if (start) place_mines(tx,ty) start=false
            --set(minefield,tx,ty,bit(get(minefield,tx,ty),1,true))
            uncover(tx,ty)
            if not dead then
                local coveredtiles=0
                for x=0,width-1 do
                    for y=0,height-1 do
                        if (not bit(get(minefield,x,y),1)) coveredtiles+=1
                    end
                end
                if (coveredtiles==mines) won=true
            end
        elseif bit(mbp,2) and not bit(get(minefield,tx,ty),1) and not start then
            set(minefield,tx,ty,get(minefield,tx,ty)^^4)
            remainingmines+=bit(get(minefield,tx,ty),2) and -1 or 1
        end
    elseif mx==mid(width*8/2-8,mx,width*8/2+7) and my==mid(2,my,17) and bit(mbp,0) then -- clicked on face
        -- reset puzzle
        dead=false
        won=false
        start=true
        remainingmines=mines
        timer=0
        for x=0,width-1 do
            for y=0,height-1 do
                set(minefield,x,y,0)
            end
        end
    end
    
    -- draw game
    cls()
    rectfill(0,0,width*8,19,22)
    --rectfill(0,19,width*8,height*8+19,20)
    palt(0,false)
    local emote=dead and frown or won and cool or bit(mb,0) and curious or smile
    spr(emote,width*8/2-8,2)
    palt(0,true)
    for x=0,width-1 do
        for y=-0,height-1 do
            local tile
            local tdata=get(minefield,x,y)
            local showneighbors
            if bit(tdata,1) then -- uncovered
                if bit(tdata,0) then -- mine
                    tile=boom
                else -- no mine
                    tile=empty
                    showneighbors=true
                end
            else -- covered
                if bit(tdata,2) or won then -- flag
                    if bit(tdata,0) or not dead then -- correct or still playing
                        tile=flag
                    else -- game over correction
                        tile=falseflag
                    end
                else -- no flag
                    if bit(tdata,0) and dead then -- game over clairvoyence
                        tile=mine
                    else -- nothing special
                        tile=block
                    end
                end
            end
            spr(tile,x*8+1,y*8+20)
            if showneighbors then
                local closemines=0
                for xdelta=-1,1 do
                    for ydelta=-1,1 do
                        if (bit(get(minefield,x+xdelta,y+ydelta),0)) closemines+=1
                    end
                end
                pal(7,numbercols[closemines])
                spr(numbers[closemines],x*8+1,y*8+20)
                pal(7,7)
            end
        end
    end
    --rect(0,0,width*8,19,1)
    rect(0,19,width*8,height*8+19,17)
    
    rectfill(1,5,16,13,2)
    local str=mid(-99,flr(remainingmines),999)
    if str<-9 then
        -- do nothing
    elseif str<0 then
        str="-".."0"..-str
    elseif str<10 then
        str="00"..str
    elseif str<100 then
        str="0"..str
    else
        -- do nothing
    end
    print(str,2,6,8)
    rectfill(width*8-16,5,width*8-1,13,2)
    local str=mid(-99,flr(timer),999)
    if str<-9 then
        -- do nothing
    elseif str<0 then
        str="-".."0"..-str
    elseif str<10 then
        str="00"..str
    elseif str<100 then
        str="0"..str
    else
        -- do nothing
    end
    print(str,width*8-15,6,8)
    
    -- debug: display mouse statistics
        --print("mx: "..mx,width*8+2,1,27)
        --print("my: "..my)
        --print("mb: "..mb)
        --print("mbp: "..mbp)
        --print("tx: "..tx)
        --print("ty: "..ty)
    -- /debug
    end

  • Optionally, edit the adjustable variables width, height and mines to change the difficulty.
  • Either hit Ctrl+R or, for the optimal experience, continue reading.
  • Type save minesweeper and hit enter.
  • Type terminal and hit enter to go to the desktop.
  • In the desktop terminal, type or paste in run_program_inside_terminal"minesweeper.p64/main.lua" and hit enter.
  • Adjust the size of the window to make it fit perfectly.
  • Play! Use the left mouse button to uncover a tile, and the right mouse button to place a flag where you think a mine is. Click the smiley face to restart. Numbers indicate how many mines are in the eight surrounding tiles. The number in the top left is an estimation of how many mines you have left to find, based on the total number of mines and how many flags you have placed down, and the number in the top-right shows your current time in seconds. Uncovering a mine leads to a game over, while uncovering all non-mine tiles causes you to win. Enjoy!
P#124805 2023-01-25 05:05 ( Edited 2023-01-30 22:17)
1

Very cool work @Kaius 👍
(with great, clear instructions!)

As for first Picotron game - quite possibly.
I saw a couple others making games on the Pico8 Discord, but don't think they've posted the code yet.

Also, I did see this posted on Twitter on Jan 16th
But again, they don't appear to have posted any source - so unable to verify if they're just abusing the hashtag:
https://twitter.com/seimon___/status/1614926407972564993

Moar Picotron games FTW! 😉

P#124812 2023-01-25 06:41

Okay so the "bug" I reported before (it's above this by a few posts) was actually on my end.
One of my antivirus' settings made me unable to paste anything too big.
I tweaked the options and now it works fine.

P#124853 2023-01-25 19:51
1

Certainly not the first program posted for Picotron in Lexaloffle, @Kaius. :) I made my demo and set it so others can use the graphics in it.

https://www.lexaloffle.com/bbs/?tid=50942

Still ... it's not good there are so many shortcomings in Picotron. I may wait a-while for some bugs to be fixed before I build anything more in it.

P#124872 2023-01-26 04:42
2

congrats on the first game Kaius!

(not the first doodle, experiment or cart, but the first published game)

[- edit to avoid going more off-thread here: wth is that reply? people on the forum can point out incorrect or obnoxious messages. I will post carts when I want to. -]

P#124904 2023-01-26 22:43 ( Edited 2023-01-28 01:44)
1

Indeed @merwok. You've certainly been with us for over 3-years now. I look forward to you writing and posting in lexaloffle your very first Pico-8 program.

Congrats go to you too, @Kaius for writing the first fully-functional game in Picotron. Well done !

I'm not going to code in Picotron again though until some of the bugs are worked out - yet I am always glad to code and share my code in Pico-8. :)

Grand cheers for @zep who is always looking to the future !

P#124912 2023-01-27 04:28 ( Edited 2023-01-27 04:33)
1

Bug report: set_draw_target breaks _draw

Example:

function _init()
 _screen=userdata("u8",240,135)
end

function _draw()
    set_draw_target(_screen)
    cls(6)
    for i=0,240-1 do
     for j=0,135-1 do
      pset(i,j,(i+j)%32)
     end
    end
    set_draw_target()

    -- bug: cls & print are not displayed
    cls(2)
    print(stat(0),2,2,8)
end

moving set_draw_target (+ render to memory) to _update restores correct behavior.

P#125139 2023-02-01 21:12 ( Edited 2023-02-01 21:12)
1

Can you post your fixed code? I put all my code in update but it's still not displaying anything after I change the draw target:

function _init()
    scr1 = userdata("u8", 480, 270)
end
function _update()
    set_draw_target(scr1)

    set_draw_target()
    -- bug: cls is not displayed
    cls(12)
end
P#125203 2023-02-02 21:56
1

@freds72 @rilden From testing, it seems that set_draw_target() does NOT reset the draw target as it is (seemingly) supposed to. It is only reset between _update and _draw calls, so once you use set_draw_target, there is no going back until the end of the _update/_draw function. This program shows this bug by printing the working function(s).

function _init()
    cls() -- erase anything from all the previous testing. (just in case)
end
function _draw()
    set_draw_target() -- note that we don't reset this, nor do we set it TO anything at all in the first place!
    print("_draw",10,20,11) -- this fails...
end
function _update()
    print("_update",10,10,8) -- ...but this works!
end
P#125223 2023-02-03 06:21
1

Yep, what I've been doing is storing the draw target via draw_target = get_draw_target() and using set_draw_target(draw_target)

P#125316 2023-02-04 18:05

@HTV04 Thanks! I didn't know that get_draw_target() existed. Here's a program I made while testing this function, utilizing the ability to make procedural sprites:

function _draw()
    cls()
    mx,my=get_mouse()
    spr(proc_gen_spr(12,17,28,16),mx-7,my-7)
end
function proc_gen_spr(col,shade,shine,size)
    local last_dt=get_draw_target()
    local procedural_sprite=userdata("u8",size,size)
    set_draw_target(procedural_sprite)
    circfill(size/2,size/2,size/2-1,shade)
    circfill(size/2-1,size/2,size/2-1,shade)
    circfill(size/2,size/2-1,size/2-1,shade)
    circfill(size/2-1,size/2-1,size/2-1,col)
    circfill(size/4,size/4,size/8,shine)
    set_draw_target(last_dt)
    return procedural_sprite
end

Also, here's a better version of set_draw_target that resets the draw target when no argument is supplied:

-- on startup
dscr=get_draw_target() -- the original display screen.
-- new function
function set_dt(dt) -- shorter name for the original function.
    set_draw_target(dt or dscr) -- literally all that's needed.
end -- ...and that's it.
-- testing
--set_dt(userdata("u8",128,128)) -- a simulated PICO-8 screen perhaps?
cls(7) -- you WOULD notice this, but you don't, 'cause it ain't there!
set_dt() -- resetting the draw target.
circfill(240,135,100,8) -- you DO notice this, however.

(Note to self: I need to be looking into pancelor's function-lister some more.)

P#125350 2023-02-05 09:31

thanks for the investigations but I still see that as a bug :)

P#125377 2023-02-05 21:18 ( Edited 2023-02-05 21:18)

@freds72 Oh, it's definitely a bug. I mean, even zep thought that set_draw_target() worked the way it should. Need proof?

function _init()
    b = userdata("u8",8,8)
    set_draw_target(b)
    circ(3,3,1,7)
    set_draw_target()

    sx = 20 sy = 20
end

That code snippet above comes from the fillp demo, specifically the _init function which draws the initial fill pattern consisting of a small, hollow circle. To do this, the draw target is set to the fill pattern, and then set back... but, we obviously know that's not what happens. Instead, set_draw_target() seems to do nothing, as evidenced by what happens if you add in a cls(28) line or other drawing function after the draw target is supposedly reset, but before the end of the _init function.

P#125399 2023-02-06 07:12

could i run a program as a desktop wallpaper in picotron?

P#126631 2023-03-05 18:00
1

this is so very very cool.
[8x8]

i'm really excited by this. i'm playing around with it a bunch as it is, regardless of the current limitations, and can't wait for a desktop release.

i absolutely love how much of the system is exposed and hackable via the system/ subdirectory. it was really fun to edit system/terminal.lua, hit ctrl+s, ctrl+r the terminal, and see my changes take effect. immediately excited to mod the system to fill in some gaps, even though my work is likely to be redundant in future releases.

i really like playing around with building little games and programs in pico-8, it's a really great experience, but this workstation concept is so up my alley it's crazy. i really love building tooling and hacking on little system things. i sate my need to do so with my linux systems now but this is just so much cozier and friendlier with your little-systems charm, zep.

would drop money on this to fund development in a heartbeat, even in its current state, btw. but hopefully not too much development, got to leave some for the rest of us old systems hackers

[17x8]

P#126744 2023-03-07 22:32
1

I had to make an account just to say woah. This thing has so much potential! I love that the system source code is accessible from within the system, really cool concept can't wait to see more from this project in the future :D

P#127382 2023-03-21 01:00
Page:

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2023-03-26 21:02:52 | 0.130s | Q:51