Inconsistent image:drawTiled behavior when a stencil pattern is set

SDK 1.12.3 on MacOS 13.1, also occurs on hardware with OS 1.12.3.

I’m trying to draw a tiled background image that can scroll, and also use graphics.setStencilPattern(level) to fade the image when drawn. What I’m seeing is that the top row is only intermittently drawn by image:drawTiled if it is positioned above the top edge of the screen. It performs as expected when drawn past any other screen edge.

The following code demonstrates the issue – it creates a 40x40 solid black image, then sets a stencil value of 0.5 and draws it tiled in a 200x200 square. You can move the position it’s drawn at using the dpad.

local gfx <const> = playdate.graphics

xPos = 10
yPos = 10

blackImg = gfx.image.new(40, 40, gfx.kColorBlack)

function playdate.update()
	if playdate.buttonIsPressed(playdate.kButtonUp) then
		yPos -= 1
	elseif playdate.buttonIsPressed(playdate.kButtonDown) then
		yPos += 1
	end
	if playdate.buttonIsPressed(playdate.kButtonLeft) then
		xPos -= 1
	elseif playdate.buttonIsPressed(playdate.kButtonRight) then
		xPos += 1
	end
	print(yPos)
	
	gfx.setColor(gfx.kColorWhite)
	gfx.fillRect(0, 0, 400, 240)
	
	gfx.setStencilPattern(0.5)
	blackImg:drawTiled(xPos, yPos, 200, 200)
end

Steps to reproduce using my example code:

  1. hold dpad up until part of the tiled image is drawn above the top of the screen (yPos < 0)

Expected result: there should be a 200x200 gray square at any x or y position, and if positioned partially offscreen, the portion of it remaining onscreen should still be filled with the tiled image

Actual result: if it goes off the top edge of the screen, the top row of the tiled image within the screen area is only drawn at certain yPos values, causing it to flicker.

This happens with any stencil value, even 1 (which should be solid). Commenting out line 24 (gfx.setStencilPattern(0.5)) causes it to behave as expected.

Untitled

To whoever at Panic looks at this issue: this probably isn’t the method I’m going to use for background drawing in the end, so consider it low priority

1 Like

Huge thanks for the demo, makes it so much easier to find the bugs! :slight_smile: In this case I have it skipping the inner loop if the matching stencil row is outside the image's drawn bounds.. but that skips the entire row of tiles, not a single scan line. I don't know what I was thinking there. That wouldn't have caused an issue here except that I'm using the modulo operator to map the screen row to the stencil row, and that doesn't work right for negative numbers. All kinds of goofs here. :confused: