home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / matrixm.asm < prev    next >
Assembly Source File  |  1996-03-19  |  17KB  |  906 lines

  1.     TITLE    MATRIXM - MATRIX ALGRBRA IN ASSEMBLER
  2.  
  3.     COMMENT $
  4.  
  5. /* Contact: dstampe@sunee.waterloo.edu */
  6.  
  7. // Routines to do matrix math for the integer math library
  8. // All code by Dave Stampe, last updated 23/12/93
  9.  
  10. /*
  11.  This code is part of the VR-386 project, created by Dave Stampe.
  12.  VR-386 is a desendent of REND386, created by Dave Stampe and
  13.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  14.  Stampre for VR-386.
  15.  
  16.  Copyright (c) 1994 by Dave Stampe:
  17.  May be freely used to write software for release into the public domain
  18.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  19.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  20.  this software or source code into their products!  Usually there is no
  21.  charge for under 50-100 items for low-cost or shareware products, and terms
  22.  are reasonable.  Any royalties are used for development, so equipment is
  23.  often acceptable payment.
  24.  
  25.  ATTRIBUTION:  If you use any part of this source code or the libraries
  26.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  27.  and any other authors in your documentation, source code, and at startup
  28.  of your program.  Let's keep the freeware ball rolling!
  29.  
  30.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  31.  REND386, improving programmer access by rewriting the code and supplying
  32.  a standard API.  If you write improvements, add new functions rather
  33.  than rewriting current functions.  This will make it possible to
  34.  include you improved code in the next API release.  YOU can help advance
  35.  VR-386.  Comments on the API are welcome.
  36.  
  37.  CONTACT: dstampe@psych.toronto.edu
  38. */
  39.  
  40.  
  41. NOTES ON MATRIX FORMATS:
  42.  
  43. Matrices are 32 bit [4][3] arrays, row major format.
  44. They are a reduced homogenous matrix, with a rotational
  45. and translational part (translational part = position).
  46. No scaling is allowed if you want to use the fast inverse
  47. supplied here.
  48.  
  49. Matrix multiplies are generally quite expensive: the 36 32-bit
  50. multiplies take 60 microseconds on a 486/33!  So use them sparingly.
  51.  
  52.  
  53. OFFSETS IN MATRIX: (homogenaous)
  54.  
  55. [ 0  4  8  | 36 ]
  56. [ 12 16 20 | 40 ]
  57. [ 24 28 32 | 44 ]
  58.  
  59.         $
  60.  
  61.     .MODEL large
  62.  
  63.  
  64.     .DATA
  65.  
  66. ;include 3dstruct.inc
  67.  
  68. ; # define XFSC 536870912   /* 2**29 for shifting xform coeffs to long */
  69.  
  70.     .CODE INTMATH
  71.  
  72.  
  73. MULT29     MACRO a,b                 ; multiply <3.29> -> eax
  74.     mov    eax,DWORD PTR a
  75.     imul    DWORD PTR b
  76.     shrd    eax,edx,29
  77.     adc    eax,0
  78.     ENDM
  79.  
  80. MMULT29 MACRO a,b,c               ; multiply 3 of <3.29> -> eax
  81.     mov    eax,DWORD PTR a
  82.     imul    DWORD PTR b
  83.     shrd    eax,edx,29
  84.     adc    eax,0
  85.     imul    DWORD PTR c
  86.     shrd    eax,edx,29
  87.     adc    eax,0
  88.     ENDM
  89.  
  90. DOTPROD    MACRO a,b,c,x,y,z,p      ; dot product plus p, accum in ecx:ebx
  91.     mov    eax,a            ; result in eax
  92.     imul    DWORD PTR x
  93.     mov    ecx,edx
  94.     mov    ebx,eax
  95.     mov    eax,b
  96.     imul    DWORD PTR y
  97.     add    ebx,eax
  98.     adc    ecx,edx
  99.     mov    eax,c
  100.     imul    DWORD PTR z
  101.     add    eax,ebx
  102.     adc    edx,ecx
  103.     shrd    eax,edx,29
  104.     adc    eax,p
  105.     ENDM
  106.  
  107. CROSSTERM MACRO a,x,b,y      ; left-handed cross product (a*x-b*y) term
  108.     mov    eax,b        ; accum in ebx:ecx, result in eax
  109.     imul    DWORD PTR y
  110.     mov    ecx,edx
  111.     mov    ebx,eax
  112.     mov    eax,a
  113.     imul    DWORD PTR x
  114.     sub    eax,ebx
  115.     sbb    edx,ecx
  116.     shrd    eax,edx,29
  117.     adc    eax,0
  118.     ENDM
  119.  
  120. ;/***************** MATRIX-VECTOR OPERATIONS **************/
  121.  
  122. ;/* rotate/translate XYZ by matrix */
  123. ;
  124. ;void matrix_point(MATRIX m, long *xp, long *yp, long *zp)
  125.  
  126.  
  127. m    equ    [bp+8]          ; arguments
  128. xp    equ    [bp+12]
  129. yp    equ    [bp+16]
  130. zp    equ    [bp+20]
  131.  
  132. x    equ    [bp-4]        ; locals
  133. y    equ    [bp-8]
  134. z    equ    [bp-12]
  135.  
  136.     PUBLIC    _matrix_point
  137.  
  138. _matrix_point     proc    far
  139.  
  140.     .386
  141.     push    ebp
  142.     mov    ebp,esp
  143.     sub    esp,16
  144.  
  145.     push    edi
  146.     push    ecx
  147.     push    edx
  148.  
  149.     les    bx,DWORD PTR xp
  150.     mov    eax,es:[bx]
  151.     mov    x,eax
  152.     les    bx,DWORD PTR yp
  153.     mov    eax,es:[bx]
  154.     mov    y,eax
  155.     les    bx,DWORD PTR zp
  156.     mov    eax,es:[bx]
  157.     mov    z,eax
  158.  
  159.     les    di,DWORD PTR m
  160.  
  161.     DOTPROD es:[di], es:[di+4], es:[di+8], x, y, z, es:[di+36]
  162.     push    eax        ; x result
  163.  
  164.     DOTPROD es:[di+12], es:[di+16], es:[di+20], x, y, z, es:[di+40]
  165.     push    eax        ; y result
  166.  
  167.     DOTPROD es:[di+24], es:[di+28], es:[di+32], x, y, z, es:[di+44]
  168.  
  169.     les    di,DWORD PTR zp
  170.     mov    es:[di],eax        ; store z result
  171.  
  172.     les    di,DWORD PTR yp
  173.     pop    DWORD PTR es:[di]    ; store y result
  174.  
  175.     les    di,DWORD PTR xp
  176.     pop    DWORD PTR es:[di]    ; store x result
  177.  
  178.     pop    edx
  179.     pop    ecx
  180.     pop    edi
  181.  
  182.     mov    esp,ebp
  183.     pop    ebp
  184.     ret
  185.  
  186. _matrix_point    endp
  187.  
  188.  
  189.  
  190. ;                /* rotate XYZ by matrix */
  191. ;
  192. ;void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp)
  193.  
  194.  
  195. m    equ    [bp+8]          ; arguments
  196. xp    equ    [bp+12]
  197. yp    equ    [bp+16]
  198. zp    equ    [bp+20]
  199.  
  200. x    equ    [bp-4]        ; locals
  201. y    equ    [bp-8]
  202. z    equ    [bp-12]
  203.  
  204.     PUBLIC    _matrix_rotate
  205.  
  206. _matrix_rotate     proc    far
  207.  
  208.     .386
  209.     push    ebp
  210.     mov    ebp,esp
  211.     sub    esp,16
  212.  
  213.     push    edi
  214.     push    ecx
  215.     push    edx
  216.  
  217.     les    bx,DWORD PTR xp
  218.     mov    eax,es:[bx]
  219.     mov    x,eax
  220.     les    bx,DWORD PTR yp
  221.     mov    eax,es:[bx]
  222.     mov    y,eax
  223.     les    bx,DWORD PTR zp
  224.     mov    eax,es:[bx]
  225.     mov    z,eax
  226.  
  227.     les    di,DWORD PTR m
  228.  
  229.     DOTPROD es:[di], es:[di+4], es:[di+8], x, y, z, 0
  230.     push    eax        ; x result
  231.  
  232.     DOTPROD es:[di+12], es:[di+16], es:[di+20], x, y, z, 0
  233.     push    eax        ; y result
  234.  
  235.     DOTPROD es:[di+24], es:[di+28], es:[di+32], x, y, z, 0
  236.  
  237.     les    di,DWORD PTR zp
  238.     mov    es:[di],eax        ; store z result
  239.  
  240.     les    di,DWORD PTR yp
  241.     pop    DWORD PTR es:[di]    ; store y result
  242.  
  243.     les    di,DWORD PTR xp
  244.     pop    DWORD PTR es:[di]    ; store x result
  245.  
  246.     pop    edx
  247.     pop    ecx
  248.     pop    edi
  249.  
  250.     mov    esp,ebp
  251.     pop    ebp
  252.     ret
  253.  
  254. _matrix_rotate    endp
  255.  
  256.  
  257.  
  258. ;/******************** MISC. VECTOR MATH ****************/
  259. ;
  260. ;        /* replaces column N of a matrix with cross of other 2 */
  261. ;        /* used to speed computations, repair matrix scaling   */
  262. ;               /* pointers into matrix: same segment! */
  263.  
  264. ;void cross_product(long *c1, long *c2, long *c3);
  265.  
  266. c1    equ    [bp+8]          ; arguments
  267. c2    equ    [bp+12]
  268. c3    equ    [bp+16]
  269.  
  270. x1    equ    DWORD PTR es:[di]  ; parts of columns
  271. x2    equ    DWORD PTR es:[si]
  272. y1    equ    DWORD PTR es:[di+12]
  273. y2    equ    DWORD PTR es:[si+12]
  274. z1    equ    DWORD PTR es:[di+24]
  275. z2    equ    DWORD PTR es:[si+24]
  276.  
  277.         PUBLIC    _cross_product
  278.  
  279. _cross_product    proc    far
  280.  
  281.     .386
  282.     push    ebp
  283.     mov    ebp,esp
  284.  
  285.     push    edx
  286.     push    ecx
  287.     push    esi
  288.     push    edi
  289.  
  290.     les    di,DWORD PTR c1
  291.     mov    si,WORD PTR c2
  292.  
  293.     CROSSTERM y1,z2,y2,z1
  294.     push    eax
  295.  
  296.     CROSSTERM z1,x2,x1,z2
  297.     push    eax
  298.  
  299.     CROSSTERM x1,y2,x2,y1
  300.  
  301.     les    di,DWORD PTR c3     ; store new column
  302.     mov     z1,eax
  303.     pop    y1
  304.     pop    x1
  305.  
  306.     pop    edi
  307.     pop    esi
  308.     pop    ecx
  309.     pop    edx
  310.  
  311.     mov    esp,ebp
  312.     pop    ebp
  313.     ret
  314.  
  315. _cross_product    endp
  316.  
  317.  
  318.  
  319. ;/****************** MATRIX MANIPULATION ***************/
  320.  
  321.  
  322. ;              /* 3x3 section of matrixs: A*B->C       */
  323. ;void matrix_mult(MATRIX a, MATRIX b, MATRIX c)
  324.  
  325. a    equ    [bp+8]          ; arguments
  326. b    equ    [bp+12]
  327. c    equ    [bp+16]
  328.  
  329. r1    equ    DWORD PTR [bp-4]  ; locals
  330. r2    equ    DWORD PTR [bp-8]  ; temp result allows A*B->A
  331. r3    equ    DWORD PTR [bp-12]
  332. r4    equ    DWORD PTR [bp-16]
  333. r5    equ    DWORD PTR [bp-20]
  334. r6    equ    DWORD PTR [bp-24]
  335. r7    equ    DWORD PTR [bp-28]
  336. r8    equ    DWORD PTR [bp-32]
  337. r9    equ    DWORD PTR [bp-36]
  338.  
  339.     PUBLIC    _matrix_mult
  340.  
  341. _matrix_mult    proc    far
  342.  
  343.     .386
  344.     push    ebp
  345.     mov    ebp,esp
  346.     sub    esp,40
  347.  
  348.     push    ds
  349.     push    esi
  350.     push    edi
  351.     push    ecx
  352.     push    edx
  353.  
  354.     les    si,DWORD PTR a        ; pointers to source matrices
  355.     lds    di,DWORD PTR b
  356.  
  357.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di],ds:[di+12],ds:[di+24],0
  358.     mov    r1,eax
  359.  
  360.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di+4],ds:[di+16],ds:[di+28],0
  361.     mov    r2,eax
  362.  
  363.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di+8],ds:[di+20],ds:[di+32],0
  364.     mov    r3,eax
  365.  
  366.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di],ds:[di+12],ds:[di+24],0
  367.     mov    r4,eax
  368.  
  369.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di+4],ds:[di+16],ds:[di+28],0
  370.     mov    r5,eax
  371.  
  372.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di+8],ds:[di+20],ds:[di+32],0
  373.     mov    r6,eax
  374.  
  375.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di],ds:[di+12],ds:[di+24],0
  376.     mov    r7,eax
  377.  
  378.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di+4],ds:[di+16],ds:[di+28],0
  379.     mov    r8,eax
  380.  
  381.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di+8],ds:[di+20],ds:[di+32],0
  382.     mov    r9,eax
  383.  
  384.     les    di,DWORD PTR c     ; store matrix
  385.     mov    eax,r1
  386.     mov    es:[di],eax
  387.     mov    eax,r2
  388.     mov    es:[di+4],eax
  389.     mov    eax,r3
  390.     mov    es:[di+8],eax
  391.     mov    eax,r4
  392.     mov    es:[di+12],eax
  393.     mov    eax,r5
  394.     mov    es:[di+16],eax
  395.     mov    eax,r6
  396.     mov    es:[di+20],eax
  397.     mov    eax,r7
  398.     mov    es:[di+24],eax
  399.     mov    eax,r8
  400.     mov    es:[di+28],eax
  401.     mov    eax,r9
  402.     mov    es:[di+32],eax
  403.  
  404.     pop    edx
  405.     pop    ecx
  406.     pop    edi
  407.     pop    esi
  408.     pop    ds
  409.  
  410.     mov    esp,ebp
  411.     pop    ebp
  412.     ret
  413.  
  414. _matrix_mult    endp
  415.  
  416.  
  417. ;         /* full homogenous matrix multiply */
  418. ;
  419. ;void matrix_product(MATRIX a, MATRIX b, MATRIX c)
  420.  
  421. a    equ    [bp+8]          ; arguments
  422. b    equ    [bp+12]
  423. c    equ    [bp+16]
  424.  
  425. r1    equ    DWORD PTR [bp-4]  ; locals
  426. r2    equ    DWORD PTR [bp-8]  ; temp result allows A*B->A
  427. r3    equ    DWORD PTR [bp-12]
  428. r4    equ    DWORD PTR [bp-16]
  429. r5    equ    DWORD PTR [bp-20]
  430. r6    equ    DWORD PTR [bp-24]
  431. r7    equ    DWORD PTR [bp-28]
  432. r8    equ    DWORD PTR [bp-32]
  433. r9    equ    DWORD PTR [bp-36]
  434.  
  435. t1    equ    DWORD PTR [bp-40]  ; translation part of result
  436. t2    equ    DWORD PTR [bp-44]
  437. t3    equ    DWORD PTR [bp-48]
  438.  
  439.     PUBLIC    _matrix_product
  440.  
  441. _matrix_product    proc    far
  442.  
  443.     .386
  444.     push    ebp
  445.     mov    ebp,esp
  446.     sub    esp,52
  447.  
  448.     push    ds
  449.     push    esi
  450.     push    edi
  451.     push    ecx
  452.     push    edx
  453.  
  454.     les    si,DWORD PTR a        ; pointers to source matrices
  455.     lds    di,DWORD PTR b
  456.  
  457.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di],ds:[di+12],ds:[di+24],0
  458.     mov    r1,eax
  459.  
  460.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di+4],ds:[di+16],ds:[di+28],0
  461.     mov    r2,eax
  462.  
  463.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di+8],ds:[di+20],ds:[di+32],0
  464.     mov    r3,eax
  465.  
  466.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di],ds:[di+12],ds:[di+24],0
  467.     mov    r4,eax
  468.  
  469.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di+4],ds:[di+16],ds:[di+28],0
  470.     mov    r5,eax
  471.  
  472.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di+8],ds:[di+20],ds:[di+32],0
  473.     mov    r6,eax
  474.  
  475.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di],ds:[di+12],ds:[di+24],0
  476.     mov    r7,eax
  477.  
  478.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di+4],ds:[di+16],ds:[di+28],0
  479.     mov    r8,eax
  480.  
  481.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di+8],ds:[di+20],ds:[di+32],0
  482.     mov    r9,eax
  483.                     ; translational part
  484.  
  485.     DOTPROD es:[si],es:[si+4],es:[si+8],ds:[di+36],ds:[di+40],ds:[di+44],es:[si+36]
  486.     mov    t1,eax
  487.  
  488.     DOTPROD es:[si+12],es:[si+16],es:[si+20],ds:[di+36],ds:[di+40],ds:[di+44],es:[si+40]
  489.     mov    t2,eax
  490.  
  491.     DOTPROD es:[si+24],es:[si+28],es:[si+32],ds:[di+36],ds:[di+40],ds:[di+44],es:[si+44]
  492.     mov    t3,eax
  493.  
  494.     les    di,DWORD PTR c     ; store matrix
  495.     mov    eax,r1
  496.     mov    es:[di],eax
  497.     mov    eax,r2
  498.     mov    es:[di+4],eax
  499.     mov    eax,r3
  500.     mov    es:[di+8],eax
  501.     mov    eax,r4
  502.     mov    es:[di+12],eax
  503.     mov    eax,r5
  504.     mov    es:[di+16],eax
  505.     mov    eax,r6
  506.     mov    es:[di+20],eax
  507.     mov    eax,r7
  508.     mov    es:[di+24],eax
  509.     mov    eax,r8
  510.     mov    es:[di+28],eax
  511.     mov    eax,r9
  512.     mov    es:[di+32],eax
  513.     mov    eax,t1
  514.     mov    es:[di+36],eax
  515.     mov    eax,t2
  516.     mov    es:[di+40],eax
  517.     mov    eax,t3
  518.     mov    es:[di+44],eax
  519.  
  520.     pop    edx
  521.     pop    ecx
  522.     pop    edi
  523.     pop    esi
  524.     pop    ds
  525.  
  526.     mov    esp,ebp
  527.     pop    ebp
  528.     ret
  529.  
  530. _matrix_product    endp
  531.  
  532.  
  533.  
  534. ;void matrix_transpose(MATRIX a, MATRIX b)
  535. ;     /* generate inverse of rotate matrix (transpose) */
  536. ;     /* ONLY WORKS FOR ORTHOGONAL UNSCALED MATRICES   */
  537. ;     /* will do self_transpose as well as copy        */
  538.  
  539. a    equ    [bp+8]          ; arguments
  540. b    equ    [bp+12]
  541.  
  542.     PUBLIC    _matrix_transpose
  543.  
  544. _matrix_transpose    proc    far
  545.  
  546.     .386
  547.     push    ebp
  548.     mov    ebp,esp
  549.  
  550.     push    ds
  551.     push    esi
  552.     push    edi
  553.     push    edx
  554.  
  555.     les    si,DWORD PTR a        ; pointers to source matrices
  556.     lds    di,DWORD PTR b
  557.  
  558.     mov    eax,es:[si]           ; copy diagonals
  559.     mov    ds:[di],eax
  560.     mov    eax,es:[si+16]
  561.     mov    ds:[di+16],eax
  562.     mov    eax,es:[si+32]
  563.     mov    ds:[di+32],eax
  564.  
  565.     mov    eax,es:[si+4]        ; swap others
  566.     mov    edx,es:[si+12]
  567.     mov    ds:[di+4],edx
  568.     mov    ds:[di+12],eax
  569.  
  570.     mov    eax,es:[si+8]
  571.     mov    edx,es:[si+24]
  572.     mov    ds:[di+8],edx
  573.     mov    ds:[di+24],eax
  574.  
  575.     mov    eax,es:[si+28]
  576.     mov    edx,es:[si+20]
  577.     mov    ds:[di+28],edx
  578.     mov    ds:[di+20],eax
  579.  
  580.     pop    edx
  581.     pop    edi
  582.     pop    esi
  583.     pop    ds
  584.  
  585.     mov    esp,ebp
  586.     pop    ebp
  587.     ret
  588.  
  589. _matrix_transpose    endp
  590.  
  591.  
  592.  
  593. ;void inverse_matrix(MATRIX a, MATRIX b)
  594. ;    /* old: Ax+b = c      */
  595. ;       /* b' = (1/A)(-b)     */
  596. ;       /* (1/A) = t(A)       */
  597. ;       /* new: (1/A)c+b' = x */
  598.  
  599. ; basically, B = tr(A) | -At * tr(A)
  600.  
  601. a    equ    [bp+8]          ; arguments
  602. b    equ    [bp+12]
  603.  
  604.     PUBLIC    _inverse_matrix
  605.  
  606. _inverse_matrix    proc    far
  607.  
  608.     .386
  609.     push    ebp
  610.     mov    ebp,esp
  611.  
  612.     push    ds
  613.     push    ecx
  614.     push    esi
  615.     push    edi
  616.     push    edx
  617.  
  618.     les    si,DWORD PTR a        ; pointers to source matrices
  619.     lds    di,DWORD PTR b
  620.  
  621.     mov    eax,es:[si]           ; copy diagonals
  622.     mov    ds:[di],eax
  623.     mov    eax,es:[si+16]
  624.     mov    ds:[di+16],eax
  625.     mov    eax,es:[si+32]
  626.     mov    ds:[di+32],eax
  627.  
  628.     mov    eax,es:[si+4]        ; swap others
  629.     mov    edx,es:[si+12]
  630.     mov    ds:[di+4],edx
  631.     mov    ds:[di+12],eax
  632.  
  633.     mov    eax,es:[si+8]
  634.     mov    edx,es:[si+24]
  635.     mov    ds:[di+8],edx
  636.     mov    ds:[di+24],eax
  637.  
  638.     mov    eax,es:[si+28]
  639.     mov    edx,es:[si+20]
  640.     mov    ds:[di+28],edx
  641.     mov    ds:[di+20],eax
  642.                 ; now, use B to convert translational part
  643.  
  644.     DOTPROD ds:[di],ds:[di+4],ds:[di+8],es:[si+36],es:[si+40],es:[si+44],0
  645.     neg    eax
  646.     mov    ds:[di+36],eax
  647.  
  648.     DOTPROD ds:[di+12],ds:[di+16],ds:[di+20],es:[si+36],es:[si+40],es:[si+44],0
  649.     neg    eax
  650.     mov    ds:[di+40],eax
  651.  
  652.     DOTPROD ds:[di+24],ds:[di+28],ds:[di+32],es:[si+36],es:[si+40],es:[si+44],0
  653.     neg    eax
  654.     mov    ds:[di+44],eax
  655.  
  656.     pop    edx
  657.     pop    edi
  658.     pop    esi
  659.     pop    ecx
  660.     pop    ds
  661.  
  662.     mov    esp,ebp
  663.     pop    ebp
  664.     ret
  665.  
  666. _inverse_matrix    endp
  667.  
  668.  
  669.  
  670. ;/*************** ANGLE/POSITION TO HOMOGENOUS MATRIX ************/
  671.  
  672.  
  673. extrn _isine   : PROC
  674. extrn _icosine : PROC
  675.  
  676. MATRIXDECL MACRO rname        ; SETS UP MATRIX COMPUTE
  677.  
  678. m     equ    [bp+8]          ; arguments
  679. rx    equ    [bp+12]
  680. ry    equ    [bp+16]
  681. rz    equ    [bp+20]
  682. tx    equ    [bp+24]
  683. ty    equ    [bp+28]
  684. tz    equ    [bp+32]
  685.  
  686. sinx    equ    DWORD PTR [bp-4]  ; locals
  687. siny    equ    DWORD PTR [bp-8]  ; temp result allows A*B->A
  688. sinz    equ    DWORD PTR [bp-12]
  689. cosx    equ    DWORD PTR [bp-16]
  690. cosy    equ    DWORD PTR [bp-20]
  691. cosz    equ    DWORD PTR [bp-24]
  692.  
  693.     PUBLIC    rname
  694.  
  695. rname    proc    far
  696.  
  697.     .386
  698.     push    ebp
  699.     mov    ebp,esp
  700.     sub    esp,30
  701.  
  702.     push    DWORD PTR rx        ; trig evaluate
  703.     call    _isine
  704.     add    esp,4
  705.     mov    sinx,eax
  706.  
  707.     push    DWORD PTR ry
  708.     call    _isine
  709.     add    esp,4
  710.     mov    siny,eax
  711.  
  712.     push    DWORD PTR rz
  713.     call    _isine
  714.     add    esp,4
  715.     mov    sinz,eax
  716.  
  717.     push    DWORD PTR rx
  718.     call    _icosine
  719.     add    esp,4
  720.     mov    cosx,eax
  721.  
  722.     push    DWORD PTR ry
  723.     call    _icosine
  724.     add    esp,4
  725.     mov    cosy,eax
  726.  
  727.     push    DWORD PTR rz
  728.     call    _icosine
  729.     add    esp,4
  730.     mov    cosz,eax
  731.  
  732.     push    esi
  733.     push    edi
  734.     les    di,DWORD PTR m
  735.  
  736.     mov    eax,tx
  737.     mov    es:[di+36],eax
  738.     mov    eax,ty
  739.     mov    es:[di+40],eax
  740.     mov    eax,tz
  741.     mov    es:[di+44],eax
  742.  
  743. ENDM
  744.  
  745. MATRIXEND  MACRO rname
  746.     pop    edi
  747.     pop    esi
  748.  
  749.     mov    esp,ebp
  750.     pop    ebp
  751.     ret
  752.  
  753. rname    endp
  754.  
  755. ENDM
  756.  
  757.  
  758. ;void matrix_RXYZ(MATRIX m, long rx, long ry, long rz,
  759. ;    long tx, long ty, long tz)
  760. ; /* a fast standard matrix compute */
  761.  
  762. MATRIXDECL _matrix_RXYZ
  763.  
  764.     MULT29    cosz,cosy
  765.     mov    es:[di],eax
  766.  
  767.     MULT29    cosy,sinz
  768.     neg    eax
  769.     mov    es:[di+4],eax
  770.  
  771.     mov    eax,siny
  772.     mov    es:[di+8],eax
  773.  
  774.     MULT29    cosx,sinz
  775.     mov    esi,eax
  776.     MMULT29 cosz,sinx,siny
  777.     add    eax,esi
  778.     mov    es:[di+12],eax
  779.  
  780.     MMULT29 sinz,sinx,siny
  781.     mov    esi,eax
  782.     MULT29    cosz,cosx
  783.     sub    eax,esi
  784.     mov    es:[di+16],eax
  785.  
  786.     MULT29    cosy,sinx
  787.     neg    eax
  788.     mov    es:[di+20],eax
  789.  
  790.     MMULT29 siny,cosz,cosx
  791.     mov    esi,eax
  792.     MULT29    sinz,sinx
  793.     sub    eax,esi
  794.     mov    es:[di+24],eax
  795.  
  796.     MULT29    cosz,sinx
  797.     mov    esi,eax
  798.     MMULT29 cosx,sinz,siny
  799.     add    eax,esi
  800.     mov    es:[di+28],eax
  801.  
  802.     MULT29    cosx,cosy
  803.     mov    es:[di+32],eax
  804.  
  805. MATRIXEND _matrix_RXYZ
  806.  
  807.  
  808. ;void matrix_RYXZ(MATRIX m, long rx, long ry, long rz, Y
  809. ;    long tx, long ty, long tz)
  810. ; /* a fast standard matrix compute */
  811.  
  812. MATRIXDECL _matrix_RYXZ
  813.  
  814.     MULT29    cosz,cosy
  815.     mov    esi,eax
  816.     MMULT29 sinz,sinx,siny
  817.     add    eax,esi
  818.     mov    es:[di],eax
  819.  
  820.     MULT29    cosy,sinz
  821.     mov    esi,eax
  822.     MMULT29 cosz,sinx,siny
  823.     sub    eax,esi
  824.     mov    es:[di+4],eax
  825.  
  826.     MULT29    cosx,siny
  827.     mov    es:[di+8],eax
  828.  
  829.     MULT29    cosx,sinz
  830.     mov    es:[di+12],eax
  831.  
  832.     MULT29    cosz,cosx
  833.     mov    es:[di+16],eax
  834.  
  835.     mov    eax,sinx
  836.     neg    eax
  837.     mov    es:[di+20],eax
  838.  
  839.     MULT29    cosz,siny
  840.     mov    esi,eax
  841.     MMULT29 cosy,sinz,sinx
  842.     sub    eax,esi
  843.     mov    es:[di+24],eax
  844.  
  845.     MULT29    sinz,siny
  846.     mov    esi,eax
  847.     MMULT29 cosz,cosy,sinx
  848.     add    eax,esi
  849.     mov    es:[di+28],eax
  850.  
  851.     MULT29    cosx,cosy
  852.     mov    es:[di+32],eax
  853.  
  854. MATRIXEND _matrix_RYXZ
  855.  
  856.  
  857.  
  858. ;void matrix_RXZY(MATRIX m, long rx, long ry, long rz, Y
  859. ;    long tx, long ty, long tz)
  860. ; /* a fast standard matrix compute */
  861.  
  862. MATRIXDECL _matrix_RXZY
  863.  
  864.     MULT29    cosz,cosy
  865.     mov    es:[di],eax
  866.  
  867.     mov    eax,sinz
  868.     neg    eax
  869.     mov    es:[di+4],eax
  870.  
  871.     MULT29    cosz,siny
  872.     mov    es:[di+8],eax
  873.  
  874.     MULT29    sinx,siny
  875.     mov    esi,eax
  876.     MMULT29 cosx,cosy,sinz
  877.     add    eax,esi
  878.     mov    es:[di+12],eax
  879.  
  880.     MULT29    cosz,cosx
  881.     mov    es:[di+16],eax
  882.  
  883.     MULT29    cosy,sinx
  884.     mov    esi,eax
  885.     MMULT29 cosx,sinz,siny
  886.     sub    eax,esi
  887.     mov    es:[di+20],eax
  888.  
  889.     MULT29    cosx,siny
  890.     mov    esi,eax
  891.     MMULT29 cosy,sinz,sinx
  892.     sub    eax,esi
  893.     mov    es:[di+24],eax
  894.  
  895.     MULT29    cosz,sinx
  896.     mov    es:[di+28],eax
  897.  
  898.     MULT29    cosx,cosy
  899.     mov    esi,eax
  900.     MMULT29 sinz,sinx,siny
  901.     add    eax,esi
  902.     mov    es:[di+32],eax
  903.  
  904. MATRIXEND _matrix_RXZY
  905.  
  906.     end