--- ray/src/hd/rhdisp.c 1997/12/08 18:51:15 3.10 +++ ray/src/hd/rhdisp.c 1998/01/04 18:37:10 3.20 @@ -14,12 +14,18 @@ static char SCCSid[] = "$SunId$ SGI"; #include "selcall.h" #include +#ifndef VIEWHISTLEN +#define VIEWHISTLEN 4 /* number of remembered views */ +#endif + HOLO *hdlist[HDMAX+1]; /* global holodeck list */ char cmdlist[DC_NCMDS][8] = DC_INIT; int imm_mode = 0; /* bundles are being delivered immediately */ +int do_outside = 0; /* render from outside sections */ + char *progname; /* global argv[0] */ FILE *sstdin, *sstdout; /* server's standard input and output */ @@ -52,24 +58,43 @@ char *argv[]; /* enter main loop */ do { rdy = disp_wait(); + if (rdy & RDY_SRV) { /* process server result */ + res = serv_result(); + if (pause && res != DS_SHUTDOWN) { + serv_request(DR_ATTEN, 0, NULL); + while ((res = serv_result()) != DS_ACKNOW && + res != DS_SHUTDOWN) + ; + } + } if (rdy & RDY_DEV) { /* user input from driver */ inp = dev_input(); - if (inp & DEV_PUTVIEW) - printview(); - if (inp & DEV_NEWVIEW) + if (inp & DFL(DC_SETVIEW)) new_view(&odev.v); - if (inp & DEV_SHUTDOWN) - serv_request(DR_SHUTDOWN, 0, NULL); - if (inp & DEV_REDRAW) { - imm_mode = 1; /* preempt updates */ - beam_sync(); + if (inp & DFL(DC_GETVIEW)) + printview(); + if (inp & DFL(DC_LASTVIEW)) + new_view(NULL); + if (inp & DFL(DC_RESUME)) { + serv_request(DR_NOOP, 0, NULL); + pause = 0; } - if (inp & DEV_WAIT) + if (inp & DFL(DC_PAUSE)) pause = 1; - if (inp & DEV_RESUME) { - serv_request(DR_NOOP, 0, NULL); + if (inp & DFL(DC_REDRAW)) + imm_mode = beam_sync() > 0; + if (inp & DFL(DC_KILL)) { + serv_request(DR_KILL, 0, NULL); pause = 0; } + if (inp & DFL(DC_CLOBBER)) + serv_request(DR_CLOBBER, 0, NULL); + if (inp & DFL(DC_RESTART)) { + serv_request(DR_RESTART, 0, NULL); + pause = 0; + } + if (inp & DFL(DC_QUIT)) + serv_request(DR_SHUTDOWN, 0, NULL); } if (rdy & RDY_SIN) /* user input from sstdin */ switch (usr_input()) { @@ -78,18 +103,12 @@ char *argv[]; break; case DC_RESUME: serv_request(DR_NOOP, 0, NULL); + /* fall through */ + case DC_KILL: + case DC_RESTART: pause = 0; break; } - if (rdy & RDY_SRV) { /* process server result */ - res = serv_result(); - if (pause && res != DS_SHUTDOWN) { - serv_request(DR_ATTEN, 0, NULL); - while ((res = serv_result()) != DS_ACKNOW && - res != DS_SHUTDOWN) - ; - } - } } while (res != DS_SHUTDOWN); /* all done */ quit(0); @@ -143,6 +162,7 @@ add_holo(hdg) /* register a new holodeck section */ HDGRID *hdg; { VIEW nv; + double d; register int hd; for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++) @@ -163,6 +183,12 @@ HDGRID *hdg; VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5); fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]); VCOPY(nv.vup, hdlist[0]->xv[2]); + if (do_outside) { + normalize(nv.vdir); + d = VLEN(hdlist[0]->xv[1]); + d += VLEN(hdlist[0]->xv[2]); + VSUM(nv.vp, nv.vp, nv.vdir, -d); + } new_view(&nv); } @@ -190,22 +216,39 @@ register PACKHEAD *p; new_view(v) /* change view parameters */ -VIEW *v; +register VIEW *v; { + static VIEW viewhist[VIEWHISTLEN]; + static unsigned nhist; char *err; - - do { - if ((err = setview(v)) != NULL) { - error(COMMAND, err); - return; - } - if (v->type == VT_PAR) { - error(COMMAND, "cannot handle parallel views"); - return; - } - dev_view(v); /* update display driver */ - dev_flush(); /* update screen */ - } while (!beam_view(v)); /* update beam list */ + /* restore previous view? */ + if (v == NULL) { + if (nhist > 1) /* get one before last setting */ + nhist--; + else /* else go to end of list */ + while (nhist < VIEWHISTLEN && viewhist[nhist].type) + nhist++; + v = viewhist + ((nhist-1)%VIEWHISTLEN); + } else +again: + if ((err = setview(v)) != NULL) { + error(COMMAND, err); + return; + } + if (v->type == VT_PAR) { + error(COMMAND, "cannot handle parallel views"); + return; + } + if (!dev_view(v)) /* update display driver */ + goto again; + dev_flush(); /* update screen */ + if (!beam_view(v)) /* update beam list */ + goto again; + /* record new view */ + if (v < viewhist || v >= viewhist+VIEWHISTLEN) { + copystruct(viewhist + (nhist%VIEWHISTLEN), v); + nhist++; + } } @@ -215,7 +258,7 @@ usr_input() /* get user input and process it */ VIEW vparams; char cmd[128]; register char *args; - register int cmdno; + register int i; if (fgets(cmd, sizeof(cmd), sstdin) == NULL) return(DC_QUIT); @@ -225,15 +268,17 @@ usr_input() /* get user input and process it */ *args++ = '\0'; if (!*cmd) return(DC_RESUME); - for (cmdno = 0; cmdno < DC_NCMDS; cmdno++) - if (!strcmp(cmd, cmdlist[cmdno])) + if (*args && args[i=strlen(args)-1] == '\n') + args[i] = '\0'; + for (i = 0; i < DC_NCMDS; i++) + if (!strcmp(cmd, cmdlist[i])) break; - if (cmdno >= DC_NCMDS) { + if (i >= DC_NCMDS) { sprintf(errmsg, "unknown command: %s", cmd); error(COMMAND, errmsg); return(-1); } - switch (cmdno) { + switch (i) { case DC_SETVIEW: /* set the view */ copystruct(&vparams, &odev.v); if (!sscanview(&vparams, args)) @@ -244,18 +289,32 @@ usr_input() /* get user input and process it */ case DC_GETVIEW: /* print the current view */ printview(); break; + case DC_LASTVIEW: /* restore previous view */ + new_view(NULL); + break; case DC_PAUSE: /* pause the current calculation */ case DC_RESUME: /* resume the calculation */ /* handled in main() */ break; + case DC_REDRAW: /* redraw from server */ + imm_mode = beam_sync() > 0; + break; + case DC_KILL: /* kill rtrace process(es) */ + serv_request(DR_KILL, 0, NULL); + break; + case DC_CLOBBER: /* clobber holodeck */ + serv_request(DR_CLOBBER, 0, NULL); + break; + case DC_RESTART: /* restart rtrace */ + serv_request(DR_RESTART, 0, NULL); + break; case DC_QUIT: /* quit request */ serv_request(DR_SHUTDOWN, 0, NULL); break; default: error(CONSISTENCY, "bad command id in usr_input"); } - return(cmdno); - + return(i); } @@ -302,11 +361,12 @@ serv_result() /* get next server result and process error(INTERNAL, "bad holodeck record from server"); add_holo((HDGRID *)buf); break; + case DS_OUTSECT: + do_outside = 1; + break; case DS_STARTIMM: case DS_ENDIMM: imm_mode = msg.type==DS_STARTIMM; - if (msg.type == DS_ENDIMM) - dev_flush(); /* update display NOW */ /* fall through */ case DS_ACKNOW: case DS_SHUTDOWN: