home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / devel5 / intmathx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-07  |  13.2 KB  |  781 lines

  1. /* Routines for moving, scaling and rotating objects */
  2. /* Matrix math, assembly by Dave Stampe */
  3.  
  4. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  5.      May be freely used to write software for release into the public domain;
  6.      all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  7.      for permission to incorporate any part of this software into their
  8.      products!
  9.  
  10.      ATTRIBUTION:  If you use any part of this source code or the libraries
  11.      in your projects, you must give attribution to REND386, Dave Stampe,
  12.      and Bernie Roehl in your documentation, source code, and at startup
  13.      of your program.  Let's keep the freeware ball rolling!
  14.  */
  15.  
  16. /* Contact: broehl@sunee.waterloo.edu or dstampe@sunee.waterloo.edu */
  17.  
  18. #pragma inline
  19.  
  20. #include <stdio.h>
  21. #include "3dstruct.h"
  22.  
  23. #define XFSC 536870912   /* 2**29 for shifting xform coeffs to long */
  24.  
  25. /*************** TRIGNOMETRIC FUNCTIONS *****************/
  26.  
  27. /* (from inttrig.c) */
  28.  
  29. extern long isine(long x);
  30. extern long icosine(long x);
  31. extern long arcsine(long x);
  32. extern long arccosine(long x);
  33. extern long arctan2(long y, long x);
  34.  
  35. /*************** MATRIX MANIPULATION *****************/
  36.  
  37. /* (from matrix.c) */
  38.  
  39. #define RXYZ 1        /* matrix rotation types */
  40. #define RYXZ 0          /* ONLY RYXZ guaranteed to be tested */
  41. #define RXZY 2
  42. #define RZYX 5
  43. #define RZXY 4
  44. #define RYZX 6
  45.  
  46. extern void matrix_point(MATRIX m, long *xp, long *yp, long *zp);
  47. extern void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp);
  48. extern void cross_column(MATRIX m, int col);
  49. extern long m_mult(long a, long b);    /* perform mult. by matrix element */
  50. extern long dot_prod_29(long a, long b, long c, long x, long y, long z);
  51. extern void matrix_mult(MATRIX a, MATRIX b, MATRIX c);
  52. extern void matrix_product(MATRIX a, MATRIX b, MATRIX c);
  53. extern void matrix_transpose(MATRIX a, MATRIX b);
  54. extern void inverse_matrix(MATRIX a, MATRIX b);
  55. extern void identity_matrix(MATRIX m);
  56. extern void matrix_copy(MATRIX m, MATRIX n);
  57. extern void matrix_rot_copy(MATRIX m, MATRIX n);
  58.  
  59.                /* create rotation/translation */
  60.                /* "matrix" from angle data    */
  61.  
  62. /******************** APPLY MATRIX TO OBJECTS **************/
  63.  
  64. void matmove_rep(REP *rep, MATRIX m)
  65. {
  66.  int i;
  67.  VERTEX *v = rep->verts;     /* use "matrix" to rotate then translate */
  68.  POLY   *p = rep->polys;
  69.  int vs = sizeof(VERTEX);
  70.  int ps = sizeof(POLY);
  71.  int vc = rep->nverts;
  72.  int pc = rep->npolys;
  73.  long rx,ry,rz;
  74.  
  75.  asm {
  76.     .386
  77.     push    ds
  78.     push    si
  79.     push    di
  80.     push    cx
  81.     push    dx
  82.     lds    si,DWORD PTR m
  83.  
  84.     les    di,DWORD PTR v   /* rotate/translate all vertices */
  85.       }
  86. vconv:
  87.  asm {
  88.     mov    eax,ds:[si]
  89.     imul    DWORD PTR es:[di].(VERTEX)ox
  90.     mov    ecx,edx
  91.     mov    ebx,eax
  92.     mov    eax,ds:[si+4]
  93.     imul    DWORD PTR es:[di].(VERTEX)oy
  94.     add    ebx,eax
  95.     adc    ecx,edx
  96.     mov    eax,ds:[si+8]
  97.     imul    DWORD PTR es:[di].(VERTEX)oz
  98.     add    eax,ebx
  99.     adc    edx,ecx
  100.     shrd    eax,edx,29
  101.     adc    eax,ds:[si+36]
  102.     mov    es:[di].(VERTEX)x,eax
  103.  
  104.     mov    eax,ds:[si+12]
  105.     imul    DWORD PTR es:[di].(VERTEX)ox
  106.     mov    ecx,edx
  107.     mov    ebx,eax
  108.     mov    eax,ds:[si+16]
  109.     imul    DWORD PTR es:[di].(VERTEX)oy
  110.     add    ebx,eax
  111.     adc    ecx,edx
  112.     mov    eax,ds:[si+20]
  113.     imul    DWORD PTR es:[di].(VERTEX)oz
  114.     add    eax,ebx
  115.     adc    edx,ecx
  116.     shrd    eax,edx,29
  117.     adc    eax,ds:[si+40]
  118.     mov    es:[di].(VERTEX)y,eax
  119.  
  120.     mov    eax,ds:[si+24]
  121.     imul    DWORD PTR es:[di].(VERTEX)ox
  122.     mov    ecx,edx
  123.     mov    ebx,eax
  124.     mov    eax,ds:[si+28]
  125.     imul    DWORD PTR es:[di].(VERTEX)oy
  126.     add    ebx,eax
  127.     adc    ecx,edx
  128.     mov    eax,ds:[si+32]
  129.     imul    DWORD PTR es:[di].(VERTEX)oz
  130.     add    eax,ebx
  131.     adc    edx,ecx
  132.     shrd    eax,edx,29
  133.     adc    eax,ds:[si+44]
  134.     mov    es:[di].(VERTEX)z,eax
  135.  
  136.     add    di,vs
  137.     dec     WORD PTR vc
  138.     jz      vconve
  139.     jmp    vconv
  140.      }
  141. vconve:
  142.  asm {
  143.     les    di,DWORD PTR p      /* rotate all normals */
  144.      }
  145. pconv:
  146.  asm {
  147.     mov    eax,ds:[si]
  148.     imul    DWORD PTR es:[di].(POLY)onormalx
  149.     mov    ecx,edx
  150.     mov    ebx,eax
  151.     mov    eax,ds:[si+4]
  152.     imul    DWORD PTR es:[di].(POLY)onormaly
  153.     add    ebx,eax
  154.     adc    ecx,edx
  155.     mov    eax,ds:[si+8]
  156.     imul    DWORD PTR es:[di].(POLY)onormalz
  157.     add    eax,ebx
  158.     adc    edx,ecx
  159.     shrd    eax,edx,29
  160.     adc    eax,0
  161.     mov    es:[di].(POLY)normalx,eax
  162.  
  163.     mov    eax,ds:[si+12]
  164.     imul    DWORD PTR es:[di].(POLY)onormalx
  165.     mov    ecx,edx
  166.     mov    ebx,eax
  167.     mov    eax,ds:[si+16]
  168.     imul    DWORD PTR es:[di].(POLY)onormaly
  169.     add    ebx,eax
  170.     adc    ecx,edx
  171.     mov    eax,ds:[si+20]
  172.     imul    DWORD PTR es:[di].(POLY)onormalz
  173.     add    eax,ebx
  174.     adc    edx,ecx
  175.     shrd    eax,edx,29
  176.     adc    eax,0
  177.     mov    es:[di].(POLY)normaly,eax
  178.  
  179.     mov    eax,ds:[si+24]
  180.     imul    DWORD PTR es:[di].(POLY)onormalx
  181.     mov    ecx,edx
  182.     mov    ebx,eax
  183.     mov    eax,ds:[si+28]
  184.     imul    DWORD PTR es:[di].(POLY)onormaly
  185.     add    ebx,eax
  186.     adc    ecx,edx
  187.     mov    eax,ds:[si+32]
  188.     imul    DWORD PTR es:[di].(POLY)onormalz
  189.     add    eax,ebx
  190.     adc    edx,ecx
  191.     shrd    eax,edx,29
  192.     adc    eax,0
  193.     mov    es:[di].(POLY)normalz,eax
  194.  
  195.     add    di,ps
  196.     dec     WORD PTR pc
  197.     jz      pconve
  198.     jmp    pconv
  199.             }
  200. pconve:
  201.  asm {
  202.     pop    dx
  203.     pop    cx
  204.     pop    di
  205.     pop    si
  206.     pop    ds
  207.          }
  208.  
  209.  rep->update_count++;
  210. }
  211.  
  212.  
  213. void matmove_osphere(OBJECT *obj, MATRIX m)
  214. {
  215.  asm {                            /* rotate/translate sphere center */
  216.     .386
  217.     push    ds
  218.     push    si
  219.     push    di
  220.     push    cx
  221.     push    dx
  222.     lds    si,DWORD PTR m
  223.  
  224.     les    di,DWORD PTR obj
  225.     mov    eax,ds:[si]
  226.     imul    DWORD PTR es:[di].(OBJECT)osphx
  227.     mov    ecx,edx
  228.     mov    ebx,eax
  229.     mov    eax,ds:[si+4]
  230.     imul    DWORD PTR es:[di].(OBJECT)osphy
  231.     add    ebx,eax
  232.     adc    ecx,edx
  233.     mov    eax,ds:[si+8]
  234.     imul    DWORD PTR es:[di].(OBJECT)osphz
  235.     add    eax,ebx
  236.     adc    edx,ecx
  237.     shrd    eax,edx,29
  238.     adc    eax,ds:[si+36]
  239.     mov    es:[di].(OBJECT)sphx,eax
  240.  
  241.     mov    eax,ds:[si+12]
  242.     imul    DWORD PTR es:[di].(OBJECT)osphx
  243.     mov    ecx,edx
  244.     mov    ebx,eax
  245.     mov    eax,ds:[si+16]
  246.     imul    DWORD PTR es:[di].(OBJECT)osphy
  247.     add    ebx,eax
  248.     adc    ecx,edx
  249.     mov    eax,ds:[si+20]
  250.     imul    DWORD PTR es:[di].(OBJECT)osphz
  251.     add    eax,ebx
  252.     adc    edx,ecx
  253.     shrd    eax,edx,29
  254.     adc    eax,ds:[si+40]
  255.     mov    es:[di].(OBJECT)sphy,eax
  256.  
  257.     mov    eax,ds:[si+24]
  258.     imul    DWORD PTR es:[di].(OBJECT)osphx
  259.     mov    ecx,edx
  260.     mov    ebx,eax
  261.     mov    eax,ds:[si+28]
  262.     imul    DWORD PTR es:[di].(OBJECT)osphy
  263.     add    ebx,eax
  264.     adc    ecx,edx
  265.     mov    eax,ds:[si+32]
  266.     imul    DWORD PTR es:[di].(OBJECT)osphz
  267.     add    eax,ebx
  268.     adc    edx,ecx
  269.     shrd    eax,edx,29
  270.     adc    eax,ds:[si+44]
  271.     mov    es:[di].(OBJECT)sphz,eax
  272.  
  273.     pop    dx
  274.     pop    cx
  275.     pop    di
  276.     pop    si
  277.     pop    ds
  278.          }
  279.  
  280.  obj->update_count++;
  281. }
  282.                                                             /* works as if only current rep existed */
  283.  
  284. void apply_matrix(OBJECT *obj, MATRIX m)
  285. {
  286.  REP *rep = obj->current_rep;
  287.  if(rep==NULL) return;
  288.  
  289.  matmove_osphere(obj, m);
  290.  matmove_rep(rep, m);
  291.  obj->update_count++;
  292.  rep->update_count++;
  293. }
  294.  
  295.  
  296.                  /* used to compute floor/ceiling of areas */
  297.  
  298. long plane_y(long a, long b, long c, long d, long x, long z)
  299. {
  300.  /* computes (Ax + Cz + D)/-B */
  301.  
  302.  long result;
  303.  
  304.  asm {
  305.     push    si
  306.     push    di
  307.  
  308.     mov    eax,a
  309.     imul    DWORD PTR x
  310.     mov    esi,eax
  311.     mov    edi,edx
  312.  
  313.     mov    eax,c
  314.     imul    DWORD PTR z
  315.     add    esi,eax
  316.     adc    edi,edx
  317.  
  318.     mov    eax,DWORD PTR d
  319.     cdq
  320.     add    eax,esi
  321.     adc    edx,edi
  322.     idiv    DWORD PTR b
  323.     mov    result,eax
  324.  
  325.     pop    di
  326.     pop    si
  327.          }
  328.  return result;
  329. }
  330.  
  331.  
  332.  
  333. /************ COLLISION DETECTION AND SELECTION ***********/
  334.  
  335. long sphere_pretest(OBJECT *obj, long x, long y, long z)
  336. {
  337.  long dist = 0;     /* returns 0x7FFFFFFF if not in, else (D) */
  338.  
  339.  long sx = obj->sphx;
  340.  long sy = obj->sphy;
  341.  long sz = obj->sphz;
  342.  long sr = obj->sphr;
  343.  
  344.  asm {
  345.     push    cx
  346.  
  347.     mov    eax,sx   /* x bounds */
  348.     sub    eax,x
  349.     cmp    eax,sr
  350.     jg    notin
  351.     neg    eax
  352.     cmp    eax,sr
  353.     jg    notin
  354.  
  355.     mov    eax,sy   /* y bounds */
  356.     sub    eax,y
  357.     cmp    eax,sr
  358.     jg    notin
  359.     neg    eax
  360.     cmp    eax,sr
  361.     jg    notin
  362.  
  363.     mov    eax,sz   /* z bounds */
  364.     sub    eax,z
  365.     cmp    eax,sr
  366.     jg    notin
  367.     neg    eax
  368.     cmp    eax,sr
  369.     jg    notin
  370.  
  371.     imul    eax      /* square of distance to center */
  372.     mov    ebx,eax
  373.     mov    ecx,edx
  374.  
  375.     mov    eax,sx
  376.     sub    eax,x
  377.     imul    eax
  378.     add    ebx,eax
  379.     adc    ecx,edx
  380.  
  381.     mov    eax,sy
  382.     sub    eax,y
  383.     imul    eax
  384.     add    ebx,eax
  385.     adc    ecx,edx
  386.  
  387.     mov    eax,sr   /* square of radius */
  388.     imul    eax
  389.     cmp    edx,ecx
  390.     ja    in
  391.     jb    notin
  392.     cmp    eax,ebx
  393.     jae    in
  394.          }
  395. notin:                   /* outside of sphere */
  396.  asm pop cx;
  397.  return 0x7FFFFFFF;      /* big never wins */
  398.  
  399. in:
  400.  asm {
  401.     test    ebx,-1         /* shift so denom. is 32-bit or less */
  402.     jz    nolo1
  403.     mov    eax,edx
  404.     xor    edx,edx
  405.     mov    ebx,ecx
  406.     xor    ecx,ecx
  407.      }
  408. nolo1:
  409.  asm {
  410.     mov    eax,x    /* abs(x-sx)+abs(y-sy)+abs(z-sz) approx. dist from center */
  411.     sub    eax,sx
  412.     cdq
  413.     xor    eax,edx
  414.     sub    eax,edx
  415.     mov    ebx,eax
  416.  
  417.     mov    eax,x
  418.     sub    eax,sx
  419.     cdq
  420.     xor    eax,edx
  421.     sub    eax,edx
  422.     add    ebx,eax
  423.  
  424.     mov    eax,x
  425.     sub    eax,sx
  426.     cdq
  427.     xor    eax,edx
  428.     sub    eax,edx
  429.     add    ebx,eax
  430.  
  431.     mov    dist, ebx
  432.     pop    cx
  433.          }
  434.  return dist;      /* for comparison between objects: smallest wins */
  435. }
  436.  
  437.  
  438.  
  439. /************* POLYGON NORMAL COMPUTATION *************/
  440.  
  441.       /* returns abs(x1-x2) + abs(y1-y2) + abs(z1-z2) */
  442.  
  443. long big_dist(long x1, long y1, long z1,
  444.            long x2, long y2, long z2 )
  445. {
  446.  long dist;
  447.  
  448.  asm {
  449.     mov     eax,x1
  450.     sub    eax,x2
  451.     cdq
  452.     xor    eax,edx
  453.     sub    eax,edx
  454.     mov    ecx,eax
  455.  
  456.     mov     eax,y1
  457.     sub    eax,y2
  458.     cdq
  459.     xor    eax,edx
  460.     sub    eax,edx
  461.     add    ecx,eax
  462.  
  463.     mov     eax,z1
  464.     sub    eax,z2
  465.     cdq
  466.     xor    eax,edx
  467.     sub    eax,edx
  468.     add    ecx,eax
  469.  
  470.     mov    dist,ecx
  471.      }
  472.  return dist;
  473. }
  474.  
  475.  
  476.     /* compute, unitize (3.29 format) normal to plane.   */
  477.     /* returns -1 if normal is zero, else log2(length)   */
  478.  
  479. int find_normal(long x1, long y1, long z1,
  480.         long x2, long y2, long z2,
  481.         long x3, long y3, long z3,
  482.         long *xn, long *yn, long *zn)
  483. {
  484.  long xh, xl, yh, yl, zh, zl;
  485.  long xah, xal, yah, yal, zah, zal;
  486.  int length;
  487.  
  488.  extern int sqrtable[1024];
  489.  
  490.  asm {
  491.     push    dx
  492.     push    cx
  493.     push    si
  494.     push    di
  495.  
  496.     mov    eax,y2        /* compute 64-bit cross product   */
  497.     sub    eax,y1        /* and also abs. value for shifts */
  498.     mov    ecx,z3
  499.     sub    ecx,z2
  500.     imul    ecx
  501.     mov    edi,edx
  502.     mov    esi,eax
  503.     mov    eax,y3
  504.     sub    eax,y2
  505.     mov    ecx,z2
  506.     sub    ecx,z1
  507.     imul    ecx
  508.     sub    esi,eax
  509.     sbb    edi,edx
  510.     mov    xh,edi
  511.     mov    xl,esi
  512.     jge    stax
  513.     not    edi
  514.     not    esi
  515.     add    esi,1
  516.     adc    edi,0
  517.      }
  518. stax:
  519.  asm {
  520.     mov    xah,edi
  521.     mov    xal,esi
  522.  
  523.     mov    eax,z2
  524.     sub    eax,z1
  525.     mov    ecx,x3
  526.     sub    ecx,x2
  527.     imul    ecx
  528.     mov    edi,edx
  529.     mov    esi,eax
  530.     mov    eax,z3
  531.     sub    eax,z2
  532.     mov    ecx,x2
  533.     sub    ecx,x1
  534.     imul    ecx
  535.     sub    esi,eax
  536.     sbb    edi,edx
  537.     mov    yh,edi
  538.     mov    yl,esi
  539.     jge    stay
  540.     not    edi
  541.     not    esi
  542.     add    esi,1
  543.     adc    edi,0
  544.      }
  545. stay:
  546.  asm {
  547.     mov    yah,edi
  548.     mov    yal,esi
  549.  
  550.     mov    eax,x2
  551.     sub    eax,x1
  552.     mov    ecx,y3
  553.     sub    ecx,y2
  554.     imul    ecx
  555.     mov    edi,edx
  556.     mov    esi,eax
  557.     mov    eax,x3
  558.     sub    eax,x2
  559.     mov    ecx,y2
  560.     sub    ecx,y1
  561.     imul    ecx
  562.     sub    esi,eax
  563.     sbb    edi,edx
  564.     mov    zh,edi
  565.     mov    zl,esi
  566.     jge    staz
  567.     not    edi
  568.     not    esi
  569.     add    esi,1
  570.     adc    edi,0
  571.      }
  572. staz:
  573.  asm {
  574.     mov    zah,edi
  575.     mov    zal,esi
  576.      }
  577.  
  578.  asm {                    /* now normalize to 3.29 */
  579.     or    esi,yal
  580.     or    esi,xal
  581.     or    edi,yah
  582.     or    edi,xah
  583.     jz    zero_h
  584.  
  585.     xor    ax,ax           /* ax is shift count */
  586.     test    edi,0FFFF0000h  /* top word not zero: cnvt to 1.n <3.29> */
  587.     jz    z16h
  588.     add    ax,16
  589.     shr    edi,16
  590.      }
  591. z16h:
  592.  asm {
  593.     test    di,0FF00h
  594.     jz    z8h
  595.     add    ax,8
  596.     shr    edi,8
  597.      }
  598. z8h:
  599.  asm {
  600.     shl    edi,8       /* most ecomonical pos'n */
  601.     bsr    cx,di       /* get exact shift */
  602.     sub    cx,5
  603.     add     cx,ax
  604.  
  605.     mov    eax,xh      /* convert cross product to 1.n */
  606.     shrd    xl,eax,cl
  607.     mov    eax,yh
  608.     shrd    yl,eax,cl
  609.     mov    eax,zh
  610.     shrd    zl,eax,cl
  611.  
  612.     add    cx,29
  613.     mov    length,cx
  614.  
  615.     jmp    dshnorm
  616.          }
  617.  
  618. zero_h:
  619.  asm {
  620.     or    esi,esi
  621.     jz    zero_normal
  622.     mov    ax,24
  623.     test    esi,0FFFF0000h  /* top word is zero: cnvt to 1.n <3.29> */
  624.     jz    z16l
  625.     sub    ax,16
  626.     shr    esi,16
  627.      }
  628. z16l:
  629.  asm {
  630.     test    si,0FF00h
  631.     jz    z8l
  632.     sub    ax,8
  633.     shr    esi,8
  634.      }
  635. z8l:
  636.  asm {
  637.     shl    esi,8       /* most ecomonical pos'n */
  638.     bsr    cx,si       /* get exact shift */
  639.     neg    cx
  640.     add    cx,13
  641.     add    cx,ax
  642.  
  643.     jz    noshiftl
  644.     jg    lshiftl
  645.  
  646.     neg    cx
  647.     mov    eax,xh      /* convert cross product to 1.n   */
  648.     shrd    xl,eax,cl   /* need ext. for borderline cases */
  649.     mov    eax,yh
  650.     shrd    yl,eax,cl
  651.     mov    eax,zh
  652.     shrd    zl,eax,cl
  653.      }
  654. noshiftl:
  655.  asm {
  656.     add    cx,29
  657.     mov    length,cx
  658.  
  659.     jmp    dshnorm
  660.      }
  661. lshiftl:
  662.  asm {
  663.     shl    DWORD PTR xl,cl
  664.     shl    DWORD PTR yl,cl
  665.     shl    DWORD PTR zl,cl
  666.  
  667.     mov    ax,29
  668.     sub    ax,cx
  669.     mov    length,ax
  670.      }
  671. dshnorm:  goto finish;
  672.  
  673. zero_normal:
  674.  asm {
  675.     pop    di
  676.     pop    si
  677.     pop    cx
  678.     pop    dx
  679.      }
  680.  *xn = *yn = *zn = -1;
  681.  return 0;
  682.  
  683. finish:             /* compute magnitude, convert to unit length */
  684.  
  685.  asm {
  686.     mov    eax,xl            /* compute squares */
  687.     sar    eax,16
  688.     imul    ax
  689.     mov    bx,dx
  690.     mov    cx,ax
  691.  
  692.     mov    eax,yl
  693.     sar    eax,16
  694.     imul    ax
  695.     add    cx,ax
  696.     adc    bx,dx
  697.  
  698.     mov    eax,zl
  699.     sar    eax,16
  700.     imul    ax
  701.     add    cx,ax
  702.     adc    bx,dx
  703.  
  704.     shr    bx,4             /* magnitude << 13 */
  705.     shl    bx,1
  706.     mov    cx,sqrtable[bx]
  707.     movzx    ecx,cx
  708.  
  709.     mov    eax,xl           /* scale cross product */
  710.     cdq
  711.     shld    edx,eax,13
  712.     shl    eax,13
  713.     idiv    ecx
  714.     mov    xl,eax
  715.  
  716.     mov    eax,yl
  717.     cdq
  718.     shld    edx,eax,13
  719.     shl    eax,13
  720.     idiv    ecx
  721.     mov    yl,eax
  722.  
  723.     mov    eax,zl
  724.     cdq
  725.     shld    edx,eax,13
  726.     shl    eax,13
  727.     idiv    ecx
  728.     mov    zl,eax
  729.  
  730.     pop    di
  731.     pop    si
  732.     pop    cx
  733.     pop    dx
  734.      }
  735.  
  736.  *xn = -xl;     /* left-hand coordinate system */
  737.  *yn = -yl;
  738.  *zn = -zl;
  739.  
  740.  return length;
  741. }
  742.  
  743.  
  744. long scale_16(long s, long a, long x)    /* perform scaling by 16.16 number */
  745. {
  746.  long result;
  747.  
  748.  asm {
  749.     mov    eax,DWORD PTR x
  750.     add eax,DWORD PTR a
  751.     imul    DWORD PTR s
  752.     shrd    eax,edx,16
  753.     adc    eax,0
  754.     mov    DWORD PTR result,eax
  755.      }
  756.  return result;
  757. }
  758.  
  759. long calc_scale_16(long a, long b, long s)   /* compute 16.16 scaling factor */
  760. {
  761.  long result = 0;
  762.  
  763.  asm {
  764.     mov    ebx,DWORD PTR a
  765.     sub    ebx,DWORD PTR b
  766.     je    cdiv
  767.     mov    eax, DWORD PTR s
  768.     cdq
  769.     shld    edx,eax,17
  770.     shl    eax,17
  771.     idiv  ebx
  772.     mov    DWORD PTR result,eax
  773.          }
  774. cdiv:
  775.  return result;
  776. }
  777.  
  778.  
  779.  
  780.  
  781.