diff recorder.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/recorder.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,347 @@
+/* $Id: recorder.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+#ifdef RECORDER
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <fcntl.h>
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "packets.h"
+
+int     record_total;
+int     lastTeamReq = -1;
+int     recfp = -1, playfp = -1;
+
+void pb_skip P((int frames));
+
+void
+startRecorder()
+{
+    if (recordGame = booleanDefault("recordGame", recordGame)) {
+	recordFile = stringDefault("recordFile", "/tmp/netrek.record");
+	recordFile = expandFilename(recordFile);
+	maxRecord = intDefault("maxRecord", maxRecord);
+	recfp = open(recordFile, O_WRONLY | O_TRUNC | O_APPEND | O_CREAT, S_IRWXU);
+	if (recfp >= 0)
+	    printf("Game being recorded to %s.  Max size is %d\n", recordFile, maxRecord);
+	else {
+	    perror("startRecorder");
+	    printf("Can't open file %s for recording\n", recordFile);
+	    recordGame = 0;
+	}
+    }
+}
+
+void
+stopRecorder()
+{
+    char    buf[80];
+
+    close(recfp);
+    recfp = -1;
+    recordGame = 0;
+    sprintf(buf, "Recording stopped, %d bytes (%d updates) written to %s\n",
+	   record_total, udcounter, (recordFile==NULL) ? "Nothing" : recordFile);
+    warning(buf);
+}
+
+void
+recordPacket(data, len)
+    char   *data;
+    int     len;
+{
+    int     res;
+
+    if (recfp >= 0 && len > 0) {
+	switch (*data) {
+	case SP_PICKOK:	/* playback needs to know what team! */
+	    data[2] = (char) lastTeamReq;
+	    break;
+	case SP_RSA_KEY:
+	case SP_MOTD:
+	case SP_MOTD_PIC:
+	case SP_NEW_MOTD:
+	    return;
+	default:
+	    break;
+	}
+	res = write(recfp, data, len);
+	record_total += res;
+	if ((maxRecord && (record_total > maxRecord)) || (res <= 0))
+	    stopRecorder();
+    }
+}
+
+void
+writeUpdateMarker()
+{
+    unsigned char update_buf[4];
+
+    update_buf[0] = REC_UPDATE;
+    /*
+       record stuff not normally sent by server.  Otherwise tractors and lock
+       markers don't work during playback
+    */
+    update_buf[1] = (unsigned char) me->p_tractor;
+    update_buf[2] = (unsigned char) ((me->p_flags & PFPLOCK) ? me->p_playerl : me->p_planet);
+    /* one more byte here, any ideas? */
+    record_total += write(recfp, update_buf, 4);
+}
+
+int
+startPlayback()
+{
+    if (playback || (playback = booleanDefault("playback", 0))) {
+	if (!playFile)
+	    playFile = stringDefault("playFile", "/tmp/netrek.record");
+	playFile = expandFilename(playFile);
+
+	playfp = open(playFile, O_RDONLY, 0);
+	if (playfp < 0) {
+	    perror("startPlayback");
+	    printf("Couldn't open playback file %s\n", playFile);
+	    exit(0);
+	}
+	printf("Replaying %s\n", playFile);
+	return 1;
+    }
+    return 0;
+}
+
+int
+readRecorded(fp, data, len)
+    int     fp, len;
+    char   *data;
+{
+    int     ret;
+
+    if (!playback || len < 0 || playfp < 0)
+	return -1;
+    if (len > 4)		/* make sure we don't skip updates */
+	len = 4;
+    ret = read(playfp, data, len);
+    if (ret <= 0)
+	EXIT(0);
+    return ret;
+}
+
+void
+pb_dokey(event)
+W_Event *event;
+{
+    switch (event->key&0xff) {
+    case 'p':
+    case 'P':
+	paused = !paused;
+	pb_scan=0;
+	if (paused)
+	    pb_advance = 0;
+	break;
+    case 'r':
+    case 'R':
+	pb_advance = PB_REDALERT;
+	paused = 0;
+	break;
+    case 'y':
+    case 'Y':
+	pb_advance = PB_YELLOWALERT;
+	paused = 0;
+	break;
+    case 'd':
+    case 'D':
+	pb_advance = PB_DEATH;
+	paused = 0;
+	break;
+    case ' ':
+	if(paused) {
+	    if(pb_scan)
+		pb_skip(pb_advance);
+	    else {
+		pb_advance=1;
+		paused=0;
+	    }
+	} else {
+	    paused = 1;
+	    pb_advance=0;
+	}
+	break;
+    case 'f':
+    case 'F': /* fast forward */
+	pb_scan=!pb_scan;
+	if(pb_scan) {
+	    pb_advance=10;
+	    pb_slow=0;
+	    paused=0;
+	    warning("1-9: set speed. P-Pause, F-Fast Fwd off");
+	} else {
+	    pb_advance=0;
+	    pb_slow=0;
+	    paused=0;
+	    warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
+	}
+	break;
+    case 's': /* Slow mode */
+    case 'S':
+	if(pb_scan || paused || !pb_slow)
+	    pb_slow=1;
+	else
+	    pb_slow=0;
+	pb_scan=0;
+	paused=0;
+	pb_advance=0;
+	break;
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	if(!pb_scan)
+	    pb_advance += (event->key - '0') * 10;
+	else
+	    pb_advance = (event->key - '0') * 10;
+	paused = 0;
+	break;
+    case 'q':
+    case 'Q':
+	exit(0);
+    default:
+	warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
+    }
+}
+
+void
+pb_skip(frames)
+     int frames;
+{
+    while(frames) {
+	pb_update=0;
+	readFromServer();
+	frames-=pb_update;
+	udcounter+=pb_update;
+    }
+}
+
+void
+pb_framectr(xloc, yloc)
+     int xloc, yloc;
+{
+    char buf[20];
+
+    if(paused) 
+	strcpy(buf,"PAU");
+    else if(pb_scan)
+	strcpy(buf,"FFW");
+    else if(pb_advance) {
+	switch(pb_advance) {
+	case PB_REDALERT:
+	    strcpy(buf,"RED");
+	    break;
+	case PB_YELLOWALERT:
+	    strcpy(buf,"YLW");
+	    break;
+	case PB_DEATH:
+	    strcpy(buf,"DTH");
+	    break;
+	default:
+	    buf[0]='+';
+	    buf[1]=(pb_advance / 10) + '0';
+	    buf[2]=(pb_advance % 10) + '0';
+	    break;
+	}
+    } else if(pb_slow)
+	strcpy(buf,"SLW");
+    else
+	strcpy(buf,"NRM");
+
+    sprintf((buf+3),":%8d",udcounter);
+
+    W_WriteText(tstatw, xloc, yloc, textColor, buf, 12, W_RegularFont);
+}
+
+void
+pb_input()
+{
+    W_Event data;
+    fd_set  readfds;
+    int     wsock = W_Socket();
+
+    struct timeval timeout;
+
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 200000;
+
+    intrupt(); /* draws the first frame */
+
+    while (me->p_status == PALIVE ||
+	   me->p_status == PEXPLODE ||
+	   me->p_status == PDEAD ||
+	   me->p_status == POBSERVE) {
+
+	if (keepInfo > 0) {
+	    if (infowin_up >= 0 &&
+		--infowin_up == -1 &&
+		infomapped) {
+		destroyInfo();
+		infowin_up = -2;
+	    }
+	}
+	exitInputLoop = 0;
+	while (W_EventsPending() && !exitInputLoop) {
+	    fastQuit = 0;	/* any event cancel fastquit */
+	    W_NextEvent(&data);
+	    dispatch_W_event(&data);
+	}
+	if (!paradise)  /* stars are ok, it's just a recording.
+			   zoom doesn't make sense. */
+	    blk_zoom = 0;
+
+#ifndef AMIGA
+	FD_ZERO(&readfds);
+	FD_SET(wsock, &readfds);
+	if (paused) {
+	    select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
+	    continue;
+	} else if(pb_slow && !pb_scan)
+	    select(32, &readfds, (fd_set *) 0, (fd_set *) 0,&timeout);
+
+	/* otherwise, in full blast mode, don't wait on anything. */
+
+#else				/* AMIGA */
+	if (paused) {
+	    sigsPending = Wait(wsock | SIGBREAKF_CTRL_C);
+	    continue;
+	} else if(pb_slow && !pb_scan) {
+	    StartTimer(0,200000);
+	    while(1) {
+		sigsPending = Wait(wsock | portmask | SIGBREAKF_CTRL_C);
+		if((sigsPending & (wsock | SIGBREAKF_CTRL_C)) ||
+		   CheckIO(&(ior->tr_node)))
+		    break;
+	    }
+		
+	    StopTimer();
+	}
+		
+	if (sigsPending & SIGBREAKF_CTRL_C) {
+	    printf("User break, Ctrl-C, exiting!\n");
+	    exit(0);
+	}
+#endif				/* AMIGA */
+	/* at this point, we're sure it's time for at least one frame. */
+	intrupt();
+    }
+}
+
+#endif