home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / DRV256 / FMULTPX.ASM < prev    next >
Assembly Source File  |  1993-05-02  |  7KB  |  372 lines

  1.     TITLE    FASTMULP - Fast multisided convex poly filling blitter
  2.     NAME    FMULTPX
  3.  
  4.  
  5.     COMMENT    $
  6.  
  7.     Name:        FMULTPX
  8.  
  9.         Written and (c) by Dave Stampe 27/5/92
  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.         .DATA
  19.  
  20. lverts        dd 40 dup (0AAh)
  21. rverts        dd 40 dup (0BBh)
  22.  
  23.         .CODE
  24.                 ; big table more eff. than masking
  25.                 ; start byte lookup table
  26. stmask:        REPT    80
  27.         db    15,14,12,8
  28.         ENDM
  29.                 ; end byte lookup table
  30. fnmask:         REPT    80
  31.         db      1,3,7,15
  32.         ENDM
  33.  
  34.     extrn    _dpaddr        ; page base address
  35.  
  36. nv    equ    [bp+6]          ; arguments to _tpoly
  37. verts    equ    [bp+8]
  38. color    equ    [bp+12]
  39.  
  40. vline   equ    [bp-2]       ; video base addr. of line
  41. lines    equ    [bp-4]        ; number of lines to fill
  42. l_incr    equ    [bp-8]
  43. r_incr    equ    [bp-12]
  44. aswap   equ     [bp-16]        ; plane mask reg. swap value
  45. lptr    equ    [bp-18]
  46. rptr    equ    [bp-20]
  47. cur_y    equ    [bp-22]
  48.  
  49.  
  50.    ;
  51.    ;   fastpoly(int count, int far *vertices)
  52.    ;       vertices must be in CCW order and x,y order!
  53.  
  54.         PUBLIC    _fastpoly
  55.  
  56. _fastpoly    proc    far
  57.  
  58.     .386
  59.     push    bp
  60.     mov    bp,sp
  61.     sub    sp,30
  62.     push    si
  63.     push    di
  64.     push    dx
  65.     push    cx         ; CREATE L, R SIDE LISTS OF VERTICES
  66.  
  67.     les    si,verts         ; find lowest y (any vertex on top of poly)
  68.     mov    cx,nv
  69.     mov    ax,30000
  70. fmin:
  71.     cmp    ax,es:[si+2]
  72.     jl    notlower
  73.     mov    ax,es:[si+2]
  74.     mov    bx,si
  75.     mov    dx,cx
  76. notlower:
  77.     add    si,4
  78.     loop    fmin
  79.  
  80.     mov    cx,dx
  81.     mov    si,bx
  82.     mov    di,OFFSET lverts
  83. clsloop:                            ; copy from lowest to end
  84.     mov    eax,es:[si]
  85.     mov    ds:[di],eax
  86.     add    si,4
  87.     add    di,4
  88.     loop    clsloop
  89.  
  90.     mov    si,verts
  91. cleloop:                            ; copy from start to lowest
  92.     mov    eax,es:[si]
  93.     mov    ds:[di],eax
  94.     add    si,4
  95.     add    di,4
  96.     cmp    si,bx
  97.     jb    cleloop
  98.  
  99.     mov    si,OFFSET lverts    ; right list in reverse order
  100.     mov     lptr,si
  101.     mov    di,OFFSET rverts    ; except first element same
  102.     mov     rptr,di
  103.     mov    eax,ds:[si]
  104.     mov    ds:[di],eax
  105.     add    si,4
  106.     add    di,4
  107.     mov    cx,nv
  108.     dec    cx
  109.     add    di,cx
  110.     add    di,cx
  111.     add    di,cx
  112.     add    di,cx
  113.     mov    ax,-1
  114.     mov    ds:[di+2],ax        ; "stopper"
  115. crrloop:                            ; copy remaining elements
  116.     sub    di,4
  117.     mov    eax,ds:[si]
  118.     mov    ds:[di],eax
  119.     add    si,4
  120.     loop    crrloop
  121.     mov    ax,-1
  122.     mov    WORD PTR ds:[si+4],-1
  123.                   ; VIDEO SETUP
  124.     cld
  125.     mov    ax,03c5h        ; setup DX adr. swap value
  126.     mov    aswap,ax
  127.     mov    ax,0a000h               ; set video segment
  128.     mov    es,ax
  129.     mov    bh,0FFh            ; load color to latches
  130.     mov    bl, BYTE PTR color
  131.     mov    al,es:[bx]
  132.     mov    ax,WORD PTR [lverts+2]           ; set current line
  133.     mov     cur_y,ax
  134.     mov    bl,80                   ; compute starting line adr
  135.     mul    bl
  136.     add    ax,WORD PTR ds:_dpaddr
  137.     mov    vline,ax
  138.  
  139.     mov    cx,nv          ; FIND FIRST EDGES IN POLY
  140.     dec    cx
  141.     mov    bx,lptr
  142. lslinit:
  143.     push    cx
  144.     call    near ptr slope    ; find first left edge
  145.     pop    cx
  146.     jnz    lfinit
  147.     add    bx,4
  148.     loop    lslinit
  149.  
  150.     pop    cx                ; unable to find next line: exit
  151.     pop    dx
  152.     pop    di
  153.     pop    si
  154.     mov    sp,bp
  155.     pop    bp
  156.     ret
  157.  
  158. lfinit:
  159.     mov    l_incr,eax
  160.     mov    lptr,bx
  161.  
  162.     mov    dx,[bx]           ; compute L start
  163.     shl    edx,16
  164. ;    add    edx,08000h        ; force left side to round up
  165.  
  166.     mov    bx,rptr
  167. rslinit:
  168.     call    near ptr slope    ; find first right edge
  169.     jnz    rfinit
  170.     add    bx,4
  171.     jmp    rslinit
  172. rfinit:
  173.     mov    r_incr,eax
  174.     mov    rptr,bx
  175.  
  176.     mov    si,[bx]         ; compute R start
  177.     shl    esi,16
  178.  
  179.                 ; POLY SLICE LOOP
  180. sliceloop:
  181.     mov    bx,rptr
  182.     mov    ax,[bx+6]    ; bottom of right edge
  183.     mov    bx,lptr
  184.     cmp    ax,[bx+6]    ; bottom of left edge
  185.     jb    fbots
  186.     mov    ax,[bx+6]
  187. fbots:
  188.     mov    cx,ax
  189.     sub    cx,cur_y                ; figure line count
  190.     mov    cur_y,ax
  191.     mov    lines,cx
  192.     call    near ptr trapezoid    ; draw it
  193.  
  194.     mov    bx,lptr
  195.     mov    ax,cur_y
  196.     cmp     ax,[bx+6]        ; left edge ended?
  197.     jnz    not_left
  198.  
  199. fll:
  200.     add    bx,4
  201.     call    near ptr slope
  202.     jl    end_poly        ; no more left edges
  203.     jnz    fleft
  204.     jmp    fll
  205. fleft:
  206.     mov    l_incr,eax
  207.     mov    lptr,bx
  208.     mov    dx,[bx]           ; compute L start
  209.     shl    edx,16
  210. ;    add    edx,08000h        ; force left side to round up
  211.  
  212. not_left:
  213.     mov    bx,rptr
  214.     mov    ax,cur_y
  215.     cmp    ax,[bx+6]
  216.     jnz    not_right
  217.  
  218. frl:
  219.     add    bx,4
  220.     call    near ptr slope
  221.     jl    end_poly      ; no more left edges
  222.     jnz    freft
  223.     jmp    frl
  224. freft:
  225.     mov    r_incr,eax
  226.     mov    rptr,bx
  227.     mov    si,[bx]           ; compute R start
  228.     shl    esi,16
  229.  
  230. not_right:
  231.     jmp    sliceloop
  232.  
  233. end_poly:
  234.     pop    cx
  235.     pop    dx
  236.     pop    di                ; exit code
  237.     pop    si
  238.     mov    sp,bp
  239.     pop    bp
  240.     ret
  241.  
  242. _fastpoly    endp
  243.  
  244.  
  245.  
  246.  
  247.  
  248. trapezoid:    ; call with edx = (left+0.5)>>16, esi = right<<16
  249.         ; vline, lines, l_incr, r_incr all set up
  250.  
  251.     mov    ebx,edx            ; convert fixed pt to integer
  252.     sar    ebx,16
  253.     mov    ecx,esi
  254.     sar    ecx,16
  255.  
  256. nextline:
  257.         ; start of fast h line blitter:
  258.         ;  bx=left side, cx=right side, vline=line start
  259.  
  260.     xchg    dx,aswap
  261.  
  262.     mov    al,BYTE PTR cs:[bx+stmask]  ; left mask
  263.     shr    bx,2                        ; left address
  264.  
  265.     mov    di,cx
  266.     mov    ah,BYTE PTR cs:[di+fnmask]  ; right mask
  267.     shr    cx,2                        ; right address
  268.  
  269.     mov    di,vline            ; start address
  270.     add    di,bx
  271.     sub    cx,bx                       ; number of bytes-1
  272.     je    short onebyte
  273.     jc    short doneline              ; clip trap
  274.  
  275.     cmp    cx,8              ; test if big enough for word speedup
  276.     jge    faster
  277.  
  278.     out    dx,al
  279.     stosb                            ; mask first byte
  280.     dec    cx
  281.     jz    nomore                        ; mask rest
  282.     cmp    al,0fh
  283.     je    noneed
  284.     mov    al,0fh                     ; rep faster than test and jmp
  285.     out    dx,al
  286. noneed:
  287.     rep    stosb
  288. nomore:
  289.     mov    al,ah
  290.     out    dx,al
  291.     mov    es:[di],ah                  ; mask last byte
  292.     jmp    short doneline
  293.  
  294. faster:
  295.     out    dx,al
  296.     stosb                            ; mask first byte
  297.     dec    cx                          ; mask rest
  298.     cmp    al,0fh
  299.     je    noneed2
  300.     mov    al,0fh                     ; rep faster than test and jmp
  301.     out    dx,al
  302. noneed2:
  303.     test    di,1
  304.     jz    notodd
  305.     stosb
  306.     dec    cx
  307. notodd:
  308.     mov    bx,cx
  309.     shr    cx,1
  310.     rep    stosw
  311.     test    bx,1
  312.     jz    noteodd
  313.     stosb
  314. noteodd:
  315.     mov    al,ah
  316.     out    dx,al
  317.     mov    es:[di],al
  318.     jmp    short doneline
  319.  
  320. onebyte:
  321.     and    al,ah
  322.     out    dx,al
  323.     mov    es:[di],al        ; single byte mask
  324.  
  325. doneline:
  326.     xchg    dx,aswap
  327.     mov    ax,80                   ; next line address
  328.     add    vline,ax
  329.  
  330.     add    edx,DWORD PTR l_incr    ; step left, right edges
  331.     add    esi,DWORD PTR r_incr
  332.     mov    ebx,edx            ; convert fixed pt to integer
  333.     sar    ebx,16
  334.     mov    ecx,esi
  335.     sar    ecx,16
  336.  
  337.     dec    WORD PTR lines          ; done lines?
  338.     jg    nextline
  339.  
  340. donetri:                                ; finished all drawing
  341. exit:
  342.     retn
  343.  
  344.  
  345.  
  346. slope:    ; [bx] is top, [bx+4] is bottom vertex in pair
  347.     ; returns slope<<16 in eax, line count in cx
  348.     ; Z set if vertices on same line
  349.  
  350.     push    edx
  351.     movzx    ecx,word ptr ds:[bx+6]
  352.     sub    cx,ds:[bx+2]
  353.     jle    round
  354.     mov    ax,ds:[bx+4]
  355.     sub    ax,ds:[bx]
  356.     movsx    eax,ax      ; conv. to double prec. << 16
  357.     je    round       ; zero slope
  358.     cmp    cx,1
  359.     je    round
  360.     cdq
  361.     shl    eax,16        ; (x2-x1)/(y2-y1)
  362.     idiv    ecx
  363.     cmp        eax,0       ; round up if pos (neg already rounded up)
  364.     jle    round
  365.     inc    eax
  366. round:
  367.     pop    edx
  368.     or    cx,cx       ; Z set if on same line
  369.     retn
  370.  
  371.     end
  372.