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.

Also, I can easely translate the comments to English and add more comments, if that's nessicary.
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

EDIT: I almost forgot to thank you for your fast reply.
Hrm, it probably isn't that, then. Sad 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 Very Happy

EDIT: as you can see, clipping still doesn't work for the left border Sad
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.

» Go to Registration page
Page 1 of 1
» 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

 

Advertisement