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

1.1.1.4 ! 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: // common.c -- misc functions used in client and server
                     21: #include "qcommon.h"
                     22: #include <setjmp.h>
1.1.1.2   root       23: 
1.1       root       24: #define        MAXPRINTMSG     4096
1.1.1.2   root       25: 
1.1       root       26: #define MAX_NUM_ARGVS  50
1.1.1.2   root       27: 
                     28: 
1.1       root       29: int            com_argc;
                     30: char   *com_argv[MAX_NUM_ARGVS+1];
1.1.1.2   root       31: 
1.1       root       32: int            realtime;
1.1.1.2   root       33: 
1.1       root       34: jmp_buf abortframe;            // an ERR_DROP occured, exit the entire frame
                     35: 
1.1.1.2   root       36: 
1.1       root       37: FILE   *log_stats_file;
1.1.1.2   root       38: 
1.1       root       39: cvar_t *host_speeds;
                     40: cvar_t *log_stats;
                     41: cvar_t *developer;
                     42: cvar_t *timescale;
                     43: cvar_t *fixedtime;
                     44: cvar_t *logfile_active;        // 1 = buffer log, 2 = flush after each print
                     45: cvar_t *showtrace;
                     46: cvar_t *dedicated;
1.1.1.2   root       47: 
1.1       root       48: FILE   *logfile;
1.1.1.2   root       49: 
1.1       root       50: int                    server_state;
1.1.1.2   root       51: 
1.1       root       52: // host_speeds times
                     53: int            time_before_game;
                     54: int            time_after_game;
                     55: int            time_before_ref;
                     56: int            time_after_ref;
1.1.1.2   root       57: 
1.1       root       58: /*
                     59: ============================================================================
1.1.1.2   root       60: 
1.1       root       61: CLIENT / SERVER interactions
1.1.1.2   root       62: 
1.1       root       63: ============================================================================
                     64: */
1.1.1.2   root       65: 
1.1       root       66: static int     rd_target;
                     67: static char    *rd_buffer;
                     68: static int     rd_buffersize;
                     69: static void    (*rd_flush)(int target, char *buffer);
1.1.1.2   root       70: 
1.1       root       71: void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush))
                     72: {
                     73:        if (!target || !buffer || !buffersize || !flush)
                     74:                return;
                     75:        rd_target = target;
                     76:        rd_buffer = buffer;
                     77:        rd_buffersize = buffersize;
                     78:        rd_flush = flush;
                     79: 
                     80:        *rd_buffer = 0;
                     81: }
                     82: 
                     83: void Com_EndRedirect (void)
                     84: {
                     85:        rd_flush(rd_target, rd_buffer);
                     86: 
                     87:        rd_target = 0;
                     88:        rd_buffer = NULL;
                     89:        rd_buffersize = 0;
                     90:        rd_flush = NULL;
                     91: }
                     92: 
                     93: /*
                     94: =============
                     95: Com_Printf
1.1.1.2   root       96: 
1.1       root       97: Both client and server can use this, and it will output
                     98: to the apropriate place.
                     99: =============
                    100: */
                    101: void Com_Printf (char *fmt, ...)
                    102: {
                    103:        va_list         argptr;
                    104:        char            msg[MAXPRINTMSG];
1.1.1.2   root      105: 
1.1       root      106:        va_start (argptr,fmt);
                    107:        vsprintf (msg,fmt,argptr);
                    108:        va_end (argptr);
1.1.1.2   root      109: 
1.1       root      110:        if (rd_target)
                    111:        {
                    112:                if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1))
                    113:                {
                    114:                        rd_flush(rd_target, rd_buffer);
                    115:                        *rd_buffer = 0;
                    116:                }
                    117:                strcat (rd_buffer, msg);
                    118:                return;
                    119:        }
                    120: 
                    121:        Con_Print (msg);
                    122:                
                    123:        // also echo to debugging console
                    124:        Sys_ConsoleOutput (msg);
1.1.1.2   root      125: 
1.1       root      126:        // logfile
                    127:        if (logfile_active && logfile_active->value)
                    128:        {
                    129:                char    name[MAX_QPATH];
                    130:                
                    131:                if (!logfile)
                    132:                {
                    133:                        Com_sprintf (name, sizeof(name), "%s/qconsole.log", FS_Gamedir ());
1.1.1.4 ! root      134:                        if (logfile_active->value > 2)
        !           135:                                logfile = fopen (name, "a");
        !           136:                        else
        !           137:                                logfile = fopen (name, "w");
1.1       root      138:                }
                    139:                if (logfile)
                    140:                        fprintf (logfile, "%s", msg);
                    141:                if (logfile_active->value > 1)
                    142:                        fflush (logfile);               // force it to save every time
                    143:        }
                    144: }
1.1.1.2   root      145: 
                    146: 
1.1       root      147: /*
                    148: ================
                    149: Com_DPrintf
1.1.1.2   root      150: 
1.1       root      151: A Com_Printf that only shows up if the "developer" cvar is set
                    152: ================
                    153: */
                    154: void Com_DPrintf (char *fmt, ...)
                    155: {
                    156:        va_list         argptr;
                    157:        char            msg[MAXPRINTMSG];
                    158:                
                    159:        if (!developer || !developer->value)
                    160:                return;                 // don't confuse non-developers with techie stuff...
1.1.1.2   root      161: 
1.1       root      162:        va_start (argptr,fmt);
                    163:        vsprintf (msg,fmt,argptr);
                    164:        va_end (argptr);
                    165:        
                    166:        Com_Printf ("%s", msg);
                    167: }
1.1.1.2   root      168: 
                    169: 
1.1       root      170: /*
                    171: =============
                    172: Com_Error
1.1.1.2   root      173: 
1.1       root      174: Both client and server can use this, and it will
                    175: do the apropriate things.
                    176: =============
                    177: */
                    178: void Com_Error (int code, char *fmt, ...)
                    179: {
                    180:        va_list         argptr;
                    181:        static char             msg[MAXPRINTMSG];
                    182:        static  qboolean        recursive;
1.1.1.2   root      183: 
1.1       root      184:        if (recursive)
                    185:                Sys_Error ("recursive error after: %s", msg);
                    186:        recursive = true;
1.1.1.2   root      187: 
1.1       root      188:        va_start (argptr,fmt);
                    189:        vsprintf (msg,fmt,argptr);
                    190:        va_end (argptr);
                    191:        
                    192:        if (code == ERR_DISCONNECT)
                    193:        {
                    194:                CL_Drop ();
                    195:                recursive = false;
                    196:                longjmp (abortframe, -1);
                    197:        }
                    198:        else if (code == ERR_DROP)
                    199:        {
                    200:                Com_Printf ("********************\nERROR: %s\n********************\n", msg);
                    201:                SV_Shutdown (va("Server crashed: %s\n", msg), false);
                    202:                CL_Drop ();
                    203:                recursive = false;
                    204:                longjmp (abortframe, -1);
                    205:        }
                    206:        else
                    207:        {
                    208:                SV_Shutdown (va("Server fatal crashed: %s\n", msg), false);
                    209:                CL_Shutdown ();
                    210:        }
1.1.1.2   root      211: 
1.1       root      212:        if (logfile)
                    213:        {
                    214:                fclose (logfile);
                    215:                logfile = NULL;
                    216:        }
1.1.1.2   root      217: 
1.1       root      218:        Sys_Error ("%s", msg);
                    219: }
1.1.1.2   root      220: 
                    221: 
1.1       root      222: /*
                    223: =============
                    224: Com_Quit
1.1.1.2   root      225: 
1.1       root      226: Both client and server can use this, and it will
                    227: do the apropriate things.
                    228: =============
                    229: */
                    230: void Com_Quit (void)
                    231: {
                    232:        SV_Shutdown ("Server quit\n", false);
                    233:        CL_Shutdown ();
1.1.1.2   root      234: 
1.1       root      235:        if (logfile)
                    236:        {
                    237:                fclose (logfile);
                    238:                logfile = NULL;
                    239:        }
1.1.1.2   root      240: 
1.1       root      241:        Sys_Quit ();
                    242: }
1.1.1.2   root      243: 
                    244: 
1.1       root      245: /*
                    246: ==================
                    247: Com_ServerState
                    248: ==================
                    249: */
                    250: int Com_ServerState (void)
                    251: {
                    252:        return server_state;
                    253: }
1.1.1.2   root      254: 
1.1       root      255: /*
                    256: ==================
                    257: Com_SetServerState
                    258: ==================
                    259: */
                    260: void Com_SetServerState (int state)
                    261: {
                    262:        server_state = state;
                    263: }
1.1.1.2   root      264: 
                    265: 
1.1       root      266: /*
                    267: ==============================================================================
1.1.1.2   root      268: 
1.1       root      269:                        MESSAGE IO FUNCTIONS
1.1.1.2   root      270: 
1.1       root      271: Handles byte ordering and avoids alignment errors
                    272: ==============================================================================
                    273: */
1.1.1.2   root      274: 
1.1       root      275: vec3_t bytedirs[NUMVERTEXNORMALS] =
                    276: {
                    277: #include "../client/anorms.h"
                    278: };
1.1.1.2   root      279: 
1.1       root      280: //
                    281: // writing functions
                    282: //
1.1.1.2   root      283: 
1.1       root      284: void MSG_WriteChar (sizebuf_t *sb, int c)
                    285: {
                    286:        byte    *buf;
                    287:        
                    288: #ifdef PARANOID
                    289:        if (c < -128 || c > 127)
                    290:                Com_Error (ERR_FATAL, "MSG_WriteChar: range error");
                    291: #endif
1.1.1.2   root      292: 
1.1       root      293:        buf = SZ_GetSpace (sb, 1);
                    294:        buf[0] = c;
                    295: }
1.1.1.2   root      296: 
1.1       root      297: void MSG_WriteByte (sizebuf_t *sb, int c)
                    298: {
                    299:        byte    *buf;
                    300:        
                    301: #ifdef PARANOID
                    302:        if (c < 0 || c > 255)
                    303:                Com_Error (ERR_FATAL, "MSG_WriteByte: range error");
                    304: #endif
1.1.1.2   root      305: 
1.1       root      306:        buf = SZ_GetSpace (sb, 1);
                    307:        buf[0] = c;
                    308: }
1.1.1.2   root      309: 
1.1       root      310: void MSG_WriteShort (sizebuf_t *sb, int c)
                    311: {
                    312:        byte    *buf;
                    313:        
                    314: #ifdef PARANOID
                    315:        if (c < ((short)0x8000) || c > (short)0x7fff)
                    316:                Com_Error (ERR_FATAL, "MSG_WriteShort: range error");
                    317: #endif
1.1.1.2   root      318: 
1.1       root      319:        buf = SZ_GetSpace (sb, 2);
                    320:        buf[0] = c&0xff;
                    321:        buf[1] = c>>8;
                    322: }
1.1.1.2   root      323: 
1.1       root      324: void MSG_WriteLong (sizebuf_t *sb, int c)
                    325: {
                    326:        byte    *buf;
                    327:        
                    328:        buf = SZ_GetSpace (sb, 4);
                    329:        buf[0] = c&0xff;
                    330:        buf[1] = (c>>8)&0xff;
                    331:        buf[2] = (c>>16)&0xff;
                    332:        buf[3] = c>>24;
                    333: }
1.1.1.2   root      334: 
1.1       root      335: void MSG_WriteFloat (sizebuf_t *sb, float f)
                    336: {
                    337:        union
                    338:        {
                    339:                float   f;
                    340:                int     l;
                    341:        } dat;
                    342:        
                    343:        
                    344:        dat.f = f;
                    345:        dat.l = LittleLong (dat.l);
                    346:        
                    347:        SZ_Write (sb, &dat.l, 4);
                    348: }
1.1.1.2   root      349: 
1.1       root      350: void MSG_WriteString (sizebuf_t *sb, char *s)
                    351: {
                    352:        if (!s)
                    353:                SZ_Write (sb, "", 1);
                    354:        else
                    355:                SZ_Write (sb, s, strlen(s)+1);
                    356: }
1.1.1.2   root      357: 
1.1       root      358: void MSG_WriteCoord (sizebuf_t *sb, float f)
                    359: {
                    360:        MSG_WriteShort (sb, (int)(f*8));
                    361: }
1.1.1.2   root      362: 
1.1       root      363: void MSG_WritePos (sizebuf_t *sb, vec3_t pos)
                    364: {
                    365:        MSG_WriteShort (sb, (int)(pos[0]*8));
                    366:        MSG_WriteShort (sb, (int)(pos[1]*8));
                    367:        MSG_WriteShort (sb, (int)(pos[2]*8));
                    368: }
1.1.1.2   root      369: 
1.1       root      370: void MSG_WriteAngle (sizebuf_t *sb, float f)
                    371: {
                    372:        MSG_WriteByte (sb, (int)(f*256/360) & 255);
                    373: }
1.1.1.2   root      374: 
1.1       root      375: void MSG_WriteAngle16 (sizebuf_t *sb, float f)
                    376: {
                    377:        MSG_WriteShort (sb, ANGLE2SHORT(f));
                    378: }
                    379: 
1.1.1.2   root      380: 
1.1       root      381: void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
                    382: {
                    383:        int             bits;
1.1.1.2   root      384: 
1.1       root      385: //
                    386: // send the movement message
                    387: //
                    388:        bits = 0;
                    389:        if (cmd->angles[0] != from->angles[0])
                    390:                bits |= CM_ANGLE1;
                    391:        if (cmd->angles[1] != from->angles[1])
                    392:                bits |= CM_ANGLE2;
                    393:        if (cmd->angles[2] != from->angles[2])
                    394:                bits |= CM_ANGLE3;
                    395:        if (cmd->forwardmove != from->forwardmove)
                    396:                bits |= CM_FORWARD;
                    397:        if (cmd->sidemove != from->sidemove)
                    398:                bits |= CM_SIDE;
                    399:        if (cmd->upmove != from->upmove)
                    400:                bits |= CM_UP;
                    401:        if (cmd->buttons != from->buttons)
                    402:                bits |= CM_BUTTONS;
                    403:        if (cmd->impulse != from->impulse)
                    404:                bits |= CM_IMPULSE;
1.1.1.2   root      405: 
1.1       root      406:     MSG_WriteByte (buf, bits);
1.1.1.2   root      407: 
1.1       root      408:        if (bits & CM_ANGLE1)
                    409:                MSG_WriteShort (buf, cmd->angles[0]);
                    410:        if (bits & CM_ANGLE2)
                    411:                MSG_WriteShort (buf, cmd->angles[1]);
                    412:        if (bits & CM_ANGLE3)
                    413:                MSG_WriteShort (buf, cmd->angles[2]);
                    414:        
                    415:        if (bits & CM_FORWARD)
                    416:                MSG_WriteShort (buf, cmd->forwardmove);
                    417:        if (bits & CM_SIDE)
                    418:                MSG_WriteShort (buf, cmd->sidemove);
                    419:        if (bits & CM_UP)
                    420:                MSG_WriteShort (buf, cmd->upmove);
1.1.1.2   root      421: 
1.1       root      422:        if (bits & CM_BUTTONS)
                    423:                MSG_WriteByte (buf, cmd->buttons);
                    424:        if (bits & CM_IMPULSE)
                    425:            MSG_WriteByte (buf, cmd->impulse);
1.1.1.2   root      426: 
1.1       root      427:     MSG_WriteByte (buf, cmd->msec);
                    428:        MSG_WriteByte (buf, cmd->lightlevel);
                    429: }
1.1.1.2   root      430: 
                    431: 
1.1       root      432: void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
                    433: {
                    434:        int             i, best;
                    435:        float   d, bestd;
                    436:        
                    437:        if (!dir)
                    438:        {
                    439:                MSG_WriteByte (sb, 0);
                    440:                return;
                    441:        }
1.1.1.2   root      442: 
1.1       root      443:        bestd = 0;
                    444:        best = 0;
                    445:        for (i=0 ; i<NUMVERTEXNORMALS ; i++)
                    446:        {
                    447:                d = DotProduct (dir, bytedirs[i]);
                    448:                if (d > bestd)
                    449:                {
                    450:                        bestd = d;
                    451:                        best = i;
                    452:                }
                    453:        }
                    454:        MSG_WriteByte (sb, best);
                    455: }
1.1.1.2   root      456: 
                    457: 
1.1       root      458: void MSG_ReadDir (sizebuf_t *sb, vec3_t dir)
                    459: {
                    460:        int             b;
1.1.1.2   root      461: 
1.1       root      462:        b = MSG_ReadByte (sb);
                    463:        if (b >= NUMVERTEXNORMALS)
                    464:                Com_Error (ERR_DROP, "MSF_ReadDir: out of range");
                    465:        VectorCopy (bytedirs[b], dir);
                    466: }
1.1.1.2   root      467: 
                    468: 
1.1       root      469: /*
                    470: ==================
                    471: MSG_WriteDeltaEntity
1.1.1.2   root      472: 
1.1       root      473: Writes part of a packetentities message.
                    474: Can delta from either a baseline or a previous packet_entity
                    475: ==================
                    476: */
1.1.1.2   root      477: void MSG_WriteDeltaEntity (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity)
1.1       root      478: {
                    479:        int             bits;
                    480: 
                    481:        if (!to->number)
                    482:                Com_Error (ERR_FATAL, "Unset entity number");
                    483:        if (to->number >= MAX_EDICTS)
                    484:                Com_Error (ERR_FATAL, "Entity number >= MAX_EDICTS");
1.1.1.2   root      485: 
1.1       root      486: // send an update
                    487:        bits = 0;
                    488: 
                    489:        if (to->number >= 256)
                    490:                bits |= U_NUMBER16;             // number8 is implicit otherwise
                    491: 
                    492:        if (to->origin[0] != from->origin[0])
                    493:                bits |= U_ORIGIN1;
                    494:        if (to->origin[1] != from->origin[1])
                    495:                bits |= U_ORIGIN2;
                    496:        if (to->origin[2] != from->origin[2])
                    497:                bits |= U_ORIGIN3;
1.1.1.2   root      498: 
1.1       root      499:        if ( to->angles[0] != from->angles[0] )
                    500:                bits |= U_ANGLE1;               
                    501:        if ( to->angles[1] != from->angles[1] )
                    502:                bits |= U_ANGLE2;
                    503:        if ( to->angles[2] != from->angles[2] )
                    504:                bits |= U_ANGLE3;
                    505:                
                    506:        if ( to->skinnum != from->skinnum )
                    507:        {
                    508:                if ((unsigned)to->skinnum < 256)
                    509:                        bits |= U_SKIN8;
                    510:                else if ((unsigned)to->skinnum < 0x10000)
                    511:                        bits |= U_SKIN16;
                    512:                else
                    513:                        bits |= (U_SKIN8|U_SKIN16);
                    514:        }
                    515:                
                    516:        if ( to->frame != from->frame )
                    517:        {
                    518:                if (to->frame < 256)
                    519:                        bits |= U_FRAME8;
                    520:                else
                    521:                        bits |= U_FRAME16;
                    522:        }
1.1.1.2   root      523: 
1.1       root      524:        if ( to->effects != from->effects )
                    525:        {
                    526:                if (to->effects < 256)
                    527:                        bits |= U_EFFECTS8;
                    528:                else if (to->effects < 0x8000)
                    529:                        bits |= U_EFFECTS16;
                    530:                else
                    531:                        bits |= U_EFFECTS8|U_EFFECTS16;
                    532:        }
                    533:        
                    534:        if ( to->renderfx != from->renderfx )
                    535:        {
                    536:                if (to->renderfx < 256)
                    537:                        bits |= U_RENDERFX8;
                    538:                else if (to->renderfx < 0x8000)
                    539:                        bits |= U_RENDERFX16;
                    540:                else
                    541:                        bits |= U_RENDERFX8|U_RENDERFX16;
                    542:        }
                    543:        
                    544:        if ( to->solid != from->solid )
                    545:                bits |= U_SOLID;
1.1.1.3   root      546: 
1.1       root      547:        // event is not delta compressed, just 0 compressed
                    548:        if ( to->event  )
                    549:                bits |= U_EVENT;
                    550:        
                    551:        if ( to->modelindex != from->modelindex )
                    552:                bits |= U_MODEL;
                    553:        if ( to->modelindex2 != from->modelindex2 )
                    554:                bits |= U_MODEL2;
                    555:        if ( to->modelindex3 != from->modelindex3 )
                    556:                bits |= U_MODEL3;
                    557:        if ( to->modelindex4 != from->modelindex4 )
                    558:                bits |= U_MODEL4;
1.1.1.2   root      559: 
1.1       root      560:        if ( to->sound != from->sound )
                    561:                bits |= U_SOUND;
                    562: 
1.1.1.2   root      563:        if (newentity || (to->renderfx & RF_BEAM))
                    564:                bits |= U_OLDORIGIN;
                    565: 
1.1       root      566:        //
                    567:        // write the message
                    568:        //
                    569:        if (!bits && !force)
                    570:                return;         // nothing to send!
1.1.1.2   root      571: 
1.1       root      572:        //----------
                    573: 
                    574:        if (bits & 0xff000000)
                    575:                bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1;
                    576:        else if (bits & 0x00ff0000)
                    577:                bits |= U_MOREBITS2 | U_MOREBITS1;
                    578:        else if (bits & 0x0000ff00)
                    579:                bits |= U_MOREBITS1;
1.1.1.2   root      580: 
1.1       root      581:        MSG_WriteByte (msg,     bits&255 );
1.1.1.2   root      582: 
1.1       root      583:        if (bits & 0xff000000)
                    584:        {
                    585:                MSG_WriteByte (msg,     (bits>>8)&255 );
                    586:                MSG_WriteByte (msg,     (bits>>16)&255 );
                    587:                MSG_WriteByte (msg,     (bits>>24)&255 );
                    588:        }
                    589:        else if (bits & 0x00ff0000)
                    590:        {
                    591:                MSG_WriteByte (msg,     (bits>>8)&255 );
                    592:                MSG_WriteByte (msg,     (bits>>16)&255 );
                    593:        }
                    594:        else if (bits & 0x0000ff00)
                    595:        {
                    596:                MSG_WriteByte (msg,     (bits>>8)&255 );
                    597:        }
1.1.1.2   root      598: 
1.1       root      599:        //----------
                    600: 
                    601:        if (bits & U_NUMBER16)
                    602:                MSG_WriteShort (msg, to->number);
                    603:        else
                    604:                MSG_WriteByte (msg,     to->number);
1.1.1.2   root      605: 
1.1       root      606:        if (bits & U_MODEL)
                    607:                MSG_WriteByte (msg,     to->modelindex);
                    608:        if (bits & U_MODEL2)
                    609:                MSG_WriteByte (msg,     to->modelindex2);
                    610:        if (bits & U_MODEL3)
                    611:                MSG_WriteByte (msg,     to->modelindex3);
                    612:        if (bits & U_MODEL4)
                    613:                MSG_WriteByte (msg,     to->modelindex4);
1.1.1.2   root      614: 
1.1       root      615:        if (bits & U_FRAME8)
                    616:                MSG_WriteByte (msg, to->frame);
                    617:        if (bits & U_FRAME16)
                    618:                MSG_WriteShort (msg, to->frame);
1.1.1.2   root      619: 
1.1       root      620:        if ((bits & U_SKIN8) && (bits & U_SKIN16))              //used for laser colors
                    621:                MSG_WriteLong (msg, to->skinnum);
                    622:        else if (bits & U_SKIN8)
                    623:                MSG_WriteByte (msg, to->skinnum);
                    624:        else if (bits & U_SKIN16)
                    625:                MSG_WriteShort (msg, to->skinnum);
                    626: 
1.1.1.2   root      627: 
1.1       root      628:        if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
                    629:                MSG_WriteLong (msg, to->effects);
                    630:        else if (bits & U_EFFECTS8)
                    631:                MSG_WriteByte (msg, to->effects);
                    632:        else if (bits & U_EFFECTS16)
                    633:                MSG_WriteShort (msg, to->effects);
1.1.1.2   root      634: 
1.1       root      635:        if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
                    636:                MSG_WriteLong (msg, to->renderfx);
                    637:        else if (bits & U_RENDERFX8)
                    638:                MSG_WriteByte (msg, to->renderfx);
                    639:        else if (bits & U_RENDERFX16)
                    640:                MSG_WriteShort (msg, to->renderfx);
1.1.1.2   root      641: 
1.1       root      642:        if (bits & U_ORIGIN1)
                    643:                MSG_WriteCoord (msg, to->origin[0]);            
                    644:        if (bits & U_ORIGIN2)
                    645:                MSG_WriteCoord (msg, to->origin[1]);
                    646:        if (bits & U_ORIGIN3)
                    647:                MSG_WriteCoord (msg, to->origin[2]);
1.1.1.2   root      648: 
1.1       root      649:        if (bits & U_ANGLE1)
                    650:                MSG_WriteAngle(msg, to->angles[0]);
                    651:        if (bits & U_ANGLE2)
                    652:                MSG_WriteAngle(msg, to->angles[1]);
                    653:        if (bits & U_ANGLE3)
                    654:                MSG_WriteAngle(msg, to->angles[2]);
1.1.1.2   root      655: 
1.1       root      656:        if (bits & U_OLDORIGIN)
                    657:        {
                    658:                MSG_WriteCoord (msg, to->old_origin[0]);
                    659:                MSG_WriteCoord (msg, to->old_origin[1]);
                    660:                MSG_WriteCoord (msg, to->old_origin[2]);
                    661:        }
1.1.1.2   root      662: 
1.1       root      663:        if (bits & U_SOUND)
                    664:                MSG_WriteByte (msg, to->sound);
                    665:        if (bits & U_EVENT)
                    666:                MSG_WriteByte (msg, to->event);
                    667:        if (bits & U_SOLID)
                    668:                MSG_WriteShort (msg, to->solid);
                    669: }
1.1.1.2   root      670: 
                    671: 
1.1       root      672: //============================================================
1.1.1.2   root      673: 
1.1       root      674: //
                    675: // reading functions
                    676: //
1.1.1.2   root      677: 
1.1       root      678: void MSG_BeginReading (sizebuf_t *msg)
                    679: {
                    680:        msg->readcount = 0;
                    681: }
1.1.1.2   root      682: 
1.1       root      683: // returns -1 if no more characters are available
                    684: int MSG_ReadChar (sizebuf_t *msg_read)
                    685: {
                    686:        int     c;
                    687:        
                    688:        if (msg_read->readcount+1 > msg_read->cursize)
                    689:                c = -1;
                    690:        else
                    691:                c = (signed char)msg_read->data[msg_read->readcount];
                    692:        msg_read->readcount++;
                    693:        
                    694:        return c;
                    695: }
1.1.1.2   root      696: 
1.1       root      697: int MSG_ReadByte (sizebuf_t *msg_read)
                    698: {
                    699:        int     c;
                    700:        
                    701:        if (msg_read->readcount+1 > msg_read->cursize)
                    702:                c = -1;
                    703:        else
                    704:                c = (unsigned char)msg_read->data[msg_read->readcount];
                    705:        msg_read->readcount++;
                    706:        
                    707:        return c;
                    708: }
1.1.1.2   root      709: 
1.1       root      710: int MSG_ReadShort (sizebuf_t *msg_read)
                    711: {
                    712:        int     c;
                    713:        
                    714:        if (msg_read->readcount+2 > msg_read->cursize)
                    715:                c = -1;
                    716:        else            
                    717:                c = (short)(msg_read->data[msg_read->readcount]
                    718:                + (msg_read->data[msg_read->readcount+1]<<8));
                    719:        
                    720:        msg_read->readcount += 2;
                    721:        
                    722:        return c;
                    723: }
1.1.1.2   root      724: 
1.1       root      725: int MSG_ReadLong (sizebuf_t *msg_read)
                    726: {
                    727:        int     c;
                    728:        
                    729:        if (msg_read->readcount+4 > msg_read->cursize)
                    730:                c = -1;
                    731:        else
                    732:                c = msg_read->data[msg_read->readcount]
                    733:                + (msg_read->data[msg_read->readcount+1]<<8)
                    734:                + (msg_read->data[msg_read->readcount+2]<<16)
                    735:                + (msg_read->data[msg_read->readcount+3]<<24);
                    736:        
                    737:        msg_read->readcount += 4;
                    738:        
                    739:        return c;
                    740: }
1.1.1.2   root      741: 
1.1       root      742: float MSG_ReadFloat (sizebuf_t *msg_read)
                    743: {
                    744:        union
                    745:        {
                    746:                byte    b[4];
                    747:                float   f;
                    748:                int     l;
                    749:        } dat;
                    750:        
                    751:        if (msg_read->readcount+4 > msg_read->cursize)
                    752:                dat.f = -1;
                    753:        else
                    754:        {
                    755:                dat.b[0] =      msg_read->data[msg_read->readcount];
                    756:                dat.b[1] =      msg_read->data[msg_read->readcount+1];
                    757:                dat.b[2] =      msg_read->data[msg_read->readcount+2];
                    758:                dat.b[3] =      msg_read->data[msg_read->readcount+3];
                    759:        }
                    760:        msg_read->readcount += 4;
                    761:        
                    762:        dat.l = LittleLong (dat.l);
1.1.1.2   root      763: 
1.1       root      764:        return dat.f;   
                    765: }
1.1.1.2   root      766: 
1.1       root      767: char *MSG_ReadString (sizebuf_t *msg_read)
                    768: {
                    769:        static char     string[2048];
                    770:        int             l,c;
                    771:        
                    772:        l = 0;
                    773:        do
                    774:        {
                    775:                c = MSG_ReadChar (msg_read);
                    776:                if (c == -1 || c == 0)
                    777:                        break;
                    778:                string[l] = c;
                    779:                l++;
                    780:        } while (l < sizeof(string)-1);
                    781:        
                    782:        string[l] = 0;
                    783:        
                    784:        return string;
                    785: }
1.1.1.2   root      786: 
1.1       root      787: char *MSG_ReadStringLine (sizebuf_t *msg_read)
                    788: {
                    789:        static char     string[2048];
                    790:        int             l,c;
                    791:        
                    792:        l = 0;
                    793:        do
                    794:        {
                    795:                c = MSG_ReadChar (msg_read);
                    796:                if (c == -1 || c == 0 || c == '\n')
                    797:                        break;
                    798:                string[l] = c;
                    799:                l++;
                    800:        } while (l < sizeof(string)-1);
                    801:        
                    802:        string[l] = 0;
                    803:        
                    804:        return string;
                    805: }
1.1.1.2   root      806: 
1.1       root      807: float MSG_ReadCoord (sizebuf_t *msg_read)
                    808: {
                    809:        return MSG_ReadShort(msg_read) * (1.0/8);
                    810: }
1.1.1.2   root      811: 
1.1       root      812: void MSG_ReadPos (sizebuf_t *msg_read, vec3_t pos)
                    813: {
                    814:        pos[0] = MSG_ReadShort(msg_read) * (1.0/8);
                    815:        pos[1] = MSG_ReadShort(msg_read) * (1.0/8);
                    816:        pos[2] = MSG_ReadShort(msg_read) * (1.0/8);
                    817: }
1.1.1.2   root      818: 
1.1       root      819: float MSG_ReadAngle (sizebuf_t *msg_read)
                    820: {
                    821:        return MSG_ReadChar(msg_read) * (360.0/256);
                    822: }
1.1.1.2   root      823: 
1.1       root      824: float MSG_ReadAngle16 (sizebuf_t *msg_read)
                    825: {
                    826:        return SHORT2ANGLE(MSG_ReadShort(msg_read));
                    827: }
1.1.1.2   root      828: 
1.1       root      829: void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move)
                    830: {
                    831:        int bits;
1.1.1.2   root      832: 
1.1       root      833:        memcpy (move, from, sizeof(*move));
1.1.1.2   root      834: 
1.1       root      835:        bits = MSG_ReadByte (msg_read);
                    836:                
                    837: // read current angles
                    838:        if (bits & CM_ANGLE1)
                    839:                move->angles[0] = MSG_ReadShort (msg_read);
                    840:        if (bits & CM_ANGLE2)
                    841:                move->angles[1] = MSG_ReadShort (msg_read);
                    842:        if (bits & CM_ANGLE3)
                    843:                move->angles[2] = MSG_ReadShort (msg_read);
                    844:                
                    845: // read movement
                    846:        if (bits & CM_FORWARD)
                    847:                move->forwardmove = MSG_ReadShort (msg_read);
                    848:        if (bits & CM_SIDE)
                    849:                move->sidemove = MSG_ReadShort (msg_read);
                    850:        if (bits & CM_UP)
                    851:                move->upmove = MSG_ReadShort (msg_read);
                    852:        
                    853: // read buttons
                    854:        if (bits & CM_BUTTONS)
                    855:                move->buttons = MSG_ReadByte (msg_read);
1.1.1.2   root      856: 
1.1       root      857:        if (bits & CM_IMPULSE)
                    858:                move->impulse = MSG_ReadByte (msg_read);
1.1.1.2   root      859: 
1.1       root      860: // read time to run command
                    861:        move->msec = MSG_ReadByte (msg_read);
1.1.1.2   root      862: 
1.1       root      863: // read the light level
                    864:        move->lightlevel = MSG_ReadByte (msg_read);
                    865: }
1.1.1.2   root      866: 
                    867: 
1.1       root      868: void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
                    869: {
                    870:        int             i;
1.1.1.2   root      871: 
1.1       root      872:        for (i=0 ; i<len ; i++)
                    873:                ((byte *)data)[i] = MSG_ReadByte (msg_read);
                    874: }
1.1.1.2   root      875: 
                    876: 
1.1       root      877: //===========================================================================
1.1.1.2   root      878: 
1.1       root      879: void SZ_Init (sizebuf_t *buf, byte *data, int length)
                    880: {
                    881:        memset (buf, 0, sizeof(*buf));
                    882:        buf->data = data;
                    883:        buf->maxsize = length;
                    884: }
1.1.1.2   root      885: 
1.1       root      886: void SZ_Clear (sizebuf_t *buf)
                    887: {
                    888:        buf->cursize = 0;
                    889:        buf->overflowed = false;
                    890: }
1.1.1.2   root      891: 
1.1       root      892: void *SZ_GetSpace (sizebuf_t *buf, int length)
                    893: {
                    894:        void    *data;
                    895:        
                    896:        if (buf->cursize + length > buf->maxsize)
                    897:        {
                    898:                if (!buf->allowoverflow)
                    899:                        Com_Error (ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set");
                    900:                
                    901:                if (length > buf->maxsize)
                    902:                        Com_Error (ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length);
                    903:                        
                    904:                Com_Printf ("SZ_GetSpace: overflow\n");
                    905:                SZ_Clear (buf); 
                    906:                buf->overflowed = true;
                    907:        }
1.1.1.2   root      908: 
1.1       root      909:        data = buf->data + buf->cursize;
                    910:        buf->cursize += length;
                    911:        
                    912:        return data;
                    913: }
1.1.1.2   root      914: 
1.1       root      915: void SZ_Write (sizebuf_t *buf, void *data, int length)
                    916: {
                    917:        memcpy (SZ_GetSpace(buf,length),data,length);           
                    918: }
1.1.1.2   root      919: 
1.1       root      920: void SZ_Print (sizebuf_t *buf, char *data)
                    921: {
                    922:        int             len;
                    923:        
                    924:        len = strlen(data)+1;
1.1.1.2   root      925: 
1.1       root      926:        if (buf->cursize)
                    927:        {
                    928:                if (buf->data[buf->cursize-1])
                    929:                        memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0
                    930:                else
                    931:                        memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
                    932:        }
                    933:        else
                    934:                memcpy ((byte *)SZ_GetSpace(buf, len),data,len);
                    935: }
1.1.1.2   root      936: 
                    937: 
1.1       root      938: //============================================================================
1.1.1.2   root      939: 
                    940: 
1.1       root      941: /*
                    942: ================
                    943: COM_CheckParm
1.1.1.2   root      944: 
1.1       root      945: Returns the position (1 to argc-1) in the program's argument list
                    946: where the given parameter apears, or 0 if not present
                    947: ================
                    948: */
                    949: int COM_CheckParm (char *parm)
                    950: {
                    951:        int             i;
                    952:        
                    953:        for (i=1 ; i<com_argc ; i++)
                    954:        {
                    955:                if (!strcmp (parm,com_argv[i]))
                    956:                        return i;
                    957:        }
                    958:                
                    959:        return 0;
                    960: }
1.1.1.2   root      961: 
1.1       root      962: int COM_Argc (void)
                    963: {
                    964:        return com_argc;
                    965: }
1.1.1.2   root      966: 
1.1       root      967: char *COM_Argv (int arg)
                    968: {
                    969:        if (arg < 0 || arg >= com_argc || !com_argv[arg])
                    970:                return "";
                    971:        return com_argv[arg];
                    972: }
1.1.1.2   root      973: 
1.1       root      974: void COM_ClearArgv (int arg)
                    975: {
                    976:        if (arg < 0 || arg >= com_argc || !com_argv[arg])
                    977:                return;
                    978:        com_argv[arg] = "";
                    979: }
1.1.1.2   root      980: 
                    981: 
1.1       root      982: /*
                    983: ================
                    984: COM_InitArgv
                    985: ================
                    986: */
                    987: void COM_InitArgv (int argc, char **argv)
                    988: {
                    989:        int             i;
1.1.1.2   root      990: 
1.1       root      991:        if (argc > MAX_NUM_ARGVS)
                    992:                Com_Error (ERR_FATAL, "argc > MAX_NUM_ARGVS");
                    993:        com_argc = argc;
                    994:        for (i=0 ; i<argc ; i++)
                    995:        {
                    996:                if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS )
                    997:                        com_argv[i] = "";
                    998:                else
                    999:                        com_argv[i] = argv[i];
                   1000:        }
                   1001: }
1.1.1.2   root     1002: 
1.1       root     1003: /*
                   1004: ================
                   1005: COM_AddParm
1.1.1.2   root     1006: 
1.1       root     1007: Adds the given string at the end of the current argument list
                   1008: ================
                   1009: */
                   1010: void COM_AddParm (char *parm)
                   1011: {
                   1012:        if (com_argc == MAX_NUM_ARGVS)
                   1013:                Com_Error (ERR_FATAL, "COM_AddParm: MAX_NUM)ARGS");
                   1014:        com_argv[com_argc++] = parm;
                   1015: }
1.1.1.2   root     1016: 
                   1017: 
                   1018: 
                   1019: 
1.1       root     1020: /// just for debugging
                   1021: int    memsearch (byte *start, int count, int search)
                   1022: {
                   1023:        int             i;
                   1024:        
                   1025:        for (i=0 ; i<count ; i++)
                   1026:                if (start[i] == search)
                   1027:                        return i;
                   1028:        return -1;
                   1029: }
1.1.1.2   root     1030: 
                   1031: 
1.1       root     1032: char *CopyString (char *in)
                   1033: {
                   1034:        char    *out;
                   1035:        
                   1036:        out = Z_Malloc (strlen(in)+1);
                   1037:        strcpy (out, in);
                   1038:        return out;
                   1039: }
1.1.1.2   root     1040: 
                   1041: 
                   1042: 
1.1       root     1043: void Info_Print (char *s)
                   1044: {
                   1045:        char    key[512];
                   1046:        char    value[512];
                   1047:        char    *o;
                   1048:        int             l;
1.1.1.2   root     1049: 
1.1       root     1050:        if (*s == '\\')
                   1051:                s++;
                   1052:        while (*s)
                   1053:        {
                   1054:                o = key;
                   1055:                while (*s && *s != '\\')
                   1056:                        *o++ = *s++;
1.1.1.2   root     1057: 
1.1       root     1058:                l = o - key;
                   1059:                if (l < 20)
                   1060:                {
                   1061:                        memset (o, ' ', 20-l);
                   1062:                        key[20] = 0;
                   1063:                }
                   1064:                else
                   1065:                        *o = 0;
                   1066:                Com_Printf ("%s", key);
1.1.1.2   root     1067: 
1.1       root     1068:                if (!*s)
                   1069:                {
                   1070:                        Com_Printf ("MISSING VALUE\n");
                   1071:                        return;
                   1072:                }
1.1.1.2   root     1073: 
1.1       root     1074:                o = value;
                   1075:                s++;
                   1076:                while (*s && *s != '\\')
                   1077:                        *o++ = *s++;
                   1078:                *o = 0;
1.1.1.2   root     1079: 
1.1       root     1080:                if (*s)
                   1081:                        s++;
                   1082:                Com_Printf ("%s\n", value);
                   1083:        }
                   1084: }
1.1.1.2   root     1085: 
                   1086: 
1.1       root     1087: /*
                   1088: ==============================================================================
1.1.1.2   root     1089: 
1.1       root     1090:                                                ZONE MEMORY ALLOCATION
1.1.1.2   root     1091: 
1.1       root     1092: just cleared malloc with counters now...
1.1.1.2   root     1093: 
1.1       root     1094: ==============================================================================
                   1095: */
1.1.1.2   root     1096: 
1.1       root     1097: #define        Z_MAGIC         0x1d1d
1.1.1.2   root     1098: 
                   1099: 
1.1       root     1100: typedef struct zhead_s
                   1101: {
                   1102:        struct zhead_s  *prev, *next;
                   1103:        short   magic;
                   1104:        short   tag;                    // for group free
                   1105:        int             size;
                   1106: } zhead_t;
1.1.1.2   root     1107: 
1.1       root     1108: zhead_t                z_chain;
                   1109: int            z_count, z_bytes;
1.1.1.2   root     1110: 
1.1       root     1111: /*
                   1112: ========================
                   1113: Z_Free
                   1114: ========================
                   1115: */
                   1116: void Z_Free (void *ptr)
                   1117: {
                   1118:        zhead_t *z;
1.1.1.2   root     1119: 
1.1       root     1120:        z = ((zhead_t *)ptr) - 1;
1.1.1.2   root     1121: 
1.1       root     1122:        if (z->magic != Z_MAGIC)
                   1123:                Com_Error (ERR_FATAL, "Z_Free: bad magic");
1.1.1.2   root     1124: 
1.1       root     1125:        z->prev->next = z->next;
                   1126:        z->next->prev = z->prev;
1.1.1.2   root     1127: 
1.1       root     1128:        z_count--;
                   1129:        z_bytes -= z->size;
                   1130:        free (z);
                   1131: }
1.1.1.2   root     1132: 
                   1133: 
1.1       root     1134: /*
                   1135: ========================
                   1136: Z_Stats_f
                   1137: ========================
                   1138: */
                   1139: void Z_Stats_f (void)
                   1140: {
                   1141:        Com_Printf ("%i bytes in %i blocks\n", z_bytes, z_count);
                   1142: }
1.1.1.2   root     1143: 
1.1       root     1144: /*
                   1145: ========================
                   1146: Z_FreeTags
                   1147: ========================
                   1148: */
                   1149: void Z_FreeTags (int tag)
                   1150: {
                   1151:        zhead_t *z, *next;
1.1.1.2   root     1152: 
1.1       root     1153:        for (z=z_chain.next ; z != &z_chain ; z=next)
                   1154:        {
                   1155:                next = z->next;
                   1156:                if (z->tag == tag)
                   1157:                        Z_Free ((void *)(z+1));
                   1158:        }
                   1159: }
1.1.1.2   root     1160: 
1.1       root     1161: /*
                   1162: ========================
                   1163: Z_TagMalloc
                   1164: ========================
                   1165: */
                   1166: void *Z_TagMalloc (int size, int tag)
                   1167: {
                   1168:        zhead_t *z;
                   1169:        
                   1170:        size = size + sizeof(zhead_t);
                   1171:        z = malloc(size);
                   1172:        if (!z)
                   1173:                Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size);
                   1174:        memset (z, 0, size);
                   1175:        z_count++;
                   1176:        z_bytes += size;
                   1177:        z->magic = Z_MAGIC;
                   1178:        z->tag = tag;
                   1179:        z->size = size;
1.1.1.2   root     1180: 
1.1       root     1181:        z->next = z_chain.next;
                   1182:        z->prev = &z_chain;
                   1183:        z_chain.next->prev = z;
                   1184:        z_chain.next = z;
1.1.1.2   root     1185: 
1.1       root     1186:        return (void *)(z+1);
                   1187: }
1.1.1.2   root     1188: 
1.1       root     1189: /*
                   1190: ========================
                   1191: Z_Malloc
                   1192: ========================
                   1193: */
                   1194: void *Z_Malloc (int size)
                   1195: {
                   1196:        return Z_TagMalloc (size, 0);
                   1197: }
1.1.1.2   root     1198: 
                   1199: 
1.1       root     1200: //============================================================================
                   1201: 
                   1202: 
                   1203: /*
                   1204: ====================
                   1205: COM_BlockSequenceCheckByte
                   1206: 
                   1207: For proxy protecting
1.1.1.2   root     1208: 
                   1209: // THIS IS MASSIVELY BROKEN!  CHALLENGE MAY BE NEGATIVE
                   1210: // DON'T USE THIS FUNCTION!!!!!
                   1211: 
1.1       root     1212: ====================
                   1213: */
1.1.1.2   root     1214: byte   COM_BlockSequenceCheckByte (byte *base, int length, int sequence, int challenge)
1.1       root     1215: {
1.1.1.2   root     1216:        Sys_Error("COM_BlockSequenceCheckByte called\n");
                   1217: 
                   1218: #if 0
1.1       root     1219:        int             checksum;
1.1.1.2   root     1220:        byte    buf[68];
1.1       root     1221:        byte    *p;
1.1.1.2   root     1222:        float temp;
                   1223:        byte c;
                   1224: 
                   1225:        temp = bytedirs[(sequence/3) % NUMVERTEXNORMALS][sequence % 3];
                   1226:        temp = LittleFloat(temp);
                   1227:        p = ((byte *)&temp);
1.1       root     1228: 
                   1229:        if (length > 60)
                   1230:                length = 60;
                   1231:        memcpy (buf, base, length);
                   1232: 
1.1.1.2   root     1233:        buf[length] = (sequence & 0xff) ^ p[0];
                   1234:        buf[length+1] = p[1];
                   1235:        buf[length+2] = ((sequence>>8) & 0xff) ^ p[2];
                   1236:        buf[length+3] = p[3];
                   1237: 
                   1238:        temp = bytedirs[((sequence+challenge)/3) % NUMVERTEXNORMALS][(sequence+challenge) % 3];
                   1239:        temp = LittleFloat(temp);
                   1240:        p = ((byte *)&temp);
                   1241: 
                   1242:        buf[length+4] = (sequence & 0xff) ^ p[3];
                   1243:        buf[length+5] = (challenge & 0xff) ^ p[2];
                   1244:        buf[length+6] = ((sequence>>8) & 0xff) ^ p[1];
                   1245:        buf[length+7] = ((challenge >> 7) & 0xff) ^ p[0];
                   1246: 
                   1247:        length += 8;
                   1248: 
                   1249:        checksum = LittleLong(Com_BlockChecksum (buf, length));
1.1       root     1250: 
                   1251:        checksum &= 0xff;
                   1252: 
                   1253:        return checksum;
1.1.1.2   root     1254: #endif
                   1255:        return 0;
                   1256: }
                   1257: 
                   1258: static byte chktbl[1024] = {
                   1259: 0x84, 0x47, 0x51, 0xc1, 0x93, 0x22, 0x21, 0x24, 0x2f, 0x66, 0x60, 0x4d, 0xb0, 0x7c, 0xda,
                   1260: 0x88, 0x54, 0x15, 0x2b, 0xc6, 0x6c, 0x89, 0xc5, 0x9d, 0x48, 0xee, 0xe6, 0x8a, 0xb5, 0xf4,
                   1261: 0xcb, 0xfb, 0xf1, 0x0c, 0x2e, 0xa0, 0xd7, 0xc9, 0x1f, 0xd6, 0x06, 0x9a, 0x09, 0x41, 0x54,
                   1262: 0x67, 0x46, 0xc7, 0x74, 0xe3, 0xc8, 0xb6, 0x5d, 0xa6, 0x36, 0xc4, 0xab, 0x2c, 0x7e, 0x85,
                   1263: 0xa8, 0xa4, 0xa6, 0x4d, 0x96, 0x19, 0x19, 0x9a, 0xcc, 0xd8, 0xac, 0x39, 0x5e, 0x3c, 0xf2,
                   1264: 0xf5, 0x5a, 0x72, 0xe5, 0xa9, 0xd1, 0xb3, 0x23, 0x82, 0x6f, 0x29, 0xcb, 0xd1, 0xcc, 0x71,
                   1265: 0xfb, 0xea, 0x92, 0xeb, 0x1c, 0xca, 0x4c, 0x70, 0xfe, 0x4d, 0xc9, 0x67, 0x43, 0x47, 0x94,
                   1266: 0xb9, 0x47, 0xbc, 0x3f, 0x01, 0xab, 0x7b, 0xa6, 0xe2, 0x76, 0xef, 0x5a, 0x7a, 0x29, 0x0b,
                   1267: 0x51, 0x54, 0x67, 0xd8, 0x1c, 0x14, 0x3e, 0x29, 0xec, 0xe9, 0x2d, 0x48, 0x67, 0xff, 0xed,
                   1268: 0x54, 0x4f, 0x48, 0xc0, 0xaa, 0x61, 0xf7, 0x78, 0x12, 0x03, 0x7a, 0x9e, 0x8b, 0xcf, 0x83,
                   1269: 0x7b, 0xae, 0xca, 0x7b, 0xd9, 0xe9, 0x53, 0x2a, 0xeb, 0xd2, 0xd8, 0xcd, 0xa3, 0x10, 0x25,
                   1270: 0x78, 0x5a, 0xb5, 0x23, 0x06, 0x93, 0xb7, 0x84, 0xd2, 0xbd, 0x96, 0x75, 0xa5, 0x5e, 0xcf,
                   1271: 0x4e, 0xe9, 0x50, 0xa1, 0xe6, 0x9d, 0xb1, 0xe3, 0x85, 0x66, 0x28, 0x4e, 0x43, 0xdc, 0x6e,
                   1272: 0xbb, 0x33, 0x9e, 0xf3, 0x0d, 0x00, 0xc1, 0xcf, 0x67, 0x34, 0x06, 0x7c, 0x71, 0xe3, 0x63,
                   1273: 0xb7, 0xb7, 0xdf, 0x92, 0xc4, 0xc2, 0x25, 0x5c, 0xff, 0xc3, 0x6e, 0xfc, 0xaa, 0x1e, 0x2a,
                   1274: 0x48, 0x11, 0x1c, 0x36, 0x68, 0x78, 0x86, 0x79, 0x30, 0xc3, 0xd6, 0xde, 0xbc, 0x3a, 0x2a,
                   1275: 0x6d, 0x1e, 0x46, 0xdd, 0xe0, 0x80, 0x1e, 0x44, 0x3b, 0x6f, 0xaf, 0x31, 0xda, 0xa2, 0xbd,
                   1276: 0x77, 0x06, 0x56, 0xc0, 0xb7, 0x92, 0x4b, 0x37, 0xc0, 0xfc, 0xc2, 0xd5, 0xfb, 0xa8, 0xda,
                   1277: 0xf5, 0x57, 0xa8, 0x18, 0xc0, 0xdf, 0xe7, 0xaa, 0x2a, 0xe0, 0x7c, 0x6f, 0x77, 0xb1, 0x26,
                   1278: 0xba, 0xf9, 0x2e, 0x1d, 0x16, 0xcb, 0xb8, 0xa2, 0x44, 0xd5, 0x2f, 0x1a, 0x79, 0x74, 0x87,
                   1279: 0x4b, 0x00, 0xc9, 0x4a, 0x3a, 0x65, 0x8f, 0xe6, 0x5d, 0xe5, 0x0a, 0x77, 0xd8, 0x1a, 0x14,
                   1280: 0x41, 0x75, 0xb1, 0xe2, 0x50, 0x2c, 0x93, 0x38, 0x2b, 0x6d, 0xf3, 0xf6, 0xdb, 0x1f, 0xcd,
                   1281: 0xff, 0x14, 0x70, 0xe7, 0x16, 0xe8, 0x3d, 0xf0, 0xe3, 0xbc, 0x5e, 0xb6, 0x3f, 0xcc, 0x81,
                   1282: 0x24, 0x67, 0xf3, 0x97, 0x3b, 0xfe, 0x3a, 0x96, 0x85, 0xdf, 0xe4, 0x6e, 0x3c, 0x85, 0x05,
                   1283: 0x0e, 0xa3, 0x2b, 0x07, 0xc8, 0xbf, 0xe5, 0x13, 0x82, 0x62, 0x08, 0x61, 0x69, 0x4b, 0x47,
                   1284: 0x62, 0x73, 0x44, 0x64, 0x8e, 0xe2, 0x91, 0xa6, 0x9a, 0xb7, 0xe9, 0x04, 0xb6, 0x54, 0x0c,
                   1285: 0xc5, 0xa9, 0x47, 0xa6, 0xc9, 0x08, 0xfe, 0x4e, 0xa6, 0xcc, 0x8a, 0x5b, 0x90, 0x6f, 0x2b,
                   1286: 0x3f, 0xb6, 0x0a, 0x96, 0xc0, 0x78, 0x58, 0x3c, 0x76, 0x6d, 0x94, 0x1a, 0xe4, 0x4e, 0xb8,
                   1287: 0x38, 0xbb, 0xf5, 0xeb, 0x29, 0xd8, 0xb0, 0xf3, 0x15, 0x1e, 0x99, 0x96, 0x3c, 0x5d, 0x63,
                   1288: 0xd5, 0xb1, 0xad, 0x52, 0xb8, 0x55, 0x70, 0x75, 0x3e, 0x1a, 0xd5, 0xda, 0xf6, 0x7a, 0x48,
                   1289: 0x7d, 0x44, 0x41, 0xf9, 0x11, 0xce, 0xd7, 0xca, 0xa5, 0x3d, 0x7a, 0x79, 0x7e, 0x7d, 0x25,
                   1290: 0x1b, 0x77, 0xbc, 0xf7, 0xc7, 0x0f, 0x84, 0x95, 0x10, 0x92, 0x67, 0x15, 0x11, 0x5a, 0x5e,
                   1291: 0x41, 0x66, 0x0f, 0x38, 0x03, 0xb2, 0xf1, 0x5d, 0xf8, 0xab, 0xc0, 0x02, 0x76, 0x84, 0x28,
                   1292: 0xf4, 0x9d, 0x56, 0x46, 0x60, 0x20, 0xdb, 0x68, 0xa7, 0xbb, 0xee, 0xac, 0x15, 0x01, 0x2f,
                   1293: 0x20, 0x09, 0xdb, 0xc0, 0x16, 0xa1, 0x89, 0xf9, 0x94, 0x59, 0x00, 0xc1, 0x76, 0xbf, 0xc1,
                   1294: 0x4d, 0x5d, 0x2d, 0xa9, 0x85, 0x2c, 0xd6, 0xd3, 0x14, 0xcc, 0x02, 0xc3, 0xc2, 0xfa, 0x6b,
                   1295: 0xb7, 0xa6, 0xef, 0xdd, 0x12, 0x26, 0xa4, 0x63, 0xe3, 0x62, 0xbd, 0x56, 0x8a, 0x52, 0x2b,
                   1296: 0xb9, 0xdf, 0x09, 0xbc, 0x0e, 0x97, 0xa9, 0xb0, 0x82, 0x46, 0x08, 0xd5, 0x1a, 0x8e, 0x1b,
                   1297: 0xa7, 0x90, 0x98, 0xb9, 0xbb, 0x3c, 0x17, 0x9a, 0xf2, 0x82, 0xba, 0x64, 0x0a, 0x7f, 0xca,
                   1298: 0x5a, 0x8c, 0x7c, 0xd3, 0x79, 0x09, 0x5b, 0x26, 0xbb, 0xbd, 0x25, 0xdf, 0x3d, 0x6f, 0x9a,
                   1299: 0x8f, 0xee, 0x21, 0x66, 0xb0, 0x8d, 0x84, 0x4c, 0x91, 0x45, 0xd4, 0x77, 0x4f, 0xb3, 0x8c,
                   1300: 0xbc, 0xa8, 0x99, 0xaa, 0x19, 0x53, 0x7c, 0x02, 0x87, 0xbb, 0x0b, 0x7c, 0x1a, 0x2d, 0xdf,
                   1301: 0x48, 0x44, 0x06, 0xd6, 0x7d, 0x0c, 0x2d, 0x35, 0x76, 0xae, 0xc4, 0x5f, 0x71, 0x85, 0x97,
                   1302: 0xc4, 0x3d, 0xef, 0x52, 0xbe, 0x00, 0xe4, 0xcd, 0x49, 0xd1, 0xd1, 0x1c, 0x3c, 0xd0, 0x1c,
                   1303: 0x42, 0xaf, 0xd4, 0xbd, 0x58, 0x34, 0x07, 0x32, 0xee, 0xb9, 0xb5, 0xea, 0xff, 0xd7, 0x8c,
                   1304: 0x0d, 0x2e, 0x2f, 0xaf, 0x87, 0xbb, 0xe6, 0x52, 0x71, 0x22, 0xf5, 0x25, 0x17, 0xa1, 0x82,
                   1305: 0x04, 0xc2, 0x4a, 0xbd, 0x57, 0xc6, 0xab, 0xc8, 0x35, 0x0c, 0x3c, 0xd9, 0xc2, 0x43, 0xdb,
                   1306: 0x27, 0x92, 0xcf, 0xb8, 0x25, 0x60, 0xfa, 0x21, 0x3b, 0x04, 0x52, 0xc8, 0x96, 0xba, 0x74,
                   1307: 0xe3, 0x67, 0x3e, 0x8e, 0x8d, 0x61, 0x90, 0x92, 0x59, 0xb6, 0x1a, 0x1c, 0x5e, 0x21, 0xc1,
                   1308: 0x65, 0xe5, 0xa6, 0x34, 0x05, 0x6f, 0xc5, 0x60, 0xb1, 0x83, 0xc1, 0xd5, 0xd5, 0xed, 0xd9,
                   1309: 0xc7, 0x11, 0x7b, 0x49, 0x7a, 0xf9, 0xf9, 0x84, 0x47, 0x9b, 0xe2, 0xa5, 0x82, 0xe0, 0xc2,
                   1310: 0x88, 0xd0, 0xb2, 0x58, 0x88, 0x7f, 0x45, 0x09, 0x67, 0x74, 0x61, 0xbf, 0xe6, 0x40, 0xe2,
                   1311: 0x9d, 0xc2, 0x47, 0x05, 0x89, 0xed, 0xcb, 0xbb, 0xb7, 0x27, 0xe7, 0xdc, 0x7a, 0xfd, 0xbf,
                   1312: 0xa8, 0xd0, 0xaa, 0x10, 0x39, 0x3c, 0x20, 0xf0, 0xd3, 0x6e, 0xb1, 0x72, 0xf8, 0xe6, 0x0f,
                   1313: 0xef, 0x37, 0xe5, 0x09, 0x33, 0x5a, 0x83, 0x43, 0x80, 0x4f, 0x65, 0x2f, 0x7c, 0x8c, 0x6a,
                   1314: 0xa0, 0x82, 0x0c, 0xd4, 0xd4, 0xfa, 0x81, 0x60, 0x3d, 0xdf, 0x06, 0xf1, 0x5f, 0x08, 0x0d,
                   1315: 0x6d, 0x43, 0xf2, 0xe3, 0x11, 0x7d, 0x80, 0x32, 0xc5, 0xfb, 0xc5, 0xd9, 0x27, 0xec, 0xc6,
                   1316: 0x4e, 0x65, 0x27, 0x76, 0x87, 0xa6, 0xee, 0xee, 0xd7, 0x8b, 0xd1, 0xa0, 0x5c, 0xb0, 0x42,
                   1317: 0x13, 0x0e, 0x95, 0x4a, 0xf2, 0x06, 0xc6, 0x43, 0x33, 0xf4, 0xc7, 0xf8, 0xe7, 0x1f, 0xdd,
                   1318: 0xe4, 0x46, 0x4a, 0x70, 0x39, 0x6c, 0xd0, 0xed, 0xca, 0xbe, 0x60, 0x3b, 0xd1, 0x7b, 0x57,
                   1319: 0x48, 0xe5, 0x3a, 0x79, 0xc1, 0x69, 0x33, 0x53, 0x1b, 0x80, 0xb8, 0x91, 0x7d, 0xb4, 0xf6,
                   1320: 0x17, 0x1a, 0x1d, 0x5a, 0x32, 0xd6, 0xcc, 0x71, 0x29, 0x3f, 0x28, 0xbb, 0xf3, 0x5e, 0x71,
                   1321: 0xb8, 0x43, 0xaf, 0xf8, 0xb9, 0x64, 0xef, 0xc4, 0xa5, 0x6c, 0x08, 0x53, 0xc7, 0x00, 0x10,
                   1322: 0x39, 0x4f, 0xdd, 0xe4, 0xb6, 0x19, 0x27, 0xfb, 0xb8, 0xf5, 0x32, 0x73, 0xe5, 0xcb, 0x32
                   1323: };
                   1324: 
                   1325: /*
                   1326: ====================
                   1327: COM_BlockSequenceCRCByte
                   1328: 
                   1329: For proxy protecting
                   1330: ====================
                   1331: */
                   1332: byte   COM_BlockSequenceCRCByte (byte *base, int length, int sequence)
                   1333: {
1.1.1.3   root     1334:        int             n;
1.1.1.2   root     1335:        byte    *p;
1.1.1.3   root     1336:        int             x;
1.1.1.2   root     1337:        byte chkb[60 + 4];
1.1.1.3   root     1338:        unsigned short crc;
                   1339: 
1.1.1.2   root     1340: 
                   1341:        if (sequence < 0)
                   1342:                Sys_Error("sequence < 0, this shouldn't happen\n");
                   1343: 
                   1344:        p = chktbl + (sequence % (sizeof(chktbl) - 4));
                   1345: 
                   1346:        if (length > 60)
                   1347:                length = 60;
                   1348:        memcpy (chkb, base, length);
                   1349: 
                   1350:        chkb[length] = p[0];
                   1351:        chkb[length+1] = p[1];
                   1352:        chkb[length+2] = p[2];
                   1353:        chkb[length+3] = p[3];
                   1354: 
                   1355:        length += 4;
                   1356: 
                   1357:        crc = CRC_Block(chkb, length);
                   1358: 
1.1.1.3   root     1359:        for (x=0, n=0; n<length; n++)
                   1360:                x += chkb[n];
                   1361: 
                   1362:        crc = (crc ^ x) & 0xff;
1.1.1.2   root     1363: 
                   1364:        return crc;
1.1       root     1365: }
                   1366: 
                   1367: //========================================================
1.1.1.2   root     1368: 
1.1       root     1369: float  frand(void)
                   1370: {
                   1371:        return (rand()&32767)* (1.0/32767);
                   1372: }
1.1.1.2   root     1373: 
1.1       root     1374: float  crand(void)
                   1375: {
                   1376:        return (rand()&32767)* (2.0/32767) - 1;
                   1377: }
1.1.1.2   root     1378: 
1.1       root     1379: void Key_Init (void);
                   1380: void SCR_EndLoadingPlaque (void);
1.1.1.2   root     1381: 
1.1       root     1382: /*
                   1383: =============
                   1384: Com_Error_f
1.1.1.2   root     1385: 
1.1       root     1386: Just throw a fatal error to
                   1387: test error shutdown procedures
                   1388: =============
                   1389: */
                   1390: void Com_Error_f (void)
                   1391: {
                   1392:        Com_Error (ERR_FATAL, "%s", Cmd_Argv(1));
                   1393: }
                   1394: 
                   1395: 
                   1396: /*
                   1397: =================
                   1398: Qcommon_Init
                   1399: =================
                   1400: */
                   1401: void Qcommon_Init (int argc, char **argv)
                   1402: {
                   1403:        char    *s;
1.1.1.2   root     1404: 
1.1       root     1405:        if (setjmp (abortframe) )
                   1406:                Sys_Error ("Error during initialization");
1.1.1.2   root     1407: 
1.1       root     1408:        z_chain.next = z_chain.prev = &z_chain;
1.1.1.2   root     1409: 
1.1       root     1410:        // prepare enough of the subsystems to handle
                   1411:        // cvar and command buffer management
                   1412:        COM_InitArgv (argc, argv);
1.1.1.2   root     1413: 
1.1       root     1414:        Swap_Init ();
                   1415:        Cbuf_Init ();
1.1.1.2   root     1416: 
1.1       root     1417:        Cmd_Init ();
                   1418:        Cvar_Init ();
1.1.1.2   root     1419: 
1.1       root     1420:        Key_Init ();
1.1.1.2   root     1421: 
1.1       root     1422:        // we need to add the early commands twice, because
                   1423:        // a basedir or cddir needs to be set before execing
                   1424:        // config files, but we want other parms to override
                   1425:        // the settings of the config files
                   1426:        Cbuf_AddEarlyCommands (false);
                   1427:        Cbuf_Execute ();
1.1.1.2   root     1428: 
1.1       root     1429:        FS_InitFilesystem ();
1.1.1.2   root     1430: 
1.1       root     1431:        Cbuf_AddText ("exec default.cfg\n");
                   1432:        Cbuf_AddText ("exec config.cfg\n");
1.1.1.2   root     1433: 
1.1       root     1434:        Cbuf_AddEarlyCommands (true);
                   1435:        Cbuf_Execute ();
1.1.1.2   root     1436: 
1.1       root     1437:        //
                   1438:        // init commands and vars
                   1439:        //
                   1440:     Cmd_AddCommand ("z_stats", Z_Stats_f);
                   1441:     Cmd_AddCommand ("error", Com_Error_f);
1.1.1.2   root     1442: 
1.1       root     1443:        host_speeds = Cvar_Get ("host_speeds", "0", 0);
                   1444:        log_stats = Cvar_Get ("log_stats", "0", 0);
                   1445:        developer = Cvar_Get ("developer", "0", 0);
                   1446:        timescale = Cvar_Get ("timescale", "1", 0);
                   1447:        fixedtime = Cvar_Get ("fixedtime", "0", 0);
                   1448:        logfile_active = Cvar_Get ("logfile", "0", 0);
                   1449:        showtrace = Cvar_Get ("showtrace", "0", 0);
1.1.1.2   root     1450: #ifdef DEDICATED_ONLY
                   1451:        dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET);
                   1452: #else
1.1       root     1453:        dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET);
1.1.1.2   root     1454: #endif
                   1455: 
1.1       root     1456:        s = va("%4.2f %s %s %s", VERSION, CPUSTRING, __DATE__, BUILDSTRING);
                   1457:        Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
1.1.1.2   root     1458: 
                   1459: 
1.1       root     1460:        if (dedicated->value)
                   1461:                Cmd_AddCommand ("quit", Com_Quit);
1.1.1.2   root     1462: 
1.1       root     1463:        Sys_Init ();
1.1.1.2   root     1464: 
1.1       root     1465:        NET_Init ();
                   1466:        Netchan_Init ();
1.1.1.2   root     1467: 
1.1       root     1468:        SV_Init ();
                   1469:        CL_Init ();
1.1.1.2   root     1470: 
1.1       root     1471:        // add + commands from command line
                   1472:        if (!Cbuf_AddLateCommands ())
                   1473:        {       // if the user didn't give any commands, run default action
                   1474:                if (!dedicated->value)
                   1475:                        Cbuf_AddText ("d1\n");
                   1476:                else
                   1477:                        Cbuf_AddText ("dedicated_start\n");
                   1478:                Cbuf_Execute ();
                   1479:        }
                   1480:        else
                   1481:        {       // the user asked for something explicit
                   1482:                // so drop the loading plaque
                   1483:                SCR_EndLoadingPlaque ();
                   1484:        }
1.1.1.2   root     1485: 
1.1       root     1486:        Com_Printf ("====== Quake2 Initialized ======\n\n");    
                   1487: }
1.1.1.2   root     1488: 
1.1       root     1489: /*
                   1490: =================
                   1491: Qcommon_Frame
                   1492: =================
                   1493: */
                   1494: void Qcommon_Frame (int msec)
                   1495: {
                   1496:        char    *s;
                   1497:        int             time_before, time_between, time_after;
1.1.1.2   root     1498: 
1.1       root     1499:        if (setjmp (abortframe) )
                   1500:                return;                 // an ERR_DROP was thrown
                   1501: 
                   1502:        if ( log_stats->modified )
                   1503:        {
                   1504:                log_stats->modified = false;
                   1505:                if ( log_stats->value )
                   1506:                {
                   1507:                        if ( log_stats_file )
                   1508:                        {
                   1509:                                fclose( log_stats_file );
                   1510:                                log_stats_file = 0;
                   1511:                        }
                   1512:                        log_stats_file = fopen( "stats.log", "w" );
                   1513:                        if ( log_stats_file )
                   1514:                                fprintf( log_stats_file, "entities,dlights,parts,frame time\n" );
                   1515:                }
                   1516:                else
                   1517:                {
                   1518:                        if ( log_stats_file )
                   1519:                        {
                   1520:                                fclose( log_stats_file );
                   1521:                                log_stats_file = 0;
                   1522:                        }
                   1523:                }
                   1524:        }
1.1.1.2   root     1525: 
1.1       root     1526:        if (fixedtime->value)
                   1527:                msec = fixedtime->value;
                   1528:        else if (timescale->value)
                   1529:        {
                   1530:                msec *= timescale->value;
                   1531:                if (msec < 1)
                   1532:                        msec = 1;
                   1533:        }
                   1534: 
                   1535:        if (showtrace->value)
                   1536:        {
                   1537:                extern  int c_traces, c_brush_traces;
                   1538:                extern  int     c_pointcontents;
1.1.1.2   root     1539: 
1.1       root     1540:                Com_Printf ("%4i traces  %4i points\n", c_traces, c_pointcontents);
                   1541:                c_traces = 0;
                   1542:                c_brush_traces = 0;
                   1543:                c_pointcontents = 0;
                   1544:        }
1.1.1.2   root     1545: 
1.1       root     1546:        do
                   1547:        {
                   1548:                s = Sys_ConsoleInput ();
                   1549:                if (s)
                   1550:                        Cbuf_AddText (va("%s\n",s));
                   1551:        } while (s);
                   1552:        Cbuf_Execute ();
1.1.1.2   root     1553: 
1.1       root     1554:        if (host_speeds->value)
                   1555:                time_before = Sys_Milliseconds ();
1.1.1.2   root     1556: 
1.1       root     1557:        SV_Frame (msec);
1.1.1.2   root     1558: 
1.1       root     1559:        if (host_speeds->value)
                   1560:                time_between = Sys_Milliseconds ();             
1.1.1.2   root     1561: 
1.1       root     1562:        CL_Frame (msec);
1.1.1.2   root     1563: 
1.1       root     1564:        if (host_speeds->value)
                   1565:                time_after = Sys_Milliseconds ();               
1.1.1.2   root     1566: 
                   1567: 
1.1       root     1568:        if (host_speeds->value)
                   1569:        {
                   1570:                int                     all, sv, gm, cl, rf;
1.1.1.2   root     1571: 
1.1       root     1572:                all = time_after - time_before;
                   1573:                sv = time_between - time_before;
                   1574:                cl = time_after - time_between;
                   1575:                gm = time_after_game - time_before_game;
                   1576:                rf = time_after_ref - time_before_ref;
                   1577:                sv -= gm;
                   1578:                cl -= rf;
                   1579:                Com_Printf ("all:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n",
                   1580:                        all, sv, gm, cl, rf);
                   1581:        }       
                   1582: }
1.1.1.2   root     1583: 
1.1       root     1584: /*
                   1585: =================
                   1586: Qcommon_Shutdown
                   1587: =================
                   1588: */
                   1589: void Qcommon_Shutdown (void)
                   1590: {
                   1591: }

unix.superglobalmegacorp.com

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