home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / asm / 3dvect25 / math.inc < prev    next >
Encoding:
Text File  |  1993-09-04  |  28.5 KB  |  1,224 lines

  1. ;math.inc - general math functions.
  2.  
  3. ; point rotation is 16 bit and uses vmatrix
  4. ; camera rotation is 32 bit and uses ematrix
  5. ; frotate uses rotation along a plane and uses ematrix with precal147
  6.  
  7. ; point rotation
  8. ; bx = x   cx = y   bp = z    16 bit!
  9. ; clobbers dx,si,ax
  10.  
  11. ; remember , matrix offsets are:
  12. ;
  13. ;  0 1 2     multiply those by 4 four the doublewords
  14. ;  3 4 5
  15. ;  6 7 8
  16. ;
  17.            align 4
  18.  
  19.            public rotate
  20.  
  21. rotate:
  22.            movsx ebx,bx  ; x
  23.            movsx ecx,cx  ; y
  24.            movsx ebp,bp  ; z
  25.  
  26.            mov eax,vmatrix+8    ; solve x = bx(0)+cx(1)+bp(2)
  27.            imul ebp
  28.            shr eax,14
  29.            movsx edi,ax
  30.            mov eax,vmatrix+4
  31.            imul ecx
  32.            shr eax,14
  33.            movsx eax,ax
  34.            add edi,eax
  35.            mov eax,vmatrix+0
  36.            imul ebx
  37.            shr eax,14
  38.            movsx eax,ax
  39.            add edi,eax   ; di = new x
  40.  
  41.            mov eax,vmatrix+20   ; solve y = bx(3)+cx(4)+bp(5)
  42.            imul ebp
  43.            shr eax,14
  44.            movsx esi,ax
  45.            mov eax,vmatrix+16
  46.            imul ecx
  47.            shr eax,14
  48.            movsx eax,ax
  49.            add esi,eax
  50.            mov eax,vmatrix+12
  51.            imul ebx
  52.            shr eax,14
  53.            movsx eax,ax
  54.            add esi,eax   ; si = new y
  55.  
  56.            mov eax,vmatrix+32   ; solve z = bx(6)+cx(7)+bp(8)
  57.            imul ebp
  58.            shr eax,14
  59.            movsx ebp,ax
  60.            mov eax,vmatrix+28
  61.            imul ecx
  62.            shr eax,14
  63.            movsx eax,ax
  64.            add ebp,eax
  65.            mov eax,vmatrix+24
  66.            imul ebx
  67.            shr eax,14
  68.            movsx eax,ax
  69.            add ebp,eax   ; bp = new z
  70.  
  71.            mov ecx,esi
  72.            mov ebx,edi
  73.  
  74.            ret
  75.  
  76.            align 4
  77.  
  78. ; fast ratiox and ratioy are 320x and 464y
  79. ; multiplication has been substituted with fast lea
  80.  
  81. ; trashes eax,edx,edi
  82.  
  83.            public make3d
  84.            public make3dx
  85.            public make3dy
  86.  
  87. make3d:                            ; bp must always be positive
  88.            if ratiox eq 320
  89.  
  90.            lea eax,[ebx*4+ebx]     ; 320 = %1 0100 0000
  91.            shl eax,6
  92.            cdq
  93.  
  94.            elseif not ratiox eq 320
  95.            imul eax,ratiox
  96.            display "Note: Slow X multiplication used in make3d routine"
  97.            endif
  98.  
  99.            idiv ebp
  100.            mov ebx,eax
  101. make3dy:
  102.            if ratioy eq 464
  103.            lea eax,[ecx*8+ecx]     ; 464 = %1 1101 0000
  104.            shl ecx,2
  105.            lea ecx,[ecx*4+ecx]
  106.            add eax,ecx
  107.            shl eax,4
  108.            cdq
  109.  
  110.            elseif not ratioy eq 464
  111.            mov eax,ecx
  112.            mov ecx,ratioy
  113.            imul ecx
  114.            display "Note: Slow Y multiplication used in make3dy routine"
  115.            endif
  116.  
  117.            idiv ebp
  118.            mov ecx,eax
  119.  
  120.            ret
  121.  
  122. make3dx:                           ; bp must always be positive
  123.            if ratiox eq 320
  124.  
  125.            lea eax,[edi*4+edi]     ; 320 = %1 0100 0000, eax=320*edi
  126.            shl eax,6
  127.            cdq
  128.  
  129.            elseif not ratiox eq 320
  130.            mov eax,edi
  131.            mov edi,ratiox
  132.            imul edi
  133.            display "Note: Slow X multiplication used in make3dx routine"
  134.            endif
  135.  
  136.            idiv esi
  137.            mov edi,eax
  138.            ret
  139.  
  140. ; checks if a side is visible.
  141. ; DI, SI, DX = x's
  142. ; BP, DS, ES = y's
  143. ; return: cx register...
  144. ; cx > 0: side visible...else not...routine courtesy of "RAZOR"
  145. ; eg:
  146. ;          call checkfront
  147. ;          cmp cx,0
  148. ;          jng dontdraw
  149.  
  150.            align 4
  151.  
  152. checkfront:
  153.            cmp di,si
  154.            jng s cfc
  155.            mov ax,di
  156.            mov di,si
  157.            mov si,dx
  158.            mov dx,ax
  159.            mov ax,bp
  160.            mov bp,dsq
  161.            mov bx,esq
  162.            mov dsq,bx
  163.            mov esq,ax
  164. cfc:
  165.            cmp di,si
  166.            jng s cfc2
  167.            mov ax,di
  168.            mov di,si
  169.            mov si,dx
  170.            mov dx,ax
  171.            mov ax,bp
  172.            mov bp,dsq
  173.            mov bx,esq
  174.            mov dsq,bx
  175.            mov esq,ax
  176. cfc2:
  177.            mov ax,dx                 ; ax = x3
  178.            sub ax,di                 ; ax = x3 - x1
  179.            mov bx,dsq                ; bx = y2
  180.            sub bx,bp                 ; bx = y2 - y1
  181.            movsx eax,ax              ; modification to allow large checks
  182.            movsx ebx,bx
  183.            imul ebx                  ; ax = (x3-x1)*(y2-y1)
  184.            mov ecx,eax               ; save it...
  185.            mov ax,si                 ; ax = x2
  186.            sub ax,di                 ; ax = x2 - x1
  187.            mov bx,esq                ; bx = y3
  188.            sub bx,bp                 ; bx = y3 - y1
  189.            movsx eax,ax
  190.            movsx ebx,bx
  191.            imul ebx                  ; ax = (x2-x1)*(y3-y1)
  192.            sub ecx,eax               ; cx = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1)
  193.            ret
  194.  
  195. ; point rotation for eye - solves all x,y,z parameters
  196. ; ebx = x   ecx = y   ebp = z   32 bit rotation!
  197. ; clobbers dx,si,di,ax
  198.  
  199.            align 4
  200.  
  201.            public erotate
  202.  
  203. erotate:
  204.            mov eax,ematrix+8
  205.            imul ebp
  206.            shrd eax,edx,14
  207.            mov edi,eax
  208.            if usez eq yes
  209.            mov eax,ematrix+4
  210.            imul ecx
  211.            shrd eax,edx,14
  212.            add edi,eax
  213.            endif
  214.            mov eax,ematrix+0
  215.            imul ebx
  216.            shrd eax,edx,14
  217.            add edi,eax   ; di = new x
  218.  
  219.            mov eax,ematrix+20
  220.            imul ebp
  221.            shrd eax,edx,14
  222.            mov esi,eax
  223.            mov eax,ematrix+16
  224.            imul ecx
  225.            shrd eax,edx,14
  226.            add esi,eax
  227.            mov eax,ematrix+12
  228.            imul ebx
  229.            shrd eax,edx,14
  230.            add esi,eax   ; si = new y
  231.  
  232.            mov eax,ematrix+32
  233.            imul ebp
  234.            shrd eax,edx,14
  235.            mov ebp,eax
  236.            mov eax,ematrix+28
  237.            imul ecx
  238.            shrd eax,edx,14
  239.            add ebp,eax
  240.            mov eax,ematrix+24
  241.            imul ebx
  242.            shrd eax,edx,14
  243.            add ebp,eax   ; bp = new z
  244.  
  245.            mov ecx,esi
  246.            mov ebx,edi
  247.  
  248.            ret
  249.  
  250. ; solve z from ematrix - same as above erotate but only solves z for fast
  251. ; test of where object is - result is in esi
  252.  
  253.            align 4
  254.  
  255.            public zsolve
  256.            public ysolve
  257.            public xsolve
  258.  
  259. zsolve:
  260.            mov eax,ematrix+32
  261.            imul ebp
  262.            shrd eax,edx,14
  263.            mov esi,eax
  264.            mov eax,ematrix+28
  265.            imul ecx
  266.            shrd eax,edx,14
  267.            add esi,eax
  268.            mov eax,ematrix+24
  269.            imul ebx
  270.            shrd eax,edx,14
  271.            add esi,eax   ; si = new z
  272.            ret
  273.  
  274. ; if object z test from above routine is positive, this routine will solve
  275. ; the rest of the rotation matrix.  this is so we don't waste time solving
  276. ; for x and y locations if the object is not within screen parameters.
  277. ; saves imuls
  278.  
  279.            align 4
  280. xsolve:
  281.            mov eax,ematrix+8
  282.            imul ebp
  283.            shrd eax,edx,14
  284.            mov edi,eax
  285.            if usez eq yes
  286.            mov eax,ematrix+4
  287.            imul ecx
  288.            shrd eax,edx,14
  289.            add edi,eax
  290.            endif
  291.            mov eax,ematrix+0
  292.            imul ebx
  293.            shrd eax,edx,14
  294.            add edi,eax   ; di = new x
  295.            ret
  296.  
  297.            align 4
  298. ysolve:
  299.            mov eax,ematrix+16
  300.            imul ecx
  301.            shrd eax,edx,14
  302.            mov ecx,eax
  303.            mov eax,ematrix+12
  304.            imul ebx
  305.            shrd eax,edx,14
  306.            add ecx,eax
  307.            mov eax,ematrix+20
  308.            imul ebp
  309.            shrd eax,edx,14
  310.            add ecx,eax   ; cx = new y
  311.  
  312.            mov ebx,edi   ; final test, move into appropriate regs
  313.            mov ebp,esi
  314.  
  315.            ret
  316.  
  317. ; calculate sign into eax, from ax, smashes bx
  318. ; after imul by sign, shr eax,14 to compensate for decimal factor!
  319.  
  320.            align 4
  321.  
  322.            public cosign
  323.            public sign
  324.  
  325. cosign:
  326.            add ax,4000h
  327. sign:
  328.            shr ax,2
  329.            cmp ax,2000h
  330.            jge s q3o4         ; quadrant 3 or 4
  331.  
  332.            cmp ax,1000h
  333.            jl s q0            ; quad 1
  334.  
  335.            mov bx,1fffh
  336.            sub bx,ax
  337.            jmp s halfsign     ; quad 2
  338. q0:
  339.            mov bx,ax
  340.            jmp s halfsign
  341. q3o4:
  342.            cmp ax,3000h
  343.            jl s q3
  344.            mov bx,3fffh
  345.            sub bx,ax
  346.            call halfsign      ; quad 4
  347.            neg eax
  348.            ret
  349. q3:
  350.            and ax,0fffh
  351.            mov bx,ax          ; quad 3
  352.            call halfsign
  353.            neg eax
  354.            ret
  355. halfsign:
  356.            shl bx,1
  357.            movsx eax,w sinus[bx]
  358.            ret
  359.  
  360. ; arctan, cx=rise,ax=run, returns ax as angle of triangle
  361. ; smashes cx,ax,dx,si
  362.  
  363.            align 4
  364.  
  365.            public arctan
  366.  
  367. arctan:
  368.            cmp ax,0
  369.            jl s qd2or3
  370.            cmp cx,0
  371.            jge s halftax      ; quadrant 1
  372.            neg cx             ; quadrant 4, ax=-ax
  373.            call halftan
  374.            neg ax
  375.            shl ax,2
  376.            ret
  377. qd2or3:
  378.            neg ax
  379.            cmp cx,0
  380.            jge s qd2
  381.            neg cx             ; quad 3, ax=ax+8192
  382.            call halftan
  383.            add ax,8192
  384.            shl ax,2
  385.            ret
  386. qd2:
  387.            call halftan
  388.            neg ax
  389.            add ax,8192
  390.            shl ax,2
  391.            ret
  392. halftax:
  393.            call halftan
  394.            shl ax,2
  395.            ret
  396.  
  397.            align 4
  398.  
  399. halftan:
  400.            movsx eax,ax
  401.            movsx ecx,cx
  402.            mov edx,0
  403.  
  404. ; cx=rise  positive
  405. ; ax=run   positive
  406.  
  407.            cmp eax,ecx
  408.            jl s opptan        ; greater than 45 degrees, other side...
  409.  
  410.            xchg ecx,eax       ; ax<cx
  411.            shl eax,10         ; *2048
  412.            div ecx
  413.            mov si,ax
  414.            shl si,2
  415.            mov ax,w negtan[si] ; resulting angle (0-512 is 0-45) in ax
  416.            ret
  417.  
  418.            align 4
  419.  
  420. opptan:
  421.            shl eax,10         ; *2048
  422.  
  423.            div ecx
  424.            mov si,ax          ; ax remainder
  425.            shl si,2
  426.            mov cx,w negtan[si]
  427.            mov ax,1000h
  428.            sub ax,cx          ; resulting angle (2048-4096 is 45-90) in ax
  429.            ret
  430.  
  431.            align 4
  432.  
  433. ; generate object matrix, 12 imul's first
  434.  
  435. ;              x                         y                      z
  436. ;
  437. ;x=  cz * cy - sx * sy * sz   - sz * cy - sx * sy * cz     - cx * sy
  438. ;
  439. ;y=         sz * cx                   cx * cz                - sx
  440. ;
  441. ;z=  cz * sy + sx * sz * cy   - sy * sz + sx * cy * cz       cx * cy
  442. ;
  443. ;then perform matrix multiply by negative x and z matricies
  444. ;
  445. ; -x matrix                             -z matrix
  446. ;     x       y       z                   x       y       z
  447. ;
  448. ;x    1       0       0                   cz     sz       0
  449. ;
  450. ;y    0      cx       sx                 -sz     cz       0
  451. ;
  452. ;z    0     -sx       cx                  0       0       1
  453. ;
  454. ; notice original object matrix takes 12 imuls, camera modify takes 24, can
  455. ; you do this faster? (less imuls)
  456.  
  457.            public compound
  458.  
  459. compound:
  460.            push esi
  461.  
  462.            mov ax,vxs[esi]
  463.            neg ax
  464.            push ax
  465.            call cosign
  466.            mov vcosx,eax
  467.            pop ax
  468.            call sign
  469.            mov vsinx,eax
  470.            mov ebp,eax            ; bp = sx
  471.            neg eax
  472.            mov [vmatrix+20],eax
  473.  
  474.            mov ax,vzs[esi]
  475.            neg ax
  476.            push ax
  477.            call cosign
  478.            mov vcosz,eax
  479.            mov edi,eax            ; di = cz
  480.            pop ax
  481.            call sign
  482.            mov vsinz,eax
  483.            mov edx,eax            ; dx = sz
  484.  
  485.            mov ax,vys[esi]
  486.            neg ax
  487.            add ax,eyeay
  488.            push ax
  489.            call cosign
  490.            mov vcosy,eax
  491.            pop ax
  492.            call sign
  493.            mov vsiny,eax          ; ax = sy
  494.  
  495.            mov ebx,edx            ; save sz
  496.  
  497.            mov ecx,eax            ; save sy
  498.  
  499.            imul ebx               ; bx = - sy * sz
  500.            shr eax,14
  501.            movsx ebx,ax
  502.            neg ebx
  503.            mov [vmatrix+28],ebx
  504.  
  505.            mov eax,ecx            ; si = cz * sy
  506.            imul edi
  507.            shr eax,14
  508.            movsx esi,ax
  509.            mov [vmatrix+24],esi
  510.  
  511.            mov eax,vcosy
  512.  
  513.            imul edi               ; di = cy * cz
  514.            shr eax,14
  515.            movsx edi,ax
  516.            mov [vmatrix+0],edi
  517.  
  518.            mov eax,vsinz
  519.            mov ecx,vcosy
  520.  
  521.            imul ecx               ; cx = - sz * cy
  522.            shr eax,14
  523.            movsx ecx,ax
  524.            neg ecx
  525.            mov [vmatrix+4],ecx
  526.  
  527.            mov eax,ebp
  528.            imul esi
  529.            shr eax,14
  530.            movsx esi,ax
  531.            neg esi
  532.            add [vmatrix+4],esi
  533.  
  534.            mov eax,ebp
  535.            imul edi
  536.            shr eax,14
  537.            movsx edi,ax
  538.            add [vmatrix+28],edi
  539.  
  540.            mov eax,ebp
  541.            imul ebx
  542.            shr eax,14
  543.            movsx ebx,ax
  544.            add [vmatrix+0],ebx
  545.  
  546.            mov eax,ebp
  547.            imul ecx
  548.            shr eax,14
  549.            movsx ecx,ax
  550.            neg ecx
  551.            add [vmatrix+24],ecx
  552.  
  553.            mov esi,vcosx
  554.  
  555.            mov eax,vcosy
  556.            imul esi                   ; cx * cy
  557.            shr eax,14
  558.            movsx eax,ax
  559.            mov [vmatrix+32],eax
  560.  
  561.            mov eax,vsiny
  562.            imul esi                   ;-cx * sy
  563.            shr eax,14
  564.            movsx eax,ax
  565.            neg eax
  566.            mov [vmatrix+8],eax
  567.  
  568.            mov eax,vsinz
  569.            imul esi                   ; cx * sz
  570.            shr eax,14
  571.            movsx eax,ax
  572.            mov [vmatrix+12],eax
  573.  
  574.            mov eax,vcosz
  575.            imul esi                   ; cx * cz
  576.            shr eax,14
  577.            movsx eax,ax
  578.            mov [vmatrix+16],eax
  579.  
  580.            mov edi,ecosx              ; now perform camera x rotation,12 imuls
  581.            mov esi,esinx
  582.            mov ebp,esi
  583.            neg ebp
  584.  
  585.            mov eax,[vmatrix+12]
  586.            imul edi
  587.            shr eax,14
  588.            movsx ecx,ax
  589.  
  590.            mov eax,[vmatrix+24]
  591.            imul esi
  592.            shr eax,14
  593.            movsx eax,ax
  594.  
  595.            add ecx,eax                ; ecx = new vmatrix+12
  596.  
  597.            mov eax,[vmatrix+12]
  598.            imul ebp
  599.            shr eax,14
  600.            movsx ebx,ax
  601.  
  602.            mov eax,[vmatrix+24]
  603.            imul edi
  604.            shr eax,14
  605.            movsx eax,ax
  606.  
  607.            add ebx,eax                ; ebx = new vmatrix+24
  608.  
  609.            mov [vmatrix+12],ecx
  610.            mov [vmatrix+24],ebx
  611.  
  612.            mov eax,[vmatrix+16]
  613.            imul edi
  614.            shr eax,14
  615.            movsx ecx,ax
  616.  
  617.            mov eax,[vmatrix+28]
  618.            imul esi
  619.            shr eax,14
  620.            movsx eax,ax
  621.  
  622.            add ecx,eax                ; ecx = new vmatrix+16
  623.  
  624.            mov eax,[vmatrix+16]
  625.            imul ebp
  626.            shr eax,14
  627.            movsx ebx,ax
  628.  
  629.            mov eax,[vmatrix+28]
  630.            imul edi
  631.            shr eax,14
  632.            movsx eax,ax
  633.  
  634.            add ebx,eax                ; ebx = new vmatrix+28
  635.  
  636.            mov [vmatrix+16],ecx
  637.            mov [vmatrix+28],ebx
  638.  
  639.            mov eax,[vmatrix+20]
  640.            imul edi
  641.            shr eax,14
  642.            movsx ecx,ax
  643.  
  644.            mov eax,[vmatrix+32]
  645.            imul esi
  646.            shr eax,14
  647.            movsx eax,ax
  648.  
  649.            add ecx,eax                ; ecx = new vmatrix+20
  650.  
  651.            mov eax,[vmatrix+20]
  652.            imul ebp
  653.            shr eax,14
  654.            movsx ebx,ax
  655.  
  656.            mov eax,[vmatrix+32]
  657.            imul edi
  658.            shr eax,14
  659.            movsx eax,ax
  660.  
  661.            add ebx,eax                ; ebx = new vmatrix+32
  662.  
  663.            mov [vmatrix+20],ecx
  664.            mov [vmatrix+32],ebx
  665.  
  666.            if usez eq yes
  667.  
  668.            mov edi,ecosz              ; now perform camera z rotation,12 imuls
  669.            mov esi,esinz
  670.            mov ebp,esi
  671.            neg esi
  672.  
  673.            mov eax,[vmatrix+0]
  674.            imul edi
  675.            shr eax,14
  676.            movsx ecx,ax
  677.  
  678.            mov eax,[vmatrix+12]
  679.            imul esi
  680.            shr eax,14
  681.            movsx eax,ax
  682.  
  683.            add ecx,eax
  684.  
  685.            mov eax,[vmatrix+0]
  686.            imul ebp
  687.            shr eax,14
  688.            movsx ebx,ax
  689.  
  690.            mov eax,[vmatrix+12]
  691.            imul edi
  692.            shr eax,14
  693.            movsx eax,ax
  694.  
  695.            add ebx,eax
  696.  
  697.            mov [vmatrix+0],ecx
  698.            mov [vmatrix+12],ebx
  699.  
  700.            mov eax,[vmatrix+4]
  701.            imul edi
  702.            shr eax,14
  703.            movsx ecx,ax
  704.  
  705.            mov eax,[vmatrix+16]
  706.            imul esi
  707.            shr eax,14
  708.            movsx eax,ax
  709.  
  710.            add ecx,eax
  711.  
  712.            mov eax,[vmatrix+4]
  713.            imul ebp
  714.            shr eax,14
  715.            movsx ebx,ax
  716.  
  717.            mov eax,[vmatrix+16]
  718.            imul edi
  719.            shr eax,14
  720.            movsx eax,ax
  721.  
  722.            add ebx,eax
  723.  
  724.            mov [vmatrix+4],ecx
  725.            mov [vmatrix+16],ebx
  726.  
  727.            mov eax,[vmatrix+8]
  728.            imul edi
  729.            shr eax,14
  730.            movsx ecx,ax
  731.  
  732.            mov eax,[vmatrix+20]
  733.            imul esi
  734.            shr eax,14
  735.            movsx eax,ax
  736.  
  737.            add ecx,eax
  738.  
  739.            mov eax,[vmatrix+8]
  740.            imul ebp
  741.            shr eax,14
  742.            movsx ebx,ax
  743.  
  744.            mov eax,[vmatrix+20]
  745.            imul edi
  746.            shr eax,14
  747.            movsx eax,ax
  748.  
  749.            add ebx,eax
  750.  
  751.            mov [vmatrix+8],ecx
  752.            mov [vmatrix+20],ebx
  753.  
  754.            endif
  755.  
  756.            pop esi
  757.            ret
  758.  
  759. ; generate rotation matrix for  y,x,z  camera rotation
  760. ; called only once every frame.  completed in 12 multiplys
  761. ; matrix is also used for objects with no rotation (always angle 0,0,0)
  762. ;
  763. ; where is my postcard! see readme.doc for info.
  764. ;
  765. ;              x                    y                    z
  766. ;
  767. ;x=  cz * cy + sx * sy * sz     -cx * sz     - sy * cz + sx * cy * sz
  768. ;
  769. ;y=  sz * cy - sx * sy * cz      cx * cz     - sy * sz - sz * cy * cz
  770. ;
  771. ;z=         cx * sy                 sx                cx * cy
  772. ;
  773.  
  774. ;  matrix offsets:
  775. ;
  776. ;     x  y  z
  777. ;
  778. ;x    0  4  8
  779. ;y   12 16 20
  780. ;z   24 28 32
  781.  
  782.            align 4
  783.  
  784.            public setsincose
  785.  
  786. setsincose:
  787.  
  788.            mov ax,eyeax
  789.            call cosign
  790.            mov ecosx,eax          ; ecosx and such are used by object rotation
  791.            mov ax,eyeax           ; ematrix is used to find where object is
  792.            call sign
  793.            mov esinx,eax
  794.            mov [ematrix+28],eax
  795.            mov ebp,eax            ; bp = sx
  796.  
  797.            if usez eq yes
  798.            mov ax,eyeaz
  799.            call cosign
  800.            mov ecosz,eax
  801.            mov edi,eax            ; di = cz
  802.            mov ax,eyeaz
  803.            call sign
  804.            mov esinz,eax
  805.            mov edx,eax            ; dx = sz
  806.            endif
  807.  
  808.            if usez eq no
  809.            mov edi,4000h          ; di = cos 0
  810.            mov ecosz,4000h
  811.            xor edx,edx            ; dx = sin 0
  812.            mov esinz,0
  813.            endif
  814.  
  815.            mov ax,eyeay
  816.            call cosign
  817.            mov ecosy,eax
  818.            mov ax,eyeay
  819.            call sign
  820.            mov esiny,eax          ; ax = sy
  821.  
  822.            mov ebx,edx            ; save sz
  823.  
  824.            mov ecx,eax            ; save sy
  825.  
  826.            imul ebx               ; bx = sy * sz
  827.            shr eax,14
  828.            movsx ebx,ax
  829.            neg ebx
  830.            mov [ematrix+20],ebx
  831.            neg ebx
  832.  
  833.            mov eax,ecx            ; si = - (cz * sy)
  834.            imul edi
  835.            shr eax,14
  836.            movsx esi,ax
  837.            neg esi
  838.            mov [ematrix+8],esi
  839.  
  840.            mov eax,ecosy
  841.  
  842.            imul edi               ; di = cy * cz
  843.            shr eax,14
  844.            movsx edi,ax
  845.            mov [ematrix+0],edi
  846.  
  847.            mov eax,esinz
  848.            mov ecx,ecosy
  849.  
  850.            imul ecx               ; cx = sz * cy
  851.            shr eax,14
  852.            movsx ecx,ax
  853.            mov [ematrix+12],ecx
  854.  
  855.            mov eax,ebp
  856.            imul esi
  857.            shr eax,14
  858.            movsx esi,ax
  859.            add [ematrix+12],esi
  860.  
  861.            mov eax,ebp
  862.            imul edi
  863.            shr eax,14
  864.            movsx edi,ax
  865.            neg edi
  866.            add [ematrix+20],edi
  867.  
  868.            mov eax,ebp
  869.            imul ebx
  870.            shr eax,14
  871.            movsx ebx,ax
  872.            add [ematrix+0],ebx
  873.  
  874.            mov eax,ebp
  875.            imul ecx
  876.            shr eax,14
  877.            movsx ecx,ax
  878.            add [ematrix+8],ecx
  879.  
  880.            mov esi,ecosx
  881.  
  882.            mov eax,ecosy
  883.            imul esi                   ; cx * cy
  884.            shr eax,14
  885.            movsx eax,ax
  886.            mov [ematrix+32],eax
  887.  
  888.            mov eax,esiny
  889.            imul esi                   ; cx * sy
  890.            shr eax,14
  891.            movsx eax,ax
  892.            mov [ematrix+24],eax
  893.  
  894.            mov eax,esinz
  895.            imul esi                   ;-cx * sz
  896.            shr eax,14
  897.            movsx eax,ax
  898.            neg eax
  899.            mov [ematrix+4],eax
  900.  
  901.            mov eax,ecosz
  902.            imul esi                   ; cx * cz
  903.            shr eax,14
  904.            movsx eax,ax
  905.            mov [ematrix+16],eax
  906.  
  907.            neg esinx                  ; reverse angles for object rotation
  908.            neg esiny
  909.  
  910.            ret
  911.  
  912. ;getroot:                      ; get square root of ax, where ax = 0-65535
  913. ;           cmp ax,0fe01h      ; since ax cannot be negative anyway!
  914. ;           jae sqr255         ; routine requires squares tables.
  915. ;           mov si,offset squares
  916. ;           mov cx,ax
  917. ;           inc cx
  918. ;           cld
  919. ;nextroot:
  920. ;           lodsw
  921. ;           cmp ax,cx
  922. ;           jbe  nextroot      ; jb is exact but jbe is better approximation
  923. ;           mov ax,si
  924. ;           sub ax,offset squares+3
  925. ;           sar ax,1
  926. ;           ret
  927. ;sqr255:
  928. ;           mov ax,255
  929. ;           ret
  930.  
  931. ; routine courtesy TRAN
  932. ;
  933. ; square root
  934. ; in:
  935. ;   eax - number to take root of
  936. ; out:
  937. ;   eax - root
  938. ;
  939. sqrtbasetbl db 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225
  940.  
  941.            public sqrt
  942.  
  943.            align 4
  944.  
  945. sqrt:
  946.            pushad
  947.            mov ebp,eax
  948.            bsr ebx,eax
  949.            jnz short sqrtf0
  950.            xor ebx,ebx
  951. sqrtf0:
  952.            shr ebx,3
  953.            lea eax,[ebx*8]
  954.            mov cl,32
  955.            sub cl,al
  956.            rol ebp,cl
  957.            mov eax,ebp
  958.            movzx eax,al
  959.            mov edi,offset sqrtbasetbl
  960.            mov ecx,10h
  961. sqrtl0:
  962.            scasb
  963.            je short sqrtl0d
  964.            jb short sqrtl0d2
  965.            loop sqrtl0
  966.            inc edi
  967. sqrtl0d2:
  968.            dec edi
  969.            inc cl
  970. sqrtl0d:
  971.            movzx edx,byte ptr [edi-1]
  972.            dec cl
  973.            xor cl,0fh
  974.            mov edi,ecx
  975.            mov ecx,ebx
  976.            jecxz short sqrtdone
  977.            sub eax,edx
  978. sqrtml:
  979.            shld eax,ebp,8
  980.            rol ebp,8
  981.            mov ebx,edi
  982.            shl ebx,5
  983.            xor edx,edx
  984.            mov esi,eax
  985.            div ebx
  986.            rol edi,4
  987.            add edi,eax
  988.            add ebx,eax
  989. sqrtf2:
  990.            imul eax,ebx
  991.            mov edx,eax
  992.            mov eax,esi
  993.            sub eax,edx
  994.            jc short sqrtf1
  995.            loop sqrtml
  996. sqrtdone:
  997.            mov [esp+28],edi
  998.            popad
  999.            ret
  1000. sqrtf1:
  1001.            dec ebx
  1002.            dec edi
  1003.            movzx eax,bl
  1004.            and al,1fh
  1005.            jmp sqrtf2
  1006.  
  1007. ; solve for z when x = bx (takes a point/object on a y plane and figures
  1008. ; where it would be if z = 16, y = precal7, only good for square translations)
  1009. ; uses ematrix as rotation matrix
  1010.  
  1011. ; cs set if not possible
  1012.  
  1013. ; formula is inverse of z = bx6+cx7+bp8. where precal7 is y*7
  1014. ; (16-bx(6)-precal7)/(8)=z
  1015.  
  1016.             public set_precal7
  1017.             public set_precal147
  1018.             public frotate
  1019.             public z16x
  1020.             public z16z
  1021.  
  1022.             public precal1
  1023.             public precal4
  1024.             public precal7
  1025.  
  1026.             align 4
  1027.  
  1028. precal1     dd 0
  1029. precal4     dd 0
  1030. precal7     dd 0
  1031.  
  1032. z16x:
  1033.             cmp ematrix+32,0
  1034.             je abort_attempt
  1035.  
  1036.             mov eax,ematrix+24
  1037.             imul ebx
  1038.             shrd eax,edx,14
  1039.  
  1040.             neg eax
  1041.             add eax,16
  1042.             sub eax,precal7
  1043.  
  1044.             cdq
  1045.             shld edx,eax,14
  1046.             mov ebx,ematrix+32
  1047.             idiv ebx
  1048.  
  1049.             stc
  1050.             ret
  1051. abort_attempt:
  1052.             clc
  1053.             ret
  1054.  
  1055. ; solve for x when z = bp (takes a point/object on a y plane and figures
  1056. ; where it would be if z = 16, y = precal7, only good for square translations)
  1057. ; uses ematrix as rotation matrix. output solves for z = 16
  1058.  
  1059. ; cs set if not possible
  1060.  
  1061. ; formula is inverse of z = bx6+cx7+bp8. where precal7 is y*7
  1062. ; (16-bp(8)-precal7)/(6)=x
  1063.  
  1064.             align 4
  1065.  
  1066. z16z:
  1067.             cmp ematrix+24,0
  1068.             je abort_attempt
  1069.  
  1070.             mov eax,ematrix+32
  1071.             imul ebp
  1072.             shrd eax,edx,14
  1073.  
  1074.             neg eax
  1075.             add eax,16
  1076.             sub eax,precal7
  1077.  
  1078.             cdq
  1079.             shld edx,eax,14
  1080.             mov ebx,ematrix+24
  1081.             idiv ebx
  1082.  
  1083.             stc
  1084.             ret
  1085.  
  1086. ; set precal7 for plane transformation - plane is ecx and allows above formulas
  1087. ; to determine where a point/object would be along that plane if z is negative
  1088.  
  1089. ; good for runway translations or super huge background polygons - not used
  1090. ; by regular 3d.asm routines
  1091.  
  1092. ; how to use: lets say you've got a million background objects that are
  1093. ; on the ground (or all on the same y plane).  you call set_precal147
  1094. ; with that y plane location and use frotate instead of erotate to
  1095. ; determine where points rotated along that plane will end up.  this
  1096. ; speeds the routine up by 33% by cutting out 3 imuls.
  1097.  
  1098.             align 4
  1099.  
  1100. set_precal147:
  1101.             if usez eq yes
  1102.             mov eax,ecx
  1103.             sub eax,eyey
  1104.             imul ematrix+4
  1105.             shr eax,14
  1106.             mov precal1,eax
  1107.             endif
  1108.  
  1109.             mov eax,ecx
  1110.             sub eax,eyey
  1111.             imul ematrix+16
  1112.             shr eax,14
  1113.             mov precal4,eax
  1114.  
  1115. set_precal7:
  1116.             sub ecx,eyey
  1117.             mov eax,ecx
  1118.             imul ematrix+28
  1119.             shr eax,14
  1120.             mov precal7,eax
  1121.             ret
  1122.  
  1123.             align 4
  1124.  
  1125. ; fast object/point rotation along pre-calculated y plane
  1126.  
  1127. frotate:
  1128.            mov eax,ematrix+8
  1129.            imul ebp
  1130.            shrd eax,edx,14
  1131.            mov edi,eax
  1132.            if usez eq yes
  1133.            add edi,precal1
  1134.            endif
  1135.            mov eax,ematrix+0
  1136.            imul ebx
  1137.            shrd eax,edx,14
  1138.            add edi,eax   ; di = new x
  1139.  
  1140.            mov eax,ematrix+20
  1141.            imul ebp
  1142.            shrd eax,edx,14
  1143.            mov esi,eax
  1144.            add esi,precal4
  1145.            mov eax,ematrix+12
  1146.            imul ebx
  1147.            shrd eax,edx,14
  1148.            add esi,eax   ; si = new y
  1149.  
  1150.            mov eax,ematrix+32
  1151.            imul ebp
  1152.            shrd eax,edx,14
  1153.            mov ebp,eax
  1154.            add ebp,precal7
  1155.            mov eax,ematrix+24
  1156.            imul ebx
  1157.            shrd eax,edx,14
  1158.            add ebp,eax   ; bp = new z
  1159.  
  1160.            mov ecx,esi
  1161.            mov ebx,edi
  1162.  
  1163.            ret
  1164.  
  1165. ; fast solve for single matrix variable similar to erotate but uses frotate
  1166. ; plane matrix with precal147
  1167. ;
  1168. ; remember , matrix offsets are:
  1169. ;
  1170. ;  0 1 2     multiply those by 4 four the doublewords
  1171. ;  3 4 5
  1172. ;  6 7 8
  1173. ;
  1174.            public fzsolve
  1175.            public fxsolve
  1176.            public fysolve
  1177.  
  1178.            align 4
  1179.  
  1180. fzsolve:
  1181.            mov eax,ematrix+32      ; solve z = bx(6)+cx(7)+bp(8)
  1182.            imul ebp
  1183.            shrd eax,edx,14
  1184.            mov esi,eax
  1185.            add esi,precal7
  1186.            mov eax,ematrix+24
  1187.            imul ebx
  1188.            shrd eax,edx,14
  1189.            add esi,eax   ; si = new z
  1190.            ret
  1191.  
  1192.            align 4
  1193. fxsolve:
  1194.            mov eax,ematrix+8        ; solve x = bx(0)+cx(1)+bp(2)
  1195.            imul ebp
  1196.            shrd eax,edx,14
  1197.            mov edi,eax
  1198.            if usez eq yes
  1199.            add edi,precal1
  1200.            endif
  1201.            mov eax,ematrix+0
  1202.            imul ebx
  1203.            shrd eax,edx,14
  1204.            add edi,eax   ; di = new x
  1205.            ret
  1206.  
  1207.            align 4
  1208. fysolve:
  1209.            mov eax,ematrix+20       ; solve y = bx(3)+cx(4)+bp(5)
  1210.            imul ebp
  1211.            shrd eax,edx,14
  1212.            mov ecx,eax
  1213.            add ecx,precal4
  1214.            mov eax,ematrix+12
  1215.            imul ebx
  1216.            shrd eax,edx,14
  1217.            add ecx,eax   ; cx = new y
  1218.  
  1219.            mov ebx,edi
  1220.            mov ebp,esi
  1221.  
  1222.            ret
  1223.  
  1224.