0 Members and 1 Guest are viewing this topic.
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, (x1) call Signed16To8 ld h, $FF ld l, a ld (x1), hl ld hl, (x2) call Signed16To8 ld h, $FF ld l, a ld (x2), hl ld hl, (x3) call Signed16To8 ld h, $FF ld l, a ld (x3), hl ld hl, (y1) ld de, (y2) cpHLDE jr c, Y1SmallerThanY2 ld hl, x1 ld de, dx1 ;temp location ld bc, 6 ;size ldir ld hl, x2 ld de, x1 ld bc, 6 ldir ld hl, dx1 ld de, x2 ld bc, 6 ldirY1SmallerThanY2: ld hl, (y1) ld de, (y3) cpHLDE jr c, Y1SmallerThanY3 ld hl, x1 ld de, dx1 ;temp location ld bc, 6 ;size ldir ld hl, x3 ld de, x1 ld bc, 6 ldir ld hl, dx1 ld de, x3 ld bc, 6 ldirY1SmallerThanY3: ld hl, (y2) ld de, (y3) cpHLDE jr c, Y2SmallerThanY3 ld hl, x2 ld de, dx1 ;temp location ld bc, 6 ;size ldir ld hl, x3 ld de, x2 ld bc, 6 ldir ld hl, dx1 ld de, x3 ld bc, 6 ldirY2SmallerThanY3:; +++++ 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 TEnd1TPos1: 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),aTEnd1: 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 add a, 128 ld b, a ld a, (tx1+1) ld (temp), a add a, 128 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), aTOrdered: ld l, d ld a, (temp);folowing line was for the test to see if the sign was the problem ;sub 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bit 7, a jr z, TGetPixel xor aTGetPixel: 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, TNoCarry;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, TSetPixelTResPixel: ;ld a, b cpl and (hl) ld (hl), a jr TEndPlotTSetPixel: ;ld a, b or (hl) ld (hl), aTEndPlot: ld hl, mask rrc (hl) jr nc, TNoCarry ld hl, (pointer) inc hl ld (pointer), hlTNoCarry: 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 TEnd4TPos4: ld (tx1+1),hl \ xor a \ ld (tx1),aTend4: 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: retgetPixel: bit 7, a ret nz bit 7, l ret nz ld h, 0 ld d, h ld e, l add hl, hl add hl, de add hl, hl add hl, hl ld e, a srl e srl e srl e add hl, de ld de, PlotSScreen add hl, de and 7 ld b, a ld a, $80 ret z rrca djnz $-1 ret