|
|
1.1 root 1: //
2: // r_aliasa.s
3: // x86 assembly-language Alias model transform and project code.
4: //
5:
6: #include "asm_i386.h"
7: #include "quakeasm.h"
8: #include "asm_draw.h"
9: #include "d_ifacea.h"
10:
11: #if id386
12:
13: .data
14:
15: Lfloat_1: .single 1.0
16: Ltemp: .long 0
17: Lcoords: .long 0, 0, 0
18:
19: .text
20:
21: #define fv 12+4
22: #define pstverts 12+8
23:
24: .globl C(R_AliasTransformAndProjectFinalVerts)
25: C(R_AliasTransformAndProjectFinalVerts):
26: pushl %ebp // preserve caller's stack frame
27: pushl %edi
28: pushl %esi // preserve register variables
29:
30: // int i, temp;
31: // float lightcos, *plightnormal, zi;
32: // trivertx_t *pverts;
33:
34: // pverts = r_apverts;
35: movl C(r_apverts),%esi
36:
37: // for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
38: // {
39: movl pstverts(%esp),%ebp
40: movl fv(%esp),%edi
41: movl C(r_anumverts),%ecx
42: subl %edx,%edx
43:
44: Lloop:
45:
46: // // transform and project
47: // zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
48: // aliastransform[2][3]);
49: movb (%esi),%dl
50: movb %dl,Lcoords
51: fildl Lcoords // v[0]
52: movb 1(%esi),%dl
53: movb %dl,Lcoords+4
54: fildl Lcoords+4 // v[1] | v[0]
55: movb 2(%esi),%dl
56: movb %dl,Lcoords+8
57: fildl Lcoords+8 // v[2] | v[1] | v[0]
58:
59: fld %st(2) // v[0] | v[2] | v[1] | v[0]
60: fmuls C(aliastransform)+32 // accum | v[2] | v[1] | v[0]
61: fld %st(2) // v[1] | accum | v[2] | v[1] | v[0]
62: fmuls C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0]
63: fxch %st(1) // accum | accum2 | v[2] | v[1] | v[0]
64: fadds C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0]
65: fld %st(2) // v[2] | accum | accum2 | v[2] | v[1] | v[0]
66: fmuls C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] |
67: // v[0]
68: fxch %st(1) // accum | accum3 | accum2 | v[2] | v[1] | v[0]
69: faddp %st(0),%st(2) // accum3 | accum | v[2] | v[1] | v[0]
70: movb tv_lightnormalindex(%esi),%dl
71: movl stv_s(%ebp),%eax
72: movl %eax,fv_v+8(%edi)
73: faddp %st(0),%st(1) // z | v[2] | v[1] | v[0]
74:
75: movl stv_t(%ebp),%eax
76: movl %eax,fv_v+12(%edi)
77:
78: // // lighting
79: // plightnormal = r_avertexnormals[pverts->lightnormalindex];
80:
81: fdivrs Lfloat_1 // zi | v[2] | v[1] | v[0]
82:
83: // fv->v[2] = pstverts->s;
84: // fv->v[3] = pstverts->t;
85: // fv->flags = pstverts->onseam;
86: movl stv_onseam(%ebp),%eax
87: movl %eax,fv_flags(%edi)
88:
89: movl fv_size(%edi),%eax
90: movl stv_size(%ebp),%eax
91: movl 4(%esi),%eax
92:
93: leal (%edx,%edx,2),%eax // index*3
94:
95: fxch %st(3) // v[0] | v[2] | v[1] | zi
96:
97: // lightcos = DotProduct (plightnormal, r_plightvec);
98: flds C(r_avertexnormals)(,%eax,4)
99: fmuls C(r_plightvec)
100: flds C(r_avertexnormals)+4(,%eax,4)
101: fmuls C(r_plightvec)+4
102: flds C(r_avertexnormals)+8(,%eax,4)
103: fmuls C(r_plightvec)+8
104: fxch %st(1)
105: faddp %st(0),%st(2)
106: fld %st(2) // v[0] | laccum | laccum2 | v[0] | v[2] |
107: // v[1] | zi
108: fmuls C(aliastransform)+0 // xaccum | laccum | laccum2 | v[0] | v[2] |
109: // v[1] | zi
110: fxch %st(2) // laccum2 | laccum | xaccum | v[0] | v[2] |
111: // v[1] | zi
112: faddp %st(0),%st(1) // laccum | xaccum | v[0] | v[2] | v[1] | zi
113:
114: // temp = r_ambientlight;
115: // if (lightcos < 0)
116: // {
117: fsts Ltemp
118: movl C(r_ambientlight),%eax
119: movb Ltemp+3,%dl
120: testb $0x80,%dl
121: jz Lsavelight // no need to clamp if only ambient lit, because
122: // r_ambientlight is preclamped
123:
124: // temp += (int)(r_shadelight * lightcos);
125: fmuls C(r_shadelight)
126: // FIXME: fast float->int conversion?
127: fistpl Ltemp
128: addl Ltemp,%eax
129:
130: // // clamp; because we limited the minimum ambient and shading light, we
131: // // don't have to clamp low light, just bright
132: // if (temp < 0)
133: // temp = 0;
134: jns Lp1
135: subl %eax,%eax
136:
137: // }
138:
139: Lp1:
140:
141: // fv->v[4] = temp;
142: //
143: // // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
144: // // scaled up by 1/2**31, and the scaling cancels out for x and y in the
145: // // projection
146: // fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
147: // aliastransform[0][3]) * zi) + aliasxcenter;
148: // fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
149: // aliastransform[1][3]) * zi) + aliasycenter;
150: // fv->v[5] = zi;
151: fxch %st(1) // v[0] | xaccum | v[2] | v[1] | zi
152: fmuls C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi
153: fxch %st(3) // v[1] | xaccum | v[2] | yaccum | zi
154: fld %st(0) // v[1] | v[1] | xaccum | v[2] | yaccum | zi
155: fmuls C(aliastransform)+4 // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi
156: fxch %st(1) // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi
157: movl %eax,fv_v+16(%edi)
158: fmuls C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum|
159: // zi
160: fxch %st(2) // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
161: // zi
162: fadds C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
163: // zi
164: fxch %st(4) // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
165: // zi
166: fadds C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
167: // zi
168: fxch %st(3) // v[2] | xaccum2 | yaccum2 | yaccum | xaccum|
169: // zi
170: fld %st(0) // v[2] | v[2] | xaccum2 | yaccum2 | yaccum |
171: // xaccum | zi
172: fmuls C(aliastransform)+8 // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum|
173: // xaccum | zi
174: fxch %st(1) // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum|
175: // xaccum | zi
176: fmuls C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 |
177: // yaccum | xaccum | zi
178: fxch %st(5) // xaccum | xaccum3 | xaccum2 | yaccum2 |
179: // yaccum | yaccum3 | zi
180: faddp %st(0),%st(2) // xaccum3 | xaccum | yaccum2 | yaccum |
181: // yaccum3 | zi
182: fxch %st(3) // yaccum | xaccum | yaccum2 | xaccum3 |
183: // yaccum3 | zi
184: faddp %st(0),%st(2) // xaccum | yaccum | xaccum3 | yaccum3 | zi
1.1.1.2 ! root 185: addl $(tv_size),%esi
1.1 root 186: faddp %st(0),%st(2) // yaccum | x | yaccum3 | zi
187: faddp %st(0),%st(2) // x | y | zi
1.1.1.2 ! root 188: addl $(stv_size),%ebp
! 189: fmul %st(2),%st(0) // x/z | y | zi
1.1 root 190: fxch %st(1) // y | x/z | zi
1.1.1.2 ! root 191: fmul %st(2),%st(0) // y/z | x/z | zi
1.1 root 192: fxch %st(1) // x/z | y/z | zi
193: fadds C(aliasxcenter) // u | y/z | zi
194: fxch %st(1) // y/z | u | zi
195: fadds C(aliasycenter) // v | u | zi
196: fxch %st(2) // zi | u | v
197: // FIXME: fast float->int conversion?
198: fistpl fv_v+20(%edi) // u | v
199: fistpl fv_v+0(%edi) // v
200: fistpl fv_v+4(%edi)
201:
202: // }
203:
1.1.1.2 ! root 204: addl $(fv_size),%edi
1.1 root 205: decl %ecx
206: jnz Lloop
207:
208: popl %esi // restore register variables
209: popl %edi
210: popl %ebp // restore the caller's stack frame
211: ret
212:
213: Lsavelight:
214: fstp %st(0)
215: jmp Lp1
216:
217: #endif // id386
218:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.