Log In  

I wanted to take a screenshot and draw it back to the screen like a sprite.

This is useful for screen transitions, like in Bubble Bobble where you scroll up to the next level.

The nice folks on the Pico-8 discord helped me put together this, which copies the screen to 0x8000 (the extended map location in 2.4+). Then when we want to draw it we copy it over the whole sprite sheet, draw that like a sprite, then reload the original sprite sheet.

Cart #screengrab_sprite-0 | 2023-01-16 | Code ▽ | Embed ▽ | No License
1

function _init()
    cls()
    -- make something to screengrab
    for x=0,127,8 do
        for y=0,127,8 do
            rect(x, y, x+7, y+7, flr(rnd(16)))
        end
    end
    target_x, target_y = 0,0
    screengrab()
end

function _update()
    -- test we can draw the screengrab to a different place
    target_x = (target_x + 1) % 128
end

function _draw()
    cls()
    -- copy to sprite sheet location
    memcpy(0x0000, 0x8000, 8192)
    -- draw it to screen
    sspr(0, 0, 128, 128, target_x, target_y)
    -- restore the sprite sheet
    reload(0x0000,0x0000,8192)
    -- debug where the screen should be painted to
    rect(target_x, target_y, target_x + 2, target_y + 2, 7)
    -- check we reloaded the sprite sheet
    spr(0, target_x, target_y + 8)
end

-- copy the screen to extended map location
function screengrab()
    memcpy(0x8000,0x6000,8192)
end

Other methods could be used like using memcpy to paint direct from memory - which would be a lot faster. This thread may offer some help with that.

If anyone would like to improve on this example please do. There's not a lot of posts on the subject that offer any working examples so the more the merrier.

P#124407 2023-01-16 19:43 ( Edited 2023-01-16 23:56)

FReDs72 on Discord suggested this alternative for just scrolling the screen away:

function _init()
    cls()
    -- make something to screengrab
    for x=0,127,8 do
     for y=0,127,8 do
        rect(x, y, x+7, y+7, flr(rnd(16)))
     end
    end
    dx, dy = 0,-1
  sx,sy = -128*mid(-1,1,dx\0x.0001),-128*mid(-1,1,dy\0x.0001)
 end

 function _update()
    sx+=dx
    sy+=dy
    -- end of transition
    if(sx%128==0) dx=0
    if(sy%128==0) dy=0
 end

 function _draw()
    palt(0,false)
    -- use screen as sprite source
    poke(0x5f54,0x60)
    -- shift screen dx/dy pixels
    sspr(0,0,128,128,dx,dy)
    -- reset
    poke(0x5f54,0x00)

    -- next level
    camera(-sx,-sy)
    rectfill(0,0,127,127,0)
    rect(0,0,127,127,7)
    print("next level",56,64,7)
    camera()
 end

This uses the screen itself as a sprite sheet instead of storing it in memory.

P#124417 2023-01-16 21:43

[Please log in to post a comment]