Annotation of quake1/host.c, revision 1.1.1.3

1.1       root        1: // host.c -- coordinates spawning and killing of local servers
                      2: 
                      3: #include "quakedef.h"
                      4: #include "r_local.h"
                      5: 
                      6: /*
                      7: 
                      8: A server can allways be started, even if the system started out as a client
                      9: to a remote system.
                     10: 
                     11: A client can NOT be started if the system started as a dedicated server.
                     12: 
                     13: Memory is cleared / released when a server or client begins, not when they end.
                     14: 
                     15: */
                     16: 
                     17: quakeparms_t host_parms;
                     18: 
                     19: qboolean       host_initialized;               // true if into command execution
                     20: 
                     21: double         host_frametime;
                     22: double         host_time;
                     23: double         realtime;                               // without any filtering or bounding
                     24: double         oldrealtime;                    // last frame run
                     25: int                    host_framecount;
                     26: 
                     27: int                    host_hunklevel;
                     28: 
1.1.1.3 ! root       29: int                    minimum_memory;
        !            30: 
1.1       root       31: client_t       *host_client;                   // current client
                     32: 
                     33: jmp_buf        host_abortserver;
                     34: 
                     35: byte           *host_basepal;
                     36: byte           *host_colormap;
                     37: 
                     38: cvar_t host_framerate = {"host_framerate","0"};        // set for slow motion
                     39: cvar_t host_speeds = {"host_speeds","0"};                      // set for running times
                     40: 
                     41: cvar_t sys_ticrate = {"sys_ticrate","0.05"};
                     42: cvar_t serverprofile = {"serverprofile","0"};
                     43: 
                     44: cvar_t fraglimit = {"fraglimit","0",false,true};
                     45: cvar_t timelimit = {"timelimit","0",false,true};
                     46: cvar_t teamplay = {"teamplay","0",false,true};
                     47: 
                     48: cvar_t samelevel = {"samelevel","0"};
                     49: cvar_t noexit = {"noexit","0",false,true};
                     50: 
1.1.1.3 ! root       51: #ifdef QUAKE2
        !            52: cvar_t developer = {"developer","1"};  // should be 0 for release!
        !            53: #else
1.1       root       54: cvar_t developer = {"developer","0"};
1.1.1.3 ! root       55: #endif
1.1       root       56: 
                     57: cvar_t skill = {"skill","1"};                                          // 0 - 3
                     58: cvar_t deathmatch = {"deathmatch","0"};                        // 0, 1, or 2
                     59: cvar_t coop = {"coop","0"};                    // 0 or 1
                     60: 
                     61: cvar_t pausable = {"pausable","1"};
                     62: 
                     63: cvar_t temp1 = {"temp1","0"};
                     64: 
                     65: 
                     66: /*
                     67: ================
                     68: Host_EndGame
                     69: ================
                     70: */
                     71: void Host_EndGame (char *message, ...)
                     72: {
                     73:        va_list         argptr;
                     74:        char            string[1024];
                     75:        
                     76:        va_start (argptr,message);
                     77:        vsprintf (string,message,argptr);
                     78:        va_end (argptr);
                     79:        Con_DPrintf ("Host_EndGame: %s\n",string);
                     80:        
                     81:        if (sv.active)
                     82:                Host_ShutdownServer (false);
                     83: 
                     84:        if (cls.state == ca_dedicated)
                     85:                Sys_Error ("Host_EndGame: %s\n",string);        // dedicated servers exit
                     86:        
                     87:        if (cls.demonum != -1)
                     88:                CL_NextDemo ();
                     89:        else
                     90:                CL_Disconnect ();
                     91: 
                     92:        longjmp (host_abortserver, 1);
                     93: }
                     94: 
                     95: /*
                     96: ================
                     97: Host_Error
                     98: 
                     99: This shuts down both the client and server
                    100: ================
                    101: */
                    102: void Host_Error (char *error, ...)
                    103: {
                    104:        va_list         argptr;
                    105:        char            string[1024];
                    106:        static  qboolean inerror = false;
                    107:        
                    108:        if (inerror)
                    109:                Sys_Error ("Host_Error: recursively entered");
                    110:        inerror = true;
                    111:        
                    112:        SCR_EndLoadingPlaque ();                // reenable screen updates
                    113: 
                    114:        va_start (argptr,error);
                    115:        vsprintf (string,error,argptr);
                    116:        va_end (argptr);
                    117:        Con_Printf ("Host_Error: %s\n",string);
                    118:        
                    119:        if (sv.active)
                    120:                Host_ShutdownServer (false);
                    121: 
                    122:        if (cls.state == ca_dedicated)
                    123:                Sys_Error ("Host_Error: %s\n",string);  // dedicated servers exit
                    124: 
                    125:        CL_Disconnect ();
                    126:        cls.demonum = -1;
                    127: 
                    128:        inerror = false;
                    129: 
                    130:        longjmp (host_abortserver, 1);
                    131: }
                    132: 
                    133: /*
                    134: ================
                    135: Host_FindMaxClients
                    136: ================
                    137: */
                    138: void   Host_FindMaxClients (void)
                    139: {
                    140:        int             i;
                    141: 
                    142:        svs.maxclients = 1;
                    143:                
                    144:        i = COM_CheckParm ("-dedicated");
                    145:        if (i)
                    146:        {
                    147:                cls.state = ca_dedicated;
                    148:                if (i != (com_argc - 1))
                    149:                {
                    150:                        svs.maxclients = Q_atoi (com_argv[i+1]);
                    151:                }
                    152:                else
                    153:                        svs.maxclients = 8;
                    154:        }
                    155:        else
                    156:                cls.state = ca_disconnected;
                    157: 
                    158:        i = COM_CheckParm ("-listen");
                    159:        if (i)
                    160:        {
                    161:                if (cls.state == ca_dedicated)
                    162:                        Sys_Error ("Only one of -dedicated or -listen can be specified");
                    163:                if (i != (com_argc - 1))
                    164:                        svs.maxclients = Q_atoi (com_argv[i+1]);
                    165:                else
                    166:                        svs.maxclients = 8;
                    167:        }
                    168:        if (svs.maxclients < 1)
                    169:                svs.maxclients = 8;
                    170:        else if (svs.maxclients > MAX_SCOREBOARD)
                    171:                svs.maxclients = MAX_SCOREBOARD;
                    172: 
                    173:        svs.maxclientslimit = svs.maxclients;
                    174:        if (svs.maxclientslimit < 4)
                    175:                svs.maxclientslimit = 4;
                    176:        svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients");
                    177: 
                    178:        if (svs.maxclients > 1)
                    179:                Cvar_SetValue ("deathmatch", 1.0);
                    180:        else
                    181:                Cvar_SetValue ("deathmatch", 0.0);
                    182: }
                    183: 
                    184: 
                    185: /*
                    186: =======================
                    187: Host_InitLocal
                    188: ======================
                    189: */
                    190: void Host_InitLocal (void)
                    191: {
                    192:        Host_InitCommands ();
                    193:        
                    194:        Cvar_RegisterVariable (&host_framerate);
                    195:        Cvar_RegisterVariable (&host_speeds);
                    196: 
                    197:        Cvar_RegisterVariable (&sys_ticrate);
                    198:        Cvar_RegisterVariable (&serverprofile);
                    199: 
                    200:        Cvar_RegisterVariable (&fraglimit);
                    201:        Cvar_RegisterVariable (&timelimit);
                    202:        Cvar_RegisterVariable (&teamplay);
                    203:        Cvar_RegisterVariable (&samelevel);
                    204:        Cvar_RegisterVariable (&noexit);
                    205:        Cvar_RegisterVariable (&skill);
                    206:        Cvar_RegisterVariable (&developer);
                    207:        Cvar_RegisterVariable (&deathmatch);
                    208:        Cvar_RegisterVariable (&coop);
                    209: 
                    210:        Cvar_RegisterVariable (&pausable);
                    211: 
                    212:        Cvar_RegisterVariable (&temp1);
                    213: 
                    214:        Host_FindMaxClients ();
                    215:        
                    216:        host_time = 1.0;                // so a think at time 0 won't get called
                    217: }
                    218: 
                    219: 
                    220: /*
                    221: ===============
                    222: Host_WriteConfiguration
                    223: 
                    224: Writes key bindings and archived cvars to config.cfg
                    225: ===============
                    226: */
                    227: void Host_WriteConfiguration (void)
                    228: {
                    229:        FILE    *f;
1.1.1.3 ! root      230: 
        !           231: // dedicated servers initialize the host but don't parse and set the
        !           232: // config.cfg cvars
        !           233:        if (host_initialized & !isDedicated)
1.1       root      234:        {
1.1.1.3 ! root      235:                f = fopen (va("%s/config.cfg",com_gamedir), "w");
        !           236:                if (!f)
        !           237:                {
        !           238:                        Con_Printf ("Couldn't write config.cfg.\n");
        !           239:                        return;
        !           240:                }
        !           241:                
        !           242:                Key_WriteBindings (f);
        !           243:                Cvar_WriteVariables (f);
1.1       root      244: 
1.1.1.3 ! root      245:                fclose (f);
        !           246:        }
1.1       root      247: }
                    248: 
                    249: 
                    250: /*
                    251: =================
                    252: SV_ClientPrintf
                    253: 
                    254: Sends text across to be displayed 
                    255: FIXME: make this just a stuffed echo?
                    256: =================
                    257: */
                    258: void SV_ClientPrintf (char *fmt, ...)
                    259: {
                    260:        va_list         argptr;
                    261:        char            string[1024];
                    262:        
                    263:        va_start (argptr,fmt);
                    264:        vsprintf (string, fmt,argptr);
                    265:        va_end (argptr);
                    266:        
                    267:        MSG_WriteByte (&host_client->message, svc_print);
                    268:        MSG_WriteString (&host_client->message, string);
                    269: }
                    270: 
                    271: /*
                    272: =================
                    273: SV_BroadcastPrintf
                    274: 
                    275: Sends text to all active clients
                    276: =================
                    277: */
                    278: void SV_BroadcastPrintf (char *fmt, ...)
                    279: {
                    280:        va_list         argptr;
                    281:        char            string[1024];
                    282:        int                     i;
                    283:        
                    284:        va_start (argptr,fmt);
                    285:        vsprintf (string, fmt,argptr);
                    286:        va_end (argptr);
                    287:        
                    288:        for (i=0 ; i<svs.maxclients ; i++)
                    289:                if (svs.clients[i].active && svs.clients[i].spawned)
                    290:                {
                    291:                        MSG_WriteByte (&svs.clients[i].message, svc_print);
                    292:                        MSG_WriteString (&svs.clients[i].message, string);
                    293:                }
                    294: }
                    295: 
                    296: /*
                    297: =================
                    298: Host_ClientCommands
                    299: 
                    300: Send text over to the client to be executed
                    301: =================
                    302: */
                    303: void Host_ClientCommands (char *fmt, ...)
                    304: {
                    305:        va_list         argptr;
                    306:        char            string[1024];
                    307:        
                    308:        va_start (argptr,fmt);
                    309:        vsprintf (string, fmt,argptr);
                    310:        va_end (argptr);
                    311:        
                    312:        MSG_WriteByte (&host_client->message, svc_stufftext);
                    313:        MSG_WriteString (&host_client->message, string);
                    314: }
                    315: 
                    316: /*
                    317: =====================
                    318: SV_DropClient
                    319: 
                    320: Called when the player is getting totally kicked off the host
                    321: if (crash = true), don't bother sending signofs
                    322: =====================
                    323: */
                    324: void SV_DropClient (qboolean crash)
                    325: {
                    326:        int             saveSelf;
                    327:        int             i;
                    328:        client_t *client;
                    329: 
                    330:        if (!crash)
                    331:        {
                    332:                // send any final messages (don't check for errors)
                    333:                if (NET_CanSendMessage (host_client->netconnection))
                    334:                {
                    335:                        MSG_WriteByte (&host_client->message, svc_disconnect);
                    336:                        NET_SendMessage (host_client->netconnection, &host_client->message);
                    337:                }
                    338:        
                    339:                if (host_client->edict && host_client->spawned)
                    340:                {
                    341:                // call the prog function for removing a client
                    342:                // this will set the body to a dead frame, among other things
                    343:                        saveSelf = pr_global_struct->self;
                    344:                        pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
                    345:                        PR_ExecuteProgram (pr_global_struct->ClientDisconnect);
                    346:                        pr_global_struct->self = saveSelf;
                    347:                }
                    348: 
                    349:                Sys_Printf ("Client %s removed\n",host_client->name);
                    350:        }
                    351: 
                    352: // break the net connection
                    353:        NET_Close (host_client->netconnection);
                    354:        host_client->netconnection = NULL;
                    355: 
                    356: // free the client (the body stays around)
                    357:        host_client->active = false;
                    358:        host_client->name[0] = 0;
                    359:        host_client->old_frags = -999999;
                    360:        net_activeconnections--;
                    361: 
                    362: // send notification to all clients
                    363:        for (i=0, client = svs.clients ; i<svs.maxclients ; i++, client++)
                    364:        {
                    365:                if (!client->active)
                    366:                        continue;
                    367:                MSG_WriteByte (&client->message, svc_updatename);
                    368:                MSG_WriteByte (&client->message, host_client - svs.clients);
                    369:                MSG_WriteString (&client->message, "");
                    370:                MSG_WriteByte (&client->message, svc_updatefrags);
                    371:                MSG_WriteByte (&client->message, host_client - svs.clients);
                    372:                MSG_WriteShort (&client->message, 0);
                    373:                MSG_WriteByte (&client->message, svc_updatecolors);
                    374:                MSG_WriteByte (&client->message, host_client - svs.clients);
                    375:                MSG_WriteByte (&client->message, 0);
                    376:        }
                    377: }
                    378: 
                    379: /*
                    380: ==================
                    381: Host_ShutdownServer
                    382: 
                    383: This only happens at the end of a game, not between levels
                    384: ==================
                    385: */
                    386: void Host_ShutdownServer(qboolean crash)
                    387: {
                    388:        int             i;
                    389:        int             count;
                    390:        sizebuf_t       buf;
                    391:        char            message[4];
                    392:        double  start;
                    393: 
                    394:        if (!sv.active)
                    395:                return;
                    396: 
                    397:        sv.active = false;
                    398: 
                    399: // stop all client sounds immediately
                    400:        if (cls.state == ca_connected)
                    401:                CL_Disconnect ();
                    402: 
                    403: // flush any pending messages - like the score!!!
                    404:        start = Sys_FloatTime();
                    405:        do
                    406:        {
                    407:                count = 0;
                    408:                for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
                    409:                {
                    410:                        if (host_client->active && host_client->message.cursize)
                    411:                        {
                    412:                                if (NET_CanSendMessage (host_client->netconnection))
                    413:                                {
                    414:                                        NET_SendMessage(host_client->netconnection, &host_client->message);
                    415:                                        SZ_Clear (&host_client->message);
                    416:                                }
                    417:                                else
                    418:                                {
                    419:                                        NET_GetMessage(host_client->netconnection);
                    420:                                        count++;
                    421:                                }
                    422:                        }
                    423:                }
                    424:                if ((Sys_FloatTime() - start) > 3.0)
                    425:                        break;
                    426:        }
                    427:        while (count);
                    428: 
                    429: // make sure all the clients know we're disconnecting
                    430:        buf.data = message;
                    431:        buf.maxsize = 4;
                    432:        buf.cursize = 0;
                    433:        MSG_WriteByte(&buf, svc_disconnect);
                    434:        count = NET_SendToAll(&buf, 5);
                    435:        if (count)
                    436:                Con_Printf("Host_ShutdownServer: NET_SendToAll failed for %u clients\n", count);
                    437: 
                    438:        for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
                    439:                if (host_client->active)
                    440:                        SV_DropClient(crash);
                    441: 
                    442: //
                    443: // clear structures
                    444: //
                    445:        memset (&sv, 0, sizeof(sv));
                    446:        memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t));
                    447: }
                    448: 
                    449: 
                    450: /*
                    451: ================
                    452: Host_ClearMemory
                    453: 
                    454: This clears all the memory used by both the client and server, but does
                    455: not reinitialize anything.
                    456: ================
                    457: */
                    458: void Host_ClearMemory (void)
                    459: {
                    460:        Con_DPrintf ("Clearing memory\n");
                    461:        D_FlushCaches ();
                    462:        Mod_ClearAll ();
                    463:        if (host_hunklevel)
                    464:                Hunk_FreeToLowMark (host_hunklevel);
                    465: 
                    466:        cls.signon = 0;
                    467:        memset (&sv, 0, sizeof(sv));
                    468:        memset (&cl, 0, sizeof(cl));
                    469: }
                    470: 
                    471: 
                    472: //============================================================================
                    473: 
                    474: 
                    475: /*
                    476: ===================
                    477: Host_FilterTime
                    478: 
                    479: Returns false if the time is too short to run a frame
                    480: ===================
                    481: */
                    482: qboolean Host_FilterTime (float time)
                    483: {
                    484:        realtime += time;
                    485: 
1.1.1.3 ! root      486:        if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0)
1.1       root      487:                return false;           // framerate is too high
                    488: 
                    489:        host_frametime = realtime - oldrealtime;
                    490:        oldrealtime = realtime;
                    491: 
                    492:        if (host_framerate.value > 0)
                    493:                host_frametime = host_framerate.value;
                    494:        else
                    495:        {       // don't allow really long or short frames
                    496:                if (host_frametime > 0.1)
                    497:                        host_frametime = 0.1;
                    498:                if (host_frametime < 0.001)
                    499:                        host_frametime = 0.001;
                    500:        }
                    501:        
                    502:        return true;
                    503: }
                    504: 
                    505: 
                    506: /*
                    507: ===================
                    508: Host_GetConsoleCommands
                    509: 
                    510: Add them exactly as if they had been typed at the console
                    511: ===================
                    512: */
                    513: void Host_GetConsoleCommands (void)
                    514: {
                    515:        char    *cmd;
                    516: 
                    517:        while (1)
                    518:        {
                    519:                cmd = Sys_ConsoleInput ();
                    520:                if (!cmd)
                    521:                        break;
                    522:                Cbuf_AddText (cmd);
                    523:        }
                    524: }
                    525: 
1.1.1.3 ! root      526: 
1.1       root      527: /*
                    528: ==================
                    529: Host_ServerFrame
                    530: 
                    531: ==================
                    532: */
1.1.1.3 ! root      533: #ifdef FPS_20
        !           534: 
        !           535: void _Host_ServerFrame (void)
        !           536: {
        !           537: // run the world state 
        !           538:        pr_global_struct->frametime = host_frametime;
        !           539: 
        !           540: // read client messages
        !           541:        SV_RunClients ();
        !           542:        
        !           543: // move things around and think
        !           544: // always pause in single player if in console or menus
        !           545:        if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
        !           546:                SV_Physics ();
        !           547: }
        !           548: 
        !           549: void Host_ServerFrame (void)
        !           550: {
        !           551:        float   save_host_frametime;
        !           552:        float   temp_host_frametime;
        !           553: 
        !           554: // run the world state 
        !           555:        pr_global_struct->frametime = host_frametime;
        !           556: 
        !           557: // set the time and clear the general datagram
        !           558:        SV_ClearDatagram ();
        !           559:        
        !           560: // check for new clients
        !           561:        SV_CheckForNewClients ();
        !           562: 
        !           563:        temp_host_frametime = save_host_frametime = host_frametime;
        !           564:        while(temp_host_frametime > (1.0/72.0))
        !           565:        {
        !           566:                if (temp_host_frametime > 0.05)
        !           567:                        host_frametime = 0.05;
        !           568:                else
        !           569:                        host_frametime = temp_host_frametime;
        !           570:                temp_host_frametime -= host_frametime;
        !           571:                _Host_ServerFrame ();
        !           572:        }
        !           573:        host_frametime = save_host_frametime;
        !           574: 
        !           575: // send all messages to the clients
        !           576:        SV_SendClientMessages ();
        !           577: }
        !           578: 
        !           579: #else
        !           580: 
1.1       root      581: void Host_ServerFrame (void)
                    582: {
                    583: // run the world state 
                    584:        pr_global_struct->frametime = host_frametime;
                    585: 
                    586: // set the time and clear the general datagram
                    587:        SV_ClearDatagram ();
                    588:        
                    589: // check for new clients
                    590:        SV_CheckForNewClients ();
                    591: 
                    592: // read client messages
                    593:        SV_RunClients ();
                    594:        
                    595: // move things around and think
1.1.1.3 ! root      596: // always pause in single player if in console or menus
1.1       root      597:        if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
                    598:                SV_Physics ();
                    599: 
                    600: // send all messages to the clients
                    601:        SV_SendClientMessages ();
                    602: }
                    603: 
1.1.1.3 ! root      604: #endif
        !           605: 
        !           606: 
1.1       root      607: /*
                    608: ==================
                    609: Host_Frame
                    610: 
                    611: Runs all active servers
                    612: ==================
                    613: */
                    614: void _Host_Frame (float time)
                    615: {
                    616:        static double           time1 = 0;
                    617:        static double           time2 = 0;
                    618:        static double           time3 = 0;
                    619:        int                     pass1, pass2, pass3;
                    620: 
                    621:        if (setjmp (host_abortserver) )
                    622:                return;                 // something bad happened, or the server disconnected
                    623: 
                    624: // keep the random time dependent
                    625:        rand ();
                    626:        
                    627: // decide the simulation time
                    628:        if (!Host_FilterTime (time))
                    629:                return;                 // don't run too fast, or packets will flood out
                    630:                
                    631: // get new key events
                    632:        Sys_SendKeyEvents ();
                    633: 
                    634: // allow mice or other external controllers to add commands
                    635:        IN_Commands ();
                    636: 
                    637: // process console commands
                    638:        Cbuf_Execute ();
                    639: 
                    640:        NET_Poll();
                    641: 
                    642: // if running the server locally, make intentions now
                    643:        if (sv.active)
                    644:                CL_SendCmd ();
                    645:        
                    646: //-------------------
                    647: //
                    648: // server operations
                    649: //
                    650: //-------------------
                    651: 
                    652: // check for commands typed to the host
                    653:        Host_GetConsoleCommands ();
                    654:        
                    655:        if (sv.active)
                    656:                Host_ServerFrame ();
                    657: 
                    658: //-------------------
                    659: //
                    660: // client operations
                    661: //
                    662: //-------------------
                    663: 
                    664: // if running the server remotely, send intentions now after
                    665: // the incoming messages have been read
                    666:        if (!sv.active)
                    667:                CL_SendCmd ();
                    668: 
                    669:        host_time += host_frametime;
                    670: 
                    671: // fetch results from server
                    672:        if (cls.state == ca_connected)
1.1.1.3 ! root      673:        {
1.1       root      674:                CL_ReadFromServer ();
1.1.1.3 ! root      675:        }
1.1       root      676: 
                    677: // update video
                    678:        if (host_speeds.value)
                    679:                time1 = Sys_FloatTime ();
                    680:                
                    681:        SCR_UpdateScreen ();
                    682: 
                    683:        if (host_speeds.value)
                    684:                time2 = Sys_FloatTime ();
                    685:                
                    686: // update audio
                    687:        if (cls.signon == SIGNONS)
                    688:        {
                    689:                S_Update (r_origin, vpn, vright, vup);
                    690:                CL_DecayLights ();
                    691:        }
                    692:        else
                    693:                S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin);
                    694:        
                    695:        CDAudio_Update();
                    696: 
                    697:        if (host_speeds.value)
                    698:        {
                    699:                pass1 = (time1 - time3)*1000;
                    700:                time3 = Sys_FloatTime ();
                    701:                pass2 = (time2 - time1)*1000;
                    702:                pass3 = (time3 - time2)*1000;
                    703:                Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n",
                    704:                                        pass1+pass2+pass3, pass1, pass2, pass3);
                    705:        }
                    706:        
                    707:        host_framecount++;
                    708: }
                    709: 
                    710: void Host_Frame (float time)
                    711: {
                    712:        double  time1, time2;
                    713:        static double   timetotal;
                    714:        static int              timecount;
                    715:        int             i, c, m;
                    716: 
                    717:        if (!serverprofile.value)
                    718:        {
                    719:                _Host_Frame (time);
                    720:                return;
                    721:        }
                    722:        
                    723:        time1 = Sys_FloatTime ();
                    724:        _Host_Frame (time);
                    725:        time2 = Sys_FloatTime ();       
                    726:        
                    727:        timetotal += time2 - time1;
                    728:        timecount++;
                    729:        
                    730:        if (timecount < 1000)
                    731:                return;
                    732: 
                    733:        m = timetotal*1000/timecount;
                    734:        timecount = 0;
                    735:        timetotal = 0;
                    736:        c = 0;
                    737:        for (i=0 ; i<svs.maxclients ; i++)
                    738:        {
                    739:                if (svs.clients[i].active)
                    740:                        c++;
                    741:        }
                    742: 
                    743:        Con_Printf ("serverprofile: %2i clients %2i msec\n",  c,  m);
                    744: }
                    745: 
                    746: //============================================================================
                    747: 
                    748: 
                    749: extern int vcrFile;
                    750: #define        VCR_SIGNATURE   0x56435231
                    751: // "VCR1"
                    752: 
                    753: void Host_InitVCR (quakeparms_t *parms)
                    754: {
                    755:        int             i, len, n;
                    756:        char    *p;
                    757:        
                    758:        if (COM_CheckParm("-playback"))
                    759:        {
                    760:                if (com_argc != 2)
                    761:                        Sys_Error("No other parameters allowed with -playback\n");
                    762: 
                    763:                Sys_FileOpenRead("quake.vcr", &vcrFile);
                    764:                if (vcrFile == -1)
                    765:                        Sys_Error("playback file not found\n");
                    766: 
                    767:                Sys_FileRead (vcrFile, &i, sizeof(int));
                    768:                if (i != VCR_SIGNATURE)
                    769:                        Sys_Error("Invalid signature in vcr file\n");
                    770: 
                    771:                Sys_FileRead (vcrFile, &com_argc, sizeof(int));
                    772:                com_argv = malloc(com_argc * sizeof(char *));
                    773:                com_argv[0] = parms->argv[0];
                    774:                for (i = 0; i < com_argc; i++)
                    775:                {
                    776:                        Sys_FileRead (vcrFile, &len, sizeof(int));
                    777:                        p = malloc(len);
                    778:                        Sys_FileRead (vcrFile, p, len);
                    779:                        com_argv[i+1] = p;
                    780:                }
                    781:                com_argc++; /* add one for arg[0] */
                    782:                parms->argc = com_argc;
                    783:                parms->argv = com_argv;
                    784:        }
                    785: 
                    786:        if ( (n = COM_CheckParm("-record")) != 0)
                    787:        {
                    788:                vcrFile = Sys_FileOpenWrite("quake.vcr");
                    789: 
                    790:                i = VCR_SIGNATURE;
                    791:                Sys_FileWrite(vcrFile, &i, sizeof(int));
                    792:                i = com_argc - 1;
                    793:                Sys_FileWrite(vcrFile, &i, sizeof(int));
                    794:                for (i = 1; i < com_argc; i++)
                    795:                {
                    796:                        if (i == n)
                    797:                        {
                    798:                                len = 10;
                    799:                                Sys_FileWrite(vcrFile, &len, sizeof(int));
                    800:                                Sys_FileWrite(vcrFile, "-playback", len);
                    801:                                continue;
                    802:                        }
                    803:                        len = Q_strlen(com_argv[i]) + 1;
                    804:                        Sys_FileWrite(vcrFile, &len, sizeof(int));
                    805:                        Sys_FileWrite(vcrFile, com_argv[i], len);
                    806:                }
                    807:        }
                    808:        
                    809: }
                    810: 
                    811: /*
                    812: ====================
                    813: Host_Init
                    814: ====================
                    815: */
                    816: void Host_Init (quakeparms_t *parms)
                    817: {
                    818: 
1.1.1.3 ! root      819:        if (standard_quake)
        !           820:                minimum_memory = MINIMUM_MEMORY;
        !           821:        else
        !           822:                minimum_memory = MINIMUM_MEMORY_LEVELPAK;
        !           823: 
1.1       root      824:        if (COM_CheckParm ("-minmemory"))
1.1.1.3 ! root      825:                parms->memsize = minimum_memory;
1.1       root      826: 
                    827:        host_parms = *parms;
                    828: 
1.1.1.3 ! root      829:        if (parms->memsize < minimum_memory)
        !           830:                Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000);
1.1       root      831: 
                    832:        com_argc = parms->argc;
                    833:        com_argv = parms->argv;
                    834: 
                    835:        Memory_Init (parms->membase, parms->memsize);
                    836:        Cbuf_Init ();
                    837:        Cmd_Init ();    
                    838:        V_Init ();
1.1.1.3 ! root      839:        Chase_Init ();
1.1       root      840:        Host_InitVCR (parms);
                    841:        COM_Init (parms->basedir);
                    842:        Host_InitLocal ();
                    843:        W_LoadWadFile ("gfx.wad");
                    844:        Key_Init ();
                    845:        Con_Init ();    
                    846:        M_Init ();      
                    847:        PR_Init ();
                    848:        Mod_Init ();
                    849:        NET_Init ();
1.1.1.2   root      850:        SV_Init ();
1.1.1.3 ! root      851: 
1.1       root      852:        Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
                    853:        Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0));
                    854:        
                    855:        R_InitTextures ();              // needed even for dedicated servers
                    856:  
                    857:        if (cls.state != ca_dedicated)
                    858:        {
                    859:                host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp");
                    860:                if (!host_basepal)
                    861:                        Sys_Error ("Couldn't load gfx/palette.lmp");
                    862:                host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp");
                    863:                if (!host_colormap)
                    864:                        Sys_Error ("Couldn't load gfx/colormap.lmp");
1.1.1.3 ! root      865: 
1.1       root      866:                VID_Init (host_basepal);
1.1.1.3 ! root      867: 
1.1       root      868:                Draw_Init ();
                    869:                SCR_Init ();
                    870:                R_Init ();
1.1.1.3 ! root      871: #ifndef        _WIN32
        !           872:        // on Win32, sound initialization has to come before video initialization, so we
        !           873:        // can put up a popup if the sound hardware is in use
        !           874:                S_Init ();
        !           875: #else
        !           876: 
        !           877: #ifdef GLQUAKE
        !           878:        // FIXME: doesn't use the new one-window approach yet
        !           879:                S_Init ();
        !           880: #endif
        !           881: 
        !           882: #endif // _WIN32
1.1       root      883:                CDAudio_Init ();
                    884:                Sbar_Init ();
                    885:                CL_Init ();
                    886:                IN_Init ();
                    887:        }
                    888: 
                    889:        Cbuf_InsertText ("exec quake.rc\n");
                    890: 
                    891:        Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
                    892:        host_hunklevel = Hunk_LowMark ();
                    893: 
                    894:        host_initialized = true;
                    895:        
                    896:        Sys_Printf ("========Quake Initialized=========\n");    
                    897: }
                    898: 
                    899: 
                    900: /*
                    901: ===============
                    902: Host_Shutdown
                    903: 
                    904: FIXME: this is a callback from Sys_Quit and Sys_Error.  It would be better
                    905: to run quit through here before the final handoff to the sys code.
                    906: ===============
                    907: */
                    908: void Host_Shutdown(void)
                    909: {
                    910:        static qboolean isdown = false;
                    911:        
                    912:        if (isdown)
                    913:        {
                    914:                printf ("recursive shutdown\n");
                    915:                return;
                    916:        }
                    917:        isdown = true;
                    918: 
1.1.1.3 ! root      919: // keep Con_Printf from trying to update the screen
        !           920:        scr_disabled_for_loading = true;
        !           921: 
1.1       root      922:        Host_WriteConfiguration (); 
1.1.1.3 ! root      923: 
1.1       root      924:        CDAudio_Shutdown ();
                    925:        NET_Shutdown ();
                    926:        S_Shutdown();
                    927:        IN_Shutdown ();
1.1.1.3 ! root      928: 
        !           929:        if (cls.state != ca_dedicated)
        !           930:        {
1.1       root      931:                VID_Shutdown();
1.1.1.3 ! root      932:        }
1.1       root      933: }
                    934: 

unix.superglobalmegacorp.com

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