Annotation of quake2/qcommon/common.c, revision 1.1

1.1     ! root        1: // common.c -- misc functions used in client and server
        !             2: #include "qcommon.h"
        !             3: #include <setjmp.h>
        !             4: #define        MAXPRINTMSG     4096
        !             5: #define MAX_NUM_ARGVS  50
        !             6: int            com_argc;
        !             7: char   *com_argv[MAX_NUM_ARGVS+1];
        !             8: int            realtime;
        !             9: jmp_buf abortframe;            // an ERR_DROP occured, exit the entire frame
        !            10: 
        !            11: FILE   *log_stats_file;
        !            12: cvar_t *host_speeds;
        !            13: cvar_t *log_stats;
        !            14: cvar_t *developer;
        !            15: cvar_t *timescale;
        !            16: cvar_t *fixedtime;
        !            17: cvar_t *logfile_active;        // 1 = buffer log, 2 = flush after each print
        !            18: cvar_t *showtrace;
        !            19: cvar_t *dedicated;
        !            20: FILE   *logfile;
        !            21: int                    server_state;
        !            22: // host_speeds times
        !            23: int            time_before_game;
        !            24: int            time_after_game;
        !            25: int            time_before_ref;
        !            26: int            time_after_ref;
        !            27: /*
        !            28: ============================================================================
        !            29: CLIENT / SERVER interactions
        !            30: ============================================================================
        !            31: */
        !            32: static int     rd_target;
        !            33: static char    *rd_buffer;
        !            34: static int     rd_buffersize;
        !            35: static void    (*rd_flush)(int target, char *buffer);
        !            36: void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush))
        !            37: {
        !            38:        if (!target || !buffer || !buffersize || !flush)
        !            39:                return;
        !            40:        rd_target = target;
        !            41:        rd_buffer = buffer;
        !            42:        rd_buffersize = buffersize;
        !            43:        rd_flush = flush;
        !            44: 
        !            45:        *rd_buffer = 0;
        !            46: }
        !            47: 
        !            48: void Com_EndRedirect (void)
        !            49: {
        !            50:        rd_flush(rd_target, rd_buffer);
        !            51: 
        !            52:        rd_target = 0;
        !            53:        rd_buffer = NULL;
        !            54:        rd_buffersize = 0;
        !            55:        rd_flush = NULL;
        !            56: }
        !            57: 
        !            58: /*
        !            59: =============
        !            60: Com_Printf
        !            61: Both client and server can use this, and it will output
        !            62: to the apropriate place.
        !            63: =============
        !            64: */
        !            65: void Com_Printf (char *fmt, ...)
        !            66: {
        !            67:        va_list         argptr;
        !            68:        char            msg[MAXPRINTMSG];
        !            69:        va_start (argptr,fmt);
        !            70:        vsprintf (msg,fmt,argptr);
        !            71:        va_end (argptr);
        !            72:        if (rd_target)
        !            73:        {
        !            74:                if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1))
        !            75:                {
        !            76:                        rd_flush(rd_target, rd_buffer);
        !            77:                        *rd_buffer = 0;
        !            78:                }
        !            79:                strcat (rd_buffer, msg);
        !            80:                return;
        !            81:        }
        !            82: 
        !            83:        Con_Print (msg);
        !            84:                
        !            85:        // also echo to debugging console
        !            86:        Sys_ConsoleOutput (msg);
        !            87:        // logfile
        !            88:        if (logfile_active && logfile_active->value)
        !            89:        {
        !            90:                char    name[MAX_QPATH];
        !            91:                
        !            92:                if (!logfile)
        !            93:                {
        !            94:                        Com_sprintf (name, sizeof(name), "%s/qconsole.log", FS_Gamedir ());
        !            95:                        logfile = fopen (name, "w");
        !            96:                }
        !            97:                if (logfile)
        !            98:                        fprintf (logfile, "%s", msg);
        !            99:                if (logfile_active->value > 1)
        !           100:                        fflush (logfile);               // force it to save every time
        !           101:        }
        !           102: }
        !           103: /*
        !           104: ================
        !           105: Com_DPrintf
        !           106: A Com_Printf that only shows up if the "developer" cvar is set
        !           107: ================
        !           108: */
        !           109: void Com_DPrintf (char *fmt, ...)
        !           110: {
        !           111:        va_list         argptr;
        !           112:        char            msg[MAXPRINTMSG];
        !           113:                
        !           114:        if (!developer || !developer->value)
        !           115:                return;                 // don't confuse non-developers with techie stuff...
        !           116:        va_start (argptr,fmt);
        !           117:        vsprintf (msg,fmt,argptr);
        !           118:        va_end (argptr);
        !           119:        
        !           120:        Com_Printf ("%s", msg);
        !           121: }
        !           122: /*
        !           123: =============
        !           124: Com_Error
        !           125: Both client and server can use this, and it will
        !           126: do the apropriate things.
        !           127: =============
        !           128: */
        !           129: void Com_Error (int code, char *fmt, ...)
        !           130: {
        !           131:        va_list         argptr;
        !           132:        static char             msg[MAXPRINTMSG];
        !           133:        static  qboolean        recursive;
        !           134:        if (recursive)
        !           135:                Sys_Error ("recursive error after: %s", msg);
        !           136:        recursive = true;
        !           137:        va_start (argptr,fmt);
        !           138:        vsprintf (msg,fmt,argptr);
        !           139:        va_end (argptr);
        !           140:        
        !           141:        if (code == ERR_DISCONNECT)
        !           142:        {
        !           143:                CL_Drop ();
        !           144:                recursive = false;
        !           145:                longjmp (abortframe, -1);
        !           146:        }
        !           147:        else if (code == ERR_DROP)
        !           148:        {
        !           149:                Com_Printf ("********************\nERROR: %s\n********************\n", msg);
        !           150:                SV_Shutdown (va("Server crashed: %s\n", msg), false);
        !           151:                CL_Drop ();
        !           152:                recursive = false;
        !           153:                longjmp (abortframe, -1);
        !           154:        }
        !           155:        else
        !           156:        {
        !           157:                SV_Shutdown (va("Server fatal crashed: %s\n", msg), false);
        !           158:                CL_Shutdown ();
        !           159:        }
        !           160:        if (logfile)
        !           161:        {
        !           162:                fclose (logfile);
        !           163:                logfile = NULL;
        !           164:        }
        !           165:        Sys_Error ("%s", msg);
        !           166: }
        !           167: /*
        !           168: =============
        !           169: Com_Quit
        !           170: Both client and server can use this, and it will
        !           171: do the apropriate things.
        !           172: =============
        !           173: */
        !           174: void Com_Quit (void)
        !           175: {
        !           176:        SV_Shutdown ("Server quit\n", false);
        !           177:        CL_Shutdown ();
        !           178:        if (logfile)
        !           179:        {
        !           180:                fclose (logfile);
        !           181:                logfile = NULL;
        !           182:        }
        !           183:        Sys_Quit ();
        !           184: }
        !           185: /*
        !           186: ==================
        !           187: Com_ServerState
        !           188: ==================
        !           189: */
        !           190: int Com_ServerState (void)
        !           191: {
        !           192:        return server_state;
        !           193: }
        !           194: /*
        !           195: ==================
        !           196: Com_SetServerState
        !           197: ==================
        !           198: */
        !           199: void Com_SetServerState (int state)
        !           200: {
        !           201:        server_state = state;
        !           202: }
        !           203: /*
        !           204: ==============================================================================
        !           205:                        MESSAGE IO FUNCTIONS
        !           206: Handles byte ordering and avoids alignment errors
        !           207: ==============================================================================
        !           208: */
        !           209: vec3_t bytedirs[NUMVERTEXNORMALS] =
        !           210: {
        !           211: #include "../client/anorms.h"
        !           212: };
        !           213: //
        !           214: // writing functions
        !           215: //
        !           216: void MSG_WriteChar (sizebuf_t *sb, int c)
        !           217: {
        !           218:        byte    *buf;
        !           219:        
        !           220: #ifdef PARANOID
        !           221:        if (c < -128 || c > 127)
        !           222:                Com_Error (ERR_FATAL, "MSG_WriteChar: range error");
        !           223: #endif
        !           224:        buf = SZ_GetSpace (sb, 1);
        !           225:        buf[0] = c;
        !           226: }
        !           227: void MSG_WriteByte (sizebuf_t *sb, int c)
        !           228: {
        !           229:        byte    *buf;
        !           230:        
        !           231: #ifdef PARANOID
        !           232:        if (c < 0 || c > 255)
        !           233:                Com_Error (ERR_FATAL, "MSG_WriteByte: range error");
        !           234: #endif
        !           235:        buf = SZ_GetSpace (sb, 1);
        !           236:        buf[0] = c;
        !           237: }
        !           238: void MSG_WriteShort (sizebuf_t *sb, int c)
        !           239: {
        !           240:        byte    *buf;
        !           241:        
        !           242: #ifdef PARANOID
        !           243:        if (c < ((short)0x8000) || c > (short)0x7fff)
        !           244:                Com_Error (ERR_FATAL, "MSG_WriteShort: range error");
        !           245: #endif
        !           246:        buf = SZ_GetSpace (sb, 2);
        !           247:        buf[0] = c&0xff;
        !           248:        buf[1] = c>>8;
        !           249: }
        !           250: void MSG_WriteLong (sizebuf_t *sb, int c)
        !           251: {
        !           252:        byte    *buf;
        !           253:        
        !           254:        buf = SZ_GetSpace (sb, 4);
        !           255:        buf[0] = c&0xff;
        !           256:        buf[1] = (c>>8)&0xff;
        !           257:        buf[2] = (c>>16)&0xff;
        !           258:        buf[3] = c>>24;
        !           259: }
        !           260: void MSG_WriteFloat (sizebuf_t *sb, float f)
        !           261: {
        !           262:        union
        !           263:        {
        !           264:                float   f;
        !           265:                int     l;
        !           266:        } dat;
        !           267:        
        !           268:        
        !           269:        dat.f = f;
        !           270:        dat.l = LittleLong (dat.l);
        !           271:        
        !           272:        SZ_Write (sb, &dat.l, 4);
        !           273: }
        !           274: void MSG_WriteString (sizebuf_t *sb, char *s)
        !           275: {
        !           276:        if (!s)
        !           277:                SZ_Write (sb, "", 1);
        !           278:        else
        !           279:                SZ_Write (sb, s, strlen(s)+1);
        !           280: }
        !           281: void MSG_WriteCoord (sizebuf_t *sb, float f)
        !           282: {
        !           283:        MSG_WriteShort (sb, (int)(f*8));
        !           284: }
        !           285: void MSG_WritePos (sizebuf_t *sb, vec3_t pos)
        !           286: {
        !           287:        MSG_WriteShort (sb, (int)(pos[0]*8));
        !           288:        MSG_WriteShort (sb, (int)(pos[1]*8));
        !           289:        MSG_WriteShort (sb, (int)(pos[2]*8));
        !           290: }
        !           291: void MSG_WriteAngle (sizebuf_t *sb, float f)
        !           292: {
        !           293:        MSG_WriteByte (sb, (int)(f*256/360) & 255);
        !           294: }
        !           295: void MSG_WriteAngle16 (sizebuf_t *sb, float f)
        !           296: {
        !           297:        MSG_WriteShort (sb, ANGLE2SHORT(f));
        !           298: }
        !           299: 
        !           300: void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
        !           301: {
        !           302:        int             bits;
        !           303: //
        !           304: // send the movement message
        !           305: //
        !           306:        bits = 0;
        !           307:        if (cmd->angles[0] != from->angles[0])
        !           308:                bits |= CM_ANGLE1;
        !           309:        if (cmd->angles[1] != from->angles[1])
        !           310:                bits |= CM_ANGLE2;
        !           311:        if (cmd->angles[2] != from->angles[2])
        !           312:                bits |= CM_ANGLE3;
        !           313:        if (cmd->forwardmove != from->forwardmove)
        !           314:                bits |= CM_FORWARD;
        !           315:        if (cmd->sidemove != from->sidemove)
        !           316:                bits |= CM_SIDE;
        !           317:        if (cmd->upmove != from->upmove)
        !           318:                bits |= CM_UP;
        !           319:        if (cmd->buttons != from->buttons)
        !           320:                bits |= CM_BUTTONS;
        !           321:        if (cmd->impulse != from->impulse)
        !           322:                bits |= CM_IMPULSE;
        !           323:     MSG_WriteByte (buf, bits);
        !           324:        if (bits & CM_ANGLE1)
        !           325:                MSG_WriteShort (buf, cmd->angles[0]);
        !           326:        if (bits & CM_ANGLE2)
        !           327:                MSG_WriteShort (buf, cmd->angles[1]);
        !           328:        if (bits & CM_ANGLE3)
        !           329:                MSG_WriteShort (buf, cmd->angles[2]);
        !           330:        
        !           331:        if (bits & CM_FORWARD)
        !           332:                MSG_WriteShort (buf, cmd->forwardmove);
        !           333:        if (bits & CM_SIDE)
        !           334:                MSG_WriteShort (buf, cmd->sidemove);
        !           335:        if (bits & CM_UP)
        !           336:                MSG_WriteShort (buf, cmd->upmove);
        !           337:        if (bits & CM_BUTTONS)
        !           338:                MSG_WriteByte (buf, cmd->buttons);
        !           339:        if (bits & CM_IMPULSE)
        !           340:            MSG_WriteByte (buf, cmd->impulse);
        !           341:     MSG_WriteByte (buf, cmd->msec);
        !           342:        MSG_WriteByte (buf, cmd->lightlevel);
        !           343: }
        !           344: void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
        !           345: {
        !           346:        int             i, best;
        !           347:        float   d, bestd;
        !           348:        
        !           349:        if (!dir)
        !           350:        {
        !           351:                MSG_WriteByte (sb, 0);
        !           352:                return;
        !           353:        }
        !           354:        bestd = 0;
        !           355:        best = 0;
        !           356:        for (i=0 ; i<NUMVERTEXNORMALS ; i++)
        !           357:        {
        !           358:                d = DotProduct (dir, bytedirs[i]);
        !           359:                if (d > bestd)
        !           360:                {
        !           361:                        bestd = d;
        !           362:                        best = i;
        !           363:                }
        !           364:        }
        !           365:        MSG_WriteByte (sb, best);
        !           366: }
        !           367: void MSG_ReadDir (sizebuf_t *sb, vec3_t dir)
        !           368: {
        !           369:        int             b;
        !           370:        b = MSG_ReadByte (sb);
        !           371:        if (b >= NUMVERTEXNORMALS)
        !           372:                Com_Error (ERR_DROP, "MSF_ReadDir: out of range");
        !           373:        VectorCopy (bytedirs[b], dir);
        !           374: }
        !           375: /*
        !           376: ==================
        !           377: MSG_WriteDeltaEntity
        !           378: Writes part of a packetentities message.
        !           379: Can delta from either a baseline or a previous packet_entity
        !           380: ==================
        !           381: */
        !           382: void MSG_WriteDeltaEntity (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force)
        !           383: {
        !           384:        int             bits;
        !           385: 
        !           386:        if (!to->number)
        !           387:                Com_Error (ERR_FATAL, "Unset entity number");
        !           388:        if (to->number >= MAX_EDICTS)
        !           389:                Com_Error (ERR_FATAL, "Entity number >= MAX_EDICTS");
        !           390: // send an update
        !           391:        bits = 0;
        !           392: 
        !           393:        if (to->number >= 256)
        !           394:                bits |= U_NUMBER16;             // number8 is implicit otherwise
        !           395: 
        !           396:        if (to->origin[0] != from->origin[0])
        !           397:                bits |= U_ORIGIN1;
        !           398:        if (to->origin[1] != from->origin[1])
        !           399:                bits |= U_ORIGIN2;
        !           400:        if (to->origin[2] != from->origin[2])
        !           401:                bits |= U_ORIGIN3;
        !           402:        if ( to->angles[0] != from->angles[0] )
        !           403:                bits |= U_ANGLE1;               
        !           404:        if ( to->angles[1] != from->angles[1] )
        !           405:                bits |= U_ANGLE2;
        !           406:        if ( to->angles[2] != from->angles[2] )
        !           407:                bits |= U_ANGLE3;
        !           408:                
        !           409:        if ( to->skinnum != from->skinnum )
        !           410:        {
        !           411:                if ((unsigned)to->skinnum < 256)
        !           412:                        bits |= U_SKIN8;
        !           413:                else if ((unsigned)to->skinnum < 0x10000)
        !           414:                        bits |= U_SKIN16;
        !           415:                else
        !           416:                        bits |= (U_SKIN8|U_SKIN16);
        !           417:        }
        !           418:                
        !           419:        if ( to->frame != from->frame )
        !           420:        {
        !           421:                if (to->frame < 256)
        !           422:                        bits |= U_FRAME8;
        !           423:                else
        !           424:                        bits |= U_FRAME16;
        !           425:        }
        !           426:        if ( to->effects != from->effects )
        !           427:        {
        !           428:                if (to->effects < 256)
        !           429:                        bits |= U_EFFECTS8;
        !           430:                else if (to->effects < 0x8000)
        !           431:                        bits |= U_EFFECTS16;
        !           432:                else
        !           433:                        bits |= U_EFFECTS8|U_EFFECTS16;
        !           434:        }
        !           435:        
        !           436:        if ( to->renderfx != from->renderfx )
        !           437:        {
        !           438:                if (to->renderfx < 256)
        !           439:                        bits |= U_RENDERFX8;
        !           440:                else if (to->renderfx < 0x8000)
        !           441:                        bits |= U_RENDERFX16;
        !           442:                else
        !           443:                        bits |= U_RENDERFX8|U_RENDERFX16;
        !           444:        }
        !           445:        
        !           446:        if ( to->solid != from->solid )
        !           447:                bits |= U_SOLID;
        !           448:        
        !           449:        // event is not delta compressed, just 0 compressed
        !           450:        if ( to->event  )
        !           451:                bits |= U_EVENT;
        !           452:        
        !           453:        if ( to->modelindex != from->modelindex )
        !           454:                bits |= U_MODEL;
        !           455:        if ( to->modelindex2 != from->modelindex2 )
        !           456:                bits |= U_MODEL2;
        !           457:        if ( to->modelindex3 != from->modelindex3 )
        !           458:                bits |= U_MODEL3;
        !           459:        if ( to->modelindex4 != from->modelindex4 )
        !           460:                bits |= U_MODEL4;
        !           461:        if ( to->sound != from->sound )
        !           462:                bits |= U_SOUND;
        !           463: 
        !           464:        if (to->old_origin[0] != from->old_origin[0]
        !           465:                || to->old_origin[1] != from->old_origin[1]
        !           466:                || to->old_origin[2] != from->old_origin[2] )
        !           467:                bits |= U_OLDORIGIN;            // FIXME: only when newly seen!!!
        !           468:        //
        !           469:        // write the message
        !           470:        //
        !           471:        if (!bits && !force)
        !           472:                return;         // nothing to send!
        !           473:        //----------
        !           474: 
        !           475:        if (bits & 0xff000000)
        !           476:                bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1;
        !           477:        else if (bits & 0x00ff0000)
        !           478:                bits |= U_MOREBITS2 | U_MOREBITS1;
        !           479:        else if (bits & 0x0000ff00)
        !           480:                bits |= U_MOREBITS1;
        !           481:        MSG_WriteByte (msg,     bits&255 );
        !           482:        if (bits & 0xff000000)
        !           483:        {
        !           484:                MSG_WriteByte (msg,     (bits>>8)&255 );
        !           485:                MSG_WriteByte (msg,     (bits>>16)&255 );
        !           486:                MSG_WriteByte (msg,     (bits>>24)&255 );
        !           487:        }
        !           488:        else if (bits & 0x00ff0000)
        !           489:        {
        !           490:                MSG_WriteByte (msg,     (bits>>8)&255 );
        !           491:                MSG_WriteByte (msg,     (bits>>16)&255 );
        !           492:        }
        !           493:        else if (bits & 0x0000ff00)
        !           494:        {
        !           495:                MSG_WriteByte (msg,     (bits>>8)&255 );
        !           496:        }
        !           497:        //----------
        !           498: 
        !           499:        if (bits & U_NUMBER16)
        !           500:                MSG_WriteShort (msg, to->number);
        !           501:        else
        !           502:                MSG_WriteByte (msg,     to->number);
        !           503:        if (bits & U_MODEL)
        !           504:                MSG_WriteByte (msg,     to->modelindex);
        !           505:        if (bits & U_MODEL2)
        !           506:                MSG_WriteByte (msg,     to->modelindex2);
        !           507:        if (bits & U_MODEL3)
        !           508:                MSG_WriteByte (msg,     to->modelindex3);
        !           509:        if (bits & U_MODEL4)
        !           510:                MSG_WriteByte (msg,     to->modelindex4);
        !           511:        if (bits & U_FRAME8)
        !           512:                MSG_WriteByte (msg, to->frame);
        !           513:        if (bits & U_FRAME16)
        !           514:                MSG_WriteShort (msg, to->frame);
        !           515:        if ((bits & U_SKIN8) && (bits & U_SKIN16))              //used for laser colors
        !           516:                MSG_WriteLong (msg, to->skinnum);
        !           517:        else if (bits & U_SKIN8)
        !           518:                MSG_WriteByte (msg, to->skinnum);
        !           519:        else if (bits & U_SKIN16)
        !           520:                MSG_WriteShort (msg, to->skinnum);
        !           521: 
        !           522:        if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
        !           523:                MSG_WriteLong (msg, to->effects);
        !           524:        else if (bits & U_EFFECTS8)
        !           525:                MSG_WriteByte (msg, to->effects);
        !           526:        else if (bits & U_EFFECTS16)
        !           527:                MSG_WriteShort (msg, to->effects);
        !           528:        if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
        !           529:                MSG_WriteLong (msg, to->renderfx);
        !           530:        else if (bits & U_RENDERFX8)
        !           531:                MSG_WriteByte (msg, to->renderfx);
        !           532:        else if (bits & U_RENDERFX16)
        !           533:                MSG_WriteShort (msg, to->renderfx);
        !           534:        if (bits & U_ORIGIN1)
        !           535:                MSG_WriteCoord (msg, to->origin[0]);            
        !           536:        if (bits & U_ORIGIN2)
        !           537:                MSG_WriteCoord (msg, to->origin[1]);
        !           538:        if (bits & U_ORIGIN3)
        !           539:                MSG_WriteCoord (msg, to->origin[2]);
        !           540:        if (bits & U_ANGLE1)
        !           541:                MSG_WriteAngle(msg, to->angles[0]);
        !           542:        if (bits & U_ANGLE2)
        !           543:                MSG_WriteAngle(msg, to->angles[1]);
        !           544:        if (bits & U_ANGLE3)
        !           545:                MSG_WriteAngle(msg, to->angles[2]);
        !           546:        if (bits & U_OLDORIGIN)
        !           547:        {
        !           548:                MSG_WriteCoord (msg, to->old_origin[0]);
        !           549:                MSG_WriteCoord (msg, to->old_origin[1]);
        !           550:                MSG_WriteCoord (msg, to->old_origin[2]);
        !           551:        }
        !           552:        if (bits & U_SOUND)
        !           553:                MSG_WriteByte (msg, to->sound);
        !           554:        if (bits & U_EVENT)
        !           555:                MSG_WriteByte (msg, to->event);
        !           556:        if (bits & U_SOLID)
        !           557:                MSG_WriteShort (msg, to->solid);
        !           558: }
        !           559: //============================================================
        !           560: //
        !           561: // reading functions
        !           562: //
        !           563: void MSG_BeginReading (sizebuf_t *msg)
        !           564: {
        !           565:        msg->readcount = 0;
        !           566: }
        !           567: // returns -1 if no more characters are available
        !           568: int MSG_ReadChar (sizebuf_t *msg_read)
        !           569: {
        !           570:        int     c;
        !           571:        
        !           572:        if (msg_read->readcount+1 > msg_read->cursize)
        !           573:                c = -1;
        !           574:        else
        !           575:                c = (signed char)msg_read->data[msg_read->readcount];
        !           576:        msg_read->readcount++;
        !           577:        
        !           578:        return c;
        !           579: }
        !           580: int MSG_ReadByte (sizebuf_t *msg_read)
        !           581: {
        !           582:        int     c;
        !           583:        
        !           584:        if (msg_read->readcount+1 > msg_read->cursize)
        !           585:                c = -1;
        !           586:        else
        !           587:                c = (unsigned char)msg_read->data[msg_read->readcount];
        !           588:        msg_read->readcount++;
        !           589:        
        !           590:        return c;
        !           591: }
        !           592: int MSG_ReadShort (sizebuf_t *msg_read)
        !           593: {
        !           594:        int     c;
        !           595:        
        !           596:        if (msg_read->readcount+2 > msg_read->cursize)
        !           597:                c = -1;
        !           598:        else            
        !           599:                c = (short)(msg_read->data[msg_read->readcount]
        !           600:                + (msg_read->data[msg_read->readcount+1]<<8));
        !           601:        
        !           602:        msg_read->readcount += 2;
        !           603:        
        !           604:        return c;
        !           605: }
        !           606: int MSG_ReadLong (sizebuf_t *msg_read)
        !           607: {
        !           608:        int     c;
        !           609:        
        !           610:        if (msg_read->readcount+4 > msg_read->cursize)
        !           611:                c = -1;
        !           612:        else
        !           613:                c = msg_read->data[msg_read->readcount]
        !           614:                + (msg_read->data[msg_read->readcount+1]<<8)
        !           615:                + (msg_read->data[msg_read->readcount+2]<<16)
        !           616:                + (msg_read->data[msg_read->readcount+3]<<24);
        !           617:        
        !           618:        msg_read->readcount += 4;
        !           619:        
        !           620:        return c;
        !           621: }
        !           622: float MSG_ReadFloat (sizebuf_t *msg_read)
        !           623: {
        !           624:        union
        !           625:        {
        !           626:                byte    b[4];
        !           627:                float   f;
        !           628:                int     l;
        !           629:        } dat;
        !           630:        
        !           631:        if (msg_read->readcount+4 > msg_read->cursize)
        !           632:                dat.f = -1;
        !           633:        else
        !           634:        {
        !           635:                dat.b[0] =      msg_read->data[msg_read->readcount];
        !           636:                dat.b[1] =      msg_read->data[msg_read->readcount+1];
        !           637:                dat.b[2] =      msg_read->data[msg_read->readcount+2];
        !           638:                dat.b[3] =      msg_read->data[msg_read->readcount+3];
        !           639:        }
        !           640:        msg_read->readcount += 4;
        !           641:        
        !           642:        dat.l = LittleLong (dat.l);
        !           643:        return dat.f;   
        !           644: }
        !           645: char *MSG_ReadString (sizebuf_t *msg_read)
        !           646: {
        !           647:        static char     string[2048];
        !           648:        int             l,c;
        !           649:        
        !           650:        l = 0;
        !           651:        do
        !           652:        {
        !           653:                c = MSG_ReadChar (msg_read);
        !           654:                if (c == -1 || c == 0)
        !           655:                        break;
        !           656:                string[l] = c;
        !           657:                l++;
        !           658:        } while (l < sizeof(string)-1);
        !           659:        
        !           660:        string[l] = 0;
        !           661:        
        !           662:        return string;
        !           663: }
        !           664: char *MSG_ReadStringLine (sizebuf_t *msg_read)
        !           665: {
        !           666:        static char     string[2048];
        !           667:        int             l,c;
        !           668:        
        !           669:        l = 0;
        !           670:        do
        !           671:        {
        !           672:                c = MSG_ReadChar (msg_read);
        !           673:                if (c == -1 || c == 0 || c == '\n')
        !           674:                        break;
        !           675:                string[l] = c;
        !           676:                l++;
        !           677:        } while (l < sizeof(string)-1);
        !           678:        
        !           679:        string[l] = 0;
        !           680:        
        !           681:        return string;
        !           682: }
        !           683: float MSG_ReadCoord (sizebuf_t *msg_read)
        !           684: {
        !           685:        return MSG_ReadShort(msg_read) * (1.0/8);
        !           686: }
        !           687: void MSG_ReadPos (sizebuf_t *msg_read, vec3_t pos)
        !           688: {
        !           689:        pos[0] = MSG_ReadShort(msg_read) * (1.0/8);
        !           690:        pos[1] = MSG_ReadShort(msg_read) * (1.0/8);
        !           691:        pos[2] = MSG_ReadShort(msg_read) * (1.0/8);
        !           692: }
        !           693: float MSG_ReadAngle (sizebuf_t *msg_read)
        !           694: {
        !           695:        return MSG_ReadChar(msg_read) * (360.0/256);
        !           696: }
        !           697: float MSG_ReadAngle16 (sizebuf_t *msg_read)
        !           698: {
        !           699:        return SHORT2ANGLE(MSG_ReadShort(msg_read));
        !           700: }
        !           701: void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move)
        !           702: {
        !           703:        int bits;
        !           704:        memcpy (move, from, sizeof(*move));
        !           705:        bits = MSG_ReadByte (msg_read);
        !           706:                
        !           707: // read current angles
        !           708:        if (bits & CM_ANGLE1)
        !           709:                move->angles[0] = MSG_ReadShort (msg_read);
        !           710:        if (bits & CM_ANGLE2)
        !           711:                move->angles[1] = MSG_ReadShort (msg_read);
        !           712:        if (bits & CM_ANGLE3)
        !           713:                move->angles[2] = MSG_ReadShort (msg_read);
        !           714:                
        !           715: // read movement
        !           716:        if (bits & CM_FORWARD)
        !           717:                move->forwardmove = MSG_ReadShort (msg_read);
        !           718:        if (bits & CM_SIDE)
        !           719:                move->sidemove = MSG_ReadShort (msg_read);
        !           720:        if (bits & CM_UP)
        !           721:                move->upmove = MSG_ReadShort (msg_read);
        !           722:        
        !           723: // read buttons
        !           724:        if (bits & CM_BUTTONS)
        !           725:                move->buttons = MSG_ReadByte (msg_read);
        !           726:        if (bits & CM_IMPULSE)
        !           727:                move->impulse = MSG_ReadByte (msg_read);
        !           728: // read time to run command
        !           729:        move->msec = MSG_ReadByte (msg_read);
        !           730: // read the light level
        !           731:        move->lightlevel = MSG_ReadByte (msg_read);
        !           732: }
        !           733: void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
        !           734: {
        !           735:        int             i;
        !           736:        for (i=0 ; i<len ; i++)
        !           737:                ((byte *)data)[i] = MSG_ReadByte (msg_read);
        !           738: }
        !           739: //===========================================================================
        !           740: void SZ_Init (sizebuf_t *buf, byte *data, int length)
        !           741: {
        !           742:        memset (buf, 0, sizeof(*buf));
        !           743:        buf->data = data;
        !           744:        buf->maxsize = length;
        !           745: }
        !           746: void SZ_Clear (sizebuf_t *buf)
        !           747: {
        !           748:        buf->cursize = 0;
        !           749:        buf->overflowed = false;
        !           750: }
        !           751: void *SZ_GetSpace (sizebuf_t *buf, int length)
        !           752: {
        !           753:        void    *data;
        !           754:        
        !           755:        if (buf->cursize + length > buf->maxsize)
        !           756:        {
        !           757:                if (!buf->allowoverflow)
        !           758:                        Com_Error (ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set");
        !           759:                
        !           760:                if (length > buf->maxsize)
        !           761:                        Com_Error (ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length);
        !           762:                        
        !           763:                Com_Printf ("SZ_GetSpace: overflow\n");
        !           764:                SZ_Clear (buf); 
        !           765:                buf->overflowed = true;
        !           766:        }
        !           767:        data = buf->data + buf->cursize;
        !           768:        buf->cursize += length;
        !           769:        
        !           770:        return data;
        !           771: }
        !           772: void SZ_Write (sizebuf_t *buf, void *data, int length)
        !           773: {
        !           774:        memcpy (SZ_GetSpace(buf,length),data,length);           
        !           775: }
        !           776: void SZ_Print (sizebuf_t *buf, char *data)
        !           777: {
        !           778:        int             len;
        !           779:        
        !           780:        len = strlen(data)+1;
        !           781:        if (buf->cursize)
        !           782:        {
        !           783:                if (buf->data[buf->cursize-1])
        !           784:                        memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0
        !           785:                else
        !           786:                        memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
        !           787:        }
        !           788:        else
        !           789:                memcpy ((byte *)SZ_GetSpace(buf, len),data,len);
        !           790: }
        !           791: //============================================================================
        !           792: /*
        !           793: ================
        !           794: COM_CheckParm
        !           795: Returns the position (1 to argc-1) in the program's argument list
        !           796: where the given parameter apears, or 0 if not present
        !           797: ================
        !           798: */
        !           799: int COM_CheckParm (char *parm)
        !           800: {
        !           801:        int             i;
        !           802:        
        !           803:        for (i=1 ; i<com_argc ; i++)
        !           804:        {
        !           805:                if (!strcmp (parm,com_argv[i]))
        !           806:                        return i;
        !           807:        }
        !           808:                
        !           809:        return 0;
        !           810: }
        !           811: int COM_Argc (void)
        !           812: {
        !           813:        return com_argc;
        !           814: }
        !           815: char *COM_Argv (int arg)
        !           816: {
        !           817:        if (arg < 0 || arg >= com_argc || !com_argv[arg])
        !           818:                return "";
        !           819:        return com_argv[arg];
        !           820: }
        !           821: void COM_ClearArgv (int arg)
        !           822: {
        !           823:        if (arg < 0 || arg >= com_argc || !com_argv[arg])
        !           824:                return;
        !           825:        com_argv[arg] = "";
        !           826: }
        !           827: /*
        !           828: ================
        !           829: COM_InitArgv
        !           830: ================
        !           831: */
        !           832: void COM_InitArgv (int argc, char **argv)
        !           833: {
        !           834:        int             i;
        !           835:        if (argc > MAX_NUM_ARGVS)
        !           836:                Com_Error (ERR_FATAL, "argc > MAX_NUM_ARGVS");
        !           837:        com_argc = argc;
        !           838:        for (i=0 ; i<argc ; i++)
        !           839:        {
        !           840:                if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS )
        !           841:                        com_argv[i] = "";
        !           842:                else
        !           843:                        com_argv[i] = argv[i];
        !           844:        }
        !           845: }
        !           846: /*
        !           847: ================
        !           848: COM_AddParm
        !           849: Adds the given string at the end of the current argument list
        !           850: ================
        !           851: */
        !           852: void COM_AddParm (char *parm)
        !           853: {
        !           854:        if (com_argc == MAX_NUM_ARGVS)
        !           855:                Com_Error (ERR_FATAL, "COM_AddParm: MAX_NUM)ARGS");
        !           856:        com_argv[com_argc++] = parm;
        !           857: }
        !           858: /// just for debugging
        !           859: int    memsearch (byte *start, int count, int search)
        !           860: {
        !           861:        int             i;
        !           862:        
        !           863:        for (i=0 ; i<count ; i++)
        !           864:                if (start[i] == search)
        !           865:                        return i;
        !           866:        return -1;
        !           867: }
        !           868: char *CopyString (char *in)
        !           869: {
        !           870:        char    *out;
        !           871:        
        !           872:        out = Z_Malloc (strlen(in)+1);
        !           873:        strcpy (out, in);
        !           874:        return out;
        !           875: }
        !           876: void Info_Print (char *s)
        !           877: {
        !           878:        char    key[512];
        !           879:        char    value[512];
        !           880:        char    *o;
        !           881:        int             l;
        !           882:        if (*s == '\\')
        !           883:                s++;
        !           884:        while (*s)
        !           885:        {
        !           886:                o = key;
        !           887:                while (*s && *s != '\\')
        !           888:                        *o++ = *s++;
        !           889:                l = o - key;
        !           890:                if (l < 20)
        !           891:                {
        !           892:                        memset (o, ' ', 20-l);
        !           893:                        key[20] = 0;
        !           894:                }
        !           895:                else
        !           896:                        *o = 0;
        !           897:                Com_Printf ("%s", key);
        !           898:                if (!*s)
        !           899:                {
        !           900:                        Com_Printf ("MISSING VALUE\n");
        !           901:                        return;
        !           902:                }
        !           903:                o = value;
        !           904:                s++;
        !           905:                while (*s && *s != '\\')
        !           906:                        *o++ = *s++;
        !           907:                *o = 0;
        !           908:                if (*s)
        !           909:                        s++;
        !           910:                Com_Printf ("%s\n", value);
        !           911:        }
        !           912: }
        !           913: /*
        !           914: ==============================================================================
        !           915:                                                ZONE MEMORY ALLOCATION
        !           916: just cleared malloc with counters now...
        !           917: ==============================================================================
        !           918: */
        !           919: #define        Z_MAGIC         0x1d1d
        !           920: typedef struct zhead_s
        !           921: {
        !           922:        struct zhead_s  *prev, *next;
        !           923:        short   magic;
        !           924:        short   tag;                    // for group free
        !           925:        int             size;
        !           926: } zhead_t;
        !           927: zhead_t                z_chain;
        !           928: int            z_count, z_bytes;
        !           929: /*
        !           930: ========================
        !           931: Z_Free
        !           932: ========================
        !           933: */
        !           934: void Z_Free (void *ptr)
        !           935: {
        !           936:        zhead_t *z;
        !           937:        z = ((zhead_t *)ptr) - 1;
        !           938:        if (z->magic != Z_MAGIC)
        !           939:                Com_Error (ERR_FATAL, "Z_Free: bad magic");
        !           940:        z->prev->next = z->next;
        !           941:        z->next->prev = z->prev;
        !           942:        z_count--;
        !           943:        z_bytes -= z->size;
        !           944:        free (z);
        !           945: }
        !           946: /*
        !           947: ========================
        !           948: Z_Stats_f
        !           949: ========================
        !           950: */
        !           951: void Z_Stats_f (void)
        !           952: {
        !           953:        Com_Printf ("%i bytes in %i blocks\n", z_bytes, z_count);
        !           954: }
        !           955: /*
        !           956: ========================
        !           957: Z_FreeTags
        !           958: ========================
        !           959: */
        !           960: void Z_FreeTags (int tag)
        !           961: {
        !           962:        zhead_t *z, *next;
        !           963:        for (z=z_chain.next ; z != &z_chain ; z=next)
        !           964:        {
        !           965:                next = z->next;
        !           966:                if (z->tag == tag)
        !           967:                        Z_Free ((void *)(z+1));
        !           968:        }
        !           969: }
        !           970: /*
        !           971: ========================
        !           972: Z_TagMalloc
        !           973: ========================
        !           974: */
        !           975: void *Z_TagMalloc (int size, int tag)
        !           976: {
        !           977:        zhead_t *z;
        !           978:        
        !           979:        size = size + sizeof(zhead_t);
        !           980:        z = malloc(size);
        !           981:        if (!z)
        !           982:                Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size);
        !           983:        memset (z, 0, size);
        !           984:        z_count++;
        !           985:        z_bytes += size;
        !           986:        z->magic = Z_MAGIC;
        !           987:        z->tag = tag;
        !           988:        z->size = size;
        !           989:        z->next = z_chain.next;
        !           990:        z->prev = &z_chain;
        !           991:        z_chain.next->prev = z;
        !           992:        z_chain.next = z;
        !           993:        return (void *)(z+1);
        !           994: }
        !           995: /*
        !           996: ========================
        !           997: Z_Malloc
        !           998: ========================
        !           999: */
        !          1000: void *Z_Malloc (int size)
        !          1001: {
        !          1002:        return Z_TagMalloc (size, 0);
        !          1003: }
        !          1004: //============================================================================
        !          1005: 
        !          1006: 
        !          1007: /*
        !          1008: ====================
        !          1009: COM_BlockSequenceCheckByte
        !          1010: 
        !          1011: For proxy protecting
        !          1012: ====================
        !          1013: */
        !          1014: byte   COM_BlockSequenceCheckByte (byte *base, int length, int sequence)
        !          1015: {
        !          1016:        int             checksum;
        !          1017:        byte    buf[64];
        !          1018:        int             n;
        !          1019:        byte    *p;
        !          1020: 
        !          1021:        n = sequence % (NUMVERTEXNORMALS * sizeof(vec3_t));
        !          1022:        p = ((byte *)bytedirs)+n;
        !          1023:        if (length > 60)
        !          1024:                length = 60;
        !          1025:        memcpy (buf, base, length);
        !          1026:        buf[length] = (sequence & 0xff) ^ *p++;
        !          1027:        buf[length+1] = *p++;
        !          1028:        buf[length+2] = ((sequence>>8) & 0xff) ^ *p++;
        !          1029:        buf[length+3] = *p;
        !          1030:        length += 4;
        !          1031: 
        !          1032:        checksum = Com_BlockChecksum (buf, length);
        !          1033: 
        !          1034:        checksum &= 0xff;
        !          1035: 
        !          1036:        return checksum;
        !          1037: }
        !          1038: 
        !          1039: //========================================================
        !          1040: float  frand(void)
        !          1041: {
        !          1042:        return (rand()&32767)* (1.0/32767);
        !          1043: }
        !          1044: float  crand(void)
        !          1045: {
        !          1046:        return (rand()&32767)* (2.0/32767) - 1;
        !          1047: }
        !          1048: void Key_Init (void);
        !          1049: void SCR_EndLoadingPlaque (void);
        !          1050: /*
        !          1051: =============
        !          1052: Com_Error_f
        !          1053: Just throw a fatal error to
        !          1054: test error shutdown procedures
        !          1055: =============
        !          1056: */
        !          1057: void Com_Error_f (void)
        !          1058: {
        !          1059:        Com_Error (ERR_FATAL, "%s", Cmd_Argv(1));
        !          1060: }
        !          1061: 
        !          1062: 
        !          1063: /*
        !          1064: =================
        !          1065: Qcommon_Init
        !          1066: =================
        !          1067: */
        !          1068: void Qcommon_Init (int argc, char **argv)
        !          1069: {
        !          1070:        char    *s;
        !          1071:        if (setjmp (abortframe) )
        !          1072:                Sys_Error ("Error during initialization");
        !          1073:        z_chain.next = z_chain.prev = &z_chain;
        !          1074:        // prepare enough of the subsystems to handle
        !          1075:        // cvar and command buffer management
        !          1076:        COM_InitArgv (argc, argv);
        !          1077:        Swap_Init ();
        !          1078:        Cbuf_Init ();
        !          1079:        Cmd_Init ();
        !          1080:        Cvar_Init ();
        !          1081:        Key_Init ();
        !          1082:        // we need to add the early commands twice, because
        !          1083:        // a basedir or cddir needs to be set before execing
        !          1084:        // config files, but we want other parms to override
        !          1085:        // the settings of the config files
        !          1086:        Cbuf_AddEarlyCommands (false);
        !          1087:        Cbuf_Execute ();
        !          1088:        FS_InitFilesystem ();
        !          1089:        Cbuf_AddText ("exec default.cfg\n");
        !          1090:        Cbuf_AddText ("exec config.cfg\n");
        !          1091:        Cbuf_AddEarlyCommands (true);
        !          1092:        Cbuf_Execute ();
        !          1093:        //
        !          1094:        // init commands and vars
        !          1095:        //
        !          1096:     Cmd_AddCommand ("z_stats", Z_Stats_f);
        !          1097:     Cmd_AddCommand ("error", Com_Error_f);
        !          1098:        host_speeds = Cvar_Get ("host_speeds", "0", 0);
        !          1099:        log_stats = Cvar_Get ("log_stats", "0", 0);
        !          1100:        developer = Cvar_Get ("developer", "0", 0);
        !          1101:        timescale = Cvar_Get ("timescale", "1", 0);
        !          1102:        fixedtime = Cvar_Get ("fixedtime", "0", 0);
        !          1103:        logfile_active = Cvar_Get ("logfile", "0", 0);
        !          1104:        showtrace = Cvar_Get ("showtrace", "0", 0);
        !          1105:        dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET);
        !          1106:        s = va("%4.2f %s %s %s", VERSION, CPUSTRING, __DATE__, BUILDSTRING);
        !          1107:        Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
        !          1108:        if (dedicated->value)
        !          1109:                Cmd_AddCommand ("quit", Com_Quit);
        !          1110:        Sys_Init ();
        !          1111:        NET_Init ();
        !          1112:        Netchan_Init ();
        !          1113:        SV_Init ();
        !          1114:        CL_Init ();
        !          1115:        // add + commands from command line
        !          1116:        if (!Cbuf_AddLateCommands ())
        !          1117:        {       // if the user didn't give any commands, run default action
        !          1118:                if (!dedicated->value)
        !          1119:                        Cbuf_AddText ("d1\n");
        !          1120:                else
        !          1121:                        Cbuf_AddText ("dedicated_start\n");
        !          1122:                Cbuf_Execute ();
        !          1123:        }
        !          1124:        else
        !          1125:        {       // the user asked for something explicit
        !          1126:                // so drop the loading plaque
        !          1127:                SCR_EndLoadingPlaque ();
        !          1128:        }
        !          1129:        Com_Printf ("====== Quake2 Initialized ======\n\n");    
        !          1130: }
        !          1131: /*
        !          1132: =================
        !          1133: Qcommon_Frame
        !          1134: =================
        !          1135: */
        !          1136: void Qcommon_Frame (int msec)
        !          1137: {
        !          1138:        char    *s;
        !          1139:        int             time_before, time_between, time_after;
        !          1140:        if (setjmp (abortframe) )
        !          1141:                return;                 // an ERR_DROP was thrown
        !          1142: 
        !          1143:        if ( log_stats->modified )
        !          1144:        {
        !          1145:                log_stats->modified = false;
        !          1146:                if ( log_stats->value )
        !          1147:                {
        !          1148:                        if ( log_stats_file )
        !          1149:                        {
        !          1150:                                fclose( log_stats_file );
        !          1151:                                log_stats_file = 0;
        !          1152:                        }
        !          1153:                        log_stats_file = fopen( "stats.log", "w" );
        !          1154:                        if ( log_stats_file )
        !          1155:                                fprintf( log_stats_file, "entities,dlights,parts,frame time\n" );
        !          1156:                }
        !          1157:                else
        !          1158:                {
        !          1159:                        if ( log_stats_file )
        !          1160:                        {
        !          1161:                                fclose( log_stats_file );
        !          1162:                                log_stats_file = 0;
        !          1163:                        }
        !          1164:                }
        !          1165:        }
        !          1166:        if (fixedtime->value)
        !          1167:                msec = fixedtime->value;
        !          1168:        else if (timescale->value)
        !          1169:        {
        !          1170:                msec *= timescale->value;
        !          1171:                if (msec < 1)
        !          1172:                        msec = 1;
        !          1173:        }
        !          1174: 
        !          1175:        if (showtrace->value)
        !          1176:        {
        !          1177:                extern  int c_traces, c_brush_traces;
        !          1178:                extern  int     c_pointcontents;
        !          1179:                Com_Printf ("%4i traces  %4i points\n", c_traces, c_pointcontents);
        !          1180:                c_traces = 0;
        !          1181:                c_brush_traces = 0;
        !          1182:                c_pointcontents = 0;
        !          1183:        }
        !          1184:        do
        !          1185:        {
        !          1186:                s = Sys_ConsoleInput ();
        !          1187:                if (s)
        !          1188:                        Cbuf_AddText (va("%s\n",s));
        !          1189:        } while (s);
        !          1190:        Cbuf_Execute ();
        !          1191:        if (host_speeds->value)
        !          1192:                time_before = Sys_Milliseconds ();
        !          1193:        SV_Frame (msec);
        !          1194:        if (host_speeds->value)
        !          1195:                time_between = Sys_Milliseconds ();             
        !          1196:        CL_Frame (msec);
        !          1197:        if (host_speeds->value)
        !          1198:                time_after = Sys_Milliseconds ();               
        !          1199:        if (host_speeds->value)
        !          1200:        {
        !          1201:                int                     all, sv, gm, cl, rf;
        !          1202:                all = time_after - time_before;
        !          1203:                sv = time_between - time_before;
        !          1204:                cl = time_after - time_between;
        !          1205:                gm = time_after_game - time_before_game;
        !          1206:                rf = time_after_ref - time_before_ref;
        !          1207:                sv -= gm;
        !          1208:                cl -= rf;
        !          1209:                Com_Printf ("all:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n",
        !          1210:                        all, sv, gm, cl, rf);
        !          1211:        }       
        !          1212: }
        !          1213: /*
        !          1214: =================
        !          1215: Qcommon_Shutdown
        !          1216: =================
        !          1217: */
        !          1218: void Qcommon_Shutdown (void)
        !          1219: {
        !          1220: }

unix.superglobalmegacorp.com

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