Annotation of quake1/cl_demo.c, revision 1.1

1.1     ! root        1: 
        !             2: #include "quakedef.h"
        !             3: 
        !             4: void CL_FinishTimeDemo (void);
        !             5: 
        !             6: /*
        !             7: ==============================================================================
        !             8: 
        !             9: DEMO CODE
        !            10: 
        !            11: When a demo is playing back, all NET_SendMessages are skipped, and
        !            12: NET_GetMessages are read from the demo file.
        !            13: 
        !            14: Whenever cl.time gets past the last received message, another message is
        !            15: read from the demo file.
        !            16: ==============================================================================
        !            17: */
        !            18: 
        !            19: /*
        !            20: ==============
        !            21: CL_StopPlayback
        !            22: 
        !            23: Called when a demo file runs out, or the user starts a game
        !            24: ==============
        !            25: */
        !            26: void CL_StopPlayback (void)
        !            27: {
        !            28:        if (!cls.demoplayback)
        !            29:                return;
        !            30: 
        !            31:        fclose (cls.demofile);
        !            32:        cls.demoplayback = false;
        !            33:        cls.demofile = NULL;
        !            34:        cls.state = ca_disconnected;
        !            35: 
        !            36:        if (cls.timedemo)
        !            37:                CL_FinishTimeDemo ();
        !            38: }
        !            39: 
        !            40: /*
        !            41: ====================
        !            42: CL_WriteDemoMessage
        !            43: 
        !            44: Dumps the current net message, prefixed by the length and view angles
        !            45: ====================
        !            46: */
        !            47: void CL_WriteDemoMessage (void)
        !            48: {
        !            49:        int             len;
        !            50:        int             i;
        !            51:        float   f;
        !            52: 
        !            53:        len = LittleLong (net_message.cursize);
        !            54:        fwrite (&len, 4, 1, cls.demofile);
        !            55:        for (i=0 ; i<3 ; i++)
        !            56:        {
        !            57:                f = LittleFloat (cl.viewangles[i]);
        !            58:                fwrite (&f, 4, 1, cls.demofile);
        !            59:        }
        !            60:        fwrite (net_message.data, net_message.cursize, 1, cls.demofile);
        !            61:        fflush (cls.demofile);
        !            62: }
        !            63: 
        !            64: /*
        !            65: ====================
        !            66: CL_GetMessage
        !            67: 
        !            68: Handles recording and playback of demos, on top of NET_ code
        !            69: ====================
        !            70: */
        !            71: int CL_GetMessage (void)
        !            72: {
        !            73:        int             r, i;
        !            74:        float   f;
        !            75:        
        !            76:        if      (cls.demoplayback)
        !            77:        {
        !            78: 
        !            79:        // decide if it is time to grab the next message                
        !            80:                if (cls.signon == SIGNONS)      // allways grab until fully connected
        !            81:                {
        !            82:                        if (cls.timedemo)
        !            83:                        {
        !            84:                                if (host_framecount == cls.td_lastframe)
        !            85:                                        return 0;               // allready read this frame's message
        !            86:                                cls.td_lastframe = host_framecount;
        !            87:                        // if this is the second frame, grab the real td_starttime
        !            88:                        // so the bogus time on the first frame doesn't count
        !            89:                                if (host_framecount == cls.td_startframe + 1)
        !            90:                                        cls.td_starttime = realtime;
        !            91:                        }
        !            92:                        else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0])
        !            93:                                return 0;               // don't need another message yet
        !            94:                }
        !            95:                
        !            96:        // get the next message
        !            97:                fread (&net_message.cursize, 4, 1, cls.demofile);
        !            98:                VectorCopy (cl.mviewangles[0], cl.mviewangles[1]);
        !            99:                for (i=0 ; i<3 ; i++)
        !           100:                {
        !           101:                        r = fread (&f, 4, 1, cls.demofile);
        !           102:                        cl.mviewangles[0][i] = LittleFloat (f);
        !           103:                }
        !           104:                
        !           105:                net_message.cursize = LittleLong (net_message.cursize);
        !           106:                if (net_message.cursize > MAX_MSGLEN)
        !           107:                        Sys_Error ("Demo message > MAX_MSGLEN");
        !           108:                r = fread (net_message.data, net_message.cursize, 1, cls.demofile);
        !           109:                if (r != 1)
        !           110:                {
        !           111:                        CL_StopPlayback ();
        !           112:                        return 0;
        !           113:                }
        !           114:        
        !           115:                return 1;
        !           116:        }
        !           117: 
        !           118:        while (1)
        !           119:        {
        !           120:                r = NET_GetMessage (cls.netcon);
        !           121:                
        !           122:                if (r != 1 && r != 2)
        !           123:                        return r;
        !           124:        
        !           125:        // discard nop keepalive message
        !           126:                if (net_message.cursize == 1 && net_message.data[0] == svc_nop)
        !           127:                        Con_Printf ("<-- server to client keepalive\n");
        !           128:                else
        !           129:                        break;
        !           130:        }
        !           131: 
        !           132:        if (cls.demorecording)
        !           133:                CL_WriteDemoMessage ();
        !           134:        
        !           135:        return r;
        !           136: }
        !           137: 
        !           138: 
        !           139: /*
        !           140: ====================
        !           141: CL_Stop_f
        !           142: 
        !           143: stop recording a demo
        !           144: ====================
        !           145: */
        !           146: void CL_Stop_f (void)
        !           147: {
        !           148:        if (cmd_source != src_command)
        !           149:                return;
        !           150: 
        !           151:        if (!cls.demorecording)
        !           152:        {
        !           153:                Con_Printf ("Not recording a demo.\n");
        !           154:                return;
        !           155:        }
        !           156: 
        !           157: // write a disconnect message to the demo file
        !           158:        SZ_Clear (&net_message);
        !           159:        MSG_WriteByte (&net_message, svc_disconnect);
        !           160:        CL_WriteDemoMessage ();
        !           161: 
        !           162: // finish up
        !           163:        fclose (cls.demofile);
        !           164:        cls.demofile = NULL;
        !           165:        cls.demorecording = false;
        !           166:        Con_Printf ("Completed demo\n");
        !           167: }
        !           168: 
        !           169: /*
        !           170: ====================
        !           171: CL_Record_f
        !           172: 
        !           173: record <demoname> <map> [cd track]
        !           174: ====================
        !           175: */
        !           176: void CL_Record_f (void)
        !           177: {
        !           178:        int             c;
        !           179:        char    name[MAX_OSPATH];
        !           180:        int             track;
        !           181: 
        !           182:        if (cmd_source != src_command)
        !           183:                return;
        !           184: 
        !           185:        c = Cmd_Argc();
        !           186:        if (c != 3 && c != 4)
        !           187:        {
        !           188:                Con_Printf ("record <demoname> <map> [cd track]\n");
        !           189:                return;
        !           190:        }
        !           191: 
        !           192:        if (strstr(Cmd_Argv(1), ".."))
        !           193:        {
        !           194:                Con_Printf ("Relative pathnames are not allowed.\n");
        !           195:                return;
        !           196:        }
        !           197: 
        !           198: // write the forced cd track number, or -1
        !           199:        if (c == 4)
        !           200:        {
        !           201:                track = atoi(Cmd_Argv(3));
        !           202:                Con_Printf ("Forcing CD track to %i\n", cls.forcetrack);
        !           203:        }
        !           204:        else
        !           205:                track = -1;     
        !           206: 
        !           207:        sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
        !           208:        
        !           209: //
        !           210: // start the map up
        !           211: //
        !           212:        Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command);
        !           213:        
        !           214: //
        !           215: // open the demo file
        !           216: //
        !           217:        COM_DefaultExtension (name, ".dem");
        !           218: 
        !           219:        Con_Printf ("recording to %s.\n", name);
        !           220:        cls.demofile = fopen (name, "wb");
        !           221:        if (!cls.demofile)
        !           222:        {
        !           223:                Con_Printf ("ERROR: couldn't open.\n");
        !           224:                return;
        !           225:        }
        !           226: 
        !           227:        cls.forcetrack = track;
        !           228:        fprintf (cls.demofile, "%i\n", cls.forcetrack);
        !           229:        
        !           230:        cls.demorecording = true;
        !           231: }
        !           232: 
        !           233: 
        !           234: /*
        !           235: ====================
        !           236: CL_PlayDemo_f
        !           237: 
        !           238: play [demoname]
        !           239: ====================
        !           240: */
        !           241: void CL_PlayDemo_f (void)
        !           242: {
        !           243:        char    name[256];
        !           244: 
        !           245:        if (cmd_source != src_command)
        !           246:                return;
        !           247: 
        !           248:        if (Cmd_Argc() != 2)
        !           249:        {
        !           250:                Con_Printf ("play <demoname> : plays a demo\n");
        !           251:                return;
        !           252:        }
        !           253: 
        !           254: //
        !           255: // disconnect from server
        !           256: //
        !           257:        CL_Disconnect ();
        !           258:        
        !           259: //
        !           260: // open the demo file
        !           261: //
        !           262:        strcpy (name, Cmd_Argv(1));
        !           263:        COM_DefaultExtension (name, ".dem");
        !           264: 
        !           265:        Con_Printf ("Playing demo from %s.\n", name);
        !           266:        COM_FOpenFile (name, &cls.demofile);
        !           267:        if (!cls.demofile)
        !           268:        {
        !           269:                Con_Printf ("ERROR: couldn't open.\n");
        !           270:                cls.demonum = -1;               // stop demo loop
        !           271:                return;
        !           272:        }
        !           273: 
        !           274:        cls.demoplayback = true;
        !           275:        cls.state = ca_connected;
        !           276:        fscanf (cls.demofile, "%i\n", &cls.forcetrack);
        !           277: }
        !           278: 
        !           279: /*
        !           280: ====================
        !           281: CL_FinishTimeDemo
        !           282: 
        !           283: ====================
        !           284: */
        !           285: void CL_FinishTimeDemo (void)
        !           286: {
        !           287:        int             frames;
        !           288:        float   time;
        !           289:        
        !           290:        cls.timedemo = false;
        !           291:        
        !           292: // the first frame didn't count
        !           293:        frames = (host_framecount - cls.td_startframe) - 1;
        !           294:        time = realtime - cls.td_starttime;
        !           295:        if (!time)
        !           296:                time = 1;
        !           297:        Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time);
        !           298: }
        !           299: 
        !           300: /*
        !           301: ====================
        !           302: CL_TimeDemo_f
        !           303: 
        !           304: timedemo [demoname]
        !           305: ====================
        !           306: */
        !           307: void CL_TimeDemo_f (void)
        !           308: {
        !           309:        if (cmd_source != src_command)
        !           310:                return;
        !           311: 
        !           312:        if (Cmd_Argc() != 2)
        !           313:        {
        !           314:                Con_Printf ("timedemo <demoname> : gets demo speeds\n");
        !           315:                return;
        !           316:        }
        !           317: 
        !           318:        CL_PlayDemo_f ();
        !           319:        
        !           320: // cls.td_starttime will be grabbed at the second frame of the demo, so
        !           321: // all the loading time doesn't get counted
        !           322:        
        !           323:        cls.timedemo = true;
        !           324:        cls.td_startframe = host_framecount;
        !           325:        cls.td_lastframe = -1;          // get a new message this frame
        !           326: }
        !           327: 

unix.superglobalmegacorp.com

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