home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / FPOLY16 / FPBLIT.ASM < prev    next >
Assembly Source File  |  1991-11-09  |  7KB  |  328 lines

  1.     TITLE    FPBLIT - Fast poly filling blitter
  2.     NAME    FPBLIT
  3.  
  4.  
  5.     COMMENT    $
  6.  
  7.     Name:        FPBLIT
  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.     COMMENT    $
  17.  
  18.     Name:        tpoly
  19.  
  20.     Caller:        C:
  21.  
  22.             int tpoly(int x1, int x2, long l_incr, long r_incr,
  23.                   int y1, int y3, int hold);
  24.  
  25.             x1 = left side start, x2 = right side start
  26.              if 0x8000, uses end of last poly's side for cont.
  27.             y1 = top, y2 = 1+bottom of poly slice
  28.             l_incr, r_incr = 2^16 times slope (add to x each line)
  29.             hold: 0 = normal, 1 = make sure left is OK
  30.                       2 = make sure right is OK
  31.                       (for continuation)
  32.  
  33.         $
  34.  
  35.  
  36.         .MODEL large
  37.  
  38.         .CODE
  39.                 ; big table more eff. than masking
  40.                 ; start byte lookup table
  41. stmask:        REPT    40
  42.         db    0ffh,07fh,03fh,01fh,00fh,007h,003h,001h
  43.         ENDM
  44.                 ; end byte lookup table
  45. fnmask:         REPT    40
  46.         db      080h,0c0h,0e0h,0f0h,0f8h,0fch,0feh,0ffh
  47.         ENDM
  48.  
  49.  
  50. x1    equ    [bp+6]          ; arguments to _tpoly
  51. x2    equ    [bp+8]
  52. l_incr    equ    [bp+10]
  53. r_incr    equ    [bp+14]
  54. y1    equ    [bp+18]
  55. y3    equ    [bp+20]
  56. hold    equ    [bp+22]
  57.  
  58. vline   equ    [bp-2]       ; video base addr. of line
  59. lines    equ    [bp-4]        ; number of lines to fill
  60. clipped    equ    [bp-6]        ; flags clipped poly (needs end recalc)
  61.  
  62.     extrn    _l_hold         ; holds full res. L, R. point
  63.     extrn    _r_hold
  64.  
  65.     extrn    _t_clip         ; clipping rect. sides
  66.     extrn    _b_clip
  67.     extrn    _l_clip
  68.     extrn    _r_clip
  69.  
  70.     extrn    _dpaddr        ; page base address
  71.  
  72.    ;
  73.    ;    tpoly(int x1,int x2, long l_incr, long r_incr,
  74.    ;                 int y1, int y3, int hold)
  75.    ;
  76.  
  77.         PUBLIC    _tpoly
  78.  
  79. _tpoly    proc    far
  80.  
  81.     .386
  82.     push    bp
  83.     mov    bp,sp
  84.     sub    sp,6
  85.     push    si
  86.     push    di
  87.  
  88.     mov    word ptr clipped,0
  89.  
  90.     mov    ax,word ptr y3           ; if(y3-y1<1)return(-1);
  91.     sub    ax,word ptr y1
  92.     cmp    ax,1
  93.     jge    short continue
  94.  
  95.     mov    ax,65535               ; return -1 on bad args
  96.     jmp    exit
  97.  
  98. continue:
  99.     cld
  100.     mov    ax,0a000h              ; set video segment
  101.     mov    es,ax
  102.  
  103.     mov    edx,DWORD PTR ds:_l_hold
  104.     mov    ax,x1
  105.     cmp    ax,8000h               ; old or new left side
  106.     je    short nlload
  107.     mov    dx,ax
  108.     shl    edx,16
  109.     add    edx,08000h             ; force left side to round up
  110. nlload:
  111.     mov    esi,DWORD PTR ds:_r_hold
  112.     mov    ax,x2
  113.     cmp    ax,8000h               ; old or new right
  114.     je    short nrload
  115.     mov    si,ax
  116.     shl    esi,16
  117. nrload:
  118.     mov    bx,y1
  119.     cmp    bx,WORD PTR ds:_b_clip   ; trivial vertical clip tests
  120.     jg    clipall
  121.     mov    ax,y3
  122.     cmp    ax,WORD PTR ds:_t_clip
  123.     jle    short clipall
  124.     cmp    ax,WORD PTR ds:_b_clip    ; test if next-slice update
  125.     jl    short okbot               ; will be required
  126.     inc    WORD PTR clipped
  127.     mov    ax,WORD PTR ds:_b_clip
  128.     mov    y3,ax
  129. okbot:
  130.                     ; test if top needs clipping
  131.     sub    bx,WORD PTR ds:_t_clip
  132.     jge    short oktop
  133.     mov    ax,WORD PTR ds:_t_clip
  134.     mov    y1,ax
  135.     neg    bx                      ; adjust left, right sides for
  136.     movzx    ebx,bx                  ; top of screen
  137.  
  138.     push    edx
  139.     mov    eax,DWORD PTR r_incr    ;advance right top
  140.     imul    eax,ebx
  141.     add    esi,eax
  142.  
  143.     mov    eax,DWORD PTR l_incr    ; advance left top
  144.     imul    eax,ebx
  145.     pop    edx
  146.     add    edx,eax
  147.  
  148. oktop:
  149.     mov    ax,y3                   ; compute # lines
  150.     sub    ax,y1
  151.     jle    short clipall           ; bad clip trap
  152.  
  153.     mov    lines,ax
  154.     mov    al,y1
  155.     mov    bl,40                   ; compute starting line adr
  156.     mul    bl
  157.     add    ax,WORD PTR ds:_dpaddr
  158.     mov    vline,ax
  159.  
  160.     mov    ebx,edx                 ; convert fixed-pt to integer
  161.     sar    ebx,16
  162.     mov    ecx,esi
  163.     sar    ecx,16
  164.     jl    short doneline          ; preclip left trap
  165.  
  166.     cmp    bx,WORD PTR ds:_l_clip  ; clip left
  167.     jge    short iclipl
  168.     mov    bx,WORD PTR ds:_l_clip
  169.  
  170. iclipl:
  171.     cmp    cx,WORD PTR ds:_r_clip  ; clip right
  172.     jle    short nextline
  173.     mov    cx,WORD PTR ds:_r_clip
  174.     jmp    short nextline
  175.  
  176. clipall:
  177.     inc    WORD PTR clipped        ; mark as clipped (none showing)
  178.     jmp    donetri
  179.  
  180. nextline:
  181.         ; start of fast h line blitter:
  182.         ;  bx=left side, cx=right side, vline=line start
  183.  
  184.     mov    al,BYTE PTR cs:[bx+stmask]  ; left mask
  185.     shr    bx,3                        ; left address
  186.  
  187.     mov    di,cx
  188.     mov    ah,BYTE PTR cs:[di+fnmask]  ; right mask
  189.     shr    cx,3                        ; right address
  190.  
  191.     mov    di,vline            ; start address
  192.     add    di,bx
  193.     sub    cx,bx                       ; number of bytes-1
  194.     je    short onebyte
  195.     jc    short doneline              ; clip trap
  196.  
  197.     and    es:[di],al                  ; mask first byte
  198.     inc    di
  199.     dec    cx                          ; mask rest
  200.     mov    al,0ffh                     ; rep faster than test and jmp
  201.     rep    stosb                       ; for zero byte case
  202.     and    es:[di],ah                  ; mask last byte
  203.     jmp    short doneline
  204.  
  205. onebyte:
  206.     and    al,ah
  207.     and    es:[di],al        ; single byte mask
  208.  
  209. doneline:
  210.     add    edx,DWORD PTR l_incr    ; step left, right edges
  211.     add    esi,DWORD PTR r_incr
  212.  
  213.     dec    WORD PTR lines          ; done lines?
  214.     jle    short donetri
  215.     mov    ax,40                   ; next line address
  216.     add    vline,ax
  217.  
  218.     mov    ebx,edx            ; convert fixed pt to integer
  219.     sar    ebx,16
  220.     mov    ecx,esi
  221.     sar    ecx,16
  222.     jl    short doneline          ; left preclip
  223.     cmp    bx,WORD PTR ds:_l_clip  ; clip left edge
  224.     jge    short nclipl
  225.     mov    bx,WORD PTR ds:_l_clip
  226.  
  227. nclipl:
  228.     cmp    cx,WORD PTR ds:_r_clip  ; clip right edge
  229.     jle    short nextline
  230.     mov    cx,WORD PTR ds:_r_clip
  231.     jmp    nextline
  232.  
  233. donetri:                                ; finished all drawing
  234.     mov    edi,edx
  235.     test    WORD PTR hold,0ffh      ; check if L,R pos'ns need
  236.     je    short nofixup           ; fixing because of clipping
  237.     test    WORD PTR clipped, 0ffh
  238.     je    short nofixup
  239.  
  240.     mov    bx,y3                   ; number of lines vertically
  241.     sub    bx,y1
  242.     movzx    ebx,bx
  243.  
  244.     test    WORD PTR hold,2        ; right update needed?
  245.     je    short nofixrt           ; (use hold flags as this is an
  246.     mov    eax,DWORD PTR r_incr    ;  expensive operation)
  247.     imul    eax,ebx
  248.     mov    si,x1
  249.     shl    esi,16
  250.     cmp    esi,80000000h              ; add to old edge or new edge?
  251.     jne    short rlold
  252.     mov    esi,DWORD PTR ds:_r_hold
  253. rlold:
  254.     add    esi,eax
  255.  
  256. nofixrt:
  257.     test    WORD PTR hold,1            ; left update needed?
  258.     je    short nofixup
  259.     mov    eax,DWORD PTR l_incr
  260.     imul    eax,ebx
  261.     mov    di,x2
  262.     shl    edi,16
  263.     add    edi,8000h
  264.     cmp    edi,80008000h              ; add to old or new edge?
  265.     jne    short llold
  266.     mov    edi,DWORD PTR ds:_l_hold
  267. llold:
  268.     add    edi,eax
  269.  
  270. nofixup:
  271.     mov    DWORD PTR ds:_l_hold,edi   ; store edge points in case
  272.     mov    DWORD PTR ds:_r_hold,esi   ; needed for next poly slice
  273. exit:
  274.     pop    di                         ; exit code
  275.     pop    si
  276.     mov    sp,bp
  277.     pop    bp
  278.     ret
  279.  
  280. _tpoly    endp
  281.  
  282.  
  283.    ;
  284.    ;    long compute_slope(int x1, int y1, int x2, int y2)
  285.    ;
  286.  
  287. y1    equ    [bp+8]
  288. y2    equ    [bp+12]
  289. x1    equ    [bp+6]
  290. x2    equ    [bp+10]
  291.  
  292.     PUBLIC    _compute_slope
  293.  
  294. _compute_slope    proc    far
  295.  
  296.     push    bp        ; computes slope (dy incrementor)
  297.     mov    bp,sp           ; with 16-bit underflow
  298.     sub    sp,4
  299.     .386
  300.     xor    ecx,ecx
  301.     mov    cx,y2
  302.     sub    cx,y1
  303.     je    short @5@386    ; skip if zero divide (special case)
  304.     mov    ax,x2           ; detected later by y1==y2 test
  305.     sub    ax,x1
  306.     cwd
  307.     movsx    eax,ax      ; (x2-x1)/(y2-y1)
  308.     movsx    edx,dx
  309.     shl    eax,16
  310.     idiv    ecx
  311.     cmp        eax,0       ; round up if pos (neg already rounded up)
  312.     jle    short @5@386
  313.     inc    eax
  314. @5@386:                         ; return long value (286 style)
  315.     mov    [bp-4],eax
  316.     mov    dx,word ptr [bp-2]
  317.     mov    ax,word ptr [bp-4]
  318.     mov    sp,bp
  319.     pop    bp
  320.     ret
  321.  
  322. _compute_slope    endp
  323.  
  324.  
  325.     end
  326.  
  327.  
  328.