ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimove.c
Revision: 3.10
Committed: Fri Mar 26 21:36:20 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.9: +71 -48 lines
Log Message:
Continued ANSIfication.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id";
3 #endif
4 /*
5 * Radiance object animation program
6 *
7 * Main program and control file handling.
8 *
9 * See ranimove.h and the ranimove(1) man page for details.
10 */
11
12 #include "copyright.h"
13
14 #include <time.h>
15 #ifdef _WIN32
16 #include <winsock.h> /* struct timeval. XXX find a replacement? */
17 #else
18 #include <sys/time.h>
19 #endif
20 #include <ctype.h>
21 #include <string.h>
22
23 #include "paths.h"
24 #include "ranimove.h"
25
26 int NVARS = NV_INIT; /* total number of variables */
27
28 VARIABLE vv[] = VV_INIT; /* variable-value pairs */
29
30 extern int nowarn; /* don't report warnings? */
31 int silent = 0; /* run silently? */
32
33 int quickstart = 0; /* time initial frame as well? */
34
35 int nprocs = 1; /* number of rendering processes */
36
37 int rtperfrm = 60; /* seconds to spend per frame */
38
39 double ndthresh = 2.; /* noticeable difference threshold */
40 int ndtset = 0; /* user threshold -- stop when reached? */
41
42 int fbeg = 1; /* starting frame */
43 int fend = 0; /* ending frame */
44 int fcur; /* current frame being rendered */
45
46 char lorendoptf[32]; /* low quality options file */
47 RAYPARAMS lorendparams; /* low quality rendering parameters */
48 char hirendoptf[32]; /* high quality options file */
49 RAYPARAMS hirendparams; /* high quality rendering parameters */
50 RAYPARAMS *curparams; /* current parameter settings */
51 int twolevels; /* low and high quality differ */
52
53 double mblur; /* vflt(MBLUR) */
54 double rate; /* vflt(RATE) */
55
56 char objtmpf[32]; /* object temporary file */
57
58 struct ObjMove *obj_move; /* object movements */
59
60 int haveprio = 0; /* high-level saliency specified */
61
62 int gargc; /* global argc for printargs */
63 char **gargv; /* global argv for printargs */
64
65 static void setdefaults(void);
66 static void setmove(struct ObjMove *om, char *ms);
67 static void setrendparams(char *optf, char *qval);
68 static void getradfile(char *rfargs);
69 static void animate(void);
70 static int countviews(void); /* XXX duplicated function */
71 static char * getobjname(struct ObjMove *om);
72 static char * getxf(struct ObjMove *om, int n);
73
74
75 int
76 main(
77 int argc,
78 char *argv[]
79 )
80 {
81 int explicate = 0;
82 char *cfname;
83 int i;
84
85 progname = argv[0]; /* get arguments */
86 gargc = argc;
87 gargv = argv;
88 for (i = 1; i < argc && argv[i][0] == '-'; i++)
89 switch (argv[i][1]) {
90 case 't': /* seconds per frame */
91 rtperfrm = atoi(argv[++i]);
92 break;
93 case 'd': /* noticeable difference */
94 ndthresh = atof(argv[++i]);
95 ndtset = 1;
96 break;
97 case 'e': /* print variables */
98 explicate++;
99 break;
100 case 's': /* silent running */
101 silent++;
102 break;
103 case 'q': /* start quickly */
104 quickstart++;
105 break;
106 case 'w': /* turn off warnings */
107 nowarn++;
108 break;
109 case 'f': /* frame range */
110 switch (sscanf(argv[++i], "%d,%d", &fbeg, &fend)) {
111 case 2:
112 if ((fbeg <= 0) | (fend < fbeg))
113 goto userr;
114 break;
115 case 1:
116 if (fbeg <= 0)
117 goto userr;
118 fend = 0;
119 break;
120 default:
121 goto userr;
122 }
123 break;
124 case 'n': /* number of processes */
125 nprocs = atoi(argv[++i]);
126 break;
127 default:
128 goto userr;
129 }
130 if (rtperfrm <= 0) {
131 if (!ndtset)
132 error(USER, "specify -d jnd with -t 0");
133 rtperfrm = 7*24*3600;
134 }
135 if (i != argc-1)
136 goto userr;
137 cfname = argv[i];
138 /* load variables */
139 loadvars(cfname);
140 /* check variables */
141 checkvalues();
142 /* load RIF if any */
143 if (vdef(RIF))
144 getradfile(vval(RIF));
145 /* set defaults */
146 setdefaults();
147 /* print variables */
148 if (explicate)
149 printvars(stdout);
150 /* run animation */
151 if (nprocs > 0)
152 animate();
153 /* all done */
154 if (lorendoptf[0])
155 unlink(lorendoptf);
156 if (hirendoptf[0] && strcmp(hirendoptf, lorendoptf))
157 unlink(hirendoptf);
158 if (objtmpf[0])
159 unlink(objtmpf);
160 return(0);
161 userr:
162 fprintf(stderr,
163 "Usage: %s [-n nprocs][-f beg,end][-t sec][-d jnd][-s][-w][-e] anim_file\n",
164 progname);
165 quit(1);
166 return 1; /* pro forma return */
167 }
168
169
170 void
171 eputs(s) /* put string to stderr */
172 register char *s;
173 {
174 static int midline = 0;
175
176 if (!*s)
177 return;
178 if (!midline++) {
179 fputs(progname, stderr);
180 fputs(": ", stderr);
181 }
182 fputs(s, stderr);
183 if (s[strlen(s)-1] == '\n') {
184 fflush(stderr);
185 midline = 0;
186 }
187 }
188
189
190 static void
191 setdefaults(void) /* set default values */
192 {
193 int nviews;
194 int decades;
195 char buf[256];
196 int i;
197
198 if (!vdef(OCTREEF)) {
199 sprintf(errmsg, "%s or %s must be defined",
200 vnam(OCTREEF), vnam(RIF));
201 error(USER, errmsg);
202 }
203 if (!vdef(VIEWFILE)) {
204 sprintf(errmsg, "%s must be defined", vnam(VIEWFILE));
205 error(USER, errmsg);
206 }
207 nviews = countviews();
208 if (!nviews)
209 error(USER, "no views in view file");
210 if (!vdef(END)) {
211 if (nviews == 1) {
212 sprintf(errmsg, "%s must be defined for single view",
213 vnam(END));
214 error(USER, errmsg);
215 }
216 sprintf(buf, "%d", nviews);
217 vval(END) = savqstr(buf);
218 vdef(END)++;
219 }
220 if (!fend)
221 fend = vint(END);
222 if (fbeg > fend)
223 error(USER, "begin after end");
224 if (!vdef(BASENAME)) {
225 decades = (int)log10((double)vint(END)) + 1;
226 if (decades < 3) decades = 3;
227 sprintf(buf, "frame%%0%dd", decades);
228 vval(BASENAME) = savqstr(buf);
229 vdef(BASENAME)++;
230 }
231 if (!vdef(RATE)) {
232 vval(RATE) = "8";
233 vdef(RATE)++;
234 }
235 rate = vflt(RATE);
236 if (!vdef(RESOLUTION)) {
237 vval(RESOLUTION) = "640";
238 vdef(RESOLUTION)++;
239 }
240 if (!vdef(MBLUR)) {
241 vval(MBLUR) = "0";
242 vdef(MBLUR)++;
243 }
244 mblur = vflt(MBLUR);
245 if (mblur > 1.)
246 mblur = 1.;
247 /* set up objects */
248 if (vdef(MOVE)) {
249 obj_move = (struct ObjMove *)malloc(
250 sizeof(struct ObjMove)*vdef(MOVE) );
251 if (obj_move == NULL)
252 error(SYSTEM, "out of memory in setdefaults");
253 for (i = 0; i < vdef(MOVE); i++)
254 setmove(&obj_move[i], nvalue(MOVE, i));
255 }
256 /* set up high quality options */
257 setrendparams(hirendoptf, vval(HIGHQ));
258 ray_save(&hirendparams);
259 /* set up low quality options */
260 setrendparams(lorendoptf, vval(LOWQ));
261 ray_save(&lorendparams);
262 curparams = &lorendparams;
263 twolevels = memcmp(&lorendparams, &hirendparams, sizeof(RAYPARAMS));
264 }
265
266
267 static void
268 setmove( /* assign a move object from spec. */
269 struct ObjMove *om,
270 char *ms
271 )
272 {
273 char parname[128];
274 char *cp;
275
276 ms = nextword(parname, sizeof(parname), ms);
277 if (!parname[0])
278 goto badspec;
279 for (cp = parname; *cp; cp++)
280 if (isspace(*cp))
281 *cp = '_';
282 for (om->parent = (om - obj_move); om->parent--; )
283 if (!strcmp(parname, obj_move[om->parent].name))
284 break;
285 if (om->parent < 0 &&
286 strcmp(parname, ".") && strcmp(parname, VOIDID)) {
287 sprintf(errmsg, "undefined parent object '%s'", parname);
288 error(USER, errmsg);
289 }
290 ms = nextword(om->name, sizeof(om->name), ms);
291 if (!om->name[0])
292 goto badspec;
293 for (cp = om->name; *cp; cp++)
294 if (isspace(*cp))
295 *cp = '_';
296 ms = nextword(om->xf_file, sizeof(om->xf_file), ms);
297 if (!strcmp(om->xf_file, "."))
298 om->xf_file[0] = '\0';
299 if (!om->xf_file[0]) {
300 om->xfs[0] = '\0';
301 } else if (om->xf_file[0] == '-') {
302 strcpy(om->xfs, om->xf_file);
303 om->xf_file[0] = '\0';
304 }
305 ms = nextword(om->spec, sizeof(om->spec), ms);
306 if (om->spec[0]) {
307 if (!strcmp(om->spec, ".") || !strcmp(om->spec, VOIDID))
308 om->spec[0] = '\0';
309 ms = nextword(om->prio_file, sizeof(om->prio_file), ms);
310 } else
311 om->prio_file[0] = '\0';
312 if (om->prio_file[0]) {
313 if (isflt(om->prio_file)) {
314 om->prio = atof(om->prio_file);
315 om->prio_file[0] = '\0';
316 haveprio |= ((om->prio < 0.95) | (om->prio > 1.05));
317 } else
318 haveprio = 1;
319 } else
320 om->prio = 1.;
321 om->cfm = -1;
322 return;
323 badspec:
324 error(USER, "bad object specification");
325 }
326
327
328 static void
329 setrendparams( /* set global rendering parameters */
330 char *optf,
331 char *qval
332 )
333 {
334 char *argv[1024];
335 char **av = argv;
336 int ac, i, rval;
337
338 av[ac=0] = NULL;
339 /* load options from file, first */
340 if (optf != NULL && *optf) {
341 ac = wordfile(av, optf);
342 if (ac < 0) {
343 sprintf(errmsg, "cannot load options file \"%s\"",
344 optf);
345 error(SYSTEM, errmsg);
346 }
347 }
348 /* then from options string */
349 if (qval != NULL && qval[0] == '-')
350 ac += wordstring(av+ac, qval);
351
352 /* restore default parameters */
353 ray_restore(NULL);
354 /* set what we have */
355 for (i = 0; i < ac; i++) {
356 while ((rval = expandarg(&ac, &av, i)) > 0)
357 ;
358 if (rval < 0) {
359 sprintf(errmsg, "cannot expand '%s'", av[i]);
360 error(SYSTEM, errmsg);
361 }
362 if (!strcmp(av[i], "-w")) {
363 nowarn++;
364 continue;
365 }
366 rval = getrenderopt(ac-i, av+i);
367 if (rval < 0) {
368 sprintf(errmsg, "bad render option at '%s'", av[i]);
369 error(USER, errmsg);
370 }
371 i += rval;
372 }
373 }
374
375
376 static void
377 getradfile( /* run rad and get needed variables */
378 char *rfargs
379 )
380 {
381 static short mvar[] = {OCONV,OCTREEF,RESOLUTION,EXPOSURE,-1};
382 char combuf[256];
383 register int i;
384 register char *cp;
385 char *pippt = NULL;
386 /* create rad command */
387 strcpy(lorendoptf, "ranim0.opt");
388 sprintf(combuf,
389 "rad -v 0 -s -e -w %s %s oconv=-f OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
390 rfargs,
391 (vdef(LOWQ) && vval(LOWQ)[0]!='-') ? vval(LOWQ) : "",
392 lorendoptf);
393 cp = combuf;
394 while (*cp) {
395 if (*cp == '|') pippt = cp;
396 cp++;
397 } /* match unset variables */
398 for (i = 0; mvar[i] >= 0; i++)
399 if (!vdef(mvar[i])) {
400 *cp++ = '|';
401 strcpy(cp, vnam(mvar[i]));
402 while (*cp) cp++;
403 pippt = NULL;
404 }
405 if (pippt != NULL)
406 strcpy(pippt, "> " NULL_DEVICE); /* nothing to match */
407 else {
408 strcpy(cp, ")[ \t]*=' > ranimove.var");
409 cp += 11; /* point to file name */
410 }
411 system(combuf); /* ignore exit code */
412 if (pippt == NULL) { /* load variables and remove file */
413 loadvars(cp);
414 unlink(cp);
415 }
416 if (!vdef(HIGHQ) || vval(HIGHQ)[0]=='-') {
417 strcpy(hirendoptf, lorendoptf);
418 return;
419 }
420 /* get high quality options */
421 strcpy(hirendoptf, "ranim1.opt");
422 sprintf(combuf, "rad -v 0 -s -w %s %s OPTFILE=%s",
423 rfargs, vval(HIGHQ), hirendoptf);
424 system(combuf);
425 }
426
427
428 static void
429 animate(void) /* run through animation */
430 {
431 int rpass;
432
433 if (fbeg > 1) /* synchronize transforms */
434 getoctspec(fbeg-1);
435
436 for (fcur = fbeg; fcur <= fend; fcur++) {
437 if (!silent)
438 printf("Frame %d:\n", fcur);
439 /* base rendering */
440 init_frame();
441 /* refinement */
442 for (rpass = 0; refine_frame(rpass); rpass++)
443 ;
444 /* final filter pass */
445 filter_frame();
446 /* output frame */
447 send_frame();
448 }
449 /* free resources */
450 free_frame();
451 if (nprocs > 1)
452 ray_pdone(1);
453 else
454 ray_done(1);
455 getview(0);
456 getexp(0);
457 }
458
459
460 extern VIEW *
461 getview( /* get view number n */
462 int n
463 )
464 {
465 static FILE *viewfp = NULL; /* view file pointer */
466 static int viewnum = 0; /* current view number */
467 static VIEW curview = STDVIEW; /* current view */
468 char linebuf[256];
469
470 if (n == 0) { /* signal to close file and clean up */
471 if (viewfp != NULL) {
472 fclose(viewfp);
473 viewfp = NULL;
474 viewnum = 0;
475 curview = stdview;
476 }
477 return(NULL);
478 }
479 if (viewfp == NULL) { /* open file */
480 if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) {
481 perror(vval(VIEWFILE));
482 quit(1);
483 }
484 } else if (n > 0 && n < viewnum) { /* rewind file */
485 if (viewnum == 1 && feof(viewfp))
486 return(&curview); /* just one view */
487 if (fseek(viewfp, 0L, 0) == EOF) {
488 perror(vval(VIEWFILE));
489 quit(1);
490 }
491 curview = stdview;
492 viewnum = 0;
493 }
494 if (n < 0) { /* get next view */
495 register int c = getc(viewfp);
496 if (c == EOF)
497 return(NULL); /* that's it */
498 ungetc(c, viewfp);
499 n = viewnum + 1;
500 }
501 while (n > viewnum) { /* scan to desired view */
502 if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL)
503 return(viewnum==1 ? &curview : (VIEW *)NULL);
504 if (isview(linebuf) && sscanview(&curview, linebuf) > 0)
505 viewnum++;
506 }
507 return(&curview); /* return it */
508 }
509
510
511 static int
512 countviews(void) /* count views in view file */
513 {
514 int n;
515
516 if (getview(n=1) == NULL)
517 return(0);
518 while (getview(-1) != NULL)
519 n++;
520 return(n);
521 }
522
523
524 extern char *
525 getexp( /* get exposure for nth frame */
526 int n
527 )
528 {
529 extern char *fskip();
530 static char expval[32];
531 static FILE *expfp = NULL;
532 static int curfrm = 0;
533 register char *cp;
534
535 if (n == 0) { /* signal to close file */
536 if (expfp != NULL) {
537 fclose(expfp);
538 expfp = NULL;
539 }
540 return(NULL);
541 }
542 if (!vdef(EXPOSURE)) /* no setting (auto) */
543 return(NULL);
544 if (isflt(vval(EXPOSURE))) /* always the same */
545 return(vval(EXPOSURE));
546 if (expfp == NULL) { /* open exposure file */
547 if ((expfp = fopen(vval(EXPOSURE), "r")) == NULL) {
548 sprintf(errmsg, "cannot open exposure file \"%s\"",
549 vval(EXPOSURE));
550 error(SYSTEM, errmsg);
551 }
552 curfrm = 0;
553 }
554 if (curfrm > n) { /* rewind if necessary */
555 rewind(expfp);
556 curfrm = 0;
557 }
558 while (n > curfrm) { /* read to line */
559 if (fgets(expval, sizeof(expval), expfp) == NULL) {
560 sprintf(errmsg, "%s: too few exposures",
561 vval(EXPOSURE));
562 error(USER, errmsg);
563 }
564 if (strlen(expval) == sizeof(expval)-1)
565 goto formerr;
566 curfrm++;
567 }
568 cp = fskip(expval); /* check format */
569 if (cp != NULL)
570 while (isspace(*cp))
571 *cp++ = '\0';
572 if (cp == NULL || *cp)
573 goto formerr;
574 return(expval); /* return value */
575 formerr:
576 sprintf(errmsg, "%s: exposure format error on line %d",
577 vval(EXPOSURE), curfrm);
578 error(USER, errmsg);
579 return NULL; /* pro forma return */
580 }
581
582
583 extern double
584 expspec_val( /* get exposure value from spec. */
585 char *s
586 )
587 {
588 double expval;
589
590 if (s == NULL || !*s)
591 return(1.0);
592
593 expval = atof(s);
594 if ((s[0] == '+') | (s[0] == '-'))
595 return(pow(2.0, expval));
596 return(expval);
597 }
598
599
600 extern char *
601 getoctspec( /* get octree for the given frame */
602 int n
603 )
604 {
605 static char combuf[1024];
606 int cfm = 0;
607 int uses_inline;
608 FILE *fp;
609 int i;
610 /* is octree static? */
611 if (!vdef(MOVE))
612 return(vval(OCTREEF));
613 /* done already */
614 if (n == cfm)
615 return(combuf);
616 /* else create object file */
617 strcpy(objtmpf, "movinobj.rad");
618 fp = fopen(objtmpf, "w");
619 if (fp == NULL) {
620 sprintf(errmsg, "cannot write to moving objects file '%s'",
621 objtmpf);
622 error(SYSTEM, errmsg);
623 }
624 uses_inline = 0;
625 for (i = 0; i < vdef(MOVE); i++) {
626 int inlc = (obj_move[i].spec[0] == '!');
627 if (!obj_move[i].spec[0])
628 continue;
629 if (inlc)
630 fprintf(fp, "%s %d \\\n\t| xform",
631 obj_move[i].spec, n);
632 else
633 fputs("!xform", fp);
634 fprintf(fp, " -n %s", getobjname(&obj_move[i]));
635 fputs(getxf(&obj_move[i], n), fp);
636 if (!inlc)
637 fprintf(fp, " %s\n", obj_move[i].spec);
638 else
639 fputc('\n', fp);
640 uses_inline |= inlc;
641 }
642 if (fclose(fp) == EOF)
643 error(SYSTEM, "error writing moving objects file");
644 if (uses_inline)
645 sprintf(combuf, "!oconv %s -f -i '%s' %s",
646 vdef(OCONV) ? vval(OCONV) : "",
647 vval(OCTREEF), objtmpf);
648 else
649 sprintf(combuf, "!xform -f %s | oconv -f -i '%s' -",
650 objtmpf, vval(OCTREEF));
651 return(combuf);
652 }
653
654
655 static char *
656 getobjname( /* get fully qualified object name */
657 register struct ObjMove *om
658 )
659 {
660 static char objName[512];
661 register char *cp = objName;
662
663 strcpy(cp, om->name);
664 while (om->parent >= 0) {
665 while (*cp) cp++;
666 *cp++ = '@';
667 om = &obj_move[om->parent];
668 strcpy(cp, om->name);
669 }
670 return(objName);
671 }
672
673
674 static char *
675 getxf( /* get total transform for object */
676 register struct ObjMove *om,
677 int n
678 )
679 {
680 static char xfsbuf[4096];
681 char *xfp;
682 int framestep = 0;
683 XF oxf;
684 FILE *fp;
685 char abuf[512];
686 char *av[64];
687 int ac;
688 int i;
689 register char *cp;
690 /* get parent transform, first */
691 if (om->parent >= 0)
692 xfp = getxf(&obj_move[om->parent], n);
693 else
694 *(xfp = xfsbuf + sizeof(xfsbuf)-1) = '\0';
695 /* get transform spec. & priority */
696 if (om->cfm != n) {
697 if (om->xf_file[0]) {
698 fp = fopen(om->xf_file, "r");
699 if (fp == NULL) {
700 sprintf(errmsg,
701 "cannot open transform file '%s'",
702 om->xf_file);
703 error(SYSTEM, errmsg);
704 }
705 for (i = 0; i < n; i++)
706 if (fgetline(om->xfs, sizeof(om->xfs), fp)
707 == NULL) {
708 sprintf(errmsg,
709 "too few transforms in file '%s'",
710 om->xf_file);
711 error(USER, errmsg);
712 }
713 fclose(fp);
714 }
715 strcpy(cp=abuf, om->xfs);
716 ac = 0;
717 for ( ; ; ) {
718 while (isspace(*cp))
719 *cp++ = '\0';
720 if (!*cp)
721 break;
722 av[ac++] = cp;
723 while (*++cp && !isspace(*cp))
724 ;
725 }
726 av[ac] = NULL;
727 if (xf(&oxf, ac, av) != ac ||
728 fabs(oxf.sca) <= FTINY) {
729 sprintf(errmsg, "bad transform args: %s",
730 om->xfs);
731 error(USER, errmsg);
732 }
733 copymat4(om->xfm, oxf.xfm);
734 if (om->prio_file[0]) {
735 fp = fopen(om->prio_file, "r");
736 if (fp == NULL) {
737 sprintf(errmsg,
738 "cannot open priority file '%s'",
739 om->prio_file);
740 error(SYSTEM, errmsg);
741 }
742 for (i = 0; i < n; i++)
743 if (fgets(abuf, sizeof(abuf), fp)
744 == NULL) {
745 sprintf(errmsg,
746 "too few priorities in file '%s'",
747 om->prio_file);
748 error(USER, errmsg);
749 }
750 fclose(fp);
751 cp = fskip(abuf);
752 if (cp != NULL)
753 while (isspace(*cp))
754 *cp++ = '\0';
755 if (cp == NULL || *cp) {
756 sprintf(errmsg,
757 "priority '%s' in file '%s' not a number",
758 abuf, om->prio_file);
759 error(USER, errmsg);
760 }
761 om->prio = atof(abuf);
762 }
763 framestep = (n == om->cfm + 1);
764 om->cfm = n;
765 }
766 /* prepend to parent transform */
767 if (om->xfs[0]) {
768 i = strlen(om->xfs);
769 if (xfp - i <= xfsbuf)
770 error(INTERNAL, "transform too long in getxf");
771 cp = om->xfs + i;
772 while (i--)
773 *--xfp = *--cp;
774 *--xfp = ' ';
775 }
776 if (framestep)
777 copymat4(oxf.xfm, om->cxfm);
778 if (om->parent >= 0) {
779 multmat4(om->cxfm, om->xfm, obj_move[om->parent].cxfm);
780 om->cprio = obj_move[om->parent].cprio * om->prio;
781 } else {
782 copymat4(om->cxfm, om->xfm);
783 om->cprio = om->prio;
784 }
785 /* XXX bxfm relies on call order */
786 if (framestep) {
787 if (invmat4(om->bxfm, om->cxfm))
788 multmat4(om->bxfm, om->bxfm, oxf.xfm);
789 else
790 setident4(om->bxfm);
791 }
792 /* all done */
793 return(xfp);
794 }
795
796
797 extern int
798 getmove( /* find matching move object */
799 OBJECT obj
800 )
801 {
802 static int lasti;
803 static OBJECT lasto = OVOID;
804 char *onm, *objnm;
805 int len, len2;
806 register int i;
807
808 if (obj == OVOID)
809 return(-1);
810 if (obj == lasto)
811 return(lasti);
812 /* look for matching object */
813 onm = objptr(obj)->oname;
814 for (i = vdef(MOVE); i--; ) {
815 objnm = obj_move[i].name;
816 len = strlen(objnm);
817 if (!strncmp(onm, objnm, len)) {
818 if ((obj_move[i].parent < 0) & (onm[len] == '.'))
819 break;
820 objnm = getobjname(&obj_move[i]) + len;
821 len2 = strlen(objnm);
822 if (!strncmp(onm+len, objnm, len2) && onm[len+len2] == '.')
823 break;
824 }
825 }
826 lasto = obj; /* cache what we found */
827 return(lasti = i);
828 }
829
830
831 extern double
832 obj_prio( /* return priority for object */
833 OBJECT obj
834 )
835 {
836 int moi;
837
838 if (obj == OVOID || (moi = getmove(obj)) < 0)
839 return(1.0);
840 return(obj_move[moi].cprio);
841 }
842
843
844 extern double
845 getTime(void) /* get current time (CPU or real) */
846 {
847 struct timeval time_now;
848 /* return CPU time if one process */
849 if (nprocs == 1)
850 return((double)clock()*(1.0/(double)CLOCKS_PER_SEC));
851 /* otherwise, return wall time */
852 gettimeofday(&time_now, NULL);
853 return((double)time_now.tv_sec + 1e-6*(double)time_now.tv_usec);
854 }