home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / POLYBLIT / FTRIBLT.ASM < prev    next >
Assembly Source File  |  1992-02-05  |  8KB  |  415 lines

  1.     TITLE    FASTRI - Fast triangle poly filling blitter
  2.     NAME    FTRIBLT
  3.  
  4.  
  5.     COMMENT    $
  6.  
  7.     Name:        FTRIBLT
  8.  
  9.         Written and (c) by Dave Stampe 9/11/91
  10.         Not for commercial use, so get permission
  11.         before marketing code using this stuff!
  12.         For private PD use only.
  13.  
  14.         $
  15.  
  16.         .MODEL large
  17.  
  18.         .CODE
  19.                 ; big table more eff. than masking
  20.                 ; start byte lookup table
  21. stmask:        REPT    40
  22.         db    0ffh,07fh,03fh,01fh,00fh,007h,003h,001h
  23.         ENDM
  24.                 ; end byte lookup table
  25. fnmask:         REPT    40
  26.         db      080h,0c0h,0e0h,0f0h,0f8h,0fch,0feh,0ffh
  27.         ENDM
  28.  
  29.     extrn    _dpaddr        ; page base address
  30.  
  31. x1    equ    [bp+6]          ; arguments to _tpoly
  32. y1    equ    [bp+8]
  33. x2    equ    [bp+10]
  34. y2    equ    [bp+12]
  35. x3    equ    [bp+14]
  36. y3     equ    [bp+16]
  37.  
  38.  
  39. vline   equ    [bp-2]       ; video base addr. of line
  40. lines    equ    [bp-4]        ; number of lines to fill
  41. l_incr    equ    [bp-8]
  42. r_incr    equ    [bp-12]
  43.  
  44.    ;
  45.    ;   fastri(int x1,int y1, int x2, int y2, int x3, int y3)
  46.    ;       vertices must be in CCW order!
  47.  
  48.         PUBLIC    _fastri
  49.  
  50. _fastri    proc    far
  51.  
  52.     .386
  53.     push    bp
  54.     mov    bp,sp
  55.     sub    sp,16
  56.     push    si
  57.     push    di
  58.  
  59.     mov    eax,x1    ; consider as 32-bit hash: look for top, then left
  60.     mov    ebx,x2
  61.     mov    ecx,x3
  62.     cmp    ebx,eax
  63.     jae    nrot1
  64.     xchg    eax,ebx    ; rotate till top-left is at head of list
  65.     xchg    ebx,ecx
  66.     cmp    ebx,eax
  67.     jae    donerot
  68.     xchg    eax,ebx
  69.     xchg    ebx,ecx
  70.     jmp    donerot
  71.  
  72. nrot1:    cmp    ecx,eax
  73.     jae    donerot
  74.     xchg    eax,ecx
  75.     xchg    ebx,ecx
  76.  
  77. donerot:
  78.     mov    x1,eax
  79.     mov    x2,ebx
  80.     mov    x3,ecx
  81.  
  82.     cld
  83.     mov    ax,0a000h               ; set video segment
  84.     mov    es,ax
  85.     mov    al,y1
  86.     mov    bl,40                   ; compute starting line adr
  87.     mul    bl
  88.     add    ax,WORD PTR ds:_dpaddr
  89.     mov    vline,ax
  90.  
  91.     mov    ax,y1     ; determine config. of vertices: one of:
  92.     cmp    ax,y3
  93.     jz    flattop
  94.     mov    ax,y2     ; 1  3      1      1      1
  95.     cmp    ax,y3     ;                2          3
  96.     jz    flatbot   ;  2      2  3     3     2
  97.     jb    onleft
  98.     jmp    onright
  99.  
  100. flatbot:
  101.     movzx    ecx,word ptr y2       ; check for sliver poly
  102.     sub    cx,y1
  103.     jz    finished
  104.     mov    lines,cx
  105.     mov    ax,x2
  106.     sub    ax,x1
  107.     movsx    eax,ax      ; conv. to double prec. << 16
  108.     je    roundpl1    ; zero slope
  109.     cmp    cx,1
  110.     je    roundpl1
  111.     cdq
  112.     shl    eax,16        ; (x2-x1)/(y2-y1)
  113.     idiv    ecx
  114.     cmp        eax,0       ; round up if pos (neg already rounded up)
  115.     jle    roundpl1
  116.     inc    eax
  117. roundpl1:
  118.     mov    l_incr,eax
  119.  
  120.     mov    ax,x3
  121.     sub    ax,x1
  122.     movsx    eax,ax      ; conv. to double prec. << 16
  123.     je    roundpl2    ; zero slope
  124.     cmp    cx,1
  125.     je    roundpl2
  126.     cdq
  127.     shl    eax,16        ; (x2-x1)/(y2-y1)
  128.     idiv    ecx
  129.     cmp        eax,0       ; round up if pos (neg already rounded up)
  130.     jle    roundpl2
  131.     inc    eax
  132. roundpl2:
  133.     mov    r_incr,eax
  134.     cmp    eax,l_incr
  135.     jz    finished        ; sliver: don't bother
  136.  
  137.     mov    dx,x1            ; compute L,R start
  138.     mov    cx,dx
  139.     shl    edx,16
  140.     mov    bx,cx
  141.     mov    esi,edx
  142.     add    edx,08000h             ; force left side to round up
  143.  
  144.     call    near ptr trapezoid
  145.     jmp    finished
  146.  
  147. flattop:
  148.     movzx    ecx,word ptr y2       ; check for sliver poly
  149.     sub    cx,y1
  150.     jz    finished
  151.     mov    lines,cx
  152.     mov    ax,x2
  153.     sub    ax,x1
  154.     movsx    eax,ax      ; conv. to double prec. << 16
  155.     je    roundpl3    ; zero slope
  156.     cmp    cx,1
  157.     je    roundpl3    ; no slope needed if 1 line only
  158.     cdq
  159.     shl    eax,16        ; (x2-x1)/(y2-y1)
  160.     idiv    ecx
  161.     cmp        eax,0       ; round up if pos (neg already rounded up)
  162.     jle    roundpl3
  163.     inc    eax
  164. roundpl3:
  165.     mov    l_incr,eax
  166.  
  167.     mov    ax,x2
  168.     sub    ax,x3
  169.     movsx    eax,ax      ; conv. to double prec. << 16
  170.     je    roundpl4    ; zero slope
  171.     cmp    cx,1
  172.     je    roundpl4    ; no slope needed if 1 line only
  173.     cdq
  174.     shl    eax,16        ; (x2-x1)/(y2-y1)
  175.     idiv    ecx
  176.     cmp        eax,0       ; round up if pos (neg already rounded up)
  177.     jle    roundpl4
  178.     inc    eax
  179. roundpl4:
  180.     mov    r_incr,eax
  181.     cmp    eax,l_incr
  182.     jz    finished        ; sliver: don't bother
  183.  
  184.     movzx    edx,word ptr x1             ; compute L,R start
  185.     mov    bx,dx
  186.     shl    edx,16
  187.     add    edx,08000h             ; force left side to round up
  188.     movzx    esi,word ptr x3
  189.     mov    cx,si
  190.     shl    esi,16
  191.  
  192.     call    near ptr trapezoid
  193.     jmp    finished
  194.  
  195. onleft:
  196.     movzx    ecx,word ptr y2       ; compute first slice height
  197.     sub    cx,y1
  198.     je    finished    ; sliver poly
  199.     mov    lines,cx
  200.     mov    ax,x2
  201.     sub    ax,x1
  202.     movsx    eax,ax      ; conv. to double prec. << 16
  203.     je    roundpl5    ; zero slope
  204.     cmp    cx,1
  205.     je    roundpl5
  206.     cdq
  207.     shl    eax,16        ; (x2-x1)/(y2-y1)
  208.     idiv    ecx
  209.     cmp        eax,0       ; round up if pos (neg already rounded up)
  210.     jle    roundpl5
  211.     inc    eax
  212. roundpl5:
  213.     mov    l_incr,eax
  214.  
  215.     movzx    ecx,word ptr y3
  216.     sub    cx,y1
  217.     mov    ax,x3
  218.     sub    ax,x1
  219.     movsx    eax,ax      ; conv. to double prec. << 16
  220.     je    roundpl6    ; zero slope
  221.     cmp    cx,1
  222.     je    roundpl6
  223.     cdq
  224.     shl    eax,16        ; (x2-x1)/(y2-y1)
  225.     idiv    ecx
  226.     cmp        eax,0       ; round up if pos (neg already rounded up)
  227.     jle    roundpl6
  228.     inc    eax
  229. roundpl6:
  230.     mov    r_incr,eax
  231.     cmp    eax,l_incr
  232.     jz    finished        ; sliver: don't bother
  233.  
  234.     mov    dx,x1            ; compute L,R start
  235.     mov    cx,dx
  236.     shl    edx,16
  237.     mov    bx,cx
  238.     mov    esi,edx
  239.     add    edx,08000h             ; force left side to round up
  240.  
  241.     call    near ptr trapezoid
  242.     push    esi        ; save full precison right side
  243.  
  244.     movzx    ecx,word ptr y3       ; compute second slice height
  245.     sub    cx,y2
  246.     mov    lines,cx
  247.     mov    ax,x3
  248.     sub    ax,x2
  249.     movsx    eax,ax      ; conv. to double prec. << 16
  250.     je    roundpl7    ; zero slope
  251.     cmp    cx,1
  252.     je    roundpl7
  253.     cdq
  254.     shl    eax,16        ; (x2-x1)/(y2-y1)
  255.     idiv    ecx
  256.     cmp        eax,0       ; round up if pos (neg already rounded up)
  257.     jle    roundpl7
  258.     inc    eax
  259. roundpl7:
  260.     mov    l_incr,eax   ; change left increment
  261.  
  262.     pop    esi
  263.     mov    ecx,esi         ; restore right side
  264.     shr    ecx,16
  265.  
  266.     movzx    edx,word ptr x2             ; compute L start
  267.     mov    bx,dx
  268.     shl    edx,16
  269.     add    edx,08000h        ; force left side to round up
  270.  
  271.     call    near ptr trapezoid
  272.     jmp    finished
  273.  
  274. onright:
  275.     movzx    ecx,word ptr y2       ; compute first slice height
  276.     sub    cx,y1
  277.     je    finished
  278.     mov    ax,x2
  279.     sub    ax,x1
  280.     movsx    eax,ax      ; conv. to double prec. << 16
  281.     je    roundpl8    ; zero slope
  282.     cmp    cx,1
  283.     je    roundpl8
  284.     cdq
  285.     shl    eax,16        ; (x2-x1)/(y2-y1)
  286.     idiv    ecx
  287.     cmp        eax,0       ; round up if pos (neg already rounded up)
  288.     jle    roundpl8
  289.     inc    eax
  290. roundpl8:
  291.     mov    l_incr,eax
  292.  
  293.     movzx    ecx,word ptr y3       ; compute first slice height
  294.     sub    cx,y1
  295.     mov    lines,cx
  296.     mov    ax,x3
  297.     sub    ax,x1
  298.     movsx    eax,ax      ; conv. to double prec. << 16
  299.     je    roundpl9    ; zero slope
  300.     cmp    cx,1
  301.     je    roundpl9
  302.     cdq
  303.     shl    eax,16        ; (x2-x1)/(y2-y1)
  304.     idiv    ecx
  305.     cmp        eax,0       ; round up if pos (neg already rounded up)
  306.     jle    roundpl9
  307.     inc    eax
  308. roundpl9:
  309.     mov    r_incr,eax
  310.     cmp    eax,l_incr
  311.     jz    finished        ; sliver: don't bother
  312.  
  313.     mov    dx,x1           ; compute L,R start
  314.     mov    cx,dx
  315.     shl    edx,16
  316.     mov    bx,cx
  317.     mov    esi,edx
  318.     add    edx,08000h             ; force left side to round up
  319.  
  320.     call    near ptr trapezoid
  321.     push    edx        ; save full precison left side
  322.  
  323.     movzx    ecx,word ptr y2       ; compute second slice height
  324.     sub    cx,y3
  325.     mov    lines,cx
  326.     mov    ax,x2
  327.     sub    ax,x3
  328.     movsx    eax,ax      ; conv. to double prec. << 16
  329.     je    roundpla    ; zero slope
  330.     cmp    cx,1
  331.     je    roundpla
  332.     cdq
  333.     shl    eax,16        ; (x2-x1)/(y2-y1)
  334.     idiv    ecx
  335.     cmp        eax,0       ; round up if pos (neg already rounded up)
  336.     jle    roundpla
  337.     inc    eax
  338. roundpla:
  339.     mov    r_incr,eax   ; change left increment
  340.  
  341.     pop    edx
  342.     mov    ebx,edx         ; restore left side
  343.     shr    ebx,16
  344.  
  345.     movzx    esi,word ptr x3             ; compute R start
  346.     mov    cx,si
  347.     shl    esi,16
  348.  
  349.     call    near ptr trapezoid
  350.     jmp    finished
  351.  
  352.  
  353. finished:
  354.     pop    di                         ; exit code
  355.     pop    si
  356.     mov    sp,bp
  357.     pop    bp
  358.     ret
  359.  
  360. _fastri    endp
  361.  
  362.  
  363.  
  364. trapezoid:    ; call with  bx = left, cx = right
  365.         ; edx = (left+0.5)>>16, esi = right<<16
  366.         ; vline, lines, l_incr, r_incr all set up
  367.  
  368. nextline:
  369.         ; start of fast h line blitter:
  370.         ;  bx=left side, cx=right side, vline=line start
  371.  
  372.     mov    al,BYTE PTR cs:[bx+stmask]  ; left mask
  373.     shr    bx,3                        ; left address
  374.  
  375.     mov    di,cx
  376.     mov    ah,BYTE PTR cs:[di+fnmask]  ; right mask
  377.     shr    cx,3                        ; right address
  378.  
  379.     mov    di,vline            ; start address
  380.     add    di,bx
  381.     sub    cx,bx                       ; number of bytes-1
  382.     je    short onebyte
  383.     jc    short doneline              ; clip trap
  384.  
  385.     and    es:[di],al                  ; mask first byte
  386.     inc    di
  387.     dec    cx                          ; mask rest
  388.     mov    al,0ffh                     ; rep faster than test and jmp
  389.     rep    stosb                       ; for zero byte case
  390.     and    es:[di],ah                  ; mask last byte
  391.     jmp    short doneline
  392.  
  393. onebyte:
  394.     and    al,ah
  395.     and    es:[di],al        ; single byte mask
  396.  
  397. doneline:
  398.     mov    ax,40                   ; next line address
  399.     add    vline,ax
  400.  
  401.     add    edx,DWORD PTR l_incr    ; step left, right edges
  402.     add    esi,DWORD PTR r_incr
  403.     mov    ebx,edx            ; convert fixed pt to integer
  404.     sar    ebx,16
  405.     mov    ecx,esi
  406.     sar    ecx,16
  407.  
  408.     dec    WORD PTR lines          ; done lines?
  409.     jg    short nextline
  410.  
  411. donetri:                                ; finished all drawing
  412. exit:
  413.     retn
  414.  
  415.     end