Log In  


See repro cart - unless I am totally wrong on my software tline, pico8 tline ("hw tline") is not correctly rendering lines with arbitrary slopes.

Software version eventually converge toward correct pattern, tline does not.

Cart #rikegukawu-0 | 2021-06-20 | Code ▽ | Embed ▽ | No License
5

5


2

Hi @freds72

This might be a bug in documentation rather than runtime. The problem is that tline increments both map_x, map_y every pixel regardless of the primary axis. Perhaps the easiest way to explain is with another reference implementation:

function tline3(x0,y0,x1,y1,mx,my,mdx,mdy)
	local dx,dy=0,0
	x0=x0\1+.5 y0=y0\1+.5
	x1=x1\1+.5 y1=y1\1+.5

	-- 3 pixel line has 2 steps
	local steps=max(abs(x1-x0),abs(y1-y0))

	if (steps > 0) then
		dx=(x1-x0)/steps
		dy=(y1-y0)/steps
	end

	while steps>=0 do
		pset(x0,y0,msget(mx,my))
		x0+=dx y0+=dy
		mx+=mdx my+=mdy
		steps-=1
	end
end

The difference in behaviour in tline2 is caused by incrementing u or v (whichever is not the primary axis) only when error is exceeded. Moving "u+=du" outside of the "if error>=0 then" block would give the same behaviour as tline3.

So, to match a tline 1:1 with the pixels on the spritesheet along an arbitrary line, the number of steps are needed. By "steps", I mean "number_of_pixels_to_draw - 1" (disregarding clipping):

 local steps = max(dx,dy)
 tline(
     p0.x,p0.y,p1.x,p1.y,
     p0.u,p0.v,
     (p1.u-p0.u)/steps,
     (p1.v-p0.v)/steps)

I hope that makes sense! I'll try to make this clearer in the next update of the manual.


@zep
Just to be clear:

You're saying that it's intended that these all result in the same final (accumulated) UV at the end of the line?

tline( 0,0,100,  0, u0,v0, du,dv )
tline( 0,0,100,100, u0,v0, du,dv )  -- even though this line is technically longer
tline( 0,0,  0,100, u0,v0, du,dv )

4

Total side note:

You should stop encouraging people (by example from The Creator) to use \1 as a flr() substitute. Using &-1 is way, way more efficient on both the virtual cpu and the host cpu.

Most of the borderline embedded systems you'd like PICO-8 to run on for handheld mode are going to have very slow divide operations, because making a fast(er) divide is a silicon nightmare from what I understand.

If \1 is commonly used in tight loops, it's going to drag perf wayyyyy down on handhelds. A divide can easily be 30-70x slower than simple stuff like an &-1 bitwise op.

If nothing else, you should bodge the parser so it recognizes a floored-divide operator with a RHS of a literal '1' and just replace it behind the scenes with an &-1, because even if you stop doing it, others will probably propagate the bad version anyway. :P



[Please log in to post a comment]