1;
2; r_drawa.asm -- for MASM
3; x86 assembly-language edge clipping and emission code
4;
5; Copyright (C) 1996-1997  Id Software, Inc.
6;
7; This program is free software; you can redistribute it and/or
8; modify it under the terms of the GNU General Public License
9; as published by the Free Software Foundation; either version 2
10; of the License, or (at your option) any later version.
11;
12; This program is distributed in the hope that it will be useful,
13; but WITHOUT ANY WARRANTY; without even the implied warranty of
14; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15;
16; See the GNU General Public License for more details.
17;
18; You should have received a copy of the GNU General Public License
19; along with this program; if not, write to:
20; Free Software Foundation, Inc.
21; 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22;
23
24 .386P
25 .model FLAT
26; externs from C code
27 externdef _r_refdef:dword
28 externdef _ycenter:dword
29 externdef _xcenter:dword
30 externdef _r_leftclipped:dword
31 externdef _r_leftenter:dword
32 externdef _r_rightclipped:dword
33 externdef _r_rightenter:dword
34 externdef _modelorg:dword
35 externdef _xscale:dword
36 externdef _yscale:dword
37 externdef _r_leftexit:dword
38 externdef _r_rightexit:dword
39 externdef _r_lastvertvalid:dword
40 externdef _cacheoffset:dword
41 externdef _newedges:dword
42 externdef _removeedges:dword
43 externdef _r_pedge:dword
44 externdef _r_framecount:dword
45 externdef _r_u1:dword
46 externdef _r_emitted:dword
47 externdef _edge_p:dword
48 externdef _surface_p:dword
49 externdef _surfaces:dword
50 externdef _r_lzi1:dword
51 externdef _r_v1:dword
52 externdef _r_ceilv1:dword
53 externdef _r_nearzi:dword
54 externdef _r_nearzionly:dword
55 externdef _vright:dword
56 externdef _vup:dword
57 externdef _vpn:dword
58
59; externs from ASM-only code
60 externdef float_point5:dword
61 externdef float_1:dword
62 externdef float_minus_1:dword
63 externdef float_0:dword
64 externdef fp_1m:dword
65 externdef fp_1m_minus_1:dword
66 externdef fp_8:dword
67 externdef fp_16:dword
68 externdef fp_64k:dword
69 externdef fp_64kx64k:dword
70 externdef ceil_cw:dword
71 externdef single_cw:dword
72
73_DATA SEGMENT
74Ld0 dd 0.0
75Ld1 dd 0.0
76Lstack dd 0
77Lfp_near_clip dd 0.01
78Lceilv0 dd 0
79Lv dd 0
80Lu0 dd 0
81Lv0 dd 0
82Lzi0 dd 0
83_DATA ENDS
84_TEXT SEGMENT
85 align 4
86 public _R_ClipEdge
87_R_ClipEdge:
88 push esi
89 push edi
90 push ebx
91 mov ds:dword ptr[Lstack],esp
92 mov ebx,ds:dword ptr[12+12+esp]
93 mov esi,ds:dword ptr[4+12+esp]
94 mov edx,ds:dword ptr[8+12+esp]
95 test ebx,ebx
96 jz Lemit
97Lcliploop:
98 fld ds:dword ptr[0+0+esi]
99 fmul ds:dword ptr[0+0+ebx]
100 fld ds:dword ptr[0+4+esi]
101 fmul ds:dword ptr[0+4+ebx]
102 fld ds:dword ptr[0+8+esi]
103 fmul ds:dword ptr[0+8+ebx]
104 fxch st(1)
105 faddp st(2),st(0)
106 fld ds:dword ptr[0+0+edx]
107 fmul ds:dword ptr[0+0+ebx]
108 fld ds:dword ptr[0+4+edx]
109 fmul ds:dword ptr[0+4+ebx]
110 fld ds:dword ptr[0+8+edx]
111 fmul ds:dword ptr[0+8+ebx]
112 fxch st(1)
113 faddp st(2),st(0)
114 fxch st(3)
115 faddp st(2),st(0)
116 faddp st(2),st(0)
117 fsub ds:dword ptr[12+ebx]
118 fxch st(1)
119 fsub ds:dword ptr[12+ebx]
120 fxch st(1)
121 fstp ds:dword ptr[Ld0]
122 fstp ds:dword ptr[Ld1]
123 mov eax,ds:dword ptr[Ld0]
124 mov ecx,ds:dword ptr[Ld1]
125 or ecx,eax
126 js Lp2
127Lcontinue:
128 mov ebx,ds:dword ptr[16+ebx]
129 test ebx,ebx
130 jnz Lcliploop
131Lemit:
132 fldcw ds:word ptr[ceil_cw]
133 cmp ds:dword ptr[_r_lastvertvalid],0
134 jz LCalcFirst
135 mov eax,ds:dword ptr[_r_lzi1]
136 mov ecx,ds:dword ptr[_r_u1]
137 mov ds:dword ptr[Lzi0],eax
138 mov ds:dword ptr[Lu0],ecx
139 mov ecx,ds:dword ptr[_r_v1]
140 mov eax,ds:dword ptr[_r_ceilv1]
141 mov ds:dword ptr[Lv0],ecx
142 mov ds:dword ptr[Lceilv0],eax
143 jmp LCalcSecond
144LCalcFirst:
145 call near ptr LTransformAndProject
146 fst ds:dword ptr[Lv0]
147 fxch st(2)
148 fstp ds:dword ptr[Lu0]
149 fstp ds:dword ptr[Lzi0]
150 fistp ds:dword ptr[Lceilv0]
151LCalcSecond:
152 mov esi,edx
153 call near ptr LTransformAndProject
154 fld ds:dword ptr[Lu0]
155 fxch st(3)
156 fld ds:dword ptr[Lzi0]
157 fxch st(3)
158 fld ds:dword ptr[Lv0]
159 fxch st(3)
160 fist ds:dword ptr[_r_ceilv1]
161 fldcw ds:word ptr[single_cw]
162 fst ds:dword ptr[_r_v1]
163 fxch st(4)
164 fcom st(1)
165 fnstsw ax
166 test ah,1
167 jz LP0
168 fstp st(0)
169 fld st(0)
170LP0:
171 fxch st(1)
172 fstp ds:dword ptr[_r_lzi1]
173 fxch st(1)
174 fst ds:dword ptr[_r_u1]
175 fxch st(1)
176 fcom ds:dword ptr[_r_nearzi]
177 fnstsw ax
178 test ah,045h
179 jnz LP1
180 fst ds:dword ptr[_r_nearzi]
181LP1:
182 mov eax,ds:dword ptr[_r_nearzionly]
183 test eax,eax
184 jz LP2
185LPop5AndDone:
186 mov eax,ds:dword ptr[_cacheoffset]
187 mov edx,ds:dword ptr[_r_framecount]
188 cmp eax,07FFFFFFFh
189 jz LDoPop
190 and edx,07FFFFFFFh
191 or edx,080000000h
192 mov ds:dword ptr[_cacheoffset],edx
193LDoPop:
194 fstp st(0)
195 fstp st(0)
196 fstp st(0)
197 fstp st(0)
198 fstp st(0)
199 jmp Ldone
200LP2:
201 mov ebx,ds:dword ptr[Lceilv0]
202 mov edi,ds:dword ptr[_edge_p]
203 mov ecx,ds:dword ptr[_r_ceilv1]
204 mov edx,edi
205 mov esi,ds:dword ptr[_r_pedge]
206 add edx,32
207 cmp ebx,ecx
208 jz LPop5AndDone
209 mov eax,ds:dword ptr[_r_pedge]
210 mov ds:dword ptr[28+edi],eax
211 fstp ds:dword ptr[24+edi]
212 jc LSide0
213LSide1:
214 fsubp st(3),st(0)
215 fsub st(0),st(1)
216 fdivp st(2),st(0)
217 mov ds:dword ptr[_r_emitted],1
218 mov ds:dword ptr[_edge_p],edx
219 mov eax,ds:dword ptr[edx]
220 mov eax,ecx
221 lea ecx,ds:dword ptr[-1+ebx]
222 mov ebx,eax
223 mov eax,ds:dword ptr[_surface_p]
224 mov esi,ds:dword ptr[_surfaces]
225 sub edx,edx
226 sub eax,esi
227 shr eax,6
228 mov ds:dword ptr[16+edi],edx
229 mov ds:dword ptr[16+2+edi],eax
230 sub esi,esi
231 mov ds:dword ptr[Lv],ebx
232 fild ds:dword ptr[Lv]
233 fsubrp st(1),st(0)
234 fmul st(0),st(1)
235 fadd ds:dword ptr[_r_u1]
236 jmp LSideDone
237LSide0:
238 fsub st(0),st(3)
239 fxch st(2)
240 fsub st(0),st(1)
241 fdivp st(2),st(0)
242 mov ds:dword ptr[_r_emitted],1
243 mov ds:dword ptr[_edge_p],edx
244 mov eax,ds:dword ptr[edx]
245 dec ecx
246 mov eax,ds:dword ptr[_surface_p]
247 mov esi,ds:dword ptr[_surfaces]
248 sub edx,edx
249 sub eax,esi
250 shr eax,6
251 mov ds:dword ptr[16+2+edi],edx
252 mov ds:dword ptr[16+edi],eax
253 mov esi,1
254 mov ds:dword ptr[Lv],ebx
255 fild ds:dword ptr[Lv]
256 fsubrp st(1),st(0)
257 fmul st(0),st(1)
258 faddp st(2),st(0)
259 fxch st(1)
260LSideDone:
261 fmul ds:dword ptr[fp_1m]
262 fxch st(1)
263 fmul ds:dword ptr[fp_1m]
264 fxch st(1)
265 fadd ds:dword ptr[fp_1m_minus_1]
266 fxch st(1)
267 fistp ds:dword ptr[4+edi]
268 fistp ds:dword ptr[0+edi]
269 mov eax,ds:dword ptr[0+edi]
270 mov edx,ds:dword ptr[_r_refdef+76]
271 cmp eax,edx
272 jl LP4
273 mov edx,ds:dword ptr[_r_refdef+80]
274 cmp eax,edx
275 jng LP5
276LP4:
277 mov ds:dword ptr[0+edi],edx
278 mov eax,edx
279LP5:
280 add eax,esi
281 mov esi,ds:dword ptr[_newedges+ebx*4]
282 test esi,esi
283 jz LDoFirst
284 cmp ds:dword ptr[0+esi],eax
285 jl LNotFirst
286LDoFirst:
287 mov ds:dword ptr[12+edi],esi
288 mov ds:dword ptr[_newedges+ebx*4],edi
289 jmp LSetRemove
290LNotFirst:
291LFindInsertLoop:
292 mov edx,esi
293 mov esi,ds:dword ptr[12+esi]
294 test esi,esi
295 jz LInsertFound
296 cmp ds:dword ptr[0+esi],eax
297 jl LFindInsertLoop
298LInsertFound:
299 mov ds:dword ptr[12+edi],esi
300 mov ds:dword ptr[12+edx],edi
301LSetRemove:
302 mov eax,ds:dword ptr[_removeedges+ecx*4]
303 mov ds:dword ptr[_removeedges+ecx*4],edi
304 mov ds:dword ptr[20+edi],eax
305Ldone:
306 mov esp,ds:dword ptr[Lstack]
307 pop ebx
308 pop edi
309 pop esi
310 ret
311Lp2:
312 test eax,eax
313 jns Lp1
314 mov eax,ds:dword ptr[Ld1]
315 test eax,eax
316 jns Lp3
317 mov eax,ds:dword ptr[_r_leftclipped]
318 mov ecx,ds:dword ptr[_r_pedge]
319 test eax,eax
320 jnz Ldone
321 mov eax,ds:dword ptr[_r_framecount]
322 and eax,07FFFFFFFh
323 or eax,080000000h
324 mov ds:dword ptr[_cacheoffset],eax
325 jmp Ldone
326Lp1:
327 fld ds:dword ptr[Ld0]
328 fld ds:dword ptr[Ld1]
329 fsubr st(0),st(1)
330 mov ds:dword ptr[_cacheoffset],07FFFFFFFh
331 fdivp st(1),st(0)
332 sub esp,12
333 fld ds:dword ptr[0+8+edx]
334 fsub ds:dword ptr[0+8+esi]
335 fld ds:dword ptr[0+4+edx]
336 fsub ds:dword ptr[0+4+esi]
337 fld ds:dword ptr[0+0+edx]
338 fsub ds:dword ptr[0+0+esi]
339 mov edx,esp
340 mov eax,ds:dword ptr[20+ebx]
341 test al,al
342 fmul st(0),st(3)
343 fxch st(1)
344 fmul st(0),st(3)
345 fxch st(2)
346 fmulp st(3),st(0)
347 fadd ds:dword ptr[0+0+esi]
348 fxch st(1)
349 fadd ds:dword ptr[0+4+esi]
350 fxch st(2)
351 fadd ds:dword ptr[0+8+esi]
352 fxch st(1)
353 fstp ds:dword ptr[0+0+esp]
354 fstp ds:dword ptr[0+8+esp]
355 fstp ds:dword ptr[0+4+esp]
356 jz Ltestright
357 mov ds:dword ptr[_r_leftclipped],1
358 mov eax,ds:dword ptr[0+0+esp]
359 mov ds:dword ptr[_r_leftexit+0+0],eax
360 mov eax,ds:dword ptr[0+4+esp]
361 mov ds:dword ptr[_r_leftexit+0+4],eax
362 mov eax,ds:dword ptr[0+8+esp]
363 mov ds:dword ptr[_r_leftexit+0+8],eax
364 jmp Lcontinue
365Ltestright:
366 test ah,ah
367 jz Lcontinue
368 mov ds:dword ptr[_r_rightclipped],1
369 mov eax,ds:dword ptr[0+0+esp]
370 mov ds:dword ptr[_r_rightexit+0+0],eax
371 mov eax,ds:dword ptr[0+4+esp]
372 mov ds:dword ptr[_r_rightexit+0+4],eax
373 mov eax,ds:dword ptr[0+8+esp]
374 mov ds:dword ptr[_r_rightexit+0+8],eax
375 jmp Lcontinue
376Lp3:
377 mov ds:dword ptr[_r_lastvertvalid],0
378 fld ds:dword ptr[Ld0]
379 fld ds:dword ptr[Ld1]
380 fsubr st(0),st(1)
381 mov ds:dword ptr[_cacheoffset],07FFFFFFFh
382 fdivp st(1),st(0)
383 sub esp,12
384 fld ds:dword ptr[0+8+edx]
385 fsub ds:dword ptr[0+8+esi]
386 fld ds:dword ptr[0+4+edx]
387 fsub ds:dword ptr[0+4+esi]
388 fld ds:dword ptr[0+0+edx]
389 fsub ds:dword ptr[0+0+esi]
390 mov eax,ds:dword ptr[20+ebx]
391 test al,al
392 fmul st(0),st(3)
393 fxch st(1)
394 fmul st(0),st(3)
395 fxch st(2)
396 fmulp st(3),st(0)
397 fadd ds:dword ptr[0+0+esi]
398 fxch st(1)
399 fadd ds:dword ptr[0+4+esi]
400 fxch st(2)
401 fadd ds:dword ptr[0+8+esi]
402 fxch st(1)
403 fstp ds:dword ptr[0+0+esp]
404 fstp ds:dword ptr[0+8+esp]
405 fstp ds:dword ptr[0+4+esp]
406 mov esi,esp
407 jz Ltestright2
408 mov ds:dword ptr[_r_leftclipped],1
409 mov eax,ds:dword ptr[0+0+esp]
410 mov ds:dword ptr[_r_leftenter+0+0],eax
411 mov eax,ds:dword ptr[0+4+esp]
412 mov ds:dword ptr[_r_leftenter+0+4],eax
413 mov eax,ds:dword ptr[0+8+esp]
414 mov ds:dword ptr[_r_leftenter+0+8],eax
415 jmp Lcontinue
416Ltestright2:
417 test ah,ah
418 jz Lcontinue
419 mov ds:dword ptr[_r_rightclipped],1
420 mov eax,ds:dword ptr[0+0+esp]
421 mov ds:dword ptr[_r_rightenter+0+0],eax
422 mov eax,ds:dword ptr[0+4+esp]
423 mov ds:dword ptr[_r_rightenter+0+4],eax
424 mov eax,ds:dword ptr[0+8+esp]
425 mov ds:dword ptr[_r_rightenter+0+8],eax
426 jmp Lcontinue
427LTransformAndProject:
428 fld ds:dword ptr[0+0+esi]
429 fsub ds:dword ptr[_modelorg+0]
430 fld ds:dword ptr[0+4+esi]
431 fsub ds:dword ptr[_modelorg+4]
432 fld ds:dword ptr[0+8+esi]
433 fsub ds:dword ptr[_modelorg+8]
434 fxch st(2)
435 fld st(0)
436 fmul ds:dword ptr[_vpn+0]
437 fld st(1)
438 fmul ds:dword ptr[_vright+0]
439 fxch st(2)
440 fmul ds:dword ptr[_vup+0]
441 fld st(3)
442 fmul ds:dword ptr[_vpn+4]
443 fld st(4)
444 fmul ds:dword ptr[_vright+4]
445 fxch st(5)
446 fmul ds:dword ptr[_vup+4]
447 fxch st(1)
448 faddp st(3),st(0)
449 fxch st(3)
450 faddp st(4),st(0)
451 faddp st(2),st(0)
452 fld st(3)
453 fmul ds:dword ptr[_vpn+8]
454 fld st(4)
455 fmul ds:dword ptr[_vright+8]
456 fxch st(5)
457 fmul ds:dword ptr[_vup+8]
458 fxch st(1)
459 faddp st(2),st(0)
460 fxch st(4)
461 faddp st(3),st(0)
462 fxch st(1)
463 faddp st(3),st(0)
464 fcom ds:dword ptr[Lfp_near_clip]
465 fnstsw ax
466 test ah,1
467 jz LNoClip
468 fstp st(0)
469 fld ds:dword ptr[Lfp_near_clip]
470LNoClip:
471 fdivr ds:dword ptr[float_1]
472 fxch st(1)
473 fld ds:dword ptr[_xscale]
474 fmul st(0),st(2)
475 fmulp st(1),st(0)
476 fadd ds:dword ptr[_xcenter]
477 fcom ds:dword ptr[_r_refdef+68]
478 fnstsw ax
479 test ah,1
480 jz LClampP0
481 fstp st(0)
482 fld ds:dword ptr[_r_refdef+68]
483LClampP0:
484 fcom ds:dword ptr[_r_refdef+84]
485 fnstsw ax
486 test ah,045h
487 jnz LClampP1
488 fstp st(0)
489 fld ds:dword ptr[_r_refdef+84]
490LClampP1:
491 fld st(1)
492 fmul ds:dword ptr[_yscale]
493 fmulp st(3),st(0)
494 fxch st(2)
495 fsubr ds:dword ptr[_ycenter]
496 fcom ds:dword ptr[_r_refdef+72]
497 fnstsw ax
498 test ah,1
499 jz LClampP2
500 fstp st(0)
501 fld ds:dword ptr[_r_refdef+72]
502LClampP2:
503 fcom ds:dword ptr[_r_refdef+88]
504 fnstsw ax
505 test ah,045h
506 jnz LClampP3
507 fstp st(0)
508 fld ds:dword ptr[_r_refdef+88]
509LClampP3:
510 ret
511_TEXT ENDS
512 END
513