Annotation of quake2/xatrix/q_shared.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.