view 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 source

/* $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