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
2

P#93773 2021-06-20 08:25 ( Edited 2021-06-20 08:25)

:: zep
1

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.

P#93785 2021-06-20 18:34
:: Felice

@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 )
P#93819 2021-06-21 13:28 ( Edited 2021-06-21 13:30)
:: Felice
1

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

P#93820 2021-06-21 13:47 ( Edited 2021-06-21 13:49)

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2021-07-29 09:17:11 | 0.025s | Q:19