home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / DRV256 / FMPMASKX.ASM < prev    next >
Assembly Source File  |  1993-05-02  |  8KB  |  411 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 (0CCh)
  21. rverts        dd 40 dup (0DDh)
  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.  
  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. aswap   equ     [bp-16]        ; plane mask reg. swap value
  44. lptr    equ    [bp-18]
  45. rptr    equ    [bp-20]
  46. cur_y    equ    [bp-22]
  47.  
  48. mcolor    equ    [bp+12]
  49. gmask    equ    [bp+14]
  50. cmask    equ    [bp+16]
  51.  
  52. orig_y1    equ    [bp-30]        ; original Y1 value before vertex rotation
  53. mtl_color equ    [bp-32]        ; color cycle number
  54.  
  55.    ;
  56.    ;   m_fastpoly(int count, int *vertices, int color, gmask, cmask))
  57.    ;       vertices must be in CCW order and x,y order!
  58.  
  59.         PUBLIC    _m_fastpoly
  60.  
  61. _m_fastpoly    proc    far
  62.  
  63.     .386
  64.     push    bp
  65.     mov    bp,sp
  66.     sub    sp,36
  67.     push    si
  68.     push    di
  69.     push    dx
  70.     push    cx         ; CREATE L, R SIDE LISTS OF VERTICES
  71.  
  72.     les    si,verts         ; find lowest y (any vertex on top of poly)
  73.     mov    cx,nv
  74.     mov    ax,30000
  75. fmin:
  76.     cmp    ax,es:[si+2]
  77.     jl    notlower
  78.     mov    ax,es:[si+2]
  79.     mov    bx,si
  80.     mov    dx,cx
  81. notlower:
  82.     add    si,4
  83.     loop    fmin
  84.  
  85.     mov    orig_y1,ax
  86.     mov    cx,dx
  87.     mov    si,bx
  88.     mov    di,OFFSET lverts
  89. clsloop:                            ; copy from lowest to end
  90.     mov    eax,es:[si]
  91.     mov    ds:[di],eax
  92.     add    si,4
  93.     add    di,4
  94.     loop    clsloop
  95.  
  96.     mov    si,verts
  97. cleloop:                            ; copy from start to lowest
  98.     mov    eax,es:[si]
  99.     mov    ds:[di],eax
  100.     add    si,4
  101.     add    di,4
  102.     cmp    si,bx
  103.     jb    cleloop
  104.  
  105.     mov    si,OFFSET lverts    ; right list in reverse order
  106.     mov     lptr,si
  107.     mov    di,OFFSET rverts    ; except first element same
  108.     mov     rptr,di
  109.     mov    eax,ds:[si]
  110.     mov    ds:[di],eax
  111.     add    si,4
  112.     add    di,4
  113.     mov    cx,nv
  114.     dec    cx
  115.     add    di,cx
  116.     add    di,cx
  117.     add    di,cx
  118.     add    di,cx
  119.     mov    ax,-1
  120.     mov    ds:[di+2],ax        ; "stopper"
  121. crrloop:                            ; copy remaining elements
  122.     sub    di,4
  123.     mov    eax,ds:[si]
  124.     mov    ds:[di],eax
  125.     add    si,4
  126.     loop    crrloop
  127.     mov    ax,-1
  128.     mov    WORD PTR ds:[si+4],-1
  129.                   ; VIDEO SETUP
  130.     test    WORD PTR orig_y1,1    ; make sure that gmask is aligned correctly
  131.     jz    _even
  132.     mov    al,cmask
  133.     xor    gmask,al
  134. _even:                ; make sure the starting color is correct...
  135.     mov    al,mcolor    ; get offset
  136.     and    al,0Fh
  137.     test    WORD PTR mcolor,100h     ; extra bit of offset
  138.     jz    firsthalf
  139.     add    al,16
  140. firsthalf:
  141.     add    al,orig_y1        ; add line number
  142.     mov    mtl_color,ax
  143.     test    al,10h
  144.     jz    cy1
  145.     not    al
  146. cy1:    and    al,0Fh
  147.     and    WORD PTR mcolor,00F0h
  148.     or    al,mcolor    ; combine hue and shade to get starting color
  149.     mov    bl,al        ; set starting color for this triangle
  150.  
  151.     cld
  152.     mov    ax,03c5h        ; setup DX adr. swap value
  153.     mov    aswap,ax
  154.     mov    ax,0a000h               ; set video segment
  155.     mov    es,ax
  156.     mov    bh,0FFh            ; low byte still in BL
  157.     mov    al,es:[bx]        ; set initial color
  158.  
  159.     mov    ax,WORD PTR [lverts+2]           ; set current line
  160.     mov     cur_y,ax
  161.     mov    bl,80                   ; compute starting line adr
  162.     mul    bl
  163.     add    ax,WORD PTR ds:_dpaddr
  164.     mov    vline,ax
  165.  
  166.     mov    cx,nv          ; FIND FIRST EDGES IN POLY
  167.     dec    cx
  168.     mov    bx,lptr
  169. lslinit:
  170.     push    cx
  171.     call    near ptr slope    ; find first left edge
  172.     pop    cx
  173.     jnz    lfinit
  174.     add    bx,4
  175.     loop    lslinit
  176.  
  177.     pop    cx                ; unable to find next line: exit
  178.     pop    dx
  179.     pop    di
  180.     pop    si
  181.     mov    sp,bp
  182.     pop    bp
  183.     ret
  184.  
  185. lfinit:
  186.     mov    l_incr,eax
  187.     mov    lptr,bx
  188.  
  189.     mov    dx,[bx]           ; compute L start
  190.     shl    edx,16
  191. ;    add    edx,08000h        ; force left side to round up
  192.  
  193.     mov    bx,rptr
  194. rslinit:
  195.     call    near ptr slope    ; find first right edge
  196.     jnz    rfinit
  197.     add    bx,4
  198.     jmp    rslinit
  199. rfinit:
  200.     mov    r_incr,eax
  201.     mov    rptr,bx
  202.  
  203.     mov    si,[bx]         ; compute R start
  204.     shl    esi,16
  205.  
  206.                 ; POLY SLICE LOOP
  207. sliceloop:
  208.     mov    bx,rptr
  209.     mov    ax,[bx+6]    ; bottom of right edge
  210.     mov    bx,lptr
  211.     cmp    ax,[bx+6]    ; bottom of left edge
  212.     jb    fbots
  213.     mov    ax,[bx+6]
  214. fbots:
  215.     mov    cx,ax
  216.     sub    cx,cur_y                ; figure line count
  217.     mov    cur_y,ax
  218.     mov    lines,cx
  219.     call    near ptr trapezoid    ; draw it
  220.  
  221.     mov    bx,lptr
  222.     mov    ax,cur_y
  223.     cmp     ax,[bx+6]        ; left edge ended?
  224.     jnz    not_left
  225.  
  226. fll:
  227.     add    bx,4
  228.     call    near ptr slope
  229.     jl    end_poly        ; no more left edges
  230.     jnz    fleft
  231.     jmp    fll
  232. fleft:
  233.     mov    l_incr,eax
  234.     mov    lptr,bx
  235.     mov    dx,[bx]           ; compute L start
  236.     shl    edx,16
  237. ;    add    edx,08000h        ; force left side to round up
  238.  
  239. not_left:
  240.     mov    bx,rptr
  241.     mov    ax,cur_y
  242.     cmp    ax,[bx+6]
  243.     jnz    not_right
  244.  
  245. frl:
  246.     add    bx,4
  247.     call    near ptr slope
  248.     jl    end_poly      ; no more left edges
  249.     jnz    freft
  250.     jmp    frl
  251. freft:
  252.     mov    r_incr,eax
  253.     mov    rptr,bx
  254.     mov    si,[bx]           ; compute R start
  255.     shl    esi,16
  256.  
  257. not_right:
  258.     jmp    sliceloop
  259.  
  260. end_poly:
  261.     pop    cx
  262.     pop    dx
  263.     pop    di                ; exit code
  264.     pop    si
  265.     mov    sp,bp
  266.     pop    bp
  267.     ret
  268.  
  269. _m_fastpoly    endp
  270.  
  271.  
  272.  
  273.  
  274.  
  275. trapezoid:    ; call with edx = (left+0.5)>>16, esi = right<<16
  276.         ; vline, lines, l_incr, r_incr all set up
  277.  
  278.     mov    ebx,edx            ; convert fixed pt to integer
  279.     sar    ebx,16
  280.     mov    ecx,esi
  281.     sar    ecx,16
  282.  
  283. nextline:
  284.         ; start of fast h line blitter:
  285.         ;  bx=left side, cx=right side, vline=line start
  286.  
  287.     xchg    dx,aswap
  288.  
  289.     mov    al,BYTE PTR cs:[bx+stmask]  ; left mask
  290.     and    al,gmask
  291.     shr    bx,2                        ; left address
  292.  
  293.     mov    di,cx
  294.     mov    ah,BYTE PTR cs:[di+fnmask]  ; right mask
  295.     and    ah,gmask
  296.     shr    cx,2                        ; right address
  297.  
  298.     mov    di,vline            ; start address
  299.     add    di,bx
  300.     sub    cx,bx                       ; number of bytes-1
  301.     je    short onebyte
  302.     jc    short doneline              ; clip trap
  303.  
  304.     cmp    cx,8              ; test if big enough for word speedup
  305.     jge    faster
  306.  
  307.     out    dx,al
  308.     stosb                            ; mask first byte
  309.     dec    cx                          ; mask rest
  310.     jz    nomore
  311.     mov    al,gmask
  312.     out    dx,al
  313.  
  314.     rep    stosb
  315. nomore:
  316.     mov    al,ah
  317.     out    dx,al
  318.     mov    es:[di],ah                  ; mask last byte
  319.     jmp    short doneline
  320.  
  321. faster:
  322.     out    dx,al
  323.     stosb                            ; mask first byte
  324.     dec    cx                          ; mask rest
  325.     mov    al,gmask
  326.     out    dx,al
  327.  
  328.     test    di,1
  329.     jz    notodd
  330.     stosb
  331.     dec    cx
  332. notodd:
  333.     mov    bx,cx
  334.     shr    cx,1
  335.     rep    stosw
  336.     test    bx,1
  337.     jz    noteodd
  338.     stosb
  339. noteodd:
  340.     mov    al,ah
  341.     out    dx,al
  342.     mov    es:[di],al
  343.     jmp    short doneline
  344.  
  345. onebyte:
  346.     and    al,ah
  347.     out    dx,al
  348.     mov    es:[di],al        ; single byte mask
  349.  
  350. doneline:
  351.     xchg    dx,aswap
  352.     mov    ax,80                   ; next line address
  353.     add    vline,ax
  354.  
  355.     add    edx,DWORD PTR l_incr    ; step left, right edges
  356.     add    esi,DWORD PTR r_incr
  357.     mov    ebx,edx            ; convert fixed pt to integer
  358.     sar    ebx,16
  359.     mov    ecx,esi
  360.     sar    ecx,16
  361.  
  362.     push    bx
  363.     inc     BYTE PTR mtl_color    ; next color in sequence
  364.     mov    bl,mtl_color
  365.     test    bl,10h
  366.     jz    cy2
  367.     not    bl
  368. cy2:    and    bl,0Fh
  369.     or    bl,mcolor    ; combine hue and shade to get color
  370.     mov    bh,0FFh        ; figure what entry to load
  371.     mov    al,es:[bx]      ; read entry into latches
  372.  
  373.     mov    bl,cmask    ; get mask for flipping bits
  374.     xor    gmask,bl    ; alter transparency mask
  375.     pop    bx
  376.  
  377.     dec    WORD PTR lines          ; done lines?
  378.     jg    nextline
  379.  
  380. donetri:                                ; finished all drawing
  381. exit:
  382.     retn
  383.  
  384.  
  385.  
  386. slope:    ; [bx] is top, [bx+4] is bottom vertex in pair
  387.     ; returns slope<<16 in eax, line count in cx
  388.     ; Z set if vertices on same line
  389.  
  390.     push    edx
  391.     movzx    ecx,word ptr ds:[bx+6]
  392.     sub    cx,ds:[bx+2]
  393.     jle    round
  394.     mov    ax,ds:[bx+4]
  395.     sub    ax,ds:[bx]
  396.     movsx    eax,ax      ; conv. to double prec. << 16
  397.     je    round       ; zero slope
  398.     cmp    cx,1
  399.     je    round
  400.     cdq
  401.     shl    eax,16        ; (x2-x1)/(y2-y1)
  402.     idiv    ecx
  403.     cmp        eax,0       ; round up if pos (neg already rounded up)
  404.     jle    round
  405.     inc    eax
  406. round:
  407.     pop    edx
  408.     or    cx,cx       ; Z set if on same line
  409.     retn
  410.  
  411.     end