Annotation of quake1/cl_demo.c, revision 1.1.1.3

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);
1.1.1.3 ! root       32:        cls.demoplayback = false;
1.1       root       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:        // decide if it is time to grab the next message                
                     79:                if (cls.signon == SIGNONS)      // allways grab until fully connected
                     80:                {
                     81:                        if (cls.timedemo)
                     82:                        {
                     83:                                if (host_framecount == cls.td_lastframe)
                     84:                                        return 0;               // allready read this frame's message
                     85:                                cls.td_lastframe = host_framecount;
                     86:                        // if this is the second frame, grab the real td_starttime
                     87:                        // so the bogus time on the first frame doesn't count
                     88:                                if (host_framecount == cls.td_startframe + 1)
                     89:                                        cls.td_starttime = realtime;
                     90:                        }
                     91:                        else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0])
1.1.1.3 ! root       92:                        {
        !            93:                                        return 0;               // don't need another message yet
        !            94:                        }
1.1       root       95:                }
                     96:                
                     97:        // get the next message
                     98:                fread (&net_message.cursize, 4, 1, cls.demofile);
                     99:                VectorCopy (cl.mviewangles[0], cl.mviewangles[1]);
                    100:                for (i=0 ; i<3 ; i++)
                    101:                {
                    102:                        r = fread (&f, 4, 1, cls.demofile);
                    103:                        cl.mviewangles[0][i] = LittleFloat (f);
                    104:                }
                    105:                
                    106:                net_message.cursize = LittleLong (net_message.cursize);
                    107:                if (net_message.cursize > MAX_MSGLEN)
                    108:                        Sys_Error ("Demo message > MAX_MSGLEN");
                    109:                r = fread (net_message.data, net_message.cursize, 1, cls.demofile);
                    110:                if (r != 1)
                    111:                {
                    112:                        CL_StopPlayback ();
                    113:                        return 0;
                    114:                }
                    115:        
                    116:                return 1;
                    117:        }
                    118: 
                    119:        while (1)
                    120:        {
                    121:                r = NET_GetMessage (cls.netcon);
                    122:                
                    123:                if (r != 1 && r != 2)
                    124:                        return r;
                    125:        
                    126:        // discard nop keepalive message
                    127:                if (net_message.cursize == 1 && net_message.data[0] == svc_nop)
                    128:                        Con_Printf ("<-- server to client keepalive\n");
                    129:                else
                    130:                        break;
                    131:        }
                    132: 
                    133:        if (cls.demorecording)
                    134:                CL_WriteDemoMessage ();
                    135:        
                    136:        return r;
                    137: }
                    138: 
                    139: 
                    140: /*
                    141: ====================
                    142: CL_Stop_f
                    143: 
                    144: stop recording a demo
                    145: ====================
                    146: */
                    147: void CL_Stop_f (void)
                    148: {
                    149:        if (cmd_source != src_command)
                    150:                return;
                    151: 
                    152:        if (!cls.demorecording)
                    153:        {
                    154:                Con_Printf ("Not recording a demo.\n");
                    155:                return;
                    156:        }
                    157: 
                    158: // write a disconnect message to the demo file
                    159:        SZ_Clear (&net_message);
                    160:        MSG_WriteByte (&net_message, svc_disconnect);
                    161:        CL_WriteDemoMessage ();
                    162: 
                    163: // finish up
                    164:        fclose (cls.demofile);
                    165:        cls.demofile = NULL;
                    166:        cls.demorecording = false;
                    167:        Con_Printf ("Completed demo\n");
                    168: }
                    169: 
                    170: /*
                    171: ====================
                    172: CL_Record_f
                    173: 
                    174: record <demoname> <map> [cd track]
                    175: ====================
                    176: */
                    177: void CL_Record_f (void)
                    178: {
                    179:        int             c;
                    180:        char    name[MAX_OSPATH];
                    181:        int             track;
                    182: 
                    183:        if (cmd_source != src_command)
                    184:                return;
                    185: 
                    186:        c = Cmd_Argc();
1.1.1.3 ! root      187:        if (c != 2 && c != 3 && c != 4)
        !           188:        {
        !           189:                Con_Printf ("record <demoname> [<map> [cd track]]\n");
        !           190:                return;
        !           191:        }
        !           192: 
        !           193:        if (strstr(Cmd_Argv(1), ".."))
1.1       root      194:        {
1.1.1.3 ! root      195:                Con_Printf ("Relative pathnames are not allowed.\n");
        !           196:                return;
        !           197:        }
        !           198: 
        !           199:        if (c == 2 && cls.state == ca_connected)
        !           200:        {
        !           201:                Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n");
1.1       root      202:                return;
                    203:        }
                    204: 
                    205: // write the forced cd track number, or -1
                    206:        if (c == 4)
                    207:        {
                    208:                track = atoi(Cmd_Argv(3));
                    209:                Con_Printf ("Forcing CD track to %i\n", cls.forcetrack);
                    210:        }
                    211:        else
                    212:                track = -1;     
                    213: 
                    214:        sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
                    215:        
                    216: //
                    217: // start the map up
                    218: //
1.1.1.3 ! root      219:        if (c > 2)
        !           220:                Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command);
1.1       root      221:        
                    222: //
                    223: // open the demo file
                    224: //
                    225:        COM_DefaultExtension (name, ".dem");
                    226: 
                    227:        Con_Printf ("recording to %s.\n", name);
                    228:        cls.demofile = fopen (name, "wb");
                    229:        if (!cls.demofile)
                    230:        {
                    231:                Con_Printf ("ERROR: couldn't open.\n");
                    232:                return;
                    233:        }
                    234: 
                    235:        cls.forcetrack = track;
                    236:        fprintf (cls.demofile, "%i\n", cls.forcetrack);
                    237:        
                    238:        cls.demorecording = true;
                    239: }
                    240: 
                    241: 
                    242: /*
                    243: ====================
                    244: CL_PlayDemo_f
                    245: 
                    246: play [demoname]
                    247: ====================
                    248: */
                    249: void CL_PlayDemo_f (void)
                    250: {
                    251:        char    name[256];
                    252: 
                    253:        if (cmd_source != src_command)
                    254:                return;
                    255: 
                    256:        if (Cmd_Argc() != 2)
                    257:        {
                    258:                Con_Printf ("play <demoname> : plays a demo\n");
                    259:                return;
                    260:        }
                    261: 
                    262: //
                    263: // disconnect from server
                    264: //
                    265:        CL_Disconnect ();
                    266:        
                    267: //
                    268: // open the demo file
                    269: //
                    270:        strcpy (name, Cmd_Argv(1));
                    271:        COM_DefaultExtension (name, ".dem");
                    272: 
                    273:        Con_Printf ("Playing demo from %s.\n", name);
                    274:        COM_FOpenFile (name, &cls.demofile);
                    275:        if (!cls.demofile)
                    276:        {
                    277:                Con_Printf ("ERROR: couldn't open.\n");
                    278:                cls.demonum = -1;               // stop demo loop
                    279:                return;
                    280:        }
                    281: 
                    282:        cls.demoplayback = true;
                    283:        cls.state = ca_connected;
                    284:        fscanf (cls.demofile, "%i\n", &cls.forcetrack);
                    285: }
                    286: 
                    287: /*
                    288: ====================
                    289: CL_FinishTimeDemo
                    290: 
                    291: ====================
                    292: */
                    293: void CL_FinishTimeDemo (void)
                    294: {
                    295:        int             frames;
                    296:        float   time;
                    297:        
                    298:        cls.timedemo = false;
                    299:        
                    300: // the first frame didn't count
                    301:        frames = (host_framecount - cls.td_startframe) - 1;
                    302:        time = realtime - cls.td_starttime;
                    303:        if (!time)
                    304:                time = 1;
                    305:        Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time);
                    306: }
                    307: 
                    308: /*
                    309: ====================
                    310: CL_TimeDemo_f
                    311: 
                    312: timedemo [demoname]
                    313: ====================
                    314: */
                    315: void CL_TimeDemo_f (void)
                    316: {
                    317:        if (cmd_source != src_command)
                    318:                return;
                    319: 
                    320:        if (Cmd_Argc() != 2)
                    321:        {
                    322:                Con_Printf ("timedemo <demoname> : gets demo speeds\n");
                    323:                return;
                    324:        }
                    325: 
                    326:        CL_PlayDemo_f ();
                    327:        
                    328: // cls.td_starttime will be grabbed at the second frame of the demo, so
                    329: // all the loading time doesn't get counted
                    330:        
                    331:        cls.timedemo = true;
                    332:        cls.td_startframe = host_framecount;
                    333:        cls.td_lastframe = -1;          // get a new message this frame
                    334: }
                    335: 

unix.superglobalmegacorp.com

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