Annotation of quake1/cl_demo.c, revision 1.1.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.