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.
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 ) |
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]