Fix for the problem that SDL applications exited
[AROS-Contrib.git] / Games / Quake / r_aliasa.s
blobb19e97aac672389c1a1465d609bd661d429227f0
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
21 // r_aliasa.s
22 // x86 assembly-language Alias model transform and project code.
25 #include "asm_i386.h"
26 #include "quakeasm.h"
27 #include "asm_draw.h"
28 #include "d_ifacea.h"
30 #if id386
32 .data
34 Lfloat_1: .single 1.0
35 Ltemp: .long 0
36 Lcoords: .long 0, 0, 0
38 .text
40 #define fv 12+4
41 #define pstverts 12+8
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
49 // int i, temp;
50 // float lightcos, *plightnormal, zi;
51 // trivertx_t *pverts;
53 // pverts = r_apverts;
54 movl C(r_apverts),%esi
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
63 Lloop:
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]
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]
94 movl stv_t(%ebp),%eax
95 movl %eax,fv_v+12(%edi)
97 // // lighting
98 // plightnormal = r_avertexnormals[pverts->lightnormalindex];
100 fdivrs Lfloat_1 // zi | v[2] | v[1] | v[0]
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)
108 movl fv_size(%edi),%eax
109 movl stv_size(%ebp),%eax
110 movl 4(%esi),%eax
112 leal (%edx,%edx,2),%eax // index*3
114 fxch %st(3) // v[0] | v[2] | v[1] | zi
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
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
143 // temp += (int)(r_shadelight * lightcos);
144 fmuls C(r_shadelight)
145 // FIXME: fast float->int conversion?
146 fistpl Ltemp
147 addl Ltemp,%eax
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
156 // }
158 Lp1:
160 // fv->v[4] = temp;
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)
221 // }
223 addl $(fv_size),%edi
224 decl %ecx
225 jnz Lloop
227 popl %esi // restore register variables
228 popl %edi
229 popl %ebp // restore the caller's stack frame
232 Lsavelight:
233 fstp %st(0)
234 jmp Lp1
236 #endif // id386