Annotation of quake2/rogue/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: // 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.