Annotation of quake2/game/q_shared.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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