Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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
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