aboutsummaryrefslogtreecommitdiffstats
path: root/QW/client/r_aliasa.s
diff options
context:
space:
mode:
Diffstat (limited to 'QW/client/r_aliasa.s')
-rw-r--r--QW/client/r_aliasa.s237
1 files changed, 237 insertions, 0 deletions
diff --git a/QW/client/r_aliasa.s b/QW/client/r_aliasa.s
new file mode 100644
index 0000000..b19e97a
--- /dev/null
+++ b/QW/client/r_aliasa.s
@@ -0,0 +1,237 @@
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+//
+// r_aliasa.s
+// x86 assembly-language Alias model transform and project code.
+//
+
+#include "asm_i386.h"
+#include "quakeasm.h"
+#include "asm_draw.h"
+#include "d_ifacea.h"
+
+#if id386
+
+ .data
+
+Lfloat_1: .single 1.0
+Ltemp: .long 0
+Lcoords: .long 0, 0, 0
+
+ .text
+
+#define fv 12+4
+#define pstverts 12+8
+
+.globl C(R_AliasTransformAndProjectFinalVerts)
+C(R_AliasTransformAndProjectFinalVerts):
+ pushl %ebp // preserve caller's stack frame
+ pushl %edi
+ pushl %esi // preserve register variables
+
+// int i, temp;
+// float lightcos, *plightnormal, zi;
+// trivertx_t *pverts;
+
+// pverts = r_apverts;
+ movl C(r_apverts),%esi
+
+// for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
+// {
+ movl pstverts(%esp),%ebp
+ movl fv(%esp),%edi
+ movl C(r_anumverts),%ecx
+ subl %edx,%edx
+
+Lloop:
+
+// // transform and project
+// zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
+// aliastransform[2][3]);
+ movb (%esi),%dl
+ movb %dl,Lcoords
+ fildl Lcoords // v[0]
+ movb 1(%esi),%dl
+ movb %dl,Lcoords+4
+ fildl Lcoords+4 // v[1] | v[0]
+ movb 2(%esi),%dl
+ movb %dl,Lcoords+8
+ fildl Lcoords+8 // v[2] | v[1] | v[0]
+
+ fld %st(2) // v[0] | v[2] | v[1] | v[0]
+ fmuls C(aliastransform)+32 // accum | v[2] | v[1] | v[0]
+ fld %st(2) // v[1] | accum | v[2] | v[1] | v[0]
+ fmuls C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0]
+ fxch %st(1) // accum | accum2 | v[2] | v[1] | v[0]
+ fadds C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0]
+ fld %st(2) // v[2] | accum | accum2 | v[2] | v[1] | v[0]
+ fmuls C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] |
+ // v[0]
+ fxch %st(1) // accum | accum3 | accum2 | v[2] | v[1] | v[0]
+ faddp %st(0),%st(2) // accum3 | accum | v[2] | v[1] | v[0]
+ movb tv_lightnormalindex(%esi),%dl
+ movl stv_s(%ebp),%eax
+ movl %eax,fv_v+8(%edi)
+ faddp %st(0),%st(1) // z | v[2] | v[1] | v[0]
+
+ movl stv_t(%ebp),%eax
+ movl %eax,fv_v+12(%edi)
+
+// // lighting
+// plightnormal = r_avertexnormals[pverts->lightnormalindex];
+
+ fdivrs Lfloat_1 // zi | v[2] | v[1] | v[0]
+
+// fv->v[2] = pstverts->s;
+// fv->v[3] = pstverts->t;
+// fv->flags = pstverts->onseam;
+ movl stv_onseam(%ebp),%eax
+ movl %eax,fv_flags(%edi)
+
+ movl fv_size(%edi),%eax
+ movl stv_size(%ebp),%eax
+ movl 4(%esi),%eax
+
+ leal (%edx,%edx,2),%eax // index*3
+
+ fxch %st(3) // v[0] | v[2] | v[1] | zi
+
+// lightcos = DotProduct (plightnormal, r_plightvec);
+ flds C(r_avertexnormals)(,%eax,4)
+ fmuls C(r_plightvec)
+ flds C(r_avertexnormals)+4(,%eax,4)
+ fmuls C(r_plightvec)+4
+ flds C(r_avertexnormals)+8(,%eax,4)
+ fmuls C(r_plightvec)+8
+ fxch %st(1)
+ faddp %st(0),%st(2)
+ fld %st(2) // v[0] | laccum | laccum2 | v[0] | v[2] |
+ // v[1] | zi
+ fmuls C(aliastransform)+0 // xaccum | laccum | laccum2 | v[0] | v[2] |
+ // v[1] | zi
+ fxch %st(2) // laccum2 | laccum | xaccum | v[0] | v[2] |
+ // v[1] | zi
+ faddp %st(0),%st(1) // laccum | xaccum | v[0] | v[2] | v[1] | zi
+
+// temp = r_ambientlight;
+// if (lightcos < 0)
+// {
+ fsts Ltemp
+ movl C(r_ambientlight),%eax
+ movb Ltemp+3,%dl
+ testb $0x80,%dl
+ jz Lsavelight // no need to clamp if only ambient lit, because
+ // r_ambientlight is preclamped
+
+// temp += (int)(r_shadelight * lightcos);
+ fmuls C(r_shadelight)
+// FIXME: fast float->int conversion?
+ fistpl Ltemp
+ addl Ltemp,%eax
+
+// // clamp; because we limited the minimum ambient and shading light, we
+// // don't have to clamp low light, just bright
+// if (temp < 0)
+// temp = 0;
+ jns Lp1
+ subl %eax,%eax
+
+// }
+
+Lp1:
+
+// fv->v[4] = temp;
+//
+// // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
+// // scaled up by 1/2**31, and the scaling cancels out for x and y in the
+// // projection
+// fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
+// aliastransform[0][3]) * zi) + aliasxcenter;
+// fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
+// aliastransform[1][3]) * zi) + aliasycenter;
+// fv->v[5] = zi;
+ fxch %st(1) // v[0] | xaccum | v[2] | v[1] | zi
+ fmuls C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi
+ fxch %st(3) // v[1] | xaccum | v[2] | yaccum | zi
+ fld %st(0) // v[1] | v[1] | xaccum | v[2] | yaccum | zi
+ fmuls C(aliastransform)+4 // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi
+ fxch %st(1) // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi
+ movl %eax,fv_v+16(%edi)
+ fmuls C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum|
+ // zi
+ fxch %st(2) // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
+ // zi
+ fadds C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
+ // zi
+ fxch %st(4) // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
+ // zi
+ fadds C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
+ // zi
+ fxch %st(3) // v[2] | xaccum2 | yaccum2 | yaccum | xaccum|
+ // zi
+ fld %st(0) // v[2] | v[2] | xaccum2 | yaccum2 | yaccum |
+ // xaccum | zi
+ fmuls C(aliastransform)+8 // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum|
+ // xaccum | zi
+ fxch %st(1) // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum|
+ // xaccum | zi
+ fmuls C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 |
+ // yaccum | xaccum | zi
+ fxch %st(5) // xaccum | xaccum3 | xaccum2 | yaccum2 |
+ // yaccum | yaccum3 | zi
+ faddp %st(0),%st(2) // xaccum3 | xaccum | yaccum2 | yaccum |
+ // yaccum3 | zi
+ fxch %st(3) // yaccum | xaccum | yaccum2 | xaccum3 |
+ // yaccum3 | zi
+ faddp %st(0),%st(2) // xaccum | yaccum | xaccum3 | yaccum3 | zi
+ addl $(tv_size),%esi
+ faddp %st(0),%st(2) // yaccum | x | yaccum3 | zi
+ faddp %st(0),%st(2) // x | y | zi
+ addl $(stv_size),%ebp
+ fmul %st(2),%st(0) // x/z | y | zi
+ fxch %st(1) // y | x/z | zi
+ fmul %st(2),%st(0) // y/z | x/z | zi
+ fxch %st(1) // x/z | y/z | zi
+ fadds C(aliasxcenter) // u | y/z | zi
+ fxch %st(1) // y/z | u | zi
+ fadds C(aliasycenter) // v | u | zi
+ fxch %st(2) // zi | u | v
+// FIXME: fast float->int conversion?
+ fistpl fv_v+20(%edi) // u | v
+ fistpl fv_v+0(%edi) // v
+ fistpl fv_v+4(%edi)
+
+// }
+
+ addl $(fv_size),%edi
+ decl %ecx
+ jnz Lloop
+
+ popl %esi // restore register variables
+ popl %edi
+ popl %ebp // restore the caller's stack frame
+ ret
+
+Lsavelight:
+ fstp %st(0)
+ jmp Lp1
+
+#endif // id386
+