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

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

unix.superglobalmegacorp.com

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