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