Mercurial > ~darius > hgwebdir.cgi > paradise_client
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 |