Annotation of quake2/ctf/q_shared.c, revision 1.1.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
                    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: 
                   1090: // handle quoted strings specially
                   1091:        if (c == '\"')
                   1092:        {
                   1093:                data++;
                   1094:                while (1)
                   1095:                {
                   1096:                        c = *data++;
                   1097:                        if (c=='\"' || !c)
                   1098:                        {
                   1099:                                com_token[len] = 0;
                   1100:                                *data_p = data;
                   1101:                                return com_token;
                   1102:                        }
                   1103:                        if (len < MAX_TOKEN_CHARS)
                   1104:                        {
                   1105:                                com_token[len] = c;
                   1106:                                len++;
                   1107:                        }
                   1108:                }
                   1109:        }
                   1110: 
                   1111: // parse a regular word
                   1112:        do
                   1113:        {
                   1114:                if (len < MAX_TOKEN_CHARS)
                   1115:                {
                   1116:                        com_token[len] = c;
                   1117:                        len++;
                   1118:                }
                   1119:                data++;
                   1120:                c = *data;
                   1121:        } while (c>32);
                   1122: 
                   1123:        if (len == MAX_TOKEN_CHARS)
                   1124:        {
                   1125: //             Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
                   1126:                len = 0;
                   1127:        }
                   1128:        com_token[len] = 0;
                   1129: 
                   1130:        *data_p = data;
                   1131:        return com_token;
                   1132: }
                   1133: 
                   1134: 
                   1135: /*
                   1136: ===============
                   1137: Com_PageInMemory
                   1138: 
                   1139: ===============
                   1140: */
                   1141: int    paged_total;
                   1142: 
                   1143: void Com_PageInMemory (byte *buffer, int size)
                   1144: {
                   1145:        int             i;
                   1146: 
                   1147:        for (i=size-1 ; i>0 ; i-=4096)
                   1148:                paged_total += buffer[i];
                   1149: }
                   1150: 
                   1151: 
                   1152: 
                   1153: /*
                   1154: ============================================================================
                   1155: 
                   1156:                                        LIBRARY REPLACEMENT FUNCTIONS
                   1157: 
                   1158: ============================================================================
                   1159: */
                   1160: 
                   1161: // FIXME: replace all Q_stricmp with Q_strcasecmp
                   1162: int Q_stricmp (char *s1, char *s2)
                   1163: {
                   1164: #if defined(WIN32)
                   1165:        return _stricmp (s1, s2);
                   1166: #else
                   1167:        return strcasecmp (s1, s2);
                   1168: #endif
                   1169: }
                   1170: 
                   1171: 
                   1172: int Q_strncasecmp (char *s1, char *s2, int n)
                   1173: {
                   1174:        int             c1, c2;
                   1175:        
                   1176:        do
                   1177:        {
                   1178:                c1 = *s1++;
                   1179:                c2 = *s2++;
                   1180: 
                   1181:                if (!n--)
                   1182:                        return 0;               // strings are equal until end point
                   1183:                
                   1184:                if (c1 != c2)
                   1185:                {
                   1186:                        if (c1 >= 'a' && c1 <= 'z')
                   1187:                                c1 -= ('a' - 'A');
                   1188:                        if (c2 >= 'a' && c2 <= 'z')
                   1189:                                c2 -= ('a' - 'A');
                   1190:                        if (c1 != c2)
                   1191:                                return -1;              // strings not equal
                   1192:                }
                   1193:        } while (c1);
                   1194:        
                   1195:        return 0;               // strings are equal
                   1196: }
                   1197: 
                   1198: int Q_strcasecmp (char *s1, char *s2)
                   1199: {
                   1200:        return Q_strncasecmp (s1, s2, 99999);
                   1201: }
                   1202: 
                   1203: 
                   1204: 
                   1205: void Com_sprintf (char *dest, int size, char *fmt, ...)
                   1206: {
                   1207:        int             len;
                   1208:        va_list         argptr;
                   1209:        char    bigbuffer[0x10000];
                   1210: 
                   1211:        va_start (argptr,fmt);
                   1212:        len = vsprintf (bigbuffer,fmt,argptr);
                   1213:        va_end (argptr);
                   1214:        if (len >= size)
                   1215:                Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
                   1216:        strncpy (dest, bigbuffer, size-1);
                   1217: }
                   1218: 
                   1219: /*
                   1220: =====================================================================
                   1221: 
                   1222:   INFO STRINGS
                   1223: 
                   1224: =====================================================================
                   1225: */
                   1226: 
                   1227: /*
                   1228: ===============
                   1229: Info_ValueForKey
                   1230: 
                   1231: Searches the string for the given
                   1232: key and returns the associated value, or an empty string.
                   1233: ===============
                   1234: */
                   1235: char *Info_ValueForKey (char *s, char *key)
                   1236: {
                   1237:        char    pkey[512];
                   1238:        static  char value[2][512];     // use two buffers so compares
                   1239:                                                                // work without stomping on each other
                   1240:        static  int     valueindex;
                   1241:        char    *o;
                   1242:        
                   1243:        valueindex ^= 1;
                   1244:        if (*s == '\\')
                   1245:                s++;
                   1246:        while (1)
                   1247:        {
                   1248:                o = pkey;
                   1249:                while (*s != '\\')
                   1250:                {
                   1251:                        if (!*s)
                   1252:                                return "";
                   1253:                        *o++ = *s++;
                   1254:                }
                   1255:                *o = 0;
                   1256:                s++;
                   1257: 
                   1258:                o = value[valueindex];
                   1259: 
                   1260:                while (*s != '\\' && *s)
                   1261:                {
                   1262:                        if (!*s)
                   1263:                                return "";
                   1264:                        *o++ = *s++;
                   1265:                }
                   1266:                *o = 0;
                   1267: 
                   1268:                if (!strcmp (key, pkey) )
                   1269:                        return value[valueindex];
                   1270: 
                   1271:                if (!*s)
                   1272:                        return "";
                   1273:                s++;
                   1274:        }
                   1275: }
                   1276: 
                   1277: void Info_RemoveKey (char *s, char *key)
                   1278: {
                   1279:        char    *start;
                   1280:        char    pkey[512];
                   1281:        char    value[512];
                   1282:        char    *o;
                   1283: 
                   1284:        if (strstr (key, "\\"))
                   1285:        {
                   1286: //             Com_Printf ("Can't use a key with a \\\n");
                   1287:                return;
                   1288:        }
                   1289: 
                   1290:        while (1)
                   1291:        {
                   1292:                start = s;
                   1293:                if (*s == '\\')
                   1294:                        s++;
                   1295:                o = pkey;
                   1296:                while (*s != '\\')
                   1297:                {
                   1298:                        if (!*s)
                   1299:                                return;
                   1300:                        *o++ = *s++;
                   1301:                }
                   1302:                *o = 0;
                   1303:                s++;
                   1304: 
                   1305:                o = value;
                   1306:                while (*s != '\\' && *s)
                   1307:                {
                   1308:                        if (!*s)
                   1309:                                return;
                   1310:                        *o++ = *s++;
                   1311:                }
                   1312:                *o = 0;
                   1313: 
                   1314:                if (!strcmp (key, pkey) )
                   1315:                {
                   1316:                        strcpy (start, s);      // remove this part
                   1317:                        return;
                   1318:                }
                   1319: 
                   1320:                if (!*s)
                   1321:                        return;
                   1322:        }
                   1323: 
                   1324: }
                   1325: 
                   1326: 
                   1327: /*
                   1328: ==================
                   1329: Info_Validate
                   1330: 
                   1331: Some characters are illegal in info strings because they
                   1332: can mess up the server's parsing
                   1333: ==================
                   1334: */
                   1335: qboolean Info_Validate (char *s)
                   1336: {
                   1337:        if (strstr (s, "\""))
                   1338:                return false;
                   1339:        if (strstr (s, ";"))
                   1340:                return false;
                   1341:        return true;
                   1342: }
                   1343: 
                   1344: void Info_SetValueForKey (char *s, char *key, char *value)
                   1345: {
                   1346:        char    newi[MAX_INFO_STRING], *v;
                   1347:        int             c;
                   1348:        int             maxsize = MAX_INFO_STRING;
                   1349: 
                   1350:        if (strstr (key, "\\") || strstr (value, "\\") )
                   1351:        {
                   1352:                Com_Printf ("Can't use keys or values with a \\\n");
                   1353:                return;
                   1354:        }
                   1355: 
                   1356:        if (strstr (key, ";") )
                   1357:        {
                   1358:                Com_Printf ("Can't use keys or values with a semicolon\n");
                   1359:                return;
                   1360:        }
                   1361: 
                   1362:        if (strstr (key, "\"") || strstr (value, "\"") )
                   1363:        {
                   1364:                Com_Printf ("Can't use keys or values with a \"\n");
                   1365:                return;
                   1366:        }
                   1367: 
                   1368:        if (strlen(key) > MAX_INFO_KEY-1 || strlen(value) > MAX_INFO_KEY-1)
                   1369:        {
                   1370:                Com_Printf ("Keys and values must be < 64 characters.\n");
                   1371:                return;
                   1372:        }
                   1373:        Info_RemoveKey (s, key);
                   1374:        if (!value || !strlen(value))
                   1375:                return;
                   1376: 
                   1377:        Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
                   1378: 
                   1379:        if (strlen(newi) + strlen(s) > maxsize)
                   1380:        {
                   1381:                Com_Printf ("Info string length exceeded\n");
                   1382:                return;
                   1383:        }
                   1384: 
                   1385:        // only copy ascii values
                   1386:        s += strlen(s);
                   1387:        v = newi;
                   1388:        while (*v)
                   1389:        {
                   1390:                c = *v++;
                   1391:                c &= 127;               // strip high bits
                   1392:                if (c >= 32 && c < 127)
                   1393:                        *s++ = c;
                   1394:        }
                   1395:        *s = 0;
                   1396: }
                   1397: 
                   1398: //====================================================================
                   1399: 
                   1400: 

unix.superglobalmegacorp.com

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