Home | History | Annotate | Download | only in client
      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