comparison recorder.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
comparison
equal deleted inserted replaced
2:fba0b6e6cdc7 3:5a977ccbc7a9
1 /* $Id: recorder.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
2
3 #ifdef RECORDER
4
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/file.h>
8 #include <sys/stat.h>
9 #include <sys/select.h>
10 #include <fcntl.h>
11
12 #include "Wlib.h"
13 #include "defs.h"
14 #include "struct.h"
15 #include "data.h"
16 #include "proto.h"
17 #include "packets.h"
18
19 int record_total;
20 int lastTeamReq = -1;
21 int recfp = -1, playfp = -1;
22
23 void pb_skip P((int frames));
24
25 void
26 startRecorder()
27 {
28 if (recordGame = booleanDefault("recordGame", recordGame)) {
29 recordFile = stringDefault("recordFile", "/tmp/netrek.record");
30 recordFile = expandFilename(recordFile);
31 maxRecord = intDefault("maxRecord", maxRecord);
32 recfp = open(recordFile, O_WRONLY | O_TRUNC | O_APPEND | O_CREAT, S_IRWXU);
33 if (recfp >= 0)
34 printf("Game being recorded to %s. Max size is %d\n", recordFile, maxRecord);
35 else {
36 perror("startRecorder");
37 printf("Can't open file %s for recording\n", recordFile);
38 recordGame = 0;
39 }
40 }
41 }
42
43 void
44 stopRecorder()
45 {
46 char buf[80];
47
48 close(recfp);
49 recfp = -1;
50 recordGame = 0;
51 sprintf(buf, "Recording stopped, %d bytes (%d updates) written to %s\n",
52 record_total, udcounter, (recordFile==NULL) ? "Nothing" : recordFile);
53 warning(buf);
54 }
55
56 void
57 recordPacket(data, len)
58 char *data;
59 int len;
60 {
61 int res;
62
63 if (recfp >= 0 && len > 0) {
64 switch (*data) {
65 case SP_PICKOK: /* playback needs to know what team! */
66 data[2] = (char) lastTeamReq;
67 break;
68 case SP_RSA_KEY:
69 case SP_MOTD:
70 case SP_MOTD_PIC:
71 case SP_NEW_MOTD:
72 return;
73 default:
74 break;
75 }
76 res = write(recfp, data, len);
77 record_total += res;
78 if ((maxRecord && (record_total > maxRecord)) || (res <= 0))
79 stopRecorder();
80 }
81 }
82
83 void
84 writeUpdateMarker()
85 {
86 unsigned char update_buf[4];
87
88 update_buf[0] = REC_UPDATE;
89 /*
90 record stuff not normally sent by server. Otherwise tractors and lock
91 markers don't work during playback
92 */
93 update_buf[1] = (unsigned char) me->p_tractor;
94 update_buf[2] = (unsigned char) ((me->p_flags & PFPLOCK) ? me->p_playerl : me->p_planet);
95 /* one more byte here, any ideas? */
96 record_total += write(recfp, update_buf, 4);
97 }
98
99 int
100 startPlayback()
101 {
102 if (playback || (playback = booleanDefault("playback", 0))) {
103 if (!playFile)
104 playFile = stringDefault("playFile", "/tmp/netrek.record");
105 playFile = expandFilename(playFile);
106
107 playfp = open(playFile, O_RDONLY, 0);
108 if (playfp < 0) {
109 perror("startPlayback");
110 printf("Couldn't open playback file %s\n", playFile);
111 exit(0);
112 }
113 printf("Replaying %s\n", playFile);
114 return 1;
115 }
116 return 0;
117 }
118
119 int
120 readRecorded(fp, data, len)
121 int fp, len;
122 char *data;
123 {
124 int ret;
125
126 if (!playback || len < 0 || playfp < 0)
127 return -1;
128 if (len > 4) /* make sure we don't skip updates */
129 len = 4;
130 ret = read(playfp, data, len);
131 if (ret <= 0)
132 EXIT(0);
133 return ret;
134 }
135
136 void
137 pb_dokey(event)
138 W_Event *event;
139 {
140 switch (event->key&0xff) {
141 case 'p':
142 case 'P':
143 paused = !paused;
144 pb_scan=0;
145 if (paused)
146 pb_advance = 0;
147 break;
148 case 'r':
149 case 'R':
150 pb_advance = PB_REDALERT;
151 paused = 0;
152 break;
153 case 'y':
154 case 'Y':
155 pb_advance = PB_YELLOWALERT;
156 paused = 0;
157 break;
158 case 'd':
159 case 'D':
160 pb_advance = PB_DEATH;
161 paused = 0;
162 break;
163 case ' ':
164 if(paused) {
165 if(pb_scan)
166 pb_skip(pb_advance);
167 else {
168 pb_advance=1;
169 paused=0;
170 }
171 } else {
172 paused = 1;
173 pb_advance=0;
174 }
175 break;
176 case 'f':
177 case 'F': /* fast forward */
178 pb_scan=!pb_scan;
179 if(pb_scan) {
180 pb_advance=10;
181 pb_slow=0;
182 paused=0;
183 warning("1-9: set speed. P-Pause, F-Fast Fwd off");
184 } else {
185 pb_advance=0;
186 pb_slow=0;
187 paused=0;
188 warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
189 }
190 break;
191 case 's': /* Slow mode */
192 case 'S':
193 if(pb_scan || paused || !pb_slow)
194 pb_slow=1;
195 else
196 pb_slow=0;
197 pb_scan=0;
198 paused=0;
199 pb_advance=0;
200 break;
201 case '1':
202 case '2':
203 case '3':
204 case '4':
205 case '5':
206 case '6':
207 case '7':
208 case '8':
209 case '9':
210 if(!pb_scan)
211 pb_advance += (event->key - '0') * 10;
212 else
213 pb_advance = (event->key - '0') * 10;
214 paused = 0;
215 break;
216 case 'q':
217 case 'Q':
218 exit(0);
219 default:
220 warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
221 }
222 }
223
224 void
225 pb_skip(frames)
226 int frames;
227 {
228 while(frames) {
229 pb_update=0;
230 readFromServer();
231 frames-=pb_update;
232 udcounter+=pb_update;
233 }
234 }
235
236 void
237 pb_framectr(xloc, yloc)
238 int xloc, yloc;
239 {
240 char buf[20];
241
242 if(paused)
243 strcpy(buf,"PAU");
244 else if(pb_scan)
245 strcpy(buf,"FFW");
246 else if(pb_advance) {
247 switch(pb_advance) {
248 case PB_REDALERT:
249 strcpy(buf,"RED");
250 break;
251 case PB_YELLOWALERT:
252 strcpy(buf,"YLW");
253 break;
254 case PB_DEATH:
255 strcpy(buf,"DTH");
256 break;
257 default:
258 buf[0]='+';
259 buf[1]=(pb_advance / 10) + '0';
260 buf[2]=(pb_advance % 10) + '0';
261 break;
262 }
263 } else if(pb_slow)
264 strcpy(buf,"SLW");
265 else
266 strcpy(buf,"NRM");
267
268 sprintf((buf+3),":%8d",udcounter);
269
270 W_WriteText(tstatw, xloc, yloc, textColor, buf, 12, W_RegularFont);
271 }
272
273 void
274 pb_input()
275 {
276 W_Event data;
277 fd_set readfds;
278 int wsock = W_Socket();
279
280 struct timeval timeout;
281
282 timeout.tv_sec = 0;
283 timeout.tv_usec = 200000;
284
285 intrupt(); /* draws the first frame */
286
287 while (me->p_status == PALIVE ||
288 me->p_status == PEXPLODE ||
289 me->p_status == PDEAD ||
290 me->p_status == POBSERVE) {
291
292 if (keepInfo > 0) {
293 if (infowin_up >= 0 &&
294 --infowin_up == -1 &&
295 infomapped) {
296 destroyInfo();
297 infowin_up = -2;
298 }
299 }
300 exitInputLoop = 0;
301 while (W_EventsPending() && !exitInputLoop) {
302 fastQuit = 0; /* any event cancel fastquit */
303 W_NextEvent(&data);
304 dispatch_W_event(&data);
305 }
306 if (!paradise) /* stars are ok, it's just a recording.
307 zoom doesn't make sense. */
308 blk_zoom = 0;
309
310 #ifndef AMIGA
311 FD_ZERO(&readfds);
312 FD_SET(wsock, &readfds);
313 if (paused) {
314 select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
315 continue;
316 } else if(pb_slow && !pb_scan)
317 select(32, &readfds, (fd_set *) 0, (fd_set *) 0,&timeout);
318
319 /* otherwise, in full blast mode, don't wait on anything. */
320
321 #else /* AMIGA */
322 if (paused) {
323 sigsPending = Wait(wsock | SIGBREAKF_CTRL_C);
324 continue;
325 } else if(pb_slow && !pb_scan) {
326 StartTimer(0,200000);
327 while(1) {
328 sigsPending = Wait(wsock | portmask | SIGBREAKF_CTRL_C);
329 if((sigsPending & (wsock | SIGBREAKF_CTRL_C)) ||
330 CheckIO(&(ior->tr_node)))
331 break;
332 }
333
334 StopTimer();
335 }
336
337 if (sigsPending & SIGBREAKF_CTRL_C) {
338 printf("User break, Ctrl-C, exiting!\n");
339 exit(0);
340 }
341 #endif /* AMIGA */
342 /* at this point, we're sure it's time for at least one frame. */
343 intrupt();
344 }
345 }
346
347 #endif