r_aliasa.s 6.9 KB

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