Hi,

I'm heaving problems with getting my triangle drawing routine to clip from the left and top edges. The right and bottom edges already work.

This is what it's doing:

After over a week I got a different result, but I don't really know which one is the closest to good clipping, but in this screenshot, I added 100 to the x coordinates before the calculating part of the routine, then substracting 100 again from the coordinates before it draws the pixels. This is what it looks like:

Here is the code of my triangle drawing routine (sorry, it isn't commented well and comments are in Dutch, and it's long too):

Code:
```DrawTriangle:   ;IN: x1,y1,u1,v1,x2,y2,u2,v2,x3,y3,u3,v3   ;scherm = 96*64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld de, 100   ld hl, (x1)   add hl, de   ld (x1), hl   ld hl, (x2)   add hl, de   ld (x2), hl   ld hl, (x3)   add hl, de   ld (x3), hl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld hl, (y1)   ld de, (y2)   cpHLDE   jr c, Y1SmallerThanY2   ld (y1), de   ld (y2), hl   ld hl, (x1)   ld de, (x2)   ld (x1), de   ld (x2), hl #comment   ld hl, (u1)   ld de, (u2)   ld (u1), de   ld (u2), hl #endComment   ld a, (u1)   ld b, a   ld a, (u2)   ld (u1), a   ld a, b   ld (u2), a   ld a, (v1)   ld b, a   ld a, (v2)   ld (v1), a   ld a, b   ld (v2), a Y1SmallerThanY2:   ld hl, (y1)   ld de, (y3)   cpHLDE   jr c, Y1SmallerThanY3   ld (y1), de   ld (y3), hl   ld hl, (x1)   ld de, (x3)   ld (x1), de   ld (x3), hl #comment   ld hl, (u1)   ld de, (u3)   ld (u1), de   ld (u3), hl #endcomment   ld a, (u1)   ld b, a   ld a, (u3)   ld (u1), a   ld a, b   ld (u3), a   ld a, (v1)   ld b, a   ld a, (v3)   ld (v1), a   ld a, b   ld (v3), a Y1SmallerThanY3:   ld hl, (y2)   ld de, (y3)   cpHLDE   jr c, Y2SmallerThanY3   ld (y2), de   ld (y3), hl   ld hl, (x2)   ld de, (x3)   ld (x2), de   ld (x3), hl #comment   ld hl, (u2)   ld de, (u3)   ld (u2), de   ld (u3), hl #endComment   ld a, (u2)   ld b, a   ld a, (u3)   ld (u2), a   ld a, b   ld (u3), a   ld a, (v2)   ld b, a   ld a, (v3)   ld (v2), a   ld a, b   ld (v3), a Y2SmallerThanY3:     res 0, (IY)   ;in bit 0, (IY) wordt opgeslagen bij welke helft het is. 0=eerste helft, 1= tweede helft   res 1, (IY)   ;bit 1, (IY) = interval texturen al berekend   ld hl, (y2)   ld de, (y1)   subFP      ;hier gebruikt om 16-bit getallen af te trekken I.P.V. fixed-point getallen   ld h, l   ld l, 0   push hl   ld hl, (x2)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x2)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u2)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v2)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld l, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv3), hl   ld hl, (x1)   bit 7, h   jr z, TPos1   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   ld (tx2+1),hl \ ld a, \$FF \ ld (tx2),a   jr TEnd1 TPos1:   ld (tx1+1),hl \ xor a \ ld (tx1),a ;store the 16bit integer at hl into 16.8 fixed point number tx1   ld (tx2+1),hl \ xor a \ ld (tx2),a TEnd1:   ld hl, (y1)   ld (_ty), hl   ld a, (u1)   ld h, a   ld l, 0   ld (tu1), hl   ld (tu2), hl   ld a, (v1)   ld h, a   ld l, 0   ld (tv1), hl   ld (tv2), hl   ld hl, (Y1)   ld de, (y2)   cpHLDE   jp z, __TEndLoop TDrawLoop:   ld a, (_ty)   ld d, a   bit 7, a   jp nz, Clip   ld a, (_ty)   cp 64   ret nc   ld hl, (tu1)   ld (tmpu), hl   ld hl, (tv1)   ld (tmpv), hl   ld hl, (tu2)   ld (temp2), hl   ld hl, (tv2)   ld (temp3), hl   ld a, (tx2+1)   ld (temp+1), a   ld b, a   ld a, (tx1+1)   ld (temp), a   cp b   jr c, TOrdered   ld hl, (tu2)   ld (tmpu), hl   ld hl, (tv2)   ld (tmpv), hl   ld hl, (tu1)   ld (temp2), hl   ld hl, (tv1)   ld (temp3), hl   ld a, (tx2+1)   ld (temp), a   ld a, (tx1+1)   ld (temp+1), a TOrdered:   ld l, d   ld a, (temp)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   call GetPixel   ld (mask), a   ld (pointer), hl   bit 1, (IY)   jr nz, TPlotLoop   ld hl, (tx1)   ld de, (tx2)   cpHLDE   jr z, TPlotLoop   ld a, (temp)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld h, a   ld l, 0   ld a, (temp+1)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpu)   ld de, (temp2)   subFP   pop de   call DivFP   ld (tmpdu), hl   ld a, (temp)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld h, a   ld l, 0   ld a, (temp+1)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpv)   ld de, (temp3)   subFP   pop de   call DivFP   ld (tmpdv), hl   set 1, (IY) TPlotLoop:   ld a, (temp)   sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   bit 7, a   jr nz, TEndPlot   cp 96   jp nc, Clip   ld a, (tmpv+1)   ld hl, texture   add a, l   ld l, a   ld a, (tmpu+1)   ld b, a   inc b   ld a, (hl) TshiftLoop:   rla   djnz   TshiftLoop   ;push af     ld a, (mask)   ld hl, (pointer)   jr c, TSetPixel TResPixel:   ;ld a, b   cpl   and (hl)   ld (hl), a   jr TEndPlot TSetPixel:   ;ld a, b   or (hl)   ld (hl), a TEndPlot:   ld hl, mask   rrc (hl)   jr nc, TNoCarry   ld hl, (pointer)   inc hl   ld (pointer), hl TNoCarry:   ld hl, (tmpu)   ld de, (tmpdu)   add hl, de   ld (tmpu), hl   ld hl, (tmpv)   ld de, (tmpdv)   add hl, de   ld (tmpv), hl   ld a, (temp+1)   sub 50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld b, a   ld a, (temp)   sub 50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld hl, temp   inc (hl)   cp b   jr nz, TPlotLoop   bit 0, (IY)   jr nz, aaaa   res 1, (IY) aaaa: Clip:   ld hl,(tx1)   ld de, (dx1)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx1), hl   ld a, (tx1+2)   adc a, b   ld (tx1+2), a   ld hl,(tx2)   ld de, (dx3)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx2), hl   ld a, (tx2+2)   adc a, b   ld (tx2+2), a   ld hl, (tu1)   ld de, (du1)   add hl, de   ld (tu1), hl   ld hl, (tu2)   ld de, (du3)   add hl, de   ld (tu2), hl   ld hl, (tv1)   ld de, (dv1)   add hl, de   ld (tv1), hl   ld hl, (tv2)   ld de, (dv3)   add hl, de   ld (tv2), hl   ld hl, (_ty)   inc hl   ld (_ty), hl   ld de, (y2)   cpHLDE   jp c, TDrawLoop   bit 0, (IY)   jr nz, _TEnd __TEndLoop:   ;Begin tweede keer tekenen:   ld hl, (y2)   ld (_ty), hl   ld hl, (y3)   ld (y2), hl   ld hl, (dx2)   ld (dx1), hl   ld hl, (du2)   ld (du1), hl   ld hl, (dv2)   ld (dv1), hl   ld hl, (x2)   bit 7, h   jr nz, TPos4   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   jr TEnd4 TPos4:   ld (tx1+1),hl \ xor a \ ld (tx1),a Tend4:   ld a, (u2)   ld h, a   ld l, 0   ld (tu1), hl   ld a, (v2)   ld h, a   ld l, 0   ld (tv1), hl   set 0, (IY)   jp TDrawLoop _TEnd:   ret```
I haven't looked through the code (it is somewhat long, and I don't read Dutch), but I played around with the second screenshot, and here's what I found:

When the rectangle is clipped on the left side, the triangle on the left looks correct, but the triangle(s) on the right side appear to be shifted 64 pixels to the right and 2 pixels down. This could be the result of shifting the image (just the right-side triangles) right by 256 pixels (2*96+64 = 256), because the LCD memory essentially wraps around and goes down by one pixel on the right side of the screen.

It looks like you're using fixed-point numbers. Are those in 8.8 format? Is that your own implementation, and have you checked that code thoroughly for bugs? 256 is a highly suspicious value here, so I wouldn't be surprised if there's some kind of bug with handling overflows or negative values in your fixed-point code. Fixed-point operations can be a good place for bugs to hide if you're not too careful.
The fixed point math is indeed 8.8, and the math routines are signed. Should I upload the math routines too? And the algorithm was based on a gauroud triangle drawing algorithm (which is a triangle of which the color of each pixel is interpolated between the colors given for the corners) which I modifies to interpolate texture coordinates, instaed of colors.

BTW: the code I posted was the code of the secound screenshot, remove the code between the two lines of ';' chars at the beginning and the lines of code with a row of ';' characters bihind them to make it like the first screenshot.

Can you explain your logic behind subtracting 100 the way you're doing in the code you presented? Also, are those coordinates in that section of code "world" coordinates or screen coordinates?
The only thing I can think of is that it'll be a signed comparison mistake somewhere, as it works when dealing with positive bounds but not when things stray into negatives. What does your cpHLDE look like? It's clunky, but here's what I use for signed values:

Code:
```   ld a,d    xor \$80    ld d,a        ld a,h    xor \$80    ld h,a        or a    sbc hl,de```
Quote:
Can you explain your logic behind subtracting 100 the way you're doing in the code you presented? Also, are those coordinates in that section of code "world" coordinates or screen coordinates?
The substracting 100 was just a test to see if the problems were caused by the sign, and it turned out some, but not all, of them were. Also, this routine uses affine texture mapping, which means that it only handles screen coordinates (which makes the texture look bad when looking at it from an angle)

Quote:
What does your cpHLDE look like?

Code:
`#define cpHLDE or a \ sbc hl, de \ add hl, de`
I tried your cpHLDE routine, and it made it draw random pixels.
Note that my cpHLDE routine destroys HL, D and A, whereas yours preserves them. You would need to find a way to preserve them; it'll be slow, but

Code:
```   ld (OP1),a    push hl    push de    ld a,d    xor \$80    ld d,a        ld a,h    xor \$80    ld h,a        or a    sbc hl,de    pop de    pop hl    ld a,(OP1)```

may be worth trying to see if it is a signed comparison bug.
It works exactely the same as with my cpHLDE routine. both with and witouth the sub 100's

Hrm, it probably isn't that, then. I'm not much good at running Z80 in my head, and tend to prototype more complex routines in a high-level language first, get them working, then translate to assembly - that way if I encounter a bug I have something to compare the assembly code to and can step through until I find a value that's incorrect or similar.
I think the problem might be that your GetPixel routine doesn't handle negative X coordinates. Your clipping routine assumes that the pixel pointer will be to the left, when in fact it is 32 bytes too far to the right.
calc84maniac wrote:
I think the problem might be that your GetPixel routine doesn't handle negative X coordinates. Your clipping routine assumes that the pixel pointer will be to the left, when in fact it is 32 bytes too far to the right.

I made the getpixel routine only work with positive coordinates, and it was a bit better:

It clippes some scanlines correctely, but doesn't draws the other ones. Also the top triangle isn't drawn.
I just put clipping asside for a moment, and tried to make the textures of a better resulution. It now has 16x16 textures, but is slower than the 8x8 version. But that isn't what I wanted to tell, what I wanted to tell is that when I was testing it, I accidentally let it go of the top border of the screen, and this is what happened:

The god of assembly finally starts being friendly to me

EDIT: as you can see, clipping still doesn't work for the left border
Congratulations on at least getting that figured out; any idea what the issue is If you're using 16x16 textures, does that mean some sign bit somewhere is a different location, which could be why the top edge suddenly worked? I'm shooting in the dark here; I can't think of a particularly good reason why you'd be able to properly go off the top of the screen. Have you checked that it's actually getting clipped, and you're not just corrupting the memory above the graphbuffer?
I really don't know why it suddenly works. The difference between 8x8 and 16x16 are only 5 instructions and a few different numbers as texture coordinates. I also already checked if it really clipped, and it looked like it didn't corrupt any memory when clipping of the top side.

I also did some more attempts on clipping of the left side, and I really couldn't get it to work.

Here's the most recent code of my triangle drawing routine:
Code:
```DrawTriangle:   ;IN: x1,y1,u1,v1,x2,y2,u2,v2,x3,y3,u3,v3   ;scherm = 96*64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;  ld de, 100 ;  ld hl, (x1) ;  add hl, de ;  ld (x1), hl ;  ld hl, (x2) ;  add hl, de ;  ld (x2), hl ;  ld hl, (x3) ;  add hl, de ;  ld (x3), hl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld hl, (y1)   ld de, (y2)   cpHLDE   jr c, Y1SmallerThanY2   ld (y1), de   ld (y2), hl   ld hl, (x1)   ld de, (x2)   ld (x1), de   ld (x2), hl #comment   ld hl, (u1)   ld de, (u2)   ld (u1), de   ld (u2), hl #endComment   ld a, (u1)   ld b, a   ld a, (u2)   ld (u1), a   ld a, b   ld (u2), a   ld a, (v1)   ld b, a   ld a, (v2)   ld (v1), a   ld a, b   ld (v2), a Y1SmallerThanY2:   ld hl, (y1)   ld de, (y3)   cpHLDE   jr c, Y1SmallerThanY3   ld (y1), de   ld (y3), hl   ld hl, (x1)   ld de, (x3)   ld (x1), de   ld (x3), hl #comment   ld hl, (u1)   ld de, (u3)   ld (u1), de   ld (u3), hl #endcomment   ld a, (u1)   ld b, a   ld a, (u3)   ld (u1), a   ld a, b   ld (u3), a   ld a, (v1)   ld b, a   ld a, (v3)   ld (v1), a   ld a, b   ld (v3), a Y1SmallerThanY3:   ld hl, (y2)   ld de, (y3)   cpHLDE   jr c, Y2SmallerThanY3   ld (y2), de   ld (y3), hl   ld hl, (x2)   ld de, (x3)   ld (x2), de   ld (x3), hl #comment   ld hl, (u2)   ld de, (u3)   ld (u2), de   ld (u3), hl #endComment   ld a, (u2)   ld b, a   ld a, (u3)   ld (u2), a   ld a, b   ld (u3), a   ld a, (v2)   ld b, a   ld a, (v3)   ld (v2), a   ld a, b   ld (v3), a Y2SmallerThanY3: ;;;;;;;;;;;;;;;;;;; ;  ld de, 100 ;  or a ;  ld hl, (x1) ;  sbc hl, de ;  ld (x1), hl ;  ld hl, (x2) ;  sbc hl, de ;  ld (x2), hl ;  ld hl, (x3) ;  sbc hl, de ;  ld (x3), hl ;;;;;;;;;;;;;;;;;;;     res 0, (IY)   ;in bit 0, (IY) wordt opgeslagen bij welke helft het is. 0=eerste helft, 1= tweede helft   res 1, (IY)   ;bit 1, (IY) = interval texturen al berekend   ld hl, (y2)   ld de, (y1)   subFP      ;hier gebruikt om 16-bit getallen af te trekken I.P.V. fixed-point getallen   ld h, l   ld l, 0   push hl   ld hl, (x2)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x2)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u2)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v2)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld l, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv3), hl   ld hl, (x1)   bit 7, h   jr z, TPos1   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   ld (tx2+1),hl \ ld a, \$FF \ ld (tx2),a   jr TEnd1 TPos1:   ld (tx1+1),hl \ xor a \ ld (tx1),a ;store the 16bit integer at hl into 16.8 fixed point number tx1   ld (tx2+1),hl \ xor a \ ld (tx2),a TEnd1:   ld hl, (y1)   ld (_ty), hl   ld a, (u1)   ld h, a   ld l, 0   ld (tu1), hl   ld (tu2), hl   ld a, (v1)   ld h, a   ld l, 0   ld (tv1), hl   ld (tv2), hl   ld hl, (Y1)   ld de, (y2)   cpHLDE   jp z, __TEndLoop TDrawLoop:   ld a, (_ty)   ld d, a   bit 7, a   jp nz, Clip   ld a, (_ty)   cp 64   ret nc ;InitScanline:   ld hl, (tu1)   ld (tmpu), hl   ld hl, (tv1)   ld (tmpv), hl   ld hl, (tu2)   ld (temp2), hl   ld hl, (tv2)   ld (temp3), hl   ld a, (tx2+1)   ld (temp+1), a   ld b, a   ld a, (tx1+1)   ld (temp), a   cp b   jr c, TOrdered   ;jp po, TOrdered   ld hl, (tu2)   ld (tmpu), hl   ld hl, (tv2)   ld (tmpv), hl   ld hl, (tu1)   ld (temp2), hl   ld hl, (tv1)   ld (temp3), hl   ld a, (tx2+1)   ld (temp), a   ld a, (tx1+1)   ld (temp+1), a TOrdered:   ld l, d   ld a, (temp)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   call GetPixel   ld (mask), a   ld (pointer), hl   bit 1, (IY)   jr nz, TPlotLoop   ld hl, (tx1)   ld de, (tx2)   cpHLDE   jr z, TPlotLoop   ld a, (temp)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld h, a   ld l, 0   ld a, (temp+1)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpu)   ld de, (temp2)   subFP   pop de   call DivFP   ld (tmpdu), hl   ld a, (temp)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld h, a   ld l, 0   ld a, (temp+1)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpv)   ld de, (temp3)   subFP   pop de   call DivFP   ld (tmpdv), hl   set 1, (IY) TPlotLoop:   ld a, (temp)   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   bit 7, a   jr nz, TEndPlot ;  ld hl, temp ;  inc (hl) ;  ld hl, (tmpu) ;  ld de, (tmpdu) ;  add hl, de ;  ld (tmpu), hl ;  ld hl, (tmpv) ;  ld de, (tmpdv) ;  add hl, de ;  ld (tmpv), hl ;  jp InitScanline ;TNoClip:   cp 96   jp nc, Clip   ld a, (tmpv+1)   add a, a      ;;;;   ld hl, texture   add a, l   ld l, a   ld a, (tmpu+1)   bit 3, a      ;;;;   jr z, TFirstByte   ;;;;   res 3, a      ;;;;   inc hl      ;;;; TFirstByte:      ;;;;   ld b, a   inc b   ld a, (hl) TshiftLoop:   rla   djnz   TshiftLoop     ld a, (mask)   ld hl, (pointer)   jr c, TSetPixel TResPixel:   ;ld a, b   cpl   and (hl)   ld (hl), a   jr TEndPlot TSetPixel:   ;ld a, b   or (hl)   ld (hl), a TEndPlot:   ld hl, mask   rrc (hl)   jr nc, TNoCarry   ld hl, (pointer)   inc hl   ld (pointer), hl TNoCarry:   ld hl, (tmpu)   ld de, (tmpdu)   add hl, de   ld (tmpu), hl   ld hl, (tmpv)   ld de, (tmpdv)   add hl, de   ld (tmpv), hl   ld a, (temp+1)   ;sub 50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld b, a   ld a, (temp)   ;sub 50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ld hl, temp   inc (hl)   cp b   jp nz, TPlotLoop   ;jr c, TPlotLoop   bit 0, (IY)   jr nz, aaaa   res 1, (IY) aaaa: Clip:   ld hl,(tx1)   ld de, (dx1)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx1), hl   ld a, (tx1+2)   adc a, b   ld (tx1+2), a   ld hl,(tx2)   ld de, (dx3)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx2), hl   ld a, (tx2+2)   adc a, b   ld (tx2+2), a   ld hl, (tu1)   ld de, (du1)   add hl, de   ld (tu1), hl   ld hl, (tu2)   ld de, (du3)   add hl, de   ld (tu2), hl   ld hl, (tv1)   ld de, (dv1)   add hl, de   ld (tv1), hl   ld hl, (tv2)   ld de, (dv3)   add hl, de   ld (tv2), hl   ld hl, (_ty)   inc hl   ld (_ty), hl   ld de, (y2)   cpHLDE   jp c, TDrawLoop   bit 0, (IY)   jr nz, _TEnd __TEndLoop:   ;Begin tweede keer tekenen:   ld hl, (y2)   ld (_ty), hl   ld hl, (y3)   ld (y2), hl   ld hl, (dx2)   ld (dx1), hl   ld hl, (du2)   ld (du1), hl   ld hl, (dv2)   ld (dv1), hl   ld hl, (x2)   bit 7, h   jr nz, TPos4   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   jr TEnd4 TPos4:   ld (tx1+1),hl \ xor a \ ld (tx1),a Tend4:   ld a, (u2)   ld h, a   ld l, 0   ld (tu1), hl   ld a, (v2)   ld h, a   ld l, 0   ld (tv1), hl   set 0, (IY)   jp TDrawLoop _TEnd:   ret```

And here's a link to the backup of my project, in case someone wants to see the full code: http://dl.dropbox.com/u/11215358/invasion.z80
Reading through it, I think I need quite a few more passes to make sense of that. I'd say you need a lot more comments, but since they probably wouldn't be in English, I don't know if they'd help. Do you have a reference page that you used for the math for this?
I used a slightely optimized version of the gauroud triangle drawing code on this page, of which I replaced the color values with texture coordinates. I'll also try to add English comments ASAP.
I finished commenting the code. Here is now a fully commented version of the triangle drawing routine:

Code:
```DrawTriangle:   ;IN: x1,y1,u1,v1,x2,y2,u2,v2,x3,y3,u3,v3   ;scherm = 96*64 ;the following code was used to add 100 to the x coordinates, to see if the sign was the problem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;  ld de, 100 ;  ld hl, (x1) ;  add hl, de ;  ld (x1), hl ;  ld hl, (x2) ;  add hl, de ;  ld (x2), hl ;  ld hl, (x3) ;  add hl, de ;  ld (x3), hl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--------------------------------------------------------------- ;   This part sorts the points so that Y1 <= Y2 <= Y3 so ;   we can just draw each scanline below the last one. ;---------------------------------------------------------------   ld hl, (y1)   ld de, (y2)   cpHLDE   jr c, Y1SmallerThanY2   ld (y1), de   ld (y2), hl   ld hl, (x1)   ld de, (x2)   ld (x1), de   ld (x2), hl #comment   ld hl, (u1)   ld de, (u2)   ld (u1), de   ld (u2), hl #endComment   ld a, (u1)   ld b, a   ld a, (u2)   ld (u1), a   ld a, b   ld (u2), a   ld a, (v1)   ld b, a   ld a, (v2)   ld (v1), a   ld a, b   ld (v2), a Y1SmallerThanY2:   ld hl, (y1)   ld de, (y3)   cpHLDE   jr c, Y1SmallerThanY3   ld (y1), de   ld (y3), hl   ld hl, (x1)   ld de, (x3)   ld (x1), de   ld (x3), hl #comment   ld hl, (u1)   ld de, (u3)   ld (u1), de   ld (u3), hl #endcomment   ld a, (u1)   ld b, a   ld a, (u3)   ld (u1), a   ld a, b   ld (u3), a   ld a, (v1)   ld b, a   ld a, (v3)   ld (v1), a   ld a, b   ld (v3), a Y1SmallerThanY3:   ld hl, (y2)   ld de, (y3)   cpHLDE   jr c, Y2SmallerThanY3   ld (y2), de   ld (y3), hl   ld hl, (x2)   ld de, (x3)   ld (x2), de   ld (x3), hl #comment   ld hl, (u2)   ld de, (u3)   ld (u2), de   ld (u3), hl #endComment   ld a, (u2)   ld b, a   ld a, (u3)   ld (u2), a   ld a, b   ld (u3), a   ld a, (v2)   ld b, a   ld a, (v3)   ld (v2), a   ld a, b   ld (v3), a Y2SmallerThanY3: ;   +++++ End of sorting code +++++ ;---------------------------------------------------------- ;   Here, some variables are initialized. The delta ;   variables (the variables which start with a 'd') ;   contain the values that need to be added to ;   the variables which start with a 't'. Variables ;   with a 't' and a '1' are used for the start of ;   the scanline. Those with a 't' and a '2' are used ;   for the end of the scanline. ;----------------------------------------------------------   res 0, (IY)   ;if this bit is 0, the routine is drawing the top half of the triangle. if it's 1, it's drawing the bottom half.   res 1, (IY)   ;This bit is used to store if the deltas for the texture coordinates inside scanlines are already calculated. They are constants, so they only need to be calculated once per half.   ld hl, (y2)   ld de, (y1)   subFP      ;This routine is for substracting fixed-point values, but here it's used to substract integer values.   ld h, l   ld l, 0   push hl   ld hl, (x2)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x2)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld hl, (x3)   ld de, (x1)   subFP   ld h, l   ld l, 0   pop de   call DivFP   ld (dx3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u2)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (u3)   ld h, a   ld l, 0   ld a, (u1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (du3), hl   ld hl, (y2)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v2)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld l, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv1), hl   ld hl, (y3)   ld de, (y2)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v2)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv2), hl   ld hl, (y3)   ld de, (y1)   subFP   ld h, l   ld l, 0   push hl   ld a, (v3)   ld h, a   ld l, 0   ld a, (v1)   ld d, a   ld e, 0   subFP   ;ld h, l   ;ld l, 0   pop de   call DivFP   ld (dv3), hl   ld hl, (x1)   bit 7, h   jr z, TPos1   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   ld (tx2+1),hl \ ld a, \$FF \ ld (tx2),a   jr TEnd1 TPos1:   ld (tx1+1),hl \ xor a \ ld (tx1),a ;store the 16bit integer at hl into 16.8 fixed point number tx1   ld (tx2+1),hl \ xor a \ ld (tx2),a TEnd1:   ld hl, (y1)   ld (_ty), hl   ld a, (u1)   ld h, a   ld l, 0   ld (tu1), hl   ld (tu2), hl   ld a, (v1)   ld h, a   ld l, 0   ld (tv1), hl   ld (tv2), hl ;if Y1 == Y2, then we don't need to draw the first half.   ld hl, (Y1)   ld de, (y2)   cpHLDE   jp z, __TEndLoop ;      +++++ End of initializing code +++++ ;------------------------------------------------------------ ;   This is the loop in which the triangle is drawn. ;   In each interval of the loop, a single scanline is ;   drawn. When this loop finished, one half of the ;   triangle is drawn. ;------------------------------------------------------------ TDrawLoop:   ld a, (_ty)   ld d, a ;if the Y of the scanline is negative, then go to the next one.   bit 7, a   jp nz, Clip   ld a, (_ty) ;If it reaches the bottom of the screen, then stop drawing the triangle.   cp 64   ret nc ;Initialize variables for the scanline   ld hl, (tu1)   ld (tmpu), hl   ld hl, (tv1)   ld (tmpv), hl   ld hl, (tu2)   ld (temp2), hl   ld hl, (tv2)   ld (temp3), hl   ld a, (tx2+1)   ld (temp+1), a   ld b, a   ld a, (tx1+1)   ld (temp), a   cp b   jr c, TOrdered   ;jp po, TOrdered   ld hl, (tu2)   ld (tmpu), hl   ld hl, (tv2)   ld (tmpv), hl   ld hl, (tu1)   ld (temp2), hl   ld hl, (tv1)   ld (temp3), hl   ld a, (tx2+1)   ld (temp), a   ld a, (tx1+1)   ld (temp+1), a TOrdered:   ld l, d   ld a, (temp) ;folowing line was for the test to see if the sign was the problem   ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   call GetPixel   ld (mask), a   ld (pointer), hl ;If the deltas for the texture coordinates inside a scanline are already ;calculated, then calculating them again is a wast of cycles.   bit 1, (IY)   jr nz, TPlotLoop   ld hl, (tx1)   ld de, (tx2)   cpHLDE   jr z, TPlotLoop   ld a, (temp)   ld h, a   ld l, 0   ld a, (temp+1)   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpu)   ld de, (temp2)   subFP   pop de   call DivFP   ld (tmpdu), hl   ld a, (temp)   ld h, a   ld l, 0   ld a, (temp+1)   ld d, a   ld e, 0   subFP   push hl   ld hl, (tmpv)   ld de, (temp3)   subFP   pop de   call DivFP   ld (tmpdv), hl   set 1, (IY) ;--------------------------------------------------------------------- ;   In this loop, the scanline is drawn. One interval here ;   draws one pixel. When the loop ends, one scanline is drawn. ;--------------------------------------------------------------------- TPlotLoop: ;If the x coordinate of the pixel is negative, then go to the next pixel.   ld a, (temp)   bit 7, a   jr nz, TEndPlot ;if the pixel goes of the right side of the screen, then go to the next scanline   cp 96   jp nc, Clip ;Everything with 4 ;'s behind it are for 16x16 textures. Remove those and the ;textures will be 8x8.   ld a, (tmpv+1)   add a, a      ;;;;   ld hl, texture   add a, l   ld l, a   ld a, (tmpu+1)   bit 3, a      ;;;;   jr z, TFirstByte   ;;;;   res 3, a      ;;;;   inc hl      ;;;; TFirstByte:      ;;;;   ld b, a   inc b   ld a, (hl) TshiftLoop:   rla   djnz   TshiftLoop     ld a, (mask)   ld hl, (pointer)   jr c, TSetPixel TResPixel:   ;ld a, b   cpl   and (hl)   ld (hl), a   jr TEndPlot TSetPixel:   ;ld a, b   or (hl)   ld (hl), a TEndPlot:   ld hl, mask   rrc (hl)   jr nc, TNoCarry   ld hl, (pointer)   inc hl   ld (pointer), hl TNoCarry:   ld hl, (tmpu)   ld de, (tmpdu)   add hl, de   ld (tmpu), hl   ld hl, (tmpv)   ld de, (tmpdv)   add hl, de   ld (tmpv), hl   ld a, (temp+1)   ld b, a   ld a, (temp)   ld hl, temp   inc (hl)   cp b   jp nz, TPlotLoop ;      +++++ End of pixel plotting code +++++ ;If it's drawing the secound half, then make it recalculate the thexture deltas ;for inside the scanlines. This was to solve a bug in the texture mapping.   bit 0, (IY)   jr nz, aaaa   ;I suddenly ran out of inspiration for label names   res 1, (IY) aaaa: Clip:   ld hl,(tx1)   ld de, (dx1)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx1), hl   ld a, (tx1+2)   adc a, b   ld (tx1+2), a   ld hl,(tx2)   ld de, (dx3)   ld a, d   rla   sbc a, a   ld b, a   add hl, de   ld (tx2), hl   ld a, (tx2+2)   adc a, b   ld (tx2+2), a   ld hl, (tu1)   ld de, (du1)   add hl, de   ld (tu1), hl   ld hl, (tu2)   ld de, (du3)   add hl, de   ld (tu2), hl   ld hl, (tv1)   ld de, (dv1)   add hl, de   ld (tv1), hl   ld hl, (tv2)   ld de, (dv3)   add hl, de   ld (tv2), hl   ld hl, (_ty)   inc hl   ld (_ty), hl   ld de, (y2)   cpHLDE   jp c, TDrawLoop ;This is the end of the drawing loop ;If the secound half was drawn, then stop this routine.   bit 0, (IY)   jr nz, _TEnd __TEndLoop:   ;Here, some variables are initialized for drawing the secound half.   ld hl, (y2)   ld (_ty), hl   ld hl, (y3)   ld (y2), hl   ld hl, (dx2)   ld (dx1), hl   ld hl, (du2)   ld (du1), hl   ld hl, (dv2)   ld (dv1), hl   ld hl, (x2)   bit 7, h   jr nz, TPos4   ld (tx1+1),hl \ ld a, \$FF \ ld (tx1),a   jr TEnd4 TPos4:   ld (tx1+1),hl \ xor a \ ld (tx1),a Tend4:   ld a, (u2)   ld h, a   ld l, 0   ld (tu1), hl   ld a, (v2)   ld h, a   ld l, 0   ld (tv1), hl   set 0, (IY)   jp TDrawLoop _TEnd:   ret ```

Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

»
» All times are UTC - 5 Hours

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum