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