display.setOffset() is scoped to graphics context while I would not expect it to be

Tentatively filing this as a bug because it might be a matter of opinion what the correct behavior is.

Given the following code, I expect the rectangle to be drawn at 0,0 into the image buffer and then the image buffer to be drawn at 20,30 to the screen. Effectively, the rectangle's top-left corner then appears at 20,30 on screen. Because to me, the graphics context is different from the display context.

function playdate.update()
    gfx.pushContext()
        display.setOffset(20,30)
    gfx.popContext()
    gfx.drawRect(0,0,40,50) -- or any other draw call like text, image, etc.
end

In reality the rectangle appears at 0,0 on screen.
This bothers me when trying to create a screen shake effect from within a gfx context. I wrap my entire game loop in a gfx context for hygiene; I don't want any gfx from the previous frame to spill into the current frame logic.

What do y'all think about this?

As I understand it, this is the difference between graphics and display: graphics is about drawing, but with display you’re changing a lower level screen thing.

If you draw the rectangle once, then animate display.setOffset each frame, what happens?

That's right, the display effects (scale, mosaic, offset, invert) are applied to the frame buffer data as it's sent out to the display. It's completely separate from the graphics context.

I'll file an issue to note this in the docs.

1 Like

If I understand you correctly, your expectations match mine. It seems I have found a bug then, right? (see sample code)

1 Like

D'oh! Yep, you're right, I'm storing and restoring the framebuffer state in push/popContext because that's where I put the draw offset, cliprect, and stencil. But it doesn't make sense at all for the display effects. I'll separate those two. Thanks for clarifying, I wasn't paying enough attention when I read your post. :frowning:

1 Like