home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / q_shared.c < prev    next >
C/C++ Source or Header  |  1997-11-23  |  20KB  |  1,146 lines

  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. int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
  330. {
  331.     float    dist1, dist2;
  332.     int        sides;
  333.  
  334. // fast axial cases
  335.     if (p->type < 3)
  336.     {
  337.         if (p->dist <= emins[p->type])
  338.             return 1;
  339.         if (p->dist >= emaxs[p->type])
  340.             return 2;
  341.         return 3;
  342.     }
  343.     
  344. // general case
  345.     switch (p->signbits)
  346.     {
  347.     case 0:
  348. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  349. dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  350.         break;
  351.     case 1:
  352. dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  353. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  354.         break;
  355.     case 2:
  356. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  357. dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  358.         break;
  359.     case 3:
  360. dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  361. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  362.         break;
  363.     case 4:
  364. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  365. dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  366.         break;
  367.     case 5:
  368. dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  369. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  370.         break;
  371.     case 6:
  372. dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  373. dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  374.         break;
  375.     case 7:
  376. dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  377. dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  378.         break;
  379.     default:
  380.         dist1 = dist2 = 0;        // shut up compiler
  381.         assert( 1 );
  382.         break;
  383.     }
  384.  
  385.     sides = 0;
  386.     if (dist1 >= p->dist)
  387.         sides = 1;
  388.     if (dist2 < p->dist)
  389.         sides |= 2;
  390.  
  391.     assert( sides != 0 );
  392.  
  393.     return sides;
  394. }
  395.  
  396.  
  397. void ClearBounds (vec3_t mins, vec3_t maxs)
  398. {
  399.     mins[0] = mins[1] = mins[2] = 99999;
  400.     maxs[0] = maxs[1] = maxs[2] = -99999;
  401. }
  402.  
  403. void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs)
  404. {
  405.     int        i;
  406.     vec_t    val;
  407.  
  408.     for (i=0 ; i<3 ; i++)
  409.     {
  410.         val = v[i];
  411.         if (val < mins[i])
  412.             mins[i] = val;
  413.         if (val > maxs[i])
  414.             maxs[i] = val;
  415.     }
  416. }
  417.  
  418.  
  419. int VectorCompare (vec3_t v1, vec3_t v2)
  420. {
  421.     if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2])
  422.             return 0;
  423.             
  424.     return 1;
  425. }
  426.  
  427.  
  428. vec_t VectorNormalize (vec3_t v)
  429. {
  430.     float    length, ilength;
  431.  
  432.     length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  433.     length = sqrt (length);        // FIXME
  434.  
  435.     if (length)
  436.     {
  437.         ilength = 1/length;
  438.         v[0] *= ilength;
  439.         v[1] *= ilength;
  440.         v[2] *= ilength;
  441.     }
  442.         
  443.     return length;
  444.  
  445. }
  446.  
  447. vec_t VectorNormalize2 (vec3_t v, vec3_t out)
  448. {
  449.     float    length, ilength;
  450.  
  451.     length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  452.     length = sqrt (length);        // FIXME
  453.  
  454.     if (length)
  455.     {
  456.         ilength = 1/length;
  457.         out[0] = v[0]*ilength;
  458.         out[1] = v[1]*ilength;
  459.         out[2] = v[2]*ilength;
  460.     }
  461.         
  462.     return length;
  463.  
  464. }
  465.  
  466. void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
  467. {
  468.     vecc[0] = veca[0] + scale*vecb[0];
  469.     vecc[1] = veca[1] + scale*vecb[1];
  470.     vecc[2] = veca[2] + scale*vecb[2];
  471. }
  472.  
  473.  
  474. vec_t _DotProduct (vec3_t v1, vec3_t v2)
  475. {
  476.     return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
  477. }
  478.  
  479. void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out)
  480. {
  481.     out[0] = veca[0]-vecb[0];
  482.     out[1] = veca[1]-vecb[1];
  483.     out[2] = veca[2]-vecb[2];
  484. }
  485.  
  486. void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out)
  487. {
  488.     out[0] = veca[0]+vecb[0];
  489.     out[1] = veca[1]+vecb[1];
  490.     out[2] = veca[2]+vecb[2];
  491. }
  492.  
  493. void _VectorCopy (vec3_t in, vec3_t out)
  494. {
  495.     out[0] = in[0];
  496.     out[1] = in[1];
  497.     out[2] = in[2];
  498. }
  499.  
  500. void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
  501. {
  502.     cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
  503.     cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
  504.     cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
  505. }
  506.  
  507. double sqrt(double x);
  508.  
  509. vec_t VectorLength(vec3_t v)
  510. {
  511.     int        i;
  512.     float    length;
  513.     
  514.     length = 0;
  515.     for (i=0 ; i< 3 ; i++)
  516.         length += v[i]*v[i];
  517.     length = sqrt (length);        // FIXME
  518.  
  519.     return length;
  520. }
  521.  
  522. void VectorInverse (vec3_t v)
  523. {
  524.     v[0] = -v[0];
  525.     v[1] = -v[1];
  526.     v[2] = -v[2];
  527. }
  528.  
  529. void VectorScale (vec3_t in, vec_t scale, vec3_t out)
  530. {
  531.     out[0] = in[0]*scale;
  532.     out[1] = in[1]*scale;
  533.     out[2] = in[2]*scale;
  534. }
  535.  
  536.  
  537. int Q_log2(int val)
  538. {
  539.     int answer=0;
  540.     while (val>>=1)
  541.         answer++;
  542.     return answer;
  543. }
  544.  
  545.  
  546.  
  547. //====================================================================================
  548.  
  549. /*
  550. ============
  551. COM_SkipPath
  552. ============
  553. */
  554. char *COM_SkipPath (char *pathname)
  555. {
  556.     char    *last;
  557.     
  558.     last = pathname;
  559.     while (*pathname)
  560.     {
  561.         if (*pathname=='/')
  562.             last = pathname+1;
  563.         pathname++;
  564.     }
  565.     return last;
  566. }
  567.  
  568. /*
  569. ============
  570. COM_StripExtension
  571. ============
  572. */
  573. void COM_StripExtension (char *in, char *out)
  574. {
  575.     while (*in && *in != '.')
  576.         *out++ = *in++;
  577.     *out = 0;
  578. }
  579.  
  580. /*
  581. ============
  582. COM_FileExtension
  583. ============
  584. */
  585. char *COM_FileExtension (char *in)
  586. {
  587.     static char exten[8];
  588.     int        i;
  589.  
  590.     while (*in && *in != '.')
  591.         in++;
  592.     if (!*in)
  593.         return "";
  594.     in++;
  595.     for (i=0 ; i<7 && *in ; i++,in++)
  596.         exten[i] = *in;
  597.     exten[i] = 0;
  598.     return exten;
  599. }
  600.  
  601. /*
  602. ============
  603. COM_FileBase
  604. ============
  605. */
  606. void COM_FileBase (char *in, char *out)
  607. {
  608.     char *s, *s2;
  609.     
  610.     s = in + strlen(in) - 1;
  611.     
  612.     while (s != in && *s != '.')
  613.         s--;
  614.     
  615.     for (s2 = s ; s2 != in && *s2 != '/' ; s2--)
  616.     ;
  617.     
  618.     if (s-s2 < 2)
  619.         out[0] = 0;
  620.     else
  621.     {
  622.         s--;
  623.         strncpy (out,s2+1, s-s2);
  624.         out[s-s2] = 0;
  625.     }
  626. }
  627.  
  628. /*
  629. ============
  630. COM_FilePath
  631.  
  632. Returns the path up to, but not including the last /
  633. ============
  634. */
  635. void COM_FilePath (char *in, char *out)
  636. {
  637.     char *s;
  638.     
  639.     s = in + strlen(in) - 1;
  640.     
  641.     while (s != in && *s != '/')
  642.         s--;
  643.  
  644.     strncpy (out,in, s-in);
  645.     out[s-in] = 0;
  646. }
  647.  
  648.  
  649. /*
  650. ==================
  651. COM_DefaultExtension
  652. ==================
  653. */
  654. void COM_DefaultExtension (char *path, char *extension)
  655. {
  656.     char    *src;
  657. //
  658. // if path doesn't have a .EXT, append extension
  659. // (extension should include the .)
  660. //
  661.     src = path + strlen(path) - 1;
  662.  
  663.     while (*src != '/' && src != path)
  664.     {
  665.         if (*src == '.')
  666.             return;                 // it has an extension
  667.         src--;
  668.     }
  669.  
  670.     strcat (path, extension);
  671. }
  672.  
  673. /*
  674. ============================================================================
  675.  
  676.                     BYTE ORDER FUNCTIONS
  677.  
  678. ============================================================================
  679. */
  680.  
  681. qboolean    bigendien;
  682.  
  683. // can't just use function pointers, or dll linkage can
  684. // mess up when qcommon is included in multiple places
  685. short    (*_BigShort) (short l);
  686. short    (*_LittleShort) (short l);
  687. int        (*_BigLong) (int l);
  688. int        (*_LittleLong) (int l);
  689. float    (*_BigFloat) (float l);
  690. float    (*_LittleFloat) (float l);
  691.  
  692. short    BigShort(short l){return _BigShort(l);}
  693. short    LittleShort(short l) {return _LittleShort(l);}
  694. int        BigLong (int l) {return _BigLong(l);}
  695. int        LittleLong (int l) {return _LittleLong(l);}
  696. float    BigFloat (float l) {return _BigFloat(l);}
  697. float    LittleFloat (float l) {return _LittleFloat(l);}
  698.  
  699. short   ShortSwap (short l)
  700. {
  701.     byte    b1,b2;
  702.  
  703.     b1 = l&255;
  704.     b2 = (l>>8)&255;
  705.  
  706.     return (b1<<8) + b2;
  707. }
  708.  
  709. short    ShortNoSwap (short l)
  710. {
  711.     return l;
  712. }
  713.  
  714. int    LongSwap (int l)
  715. {
  716.     byte    b1,b2,b3,b4;
  717.  
  718.     b1 = l&255;
  719.     b2 = (l>>8)&255;
  720.     b3 = (l>>16)&255;
  721.     b4 = (l>>24)&255;
  722.  
  723.     return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
  724. }
  725.  
  726. int    LongNoSwap (int l)
  727. {
  728.     return l;
  729. }
  730.  
  731. float FloatSwap (float f)
  732. {
  733.     union
  734.     {
  735.         float    f;
  736.         byte    b[4];
  737.     } dat1, dat2;
  738.     
  739.     
  740.     dat1.f = f;
  741.     dat2.b[0] = dat1.b[3];
  742.     dat2.b[1] = dat1.b[2];
  743.     dat2.b[2] = dat1.b[1];
  744.     dat2.b[3] = dat1.b[0];
  745.     return dat2.f;
  746. }
  747.  
  748. float FloatNoSwap (float f)
  749. {
  750.     return f;
  751. }
  752.  
  753. /*
  754. ================
  755. Swap_Init
  756. ================
  757. */
  758. void Swap_Init (void)
  759. {
  760.     byte    swaptest[2] = {1,0};
  761.  
  762. // set the byte swapping variables in a portable manner    
  763.     if ( *(short *)swaptest == 1)
  764.     {
  765.         bigendien = false;
  766.         _BigShort = ShortSwap;
  767.         _LittleShort = ShortNoSwap;
  768.         _BigLong = LongSwap;
  769.         _LittleLong = LongNoSwap;
  770.         _BigFloat = FloatSwap;
  771.         _LittleFloat = FloatNoSwap;
  772.     }
  773.     else
  774.     {
  775.         bigendien = true;
  776.         _BigShort = ShortNoSwap;
  777.         _LittleShort = ShortSwap;
  778.         _BigLong = LongNoSwap;
  779.         _LittleLong = LongSwap;
  780.         _BigFloat = FloatNoSwap;
  781.         _LittleFloat = FloatSwap;
  782.     }
  783.  
  784. }
  785.  
  786.  
  787.  
  788. /*
  789. ============
  790. va
  791.  
  792. does a varargs printf into a temp buffer, so I don't need to have
  793. varargs versions of all text functions.
  794. FIXME: make this buffer size safe someday
  795. ============
  796. */
  797. char    *va(char *format, ...)
  798. {
  799.     va_list        argptr;
  800.     static char        string[1024];
  801.     
  802.     va_start (argptr, format);
  803.     vsprintf (string, format,argptr);
  804.     va_end (argptr);
  805.  
  806.     return string;    
  807. }
  808.  
  809.  
  810. char    com_token[MAX_TOKEN_CHARS];
  811.  
  812. /*
  813. ==============
  814. COM_Parse
  815.  
  816. Parse a token out of a string
  817. ==============
  818. */
  819. char *COM_Parse (char **data_p)
  820. {
  821.     int        c;
  822.     int        len;
  823.     char    *data;
  824.  
  825.     data = *data_p;
  826.     len = 0;
  827.     com_token[0] = 0;
  828.     
  829.     if (!data)
  830.     {
  831.         *data_p = NULL;
  832.         return "";
  833.     }
  834.         
  835. // skip whitespace
  836. skipwhite:
  837.     while ( (c = *data) <= ' ')
  838.     {
  839.         if (c == 0)
  840.         {
  841.             *data_p = NULL;
  842.             return "";
  843.         }
  844.         data++;
  845.     }
  846.     
  847. // skip // comments
  848.     if (c=='/' && data[1] == '/')
  849.     {
  850.         while (*data && *data != '\n')
  851.             data++;
  852.         goto skipwhite;
  853.     }
  854.     
  855.  
  856. // handle quoted strings specially
  857.     if (c == '\"')
  858.     {
  859.         data++;
  860.         while (1)
  861.         {
  862.             c = *data++;
  863.             if (c=='\"' || !c)
  864.             {
  865.                 com_token[len] = 0;
  866.                 *data_p = data;
  867.                 return com_token;
  868.             }
  869.             if (len < MAX_TOKEN_CHARS)
  870.             {
  871.                 com_token[len] = c;
  872.                 len++;
  873.             }
  874.         }
  875.     }
  876.  
  877. // parse a regular word
  878.     do
  879.     {
  880.         if (len < MAX_TOKEN_CHARS)
  881.         {
  882.             com_token[len] = c;
  883.             len++;
  884.         }
  885.         data++;
  886.         c = *data;
  887.     } while (c>32);
  888.  
  889.     if (len == MAX_TOKEN_CHARS)
  890.     {
  891. //        Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
  892.         len = 0;
  893.     }
  894.     com_token[len] = 0;
  895.  
  896.     *data_p = data;
  897.     return com_token;
  898. }
  899.  
  900.  
  901. /*
  902. ===============
  903. Com_PageInMemory
  904.  
  905. ===============
  906. */
  907. int    paged_total;
  908.  
  909. void Com_PageInMemory (byte *buffer, int size)
  910. {
  911.     int        i;
  912.  
  913.     for (i=size-1 ; i>0 ; i-=4096)
  914.         paged_total += buffer[i];
  915. }
  916.  
  917.  
  918.  
  919. /*
  920. ============================================================================
  921.  
  922.                     LIBRARY REPLACEMENT FUNCTIONS
  923.  
  924. ============================================================================
  925. */
  926.  
  927. // FIXME: replace all Q_stricmp with Q_strcasecmp
  928. int Q_stricmp (char *s1, char *s2)
  929. {
  930. #if defined(IRIX)
  931.     return strcmp (s1, s2);
  932. #elif defined(WIN32)
  933.     return _stricmp (s1, s2);
  934. #else
  935.     return stricmp (s1, s2);
  936. #endif
  937. }
  938.  
  939.  
  940. int Q_strncasecmp (char *s1, char *s2, int n)
  941. {
  942.     int        c1, c2;
  943.     
  944.     do
  945.     {
  946.         c1 = *s1++;
  947.         c2 = *s2++;
  948.  
  949.         if (!n--)
  950.             return 0;        // strings are equal until end point
  951.         
  952.         if (c1 != c2)
  953.         {
  954.             if (c1 >= 'a' && c1 <= 'z')
  955.                 c1 -= ('a' - 'A');
  956.             if (c2 >= 'a' && c2 <= 'z')
  957.                 c2 -= ('a' - 'A');
  958.             if (c1 != c2)
  959.                 return -1;        // strings not equal
  960.         }
  961.     } while (c1);
  962.     
  963.     return 0;        // strings are equal
  964. }
  965.  
  966. int Q_strcasecmp (char *s1, char *s2)
  967. {
  968.     return Q_strncasecmp (s1, s2, 99999);
  969. }
  970.  
  971.  
  972.  
  973. void Com_sprintf (char *dest, int size, char *fmt, ...)
  974. {
  975.     char    bigbuffer[0x10000];
  976.     int        len;
  977.     va_list        argptr;
  978.  
  979.     va_start (argptr,fmt);
  980.     len = vsprintf (bigbuffer,fmt,argptr);
  981.     va_end (argptr);
  982.     if (len >= size)
  983.         Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
  984.     strncpy (dest, bigbuffer, size-1);
  985. }
  986.  
  987. /*
  988. =====================================================================
  989.  
  990.   INFO STRINGS
  991.  
  992. =====================================================================
  993. */
  994.  
  995. /*
  996. ===============
  997. Info_ValueForKey
  998.  
  999. Searches the string for the given
  1000. key and returns the associated value, or an empty string.
  1001. ===============
  1002. */
  1003. char *Info_ValueForKey (char *s, char *key)
  1004. {
  1005.     char    pkey[512];
  1006.     static    char value[2][512];    // use two buffers so compares
  1007.                                 // work without stomping on each other
  1008.     static    int    valueindex;
  1009.     char    *o;
  1010.     
  1011.     valueindex ^= 1;
  1012.     if (*s == '\\')
  1013.         s++;
  1014.     while (1)
  1015.     {
  1016.         o = pkey;
  1017.         while (*s != '\\')
  1018.         {
  1019.             if (!*s)
  1020.                 return "";
  1021.             *o++ = *s++;
  1022.         }
  1023.         *o = 0;
  1024.         s++;
  1025.  
  1026.         o = value[valueindex];
  1027.  
  1028.         while (*s != '\\' && *s)
  1029.         {
  1030.             if (!*s)
  1031.                 return "";
  1032.             *o++ = *s++;
  1033.         }
  1034.         *o = 0;
  1035.  
  1036.         if (!strcmp (key, pkey) )
  1037.             return value[valueindex];
  1038.  
  1039.         if (!*s)
  1040.             return "";
  1041.         s++;
  1042.     }
  1043. }
  1044.  
  1045. void Info_RemoveKey (char *s, char *key)
  1046. {
  1047.     char    *start;
  1048.     char    pkey[512];
  1049.     char    value[512];
  1050.     char    *o;
  1051.  
  1052.     if (strstr (key, "\\"))
  1053.     {
  1054. //        Com_Printf ("Can't use a key with a \\\n");
  1055.         return;
  1056.     }
  1057.  
  1058.     while (1)
  1059.     {
  1060.         start = s;
  1061.         if (*s == '\\')
  1062.             s++;
  1063.         o = pkey;
  1064.         while (*s != '\\')
  1065.         {
  1066.             if (!*s)
  1067.                 return;
  1068.             *o++ = *s++;
  1069.         }
  1070.         *o = 0;
  1071.         s++;
  1072.  
  1073.         o = value;
  1074.         while (*s != '\\' && *s)
  1075.         {
  1076.             if (!*s)
  1077.                 return;
  1078.             *o++ = *s++;
  1079.         }
  1080.         *o = 0;
  1081.  
  1082.         if (!strcmp (key, pkey) )
  1083.         {
  1084.             strcpy (start, s);    // remove this part
  1085.             return;
  1086.         }
  1087.  
  1088.         if (!*s)
  1089.             return;
  1090.     }
  1091.  
  1092. }
  1093.  
  1094.  
  1095. void Info_SetValueForKey (char *s, char *key, char *value)
  1096. {
  1097.     char    newi[MAX_INFO_STRING], *v;
  1098.     int        c;
  1099.     int        maxsize = MAX_INFO_STRING;
  1100.  
  1101.     if (strstr (key, "\\") || strstr (value, "\\") )
  1102.     {
  1103.         Com_Printf ("Can't use keys or values with a \\\n");
  1104.         return;
  1105.     }
  1106.  
  1107.     if (strstr (key, "\"") || strstr (value, "\"") )
  1108.     {
  1109.         Com_Printf ("Can't use keys or values with a \"\n");
  1110.         return;
  1111.     }
  1112.  
  1113.     if (strlen(key) > MAX_INFO_KEY-1 || strlen(value) > MAX_INFO_KEY-1)
  1114.     {
  1115.         Com_Printf ("Keys and values must be < 64 characters.\n");
  1116.         return;
  1117.     }
  1118.     Info_RemoveKey (s, key);
  1119.     if (!value || !strlen(value))
  1120.         return;
  1121.  
  1122.     Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
  1123.  
  1124.     if (strlen(newi) + strlen(s) > maxsize)
  1125.     {
  1126.         Com_Printf ("Info string length exceeded\n");
  1127.         return;
  1128.     }
  1129.  
  1130.     // only copy ascii values
  1131.     s += strlen(s);
  1132.     v = newi;
  1133.     while (*v)
  1134.     {
  1135.         c = *v++;
  1136.         c &= 127;        // strip high bits
  1137.         if (c >= 32 && c < 127)
  1138.             *s++ = c;
  1139.     }
  1140.     *s = 0;
  1141. }
  1142.  
  1143. //====================================================================
  1144.  
  1145.  
  1146.