Annotation of quake1/host.c, revision 1.1

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 ();
        !           769:        Host_InitVCR (parms);
        !           770:        COM_Init (parms->basedir);
        !           771:        Host_InitLocal ();
        !           772:        W_LoadWadFile ("gfx.wad");
        !           773:        Key_Init ();
        !           774:        Con_Init ();    
        !           775:        M_Init ();      
        !           776:        PR_Init ();
        !           777:        Mod_Init ();
        !           778:        NET_Init ();
        !           779:        SV_Init ();
        !           780: 
        !           781:        Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
        !           782:        Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0));
        !           783:        
        !           784:        R_InitTextures ();              // needed even for dedicated servers
        !           785:  
        !           786:        if (cls.state != ca_dedicated)
        !           787:        {
        !           788:                host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp");
        !           789:                if (!host_basepal)
        !           790:                        Sys_Error ("Couldn't load gfx/palette.lmp");
        !           791:                host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp");
        !           792:                if (!host_colormap)
        !           793:                        Sys_Error ("Couldn't load gfx/colormap.lmp");
        !           794: 
        !           795:                VID_Init (host_basepal);
        !           796: 
        !           797:                Draw_Init ();
        !           798:                SCR_Init ();
        !           799:                R_Init ();
        !           800:                S_Init ();              
        !           801:                CDAudio_Init ();
        !           802:                Sbar_Init ();
        !           803:                CL_Init ();
        !           804:                IN_Init ();
        !           805:        }
        !           806: 
        !           807:        Cbuf_InsertText ("exec quake.rc\n");
        !           808: 
        !           809:        Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
        !           810:        host_hunklevel = Hunk_LowMark ();
        !           811: 
        !           812:        host_initialized = true;
        !           813:        
        !           814:        Sys_Printf ("========Quake Initialized=========\n");    
        !           815: }
        !           816: 
        !           817: 
        !           818: /*
        !           819: ===============
        !           820: Host_Shutdown
        !           821: 
        !           822: FIXME: this is a callback from Sys_Quit and Sys_Error.  It would be better
        !           823: to run quit through here before the final handoff to the sys code.
        !           824: ===============
        !           825: */
        !           826: void Host_Shutdown(void)
        !           827: {
        !           828:        static qboolean isdown = false;
        !           829:        
        !           830:        if (isdown)
        !           831:        {
        !           832:                printf ("recursive shutdown\n");
        !           833:                return;
        !           834:        }
        !           835:        isdown = true;
        !           836: 
        !           837:        Host_WriteConfiguration (); 
        !           838:                
        !           839:        CDAudio_Shutdown ();
        !           840:        NET_Shutdown ();
        !           841:        S_Shutdown();
        !           842:        IN_Shutdown ();
        !           843:        if (host_basepal)
        !           844:                VID_Shutdown();
        !           845: }
        !           846: 

unix.superglobalmegacorp.com

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