Annotation of quake2/client/cl_main.c, revision 1.1.1.2

1.1       root        1: // cl_main.c  -- client main loop
1.1.1.2 ! root        2: 
1.1       root        3: #include "client.h"
1.1.1.2 ! root        4: 
1.1       root        5: cvar_t *freelook;
                      6: 
                      7: cvar_t *adr0;
                      8: cvar_t *adr1;
                      9: cvar_t *adr2;
                     10: cvar_t *adr3;
                     11: cvar_t *adr4;
                     12: cvar_t *adr5;
                     13: cvar_t *adr6;
                     14: cvar_t *adr7;
                     15: cvar_t *adr8;
                     16: 
                     17: cvar_t *cl_stereo_separation;
                     18: cvar_t *cl_stereo;
1.1.1.2 ! root       19: 
1.1       root       20: cvar_t *rcon_client_password;
                     21: cvar_t *rcon_address;
                     22: 
                     23: cvar_t *cl_noskins;
                     24: cvar_t *cl_autoskins;
                     25: cvar_t *cl_footsteps;
                     26: cvar_t *cl_timeout;
                     27: cvar_t *cl_predict;
1.1.1.2 ! root       28: //cvar_t       *cl_minfps;
1.1       root       29: cvar_t *cl_maxfps;
                     30: cvar_t *cl_gun;
1.1.1.2 ! root       31: 
1.1       root       32: cvar_t *cl_add_particles;
                     33: cvar_t *cl_add_lights;
                     34: cvar_t *cl_add_entities;
                     35: cvar_t *cl_add_blend;
1.1.1.2 ! root       36: 
1.1       root       37: cvar_t *cl_shownet;
                     38: cvar_t *cl_showmiss;
                     39: cvar_t *cl_showclamp;
1.1.1.2 ! root       40: 
1.1       root       41: cvar_t *cl_paused;
                     42: cvar_t *cl_timedemo;
1.1.1.2 ! root       43: 
1.1       root       44: cvar_t *lookspring;
                     45: cvar_t *lookstrafe;
                     46: cvar_t *sensitivity;
1.1.1.2 ! root       47: 
1.1       root       48: cvar_t *m_pitch;
                     49: cvar_t *m_yaw;
                     50: cvar_t *m_forward;
                     51: cvar_t *m_side;
1.1.1.2 ! root       52: 
1.1       root       53: cvar_t *cl_lightlevel;
1.1.1.2 ! root       54: 
1.1       root       55: //
                     56: // userinfo
                     57: //
                     58: cvar_t *info_password;
                     59: cvar_t *name;
                     60: cvar_t *skin;
                     61: cvar_t *rate;
                     62: cvar_t *fov;
                     63: cvar_t *msg;
                     64: cvar_t *hand;
1.1.1.2 ! root       65: cvar_t *gender;
        !            66: cvar_t *gender_auto;
        !            67: 
        !            68: cvar_t *cl_vwep;
        !            69: 
1.1       root       70: client_static_t        cls;
                     71: client_state_t cl;
1.1.1.2 ! root       72: 
1.1       root       73: centity_t              cl_entities[MAX_EDICTS];
                     74: 
                     75: entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
                     76: 
1.1.1.2 ! root       77: extern cvar_t *allow_download;
        !            78: extern cvar_t *allow_download_players;
        !            79: extern cvar_t *allow_download_models;
        !            80: extern cvar_t *allow_download_sounds;
        !            81: extern cvar_t *allow_download_maps;
        !            82: 
1.1       root       83: //======================================================================
                     84: 
                     85: 
                     86: /*
                     87: ====================
                     88: CL_WriteDemoMessage
                     89: 
                     90: Dumps the current net message, prefixed by the length
                     91: ====================
                     92: */
                     93: void CL_WriteDemoMessage (void)
                     94: {
                     95:        int             len, swlen;
                     96: 
                     97:        // the first eight bytes are just packet sequencing stuff
                     98:        len = net_message.cursize-8;
                     99:        swlen = LittleLong(len);
                    100:        fwrite (&swlen, 4, 1, cls.demofile);
                    101:        fwrite (net_message.data+8,     len, 1, cls.demofile);
                    102: }
                    103: 
                    104: 
                    105: /*
                    106: ====================
                    107: CL_Stop_f
                    108: 
                    109: stop recording a demo
                    110: ====================
                    111: */
                    112: void CL_Stop_f (void)
                    113: {
                    114:        int             len;
                    115: 
                    116:        if (!cls.demorecording)
                    117:        {
                    118:                Com_Printf ("Not recording a demo.\n");
                    119:                return;
                    120:        }
                    121: 
                    122: // finish up
                    123:        len = -1;
                    124:        fwrite (&len, 4, 1, cls.demofile);
                    125:        fclose (cls.demofile);
                    126:        cls.demofile = NULL;
                    127:        cls.demorecording = false;
                    128:        Com_Printf ("Stopped demo.\n");
                    129: }
                    130: 
                    131: /*
                    132: ====================
                    133: CL_Record_f
                    134: 
                    135: record <demoname>
                    136: 
                    137: Begins recording a demo from the current position
                    138: ====================
                    139: */
                    140: void CL_Record_f (void)
                    141: {
                    142:        char    name[MAX_OSPATH];
                    143:        char    buf_data[MAX_MSGLEN];
                    144:        sizebuf_t       buf;
                    145:        int             i;
                    146:        int             len;
                    147:        entity_state_t  *ent;
                    148:        entity_state_t  nullstate;
                    149: 
                    150:        if (Cmd_Argc() != 2)
                    151:        {
                    152:                Com_Printf ("record <demoname>\n");
                    153:                return;
                    154:        }
                    155: 
                    156:        if (cls.demorecording)
                    157:        {
                    158:                Com_Printf ("Already recording.\n");
                    159:                return;
                    160:        }
                    161: 
                    162:        if (cls.state != ca_active)
                    163:        {
                    164:                Com_Printf ("You must be in a level to record.\n");
                    165:                return;
                    166:        }
                    167: 
                    168:        //
                    169:        // open the demo file
                    170:        //
                    171:        Com_sprintf (name, sizeof(name), "%s/demos/%s.dm2", FS_Gamedir(), Cmd_Argv(1));
                    172: 
                    173:        Com_Printf ("recording to %s.\n", name);
                    174:        FS_CreatePath (name);
                    175:        cls.demofile = fopen (name, "wb");
                    176:        if (!cls.demofile)
                    177:        {
                    178:                Com_Printf ("ERROR: couldn't open.\n");
                    179:                return;
                    180:        }
                    181:        cls.demorecording = true;
                    182: 
                    183:        // don't start saving messages until a non-delta compressed message is received
                    184:        cls.demowaiting = true;
                    185: 
                    186:        //
                    187:        // write out messages to hold the startup information
                    188:        //
                    189:        SZ_Init (&buf, buf_data, sizeof(buf_data));
                    190: 
                    191:        // send the serverdata
                    192:        MSG_WriteByte (&buf, svc_serverdata);
                    193:        MSG_WriteLong (&buf, PROTOCOL_VERSION);
                    194:        MSG_WriteLong (&buf, 0x10000 + cl.servercount);
                    195:        MSG_WriteByte (&buf, 1);        // demos are always attract loops
                    196:        MSG_WriteString (&buf, cl.gamedir);
                    197:        MSG_WriteShort (&buf, cl.playernum);
                    198: 
                    199:        MSG_WriteString (&buf, cl.configstrings[CS_NAME]);
                    200: 
                    201:        // configstrings
                    202:        for (i=0 ; i<MAX_CONFIGSTRINGS ; i++)
                    203:        {
                    204:                if (cl.configstrings[i][0])
                    205:                {
                    206:                        if (buf.cursize + strlen (cl.configstrings[i]) + 32 > buf.maxsize)
                    207:                        {       // write it out
                    208:                                len = LittleLong (buf.cursize);
                    209:                                fwrite (&len, 4, 1, cls.demofile);
                    210:                                fwrite (buf.data, buf.cursize, 1, cls.demofile);
                    211:                                buf.cursize = 0;
                    212:                        }
                    213: 
                    214:                        MSG_WriteByte (&buf, svc_configstring);
                    215:                        MSG_WriteShort (&buf, i);
                    216:                        MSG_WriteString (&buf, cl.configstrings[i]);
                    217:                }
                    218: 
                    219:        }
                    220: 
                    221:        // baselines
                    222:        memset (&nullstate, 0, sizeof(nullstate));
                    223:        for (i=0; i<MAX_EDICTS ; i++)
                    224:        {
                    225:                ent = &cl_entities[i].baseline;
                    226:                if (!ent->modelindex)
                    227:                        continue;
                    228: 
                    229:                if (buf.cursize + 64 > buf.maxsize)
                    230:                {       // write it out
                    231:                        len = LittleLong (buf.cursize);
                    232:                        fwrite (&len, 4, 1, cls.demofile);
                    233:                        fwrite (buf.data, buf.cursize, 1, cls.demofile);
                    234:                        buf.cursize = 0;
                    235:                }
                    236: 
                    237:                MSG_WriteByte (&buf, svc_spawnbaseline);                
1.1.1.2 ! root      238:                MSG_WriteDeltaEntity (&nullstate, &cl_entities[i].baseline, &buf, true, true);
1.1       root      239:        }
                    240: 
                    241:        MSG_WriteByte (&buf, svc_stufftext);
                    242:        MSG_WriteString (&buf, "precache\n");
                    243: 
                    244:        // write it to the demo file
                    245: 
                    246:        len = LittleLong (buf.cursize);
                    247:        fwrite (&len, 4, 1, cls.demofile);
                    248:        fwrite (buf.data, buf.cursize, 1, cls.demofile);
                    249: 
                    250:        // the rest of the demo file will be individual frames
                    251: }
                    252: 
                    253: //======================================================================
1.1.1.2 ! root      254: 
1.1       root      255: /*
                    256: ===================
                    257: Cmd_ForwardToServer
1.1.1.2 ! root      258: 
1.1       root      259: adds the current command line as a clc_stringcmd to the client message.
                    260: things like godmode, noclip, etc, are commands directed to the server,
                    261: so when they are typed in at the console, they will need to be forwarded.
                    262: ===================
                    263: */
                    264: void Cmd_ForwardToServer (void)
                    265: {
                    266:        char    *cmd;
                    267: 
                    268:        cmd = Cmd_Argv(0);
                    269:        if (cls.state <= ca_connected || *cmd == '-' || *cmd == '+')
                    270:        {
                    271:                Com_Printf ("Unknown command \"%s\"\n", cmd);
                    272:                return;
                    273:        }
                    274: 
                    275:        MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
                    276:        SZ_Print (&cls.netchan.message, cmd);
                    277:        if (Cmd_Argc() > 1)
                    278:        {
                    279:                SZ_Print (&cls.netchan.message, " ");
                    280:                SZ_Print (&cls.netchan.message, Cmd_Args());
                    281:        }
                    282: }
1.1.1.2 ! root      283: 
1.1       root      284: void CL_Setenv_f( void )
                    285: {
                    286:        int argc = Cmd_Argc();
1.1.1.2 ! root      287: 
1.1       root      288:        if ( argc > 2 )
                    289:        {
                    290:                char buffer[1000];
                    291:                int i;
1.1.1.2 ! root      292: 
1.1       root      293:                strcpy( buffer, Cmd_Argv(1) );
                    294:                strcat( buffer, "=" );
1.1.1.2 ! root      295: 
1.1       root      296:                for ( i = 2; i < argc; i++ )
                    297:                {
                    298:                        strcat( buffer, Cmd_Argv( i ) );
                    299:                        strcat( buffer, " " );
                    300:                }
1.1.1.2 ! root      301: 
1.1       root      302:                putenv( buffer );
                    303:        }
                    304:        else if ( argc == 2 )
                    305:        {
                    306:                char *env = getenv( Cmd_Argv(1) );
                    307: 
                    308:                if ( env )
                    309:                {
                    310:                        Com_Printf( "%s=%s\n", Cmd_Argv(1), env );
                    311:                }
                    312:                else
                    313:                {
                    314:                        Com_Printf( "%s undefined\n", Cmd_Argv(1), env );
                    315:                }
                    316:        }
                    317: }
1.1.1.2 ! root      318: 
        !           319: 
1.1       root      320: /*
                    321: ==================
                    322: CL_ForwardToServer_f
                    323: ==================
                    324: */
                    325: void CL_ForwardToServer_f (void)
                    326: {
                    327:        if (cls.state != ca_connected && cls.state != ca_active)
                    328:        {
                    329:                Com_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0));
                    330:                return;
                    331:        }
                    332:        
                    333:        // don't forward the first argument
                    334:        if (Cmd_Argc() > 1)
                    335:        {
                    336:                MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
                    337:                SZ_Print (&cls.netchan.message, Cmd_Args());
                    338:        }
                    339: }
1.1.1.2 ! root      340: 
        !           341: 
1.1       root      342: /*
                    343: ==================
                    344: CL_Pause_f
                    345: ==================
                    346: */
                    347: void CL_Pause_f (void)
                    348: {
                    349:        // never pause in multiplayer
                    350:        if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ())
                    351:        {
                    352:                Cvar_SetValue ("paused", 0);
                    353:                return;
                    354:        }
                    355: 
                    356:        Cvar_SetValue ("paused", !cl_paused->value);
                    357: }
1.1.1.2 ! root      358: 
1.1       root      359: /*
                    360: ==================
                    361: CL_Quit_f
                    362: ==================
                    363: */
                    364: void CL_Quit_f (void)
                    365: {
                    366:        CL_Disconnect ();
                    367:        Com_Quit ();
                    368: }
1.1.1.2 ! root      369: 
1.1       root      370: /*
                    371: ================
                    372: CL_Drop
1.1.1.2 ! root      373: 
1.1       root      374: Called after an ERR_DROP was thrown
                    375: ================
                    376: */
                    377: void CL_Drop (void)
                    378: {
                    379:        if (cls.state == ca_uninitialized)
                    380:                return;
                    381:        if (cls.state == ca_disconnected)
                    382:                return;
1.1.1.2 ! root      383: 
1.1       root      384:        CL_Disconnect ();
1.1.1.2 ! root      385: 
1.1       root      386:        // drop loading plaque unless this is the initial game start
                    387:        if (cls.disable_servercount != -1)
                    388:                SCR_EndLoadingPlaque ();        // get rid of loading plaque
                    389: }
1.1.1.2 ! root      390: 
        !           391: 
1.1       root      392: /*
                    393: =======================
                    394: CL_SendConnectPacket
                    395: 
                    396: We have gotten a challenge from the server, so try and
                    397: connect.
                    398: ======================
                    399: */
                    400: void CL_SendConnectPacket (void)
                    401: {
                    402:        netadr_t        adr;
                    403:        int             port;
                    404: 
                    405:        if (!NET_StringToAdr (cls.servername, &adr))
                    406:        {
                    407:                Com_Printf ("Bad server address\n");
                    408:                cls.connect_time = 0;
                    409:                return;
                    410:        }
                    411:        if (adr.port == 0)
                    412:                adr.port = BigShort (PORT_SERVER);
                    413: 
                    414:        port = Cvar_VariableValue ("qport");
                    415:        userinfo_modified = false;
                    416: 
                    417:        Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",
                    418:                PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() );
                    419: }
                    420: 
                    421: /*
                    422: =================
                    423: CL_CheckForResend
1.1.1.2 ! root      424: 
1.1       root      425: Resend a connect message if the last one has timed out
                    426: =================
                    427: */
                    428: void CL_CheckForResend (void)
                    429: {
                    430:        netadr_t        adr;
                    431: 
                    432:        // if the local server is running and we aren't
                    433:        // then connect
                    434:        if (cls.state == ca_disconnected && Com_ServerState() )
                    435:        {
                    436:                cls.state = ca_connecting;
                    437:                strncpy (cls.servername, "localhost", sizeof(cls.servername)-1);
                    438:                // we don't need a challenge on the localhost
                    439:                CL_SendConnectPacket ();
                    440:                return;
                    441: //             cls.connect_time = -99999;      // CL_CheckForResend() will fire immediately
                    442:        }
1.1.1.2 ! root      443: 
1.1       root      444:        // resend if we haven't gotten a reply yet
                    445:        if (cls.state != ca_connecting)
                    446:                return;
1.1.1.2 ! root      447: 
1.1       root      448:        if (cls.realtime - cls.connect_time < 3000)
                    449:                return;
                    450: 
                    451:        if (!NET_StringToAdr (cls.servername, &adr))
                    452:        {
                    453:                Com_Printf ("Bad server address\n");
                    454:                cls.state = ca_disconnected;
                    455:                return;
                    456:        }
                    457:        if (adr.port == 0)
                    458:                adr.port = BigShort (PORT_SERVER);
                    459: 
                    460:        cls.connect_time = cls.realtime;        // for retransmit requests
                    461: 
                    462:        Com_Printf ("Connecting to %s...\n", cls.servername);
                    463: 
                    464:        Netchan_OutOfBandPrint (NS_CLIENT, adr, "getchallenge\n");
                    465: }
1.1.1.2 ! root      466: 
        !           467: 
1.1       root      468: /*
                    469: ================
                    470: CL_Connect_f
1.1.1.2 ! root      471: 
1.1       root      472: ================
                    473: */
                    474: void CL_Connect_f (void)
                    475: {
                    476:        char    *server;
1.1.1.2 ! root      477: 
1.1       root      478:        if (Cmd_Argc() != 2)
                    479:        {
                    480:                Com_Printf ("usage: connect <server>\n");
                    481:                return; 
                    482:        }
                    483:        
                    484:        if (Com_ServerState ())
                    485:        {       // if running a local server, kill it and reissue
                    486:                SV_Shutdown (va("Server quit\n", msg), false);
                    487:        }
                    488:        else
                    489:        {
                    490:                CL_Disconnect ();
                    491:        }
1.1.1.2 ! root      492: 
1.1       root      493:        server = Cmd_Argv (1);
1.1.1.2 ! root      494: 
1.1       root      495:        NET_Config (true);              // allow remote
1.1.1.2 ! root      496: 
1.1       root      497:        CL_Disconnect ();
1.1.1.2 ! root      498: 
1.1       root      499:        cls.state = ca_connecting;
                    500:        strncpy (cls.servername, server, sizeof(cls.servername)-1);
                    501:        cls.connect_time = -99999;      // CL_CheckForResend() will fire immediately
                    502: }
1.1.1.2 ! root      503: 
        !           504: 
1.1       root      505: /*
                    506: =====================
                    507: CL_Rcon_f
1.1.1.2 ! root      508: 
1.1       root      509:   Send the rest of the command line over as
                    510:   an unconnected command.
                    511: =====================
                    512: */
                    513: void CL_Rcon_f (void)
                    514: {
                    515:        char    message[1024];
                    516:        int             i;
                    517:        netadr_t        to;
1.1.1.2 ! root      518: 
1.1       root      519:        if (!rcon_client_password->string)
                    520:        {
                    521:                Com_Printf ("You must set 'rcon_password' before\n"
                    522:                                        "issuing an rcon command.\n");
                    523:                return;
                    524:        }
1.1.1.2 ! root      525: 
1.1       root      526:        message[0] = (char)255;
                    527:        message[1] = (char)255;
                    528:        message[2] = (char)255;
                    529:        message[3] = (char)255;
                    530:        message[4] = 0;
                    531: 
                    532:        NET_Config (true);              // allow remote
1.1.1.2 ! root      533: 
1.1       root      534:        strcat (message, "rcon ");
1.1.1.2 ! root      535: 
1.1       root      536:        strcat (message, rcon_client_password->string);
                    537:        strcat (message, " ");
1.1.1.2 ! root      538: 
1.1       root      539:        for (i=1 ; i<Cmd_Argc() ; i++)
                    540:        {
                    541:                strcat (message, Cmd_Argv(i));
                    542:                strcat (message, " ");
                    543:        }
1.1.1.2 ! root      544: 
1.1       root      545:        if (cls.state >= ca_connected)
                    546:                to = cls.netchan.remote_address;
                    547:        else
                    548:        {
                    549:                if (!strlen(rcon_address->string))
                    550:                {
                    551:                        Com_Printf ("You must either be connected,\n"
                    552:                                                "or set the 'rcon_address' cvar\n"
                    553:                                                "to issue rcon commands\n");
1.1.1.2 ! root      554: 
1.1       root      555:                        return;
                    556:                }
                    557:                NET_StringToAdr (rcon_address->string, &to);
                    558:                if (to.port == 0)
                    559:                        to.port = BigShort (PORT_SERVER);
                    560:        }
                    561:        
                    562:        NET_SendPacket (NS_CLIENT, strlen(message)+1, message, to);
                    563: }
1.1.1.2 ! root      564: 
        !           565: 
1.1       root      566: /*
                    567: =====================
                    568: CL_ClearState
1.1.1.2 ! root      569: 
1.1       root      570: =====================
                    571: */
                    572: void CL_ClearState (void)
                    573: {
                    574:        S_StopAllSounds ();
                    575:        CL_ClearEffects ();
                    576:        CL_ClearTEnts ();
1.1.1.2 ! root      577: 
1.1       root      578: // wipe the entire cl structure
                    579:        memset (&cl, 0, sizeof(cl));
                    580:        memset (&cl_entities, 0, sizeof(cl_entities));
1.1.1.2 ! root      581: 
1.1       root      582:        SZ_Clear (&cls.netchan.message);
1.1.1.2 ! root      583: 
1.1       root      584: }
1.1.1.2 ! root      585: 
1.1       root      586: /*
                    587: =====================
                    588: CL_Disconnect
1.1.1.2 ! root      589: 
1.1       root      590: Goes from a connected state to full screen console state
                    591: Sends a disconnect message to the server
                    592: This is also called on Com_Error, so it shouldn't cause any errors
                    593: =====================
                    594: */
                    595: void CL_Disconnect (void)
                    596: {
                    597:        byte    final[32];
1.1.1.2 ! root      598: 
1.1       root      599:        if (cls.state == ca_disconnected)
                    600:                return;
1.1.1.2 ! root      601: 
1.1       root      602:        if (cl_timedemo && cl_timedemo->value)
                    603:        {
                    604:                int     time;
                    605:                
                    606:                time = Sys_Milliseconds () - cl.timedemo_start;
                    607:                if (time > 0)
                    608:                        Com_Printf ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames,
                    609:                        time/1000.0, cl.timedemo_frames*1000.0 / time);
                    610:        }
1.1.1.2 ! root      611: 
1.1       root      612:        VectorClear (cl.refdef.blend);
                    613:        re.CinematicSetPalette(NULL);
                    614: 
                    615:        M_ForceMenuOff ();
1.1.1.2 ! root      616: 
1.1       root      617:        cls.connect_time = 0;
1.1.1.2 ! root      618: 
1.1       root      619:        SCR_StopCinematic ();
1.1.1.2 ! root      620: 
1.1       root      621:        if (cls.demorecording)
                    622:                CL_Stop_f ();
1.1.1.2 ! root      623: 
1.1       root      624:        // send a disconnect message to the server
                    625:        final[0] = clc_stringcmd;
                    626:        strcpy ((char *)final+1, "disconnect");
                    627:        Netchan_Transmit (&cls.netchan, strlen(final), final);
                    628:        Netchan_Transmit (&cls.netchan, strlen(final), final);
                    629:        Netchan_Transmit (&cls.netchan, strlen(final), final);
1.1.1.2 ! root      630: 
1.1       root      631:        CL_ClearState ();
1.1.1.2 ! root      632: 
        !           633:        // stop download
        !           634:        if (cls.download) {
        !           635:                fclose(cls.download);
        !           636:                cls.download = NULL;
        !           637:        }
        !           638: 
1.1       root      639:        cls.state = ca_disconnected;
                    640: }
1.1.1.2 ! root      641: 
1.1       root      642: void CL_Disconnect_f (void)
                    643: {
                    644:        Com_Error (ERR_DROP, "Disconnected from server");
                    645: }
1.1.1.2 ! root      646: 
        !           647: 
1.1       root      648: /*
                    649: ====================
                    650: CL_Packet_f
1.1.1.2 ! root      651: 
1.1       root      652: packet <destination> <contents>
1.1.1.2 ! root      653: 
1.1       root      654: Contents allows \n escape character
                    655: ====================
                    656: */
                    657: void CL_Packet_f (void)
                    658: {
                    659:        char    send[2048];
                    660:        int             i, l;
                    661:        char    *in, *out;
                    662:        netadr_t        adr;
1.1.1.2 ! root      663: 
1.1       root      664:        if (Cmd_Argc() != 3)
                    665:        {
                    666:                Com_Printf ("packet <destination> <contents>\n");
                    667:                return;
                    668:        }
1.1.1.2 ! root      669: 
1.1       root      670:        NET_Config (true);              // allow remote
1.1.1.2 ! root      671: 
1.1       root      672:        if (!NET_StringToAdr (Cmd_Argv(1), &adr))
                    673:        {
                    674:                Com_Printf ("Bad address\n");
                    675:                return;
                    676:        }
                    677:        if (!adr.port)
                    678:                adr.port = BigShort (PORT_SERVER);
1.1.1.2 ! root      679: 
1.1       root      680:        in = Cmd_Argv(2);
                    681:        out = send+4;
                    682:        send[0] = send[1] = send[2] = send[3] = (char)0xff;
1.1.1.2 ! root      683: 
1.1       root      684:        l = strlen (in);
                    685:        for (i=0 ; i<l ; i++)
                    686:        {
                    687:                if (in[i] == '\\' && in[i+1] == 'n')
                    688:                {
                    689:                        *out++ = '\n';
                    690:                        i++;
                    691:                }
                    692:                else
                    693:                        *out++ = in[i];
                    694:        }
                    695:        *out = 0;
1.1.1.2 ! root      696: 
1.1       root      697:        NET_SendPacket (NS_CLIENT, out-send, send, adr);
                    698: }
1.1.1.2 ! root      699: 
1.1       root      700: /*
                    701: =================
                    702: CL_Changing_f
1.1.1.2 ! root      703: 
1.1       root      704: Just sent as a hint to the client that they should
                    705: drop to full console
                    706: =================
                    707: */
                    708: void CL_Changing_f (void)
                    709: {
1.1.1.2 ! root      710:        //ZOID
        !           711:        //if we are downloading, we don't change!  This so we don't suddenly stop downloading a map
        !           712:        if (cls.download)
        !           713:                return;
        !           714: 
1.1       root      715:        SCR_BeginLoadingPlaque ();
                    716:        cls.state = ca_connected;       // not active anymore, but not disconnected
                    717:        Com_Printf ("\nChanging map...\n");
                    718: }
1.1.1.2 ! root      719: 
        !           720: 
1.1       root      721: /*
                    722: =================
                    723: CL_Reconnect_f
1.1.1.2 ! root      724: 
1.1       root      725: The server is changing levels
                    726: =================
                    727: */
                    728: void CL_Reconnect_f (void)
                    729: {
1.1.1.2 ! root      730:        //ZOID
        !           731:        //if we are downloading, we don't change!  This so we don't suddenly stop downloading a map
        !           732:        if (cls.download)
        !           733:                return;
        !           734: 
1.1       root      735:        S_StopAllSounds ();
1.1.1.2 ! root      736:        if (cls.state == ca_connected) {
        !           737:                Com_Printf ("reconnecting...\n");
        !           738:                cls.state = ca_connected;
        !           739:                MSG_WriteChar (&cls.netchan.message, clc_stringcmd);
        !           740:                MSG_WriteString (&cls.netchan.message, "new");          
        !           741:                return;
        !           742:        }
        !           743: 
        !           744:        if (*cls.servername) {
        !           745:                if (cls.state >= ca_connected) {
        !           746:                        CL_Disconnect();
        !           747:                        cls.connect_time = cls.realtime - 1500;
        !           748:                } else
        !           749:                        cls.connect_time = -99999; // fire immediately
        !           750: 
        !           751:                cls.state = ca_connecting;
        !           752:                Com_Printf ("reconnecting...\n");
        !           753:        }
1.1       root      754: }
1.1.1.2 ! root      755: 
1.1       root      756: /*
                    757: =================
                    758: CL_ParseStatusMessage
1.1.1.2 ! root      759: 
1.1       root      760: Handle a reply from a ping
                    761: =================
                    762: */
                    763: void CL_ParseStatusMessage (void)
                    764: {
                    765:        char    *s;
                    766: 
                    767:        s = MSG_ReadString(&net_message);
1.1.1.2 ! root      768: 
1.1       root      769:        Com_Printf ("%s\n", s);
                    770:        M_AddToServerList (net_from, s);
                    771: }
1.1.1.2 ! root      772: 
        !           773: 
1.1       root      774: /*
                    775: =================
                    776: CL_PingServers_f
                    777: =================
                    778: */
                    779: void CL_PingServers_f (void)
                    780: {
                    781:        int                     i;
                    782:        netadr_t        adr;
                    783:        char            name[32];
                    784:        char            *adrstring;
                    785:        cvar_t          *noudp;
                    786:        cvar_t          *noipx;
1.1.1.2 ! root      787: 
1.1       root      788:        NET_Config (true);              // allow remote
1.1.1.2 ! root      789: 
1.1       root      790:        // send a broadcast packet
                    791:        Com_Printf ("pinging broadcast...\n");
                    792: 
                    793:        noudp = Cvar_Get ("noudp", "0", CVAR_NOSET);
                    794:        if (!noudp->value)
                    795:        {
                    796:                adr.type = NA_BROADCAST;
                    797:                adr.port = BigShort(PORT_SERVER);
                    798:                Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
                    799:        }
                    800: 
                    801:        noipx = Cvar_Get ("noipx", "0", CVAR_NOSET);
                    802:        if (!noipx->value)
                    803:        {
                    804:                adr.type = NA_BROADCAST_IPX;
                    805:                adr.port = BigShort(PORT_SERVER);
                    806:                Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
                    807:        }
1.1.1.2 ! root      808: 
1.1       root      809:        // send a packet to each address book entry
                    810:        for (i=0 ; i<16 ; i++)
                    811:        {
                    812:                Com_sprintf (name, sizeof(name), "adr%i", i);
                    813:                adrstring = Cvar_VariableString (name);
                    814:                if (!adrstring || !adrstring[0])
                    815:                        continue;
1.1.1.2 ! root      816: 
1.1       root      817:                Com_Printf ("pinging %s...\n", adrstring);
                    818:                if (!NET_StringToAdr (adrstring, &adr))
                    819:                {
                    820:                        Com_Printf ("Bad address: %s\n", adrstring);
                    821:                        continue;
                    822:                }
                    823:                if (!adr.port)
                    824:                        adr.port = BigShort(PORT_SERVER);
                    825:                Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
                    826:        }
                    827: }
                    828: 
1.1.1.2 ! root      829: 
1.1       root      830: /*
                    831: =================
                    832: CL_Skins_f
                    833: 
                    834: Load or download any custom player skins and models
                    835: =================
                    836: */
                    837: void CL_Skins_f (void)
                    838: {
                    839:        int             i;
                    840: 
                    841:        for (i=0 ; i<MAX_CLIENTS ; i++)
                    842:        {
                    843:                if (!cl.configstrings[CS_PLAYERSKINS+i][0])
                    844:                        continue;
                    845:                Com_Printf ("client %i: %s\n", i, cl.configstrings[CS_PLAYERSKINS+i]); 
                    846:                SCR_UpdateScreen ();
                    847:                Sys_SendKeyEvents ();   // pump message loop
                    848:                CL_ParseClientinfo (i);
                    849:        }
                    850: }
                    851: 
1.1.1.2 ! root      852: 
1.1       root      853: /*
                    854: =================
                    855: CL_ConnectionlessPacket
1.1.1.2 ! root      856: 
1.1       root      857: Responses to broadcasts, etc
                    858: =================
                    859: */
                    860: void CL_ConnectionlessPacket (void)
                    861: {
                    862:        char    *s;
                    863:        char    *c;
                    864:        
                    865:        MSG_BeginReading (&net_message);
                    866:        MSG_ReadLong (&net_message);    // skip the -1
1.1.1.2 ! root      867: 
1.1       root      868:        s = MSG_ReadStringLine (&net_message);
1.1.1.2 ! root      869: 
1.1       root      870:        Cmd_TokenizeString (s, false);
1.1.1.2 ! root      871: 
1.1       root      872:        c = Cmd_Argv(0);
1.1.1.2 ! root      873: 
1.1       root      874:        Com_Printf ("%s: %s\n", NET_AdrToString (net_from), c);
1.1.1.2 ! root      875: 
1.1       root      876:        // server connection
                    877:        if (!strcmp(c, "client_connect"))
                    878:        {
                    879:                if (cls.state == ca_connected)
                    880:                {
                    881:                        Com_Printf ("Dup connect received.  Ignored.\n");
                    882:                        return;
                    883:                }
                    884:                Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.quakePort);
                    885:                MSG_WriteChar (&cls.netchan.message, clc_stringcmd);
                    886:                MSG_WriteString (&cls.netchan.message, "new");  
                    887:                cls.state = ca_connected;
                    888:                return;
                    889:        }
1.1.1.2 ! root      890: 
1.1       root      891:        // server responding to a status broadcast
                    892:        if (!strcmp(c, "info"))
                    893:        {
                    894:                CL_ParseStatusMessage ();
                    895:                return;
                    896:        }
1.1.1.2 ! root      897: 
1.1       root      898:        // remote command from gui front end
                    899:        if (!strcmp(c, "cmd"))
                    900:        {
                    901:                if (!NET_IsLocalAddress(net_from))
                    902:                {
                    903:                        Com_Printf ("Command packet from remote host.  Ignored.\n");
                    904:                        return;
                    905:                }
                    906:                Sys_AppActivate ();
                    907:                s = MSG_ReadString (&net_message);
                    908:                Cbuf_AddText (s);
                    909:                Cbuf_AddText ("\n");
                    910:                return;
                    911:        }
                    912:        // print command from somewhere
                    913:        if (!strcmp(c, "print"))
                    914:        {
                    915:                s = MSG_ReadString (&net_message);
                    916:                Com_Printf (s);
                    917:                return;
                    918:        }
1.1.1.2 ! root      919: 
1.1       root      920:        // ping from somewhere
                    921:        if (!strcmp(c, "ping"))
                    922:        {
                    923:                Netchan_OutOfBandPrint (NS_CLIENT, net_from, "ack");
                    924:                return;
                    925:        }
                    926: 
                    927:        // challenge from the server we are connecting to
                    928:        if (!strcmp(c, "challenge"))
                    929:        {
                    930:                cls.challenge = atoi(Cmd_Argv(1));
                    931:                CL_SendConnectPacket ();
                    932:                return;
                    933:        }
                    934: 
                    935:        // echo request from server
                    936:        if (!strcmp(c, "echo"))
                    937:        {
                    938:                Netchan_OutOfBandPrint (NS_CLIENT, net_from, "%s", Cmd_Argv(1) );
                    939:                return;
                    940:        }
                    941: 
                    942:        Com_Printf ("Unknown command.\n");
                    943: }
1.1.1.2 ! root      944: 
        !           945: 
1.1       root      946: /*
                    947: =================
                    948: CL_DumpPackets
                    949: 
                    950: A vain attempt to help bad TCP stacks that cause problems
                    951: when they overflow
                    952: =================
                    953: */
                    954: void CL_DumpPackets (void)
                    955: {
                    956:        while (NET_GetPacket (NS_CLIENT, &net_from, &net_message))
                    957:        {
                    958:                Com_Printf ("dumnping a packet\n");
                    959:        }
                    960: }
1.1.1.2 ! root      961: 
1.1       root      962: /*
                    963: =================
                    964: CL_ReadPackets
                    965: =================
                    966: */
                    967: void CL_ReadPackets (void)
                    968: {
                    969:        while (NET_GetPacket (NS_CLIENT, &net_from, &net_message))
                    970:        {
                    971: //     Com_Printf ("packet\n");
                    972:                //
                    973:                // remote command packet
                    974:                //
                    975:                if (*(int *)net_message.data == -1)
                    976:                {
                    977:                        CL_ConnectionlessPacket ();
                    978:                        continue;
                    979:                }
1.1.1.2 ! root      980: 
1.1       root      981:                if (cls.state == ca_disconnected || cls.state == ca_connecting)
                    982:                        continue;               // dump it if not connected
1.1.1.2 ! root      983: 
1.1       root      984:                if (net_message.cursize < 8)
                    985:                {
                    986:                        Com_Printf ("%s: Runt packet\n",NET_AdrToString(net_from));
                    987:                        continue;
                    988:                }
1.1.1.2 ! root      989: 
1.1       root      990:                //
                    991:                // packet from server
                    992:                //
                    993:                if (!NET_CompareAdr (net_from, cls.netchan.remote_address))
                    994:                {
                    995:                        Com_DPrintf ("%s:sequenced packet without connection\n"
                    996:                                ,NET_AdrToString(net_from));
                    997:                        continue;
                    998:                }
                    999:                if (!Netchan_Process(&cls.netchan, &net_message))
                   1000:                        continue;               // wasn't accepted for some reason
                   1001:                CL_ParseServerMessage ();
                   1002:        }
1.1.1.2 ! root     1003: 
1.1       root     1004:        //
                   1005:        // check timeout
                   1006:        //
                   1007:        if (cls.state >= ca_connected
                   1008:         && cls.realtime - cls.netchan.last_received > cl_timeout->value*1000)
                   1009:        {
                   1010:                if (++cl.timeoutcount > 5)      // timeoutcount saves debugger
                   1011:                {
                   1012:                        Com_Printf ("\nServer connection timed out.\n");
                   1013:                        CL_Disconnect ();
                   1014:                        return;
                   1015:                }
                   1016:        }
                   1017:        else
                   1018:                cl.timeoutcount = 0;
                   1019:        
                   1020: }
1.1.1.2 ! root     1021: 
        !          1022: 
1.1       root     1023: //=============================================================================
1.1.1.2 ! root     1024: 
        !          1025: /*
        !          1026: ==============
        !          1027: CL_FixUpGender_f
        !          1028: ==============
        !          1029: */
        !          1030: void CL_FixUpGender(void)
        !          1031: {
        !          1032:        char *p;
        !          1033:        char sk[80];
        !          1034: 
        !          1035:        if (gender_auto->value) {
        !          1036: 
        !          1037:                if (gender->modified) {
        !          1038:                        // was set directly, don't override the user
        !          1039:                        gender->modified = false;
        !          1040:                        return;
        !          1041:                }
        !          1042: 
        !          1043:                strncpy(sk, skin->string, sizeof(sk) - 1);
        !          1044:                if ((p = strchr(sk, '/')) != NULL)
        !          1045:                        *p = 0;
        !          1046:                if (Q_stricmp(sk, "male") == 0 || Q_stricmp(sk, "cyborg") == 0)
        !          1047:                        Cvar_Set ("gender", "male");
        !          1048:                else if (Q_stricmp(sk, "female") == 0 || Q_stricmp(sk, "crackhor") == 0)
        !          1049:                        Cvar_Set ("gender", "female");
        !          1050:                else
        !          1051:                        Cvar_Set ("gender", "none");
        !          1052:                gender->modified = false;
        !          1053:        }
        !          1054: }
        !          1055: 
1.1       root     1056: /*
                   1057: ==============
                   1058: CL_Userinfo_f
                   1059: ==============
                   1060: */
                   1061: void CL_Userinfo_f (void)
                   1062: {
                   1063:        Com_Printf ("User info settings:\n");
                   1064:        Info_Print (Cvar_Userinfo());
                   1065: }
1.1.1.2 ! root     1066: 
1.1       root     1067: /*
                   1068: =================
                   1069: CL_Snd_Restart_f
1.1.1.2 ! root     1070: 
1.1       root     1071: Restart the sound subsystem so it can pick up
                   1072: new parameters and flush all sounds
                   1073: =================
                   1074: */
                   1075: void CL_Snd_Restart_f (void)
                   1076: {
                   1077:        S_Shutdown ();
                   1078:        S_Init ();
                   1079:        CL_RegisterSounds ();
                   1080: }
1.1.1.2 ! root     1081: 
        !          1082: int precache_check; // for autodownload of precache items
        !          1083: int precache_spawncount;
        !          1084: int precache_tex;
        !          1085: int precache_model_skin;
        !          1086: 
        !          1087: byte *precache_model; // used for skin checking in alias models
        !          1088: 
        !          1089: #define PLAYER_MULT 5
        !          1090: 
        !          1091: #define TEXTURE_CNT (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
        !          1092: 
        !          1093: void CL_RequestNextDownload (void)
        !          1094: {
        !          1095:        unsigned        map_checksum;           // for detecting cheater maps
        !          1096:        char fn[MAX_OSPATH];
        !          1097:        dmdl_t *pheader;
        !          1098: 
        !          1099:        if (cls.state != ca_connected)
        !          1100:                return;
        !          1101: 
        !          1102:        if (!allow_download->value && precache_check < TEXTURE_CNT)
        !          1103:                precache_check = TEXTURE_CNT;
        !          1104: 
        !          1105: //ZOID
        !          1106:        if (precache_check == CS_MODELS) { // confirm map
        !          1107:                precache_check = CS_MODELS+2; // 0 isn't used
        !          1108:                if (allow_download_maps->value)
        !          1109:                        if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
        !          1110:                                return; // started a download
        !          1111:        }
        !          1112:        if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS) {
        !          1113:                if (allow_download_models->value) {
        !          1114:                        while (precache_check < CS_MODELS+MAX_MODELS &&
        !          1115:                                cl.configstrings[precache_check][0]) {
        !          1116:                                if (cl.configstrings[precache_check][0] == '*' ||
        !          1117:                                        cl.configstrings[precache_check][0] == '#') {
        !          1118:                                        precache_check++;
        !          1119:                                        continue;
        !          1120:                                }
        !          1121:                                if (precache_model_skin == 0) {
        !          1122:                                        if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
        !          1123:                                                precache_model_skin = 1;
        !          1124:                                                return; // started a download
        !          1125:                                        }
        !          1126:                                        precache_model_skin = 1;
        !          1127:                                }
        !          1128: 
        !          1129:                                // checking for skins in the model
        !          1130:                                if (!precache_model) {
        !          1131: 
        !          1132:                                        FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);
        !          1133:                                        if (!precache_model) {
        !          1134:                                                precache_model_skin = 0;
        !          1135:                                                precache_check++;
        !          1136:                                                continue; // couldn't load it
        !          1137:                                        }
        !          1138:                                        if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) {
        !          1139:                                                // not an alias model
        !          1140:                                                FS_FreeFile(precache_model);
        !          1141:                                                precache_model = 0;
        !          1142:                                                precache_model_skin = 0;
        !          1143:                                                precache_check++;
        !          1144:                                                continue;
        !          1145:                                        }
        !          1146:                                        pheader = (dmdl_t *)precache_model;
        !          1147:                                        if (LittleLong (pheader->version) != ALIAS_VERSION) {
        !          1148:                                                precache_check++;
        !          1149:                                                precache_model_skin = 0;
        !          1150:                                                continue; // couldn't load it
        !          1151:                                        }
        !          1152:                                }
        !          1153: 
        !          1154:                                pheader = (dmdl_t *)precache_model;
        !          1155: 
        !          1156:                                while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) {
        !          1157:                                        if (!CL_CheckOrDownloadFile((char *)precache_model +
        !          1158:                                                LittleLong(pheader->ofs_skins) + 
        !          1159:                                                (precache_model_skin - 1)*MAX_SKINNAME)) {
        !          1160:                                                precache_model_skin++;
        !          1161:                                                return; // started a download
        !          1162:                                        }
        !          1163:                                        precache_model_skin++;
        !          1164:                                }
        !          1165:                                if (precache_model) { 
        !          1166:                                        FS_FreeFile(precache_model);
        !          1167:                                        precache_model = 0;
        !          1168:                                }
        !          1169:                                precache_model_skin = 0;
        !          1170:                                precache_check++;
        !          1171:                        }
        !          1172:                }
        !          1173:                precache_check = CS_SOUNDS;
        !          1174:        }
        !          1175:        if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS) { 
        !          1176:                if (allow_download_sounds->value) {
        !          1177:                        if (precache_check == CS_SOUNDS)
        !          1178:                                precache_check++; // zero is blank
        !          1179:                        while (precache_check < CS_SOUNDS+MAX_SOUNDS &&
        !          1180:                                cl.configstrings[precache_check][0]) {
        !          1181:                                if (cl.configstrings[precache_check][0] == '*') {
        !          1182:                                        precache_check++;
        !          1183:                                        continue;
        !          1184:                                }
        !          1185:                                Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);
        !          1186:                                if (!CL_CheckOrDownloadFile(fn))
        !          1187:                                        return; // started a download
        !          1188:                        }
        !          1189:                }
        !          1190:                precache_check = CS_IMAGES;
        !          1191:        }
        !          1192:        if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES) {
        !          1193:                if (precache_check == CS_IMAGES)
        !          1194:                        precache_check++; // zero is blank
        !          1195:                while (precache_check < CS_IMAGES+MAX_IMAGES &&
        !          1196:                        cl.configstrings[precache_check][0]) {
        !          1197:                        Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);
        !          1198:                        if (!CL_CheckOrDownloadFile(fn))
        !          1199:                                return; // started a download
        !          1200:                }
        !          1201:                precache_check = CS_PLAYERSKINS;
        !          1202:        }
        !          1203:        // skins are special, since a player has three things to download:
        !          1204:        // model, weapon model and skin
        !          1205:        // so precache_check is now *3
        !          1206:        if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
        !          1207:                if (allow_download_players->value) {
        !          1208:                        while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
        !          1209:                                int i, n;
        !          1210:                                char model[MAX_QPATH], skin[MAX_QPATH], *p;
        !          1211: 
        !          1212:                                i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT;
        !          1213:                                n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT;
        !          1214: 
        !          1215:                                if (!cl.configstrings[CS_PLAYERSKINS+i][0]) {
        !          1216:                                        precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
        !          1217:                                        continue;
        !          1218:                                }
        !          1219: 
        !          1220:                                if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL)
        !          1221:                                        p++;
        !          1222:                                else
        !          1223:                                        p = cl.configstrings[CS_PLAYERSKINS+i];
        !          1224:                                strcpy(model, p);
        !          1225:                                p = strchr(model, '/');
        !          1226:                                if (!p)
        !          1227:                                        p = strchr(model, '\\');
        !          1228:                                if (p) {
        !          1229:                                        *p++ = 0;
        !          1230:                                        strcpy(skin, p);
        !          1231:                                } else
        !          1232:                                        *skin = 0;
        !          1233: 
        !          1234:                                switch (n) {
        !          1235:                                case 0: // model
        !          1236:                                        Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
        !          1237:                                        if (!CL_CheckOrDownloadFile(fn)) {
        !          1238:                                                precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1;
        !          1239:                                                return; // started a download
        !          1240:                                        }
        !          1241:                                        n++;
        !          1242:                                        /*FALL THROUGH*/
        !          1243: 
        !          1244:                                case 1: // weapon model
        !          1245:                                        Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);
        !          1246:                                        if (!CL_CheckOrDownloadFile(fn)) {
        !          1247:                                                precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2;
        !          1248:                                                return; // started a download
        !          1249:                                        }
        !          1250:                                        n++;
        !          1251:                                        /*FALL THROUGH*/
        !          1252: 
        !          1253:                                case 2: // weapon skin
        !          1254:                                        Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);
        !          1255:                                        if (!CL_CheckOrDownloadFile(fn)) {
        !          1256:                                                precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3;
        !          1257:                                                return; // started a download
        !          1258:                                        }
        !          1259:                                        n++;
        !          1260:                                        /*FALL THROUGH*/
        !          1261: 
        !          1262:                                case 3: // skin
        !          1263:                                        Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);
        !          1264:                                        if (!CL_CheckOrDownloadFile(fn)) {
        !          1265:                                                precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4;
        !          1266:                                                return; // started a download
        !          1267:                                        }
        !          1268:                                        n++;
        !          1269:                                        /*FALL THROUGH*/
        !          1270: 
        !          1271:                                case 4: // skin_i
        !          1272:                                        Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);
        !          1273:                                        if (!CL_CheckOrDownloadFile(fn)) {
        !          1274:                                                precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5;
        !          1275:                                                return; // started a download
        !          1276:                                        }
        !          1277:                                        // move on to next model
        !          1278:                                        precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
        !          1279:                                }
        !          1280:                        }
        !          1281:                }
        !          1282:                // precache phase completed
        !          1283:                precache_check = TEXTURE_CNT;
        !          1284:        }
        !          1285: 
        !          1286:        if (precache_check == TEXTURE_CNT) {
        !          1287:                precache_check = TEXTURE_CNT+1;
        !          1288:                precache_tex = 0;
        !          1289: 
        !          1290:                CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);
        !          1291: 
        !          1292:                if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM]))
        !          1293:                        Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
        !          1294:                        map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
        !          1295:        }
        !          1296: 
        !          1297:        // confirm existance of textures, download any that don't exist
        !          1298:        if (precache_check == TEXTURE_CNT+1) {
        !          1299:                // from qcommon/cmodel.c
        !          1300:                extern int                      numtexinfo;
        !          1301:                extern mapsurface_t     map_surfaces[];
        !          1302: 
        !          1303:                if (allow_download->value && allow_download_maps->value) {
        !          1304:                        while (precache_tex < numtexinfo) {
        !          1305:                                char fn[MAX_OSPATH];
        !          1306: 
        !          1307:                                sprintf(fn, "textures/%s.wal", map_surfaces[precache_tex++].rname);
        !          1308:                                if (!CL_CheckOrDownloadFile(fn))
        !          1309:                                        return; // started a download
        !          1310:                        }
        !          1311:                }
        !          1312:                precache_check = TEXTURE_CNT+999;
        !          1313:        }
        !          1314: 
        !          1315: //ZOID
        !          1316:        CL_RegisterSounds ();
        !          1317:        CL_PrepRefresh ();
        !          1318: 
        !          1319:        MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
        !          1320:        MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) );
        !          1321: }
        !          1322: 
1.1       root     1323: /*
                   1324: =================
                   1325: CL_Precache_f
1.1.1.2 ! root     1326: 
1.1       root     1327: The server will send this command right
                   1328: before allowing the client into the server
                   1329: =================
                   1330: */
                   1331: void CL_Precache_f (void)
                   1332: {
1.1.1.2 ! root     1333:        //Yet another hack to let old demos work
        !          1334:        //the old precache sequence
        !          1335:        if (Cmd_Argc() < 2) {
        !          1336:                unsigned        map_checksum;           // for detecting cheater maps
1.1       root     1337: 
1.1.1.2 ! root     1338:                CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);
        !          1339:                CL_RegisterSounds ();
        !          1340:                CL_PrepRefresh ();
        !          1341:                return;
        !          1342:        }
1.1       root     1343: 
1.1.1.2 ! root     1344:        precache_check = CS_MODELS;
        !          1345:        precache_spawncount = atoi(Cmd_Argv(1));
        !          1346:        precache_model = 0;
        !          1347:        precache_model_skin = 0;
        !          1348: 
        !          1349:        CL_RequestNextDownload();
1.1       root     1350: }
1.1.1.2 ! root     1351: 
        !          1352: 
1.1       root     1353: /*
                   1354: =================
                   1355: CL_InitLocal
                   1356: =================
                   1357: */
                   1358: void CL_InitLocal (void)
                   1359: {
                   1360:        cls.state = ca_disconnected;
                   1361:        cls.realtime = Sys_Milliseconds ();
1.1.1.2 ! root     1362: 
1.1       root     1363:        CL_InitInput ();
                   1364: 
                   1365:        adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
                   1366:        adr1 = Cvar_Get( "adr1", "", CVAR_ARCHIVE );
                   1367:        adr2 = Cvar_Get( "adr2", "", CVAR_ARCHIVE );
                   1368:        adr3 = Cvar_Get( "adr3", "", CVAR_ARCHIVE );
                   1369:        adr4 = Cvar_Get( "adr4", "", CVAR_ARCHIVE );
                   1370:        adr5 = Cvar_Get( "adr5", "", CVAR_ARCHIVE );
                   1371:        adr6 = Cvar_Get( "adr6", "", CVAR_ARCHIVE );
                   1372:        adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE );
                   1373:        adr8 = Cvar_Get( "adr8", "", CVAR_ARCHIVE );
1.1.1.2 ! root     1374: 
1.1       root     1375: //
                   1376: // register our variables
                   1377: //
                   1378:        cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE );
                   1379:        cl_stereo = Cvar_Get( "cl_stereo", "0", 0 );
                   1380: 
                   1381:        cl_add_blend = Cvar_Get ("cl_blend", "1", 0);
                   1382:        cl_add_lights = Cvar_Get ("cl_lights", "1", 0);
                   1383:        cl_add_particles = Cvar_Get ("cl_particles", "1", 0);
                   1384:        cl_add_entities = Cvar_Get ("cl_entities", "1", 0);
                   1385:        cl_gun = Cvar_Get ("cl_gun", "1", 0);
                   1386:        cl_footsteps = Cvar_Get ("cl_footsteps", "1", 0);
                   1387:        cl_noskins = Cvar_Get ("cl_noskins", "0", 0);
                   1388:        cl_autoskins = Cvar_Get ("cl_autoskins", "0", 0);
                   1389:        cl_predict = Cvar_Get ("cl_predict", "1", 0);
1.1.1.2 ! root     1390: //     cl_minfps = Cvar_Get ("cl_minfps", "5", 0);
1.1       root     1391:        cl_maxfps = Cvar_Get ("cl_maxfps", "90", 0);
1.1.1.2 ! root     1392: 
1.1       root     1393:        cl_upspeed = Cvar_Get ("cl_upspeed", "200", 0);
                   1394:        cl_forwardspeed = Cvar_Get ("cl_forwardspeed", "200", 0);
                   1395:        cl_sidespeed = Cvar_Get ("cl_sidespeed", "200", 0);
                   1396:        cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", 0);
                   1397:        cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "150", 0);
                   1398:        cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", 0);
1.1.1.2 ! root     1399: 
1.1       root     1400:        cl_run = Cvar_Get ("cl_run", "0", CVAR_ARCHIVE);
                   1401:        freelook = Cvar_Get( "freelook", "0", CVAR_ARCHIVE );
                   1402:        lookspring = Cvar_Get ("lookspring", "0", CVAR_ARCHIVE);
                   1403:        lookstrafe = Cvar_Get ("lookstrafe", "0", CVAR_ARCHIVE);
                   1404:        sensitivity = Cvar_Get ("sensitivity", "3", CVAR_ARCHIVE);
                   1405: 
                   1406:        m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE);
                   1407:        m_yaw = Cvar_Get ("m_yaw", "0.022", 0);
                   1408:        m_forward = Cvar_Get ("m_forward", "1", 0);
                   1409:        m_side = Cvar_Get ("m_side", "1", 0);
                   1410: 
                   1411:        cl_shownet = Cvar_Get ("cl_shownet", "0", 0);
                   1412:        cl_showmiss = Cvar_Get ("cl_showmiss", "0", 0);
                   1413:        cl_showclamp = Cvar_Get ("showclamp", "0", 0);
                   1414:        cl_timeout = Cvar_Get ("cl_timeout", "120", 0);
                   1415:        cl_paused = Cvar_Get ("paused", "0", 0);
                   1416:        cl_timedemo = Cvar_Get ("timedemo", "0", 0);
1.1.1.2 ! root     1417: 
1.1       root     1418:        rcon_client_password = Cvar_Get ("rcon_password", "", 0);
                   1419:        rcon_address = Cvar_Get ("rcon_address", "", 0);
1.1.1.2 ! root     1420: 
1.1       root     1421:        cl_lightlevel = Cvar_Get ("r_lightlevel", "0", 0);
1.1.1.2 ! root     1422: 
1.1       root     1423:        //
                   1424:        // userinfo
                   1425:        //
                   1426:        info_password = Cvar_Get ("password", "", CVAR_USERINFO);
                   1427:        name = Cvar_Get ("name", "unnamed", CVAR_USERINFO | CVAR_ARCHIVE);
                   1428:        skin = Cvar_Get ("skin", "male/grunt", CVAR_USERINFO | CVAR_ARCHIVE);
                   1429:        rate = Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE);        // FIXME
                   1430:        msg = Cvar_Get ("msg", "1", CVAR_USERINFO | CVAR_ARCHIVE);
                   1431:        hand = Cvar_Get ("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE);
                   1432:        fov = Cvar_Get ("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE);
1.1.1.2 ! root     1433:        gender = Cvar_Get ("gender", "male", CVAR_USERINFO | CVAR_ARCHIVE);
        !          1434:        gender_auto = Cvar_Get ("gender_auto", "1", CVAR_ARCHIVE);
        !          1435:        gender->modified = false; // clear this so we know when user sets it manually
        !          1436: 
        !          1437:        cl_vwep = Cvar_Get ("cl_vwep", "1", CVAR_ARCHIVE);
        !          1438: 
        !          1439: 
1.1       root     1440:        //
                   1441:        // register our commands
                   1442:        //
                   1443:        Cmd_AddCommand ("cmd", CL_ForwardToServer_f);
                   1444:        Cmd_AddCommand ("pause", CL_Pause_f);
                   1445:        Cmd_AddCommand ("pingservers", CL_PingServers_f);
                   1446:        Cmd_AddCommand ("skins", CL_Skins_f);
1.1.1.2 ! root     1447: 
1.1       root     1448:        Cmd_AddCommand ("userinfo", CL_Userinfo_f);
                   1449:        Cmd_AddCommand ("snd_restart", CL_Snd_Restart_f);
1.1.1.2 ! root     1450: 
1.1       root     1451:        Cmd_AddCommand ("changing", CL_Changing_f);
                   1452:        Cmd_AddCommand ("disconnect", CL_Disconnect_f);
                   1453:        Cmd_AddCommand ("record", CL_Record_f);
                   1454:        Cmd_AddCommand ("stop", CL_Stop_f);
1.1.1.2 ! root     1455: 
1.1       root     1456:        Cmd_AddCommand ("quit", CL_Quit_f);
1.1.1.2 ! root     1457: 
1.1       root     1458:        Cmd_AddCommand ("connect", CL_Connect_f);
                   1459:        Cmd_AddCommand ("reconnect", CL_Reconnect_f);
1.1.1.2 ! root     1460: 
1.1       root     1461:        Cmd_AddCommand ("rcon", CL_Rcon_f);
                   1462: 
                   1463: //     Cmd_AddCommand ("packet", CL_Packet_f); // this is dangerous to leave in
1.1.1.2 ! root     1464: 
1.1       root     1465:        Cmd_AddCommand ("setenv", CL_Setenv_f );
1.1.1.2 ! root     1466: 
1.1       root     1467:        Cmd_AddCommand ("precache", CL_Precache_f);
1.1.1.2 ! root     1468: 
        !          1469:        Cmd_AddCommand ("download", CL_Download_f);
        !          1470: 
1.1       root     1471:        //
                   1472:        // forward to server commands
                   1473:        //
                   1474:        // the only thing this does is allow command completion
                   1475:        // to work -- all unknown commands are automatically
                   1476:        // forwarded to the server
                   1477:        Cmd_AddCommand ("wave", NULL);
                   1478:        Cmd_AddCommand ("inven", NULL);
                   1479:        Cmd_AddCommand ("kill", NULL);
                   1480:        Cmd_AddCommand ("use", NULL);
                   1481:        Cmd_AddCommand ("drop", NULL);
                   1482:        Cmd_AddCommand ("say", NULL);
                   1483:        Cmd_AddCommand ("say_team", NULL);
                   1484:        Cmd_AddCommand ("info", NULL);
                   1485:        Cmd_AddCommand ("prog", NULL);
                   1486:        Cmd_AddCommand ("give", NULL);
                   1487:        Cmd_AddCommand ("god", NULL);
                   1488:        Cmd_AddCommand ("notarget", NULL);
                   1489:        Cmd_AddCommand ("noclip", NULL);
                   1490:        Cmd_AddCommand ("invuse", NULL);
                   1491:        Cmd_AddCommand ("invprev", NULL);
                   1492:        Cmd_AddCommand ("invnext", NULL);
                   1493:        Cmd_AddCommand ("invdrop", NULL);
                   1494:        Cmd_AddCommand ("weapnext", NULL);
                   1495:        Cmd_AddCommand ("weapprev", NULL);
                   1496: }
1.1.1.2 ! root     1497: 
        !          1498: 
        !          1499: 
1.1       root     1500: /*
                   1501: ===============
                   1502: CL_WriteConfiguration
1.1.1.2 ! root     1503: 
1.1       root     1504: Writes key bindings and archived cvars to config.cfg
                   1505: ===============
                   1506: */
                   1507: void CL_WriteConfiguration (void)
                   1508: {
                   1509:        FILE    *f;
                   1510:        char    path[MAX_QPATH];
1.1.1.2 ! root     1511: 
1.1       root     1512:        if (cls.state == ca_uninitialized)
                   1513:                return;
1.1.1.2 ! root     1514: 
1.1       root     1515:        Com_sprintf (path, sizeof(path),"%s/config.cfg",FS_Gamedir());
                   1516:        f = fopen (path, "w");
                   1517:        if (!f)
                   1518:        {
                   1519:                Com_Printf ("Couldn't write config.cfg.\n");
                   1520:                return;
                   1521:        }
1.1.1.2 ! root     1522: 
1.1       root     1523:        fprintf (f, "// generated by quake, do not modify\n");
                   1524:        Key_WriteBindings (f);
                   1525:        fclose (f);
1.1.1.2 ! root     1526: 
1.1       root     1527:        Cvar_WriteVariables (path);
                   1528: }
                   1529: 
1.1.1.2 ! root     1530: 
1.1       root     1531: /*
                   1532: ==================
                   1533: CL_FixCvarCheats
                   1534: 
                   1535: ==================
                   1536: */
                   1537: 
                   1538: typedef struct
                   1539: {
                   1540:        char    *name;
                   1541:        char    *value;
                   1542:        cvar_t  *var;
                   1543: } cheatvar_t;
                   1544: 
                   1545: cheatvar_t     cheatvars[] = {
                   1546:        {"timescale", "1"},
                   1547:        {"timedemo", "0"},
                   1548:        {"r_drawworld", "1"},
                   1549:        {"cl_testlights", "0"},
                   1550:        {"r_fullbright", "0"},
                   1551:        {"r_drawflat", "0"},
                   1552:        {"paused", "0"},
                   1553:        {"fixedtime", "0"},
1.1.1.2 ! root     1554:        {"sw_draworder", "0"},
        !          1555:        {"gl_lightmap", "0"},
        !          1556:        {"gl_saturatelighting", "0"},
1.1       root     1557:        {NULL, NULL}
                   1558: };
                   1559: 
                   1560: int            numcheatvars;
                   1561: 
                   1562: void CL_FixCvarCheats (void)
                   1563: {
                   1564:        int                     i;
                   1565:        cheatvar_t      *var;
                   1566: 
                   1567:        if ( !strcmp(cl.configstrings[CS_MAXCLIENTS], "1") 
                   1568:                || !cl.configstrings[CS_MAXCLIENTS][0] )
                   1569:                return;         // single player can cheat
                   1570: 
                   1571:        // find all the cvars if we haven't done it yet
                   1572:        if (!numcheatvars)
                   1573:        {
                   1574:                while (cheatvars[numcheatvars].name)
                   1575:                {
                   1576:                        cheatvars[numcheatvars].var = Cvar_Get (cheatvars[numcheatvars].name,
                   1577:                                        cheatvars[numcheatvars].value, 0);
                   1578:                        numcheatvars++;
                   1579:                }
                   1580:        }
                   1581: 
                   1582:        // make sure they are all set to the proper values
                   1583:        for (i=0, var = cheatvars ; i<numcheatvars ; i++, var++)
                   1584:        {
                   1585:                if ( strcmp (var->var->string, var->value) )
                   1586:                {
                   1587:                        Cvar_Set (var->name, var->value);
                   1588:                }
                   1589:        }
                   1590: }
1.1.1.2 ! root     1591: 
1.1       root     1592: //============================================================================
                   1593: 
                   1594: /*
                   1595: ==================
                   1596: CL_SendCommand
                   1597: 
                   1598: ==================
                   1599: */
                   1600: void CL_SendCommand (void)
                   1601: {
                   1602:        // get new key events
                   1603:        Sys_SendKeyEvents ();
                   1604: 
                   1605:        // allow mice or other external controllers to add commands
                   1606:        IN_Commands ();
                   1607: 
                   1608:        // process console commands
                   1609:        Cbuf_Execute ();
                   1610: 
                   1611:        // fix any cheating cvars
                   1612:        CL_FixCvarCheats ();
                   1613: 
                   1614:        // send intentions now
                   1615:        CL_SendCmd ();
                   1616: 
                   1617:        // resend a connection request if necessary
                   1618:        CL_CheckForResend ();
                   1619: }
1.1.1.2 ! root     1620: 
        !          1621: 
1.1       root     1622: /*
                   1623: ==================
                   1624: CL_Frame
1.1.1.2 ! root     1625: 
1.1       root     1626: ==================
                   1627: */
                   1628: void CL_Frame (int msec)
                   1629: {
                   1630:        static int      extratime;
                   1631:        static int  lasttimecalled;
1.1.1.2 ! root     1632: 
1.1       root     1633:        if (dedicated->value)
                   1634:                return;
1.1.1.2 ! root     1635: 
1.1       root     1636:        extratime += msec;
                   1637: 
                   1638:        if (!cl_timedemo->value)
                   1639:        {
                   1640:                if (cls.state == ca_connected && extratime < 100)
                   1641:                        return;                 // don't flood packets out while connecting
                   1642:                if (extratime < 1000/cl_maxfps->value)
                   1643:                        return;                 // framerate is too high
                   1644:        }
                   1645: 
                   1646:        // let the mouse activate or deactivate
                   1647:        IN_Frame ();
1.1.1.2 ! root     1648: 
1.1       root     1649:        // decide the simulation time
                   1650:        cls.frametime = extratime/1000.0;
                   1651:        cl.time += extratime;
                   1652:        cls.realtime = curtime;
1.1.1.2 ! root     1653: 
1.1       root     1654:        extratime = 0;
1.1.1.2 ! root     1655: #if 0
1.1       root     1656:        if (cls.frametime > (1.0 / cl_minfps->value))
                   1657:                cls.frametime = (1.0 / cl_minfps->value);
1.1.1.2 ! root     1658: #else
        !          1659:        if (cls.frametime > (1.0 / 5))
        !          1660:                cls.frametime = (1.0 / 5);
        !          1661: #endif
        !          1662: 
1.1       root     1663:        // if in the debugger last frame, don't timeout
                   1664:        if (msec > 5000)
                   1665:                cls.netchan.last_received = Sys_Milliseconds ();
                   1666: 
                   1667:        // fetch results from server
                   1668:        CL_ReadPackets ();
                   1669: 
                   1670:        // send a new command message to the server
                   1671:        CL_SendCommand ();
                   1672: 
                   1673:        // predict all unacknowledged movements
                   1674:        CL_PredictMovement ();
1.1.1.2 ! root     1675: 
1.1       root     1676:        // allow rendering DLL change
                   1677:        VID_CheckChanges ();
                   1678:        if (!cl.refresh_prepped && cls.state == ca_active)
                   1679:                CL_PrepRefresh ();
                   1680: 
                   1681:        // update the screen
                   1682:        if (host_speeds->value)
                   1683:                time_before_ref = Sys_Milliseconds ();
                   1684:        SCR_UpdateScreen ();
                   1685:        if (host_speeds->value)
                   1686:                time_after_ref = Sys_Milliseconds ();
1.1.1.2 ! root     1687: 
1.1       root     1688:        // update audio
                   1689:        S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up);
                   1690:        
                   1691:        CDAudio_Update();
                   1692: 
                   1693:        // advance local effects for next frame
                   1694:        CL_RunDLights ();
                   1695:        CL_RunLightStyles ();
                   1696:        SCR_RunCinematic ();
                   1697:        SCR_RunConsole ();
                   1698: 
                   1699:        cls.framecount++;
                   1700: 
                   1701:        if ( log_stats->value )
                   1702:        {
                   1703:                if ( cls.state == ca_active )
                   1704:                {
                   1705:                        if ( !lasttimecalled )
                   1706:                        {
                   1707:                                lasttimecalled = Sys_Milliseconds();
                   1708:                                if ( log_stats_file )
                   1709:                                        fprintf( log_stats_file, "0\n" );
                   1710:                        }
                   1711:                        else
                   1712:                        {
                   1713:                                int now = Sys_Milliseconds();
                   1714: 
                   1715:                                if ( log_stats_file )
                   1716:                                        fprintf( log_stats_file, "%d\n", now - lasttimecalled );
                   1717:                                lasttimecalled = now;
                   1718:                        }
                   1719:                }
                   1720:        }
                   1721: }
1.1.1.2 ! root     1722: 
        !          1723: 
1.1       root     1724: //============================================================================
1.1.1.2 ! root     1725: 
1.1       root     1726: /*
                   1727: ====================
                   1728: CL_Init
                   1729: ====================
                   1730: */
                   1731: void CL_Init (void)
                   1732: {
                   1733:        if (dedicated->value)
                   1734:                return;         // nothing running on the client
1.1.1.2 ! root     1735: 
1.1       root     1736:        // all archived variables will now be loaded
1.1.1.2 ! root     1737: 
1.1       root     1738:        Con_Init ();    
1.1.1.2 ! root     1739: #if defined __linux__ || defined __sgi
        !          1740:        S_Init ();      
        !          1741:        VID_Init ();
        !          1742: #else
1.1       root     1743:        VID_Init ();
                   1744:        S_Init ();      // sound must be initialized after window is created
1.1.1.2 ! root     1745: #endif
1.1       root     1746:        
                   1747:        V_Init ();
                   1748:        
                   1749:        net_message.data = net_message_buffer;
                   1750:        net_message.maxsize = sizeof(net_message_buffer);
1.1.1.2 ! root     1751: 
1.1       root     1752:        M_Init ();      
                   1753:        
                   1754:        SCR_Init ();
                   1755:        cls.disable_screen = true;      // don't draw yet
1.1.1.2 ! root     1756: 
1.1       root     1757:        CDAudio_Init ();
                   1758:        CL_InitLocal ();
                   1759:        IN_Init ();
1.1.1.2 ! root     1760: 
1.1       root     1761: //     Cbuf_AddText ("exec autoexec.cfg\n");
                   1762:        FS_ExecAutoexec ();
                   1763:        Cbuf_Execute ();
1.1.1.2 ! root     1764: 
1.1       root     1765: }
1.1.1.2 ! root     1766: 
        !          1767: 
1.1       root     1768: /*
                   1769: ===============
                   1770: CL_Shutdown
1.1.1.2 ! root     1771: 
1.1       root     1772: FIXME: this is a callback from Sys_Quit and Com_Error.  It would be better
                   1773: to run quit through here before the final handoff to the sys code.
                   1774: ===============
                   1775: */
                   1776: void CL_Shutdown(void)
                   1777: {
                   1778:        static qboolean isdown = false;
                   1779:        
                   1780:        if (isdown)
                   1781:        {
                   1782:                printf ("recursive shutdown\n");
                   1783:                return;
                   1784:        }
                   1785:        isdown = true;
1.1.1.2 ! root     1786: 
1.1       root     1787:        CL_WriteConfiguration (); 
1.1.1.2 ! root     1788: 
1.1       root     1789:        CDAudio_Shutdown ();
                   1790:        S_Shutdown();
                   1791:        IN_Shutdown ();
                   1792:        VID_Shutdown();
                   1793: }
                   1794: 
                   1795: 

unix.superglobalmegacorp.com

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