ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhdisp.c
Revision: 3.11
Committed: Tue Dec 9 17:12:15 1997 UTC (26 years, 4 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.10: +8 -7 lines
Log Message:
fixed minor error in parsing of command arguments

File Contents

# Content
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Holodeck display process.
9 */
10
11 #include "rholo.h"
12 #include "rhdisp.h"
13 #include "rhdriver.h"
14 #include "selcall.h"
15 #include <ctype.h>
16
17 HOLO *hdlist[HDMAX+1]; /* global holodeck list */
18
19 char cmdlist[DC_NCMDS][8] = DC_INIT;
20
21 int imm_mode = 0; /* bundles are being delivered immediately */
22
23 char *progname; /* global argv[0] */
24
25 FILE *sstdin, *sstdout; /* server's standard input and output */
26
27 #define RDY_SRV 01
28 #define RDY_DEV 02
29 #define RDY_SIN 04
30
31
32 main(argc, argv)
33 int argc;
34 char *argv[];
35 {
36 extern int eputs();
37 int rdy, inp, res = 0, pause = 0;
38
39 progname = argv[0];
40 if (argc < 3)
41 error(USER, "bad command line arguments");
42 /* open our device */
43 dev_open(argv[1]);
44 /* open server process i/o */
45 sstdout = fdopen(atoi(argv[2]), "w");
46 if (argc < 4 || (inp = atoi(argv[3])) < 0)
47 sstdin = NULL;
48 else
49 sstdin = fdopen(inp, "r");
50 /* set command error vector */
51 erract[COMMAND].pf = eputs;
52 /* enter main loop */
53 do {
54 rdy = disp_wait();
55 if (rdy & RDY_DEV) { /* user input from driver */
56 inp = dev_input();
57 if (inp & DEV_PUTVIEW)
58 printview();
59 if (inp & DEV_NEWVIEW)
60 new_view(&odev.v);
61 if (inp & DEV_SHUTDOWN)
62 serv_request(DR_SHUTDOWN, 0, NULL);
63 if (inp & DEV_REDRAW) {
64 imm_mode = 1; /* preempt updates */
65 beam_sync();
66 }
67 if (inp & DEV_WAIT)
68 pause = 1;
69 if (inp & DEV_RESUME) {
70 serv_request(DR_NOOP, 0, NULL);
71 pause = 0;
72 }
73 }
74 if (rdy & RDY_SIN) /* user input from sstdin */
75 switch (usr_input()) {
76 case DC_PAUSE:
77 pause = 1;
78 break;
79 case DC_RESUME:
80 serv_request(DR_NOOP, 0, NULL);
81 pause = 0;
82 break;
83 }
84 if (rdy & RDY_SRV) { /* process server result */
85 res = serv_result();
86 if (pause && res != DS_SHUTDOWN) {
87 serv_request(DR_ATTEN, 0, NULL);
88 while ((res = serv_result()) != DS_ACKNOW &&
89 res != DS_SHUTDOWN)
90 ;
91 }
92 }
93 } while (res != DS_SHUTDOWN);
94 /* all done */
95 quit(0);
96 }
97
98
99 int
100 disp_wait() /* wait for more input */
101 {
102 fd_set readset, errset;
103 int flgs;
104 int n;
105 register int i;
106 /* see if we can avoid select call */
107 if (imm_mode || stdin->_cnt > 0)
108 return(RDY_SRV);
109 if (sstdin != NULL && sstdin->_cnt > 0)
110 return(RDY_SIN);
111 if (dev_flush())
112 return(RDY_DEV);
113 /* make the call */
114 FD_ZERO(&readset); FD_ZERO(&errset);
115 FD_SET(0, &readset);
116 FD_SET(0, &errset);
117 FD_SET(odev.ifd, &readset);
118 FD_SET(odev.ifd, &errset);
119 n = odev.ifd+1;
120 if (sstdin != NULL) {
121 FD_SET(fileno(sstdin), &readset);
122 if (fileno(sstdin) >= n)
123 n = fileno(sstdin) + 1;
124 }
125 n = select(n, &readset, NULL, &errset, NULL);
126 if (n < 0) {
127 if (errno == EINTR)
128 return(0);
129 error(SYSTEM, "select call failure in disp_wait");
130 }
131 flgs = 0; /* flag what's ready */
132 if (FD_ISSET(0, &readset) || FD_ISSET(0, &errset))
133 flgs |= RDY_SRV;
134 if (FD_ISSET(odev.ifd, &readset) || FD_ISSET(odev.ifd, &errset))
135 flgs |= RDY_DEV;
136 if (sstdin != NULL && FD_ISSET(fileno(sstdin), &readset))
137 flgs |= RDY_SIN;
138 return(flgs);
139 }
140
141
142 add_holo(hdg) /* register a new holodeck section */
143 HDGRID *hdg;
144 {
145 VIEW nv;
146 register int hd;
147
148 for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++)
149 ;
150 if (hd >= HDMAX)
151 error(INTERNAL, "too many holodeck sections in add_holo");
152 hdlist[hd] = (HOLO *)malloc(sizeof(HOLO));
153 if (hdlist[hd] == NULL)
154 error(SYSTEM, "out of memory in add_holo");
155 bcopy((char *)hdg, (char *)hdlist[hd], sizeof(HDGRID));
156 hdcompgrid(hdlist[hd]);
157 if (hd)
158 return;
159 /* set initial viewpoint */
160 copystruct(&nv, &odev.v);
161 VSUM(nv.vp, hdlist[0]->orig, hdlist[0]->xv[0], 0.5);
162 VSUM(nv.vp, nv.vp, hdlist[0]->xv[1], 0.5);
163 VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5);
164 fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]);
165 VCOPY(nv.vup, hdlist[0]->xv[2]);
166 new_view(&nv);
167 }
168
169
170 disp_bundle(p) /* display a ray bundle */
171 register PACKHEAD *p;
172 {
173 GCOORD gc[2];
174 FVECT ro, rd, wp;
175 double d;
176 register int i;
177 /* get beam coordinates */
178 if (p->hd < 0 | p->hd >= HDMAX || hdlist[p->hd] == NULL)
179 error(INTERNAL, "bad holodeck number in disp_bundle");
180 if (!hdbcoord(gc, hdlist[p->hd], p->bi))
181 error(INTERNAL, "bad beam index in disp_bundle");
182 /* display each ray */
183 for (i = p->nr; i--; ) {
184 hdray(ro, rd, hdlist[p->hd], gc, packra(p)[i].r);
185 d = hddepth(hdlist[p->hd], packra(p)[i].d);
186 VSUM(wp, ro, rd, d); /* might be behind viewpoint */
187 dev_value(packra(p)[i].v, wp, rd);
188 }
189 }
190
191
192 new_view(v) /* change view parameters */
193 VIEW *v;
194 {
195 char *err;
196
197 do {
198 if ((err = setview(v)) != NULL) {
199 error(COMMAND, err);
200 return;
201 }
202 if (v->type == VT_PAR) {
203 error(COMMAND, "cannot handle parallel views");
204 return;
205 }
206 dev_view(v); /* update display driver */
207 dev_flush(); /* update screen */
208 } while (!beam_view(v)); /* update beam list */
209 }
210
211
212 int
213 usr_input() /* get user input and process it */
214 {
215 VIEW vparams;
216 char cmd[128];
217 register char *args;
218 register int i;
219
220 if (fgets(cmd, sizeof(cmd), sstdin) == NULL)
221 return(DC_QUIT);
222 for (args = cmd; *args && !isspace(*args); args++)
223 ;
224 while (isspace(*args))
225 *args++ = '\0';
226 if (!*cmd)
227 return(DC_RESUME);
228 if (*args && args[i=strlen(args)-1] == '\n')
229 args[i] = '\0';
230 for (i = 0; i < DC_NCMDS; i++)
231 if (!strcmp(cmd, cmdlist[i]))
232 break;
233 if (i >= DC_NCMDS) {
234 sprintf(errmsg, "unknown command: %s", cmd);
235 error(COMMAND, errmsg);
236 return(-1);
237 }
238 switch (i) {
239 case DC_SETVIEW: /* set the view */
240 copystruct(&vparams, &odev.v);
241 if (!sscanview(&vparams, args))
242 error(COMMAND, "missing view options");
243 else
244 new_view(&vparams);
245 break;
246 case DC_GETVIEW: /* print the current view */
247 printview();
248 break;
249 case DC_PAUSE: /* pause the current calculation */
250 case DC_RESUME: /* resume the calculation */
251 /* handled in main() */
252 break;
253 case DC_QUIT: /* quit request */
254 serv_request(DR_SHUTDOWN, 0, NULL);
255 break;
256 default:
257 error(CONSISTENCY, "bad command id in usr_input");
258 }
259 return(i);
260 }
261
262
263 printview() /* print our current view to server stdout */
264 {
265 fputs(VIEWSTR, sstdout);
266 fprintview(&odev.v, sstdout);
267 fputc('\n', sstdout);
268 fflush(sstdout);
269 }
270
271
272 int
273 serv_result() /* get next server result and process it */
274 {
275 static char *buf = NULL;
276 static int bufsiz = 0;
277 MSGHEAD msg;
278 int n;
279 /* read message header */
280 if (fread((char *)&msg, sizeof(MSGHEAD), 1, stdin) != 1)
281 goto readerr;
282 if (msg.nbytes > 0) { /* get the message body */
283 if (msg.nbytes > bufsiz) {
284 if (buf == NULL)
285 buf = (char *)malloc(bufsiz=msg.nbytes);
286 else
287 buf = (char *)realloc(buf, bufsiz=msg.nbytes);
288 if (buf == NULL)
289 error(SYSTEM, "out of memory in serv_result");
290 }
291 if (fread(buf, 1, msg.nbytes, stdin) != msg.nbytes)
292 goto readerr;
293 }
294 switch (msg.type) { /* process results */
295 case DS_BUNDLE:
296 if (msg.nbytes < sizeof(PACKHEAD) ||
297 msg.nbytes != packsiz(((PACKHEAD *)buf)->nr))
298 error(INTERNAL, "bad display packet from server");
299 disp_bundle((PACKHEAD *)buf);
300 break;
301 case DS_ADDHOLO:
302 if (msg.nbytes != sizeof(HDGRID))
303 error(INTERNAL, "bad holodeck record from server");
304 add_holo((HDGRID *)buf);
305 break;
306 case DS_STARTIMM:
307 case DS_ENDIMM:
308 imm_mode = msg.type==DS_STARTIMM;
309 if (msg.type == DS_ENDIMM)
310 dev_flush(); /* update display NOW */
311 /* fall through */
312 case DS_ACKNOW:
313 case DS_SHUTDOWN:
314 if (msg.nbytes) {
315 sprintf(errmsg,
316 "unexpected body with server message %d",
317 msg.type);
318 error(INTERNAL, errmsg);
319 }
320 break;
321 default:
322 error(INTERNAL, "unrecognized result from server process");
323 }
324 return(msg.type); /* return message type */
325 readerr:
326 if (feof(stdin))
327 error(SYSTEM, "server process died");
328 error(SYSTEM, "error reading from server process");
329 }
330
331
332 serv_request(type, nbytes, p) /* send a request to the server process */
333 int type, nbytes;
334 char *p;
335 {
336 MSGHEAD msg;
337 int m;
338 /* get server's attention for big request */
339 if (nbytes >= BIGREQSIZ-sizeof(MSGHEAD)) {
340 serv_request(DR_ATTEN, 0, NULL);
341 while ((m = serv_result()) != DS_ACKNOW)
342 if (m == DS_SHUTDOWN) /* the bugger quit on us */
343 quit(0);
344 }
345 msg.type = type; /* write and flush the message */
346 msg.nbytes = nbytes;
347 fwrite((char *)&msg, sizeof(MSGHEAD), 1, stdout);
348 if (nbytes > 0)
349 fwrite(p, 1, nbytes, stdout);
350 if (fflush(stdout) < 0)
351 error(SYSTEM, "write error in serv_request");
352 }
353
354
355 eputs(s) /* put error message to stderr */
356 register char *s;
357 {
358 static int midline = 0;
359
360 if (!*s)
361 return;
362 if (!midline++) { /* prepend line with program name */
363 fputs(progname, stderr);
364 fputs(": ", stderr);
365 }
366 fputs(s, stderr);
367 if (s[strlen(s)-1] == '\n') {
368 fflush(stderr);
369 midline = 0;
370 }
371 }
372
373
374 quit(code) /* clean up and exit */
375 int code;
376 {
377 if (odev.v.type)
378 dev_close();
379 exit(code);
380 }