Annotation of quake1/host.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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