|
|
1.1 ! root 1: #include "q_shared.h" ! 2: ! 3: #define DEG2RAD( a ) ( a * M_PI ) / 180.0F ! 4: ! 5: vec3_t vec3_origin = {0,0,0}; ! 6: ! 7: //============================================================================ ! 8: ! 9: #ifdef _WIN32 ! 10: #pragma optimize( "", off ) ! 11: #endif ! 12: ! 13: void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) ! 14: { ! 15: float m[3][3]; ! 16: float im[3][3]; ! 17: float zrot[3][3]; ! 18: float tmpmat[3][3]; ! 19: float rot[3][3]; ! 20: int i; ! 21: vec3_t vr, vup, vf; ! 22: ! 23: vf[0] = dir[0]; ! 24: vf[1] = dir[1]; ! 25: vf[2] = dir[2]; ! 26: ! 27: PerpendicularVector( vr, dir ); ! 28: CrossProduct( vr, vf, vup ); ! 29: ! 30: m[0][0] = vr[0]; ! 31: m[1][0] = vr[1]; ! 32: m[2][0] = vr[2]; ! 33: ! 34: m[0][1] = vup[0]; ! 35: m[1][1] = vup[1]; ! 36: m[2][1] = vup[2]; ! 37: ! 38: m[0][2] = vf[0]; ! 39: m[1][2] = vf[1]; ! 40: m[2][2] = vf[2]; ! 41: ! 42: memcpy( im, m, sizeof( im ) ); ! 43: ! 44: im[0][1] = m[1][0]; ! 45: im[0][2] = m[2][0]; ! 46: im[1][0] = m[0][1]; ! 47: im[1][2] = m[2][1]; ! 48: im[2][0] = m[0][2]; ! 49: im[2][1] = m[1][2]; ! 50: ! 51: memset( zrot, 0, sizeof( zrot ) ); ! 52: zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; ! 53: ! 54: zrot[0][0] = cos( DEG2RAD( degrees ) ); ! 55: zrot[0][1] = sin( DEG2RAD( degrees ) ); ! 56: zrot[1][0] = -sin( DEG2RAD( degrees ) ); ! 57: zrot[1][1] = cos( DEG2RAD( degrees ) ); ! 58: ! 59: R_ConcatRotations( m, zrot, tmpmat ); ! 60: R_ConcatRotations( tmpmat, im, rot ); ! 61: ! 62: for ( i = 0; i < 3; i++ ) ! 63: { ! 64: dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; ! 65: } ! 66: } ! 67: ! 68: #ifdef _WIN32 ! 69: #pragma optimize( "", on ) ! 70: #endif ! 71: ! 72: ! 73: ! 74: void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) ! 75: { ! 76: float angle; ! 77: static float sr, sp, sy, cr, cp, cy; ! 78: // static to help MS compiler fp bugs ! 79: ! 80: angle = angles[YAW] * (M_PI*2 / 360); ! 81: sy = sin(angle); ! 82: cy = cos(angle); ! 83: angle = angles[PITCH] * (M_PI*2 / 360); ! 84: sp = sin(angle); ! 85: cp = cos(angle); ! 86: angle = angles[ROLL] * (M_PI*2 / 360); ! 87: sr = sin(angle); ! 88: cr = cos(angle); ! 89: ! 90: if (forward) ! 91: { ! 92: forward[0] = cp*cy; ! 93: forward[1] = cp*sy; ! 94: forward[2] = -sp; ! 95: } ! 96: if (right) ! 97: { ! 98: right[0] = (-1*sr*sp*cy+-1*cr*-sy); ! 99: right[1] = (-1*sr*sp*sy+-1*cr*cy); ! 100: right[2] = -1*sr*cp; ! 101: } ! 102: if (up) ! 103: { ! 104: up[0] = (cr*sp*cy+-sr*-sy); ! 105: up[1] = (cr*sp*sy+-sr*cy); ! 106: up[2] = cr*cp; ! 107: } ! 108: } ! 109: ! 110: ! 111: void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) ! 112: { ! 113: float d; ! 114: vec3_t n; ! 115: float inv_denom; ! 116: ! 117: inv_denom = 1.0F / DotProduct( normal, normal ); ! 118: ! 119: d = DotProduct( normal, p ) * inv_denom; ! 120: ! 121: n[0] = normal[0] * inv_denom; ! 122: n[1] = normal[1] * inv_denom; ! 123: n[2] = normal[2] * inv_denom; ! 124: ! 125: dst[0] = p[0] - d * n[0]; ! 126: dst[1] = p[1] - d * n[1]; ! 127: dst[2] = p[2] - d * n[2]; ! 128: } ! 129: ! 130: /* ! 131: ** assumes "src" is normalized ! 132: */ ! 133: void PerpendicularVector( vec3_t dst, const vec3_t src ) ! 134: { ! 135: int pos; ! 136: int i; ! 137: float minelem = 1.0F; ! 138: vec3_t tempvec; ! 139: ! 140: /* ! 141: ** find the smallest magnitude axially aligned vector ! 142: */ ! 143: for ( pos = 0, i = 0; i < 3; i++ ) ! 144: { ! 145: if ( fabs( src[i] ) < minelem ) ! 146: { ! 147: pos = i; ! 148: minelem = fabs( src[i] ); ! 149: } ! 150: } ! 151: tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; ! 152: tempvec[pos] = 1.0F; ! 153: ! 154: /* ! 155: ** project the point onto the plane defined by src ! 156: */ ! 157: ProjectPointOnPlane( dst, tempvec, src ); ! 158: ! 159: /* ! 160: ** normalize the result ! 161: */ ! 162: VectorNormalize( dst ); ! 163: } ! 164: ! 165: ! 166: ! 167: /* ! 168: ================ ! 169: R_ConcatRotations ! 170: ================ ! 171: */ ! 172: void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) ! 173: { ! 174: out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + ! 175: in1[0][2] * in2[2][0]; ! 176: out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + ! 177: in1[0][2] * in2[2][1]; ! 178: out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + ! 179: in1[0][2] * in2[2][2]; ! 180: out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + ! 181: in1[1][2] * in2[2][0]; ! 182: out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + ! 183: in1[1][2] * in2[2][1]; ! 184: out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + ! 185: in1[1][2] * in2[2][2]; ! 186: out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + ! 187: in1[2][2] * in2[2][0]; ! 188: out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + ! 189: in1[2][2] * in2[2][1]; ! 190: out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + ! 191: in1[2][2] * in2[2][2]; ! 192: } ! 193: ! 194: ! 195: /* ! 196: ================ ! 197: R_ConcatTransforms ! 198: ================ ! 199: */ ! 200: void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) ! 201: { ! 202: out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + ! 203: in1[0][2] * in2[2][0]; ! 204: out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + ! 205: in1[0][2] * in2[2][1]; ! 206: out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + ! 207: in1[0][2] * in2[2][2]; ! 208: out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + ! 209: in1[0][2] * in2[2][3] + in1[0][3]; ! 210: out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + ! 211: in1[1][2] * in2[2][0]; ! 212: out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + ! 213: in1[1][2] * in2[2][1]; ! 214: out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + ! 215: in1[1][2] * in2[2][2]; ! 216: out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + ! 217: in1[1][2] * in2[2][3] + in1[1][3]; ! 218: out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + ! 219: in1[2][2] * in2[2][0]; ! 220: out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + ! 221: in1[2][2] * in2[2][1]; ! 222: out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + ! 223: in1[2][2] * in2[2][2]; ! 224: out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + ! 225: in1[2][2] * in2[2][3] + in1[2][3]; ! 226: } ! 227: ! 228: ! 229: //============================================================================ ! 230: ! 231: ! 232: float Q_fabs (float f) ! 233: { ! 234: #if 0 ! 235: if (f >= 0) ! 236: return f; ! 237: return -f; ! 238: #else ! 239: int tmp = * ( int * ) &f; ! 240: tmp &= 0x7FFFFFFF; ! 241: return * ( float * ) &tmp; ! 242: #endif ! 243: } ! 244: ! 245: #if defined _M_IX86 && !defined C_ONLY ! 246: #pragma warning (disable:4035) ! 247: __declspec( naked ) long Q_ftol( float f ) ! 248: { ! 249: static int tmp; ! 250: __asm fld dword ptr [esp+4] ! 251: __asm fistp tmp ! 252: __asm mov eax, tmp ! 253: __asm ret ! 254: } ! 255: #pragma warning (default:4035) ! 256: #endif ! 257: ! 258: /* ! 259: =============== ! 260: LerpAngle ! 261: ! 262: =============== ! 263: */ ! 264: float LerpAngle (float a2, float a1, float frac) ! 265: { ! 266: if (a1 - a2 > 180) ! 267: a1 -= 360; ! 268: if (a1 - a2 < -180) ! 269: a1 += 360; ! 270: return a2 + frac * (a1 - a2); ! 271: } ! 272: ! 273: ! 274: float anglemod(float a) ! 275: { ! 276: #if 0 ! 277: if (a >= 0) ! 278: a -= 360*(int)(a/360); ! 279: else ! 280: a += 360*( 1 + (int)(-a/360) ); ! 281: #endif ! 282: a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); ! 283: return a; ! 284: } ! 285: ! 286: int i; ! 287: vec3_t corners[2]; ! 288: ! 289: ! 290: // this is the slow, general version ! 291: int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p) ! 292: { ! 293: int i; ! 294: float dist1, dist2; ! 295: int sides; ! 296: vec3_t corners[2]; ! 297: ! 298: for (i=0 ; i<3 ; i++) ! 299: { ! 300: if (p->normal[i] < 0) ! 301: { ! 302: corners[0][i] = emins[i]; ! 303: corners[1][i] = emaxs[i]; ! 304: } ! 305: else ! 306: { ! 307: corners[1][i] = emins[i]; ! 308: corners[0][i] = emaxs[i]; ! 309: } ! 310: } ! 311: dist1 = DotProduct (p->normal, corners[0]) - p->dist; ! 312: dist2 = DotProduct (p->normal, corners[1]) - p->dist; ! 313: sides = 0; ! 314: if (dist1 >= 0) ! 315: sides = 1; ! 316: if (dist2 < 0) ! 317: sides |= 2; ! 318: ! 319: return sides; ! 320: } ! 321: ! 322: /* ! 323: ================== ! 324: BoxOnPlaneSide ! 325: ! 326: Returns 1, 2, or 1 + 2 ! 327: ================== ! 328: */ ! 329: #if !id386 || defined __linux__ ! 330: int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) ! 331: { ! 332: float dist1, dist2; ! 333: int sides; ! 334: ! 335: // fast axial cases ! 336: if (p->type < 3) ! 337: { ! 338: if (p->dist <= emins[p->type]) ! 339: return 1; ! 340: if (p->dist >= emaxs[p->type]) ! 341: return 2; ! 342: return 3; ! 343: } ! 344: ! 345: // general case ! 346: switch (p->signbits) ! 347: { ! 348: case 0: ! 349: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; ! 350: dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; ! 351: break; ! 352: case 1: ! 353: dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; ! 354: dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; ! 355: break; ! 356: case 2: ! 357: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; ! 358: dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; ! 359: break; ! 360: case 3: ! 361: dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; ! 362: dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; ! 363: break; ! 364: case 4: ! 365: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; ! 366: dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; ! 367: break; ! 368: case 5: ! 369: dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; ! 370: dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; ! 371: break; ! 372: case 6: ! 373: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; ! 374: dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; ! 375: break; ! 376: case 7: ! 377: dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; ! 378: dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; ! 379: break; ! 380: default: ! 381: dist1 = dist2 = 0; // shut up compiler ! 382: assert( 0 ); ! 383: break; ! 384: } ! 385: ! 386: sides = 0; ! 387: if (dist1 >= p->dist) ! 388: sides = 1; ! 389: if (dist2 < p->dist) ! 390: sides |= 2; ! 391: ! 392: assert( sides != 0 ); ! 393: ! 394: return sides; ! 395: } ! 396: #else ! 397: #pragma warning( disable: 4035 ) ! 398: ! 399: __declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) ! 400: { ! 401: static int bops_initialized; ! 402: static int Ljmptab[8]; ! 403: ! 404: __asm { ! 405: ! 406: push ebx ! 407: ! 408: cmp bops_initialized, 1 ! 409: je initialized ! 410: mov bops_initialized, 1 ! 411: ! 412: mov Ljmptab[0*4], offset Lcase0 ! 413: mov Ljmptab[1*4], offset Lcase1 ! 414: mov Ljmptab[2*4], offset Lcase2 ! 415: mov Ljmptab[3*4], offset Lcase3 ! 416: mov Ljmptab[4*4], offset Lcase4 ! 417: mov Ljmptab[5*4], offset Lcase5 ! 418: mov Ljmptab[6*4], offset Lcase6 ! 419: mov Ljmptab[7*4], offset Lcase7 ! 420: ! 421: initialized: ! 422: ! 423: mov edx,ds:dword ptr[4+12+esp] ! 424: mov ecx,ds:dword ptr[4+4+esp] ! 425: xor eax,eax ! 426: mov ebx,ds:dword ptr[4+8+esp] ! 427: mov al,ds:byte ptr[17+edx] ! 428: cmp al,8 ! 429: jge Lerror ! 430: fld ds:dword ptr[0+edx] ! 431: fld st(0) ! 432: jmp dword ptr[Ljmptab+eax*4] ! 433: Lcase0: ! 434: fmul ds:dword ptr[ebx] ! 435: fld ds:dword ptr[0+4+edx] ! 436: fxch st(2) ! 437: fmul ds:dword ptr[ecx] ! 438: fxch st(2) ! 439: fld st(0) ! 440: fmul ds:dword ptr[4+ebx] ! 441: fld ds:dword ptr[0+8+edx] ! 442: fxch st(2) ! 443: fmul ds:dword ptr[4+ecx] ! 444: fxch st(2) ! 445: fld st(0) ! 446: fmul ds:dword ptr[8+ebx] ! 447: fxch st(5) ! 448: faddp st(3),st(0) ! 449: fmul ds:dword ptr[8+ecx] ! 450: fxch st(1) ! 451: faddp st(3),st(0) ! 452: fxch st(3) ! 453: faddp st(2),st(0) ! 454: jmp LSetSides ! 455: Lcase1: ! 456: fmul ds:dword ptr[ecx] ! 457: fld ds:dword ptr[0+4+edx] ! 458: fxch st(2) ! 459: fmul ds:dword ptr[ebx] ! 460: fxch st(2) ! 461: fld st(0) ! 462: fmul ds:dword ptr[4+ebx] ! 463: fld ds:dword ptr[0+8+edx] ! 464: fxch st(2) ! 465: fmul ds:dword ptr[4+ecx] ! 466: fxch st(2) ! 467: fld st(0) ! 468: fmul ds:dword ptr[8+ebx] ! 469: fxch st(5) ! 470: faddp st(3),st(0) ! 471: fmul ds:dword ptr[8+ecx] ! 472: fxch st(1) ! 473: faddp st(3),st(0) ! 474: fxch st(3) ! 475: faddp st(2),st(0) ! 476: jmp LSetSides ! 477: Lcase2: ! 478: fmul ds:dword ptr[ebx] ! 479: fld ds:dword ptr[0+4+edx] ! 480: fxch st(2) ! 481: fmul ds:dword ptr[ecx] ! 482: fxch st(2) ! 483: fld st(0) ! 484: fmul ds:dword ptr[4+ecx] ! 485: fld ds:dword ptr[0+8+edx] ! 486: fxch st(2) ! 487: fmul ds:dword ptr[4+ebx] ! 488: fxch st(2) ! 489: fld st(0) ! 490: fmul ds:dword ptr[8+ebx] ! 491: fxch st(5) ! 492: faddp st(3),st(0) ! 493: fmul ds:dword ptr[8+ecx] ! 494: fxch st(1) ! 495: faddp st(3),st(0) ! 496: fxch st(3) ! 497: faddp st(2),st(0) ! 498: jmp LSetSides ! 499: Lcase3: ! 500: fmul ds:dword ptr[ecx] ! 501: fld ds:dword ptr[0+4+edx] ! 502: fxch st(2) ! 503: fmul ds:dword ptr[ebx] ! 504: fxch st(2) ! 505: fld st(0) ! 506: fmul ds:dword ptr[4+ecx] ! 507: fld ds:dword ptr[0+8+edx] ! 508: fxch st(2) ! 509: fmul ds:dword ptr[4+ebx] ! 510: fxch st(2) ! 511: fld st(0) ! 512: fmul ds:dword ptr[8+ebx] ! 513: fxch st(5) ! 514: faddp st(3),st(0) ! 515: fmul ds:dword ptr[8+ecx] ! 516: fxch st(1) ! 517: faddp st(3),st(0) ! 518: fxch st(3) ! 519: faddp st(2),st(0) ! 520: jmp LSetSides ! 521: Lcase4: ! 522: fmul ds:dword ptr[ebx] ! 523: fld ds:dword ptr[0+4+edx] ! 524: fxch st(2) ! 525: fmul ds:dword ptr[ecx] ! 526: fxch st(2) ! 527: fld st(0) ! 528: fmul ds:dword ptr[4+ebx] ! 529: fld ds:dword ptr[0+8+edx] ! 530: fxch st(2) ! 531: fmul ds:dword ptr[4+ecx] ! 532: fxch st(2) ! 533: fld st(0) ! 534: fmul ds:dword ptr[8+ecx] ! 535: fxch st(5) ! 536: faddp st(3),st(0) ! 537: fmul ds:dword ptr[8+ebx] ! 538: fxch st(1) ! 539: faddp st(3),st(0) ! 540: fxch st(3) ! 541: faddp st(2),st(0) ! 542: jmp LSetSides ! 543: Lcase5: ! 544: fmul ds:dword ptr[ecx] ! 545: fld ds:dword ptr[0+4+edx] ! 546: fxch st(2) ! 547: fmul ds:dword ptr[ebx] ! 548: fxch st(2) ! 549: fld st(0) ! 550: fmul ds:dword ptr[4+ebx] ! 551: fld ds:dword ptr[0+8+edx] ! 552: fxch st(2) ! 553: fmul ds:dword ptr[4+ecx] ! 554: fxch st(2) ! 555: fld st(0) ! 556: fmul ds:dword ptr[8+ecx] ! 557: fxch st(5) ! 558: faddp st(3),st(0) ! 559: fmul ds:dword ptr[8+ebx] ! 560: fxch st(1) ! 561: faddp st(3),st(0) ! 562: fxch st(3) ! 563: faddp st(2),st(0) ! 564: jmp LSetSides ! 565: Lcase6: ! 566: fmul ds:dword ptr[ebx] ! 567: fld ds:dword ptr[0+4+edx] ! 568: fxch st(2) ! 569: fmul ds:dword ptr[ecx] ! 570: fxch st(2) ! 571: fld st(0) ! 572: fmul ds:dword ptr[4+ecx] ! 573: fld ds:dword ptr[0+8+edx] ! 574: fxch st(2) ! 575: fmul ds:dword ptr[4+ebx] ! 576: fxch st(2) ! 577: fld st(0) ! 578: fmul ds:dword ptr[8+ecx] ! 579: fxch st(5) ! 580: faddp st(3),st(0) ! 581: fmul ds:dword ptr[8+ebx] ! 582: fxch st(1) ! 583: faddp st(3),st(0) ! 584: fxch st(3) ! 585: faddp st(2),st(0) ! 586: jmp LSetSides ! 587: Lcase7: ! 588: fmul ds:dword ptr[ecx] ! 589: fld ds:dword ptr[0+4+edx] ! 590: fxch st(2) ! 591: fmul ds:dword ptr[ebx] ! 592: fxch st(2) ! 593: fld st(0) ! 594: fmul ds:dword ptr[4+ecx] ! 595: fld ds:dword ptr[0+8+edx] ! 596: fxch st(2) ! 597: fmul ds:dword ptr[4+ebx] ! 598: fxch st(2) ! 599: fld st(0) ! 600: fmul ds:dword ptr[8+ecx] ! 601: fxch st(5) ! 602: faddp st(3),st(0) ! 603: fmul ds:dword ptr[8+ebx] ! 604: fxch st(1) ! 605: faddp st(3),st(0) ! 606: fxch st(3) ! 607: faddp st(2),st(0) ! 608: LSetSides: ! 609: faddp st(2),st(0) ! 610: fcomp ds:dword ptr[12+edx] ! 611: xor ecx,ecx ! 612: fnstsw ax ! 613: fcomp ds:dword ptr[12+edx] ! 614: and ah,1 ! 615: xor ah,1 ! 616: add cl,ah ! 617: fnstsw ax ! 618: and ah,1 ! 619: add ah,ah ! 620: add cl,ah ! 621: pop ebx ! 622: mov eax,ecx ! 623: ret ! 624: Lerror: ! 625: int 3 ! 626: } ! 627: } ! 628: #pragma warning( default: 4035 ) ! 629: #endif ! 630: ! 631: void ClearBounds (vec3_t mins, vec3_t maxs) ! 632: { ! 633: mins[0] = mins[1] = mins[2] = 99999; ! 634: maxs[0] = maxs[1] = maxs[2] = -99999; ! 635: } ! 636: ! 637: void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs) ! 638: { ! 639: int i; ! 640: vec_t val; ! 641: ! 642: for (i=0 ; i<3 ; i++) ! 643: { ! 644: val = v[i]; ! 645: if (val < mins[i]) ! 646: mins[i] = val; ! 647: if (val > maxs[i]) ! 648: maxs[i] = val; ! 649: } ! 650: } ! 651: ! 652: ! 653: int VectorCompare (vec3_t v1, vec3_t v2) ! 654: { ! 655: if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) ! 656: return 0; ! 657: ! 658: return 1; ! 659: } ! 660: ! 661: ! 662: vec_t VectorNormalize (vec3_t v) ! 663: { ! 664: float length, ilength; ! 665: ! 666: length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; ! 667: length = sqrt (length); // FIXME ! 668: ! 669: if (length) ! 670: { ! 671: ilength = 1/length; ! 672: v[0] *= ilength; ! 673: v[1] *= ilength; ! 674: v[2] *= ilength; ! 675: } ! 676: ! 677: return length; ! 678: ! 679: } ! 680: ! 681: vec_t VectorNormalize2 (vec3_t v, vec3_t out) ! 682: { ! 683: float length, ilength; ! 684: ! 685: length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; ! 686: length = sqrt (length); // FIXME ! 687: ! 688: if (length) ! 689: { ! 690: ilength = 1/length; ! 691: out[0] = v[0]*ilength; ! 692: out[1] = v[1]*ilength; ! 693: out[2] = v[2]*ilength; ! 694: } ! 695: ! 696: return length; ! 697: ! 698: } ! 699: ! 700: void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) ! 701: { ! 702: vecc[0] = veca[0] + scale*vecb[0]; ! 703: vecc[1] = veca[1] + scale*vecb[1]; ! 704: vecc[2] = veca[2] + scale*vecb[2]; ! 705: } ! 706: ! 707: ! 708: vec_t _DotProduct (vec3_t v1, vec3_t v2) ! 709: { ! 710: return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; ! 711: } ! 712: ! 713: void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) ! 714: { ! 715: out[0] = veca[0]-vecb[0]; ! 716: out[1] = veca[1]-vecb[1]; ! 717: out[2] = veca[2]-vecb[2]; ! 718: } ! 719: ! 720: void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) ! 721: { ! 722: out[0] = veca[0]+vecb[0]; ! 723: out[1] = veca[1]+vecb[1]; ! 724: out[2] = veca[2]+vecb[2]; ! 725: } ! 726: ! 727: void _VectorCopy (vec3_t in, vec3_t out) ! 728: { ! 729: out[0] = in[0]; ! 730: out[1] = in[1]; ! 731: out[2] = in[2]; ! 732: } ! 733: ! 734: void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) ! 735: { ! 736: cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; ! 737: cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; ! 738: cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; ! 739: } ! 740: ! 741: double sqrt(double x); ! 742: ! 743: vec_t VectorLength(vec3_t v) ! 744: { ! 745: int i; ! 746: float length; ! 747: ! 748: length = 0; ! 749: for (i=0 ; i< 3 ; i++) ! 750: length += v[i]*v[i]; ! 751: length = sqrt (length); // FIXME ! 752: ! 753: return length; ! 754: } ! 755: ! 756: void VectorInverse (vec3_t v) ! 757: { ! 758: v[0] = -v[0]; ! 759: v[1] = -v[1]; ! 760: v[2] = -v[2]; ! 761: } ! 762: ! 763: void VectorScale (vec3_t in, vec_t scale, vec3_t out) ! 764: { ! 765: out[0] = in[0]*scale; ! 766: out[1] = in[1]*scale; ! 767: out[2] = in[2]*scale; ! 768: } ! 769: ! 770: ! 771: int Q_log2(int val) ! 772: { ! 773: int answer=0; ! 774: while (val>>=1) ! 775: answer++; ! 776: return answer; ! 777: } ! 778: ! 779: ! 780: ! 781: //==================================================================================== ! 782: ! 783: /* ! 784: ============ ! 785: COM_SkipPath ! 786: ============ ! 787: */ ! 788: char *COM_SkipPath (char *pathname) ! 789: { ! 790: char *last; ! 791: ! 792: last = pathname; ! 793: while (*pathname) ! 794: { ! 795: if (*pathname=='/') ! 796: last = pathname+1; ! 797: pathname++; ! 798: } ! 799: return last; ! 800: } ! 801: ! 802: /* ! 803: ============ ! 804: COM_StripExtension ! 805: ============ ! 806: */ ! 807: void COM_StripExtension (char *in, char *out) ! 808: { ! 809: while (*in && *in != '.') ! 810: *out++ = *in++; ! 811: *out = 0; ! 812: } ! 813: ! 814: /* ! 815: ============ ! 816: COM_FileExtension ! 817: ============ ! 818: */ ! 819: char *COM_FileExtension (char *in) ! 820: { ! 821: static char exten[8]; ! 822: int i; ! 823: ! 824: while (*in && *in != '.') ! 825: in++; ! 826: if (!*in) ! 827: return ""; ! 828: in++; ! 829: for (i=0 ; i<7 && *in ; i++,in++) ! 830: exten[i] = *in; ! 831: exten[i] = 0; ! 832: return exten; ! 833: } ! 834: ! 835: /* ! 836: ============ ! 837: COM_FileBase ! 838: ============ ! 839: */ ! 840: void COM_FileBase (char *in, char *out) ! 841: { ! 842: char *s, *s2; ! 843: ! 844: s = in + strlen(in) - 1; ! 845: ! 846: while (s != in && *s != '.') ! 847: s--; ! 848: ! 849: for (s2 = s ; s2 != in && *s2 != '/' ; s2--) ! 850: ; ! 851: ! 852: if (s-s2 < 2) ! 853: out[0] = 0; ! 854: else ! 855: { ! 856: s--; ! 857: strncpy (out,s2+1, s-s2); ! 858: out[s-s2] = 0; ! 859: } ! 860: } ! 861: ! 862: /* ! 863: ============ ! 864: COM_FilePath ! 865: ! 866: Returns the path up to, but not including the last / ! 867: ============ ! 868: */ ! 869: void COM_FilePath (char *in, char *out) ! 870: { ! 871: char *s; ! 872: ! 873: s = in + strlen(in) - 1; ! 874: ! 875: while (s != in && *s != '/') ! 876: s--; ! 877: ! 878: strncpy (out,in, s-in); ! 879: out[s-in] = 0; ! 880: } ! 881: ! 882: ! 883: /* ! 884: ================== ! 885: COM_DefaultExtension ! 886: ================== ! 887: */ ! 888: void COM_DefaultExtension (char *path, char *extension) ! 889: { ! 890: char *src; ! 891: // ! 892: // if path doesn't have a .EXT, append extension ! 893: // (extension should include the .) ! 894: // ! 895: src = path + strlen(path) - 1; ! 896: ! 897: while (*src != '/' && src != path) ! 898: { ! 899: if (*src == '.') ! 900: return; // it has an extension ! 901: src--; ! 902: } ! 903: ! 904: strcat (path, extension); ! 905: } ! 906: ! 907: /* ! 908: ============================================================================ ! 909: ! 910: BYTE ORDER FUNCTIONS ! 911: ! 912: ============================================================================ ! 913: */ ! 914: ! 915: qboolean bigendien; ! 916: ! 917: // can't just use function pointers, or dll linkage can ! 918: // mess up when qcommon is included in multiple places ! 919: short (*_BigShort) (short l); ! 920: short (*_LittleShort) (short l); ! 921: int (*_BigLong) (int l); ! 922: int (*_LittleLong) (int l); ! 923: float (*_BigFloat) (float l); ! 924: float (*_LittleFloat) (float l); ! 925: ! 926: short BigShort(short l){return _BigShort(l);} ! 927: short LittleShort(short l) {return _LittleShort(l);} ! 928: int BigLong (int l) {return _BigLong(l);} ! 929: int LittleLong (int l) {return _LittleLong(l);} ! 930: float BigFloat (float l) {return _BigFloat(l);} ! 931: float LittleFloat (float l) {return _LittleFloat(l);} ! 932: ! 933: short ShortSwap (short l) ! 934: { ! 935: byte b1,b2; ! 936: ! 937: b1 = l&255; ! 938: b2 = (l>>8)&255; ! 939: ! 940: return (b1<<8) + b2; ! 941: } ! 942: ! 943: short ShortNoSwap (short l) ! 944: { ! 945: return l; ! 946: } ! 947: ! 948: int LongSwap (int l) ! 949: { ! 950: byte b1,b2,b3,b4; ! 951: ! 952: b1 = l&255; ! 953: b2 = (l>>8)&255; ! 954: b3 = (l>>16)&255; ! 955: b4 = (l>>24)&255; ! 956: ! 957: return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; ! 958: } ! 959: ! 960: int LongNoSwap (int l) ! 961: { ! 962: return l; ! 963: } ! 964: ! 965: float FloatSwap (float f) ! 966: { ! 967: union ! 968: { ! 969: float f; ! 970: byte b[4]; ! 971: } dat1, dat2; ! 972: ! 973: ! 974: dat1.f = f; ! 975: dat2.b[0] = dat1.b[3]; ! 976: dat2.b[1] = dat1.b[2]; ! 977: dat2.b[2] = dat1.b[1]; ! 978: dat2.b[3] = dat1.b[0]; ! 979: return dat2.f; ! 980: } ! 981: ! 982: float FloatNoSwap (float f) ! 983: { ! 984: return f; ! 985: } ! 986: ! 987: /* ! 988: ================ ! 989: Swap_Init ! 990: ================ ! 991: */ ! 992: void Swap_Init (void) ! 993: { ! 994: byte swaptest[2] = {1,0}; ! 995: ! 996: // set the byte swapping variables in a portable manner ! 997: if ( *(short *)swaptest == 1) ! 998: { ! 999: bigendien = false; ! 1000: _BigShort = ShortSwap; ! 1001: _LittleShort = ShortNoSwap; ! 1002: _BigLong = LongSwap; ! 1003: _LittleLong = LongNoSwap; ! 1004: _BigFloat = FloatSwap; ! 1005: _LittleFloat = FloatNoSwap; ! 1006: } ! 1007: else ! 1008: { ! 1009: bigendien = true; ! 1010: _BigShort = ShortNoSwap; ! 1011: _LittleShort = ShortSwap; ! 1012: _BigLong = LongNoSwap; ! 1013: _LittleLong = LongSwap; ! 1014: _BigFloat = FloatNoSwap; ! 1015: _LittleFloat = FloatSwap; ! 1016: } ! 1017: ! 1018: } ! 1019: ! 1020: ! 1021: ! 1022: /* ! 1023: ============ ! 1024: va ! 1025: ! 1026: does a varargs printf into a temp buffer, so I don't need to have ! 1027: varargs versions of all text functions. ! 1028: FIXME: make this buffer size safe someday ! 1029: ============ ! 1030: */ ! 1031: char *va(char *format, ...) ! 1032: { ! 1033: va_list argptr; ! 1034: static char string[1024]; ! 1035: ! 1036: va_start (argptr, format); ! 1037: vsprintf (string, format,argptr); ! 1038: va_end (argptr); ! 1039: ! 1040: return string; ! 1041: } ! 1042: ! 1043: ! 1044: char com_token[MAX_TOKEN_CHARS]; ! 1045: ! 1046: /* ! 1047: ============== ! 1048: COM_Parse ! 1049: ! 1050: Parse a token out of a string ! 1051: ============== ! 1052: */ ! 1053: char *COM_Parse (char **data_p) ! 1054: { ! 1055: int c; ! 1056: int len; ! 1057: char *data; ! 1058: ! 1059: data = *data_p; ! 1060: len = 0; ! 1061: com_token[0] = 0; ! 1062: ! 1063: if (!data) ! 1064: { ! 1065: *data_p = NULL; ! 1066: return ""; ! 1067: } ! 1068: ! 1069: // skip whitespace ! 1070: skipwhite: ! 1071: while ( (c = *data) <= ' ') ! 1072: { ! 1073: if (c == 0) ! 1074: { ! 1075: *data_p = NULL; ! 1076: return ""; ! 1077: } ! 1078: data++; ! 1079: } ! 1080: ! 1081: // skip // comments ! 1082: if (c=='/' && data[1] == '/') ! 1083: { ! 1084: while (*data && *data != '\n') ! 1085: data++; ! 1086: goto skipwhite; ! 1087: } ! 1088: ! 1089: // handle quoted strings specially ! 1090: if (c == '\"') ! 1091: { ! 1092: data++; ! 1093: while (1) ! 1094: { ! 1095: c = *data++; ! 1096: if (c=='\"' || !c) ! 1097: { ! 1098: com_token[len] = 0; ! 1099: *data_p = data; ! 1100: return com_token; ! 1101: } ! 1102: if (len < MAX_TOKEN_CHARS) ! 1103: { ! 1104: com_token[len] = c; ! 1105: len++; ! 1106: } ! 1107: } ! 1108: } ! 1109: ! 1110: // parse a regular word ! 1111: do ! 1112: { ! 1113: if (len < MAX_TOKEN_CHARS) ! 1114: { ! 1115: com_token[len] = c; ! 1116: len++; ! 1117: } ! 1118: data++; ! 1119: c = *data; ! 1120: } while (c>32); ! 1121: ! 1122: if (len == MAX_TOKEN_CHARS) ! 1123: { ! 1124: // Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS); ! 1125: len = 0; ! 1126: } ! 1127: com_token[len] = 0; ! 1128: ! 1129: *data_p = data; ! 1130: return com_token; ! 1131: } ! 1132: ! 1133: ! 1134: /* ! 1135: =============== ! 1136: Com_PageInMemory ! 1137: ! 1138: =============== ! 1139: */ ! 1140: int paged_total; ! 1141: ! 1142: void Com_PageInMemory (byte *buffer, int size) ! 1143: { ! 1144: int i; ! 1145: ! 1146: for (i=size-1 ; i>0 ; i-=4096) ! 1147: paged_total += buffer[i]; ! 1148: } ! 1149: ! 1150: ! 1151: ! 1152: /* ! 1153: ============================================================================ ! 1154: ! 1155: LIBRARY REPLACEMENT FUNCTIONS ! 1156: ! 1157: ============================================================================ ! 1158: */ ! 1159: ! 1160: // FIXME: replace all Q_stricmp with Q_strcasecmp ! 1161: int Q_stricmp (char *s1, char *s2) ! 1162: { ! 1163: #if defined(WIN32) ! 1164: return _stricmp (s1, s2); ! 1165: #else ! 1166: return strcasecmp (s1, s2); ! 1167: #endif ! 1168: } ! 1169: ! 1170: ! 1171: int Q_strncasecmp (char *s1, char *s2, int n) ! 1172: { ! 1173: int c1, c2; ! 1174: ! 1175: do ! 1176: { ! 1177: c1 = *s1++; ! 1178: c2 = *s2++; ! 1179: ! 1180: if (!n--) ! 1181: return 0; // strings are equal until end point ! 1182: ! 1183: if (c1 != c2) ! 1184: { ! 1185: if (c1 >= 'a' && c1 <= 'z') ! 1186: c1 -= ('a' - 'A'); ! 1187: if (c2 >= 'a' && c2 <= 'z') ! 1188: c2 -= ('a' - 'A'); ! 1189: if (c1 != c2) ! 1190: return -1; // strings not equal ! 1191: } ! 1192: } while (c1); ! 1193: ! 1194: return 0; // strings are equal ! 1195: } ! 1196: ! 1197: int Q_strcasecmp (char *s1, char *s2) ! 1198: { ! 1199: return Q_strncasecmp (s1, s2, 99999); ! 1200: } ! 1201: ! 1202: ! 1203: ! 1204: void Com_sprintf (char *dest, int size, char *fmt, ...) ! 1205: { ! 1206: int len; ! 1207: va_list argptr; ! 1208: char bigbuffer[0x10000]; ! 1209: ! 1210: va_start (argptr,fmt); ! 1211: len = vsprintf (bigbuffer,fmt,argptr); ! 1212: va_end (argptr); ! 1213: if (len >= size) ! 1214: Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size); ! 1215: strncpy (dest, bigbuffer, size-1); ! 1216: } ! 1217: ! 1218: /* ! 1219: ===================================================================== ! 1220: ! 1221: INFO STRINGS ! 1222: ! 1223: ===================================================================== ! 1224: */ ! 1225: ! 1226: /* ! 1227: =============== ! 1228: Info_ValueForKey ! 1229: ! 1230: Searches the string for the given ! 1231: key and returns the associated value, or an empty string. ! 1232: =============== ! 1233: */ ! 1234: char *Info_ValueForKey (char *s, char *key) ! 1235: { ! 1236: char pkey[512]; ! 1237: static char value[2][512]; // use two buffers so compares ! 1238: // work without stomping on each other ! 1239: static int valueindex; ! 1240: char *o; ! 1241: ! 1242: valueindex ^= 1; ! 1243: if (*s == '\\') ! 1244: s++; ! 1245: while (1) ! 1246: { ! 1247: o = pkey; ! 1248: while (*s != '\\') ! 1249: { ! 1250: if (!*s) ! 1251: return ""; ! 1252: *o++ = *s++; ! 1253: } ! 1254: *o = 0; ! 1255: s++; ! 1256: ! 1257: o = value[valueindex]; ! 1258: ! 1259: while (*s != '\\' && *s) ! 1260: { ! 1261: if (!*s) ! 1262: return ""; ! 1263: *o++ = *s++; ! 1264: } ! 1265: *o = 0; ! 1266: ! 1267: if (!strcmp (key, pkey) ) ! 1268: return value[valueindex]; ! 1269: ! 1270: if (!*s) ! 1271: return ""; ! 1272: s++; ! 1273: } ! 1274: } ! 1275: ! 1276: void Info_RemoveKey (char *s, char *key) ! 1277: { ! 1278: char *start; ! 1279: char pkey[512]; ! 1280: char value[512]; ! 1281: char *o; ! 1282: ! 1283: if (strstr (key, "\\")) ! 1284: { ! 1285: // Com_Printf ("Can't use a key with a \\\n"); ! 1286: return; ! 1287: } ! 1288: ! 1289: while (1) ! 1290: { ! 1291: start = s; ! 1292: if (*s == '\\') ! 1293: s++; ! 1294: o = pkey; ! 1295: while (*s != '\\') ! 1296: { ! 1297: if (!*s) ! 1298: return; ! 1299: *o++ = *s++; ! 1300: } ! 1301: *o = 0; ! 1302: s++; ! 1303: ! 1304: o = value; ! 1305: while (*s != '\\' && *s) ! 1306: { ! 1307: if (!*s) ! 1308: return; ! 1309: *o++ = *s++; ! 1310: } ! 1311: *o = 0; ! 1312: ! 1313: if (!strcmp (key, pkey) ) ! 1314: { ! 1315: strcpy (start, s); // remove this part ! 1316: return; ! 1317: } ! 1318: ! 1319: if (!*s) ! 1320: return; ! 1321: } ! 1322: ! 1323: } ! 1324: ! 1325: ! 1326: /* ! 1327: ================== ! 1328: Info_Validate ! 1329: ! 1330: Some characters are illegal in info strings because they ! 1331: can mess up the server's parsing ! 1332: ================== ! 1333: */ ! 1334: qboolean Info_Validate (char *s) ! 1335: { ! 1336: if (strstr (s, "\"")) ! 1337: return false; ! 1338: if (strstr (s, ";")) ! 1339: return false; ! 1340: return true; ! 1341: } ! 1342: ! 1343: void Info_SetValueForKey (char *s, char *key, char *value) ! 1344: { ! 1345: char newi[MAX_INFO_STRING], *v; ! 1346: int c; ! 1347: int maxsize = MAX_INFO_STRING; ! 1348: ! 1349: if (strstr (key, "\\") || strstr (value, "\\") ) ! 1350: { ! 1351: Com_Printf ("Can't use keys or values with a \\\n"); ! 1352: return; ! 1353: } ! 1354: ! 1355: if (strstr (key, ";") ) ! 1356: { ! 1357: Com_Printf ("Can't use keys or values with a semicolon\n"); ! 1358: return; ! 1359: } ! 1360: ! 1361: if (strstr (key, "\"") || strstr (value, "\"") ) ! 1362: { ! 1363: Com_Printf ("Can't use keys or values with a \"\n"); ! 1364: return; ! 1365: } ! 1366: ! 1367: if (strlen(key) > MAX_INFO_KEY-1 || strlen(value) > MAX_INFO_KEY-1) ! 1368: { ! 1369: Com_Printf ("Keys and values must be < 64 characters.\n"); ! 1370: return; ! 1371: } ! 1372: Info_RemoveKey (s, key); ! 1373: if (!value || !strlen(value)) ! 1374: return; ! 1375: ! 1376: Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value); ! 1377: ! 1378: if (strlen(newi) + strlen(s) > maxsize) ! 1379: { ! 1380: Com_Printf ("Info string length exceeded\n"); ! 1381: return; ! 1382: } ! 1383: ! 1384: // only copy ascii values ! 1385: s += strlen(s); ! 1386: v = newi; ! 1387: while (*v) ! 1388: { ! 1389: c = *v++; ! 1390: c &= 127; // strip high bits ! 1391: if (c >= 32 && c < 127) ! 1392: *s++ = c; ! 1393: } ! 1394: *s = 0; ! 1395: } ! 1396: ! 1397: //==================================================================== ! 1398: ! 1399:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.