home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / asm / 3dvect25 / poly.inc < prev    next >
Encoding:
Text File  |  1993-09-06  |  22.7 KB  |  787 lines

  1. ; common routines between 3d1.asm and 3d2.asm
  2.  
  3.             public poly_fill
  4.             public clear_fill
  5.             public initpages
  6.             public flip_page
  7.             public fakeline
  8.             public set_clip_absolute
  9.             public set_clip_offset
  10.             public updvectors
  11.  
  12. ; clears a block from active display page
  13. ;
  14. ; this routine works only if borders of xclip land on even nybbles
  15. ; eg minimum x is 32 - works fine.  but if minimum x is 37, this
  16. ; routine will clear all the way to 32 just the same.  for better clearing,
  17. ; call fill_block routine with lxupdate and lyupdate parameters on stack
  18. ;
  19. ; routine was originally written by matt prichard.  routine was then modified
  20. ; to clear using dwords, and clear to integer borders.
  21. ;
  22. ; entry: lxupdate+0  = left x position of area to fill
  23. ;        lxupdate+2  = top y position of area to fill
  24. ;        lyupdate+0  = right x position of area to fill
  25. ;        lyupdate+2  = bottom y position of area to fill
  26.  
  27.            align 4
  28.  
  29. clear_fill:
  30.  
  31.            if useborders eq yes
  32.  
  33.            cmp use_clear,no
  34.            je tf_exit                  ; don't use clear routine
  35.  
  36.            mov edi, current_page       ; point to active vga page
  37.            cld                         ; direction flag = forward
  38.  
  39.            out_8 sc_index, map_mask    ; set up for plane select
  40.            out_8 sc_data, all_planes ; write to all planes
  41.  
  42.            mov ax,lxupdate+0
  43.            mov bx,lxupdate+2
  44.            mov cx,lyupdate+0
  45.            mov dx,lyupdate+2
  46.  
  47.            add ax,xcent        ; center on screen
  48.            add bx,xcent
  49.            add cx,ycents1
  50.            add dx,ycentp1
  51.  
  52.            and ax,0fff8h
  53.            and bx,0fff8h
  54.            add bx,7
  55.  
  56.            cmp ax,cliplt       ; clip to inside borders
  57.            jge s tf_noclip1
  58.            mov ax,cliplt
  59. tf_noclip1:
  60.            cmp bx,xmaxxcent
  61.            jl  s tf_noclip2
  62.            mov bx,cliprt
  63. tf_noclip2:
  64.            cmp cx,cliptp
  65.            jge s tf_noclip3
  66.            mov cx,cliptp
  67. tf_noclip3:
  68.            cmp dx,ymaxycent
  69.            jl  s tf_noclip4
  70.            mov dx,ymaxycent
  71. tf_noclip4:
  72.            mov lxupdate+0,ax
  73.            mov lxupdate+2,bx
  74.            mov lyupdate+0,cx
  75.            mov lyupdate+2,dx
  76.  
  77.            cmp ax,bx
  78.            jg  tf_exit             ; nothing to do!
  79.  
  80.            cmp cx,dx
  81.            jg  tf_exit             ; nothing to do!
  82.  
  83.            mov ax,cx
  84.            mov bx,dx
  85.  
  86.            sub bx,ax               ; get y width
  87.            mov lyupdate+2,bx       ; save in ypos2
  88.  
  89.            mov si,ax
  90.            shl si,1
  91.            movzx eax,w [si+fastimultable]  ; mul y1 by bytes per line
  92.            add edi,eax             ; di = start of line y1
  93.  
  94.            mov dx,lxupdate         ; dx = x1 (pixel position)
  95.            shr dx,2                ; dx/4 = bytes into line
  96.            movzx edx,dx
  97.            add edi,edx             ; di = addr of upper-left corner
  98.  
  99.            mov cx,lxupdate+2       ; cx = x2 (pixel position)
  100.            sub cx,lxupdate
  101.            shr cx,3                ; cx/4 = bytes into line
  102.            inc cx
  103.  
  104. ; di = addr of upper left block to fill
  105. ; cx = # of bands to fill in (width)
  106.  
  107.            mov dx,xactual/4        ; dx = di increment
  108.            sub dx,cx               ;  = screen_width-# planes filled
  109.            sub dx,cx
  110.  
  111.            movzx ecx,cx
  112.            mov ebx,ecx             ; bx = quick refill for cx
  113.            mov si,lyupdate+2       ; si = # of lines to fill
  114.            mov ax,background       ; get fill color
  115.            push ax                 ; make 32 bit
  116.            shl eax,16
  117.            pop ax
  118.  
  119.            shr ecx,1
  120.            shr ebx,1
  121.            jnc s tf_middle_loop2
  122.  
  123.            align 4
  124.  
  125. tf_middle_loop1:
  126.            stosw
  127.            rep stosd               ; fill in entire line
  128.  
  129.            mov ecx, ebx            ; recharge cx (line width)
  130.            add edi, edx            ; point to start of next line
  131.            loopx si, tf_middle_loop1  ; loop until all lines drawn
  132.  
  133.            ret
  134.  
  135.            align 4
  136.  
  137. tf_middle_loop2:
  138.            rep stosd               ; fill in entire line, doubleword store
  139.  
  140.            mov ecx, ebx            ; recharge cx (line width)
  141.            add edi, edx            ; point to start of next line
  142.            loopx si, tf_middle_loop2  ; loop until all lines drawn
  143. tf_exit:
  144.            endif
  145.  
  146.            ret                     ; exit
  147.  
  148. ; fill starting at oney, from firstbyte to lastbyte
  149.  
  150.            align 4
  151.  
  152. poly_fill:
  153.            mov edi, current_page   ; point to active vga page
  154.  
  155.            out_8 sc_index, map_mask ; set up for plane select
  156.  
  157.            mov ax,oney             ; ax=y1
  158.            cmp ax,ymins
  159.            jge s pf_okmin
  160.            xor ax,ax
  161.            jmp s pf_missub
  162.            align 4
  163. pf_okmin:
  164.            cmp ax,ymaxs
  165.            jge pf_outearly
  166.            sub ax,ymins
  167. pf_missub:
  168.            if usesteel eq yes
  169.            cmp steel,no            ; test to use steel texture
  170.            je s pf_skipsteel
  171.            mov bl,colq             ; yes, save colour offset and 16 block
  172.            mov steelc,bl
  173.            and steelc,0f0h         ; save base offset of 16 colour block
  174.            shl bl,2                ; colour offset is *2 (small) *4 (large)
  175.            add bl,al               ; make steel always constant
  176.            and bl,03fh             ; colour indexer (so sides look different)
  177.            mov steel ,bl
  178. pf_skipsteel:
  179.            endif
  180.  
  181.            mov bp,ax               ; indexer to line
  182.            shl bp,1
  183.            add ax, cliptp
  184.  
  185.            mov si,ax
  186.            shl si,1
  187.            movzx eax,w [si+fastimultable] ; mul y1 by bytes per line
  188.  
  189.            add edi,eax             ; di = start of line y1
  190.  
  191. pf_more_lines:
  192.            push edi                ; save right hand position
  193.            mov ax, [firstbyte+bp]
  194.            cmp ax,xmaxs            ; check if fill done
  195.            jge pf_done
  196.  
  197.            if usesteel eq yes
  198.            mov bl,steel            ; use steel texture?
  199.            cmp bl,no
  200.            je s pf_no_steel
  201.            xor bh,bh
  202.            mov dl,pf_updown[bx]
  203.            add dl,steelc
  204.            mov colq,dl
  205.            inc bl
  206.            and bl,03fh             ; 16 colours, 32 positions for steel texture
  207.            mov steel,bl
  208. pf_no_steel:
  209.            endif
  210.  
  211.            mov bx,[lastbyte+bp]
  212.            add ax,xcent
  213.            add bx,xcent
  214.  
  215.            mov dx,ax               ; dx = x1 (pixel position)
  216.            shr dx,2                ; dx/4 = bytes into line
  217.            movzx edx,dx
  218.            add edi,edx             ; di = addr of upper-left corner
  219.  
  220.            movzx ecx,bx            ; cx = x2 (pixel position)
  221.            shr cx,2                ; cx/4 = bytes into line
  222.  
  223.            cmp dx,cx               ; start and end in same band?
  224.            jg pf_exit              ; skip if fakeline fails connection
  225.            jne s pf_normal         ; if not, check for l & r edges
  226.            jmp pf_one_band_only    ; if so, then special processing
  227. pf_done:
  228.            pop eax
  229. pf_outearly:
  230.            mov oney,1000           ; reset for next polygon call
  231.            ret
  232. pf_normal:
  233.            sub cx,dx               ; cx = # bands -1
  234.            mov si,ax               ; si = plane#(x1)
  235.            and si,plane_bits       ; if left edge is aligned then
  236.            jz s pf_l_plane_flush   ; no special processing..
  237.  
  238. ; draw "left edge" of 1-3 pixels...
  239.  
  240.            out_8 sc_data, left_clip_mask[si] ; set left edge plane mask
  241.  
  242.            mov al,colq             ; get fill color
  243.            mov [edi], al           ; fill in left edge pixels
  244.  
  245.            inc edi                 ; point to middle (or right) block
  246.            dec cx                  ; reset cx instead of jmp pf_right
  247.  
  248. pf_l_plane_flush:
  249.            inc cx                  ; add in left band to middle block
  250.  
  251. ; di = addr of 1st middle pixel (band) to fill
  252. ; cx = # of bands to fill -1
  253.  
  254. pf_right:
  255.            mov si,bx               ; get xpos2
  256.            and si,plane_bits       ; get plane values
  257.            cmp si,0003             ; plane = 3?
  258.            je s pf_r_edge_flush    ; hey, add to middle
  259.  
  260. ; draw "right edge" of 1-3 pixels...
  261.  
  262.            out_8 sc_data, right_clip_mask[si]  ; right edge plane mask
  263.  
  264.            mov esi,edi             ; get addr of left edge
  265.            add esi,ecx             ; add width-1 (bands)
  266.            dec esi                 ; to point to top of right edge
  267.  
  268.            mov al,colq             ; get fill color
  269.  
  270. pf_right_loop:
  271.            mov [esi], al           ; fill in right edge pixels
  272.  
  273.            dec cx                  ; minus 1 for middle bands
  274.            jz s pf_exit            ; uh.. no middle bands...
  275.  
  276. pf_r_edge_flush:
  277.  
  278. ; di = addr of upper left block to fill
  279. ; cx = # of bands to fill in (width)
  280.  
  281.            out_8 sc_data, all_planes ; write to all planes
  282.  
  283.            mov dx, xactual/4       ; dx = di increment
  284.            sub dx, cx              ;  = screen_width-# planes filled
  285.  
  286.            mov al, colq            ; get fill color
  287.            mov ah, al              ; colour is in high and low for stosw
  288.            push ax                 ; make colour 32 bit
  289.            shl eax,16
  290.            pop ax
  291.  
  292. pf_middle_loop:
  293.            shr cx,1                ; use doubleword transfer
  294.            jnc s pf_ord
  295.            stosb                   ; if cx odd, store byte first
  296.            jcxz s pf_exit          ; no words after stosb
  297. pf_ord:
  298.            shr cx,1
  299.            jnc s pf_dord
  300.            stosw
  301.            jcxz s pf_exit          ; no doublewords after stosw
  302. pf_dord:
  303.            rep stosd               ; fill in entire line
  304. pf_exit:
  305.            pop edi
  306.            mov [firstbyte+bp],1000 ; reset table for next polygon
  307.            mov [lastbyte+bp],-1000
  308.            add bp,2
  309.            add edi,xactual/4
  310.            jmp pf_more_lines
  311.  
  312. pf_one_band_only:
  313.            cmp ax, cliplt
  314.            jne s pf_nexit
  315.            cmp bx,ax
  316.            je s pf_exit
  317. pf_nexit:
  318.            cmp ax, cliprt
  319.            je s pf_exit
  320.            mov si,ax                  ; get left clip mask, save x1
  321.            and si,plane_bits          ; mask out row #
  322.            mov al,left_clip_mask[si]  ; get left edge mask
  323.            mov si,bx                  ; get right clip mask, save x2
  324.            and si,plane_bits          ; mask out row #
  325.            and al,right_clip_mask[si] ; get right edge mask byte
  326.  
  327.            out_8 sc_data, al       ; clip for left & right masks
  328.  
  329.            mov al, colq            ; get fill color
  330.  
  331.            mov [edi], al           ; fill in pixels
  332.            jmp s pf_exit           ; outa here, for this line
  333.  
  334. ; small steel texture, make sure to set shl bl,*1* before skip_steel:
  335.  
  336. ;pf_updown  db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  337. ;           db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
  338. ;           db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  339. ;           db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
  340.  
  341. ; large steel texture, make sure to set shl bl,*2* before skip_steel:
  342.  
  343. pf_updown  db 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9
  344.            db 10,10,11,11,12,12,13,13,14,14,15,15
  345.            db 15,15,14,14,13,13,12,12,11,11,10,10
  346.            db 9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0
  347.  
  348. fastimultable label word
  349.            i=0
  350.            rept yactual
  351.            dw i*(xactual/4)
  352.            i=i+1
  353.            endm
  354.  
  355. resetupd:                         ; make old update equal current update
  356.            if useborders eq yes
  357.  
  358.            mov ax,xupdate[0]      ; and reset current update
  359.            mov lxupdate[0],ax
  360.            mov ax,xupdate[2]
  361.            mov lxupdate[2],ax
  362.            mov ax,yupdate[0]
  363.            mov lyupdate[0],ax
  364.            mov ax,yupdate[2]
  365.            mov lyupdate[2],ax
  366.            mov ax,xmaxs
  367.            mov bx,xmins1
  368.            mov cx,ymaxs
  369.            mov dx,ymins1
  370.            mov xupdate[0],ax
  371.            mov xupdate[2],bx
  372.            mov yupdate[0],cx
  373.            mov yupdate[2],dx
  374.  
  375.            endif
  376.  
  377.            ret
  378.  
  379. ; hey! where is my postcard! see readme.doc file and send me that postcard!
  380.  
  381. initpages:
  382.            pushw 0
  383.            call set_display_page
  384.  
  385.            pushw 0
  386.            call set_active_page
  387.            pushw 0
  388.            call clear_vga_screen
  389.  
  390.            pushw 1
  391.            call set_active_page
  392.            pushw 0
  393.            call clear_vga_screen
  394.  
  395.            ret
  396.  
  397. flip_page:
  398.            call get_display_page
  399.            xor ax,1
  400.            push ax
  401.            call set_display_page
  402.  
  403.            call get_active_page
  404.            xor ax,1
  405.            push ax
  406.            call set_active_page
  407.  
  408.            ret
  409.  
  410. ; draw a line in tables firstbyte,lastbyte
  411. ;
  412. ; line is not drawn on screen  but  is  drawn  in  memory  tables.    to  use,
  413. ; tables  must  be  clear,   (default  is    always    clear),    just    draw
  414. ; line around screen, in any order, then  call  poly_fill.  the  polygon  will
  415. ; be drawn and checked in memory, then poly_fill will plop it on  the  current
  416. ; page.  poly_fill routine clears tables during plot so tables are  ready  for
  417. ; more lines and more polygons.
  418.  
  419.            align 4
  420.  
  421. fakeline:
  422.            mov ax,y1
  423.            cmp y2,ax              ; flip order of points if drawing up
  424.            jg s okorder
  425.            mov bx,x1
  426.            xchg bx,x2
  427.            xchg bx,x1
  428.            xchg ax,y2
  429.            xchg ax,y1
  430. okorder:
  431.            mov ax,y1              ; set starting point for fill
  432.            cmp ax,oney
  433.            jge s nonewoney
  434.            mov oney,ax
  435. nonewoney:
  436.            if useborders eq yes
  437.  
  438.            cmp ax,yupdate+0       ; update borders for clearing routine
  439.            jge s up_no1
  440.            mov yupdate+0,ax
  441. up_no1:
  442.            mov ax,y2
  443.            cmp ax,yupdate+2
  444.            jng s up_no2
  445.            mov yupdate+2,ax
  446. up_no2:
  447.            mov dx,xupdate+0
  448.            mov cx,xupdate+2
  449.            mov ax,x1
  450.            mov bx,x2
  451.  
  452.            cmp ax,dx
  453.            jge s up_no3
  454.            dec ax
  455.            mov xupdate+0,ax
  456.            mov dx,ax
  457.            inc ax
  458. up_no3:
  459.            cmp bx,cx
  460.            jle s up_no4
  461.            inc bx
  462.            mov xupdate+2,bx
  463.            mov cx,bx
  464.            dec bx
  465. up_no4:
  466.            cmp bx,dx
  467.            jge s up_no5
  468.            dec bx
  469.            mov xupdate+0,bx
  470. up_no5:
  471.            cmp ax,cx
  472.            jle s up_no6
  473.            inc ax
  474.            mov xupdate+2,ax
  475. up_no6:
  476.            endif
  477.  
  478.            mov ax,x2              ; ax=x
  479.            sub ax,x1
  480.            mov bx,y2              ; bx=y
  481.            sub bx,y1
  482.            jle sliver
  483.  
  484.            mov rise,bx
  485.            movsx ebx,bx
  486.  
  487.            shl eax,16
  488.            cdq
  489.            idiv ebx
  490.            mov ebp,eax            ; ebp = slope*65536 (allows decimals)
  491.  
  492.            mov ax,ymins
  493.            cmp y1,ax              ; check if above screen
  494.            jge s li_abov1
  495.            sub ax,y1              ; ax = abs(difference of ymin-y1)
  496.            sub rise,ax            ; dec counter
  497.            jle li_out             ; line totally off screen
  498.  
  499.            movsx eax,ax           ; prepare for 32bit mul
  500.            imul ebp
  501.            shr eax,16             ; get top word
  502.            add x1,ax              ; set new x1,y1 pair
  503.            mov ax,ymins
  504.            mov y1,ax
  505. li_abov1:
  506.            movsx edx,x1
  507.            shl edx,16
  508.            mov cx,rise
  509.            mov ax,y1
  510.            mov bx,ax              ; bx pointer first/lastbyte table
  511.            sub bx,ymins
  512.            shl bx,1               ; bx now word
  513.  
  514.            add ax,cx              ; will line go off bottom of screen?
  515.            cmp ax,ymaxs
  516.            jl s linep             ; no...
  517.            sub ax,ymaxs           ; yes, truncate cx for early exit
  518.            sub cx,ax
  519.            jle s li_out           ; right off screen
  520. linep:
  521.            mov eax,edx
  522.            movzx ecx,cx
  523.  
  524.            mov di,xmins
  525.            mov si,xmaxs1
  526.  
  527.            align 4
  528. lineloop:
  529.            shr edx,16             ; main line drawing loop!!!
  530.  
  531.            cmp dx,di
  532.            jge s nou
  533.            mov dx,di
  534. nou:
  535.            cmp dx,si
  536.            jle s noq
  537.            mov dx,si
  538. noq:
  539.            cmp dx,firstbyte[bx]   ; fix first and lastbyte table
  540.            jge s ci1
  541.            mov firstbyte[bx],dx
  542. ci1:
  543.            cmp dx,lastbyte[bx]
  544.            jng s ci2
  545.            mov lastbyte[bx],dx
  546. ci2:
  547.            add eax,ebp
  548.            mov edx,eax
  549.            add bx,2
  550.            loop s lineloop
  551. li_out:
  552.            ret
  553. sliver:
  554.            mov cx,x1
  555.            mov ax,y1
  556.            call checkin           ; if off bottom of screen, never returns
  557.            mov cx,x2
  558.            mov ax,y1
  559. checkin:                          ; cx,ax=x,y...
  560.            cmp ax,ymaxs
  561.            jge s ci9q
  562.            cmp ax,ymins           ; clip to borders
  563.            jl  s ci6q
  564.  
  565.            cmp cx,xmins
  566.            jge s nouq
  567.            mov cx,xmins
  568. nouq:
  569.            cmp cx,xmaxs
  570.            jl s noqq
  571.            mov cx,xmaxs1
  572. noqq:
  573.            mov bx,ax              ; bx pointer first/lastbyte table
  574.            sub bx,ymins
  575.            shl bx,1               ; bx now word
  576.            cmp cx,firstbyte[bx]   ; fix first and lastbyte table
  577.            jg s ci1q
  578.            mov firstbyte[bx],cx
  579. ci1q:
  580.            cmp cx,lastbyte[bx]
  581.            jng s ci6q
  582.            mov lastbyte[bx],cx
  583. ci6q:
  584.            ret
  585. ci9q:
  586.            add esp,4              ; off bottom of screen, exit now!
  587.            ret
  588.  
  589. ; set new clipping parameters where center is in middle of points ax,bx cx,dx
  590. ; where points are absolutes! eg (10,10) (50,50) would be a small window in
  591. ; the top corner of the screen.
  592.  
  593. set_clip_absolute:
  594.  
  595.            mov si,cx             ; calc center based on points
  596.            sub si,ax
  597.            shr si,1
  598.            add si,ax
  599.  
  600.            mov di,dx
  601.            sub di,bx
  602.            shr di,1
  603.            add di,bx
  604.  
  605.            sub ax,si             ; now make points offset from center
  606.            sub cx,si
  607.            sub bx,di
  608.            sub dx,di
  609.  
  610. ; set new clipping parameters. does  all  pre-calculation   for  variables  and
  611. ; resets oney, firstbyte and lastbyte table.  si,di is center of screen.  ax,bx
  612. ; and cx,dx are topleft and botright points to clip to.  clipping will  include
  613. ; minimum clip variables but will exclude maximum clip variables.  eg -160,-100
  614. ; +160,+100, with center 160,100 are valid clip parameters.  points are offsets
  615. ; from center, not absolutes! this allows you to have the camera looking to the
  616. ; left or right of where the pilot/plane is moving  without  having  to  change
  617. ; the camera angle. note: this can only change slightly as  distortion  occures
  618. ; with too large an offset.  make sure to assemble the original file  with  the
  619. ; maximum y size you will ever need so tables are set to correct size.
  620.  
  621. set_clip_offset:
  622.            mov bp,dx
  623.            sub bp,bx
  624.            cmp bp,ymax-ymin  ; check input parameters with assembley restraints
  625.            jg you_must_assemble_original_file_with_larger_clipping_to_achieve_this
  626.  
  627.            mov xmins,ax
  628.            mov xmaxs,cx
  629.            mov ymins,bx
  630.            mov ymaxs,dx
  631.            mov xcent,si
  632.            mov ycent,di
  633.  
  634.            mov cliptp,di
  635.            add cliptp,bx
  636.  
  637.            mov ycentp1,di
  638.            inc ycentp1
  639.  
  640.            mov ycents1,di
  641.            dec ycents1
  642.  
  643.            mov clipbt,di
  644.            add clipbt,dx
  645.            dec clipbt
  646.  
  647.            mov cliplt,si
  648.            add cliplt,ax
  649.  
  650.            mov cliprt,si
  651.            add cliprt,cx
  652.            dec cliprt
  653.  
  654.            mov xmaxxcent,si
  655.            add xmaxxcent,cx
  656.  
  657.            mov ymaxycent,di
  658.            add ymaxycent,dx
  659.  
  660.            mov xmins1,ax
  661.            dec xmins1
  662.  
  663.            mov xmaxs1,cx
  664.            dec xmaxs1
  665.  
  666.            mov ymins1,bx
  667.            dec ymins1
  668.  
  669.            movsx eax,ax
  670.            movsx ebx,bx
  671.            movsx ecx,cx
  672.            movsx edx,dx
  673.  
  674.            mov xmit,eax
  675.            mov xmat,ecx
  676.            mov ymit,ebx
  677.            mov ymat,edx
  678.  
  679.            sub xmit,tolerance
  680.            add xmat,tolerance
  681.            sub ymit,tolerance
  682.            add ymat,tolerance
  683. you_must_assemble_original_file_with_larger_clipping_to_achieve_this:
  684.            ret
  685.  
  686.            align 4
  687.  
  688. ; update vector list based on traces_past
  689. ; i could have used a loop but shl ax,cl works faster
  690. ;
  691. ; what i am really doing is:
  692. ;
  693. ; for i = 1 to traces_past
  694. ;  call updvectors
  695. ; next i
  696. ;
  697. ; but instead i am shifting and adding (if bit present) for a faster method
  698. ; you get the idea right?
  699. ;
  700. ; this way, the slower the machine, the faster we move the objects to
  701. ; maintaine a universal speed from 486dx66 machine to 386sx33 machine
  702.  
  703. updvectors:
  704.            mov bx, traces_past
  705.            mov traces_past,0
  706.  
  707.            mov dx,1
  708.            mov cl,0
  709. up_loop:
  710.            shr bl,1
  711.            jnc not_call
  712.            call updvectors2
  713. not_call:
  714.            shl dx,1                ; dx = 1,2,4,8..
  715.            add cl,1                ; cx = 0,1,2,3,4,5,6...
  716.            cmp bl,0                ; all bits clear?
  717.            jne up_loop
  718.  
  719.            cmp wfollow,no          ; check if camera has reached follow object
  720.            je s nretest            ; nothing to follow
  721.            cmp eyeacount,0
  722.            jne s nretest           ; not reached yet
  723.            mov si,wfollow          ; looking at it, re-call newfollow
  724.            mov di,oldspeed
  725.            cmp di,0
  726.            jne newfollow           ; re-calculate in case its accelerating
  727.  
  728.            jmp just_look_at_it_now_instead_of_calculating
  729. nretest:
  730.            ret
  731.  
  732.            align 4
  733.  
  734. updvectors2:                      ; update vector list - shifted by cl
  735.                                   ; and dec'ed by dx
  736.            i=0
  737.            rept maxobjects+1      ; generate unrolled update loop
  738.            local nupang, nuploc, nuder, nuuder
  739.  
  740.            cmp acount+i*2,0
  741.            je s nupang
  742.            sub acount+i*2,dx
  743.            jnc s nuder
  744.            mov acount+i*2,0
  745. nuder:
  746.            mov ax,vxadds+i*2      ; update angles
  747.            shl ax,cl
  748.            add ax,vxs+i*2
  749.            mov vxs+i*2,ax
  750.  
  751.            mov ax,vyadds+i*2
  752.            shl ax,cl
  753.            add ax,vys+i*2
  754.            mov vys+i*2,ax
  755.  
  756.            mov ax,vzadds+i*2
  757.            shl ax,cl
  758.            add ax,vzs+i*2
  759.            mov vzs+i*2,ax
  760. nupang:
  761.            cmp lcount+i*2,0
  762.            je s nuploc
  763.            sub lcount+i*2,dx
  764.            jnc s nuuder
  765.            mov lcount+i*2,0
  766. nuuder:
  767.            mov eax,xadds+i*4       ; update position
  768.            shl eax,cl
  769.            add eax,xs+i*4
  770.            mov xs+i*4,eax
  771.  
  772.            mov eax,yadds+i*4
  773.            shl eax,cl
  774.            add eax,ys+i*4
  775.            mov ys+i*4,eax
  776.  
  777.            mov eax,zadds+i*4
  778.            shl eax,cl
  779.            add eax,zs+i*4
  780.            mov zs+i*4,eax
  781. nuploc:
  782.            i=i+1
  783.            endm
  784.  
  785.            ret
  786.  
  787.