Annotation of quake2/qcommon/common.c, revision 1.1.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.