Go to most recent revision | 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_drawa.s |
||
22 | // x86 assembly-language edge clipping and emission 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 | // !!! if these are changed, they must be changed in r_draw.c too !!! |
||
33 | #define FULLY_CLIPPED_CACHED 0x80000000 |
||
34 | #define FRAMECOUNT_MASK 0x7FFFFFFF |
||
35 | |||
36 | .data |
||
37 | |||
38 | Ld0: .single 0.0 |
||
39 | Ld1: .single 0.0 |
||
40 | Lstack: .long 0 |
||
41 | Lfp_near_clip: .single NEAR_CLIP |
||
42 | Lceilv0: .long 0 |
||
43 | Lv: .long 0 |
||
44 | Lu0: .long 0 |
||
45 | Lv0: .long 0 |
||
46 | Lzi0: .long 0 |
||
47 | |||
48 | .text |
||
49 | |||
50 | //---------------------------------------------------------------------- |
||
51 | // edge clipping code |
||
52 | //---------------------------------------------------------------------- |
||
53 | |||
54 | #define pv0 4+12 |
||
55 | #define pv1 8+12 |
||
56 | #define clip 12+12 |
||
57 | |||
58 | .align 4 |
||
59 | .globl C(R_ClipEdge) |
||
60 | C(R_ClipEdge): |
||
61 | pushl %esi // preserve register variables |
||
62 | pushl %edi |
||
63 | pushl %ebx |
||
64 | movl %esp,Lstack // for clearing the stack later |
||
65 | |||
66 | // float d0, d1, f; |
||
67 | // mvertex_t clipvert; |
||
68 | |||
69 | movl clip(%esp),%ebx |
||
70 | movl pv0(%esp),%esi |
||
71 | movl pv1(%esp),%edx |
||
72 | |||
73 | // if (clip) |
||
74 | // { |
||
75 | testl %ebx,%ebx |
||
76 | jz Lemit |
||
77 | |||
78 | // do |
||
79 | // { |
||
80 | |||
81 | Lcliploop: |
||
82 | |||
83 | // d0 = DotProduct (pv0->position, clip->normal) - clip->dist; |
||
84 | // d1 = DotProduct (pv1->position, clip->normal) - clip->dist; |
||
85 | flds mv_position+0(%esi) |
||
86 | fmuls cp_normal+0(%ebx) |
||
87 | flds mv_position+4(%esi) |
||
88 | fmuls cp_normal+4(%ebx) |
||
89 | flds mv_position+8(%esi) |
||
90 | fmuls cp_normal+8(%ebx) |
||
91 | fxch %st(1) |
||
92 | faddp %st(0),%st(2) // d0mul2 | d0add0 |
||
93 | |||
94 | flds mv_position+0(%edx) |
||
95 | fmuls cp_normal+0(%ebx) |
||
96 | flds mv_position+4(%edx) |
||
97 | fmuls cp_normal+4(%ebx) |
||
98 | flds mv_position+8(%edx) |
||
99 | fmuls cp_normal+8(%ebx) |
||
100 | fxch %st(1) |
||
101 | faddp %st(0),%st(2) // d1mul2 | d1add0 | d0mul2 | d0add0 |
||
102 | fxch %st(3) // d0add0 | d1add0 | d0mul2 | d1mul2 |
||
103 | |||
104 | faddp %st(0),%st(2) // d1add0 | dot0 | d1mul2 |
||
105 | faddp %st(0),%st(2) // dot0 | dot1 |
||
106 | |||
107 | fsubs cp_dist(%ebx) // d0 | dot1 |
||
108 | fxch %st(1) // dot1 | d0 |
||
109 | fsubs cp_dist(%ebx) // d1 | d0 |
||
110 | fxch %st(1) |
||
111 | fstps Ld0 |
||
112 | fstps Ld1 |
||
113 | |||
114 | // if (d0 >= 0) |
||
115 | // { |
||
116 | movl Ld0,%eax |
||
117 | movl Ld1,%ecx |
||
118 | orl %eax,%ecx |
||
119 | js Lp2 |
||
120 | |||
121 | // both points are unclipped |
||
122 | |||
123 | Lcontinue: |
||
124 | |||
125 | // |
||
126 | // R_ClipEdge (&clipvert, pv1, clip->next); |
||
127 | // return; |
||
128 | // } |
||
129 | // } while ((clip = clip->next) != NULL); |
||
130 | movl cp_next(%ebx),%ebx |
||
131 | testl %ebx,%ebx |
||
132 | jnz Lcliploop |
||
133 | |||
134 | // } |
||
135 | |||
136 | //// add the edge |
||
137 | // R_EmitEdge (pv0, pv1); |
||
138 | Lemit: |
||
139 | |||
140 | // |
||
141 | // set integer rounding to ceil mode, set to single precision |
||
142 | // |
||
143 | // FIXME: do away with by manually extracting integers from floats? |
||
144 | // FIXME: set less often |
||
145 | fldcw ceil_cw |
||
146 | |||
147 | // edge_t *edge, *pcheck; |
||
148 | // int u_check; |
||
149 | // float u, u_step; |
||
150 | // vec3_t local, transformed; |
||
151 | // float *world; |
||
152 | // int v, v2, ceilv0; |
||
153 | // float scale, lzi0, u0, v0; |
||
154 | // int side; |
||
155 | |||
156 | // if (r_lastvertvalid) |
||
157 | // { |
||
158 | cmpl $0,C(r_lastvertvalid) |
||
159 | jz LCalcFirst |
||
160 | |||
161 | // u0 = r_u1; |
||
162 | // v0 = r_v1; |
||
163 | // lzi0 = r_lzi1; |
||
164 | // ceilv0 = r_ceilv1; |
||
165 | movl C(r_lzi1),%eax |
||
166 | movl C(r_u1),%ecx |
||
167 | movl %eax,Lzi0 |
||
168 | movl %ecx,Lu0 |
||
169 | movl C(r_v1),%ecx |
||
170 | movl C(r_ceilv1),%eax |
||
171 | movl %ecx,Lv0 |
||
172 | movl %eax,Lceilv0 |
||
173 | jmp LCalcSecond |
||
174 | |||
175 | // } |
||
176 | |||
177 | LCalcFirst: |
||
178 | |||
179 | // else |
||
180 | // { |
||
181 | // world = &pv0->position[0]; |
||
182 | |||
183 | call LTransformAndProject // v0 | lzi0 | u0 |
||
184 | |||
185 | fsts Lv0 |
||
186 | fxch %st(2) // u0 | lzi0 | v0 |
||
187 | fstps Lu0 // lzi0 | v0 |
||
188 | fstps Lzi0 // v0 |
||
189 | |||
190 | // ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0); |
||
191 | fistpl Lceilv0 |
||
192 | |||
193 | // } |
||
194 | |||
195 | LCalcSecond: |
||
196 | |||
197 | // world = &pv1->position[0]; |
||
198 | movl %edx,%esi |
||
199 | |||
200 | call LTransformAndProject // v1 | lzi1 | u1 |
||
201 | |||
202 | flds Lu0 // u0 | v1 | lzi1 | u1 |
||
203 | fxch %st(3) // u1 | v1 | lzi1 | u0 |
||
204 | flds Lzi0 // lzi0 | u1 | v1 | lzi1 | u0 |
||
205 | fxch %st(3) // lzi1 | u1 | v1 | lzi0 | u0 |
||
206 | flds Lv0 // v0 | lzi1 | u1 | v1 | lzi0 | u0 |
||
207 | fxch %st(3) // v1 | lzi1 | u1 | v0 | lzi0 | u0 |
||
208 | |||
209 | // r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1); |
||
210 | fistl C(r_ceilv1) |
||
211 | |||
212 | fldcw single_cw // put back normal floating-point state |
||
213 | |||
214 | fsts C(r_v1) |
||
215 | fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0 |
||
216 | |||
217 | // if (r_lzi1 > lzi0) |
||
218 | // lzi0 = r_lzi1; |
||
219 | fcom %st(1) |
||
220 | fnstsw %ax |
||
221 | testb $1,%ah |
||
222 | jz LP0 |
||
223 | fstp %st(0) |
||
224 | fld %st(0) |
||
225 | LP0: |
||
226 | |||
227 | fxch %st(1) // lzi1 | lzi0 | u1 | v0 | v1 | u0 |
||
228 | fstps C(r_lzi1) // lzi0 | u1 | v0 | v1 | u0 |
||
229 | fxch %st(1) |
||
230 | fsts C(r_u1) |
||
231 | fxch %st(1) |
||
232 | |||
233 | // if (lzi0 > r_nearzi) // for mipmap finding |
||
234 | // r_nearzi = lzi0; |
||
235 | fcoms C(r_nearzi) |
||
236 | fnstsw %ax |
||
237 | testb $0x45,%ah |
||
238 | jnz LP1 |
||
239 | fsts C(r_nearzi) |
||
240 | LP1: |
||
241 | |||
242 | // // for right edges, all we want is the effect on 1/z |
||
243 | // if (r_nearzionly) |
||
244 | // return; |
||
245 | movl C(r_nearzionly),%eax |
||
246 | testl %eax,%eax |
||
247 | jz LP2 |
||
248 | LPop5AndDone: |
||
249 | movl C(cacheoffset),%eax |
||
250 | movl C(r_framecount),%edx |
||
251 | cmpl $0x7FFFFFFF,%eax |
||
252 | jz LDoPop |
||
253 | andl $(FRAMECOUNT_MASK),%edx |
||
254 | orl $(FULLY_CLIPPED_CACHED),%edx |
||
255 | movl %edx,C(cacheoffset) |
||
256 | |||
257 | LDoPop: |
||
258 | fstp %st(0) // u1 | v0 | v1 | u0 |
||
259 | fstp %st(0) // v0 | v1 | u0 |
||
260 | fstp %st(0) // v1 | u0 |
||
261 | fstp %st(0) // u0 |
||
262 | fstp %st(0) |
||
263 | jmp Ldone |
||
264 | |||
265 | LP2: |
||
266 | |||
267 | // // create the edge |
||
268 | // if (ceilv0 == r_ceilv1) |
||
269 | // return; // horizontal edge |
||
270 | movl Lceilv0,%ebx |
||
271 | movl C(edge_p),%edi |
||
272 | movl C(r_ceilv1),%ecx |
||
273 | movl %edi,%edx |
||
274 | movl C(r_pedge),%esi |
||
275 | addl $(et_size),%edx |
||
276 | cmpl %ecx,%ebx |
||
277 | jz LPop5AndDone |
||
278 | |||
279 | movl C(r_pedge),%eax |
||
280 | movl %eax,et_owner(%edi) |
||
281 | |||
282 | // side = ceilv0 > r_ceilv1; |
||
283 | // |
||
284 | // edge->nearzi = lzi0; |
||
285 | fstps et_nearzi(%edi) // u1 | v0 | v1 | u0 |
||
286 | |||
287 | // if (side == 1) |
||
288 | // { |
||
289 | jc LSide0 |
||
290 | |||
291 | LSide1: |
||
292 | |||
293 | // // leading edge (go from p2 to p1) |
||
294 | |||
295 | // u_step = ((u0 - r_u1) / (v0 - r_v1)); |
||
296 | fsubrp %st(0),%st(3) // v0 | v1 | u0-u1 |
||
297 | fsub %st(1),%st(0) // v0-v1 | v1 | u0-u1 |
||
298 | fdivrp %st(0),%st(2) // v1 | ustep |
||
299 | |||
300 | // r_emitted = 1; |
||
301 | movl $1,C(r_emitted) |
||
302 | |||
303 | // edge = edge_p++; |
||
304 | movl %edx,C(edge_p) |
||
305 | |||
306 | // pretouch next edge |
||
307 | movl (%edx),%eax |
||
308 | |||
309 | // v2 = ceilv0 - 1; |
||
310 | // v = r_ceilv1; |
||
311 | movl %ecx,%eax |
||
312 | leal -1(%ebx),%ecx |
||
313 | movl %eax,%ebx |
||
314 | |||
315 | // edge->surfs[0] = 0; |
||
316 | // edge->surfs[1] = surface_p - surfaces; |
||
317 | movl C(surface_p),%eax |
||
318 | movl C(surfaces),%esi |
||
319 | subl %edx,%edx |
||
320 | subl %esi,%eax |
||
321 | shrl $(SURF_T_SHIFT),%eax |
||
322 | movl %edx,et_surfs(%edi) |
||
323 | movl %eax,et_surfs+2(%edi) |
||
324 | |||
325 | subl %esi,%esi |
||
326 | |||
327 | // u = r_u1 + ((float)v - r_v1) * u_step; |
||
328 | movl %ebx,Lv |
||
329 | fildl Lv // v | v1 | ustep |
||
330 | fsubp %st(0),%st(1) // v-v1 | ustep |
||
331 | fmul %st(1),%st(0) // (v-v1)*ustep | ustep |
||
332 | fadds C(r_u1) // u | ustep |
||
333 | |||
334 | jmp LSideDone |
||
335 | |||
336 | // } |
||
337 | |||
338 | LSide0: |
||
339 | |||
340 | // else |
||
341 | // { |
||
342 | // // trailing edge (go from p1 to p2) |
||
343 | |||
344 | // u_step = ((r_u1 - u0) / (r_v1 - v0)); |
||
345 | fsub %st(3),%st(0) // u1-u0 | v0 | v1 | u0 |
||
346 | fxch %st(2) // v1 | v0 | u1-u0 | u0 |
||
347 | fsub %st(1),%st(0) // v1-v0 | v0 | u1-u0 | u0 |
||
348 | fdivrp %st(0),%st(2) // v0 | ustep | u0 |
||
349 | |||
350 | // r_emitted = 1; |
||
351 | movl $1,C(r_emitted) |
||
352 | |||
353 | // edge = edge_p++; |
||
354 | movl %edx,C(edge_p) |
||
355 | |||
356 | // pretouch next edge |
||
357 | movl (%edx),%eax |
||
358 | |||
359 | // v = ceilv0; |
||
360 | // v2 = r_ceilv1 - 1; |
||
361 | decl %ecx |
||
362 | |||
363 | // edge->surfs[0] = surface_p - surfaces; |
||
364 | // edge->surfs[1] = 0; |
||
365 | movl C(surface_p),%eax |
||
366 | movl C(surfaces),%esi |
||
367 | subl %edx,%edx |
||
368 | subl %esi,%eax |
||
369 | shrl $(SURF_T_SHIFT),%eax |
||
370 | movl %edx,et_surfs+2(%edi) |
||
371 | movl %eax,et_surfs(%edi) |
||
372 | |||
373 | movl $1,%esi |
||
374 | |||
375 | // u = u0 + ((float)v - v0) * u_step; |
||
376 | movl %ebx,Lv |
||
377 | fildl Lv // v | v0 | ustep | u0 |
||
378 | fsubp %st(0),%st(1) // v-v0 | ustep | u0 |
||
379 | fmul %st(1),%st(0) // (v-v0)*ustep | ustep | u0 |
||
380 | faddp %st(0),%st(2) // ustep | u |
||
381 | fxch %st(1) // u | ustep |
||
382 | |||
383 | // } |
||
384 | |||
385 | LSideDone: |
||
386 | |||
387 | // edge->u_step = u_step*0x100000; |
||
388 | // edge->u = u*0x100000 + 0xFFFFF; |
||
389 | |||
390 | fmuls fp_1m // u*0x100000 | ustep |
||
391 | fxch %st(1) // ustep | u*0x100000 |
||
392 | fmuls fp_1m // ustep*0x100000 | u*0x100000 |
||
393 | fxch %st(1) // u*0x100000 | ustep*0x100000 |
||
394 | fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000 |
||
395 | fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF |
||
396 | fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF |
||
397 | fistpl et_u(%edi) |
||
398 | |||
399 | // // we need to do this to avoid stepping off the edges if a very nearly |
||
400 | // // horizontal edge is less than epsilon above a scan, and numeric error |
||
401 | // // causes it to incorrectly extend to the scan, and the extension of the |
||
402 | // // line goes off the edge of the screen |
||
403 | // // FIXME: is this actually needed? |
||
404 | // if (edge->u < r_refdef.vrect_x_adj_shift20) |
||
405 | // edge->u = r_refdef.vrect_x_adj_shift20; |
||
406 | // if (edge->u > r_refdef.vrectright_adj_shift20) |
||
407 | // edge->u = r_refdef.vrectright_adj_shift20; |
||
408 | movl et_u(%edi),%eax |
||
409 | movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx |
||
410 | cmpl %edx,%eax |
||
411 | jl LP4 |
||
412 | movl C(r_refdef)+rd_vrectright_adj_shift20,%edx |
||
413 | cmpl %edx,%eax |
||
414 | jng LP5 |
||
415 | LP4: |
||
416 | movl %edx,et_u(%edi) |
||
417 | movl %edx,%eax |
||
418 | LP5: |
||
419 | |||
420 | // // sort the edge in normally |
||
421 | // u_check = edge->u; |
||
422 | // |
||
423 | // if (edge->surfs[0]) |
||
424 | // u_check++; // sort trailers after leaders |
||
425 | addl %esi,%eax |
||
426 | |||
427 | // if (!newedges[v] || newedges[v]->u >= u_check) |
||
428 | // { |
||
429 | movl C(newedges)(,%ebx,4),%esi |
||
430 | testl %esi,%esi |
||
431 | jz LDoFirst |
||
432 | cmpl %eax,et_u(%esi) |
||
433 | jl LNotFirst |
||
434 | LDoFirst: |
||
435 | |||
436 | // edge->next = newedges[v]; |
||
437 | // newedges[v] = edge; |
||
438 | movl %esi,et_next(%edi) |
||
439 | movl %edi,C(newedges)(,%ebx,4) |
||
440 | |||
441 | jmp LSetRemove |
||
442 | |||
443 | // } |
||
444 | |||
445 | LNotFirst: |
||
446 | |||
447 | // else |
||
448 | // { |
||
449 | // pcheck = newedges[v]; |
||
450 | // |
||
451 | // while (pcheck->next && pcheck->next->u < u_check) |
||
452 | // pcheck = pcheck->next; |
||
453 | LFindInsertLoop: |
||
454 | movl %esi,%edx |
||
455 | movl et_next(%esi),%esi |
||
456 | testl %esi,%esi |
||
457 | jz LInsertFound |
||
458 | cmpl %eax,et_u(%esi) |
||
459 | jl LFindInsertLoop |
||
460 | |||
461 | LInsertFound: |
||
462 | |||
463 | // edge->next = pcheck->next; |
||
464 | // pcheck->next = edge; |
||
465 | movl %esi,et_next(%edi) |
||
466 | movl %edi,et_next(%edx) |
||
467 | |||
468 | // } |
||
469 | |||
470 | LSetRemove: |
||
471 | |||
472 | // edge->nextremove = removeedges[v2]; |
||
473 | // removeedges[v2] = edge; |
||
474 | movl C(removeedges)(,%ecx,4),%eax |
||
475 | movl %edi,C(removeedges)(,%ecx,4) |
||
476 | movl %eax,et_nextremove(%edi) |
||
477 | |||
478 | Ldone: |
||
479 | movl Lstack,%esp // clear temporary variables from stack |
||
480 | |||
481 | popl %ebx // restore register variables |
||
482 | popl %edi |
||
483 | popl %esi |
||
484 | ret |
||
485 | |||
486 | // at least one point is clipped |
||
487 | |||
488 | Lp2: |
||
489 | testl %eax,%eax |
||
490 | jns Lp1 |
||
491 | |||
492 | // else |
||
493 | // { |
||
494 | // // point 0 is clipped |
||
495 | |||
496 | // if (d1 < 0) |
||
497 | // { |
||
498 | movl Ld1,%eax |
||
499 | testl %eax,%eax |
||
500 | jns Lp3 |
||
501 | |||
502 | // // both points are clipped |
||
503 | // // we do cache fully clipped edges |
||
504 | // if (!leftclipped) |
||
505 | movl C(r_leftclipped),%eax |
||
506 | movl C(r_pedge),%ecx |
||
507 | testl %eax,%eax |
||
508 | jnz Ldone |
||
509 | |||
510 | // r_pedge->framecount = r_framecount; |
||
511 | movl C(r_framecount),%eax |
||
512 | andl $(FRAMECOUNT_MASK),%eax |
||
513 | orl $(FULLY_CLIPPED_CACHED),%eax |
||
514 | movl %eax,C(cacheoffset) |
||
515 | |||
516 | // return; |
||
517 | jmp Ldone |
||
518 | |||
519 | // } |
||
520 | |||
521 | Lp1: |
||
522 | |||
523 | // // point 0 is unclipped |
||
524 | // if (d1 >= 0) |
||
525 | // { |
||
526 | // // both points are unclipped |
||
527 | // continue; |
||
528 | |||
529 | // // only point 1 is clipped |
||
530 | |||
531 | // f = d0 / (d0 - d1); |
||
532 | flds Ld0 |
||
533 | flds Ld1 |
||
534 | fsubr %st(1),%st(0) |
||
535 | |||
536 | // // we don't cache partially clipped edges |
||
537 | movl $0x7FFFFFFF,C(cacheoffset) |
||
538 | |||
539 | fdivrp %st(0),%st(1) |
||
540 | |||
541 | subl $(mv_size),%esp // allocate space for clipvert |
||
542 | |||
543 | // clipvert.position[0] = pv0->position[0] + |
||
544 | // f * (pv1->position[0] - pv0->position[0]); |
||
545 | // clipvert.position[1] = pv0->position[1] + |
||
546 | // f * (pv1->position[1] - pv0->position[1]); |
||
547 | // clipvert.position[2] = pv0->position[2] + |
||
548 | // f * (pv1->position[2] - pv0->position[2]); |
||
549 | flds mv_position+8(%edx) |
||
550 | fsubs mv_position+8(%esi) |
||
551 | flds mv_position+4(%edx) |
||
552 | fsubs mv_position+4(%esi) |
||
553 | flds mv_position+0(%edx) |
||
554 | fsubs mv_position+0(%esi) // 0 | 1 | 2 |
||
555 | |||
556 | // replace pv1 with the clip point |
||
557 | movl %esp,%edx |
||
558 | movl cp_leftedge(%ebx),%eax |
||
559 | testb %al,%al |
||
560 | |||
561 | fmul %st(3),%st(0) |
||
562 | fxch %st(1) // 1 | 0 | 2 |
||
563 | fmul %st(3),%st(0) |
||
564 | fxch %st(2) // 2 | 0 | 1 |
||
565 | fmulp %st(0),%st(3) // 0 | 1 | 2 |
||
566 | fadds mv_position+0(%esi) |
||
567 | fxch %st(1) // 1 | 0 | 2 |
||
568 | fadds mv_position+4(%esi) |
||
569 | fxch %st(2) // 2 | 0 | 1 |
||
570 | fadds mv_position+8(%esi) |
||
571 | fxch %st(1) // 0 | 2 | 1 |
||
572 | fstps mv_position+0(%esp) // 2 | 1 |
||
573 | fstps mv_position+8(%esp) // 1 |
||
574 | fstps mv_position+4(%esp) |
||
575 | |||
576 | // if (clip->leftedge) |
||
577 | // { |
||
578 | jz Ltestright |
||
579 | |||
580 | // r_leftclipped = true; |
||
581 | // r_leftexit = clipvert; |
||
582 | movl $1,C(r_leftclipped) |
||
583 | movl mv_position+0(%esp),%eax |
||
584 | movl %eax,C(r_leftexit)+mv_position+0 |
||
585 | movl mv_position+4(%esp),%eax |
||
586 | movl %eax,C(r_leftexit)+mv_position+4 |
||
587 | movl mv_position+8(%esp),%eax |
||
588 | movl %eax,C(r_leftexit)+mv_position+8 |
||
589 | |||
590 | jmp Lcontinue |
||
591 | |||
592 | // } |
||
593 | |||
594 | Ltestright: |
||
595 | // else if (clip->rightedge) |
||
596 | // { |
||
597 | testb %ah,%ah |
||
598 | jz Lcontinue |
||
599 | |||
600 | // r_rightclipped = true; |
||
601 | // r_rightexit = clipvert; |
||
602 | movl $1,C(r_rightclipped) |
||
603 | movl mv_position+0(%esp),%eax |
||
604 | movl %eax,C(r_rightexit)+mv_position+0 |
||
605 | movl mv_position+4(%esp),%eax |
||
606 | movl %eax,C(r_rightexit)+mv_position+4 |
||
607 | movl mv_position+8(%esp),%eax |
||
608 | movl %eax,C(r_rightexit)+mv_position+8 |
||
609 | |||
610 | // } |
||
611 | // |
||
612 | // R_ClipEdge (pv0, &clipvert, clip->next); |
||
613 | // return; |
||
614 | // } |
||
615 | jmp Lcontinue |
||
616 | |||
617 | // } |
||
618 | |||
619 | Lp3: |
||
620 | |||
621 | // // only point 0 is clipped |
||
622 | // r_lastvertvalid = false; |
||
623 | |||
624 | movl $0,C(r_lastvertvalid) |
||
625 | |||
626 | // f = d0 / (d0 - d1); |
||
627 | flds Ld0 |
||
628 | flds Ld1 |
||
629 | fsubr %st(1),%st(0) |
||
630 | |||
631 | // // we don't cache partially clipped edges |
||
632 | movl $0x7FFFFFFF,C(cacheoffset) |
||
633 | |||
634 | fdivrp %st(0),%st(1) |
||
635 | |||
636 | subl $(mv_size),%esp // allocate space for clipvert |
||
637 | |||
638 | // clipvert.position[0] = pv0->position[0] + |
||
639 | // f * (pv1->position[0] - pv0->position[0]); |
||
640 | // clipvert.position[1] = pv0->position[1] + |
||
641 | // f * (pv1->position[1] - pv0->position[1]); |
||
642 | // clipvert.position[2] = pv0->position[2] + |
||
643 | // f * (pv1->position[2] - pv0->position[2]); |
||
644 | flds mv_position+8(%edx) |
||
645 | fsubs mv_position+8(%esi) |
||
646 | flds mv_position+4(%edx) |
||
647 | fsubs mv_position+4(%esi) |
||
648 | flds mv_position+0(%edx) |
||
649 | fsubs mv_position+0(%esi) // 0 | 1 | 2 |
||
650 | |||
651 | movl cp_leftedge(%ebx),%eax |
||
652 | testb %al,%al |
||
653 | |||
654 | fmul %st(3),%st(0) |
||
655 | fxch %st(1) // 1 | 0 | 2 |
||
656 | fmul %st(3),%st(0) |
||
657 | fxch %st(2) // 2 | 0 | 1 |
||
658 | fmulp %st(0),%st(3) // 0 | 1 | 2 |
||
659 | fadds mv_position+0(%esi) |
||
660 | fxch %st(1) // 1 | 0 | 2 |
||
661 | fadds mv_position+4(%esi) |
||
662 | fxch %st(2) // 2 | 0 | 1 |
||
663 | fadds mv_position+8(%esi) |
||
664 | fxch %st(1) // 0 | 2 | 1 |
||
665 | fstps mv_position+0(%esp) // 2 | 1 |
||
666 | fstps mv_position+8(%esp) // 1 |
||
667 | fstps mv_position+4(%esp) |
||
668 | |||
669 | // replace pv0 with the clip point |
||
670 | movl %esp,%esi |
||
671 | |||
672 | // if (clip->leftedge) |
||
673 | // { |
||
674 | jz Ltestright2 |
||
675 | |||
676 | // r_leftclipped = true; |
||
677 | // r_leftenter = clipvert; |
||
678 | movl $1,C(r_leftclipped) |
||
679 | movl mv_position+0(%esp),%eax |
||
680 | movl %eax,C(r_leftenter)+mv_position+0 |
||
681 | movl mv_position+4(%esp),%eax |
||
682 | movl %eax,C(r_leftenter)+mv_position+4 |
||
683 | movl mv_position+8(%esp),%eax |
||
684 | movl %eax,C(r_leftenter)+mv_position+8 |
||
685 | |||
686 | jmp Lcontinue |
||
687 | |||
688 | // } |
||
689 | |||
690 | Ltestright2: |
||
691 | // else if (clip->rightedge) |
||
692 | // { |
||
693 | testb %ah,%ah |
||
694 | jz Lcontinue |
||
695 | |||
696 | // r_rightclipped = true; |
||
697 | // r_rightenter = clipvert; |
||
698 | movl $1,C(r_rightclipped) |
||
699 | movl mv_position+0(%esp),%eax |
||
700 | movl %eax,C(r_rightenter)+mv_position+0 |
||
701 | movl mv_position+4(%esp),%eax |
||
702 | movl %eax,C(r_rightenter)+mv_position+4 |
||
703 | movl mv_position+8(%esp),%eax |
||
704 | movl %eax,C(r_rightenter)+mv_position+8 |
||
705 | |||
706 | // } |
||
707 | jmp Lcontinue |
||
708 | |||
709 | // %esi = vec3_t point to transform and project |
||
710 | // %edx preserved |
||
711 | LTransformAndProject: |
||
712 | |||
713 | // // transform and project |
||
714 | // VectorSubtract (world, modelorg, local); |
||
715 | flds mv_position+0(%esi) |
||
716 | fsubs C(modelorg)+0 |
||
717 | flds mv_position+4(%esi) |
||
718 | fsubs C(modelorg)+4 |
||
719 | flds mv_position+8(%esi) |
||
720 | fsubs C(modelorg)+8 |
||
721 | fxch %st(2) // local[0] | local[1] | local[2] |
||
722 | |||
723 | // TransformVector (local, transformed); |
||
724 | // |
||
725 | // if (transformed[2] < NEAR_CLIP) |
||
726 | // transformed[2] = NEAR_CLIP; |
||
727 | // |
||
728 | // lzi0 = 1.0 / transformed[2]; |
||
729 | fld %st(0) // local[0] | local[0] | local[1] | local[2] |
||
730 | fmuls C(vpn)+0 // zm0 | local[0] | local[1] | local[2] |
||
731 | fld %st(1) // local[0] | zm0 | local[0] | local[1] | |
||
732 | // local[2] |
||
733 | fmuls C(vright)+0 // xm0 | zm0 | local[0] | local[1] | local[2] |
||
734 | fxch %st(2) // local[0] | zm0 | xm0 | local[1] | local[2] |
||
735 | fmuls C(vup)+0 // ym0 | zm0 | xm0 | local[1] | local[2] |
||
736 | fld %st(3) // local[1] | ym0 | zm0 | xm0 | local[1] | |
||
737 | // local[2] |
||
738 | fmuls C(vpn)+4 // zm1 | ym0 | zm0 | xm0 | local[1] | |
||
739 | // local[2] |
||
740 | fld %st(4) // local[1] | zm1 | ym0 | zm0 | xm0 | |
||
741 | // local[1] | local[2] |
||
742 | fmuls C(vright)+4 // xm1 | zm1 | ym0 | zm0 | xm0 | |
||
743 | // local[1] | local[2] |
||
744 | fxch %st(5) // local[1] | zm1 | ym0 | zm0 | xm0 | |
||
745 | // xm1 | local[2] |
||
746 | fmuls C(vup)+4 // ym1 | zm1 | ym0 | zm0 | xm0 | |
||
747 | // xm1 | local[2] |
||
748 | fxch %st(1) // zm1 | ym1 | ym0 | zm0 | xm0 | |
||
749 | // xm1 | local[2] |
||
750 | faddp %st(0),%st(3) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2] |
||
751 | fxch %st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2] |
||
752 | faddp %st(0),%st(4) // ym0 | zm2 | ym1 | xm2 | local[2] |
||
753 | faddp %st(0),%st(2) // zm2 | ym2 | xm2 | local[2] |
||
754 | fld %st(3) // local[2] | zm2 | ym2 | xm2 | local[2] |
||
755 | fmuls C(vpn)+8 // zm3 | zm2 | ym2 | xm2 | local[2] |
||
756 | fld %st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2] |
||
757 | fmuls C(vright)+8 // xm3 | zm3 | zm2 | ym2 | xm2 | local[2] |
||
758 | fxch %st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3 |
||
759 | fmuls C(vup)+8 // ym3 | zm3 | zm2 | ym2 | xm2 | xm3 |
||
760 | fxch %st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3 |
||
761 | faddp %st(0),%st(2) // ym3 | zm4 | ym2 | xm2 | xm3 |
||
762 | fxch %st(4) // xm3 | zm4 | ym2 | xm2 | ym3 |
||
763 | faddp %st(0),%st(3) // zm4 | ym2 | xm4 | ym3 |
||
764 | fxch %st(1) // ym2 | zm4 | xm4 | ym3 |
||
765 | faddp %st(0),%st(3) // zm4 | xm4 | ym4 |
||
766 | |||
767 | fcoms Lfp_near_clip |
||
768 | fnstsw %ax |
||
769 | testb $1,%ah |
||
770 | jz LNoClip |
||
771 | fstp %st(0) |
||
772 | flds Lfp_near_clip |
||
773 | |||
774 | LNoClip: |
||
775 | |||
776 | fdivrs float_1 // lzi0 | x | y |
||
777 | fxch %st(1) // x | lzi0 | y |
||
778 | |||
779 | // // FIXME: build x/yscale into transform? |
||
780 | // scale = xscale * lzi0; |
||
781 | // u0 = (xcenter + scale*transformed[0]); |
||
782 | flds C(xscale) // xscale | x | lzi0 | y |
||
783 | fmul %st(2),%st(0) // scale | x | lzi0 | y |
||
784 | fmulp %st(0),%st(1) // scale*x | lzi0 | y |
||
785 | fadds C(xcenter) // u0 | lzi0 | y |
||
786 | |||
787 | // if (u0 < r_refdef.fvrectx_adj) |
||
788 | // u0 = r_refdef.fvrectx_adj; |
||
789 | // if (u0 > r_refdef.fvrectright_adj) |
||
790 | // u0 = r_refdef.fvrectright_adj; |
||
791 | // FIXME: use integer compares of floats? |
||
792 | fcoms C(r_refdef)+rd_fvrectx_adj |
||
793 | fnstsw %ax |
||
794 | testb $1,%ah |
||
795 | jz LClampP0 |
||
796 | fstp %st(0) |
||
797 | flds C(r_refdef)+rd_fvrectx_adj |
||
798 | LClampP0: |
||
799 | fcoms C(r_refdef)+rd_fvrectright_adj |
||
800 | fnstsw %ax |
||
801 | testb $0x45,%ah |
||
802 | jnz LClampP1 |
||
803 | fstp %st(0) |
||
804 | flds C(r_refdef)+rd_fvrectright_adj |
||
805 | LClampP1: |
||
806 | |||
807 | fld %st(1) // lzi0 | u0 | lzi0 | y |
||
808 | |||
809 | // scale = yscale * lzi0; |
||
810 | // v0 = (ycenter - scale*transformed[1]); |
||
811 | fmuls C(yscale) // scale | u0 | lzi0 | y |
||
812 | fmulp %st(0),%st(3) // u0 | lzi0 | scale*y |
||
813 | fxch %st(2) // scale*y | lzi0 | u0 |
||
814 | fsubrs C(ycenter) // v0 | lzi0 | u0 |
||
815 | |||
816 | // if (v0 < r_refdef.fvrecty_adj) |
||
817 | // v0 = r_refdef.fvrecty_adj; |
||
818 | // if (v0 > r_refdef.fvrectbottom_adj) |
||
819 | // v0 = r_refdef.fvrectbottom_adj; |
||
820 | // FIXME: use integer compares of floats? |
||
821 | fcoms C(r_refdef)+rd_fvrecty_adj |
||
822 | fnstsw %ax |
||
823 | testb $1,%ah |
||
824 | jz LClampP2 |
||
825 | fstp %st(0) |
||
826 | flds C(r_refdef)+rd_fvrecty_adj |
||
827 | LClampP2: |
||
828 | fcoms C(r_refdef)+rd_fvrectbottom_adj |
||
829 | fnstsw %ax |
||
830 | testb $0x45,%ah |
||
831 | jnz LClampP3 |
||
832 | fstp %st(0) |
||
833 | flds C(r_refdef)+rd_fvrectbottom_adj |
||
834 | LClampP3: |
||
835 | ret |
||
836 | |||
837 | #endif // id386>>>>>> |
||
838 |