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

unix.superglobalmegacorp.com

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