Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. //
  21. // r_aliasa.s
  22. // x86 assembly-language Alias model transform and project code.
  23. //
  24.  
  25. #include "asm_i386.h"
  26. #include "quakeasm.h"
  27. #include "asm_draw.h"
  28. #include "d_ifacea.h"
  29.  
  30. #if id386
  31.  
  32.         .data
  33.  
  34. Lfloat_1:       .single 1.0
  35. Ltemp:          .long   0
  36. Lcoords:        .long   0, 0, 0
  37.  
  38.         .text
  39.  
  40. #define fv                      12+4
  41. #define pstverts        12+8
  42.  
  43. .globl C(R_AliasTransformAndProjectFinalVerts)
  44. C(R_AliasTransformAndProjectFinalVerts):
  45.         pushl   %ebp                            // preserve caller's stack frame
  46.         pushl   %edi
  47.         pushl   %esi                            // preserve register variables
  48.  
  49. //      int                     i, temp;
  50. //      float           lightcos, *plightnormal, zi;
  51. //      trivertx_t      *pverts;
  52.  
  53. //      pverts = r_apverts;
  54.         movl    C(r_apverts),%esi
  55.  
  56. //      for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
  57. //      {
  58.         movl    pstverts(%esp),%ebp
  59.         movl    fv(%esp),%edi
  60.         movl    C(r_anumverts),%ecx
  61.         subl    %edx,%edx
  62.  
  63. Lloop:
  64.  
  65. //      // transform and project
  66. //              zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
  67. //                              aliastransform[2][3]);
  68.         movb    (%esi),%dl
  69.         movb    %dl,Lcoords
  70.         fildl   Lcoords                         // v[0]
  71.         movb    1(%esi),%dl
  72.         movb    %dl,Lcoords+4
  73.         fildl   Lcoords+4                       // v[1] | v[0]
  74.         movb    2(%esi),%dl    
  75.         movb    %dl,Lcoords+8
  76.         fildl   Lcoords+8                       // v[2] | v[1] | v[0]
  77.  
  78.         fld             %st(2)                          // v[0] | v[2] | v[1] | v[0]
  79.         fmuls   C(aliastransform)+32 // accum | v[2] | v[1] | v[0]
  80.         fld             %st(2)                          // v[1] | accum | v[2] | v[1] | v[0]
  81.         fmuls   C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0]
  82.         fxch    %st(1)                          // accum | accum2 | v[2] | v[1] | v[0]
  83.         fadds   C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0]
  84.         fld             %st(2)                          // v[2] | accum | accum2 | v[2] | v[1] | v[0]
  85.         fmuls   C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] |
  86.                                                                  //  v[0]
  87.         fxch    %st(1)                          // accum | accum3 | accum2 | v[2] | v[1] | v[0]
  88.         faddp   %st(0),%st(2)           // accum3 | accum | v[2] | v[1] | v[0]
  89.         movb    tv_lightnormalindex(%esi),%dl
  90.         movl    stv_s(%ebp),%eax
  91.         movl    %eax,fv_v+8(%edi)
  92.         faddp   %st(0),%st(1)           // z | v[2] | v[1] | v[0]
  93.  
  94.         movl    stv_t(%ebp),%eax
  95.         movl    %eax,fv_v+12(%edi)
  96.  
  97. //      // lighting
  98. //              plightnormal = r_avertexnormals[pverts->lightnormalindex];
  99.  
  100.         fdivrs  Lfloat_1                        // zi | v[2] | v[1] | v[0]
  101.  
  102. //              fv->v[2] = pstverts->s;
  103. //              fv->v[3] = pstverts->t;
  104. //              fv->flags = pstverts->onseam;
  105.         movl    stv_onseam(%ebp),%eax
  106.         movl    %eax,fv_flags(%edi)
  107.  
  108.         movl    fv_size(%edi),%eax
  109.         movl    stv_size(%ebp),%eax
  110.         movl    4(%esi),%eax
  111.  
  112.         leal    (%edx,%edx,2),%eax      // index*3
  113.  
  114.         fxch    %st(3)                          // v[0] | v[2] | v[1] | zi
  115.  
  116. //              lightcos = DotProduct (plightnormal, r_plightvec);
  117.         flds    C(r_avertexnormals)(,%eax,4)
  118.         fmuls   C(r_plightvec)
  119.         flds    C(r_avertexnormals)+4(,%eax,4)
  120.         fmuls   C(r_plightvec)+4
  121.         flds    C(r_avertexnormals)+8(,%eax,4)
  122.         fmuls   C(r_plightvec)+8
  123.         fxch    %st(1)
  124.         faddp   %st(0),%st(2)
  125.         fld             %st(2)                           // v[0] | laccum | laccum2 | v[0] | v[2] |
  126.                                                                  //  v[1] | zi
  127.         fmuls   C(aliastransform)+0  // xaccum | laccum | laccum2 | v[0] | v[2] |
  128.                                                                  //  v[1] | zi
  129.         fxch    %st(2)                           // laccum2 | laccum | xaccum | v[0] | v[2] |
  130.                                                                  //  v[1] | zi
  131.         faddp   %st(0),%st(1)            // laccum | xaccum | v[0] | v[2] | v[1] | zi
  132.  
  133. //              temp = r_ambientlight;
  134. //              if (lightcos < 0)
  135. //              {
  136.         fsts    Ltemp
  137.         movl    C(r_ambientlight),%eax
  138.         movb    Ltemp+3,%dl
  139.         testb   $0x80,%dl
  140.         jz              Lsavelight      // no need to clamp if only ambient lit, because
  141.                                                 //  r_ambientlight is preclamped
  142.  
  143. //                      temp += (int)(r_shadelight * lightcos);
  144.         fmuls   C(r_shadelight)
  145. // FIXME: fast float->int conversion?
  146.         fistpl  Ltemp
  147.         addl    Ltemp,%eax
  148.  
  149. //              // clamp; because we limited the minimum ambient and shading light, we
  150. //              // don't have to clamp low light, just bright
  151. //                      if (temp < 0)
  152. //                              temp = 0;
  153.         jns             Lp1
  154.         subl    %eax,%eax
  155.  
  156. //              }
  157.  
  158. Lp1:
  159.  
  160. //              fv->v[4] = temp;
  161. //
  162. //      // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
  163. //      // scaled up by 1/2**31, and the scaling cancels out for x and y in the
  164. //      // projection
  165. //              fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
  166. //                              aliastransform[0][3]) * zi) + aliasxcenter;
  167. //              fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
  168. //                              aliastransform[1][3]) * zi) + aliasycenter;
  169. //              fv->v[5] = zi;
  170.         fxch    %st(1)                           // v[0] | xaccum | v[2] | v[1] | zi
  171.         fmuls   C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi
  172.         fxch    %st(3)                           // v[1] | xaccum | v[2] | yaccum | zi
  173.         fld             %st(0)                           // v[1] | v[1] | xaccum | v[2] | yaccum | zi
  174.         fmuls   C(aliastransform)+4      // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi
  175.         fxch    %st(1)                           // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi
  176.         movl    %eax,fv_v+16(%edi)
  177.         fmuls   C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum|
  178.                                                                  //  zi
  179.         fxch    %st(2)                           // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
  180.                                                                  //  zi
  181.         fadds   C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
  182.                                                                  //  zi
  183.         fxch    %st(4)                           // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
  184.                                                                  //  zi
  185.         fadds   C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
  186.                                                                  //  zi
  187.         fxch    %st(3)                           // v[2] | xaccum2 | yaccum2 | yaccum | xaccum|
  188.                                                                  //  zi
  189.         fld             %st(0)                           // v[2] | v[2] | xaccum2 | yaccum2 | yaccum |
  190.                                                                  //  xaccum | zi
  191.         fmuls   C(aliastransform)+8      // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum|
  192.                                                                  //  xaccum | zi
  193.         fxch    %st(1)                           // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum|
  194.                                                                  //  xaccum | zi
  195.         fmuls   C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 |
  196.                                                                  // yaccum | xaccum | zi
  197.         fxch    %st(5)                           // xaccum | xaccum3 | xaccum2 | yaccum2 |
  198.                                                                  // yaccum | yaccum3 | zi
  199.         faddp   %st(0),%st(2)            // xaccum3 | xaccum | yaccum2 | yaccum |
  200.                                                                  //  yaccum3 | zi
  201.         fxch    %st(3)                           // yaccum | xaccum | yaccum2 | xaccum3 |
  202.                                                                  //  yaccum3 | zi
  203.         faddp   %st(0),%st(2)            // xaccum | yaccum | xaccum3 | yaccum3 | zi
  204.         addl    $(tv_size),%esi
  205.         faddp   %st(0),%st(2)            // yaccum | x | yaccum3 | zi
  206.         faddp   %st(0),%st(2)            // x | y | zi
  207.         addl    $(stv_size),%ebp
  208.         fmul    %st(2),%st(0)            // x/z | y | zi
  209.         fxch    %st(1)                           // y | x/z | zi
  210.         fmul    %st(2),%st(0)            // y/z | x/z | zi
  211.         fxch    %st(1)                           // x/z | y/z | zi
  212.         fadds   C(aliasxcenter)          // u | y/z | zi
  213.         fxch    %st(1)                           // y/z | u | zi
  214.         fadds   C(aliasycenter)          // v | u | zi
  215.         fxch    %st(2)                           // zi | u | v
  216. // FIXME: fast float->int conversion?
  217.         fistpl  fv_v+20(%edi)            // u | v
  218.         fistpl  fv_v+0(%edi)             // v
  219.         fistpl  fv_v+4(%edi)
  220.  
  221. //      }
  222.  
  223.         addl    $(fv_size),%edi
  224.         decl    %ecx
  225.         jnz             Lloop
  226.  
  227.         popl    %esi                            // restore register variables
  228.         popl    %edi
  229.         popl    %ebp                            // restore the caller's stack frame
  230.         ret
  231.  
  232. Lsavelight:
  233.         fstp    %st(0)
  234.         jmp             Lp1
  235.  
  236. #endif  // id386
  237.  
  238.