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