1 // lpanel.cpp lightpanel class
2
3 #define DEBUG 0
4
5 /* Copyright (c) 2007-2008, John Kichury
6
7 This software is freely distributable free of charge and without license fees with the
8 following conditions:
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
13 JOHN KICHURY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
14 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
17 The above copyright notice must be included in any copies of this software.
18
19 */
20
21 #ifdef __CYGWIN__
22 #include <windef.h>
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <pthread.h>
30 #include <GL/gl.h>
31 #include <GL/glu.h>
32 #include "lp_utils.h"
33 #include "lp_materials.h"
34 #include "lpanel.h"
35
36 #include "lpanel_data.h"
37
38 extern pthread_mutex_t data_sample_lock;
39
40 static parser_rules_t light_parse_rules[] =
41 {
42 { "color", 3, 3, PARSER_FLOAT },
43 { "group", 1, 1, PARSER_INT },
44 { "object", 1, 1, PARSER_STRING },
45 { "pos", 2, 3, PARSER_FLOAT },
46 { "size", 2, 3, PARSER_FLOAT },
47 { NULL,0,0,0 }
48 };
49
50 extern Parser parser;
51
52
drawLightObject(lpLight * lp)53 void drawLightObject(lpLight *lp)
54 {
55 lp->obj_ref->draw(2);
56 }
57
drawLightGraphics(lpLight * lp)58 void drawLightGraphics(lpLight *lp)
59 {
60 int i;
61 int lod=1;
62
63 for(i=0;i<3;i++)
64 {
65 if( lp->color[i] < 0. ||
66 lp->color[i] > 1. )
67 printf("drawLight: color out of range color[%d] = %f\n", i, lp->color[i]);
68 }
69
70 //glColor3f(0.,0.,0.);
71 glBegin(GL_POLYGON);
72
73 for(i=0;i<cir2d_nverts-1;i+=lod)
74 glVertex2fv(&cir2d_data2[i][0]);
75
76 glEnd();
77
78 glBegin(GL_TRIANGLE_STRIP);
79
80 for(i=0;i<cir2d_nverts-1;i+=lod)
81 {
82 glColor3fv(&lp->color[0]);
83 glVertex2fv(&cir2d_data2[i][0]);
84 glColor3f(0.,0.,0.);
85 glVertex2fv(&cir2d_data[i][0]);
86 }
87
88 glColor3fv(&lp->color[0]);
89 glVertex2fv(&cir2d_data2[0][0]);
90 glColor3f(0.,0.,0.);
91 glVertex2fv(&cir2d_data[0][0]);
92 glEnd();
93
94 }
95
96 void
sampleData8_error(lpLight * p)97 sampleData8_error(lpLight *p)
98 {
99 #if 0
100 static int flag = 0;
101 if(!flag)
102 {
103 printf("sampleData8: light %s has no data bound to it. \n", p->name);
104 flag = 1;
105 }
106 #endif
107 }
108
109 void
sampleData8(lpLight * p)110 sampleData8(lpLight *p)
111 {
112 unsigned char bit;
113 uint8 *ptr = (uint8 *) p->dataptr;
114
115 bit = (int) (*ptr >> p->bitnum) & 0x01;
116
117 if(bit)
118 {
119 p->on_time += ( *p->simclock - p->old_clock );
120 }
121 p->old_clock = *p->simclock;
122 p->dirty = 1;
123 p->state = bit;
124
125 }
126
127
128 void
sampleData8invert(lpLight * p)129 sampleData8invert(lpLight *p)
130 {
131 unsigned char bit;
132 uint8 *ptr = (uint8 *) p->dataptr;
133
134 bit = (int) ~(*ptr >> p->bitnum) & 0x01;
135
136 if(bit)
137 {
138 p->on_time += ( *p->simclock - p->old_clock );
139 }
140 p->old_clock = *p->simclock;
141 p->dirty = 1;
142 p->state = bit;
143
144 }
145
146 void
sampleData16(lpLight * p)147 sampleData16(lpLight *p)
148 {
149 unsigned char bit;
150 uint16 *ptr = (uint16 *) p->dataptr;
151 uint64 on_time_inc = 0;
152 int logit = 0;
153
154 bit = (int) (*ptr >> p->bitnum) & 0x01;
155
156 #if 0
157 if(bit)
158 {
159 #if 0
160 p->on_time += ( *p->simclock - p->old_clock );
161 #endif
162 on_time_inc = ( *p->simclock - p->old_clock );
163 }
164
165 if( bit != p->state)
166 {
167 on_time_inc = on_time_inc >> 1;
168 }
169 p->on_time += on_time_inc;
170 #endif
171
172 //if(p->old_clock > *p->simclock) printf("sampleData16: clock stepped backward\n");
173
174 if(bit)
175 {
176 p->on_time += ( *p->simclock - p->old_clock );
177 }
178
179 p->old_clock = *p->simclock;
180 p->dirty = 1;
181 p->state = bit;
182
183 }
184
185 void
sampleDatafv(lpLight * p)186 sampleDatafv(lpLight *p)
187 {
188 float *ptr = (float *) p->dataptr;
189 int logit = 0;
190
191 if(p->smoothing > 0)
192 {
193 p->intense_curr = p->intensity;
194 p->intense_samples[p->intense_curr_idx] = ptr[p->bitnum];
195
196 if(p->intense_samples[p->intense_curr_idx] > 1.0) p->intense_samples[p->intense_curr_idx] = 1.0;
197 else if(p->intense_samples[p->intense_curr_idx] < 0.0) p->intense_samples[p->intense_curr_idx] = 0.0;
198
199 p->intense_incr = ( p->intense_samples[p->intense_curr_idx] -
200 p->intense_samples[!p->intense_curr_idx]) / (float) p->smoothing;
201
202 }
203 else
204 p->intensity = ptr[p->bitnum];
205
206 }
207
208
209
210 void
sampleData16invert(lpLight * p)211 sampleData16invert(lpLight *p)
212 {
213 unsigned char bit;
214 uint16 *ptr = (uint16 *) p->dataptr;
215
216 bit = (int) ~(*ptr >> p->bitnum) & 0x01;
217
218 if(bit)
219 {
220 p->on_time += ( *p->simclock - p->old_clock );
221 }
222 p->old_clock = *p->simclock;
223 p->dirty = 1;
224 p->state = bit;
225
226 }
227
228 void
sampleData32(lpLight * p)229 sampleData32(lpLight *p)
230 {
231 unsigned char bit;
232 uint32 *ptr = (uint32 *) p->dataptr;
233
234 bit = (int) (*ptr >> p->bitnum) & 0x01;
235
236 if(bit)
237 {
238 p->on_time += ( *p->simclock - p->old_clock );
239 }
240 p->old_clock = *p->simclock;
241 p->dirty = 1;
242 p->state = bit;
243
244 }
245
246
247 void
sampleData32invert(lpLight * p)248 sampleData32invert(lpLight *p)
249 {
250 unsigned char bit;
251 uint32 *ptr = (uint32 *) p->dataptr;
252
253 bit = (int) ~(*ptr >> p->bitnum) & 0x01;
254
255 if(bit)
256 {
257 p->on_time += ( *p->simclock - p->old_clock );
258 }
259 p->old_clock = *p->simclock;
260 p->dirty = 1;
261 p->state = bit;
262
263 }
264
265 void
sampleData64(lpLight * p)266 sampleData64(lpLight *p)
267 {
268 unsigned char bit;
269 uint64 *ptr = (uint64 *) p->dataptr;
270
271 bit = (int) (*ptr >> p->bitnum) & 0x01;
272
273 if(bit)
274 {
275 p->on_time += ( *p->simclock - p->old_clock );
276 }
277 p->old_clock = *p->simclock;
278 p->dirty = 1;
279 p->state = bit;
280
281 }
282
283 void
sampleData64invert(lpLight * p)284 sampleData64invert(lpLight *p)
285 {
286 unsigned char bit;
287 uint64 *ptr = (uint64 *) p->dataptr;
288
289 bit = (int) ~(*ptr >> p->bitnum) & 0x01;
290
291 if(bit)
292 {
293 p->on_time += ( *p->simclock - p->old_clock );
294 }
295 p->old_clock = *p->simclock;
296 p->dirty = 1;
297 p->state = bit;
298
299 }
300
301
Lpanel(void)302 Lpanel::Lpanel(void) // constructor
303 {
304 int i;
305
306 #if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
307 #else
308 window = 0;
309 cx = 0;
310 dpy = 0;
311 #endif
312
313 num_lights = 0;
314 max_lights = 0;
315 lights = NULL;
316
317 num_switches = max_switches = 0;
318 switches = NULL;
319 mom_switch_pressed = NULL;
320
321 default_clock = 0;
322 old_clock = 0;
323 simclock = &default_clock;
324 clock_warp = 0;
325
326 default_runflag = 0;
327 runflag = &default_runflag;
328
329 // init light groups
330
331 for(i=0;i<LP_MAX_LIGHT_GROUPS;i++)
332 {
333 light_groups[i].num_items = 0;
334 light_groups[i].max_items = 0;
335 light_groups[i].list = NULL;
336 }
337
338 // init light graphics
339
340 lightcolor[0] = 1.;
341 lightcolor[1] = 0.;
342 lightcolor[2] = 0.;
343 lightsize[0] = 0.1875;
344 lightsize[1] = 0.1875;
345 lightsize[2] = 0.1875;
346
347 for(i=0;i<cir2d_nverts;i++)
348 {
349 cir2d_data2[i][0] = cir2d_data[i][0] * .4;
350 cir2d_data2[i][1] = cir2d_data[i][1] * .4;
351 }
352
353 // init config root path
354
355 setConfigRootPath(".");
356
357 // init graphics objects
358
359 envmap_detected = 0;
360 num_objects = 0;
361 max_objects = 0;
362 objects = NULL;
363
364 num_alpha_objects = 0;
365 max_alpha_objects = 0;
366 alpha_objects = NULL;
367
368 curr_object = NULL;
369 curr_element = NULL;
370 curr_vertex = NULL;
371
372 // use this for small displays like notebooks etc.
373 window_xsize = 800;
374 window_ysize = 325;
375
376 // use this for Desktops/Workstations with good graphics
377 //window_xsize = 1600;
378 //window_ysize = 650;
379
380 cursor[0] = 0.;
381 cursor[1] = 0.;
382 cursor[2] = 0.0;
383 cursor_inc = .01;
384 do_cursor = 0;
385 do_stats = 0;
386 shift_key_pressed = 0;
387
388
389 // graphics view parms
390
391 view.rot[0] = 0.;
392 view.rot[1] = 0.;
393 view.rot[2] = 0.;
394
395 view.pan[0] = 0.;
396 view.pan[1] = -0.0;
397 view.pan[2] = -16.0;
398
399 view.znear = 0.01;
400 view.zfar = 1000.0;
401 view.fovy = 25.0;
402 view.projection = LP_ORTHO;
403 view.redo_projections = 1;
404 view.do_depthtest = 0; // default to no zbuffer
405
406 quit_callbackfunc = NULL;
407
408 } // end constructor
409
410
~Lpanel(void)411 Lpanel::~Lpanel(void) // destructor
412 {
413 Quit();
414
415 }
416
417 int
test(int n)418 Lpanel::test(int n)
419 {
420
421 printf("panel test %d\n",n);
422
423 switch(n)
424 {
425 case 0:
426 break;
427 case 1:
428 break;
429 default:
430 break;
431 }
432
433 return 1;
434 }
435
436 void
addQuitCallback(void (* cbfunc)(void))437 Lpanel::addQuitCallback( void (*cbfunc)(void))
438 {
439 quit_callbackfunc = cbfunc;
440 }
441
442 void
Quit(void)443 Lpanel::Quit(void)
444 {
445 int i;
446
447
448 for(i=0;i<num_lights;i++)
449 if(lights[i]) delete lights[i];
450 num_lights = max_lights = 0;
451
452
453 for(i=0;i<num_objects;i++)
454 if(objects[i]) delete objects[i];
455 num_objects = max_objects = 0;
456
457 for(i=0;i<num_switches;i++)
458 if(switches[i]) delete switches[i];
459 num_switches = max_switches = 0;
460
461 for(i=0;i<LP_MAX_LIGHT_GROUPS;i++)
462 {
463 if(light_groups[i].list)
464 { delete light_groups[i].list;
465 light_groups[i].list = NULL;
466 }
467 light_groups[i].num_items = 0;
468 light_groups[i].max_items = 0;
469 }
470
471 //destroyWindow();
472
473 } // end destructor
474
475
476 int
addLight(const char * name,lp_obj_parm_t * obj,const char * buff)477 Lpanel::addLight(const char *name, lp_obj_parm_t *obj, const char *buff)
478 {
479 int i,n;
480 parser_result_t *result;
481 lpLight *light;
482
483
484 if(num_lights + 1 > max_lights) growLights();
485
486 lights[num_lights] = new lpLight;
487 light = lights[num_lights];
488 lights[num_lights]->parms = obj;
489 lights[num_lights]->setName(name);
490 lights[num_lights]->bindSimclock(simclock, &clock_warp);
491 lights[num_lights]->panel = this;
492
493 parser.setRules(light_parse_rules);
494 parser.setParseString(buff);
495
496 // parse config file line values such has position, color etc.
497 // if n >= 0 it contains the char position in the line where an error
498 // ocurred
499
500 while( (n = parser.parse(&result)) < 0 )
501 {
502 if(n != PARSER_DONE)
503 {
504
505 if(!strcmp(light_parse_rules[result->cmd_idx].cmd, "color"))
506 {
507 for(i=0;i<result->num_args;i++)
508 light->parms->color[i] = result->floats[i];
509 }
510 else if(!strcmp(light_parse_rules[result->cmd_idx].cmd, "group"))
511 {
512 light->parms->group = result->ints[0];
513 }
514 else if(!strcmp(light_parse_rules[result->cmd_idx].cmd, "object"))
515 {
516 light->obj_refname = new char[strlen(result->strings[0])+1];
517 strcpy(light->obj_refname, result->strings[0]);
518 }
519 else if(!strcmp(light_parse_rules[result->cmd_idx].cmd, "pos"))
520 {
521 for(i=0;i<result->num_args;i++)
522 light->parms->pos[i] = result->floats[i];
523 }
524 else if(!strcmp(light_parse_rules[result->cmd_idx].cmd, "size"))
525 {
526 for(i=0;i<result->num_args;i++)
527 light->parms->scale[i] = result->floats[i];
528 }
529 } // end if(n != PARSER_DONE)
530
531 if( n == PARSER_DONE) break;
532 }
533
534 if( n >= 0)
535 { printf("n=%d\n",n);
536 parser.printError();
537 return n;
538 }
539
540
541 if(obj->group >=0)
542 {
543 addLightToGroup(num_lights, obj->group);
544 }
545
546 num_lights++;
547
548 return(-1);
549
550 }
551
552 int
addLightToGroup(int lightnum,int groupnum)553 Lpanel::addLightToGroup( int lightnum, int groupnum)
554 {
555
556 if(groupnum >= LP_MAX_LIGHT_GROUPS)
557 {
558 fprintf(stderr, "error: light %s invalid group number (%d)\n", lights[lightnum]->name, groupnum);
559 return 0;
560 }
561
562 if( light_groups[groupnum].num_items + 1 > light_groups[groupnum].max_items)
563 {
564 int *new_list,
565 i;
566
567 new_list = new int[light_groups[groupnum].max_items + 1];
568
569 if(light_groups[groupnum].list)
570 { for(i=0; i < light_groups[groupnum].max_items;i++)
571 new_list[i] = light_groups[groupnum].list[i];
572 delete light_groups[groupnum].list;
573 }
574 light_groups[groupnum].list = new_list;
575 }
576 light_groups[groupnum].max_items += 1;
577 light_groups[groupnum].list[light_groups[groupnum].num_items] = lightnum;
578 light_groups[groupnum].num_items++;
579 return 1;
580 }
581
582 int
bindLight8(char * name,void * loc,int start_bit_number)583 Lpanel::bindLight8(char *name, void *loc, int start_bit_number)
584 {
585 char **namelist;
586 int num_names;
587 int i, status = 1;
588 int bitnum, bit_inc;
589 lpLight *light;
590
591 num_names = xpand(name, &namelist);
592
593 bitnum = abs(start_bit_number);
594 if(start_bit_number > 0) bit_inc = 1;
595 else bit_inc = -1;
596
597 for(i=0;i<num_names;i++)
598 {
599 if(bitnum <=0)
600 {
601 fprintf(stderr, "bindLight8: light %s bad bitnum %d\n", namelist[i], bitnum);
602 bitnum = 1;
603 }
604
605 light = findLightByName(namelist[i]);
606
607 if(light)
608 {
609 light->bindData8( (uint8 *) loc);
610 light->setBitNumber(bitnum-1);
611 }
612 else
613 {
614 if(!ignore_bind_errors) fprintf(stderr, "bindLight8: light %s not found\n", namelist[i]);
615 status = 0;
616 }
617 if(namelist[i]) delete namelist[i];
618 bitnum += bit_inc;
619 }
620
621 return status;
622 }
623
624 // bind light and invert logic according to mask
625
626 int
bindLight8invert(char * name,void * loc,int start_bit_number,uint8 mask)627 Lpanel::bindLight8invert(char *name, void *loc, int start_bit_number, uint8 mask)
628 {
629 char **namelist;
630 int num_names;
631 int i, status = 1;
632 int bitnum, bit_inc, bit_inv;
633 lpLight *light;
634
635 num_names = xpand(name, &namelist);
636
637 bitnum = abs(start_bit_number);
638 if(start_bit_number > 0) bit_inc = 1;
639 else bit_inc = -1;
640
641 for(i=0;i<num_names;i++)
642 {
643 if(bitnum <=0)
644 {
645 fprintf(stderr, "bindLight8invert: light %s bad bitnum %d\n", namelist[i], bitnum);
646 bitnum = 1;
647 }
648
649 light = findLightByName(namelist[i]);
650
651 if(light)
652 {
653 if( mask & (0x1 << (bitnum-1)))
654 light->bindData8invert( (uint8 *) loc);
655 else
656 light->bindData8( (uint8 *) loc);
657 light->setBitNumber(bitnum-1);
658 }
659 else
660 {
661 if(!ignore_bind_errors) fprintf(stderr, "bindLight8invert: light %s not found\n", namelist[i]);
662 status = 0;
663 }
664 if(namelist[i]) delete namelist[i];
665 bitnum += bit_inc;
666 }
667
668 return status;
669 }
670
671 int
bindLight16(char * name,void * loc,int start_bit_number)672 Lpanel::bindLight16(char *name, void *loc, int start_bit_number)
673 {
674 char **namelist;
675 int num_names;
676 int i, status = 1;
677 int bitnum, bit_inc;
678 lpLight *light;
679
680 num_names = xpand(name, &namelist);
681
682 bitnum = abs(start_bit_number);
683 if(start_bit_number > 0) bit_inc = 1;
684 else bit_inc = -1;
685
686 for(i=0;i<num_names;i++)
687 {
688 if(bitnum <=0)
689 {
690 fprintf(stderr, "bindLight16: light %s bad bitnum %d\n", namelist[i], bitnum);
691 bitnum = 1;
692 }
693
694 light = findLightByName(namelist[i]);
695
696 if(light)
697 {
698 light->bindData16( (uint16 *) loc);
699 light->setBitNumber(bitnum-1);
700 }
701 else
702 {
703 if(!ignore_bind_errors) fprintf(stderr, "bindLight16: light %s not found\n", namelist[i]);
704 status = 0;
705 }
706 if(namelist[i]) delete namelist[i];
707 bitnum += bit_inc;
708 }
709
710 return status;
711 }
712
713
714 // bindLightfv
715 // bind to an array of float values
716 // subsequent sampling will use the bit number as an index into the array of float values
717 // instead of a single bit
718
719 int
bindLightfv(char * name,void * loc)720 Lpanel::bindLightfv(char *name, void *loc)
721 {
722 char **namelist;
723 int num_names;
724 int i, status = 1;
725 int bitnum, bit_inc;
726 lpLight *light;
727
728 num_names = xpand(name, &namelist);
729
730 for(i=0;i<num_names;i++)
731 {
732
733 light = findLightByName(namelist[i]);
734
735 if(light)
736 {
737 light->bindDatafv( (float *) loc);
738 light->setBitNumber(i);
739 }
740 else
741 {
742 if(!ignore_bind_errors) fprintf(stderr, "bindLightfv: light %s not found\n", namelist[i]);
743 status = 0;
744 }
745 if(namelist[i]) delete namelist[i];
746 bitnum += bit_inc;
747 }
748
749 return status;
750 }
751
752 int
bindLight16invert(char * name,void * loc,int start_bit_number,uint16 mask)753 Lpanel::bindLight16invert(char *name, void *loc, int start_bit_number, uint16 mask)
754 {
755 char **namelist;
756 int num_names;
757 int i, status = 1;
758 int bitnum, bit_inc, bit_inv;
759 lpLight *light;
760
761 num_names = xpand(name, &namelist);
762
763 bitnum = abs(start_bit_number);
764 if(start_bit_number > 0) bit_inc = 1;
765 else bit_inc = -1;
766
767 for(i=0;i<num_names;i++)
768 {
769 if(bitnum <=0)
770 {
771 fprintf(stderr, "bindLight16invert: light %s bad bitnum %d\n", namelist[i], bitnum);
772 bitnum = 1;
773 }
774
775 light = findLightByName(namelist[i]);
776
777 if(light)
778 {
779 if( mask & (0x1 << (bitnum-1)))
780 light->bindData16invert( (uint16 *) loc);
781 else
782 light->bindData16( (uint16 *) loc);
783 light->setBitNumber(bitnum-1);
784 }
785 else
786 {
787 if(!ignore_bind_errors) fprintf(stderr, "bindLight16invert: light %s not found\n", namelist[i]);
788 status = 0;
789 }
790 if(namelist[i]) delete namelist[i];
791 bitnum += bit_inc;
792 }
793
794 return status;
795 }
796
797
798
799 int
bindLight32(char * name,void * loc,int start_bit_number)800 Lpanel::bindLight32(char *name, void *loc, int start_bit_number)
801 {
802 char **namelist;
803 int num_names;
804 int i, status = 1;
805 int bitnum, bit_inc;
806 lpLight *light;
807
808 num_names = xpand(name, &namelist);
809
810 bitnum = abs(start_bit_number);
811 if(start_bit_number > 0) bit_inc = 1;
812 else bit_inc = -1;
813
814 for(i=0;i<num_names;i++)
815 {
816 if(bitnum <=0)
817 {
818 fprintf(stderr, "bindLight16: light %s bad bitnum %d\n", namelist[i], bitnum);
819 bitnum = 1;
820 }
821
822 light = findLightByName(namelist[i]);
823
824 if(light)
825 {
826 light->bindData32( (uint32 *) loc);
827 light->setBitNumber(bitnum-1);
828 }
829 else
830 {
831 if(!ignore_bind_errors) fprintf(stderr, "bindLight32: light %s not found\n", namelist[i]);
832 status = 0;
833 }
834 if(namelist[i]) delete namelist[i];
835 bitnum += bit_inc;
836 }
837
838 return status;
839 }
840
841 int
bindLight32invert(char * name,void * loc,int start_bit_number,uint32 mask)842 Lpanel::bindLight32invert(char *name, void *loc, int start_bit_number, uint32 mask)
843 {
844 char **namelist;
845 int num_names;
846 int i, status = 1;
847 int bitnum, bit_inc, bit_inv;
848 lpLight *light;
849
850 num_names = xpand(name, &namelist);
851
852 bitnum = abs(start_bit_number);
853 if(start_bit_number > 0) bit_inc = 1;
854 else bit_inc = -1;
855
856 for(i=0;i<num_names;i++)
857 {
858 if(bitnum <=0)
859 {
860 fprintf(stderr, "bindLight32invert: light %s bad bitnum %d\n", namelist[i], bitnum);
861 bitnum = 1;
862 }
863
864 light = findLightByName(namelist[i]);
865
866 if(light)
867 {
868 if( mask & (0x1 << (bitnum-1)))
869 light->bindData32invert( (uint32 *) loc);
870 else
871 light->bindData32( (uint32 *) loc);
872 light->setBitNumber(bitnum-1);
873 }
874 else
875 {
876 if(!ignore_bind_errors) fprintf(stderr, "bindLight32invert: light %s not found\n", namelist[i]);
877 status = 0;
878 }
879 if(namelist[i]) delete namelist[i];
880 bitnum += bit_inc;
881 }
882
883 return status;
884 }
885
886
887 int
bindLight64(char * name,void * loc,int start_bit_number)888 Lpanel::bindLight64(char *name, void *loc, int start_bit_number)
889 {
890 char **namelist;
891 int num_names;
892 int i, status = 1;
893 int bitnum, bit_inc;
894 lpLight *light;
895
896 num_names = xpand(name, &namelist);
897
898 bitnum = abs(start_bit_number);
899 if(start_bit_number > 0) bit_inc = 1;
900 else bit_inc = -1;
901
902 for(i=0;i<num_names;i++)
903 {
904 if(bitnum <=0)
905 {
906 fprintf(stderr, "bindLight64: light %s bad bitnum %d\n", namelist[i], bitnum);
907 bitnum = 1;
908 }
909
910 light = findLightByName(namelist[i]);
911
912 if(light)
913 {
914 light->bindData64( (uint64 *) loc);
915 light->setBitNumber(bitnum-1);
916 }
917 else
918 {
919 if(!ignore_bind_errors) fprintf(stderr, "bindLight64: light %s not found\n", namelist[i]);
920 status = 0;
921 }
922 if(namelist[i]) delete namelist[i];
923 bitnum += bit_inc;
924 }
925
926 return status;
927 }
928
929 int
bindLight64invert(char * name,void * loc,int start_bit_number,uint64 mask)930 Lpanel::bindLight64invert(char *name, void *loc, int start_bit_number, uint64 mask)
931 {
932 char **namelist;
933 int num_names;
934 int i, status = 1;
935 int bitnum, bit_inc, bit_inv;
936 lpLight *light;
937
938 num_names = xpand(name, &namelist);
939
940 bitnum = abs(start_bit_number);
941 if(start_bit_number > 0) bit_inc = 1;
942 else bit_inc = -1;
943
944 for(i=0;i<num_names;i++)
945 {
946 if(bitnum <=0)
947 {
948 fprintf(stderr, "bindLight64invert: light %s bad bitnum %d\n", namelist[i], bitnum);
949 bitnum = 1;
950 }
951
952 light = findLightByName(namelist[i]);
953
954 if(light)
955 {
956 if( mask & (0x1 << (bitnum-1)))
957 light->bindData64invert( (uint64 *) loc);
958 else
959 light->bindData64( (uint64 *) loc);
960 light->setBitNumber(bitnum-1);
961 }
962 else
963 {
964 if(!ignore_bind_errors) fprintf(stderr, "bindLight64invert: light %s not found\n", namelist[i]);
965 status = 0;
966 }
967 if(namelist[i]) delete namelist[i];
968 bitnum += bit_inc;
969 }
970
971 return status;
972 }
973
974 void
bindRunFlag(uint8 * addr)975 Lpanel::bindRunFlag(uint8 *addr)
976 {
977 int i;
978
979 runflag = (uint8 *) addr;
980
981 for(i=0;i<num_lights;i++)
982 lights[i]->bindRunFlag((uint8 *)addr);
983 }
984
985 void
bindSimclock(uint64 * addr)986 Lpanel::bindSimclock(uint64 *addr)
987 {
988 int i;
989 simclock = (uint64 *) addr;
990
991 for(i=0;i<num_lights;i++)
992 lights[i]->bindSimclock((uint64 *) addr, &clock_warp);
993
994 }
995
996
997 void
draw(void)998 Lpanel::draw(void)
999 { int i;
1000
1001 if(view.redo_projections)
1002 {
1003 setProjection(0);
1004 setModelview(0);
1005 view.redo_projections = 0;
1006 }
1007 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1008
1009 // draw graphics objects
1010
1011 //glEnable(GL_LIGHTING);
1012
1013 for(i=0;i<num_objects;i++)
1014 {
1015 if(objects[i]->is_alpha) continue;
1016
1017 if(objects[i]->texture_num)
1018 {
1019 textures.bindTexture(objects[i]->texture_num);
1020 }
1021 if(objects[i]->have_normals) glEnable(GL_LIGHTING);
1022 objects[i]->draw();
1023 }
1024
1025 // draw lights
1026
1027 glDisable(GL_TEXTURE_2D);
1028 glDisable(GL_LIGHTING);
1029 glEnable(GL_POLYGON_OFFSET_FILL);
1030 glPolygonOffset(0.,-10.);
1031
1032 for(i=0;i<num_lights;i++)
1033 lights[i]->draw();
1034
1035 // draw switches
1036
1037 for(i=0;i<num_switches;i++)
1038 switches[i]->drawFunc(this, switches[i]);
1039
1040 if(alpha_objects)
1041 {
1042 // glDisable(GL_DEPTH_TEST);
1043 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1044 glEnable(GL_BLEND);
1045
1046 for(i=0;i<num_alpha_objects;i++)
1047 {
1048 if(alpha_objects[i]->texture_num)
1049 {
1050 textures.bindTexture(alpha_objects[i]->texture_num);
1051 }
1052 if(alpha_objects[i]->have_normals) glEnable(GL_LIGHTING);
1053 alpha_objects[i]->draw();
1054 }
1055 // glEnable(GL_DEPTH_TEST);
1056 }
1057
1058 glDisable(GL_TEXTURE_2D);
1059 glDisable(GL_POLYGON_OFFSET_FILL);
1060 glEnable(GL_POLYGON_OFFSET_LINE);
1061 if(do_cursor)
1062 {
1063 glEnable(GL_POLYGON_OFFSET_LINE);
1064 draw_cursor();
1065 glDisable(GL_POLYGON_OFFSET_LINE);
1066 }
1067 if(do_stats) draw_stats();
1068 #if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
1069 SwapBuffers(hDC);
1070 //UpdateWindow(hWnd);
1071 #else
1072 glXSwapBuffers(dpy, window);
1073 #endif
1074 }
1075
1076
1077 void
growLights(void)1078 Lpanel::growLights(void)
1079 {
1080 int i;
1081 lpLight **new_lights;
1082
1083 new_lights = new lpLight * [num_lights + 8];
1084 for(i=0;i<num_lights;i++)
1085 new_lights[i] = lights[i];
1086
1087 max_lights += 8;
1088 delete lights;
1089 lights = new_lights;
1090 }
1091
1092 void
growSwitches(void)1093 Lpanel::growSwitches(void)
1094 {
1095 int i;
1096 lpSwitch **new_switches;
1097
1098 new_switches = new lpSwitch* [num_switches + 1];
1099 for(i=0;i<num_switches;i++)
1100 new_switches[i] = switches[i];
1101
1102 max_switches += 1;
1103 delete switches;
1104 switches = new_switches;
1105 }
1106
1107 int
pick(int button,int state,int x,int y)1108 Lpanel::pick(int button, int state, int x, int y)
1109 {
1110 GLuint namebuf[500], *ptr;
1111 int i,
1112 num_picked = 0,
1113 switch_dir;
1114 uint32 switch_num;
1115
1116 if(state == 0)
1117 {
1118 if( mom_switch_pressed )
1119 mom_switch_pressed->action(2);
1120 return(num_picked);
1121 }
1122
1123
1124 namebuf[0]=0;
1125 glSelectBuffer(500,&namebuf[0]);
1126 glRenderMode(GL_SELECT);
1127 glInitNames();
1128 glPushName(0);
1129 glGetIntegerv (GL_VIEWPORT, viewport);
1130 glMatrixMode (GL_PROJECTION);
1131 glPushMatrix ();
1132 glLoadIdentity ();
1133
1134 gluPickMatrix ((GLdouble) x, (GLdouble) (window_ysize - y), 1.0, 1.0, viewport);
1135 doPickProjection();
1136 glMatrixMode (GL_MODELVIEW);
1137 glPushMatrix();
1138 doPickModelview();
1139
1140 // draw switches
1141
1142 for(i=0;i<num_switches;i++)
1143 switches[i]->drawForPick();
1144
1145 num_picked = glRenderMode(GL_RENDER);
1146
1147 if( num_picked)
1148 {
1149 uint32 n;
1150 ptr = (GLuint *) namebuf;
1151 n = ptr[3];
1152
1153 switch_num = n & LP_SW_PICK_IDMASK; // decode the switch number
1154 switch_dir = ((n & LP_SW_PICK_UP_BIT) != 0);
1155 //printf("pick: switch_num=%d dir=%d\n", switch_num, switch_dir);
1156
1157 switches[switch_num]->action(switch_dir);
1158 }
1159
1160 glPopMatrix();
1161 glMatrixMode (GL_PROJECTION);
1162 glPopMatrix();
1163 glMatrixMode (GL_MODELVIEW);
1164 glPopMatrix();
1165 glRenderMode(GL_RENDER);
1166
1167 return(num_picked);
1168
1169 }
1170
1171
1172 int
readConfig(const char * _fname)1173 Lpanel::readConfig(const char *_fname)
1174 {
1175 FILE *fd;
1176 int i,n;
1177
1178 #define BUFSIZE 256
1179 #define TOKENSIZE 80
1180
1181 char buffer[BUFSIZE], token[TOKENSIZE];
1182 int pos, lineno=0, bailout=0;
1183 lp_obj_parm_t *obj;
1184
1185 char *fname;
1186
1187 fname = new char[strlen(config_root_path) + strlen(_fname) + 1];
1188 strcpy(fname, config_root_path);
1189 strcat(fname, "/");
1190 strcat(fname, _fname);
1191
1192 if( (fd=fopen(fname,"r")) == 0)
1193 {
1194 fprintf(stderr,"readFile: could not open file %s\n",fname);
1195 return 0;
1196 }
1197
1198 lp_init_materials();
1199
1200 while(!feof(fd) && !bailout)
1201 {
1202 lineno++;
1203 if(!freadlin(fd,buffer,BUFSIZE)) continue;
1204 pos = 0;
1205 if(!gtoken(buffer,token,TOKENSIZE,&pos)) continue; // blank line
1206 if(token[0] == '#') continue; // comment
1207
1208 if(!strcmp(token, "color")) // color
1209 { int n;
1210
1211 if(!curr_object)
1212 { printf("Error on line %d of config file %s\n",lineno, fname);
1213 printf("color defined outside of an object\n");
1214 bailout = 1;
1215 }
1216 else
1217 {
1218 n = sscanf(&buffer[pos],"%f %f %f",
1219 &curr_object->color[0],
1220 &curr_object->color[1],
1221 &curr_object->color[2]);
1222
1223 if(n < 3)
1224 { printf("Error on line %d of config file %s\n",lineno, fname);
1225 printf("color must have 3 (r g b) values in the range of 0.0 - 1.0.\n");
1226 bailout = 1;
1227 }
1228
1229 }
1230 }
1231 else if(!strcmp(token, "zbuffer"))
1232 {
1233 view.do_depthtest = 1;
1234 }
1235 else
1236 if(!strcmp(token, "envmap")) // environment mapped reflection
1237 {
1238 if(!curr_object)
1239 { printf("Error on line %d of config file %s\n",lineno, fname);
1240 printf("envmap defined outside of an object\n");
1241 bailout = 1;
1242 }
1243 else
1244 {
1245 envmap_detected = 1;
1246 curr_object->envmapped = 1;
1247 }
1248 }
1249 else if(!strcmp(token, "instance"))
1250 {
1251 char s[100];
1252
1253 if(!curr_object)
1254 { printf("Error on line %d of config file %s\n",lineno, fname);
1255 printf("instance defined outside of an object\n");
1256 bailout = 1;
1257 }
1258 else
1259 {
1260 if(!gtoken(buffer,s,100,&pos))
1261 { printf("Error on line %d of config file %s\n",lineno, fname);
1262 printf("instance with no object name.\n");
1263 bailout = 1;
1264 }
1265 else
1266 curr_object->setInstanceName(s);
1267 }
1268 }
1269 else if(!strcmp(token, "light"))
1270 {
1271 obj = new lp_obj_parm_t;
1272 obj->type = LP_LED;
1273 obj->subtype = LP_LED_3D;
1274 obj->group = -1; // does not belong to group
1275 obj->pos[0] = 0.;
1276 obj->pos[1] = 0.;
1277 obj->pos[2] = 0.;
1278 obj->color[0] = lightcolor[0];
1279 obj->color[1] = lightcolor[1];
1280 obj->color[2] = lightcolor[2];
1281 obj->scale[0] = lightsize[0];
1282 obj->scale[1] = lightsize[1];
1283 obj->scale[2] = lightsize[2];
1284
1285 gtoken(buffer,token,TOKENSIZE,&pos); // get name
1286
1287 n = addLight(token, obj, &buffer[pos]);
1288 if(n >= 0)
1289 { bailout = 1;
1290 n += pos;
1291 printf("Error on line %d of config file %s\n",lineno, fname);
1292
1293 printf("%s\n",buffer);
1294 for(i=0;i<n;i++)
1295 putchar(' ');
1296 printf("^\n");
1297 }
1298
1299 }
1300 else if(!strcmp(token, "lightcolor")) // default light size
1301 { int n;
1302
1303 n = sscanf(&buffer[pos],"%f %f %f",
1304 &lightcolor[0],
1305 &lightcolor[1],
1306 &lightcolor[2]);
1307
1308 if(n < 3)
1309 { printf("Error on line %d of config file %s\n",lineno, fname);
1310 printf("lightcolor must have 3 (r g b) values in the range of 0.0 - 1.0.\n");
1311 bailout = 1;
1312 }
1313
1314 }
1315 else if(!strcmp(token, "lightsize")) // default light size
1316 { int n;
1317
1318 n = sscanf(&buffer[pos],"%f %f %f",
1319 &lightsize[0],
1320 &lightsize[1],
1321 &lightsize[2]);
1322
1323 if(n < 1)
1324 { printf("Error on line %d of config file %s\n",lineno, fname);
1325 printf("lightsize must have 1, 2, or 3 values (x y z).\n");
1326 bailout = 1;
1327 }
1328
1329 if(n == 1) lightsize[1] = lightsize[2] = lightsize[0];
1330 else if(n == 2) lightsize[2] = lightsize[0];
1331
1332 }
1333 else if(!strcmp(token, "line"))
1334 {
1335 if(!curr_object)
1336 { printf("Error on line %d of config file %s\n",lineno, fname);
1337 printf("line defined outside of an object\n");
1338 bailout = 1;
1339 }
1340 else
1341 {
1342 if(!(curr_element = curr_object->addElement(curr_object)))
1343 { printf("could not allocate memory for line.\n");
1344 bailout = 1;
1345 }
1346 else
1347 { curr_element->type = LP_LINE;
1348 curr_element->setTextureManager(&textures);
1349 }
1350 }
1351 }
1352 else if(!strcmp(token, "material")) // material reference or definition
1353 { int n, matnum;
1354 float Ar, Ag, Ab, Aa, // Ambient rgba
1355 Dr, Dg, Db, Da, // Diffuse rgba
1356 Sr, Sg, Sb, Sa, // Specular rgba
1357 shine, // shinyness
1358 Er, Eg, Eb, Ea; // emission rgba
1359
1360 if(curr_object) // material reference
1361 {
1362 n = sscanf(&buffer[pos],"%d",&curr_object->material);
1363
1364 if(n != 1)
1365 { printf("Error on line %d of config file %s\n",lineno, fname);
1366 printf("material within an object definition must have one integer value.\n");
1367 bailout = 1;
1368 }
1369 curr_object->is_alpha = lp_is_material_alpha(curr_object->material);
1370 }
1371 else // material definition
1372 {
1373
1374 n = sscanf(&buffer[pos],"%d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
1375 &matnum, &Ar,&Ag,&Ab,&Aa, &Dr,&Dg,&Db,&Da, &Sr,&Sg,&Sb,&Sa, &shine, &Er,&Eg,&Eb,&Ea);
1376
1377 if(n < 18)
1378 { printf("Error on line %d of config file %s\n",lineno, fname);
1379 printf("material definition must have 18 values.\n");
1380 bailout = 1;
1381 }
1382 else
1383 lp_set_material_params(matnum, Ar,Ag,Ab,Aa, Dr,Dg,Db,Da, Sr,Sg,Sb,Sa, shine, Er,Eg,Eb,Ea);
1384
1385 }
1386 }
1387 else if(!strcmp(token, "message")) // message
1388 {
1389 printf("%s\n", &buffer[pos]);
1390 }
1391 else if(!strcmp(token, "n")) // vertex normal vector
1392 { int n;
1393
1394 if(!curr_element || !curr_object)
1395 { printf("Error on line %d of config file %s\n",lineno, fname);
1396 printf("normal defined outside of a polygon or line\n");
1397 bailout = 1;
1398 }
1399 else
1400 {
1401 if(!curr_vertex)
1402 { printf("Error on line %d of config file %s\n",lineno, fname);
1403 printf("normal defined before a vertex definition\n");
1404 bailout = 1;
1405 }
1406
1407 n = sscanf(&buffer[pos],"%f %f %f",
1408 &curr_vertex->norm[0],
1409 &curr_vertex->norm[1],
1410 &curr_vertex->norm[2]);
1411
1412 if(n < 3)
1413 { printf("Error on line %d of config file %s\n",lineno, fname);
1414 printf("normal must have 3 values.\n");
1415 bailout = 1;
1416 }
1417 else
1418 curr_object->have_normals = 1;
1419 }
1420 }
1421 else if(!strcmp(token, "object"))
1422 {
1423 curr_object = addObject();
1424 curr_object->setTextureManager(&textures);
1425 if( gtoken(buffer,token,TOKENSIZE,&pos))
1426 curr_object->setName(token);
1427 curr_element = NULL;
1428 curr_vertex = NULL;
1429 }
1430 else if(!strcmp(token, "perspective"))
1431 {
1432 view.projection = LP_PERSPECTIVE;
1433 }
1434 else if(!strcmp(token, "polygon"))
1435 {
1436 if(!curr_object)
1437 { printf("Error on line %d of config file %s\n",lineno, fname);
1438 printf("polygon defined outside of an object\n");
1439 bailout = 1;
1440 }
1441 else
1442 {
1443 if(!(curr_element = curr_object->addElement(curr_object)))
1444 { printf("could not allocate memory for polygon.\n");
1445 bailout = 1;
1446 }
1447 else
1448 { curr_element->type = LP_POLYGON;
1449 curr_element->setTextureManager(&textures);
1450 }
1451 }
1452 }
1453 else if(!strcmp(token, "referenced")) // referenced
1454 {
1455 if(!curr_object)
1456 { printf("Error on line %d of config file %s\n",lineno, fname);
1457 printf("color defined outside of an object\n");
1458 bailout = 1;
1459 }
1460 else
1461 curr_object->referenced = 1;
1462 }
1463 else if(!strcmp(token, "rotate")) // rotate hpr
1464 { int n;
1465
1466 if(!curr_object)
1467 {
1468 n = sscanf(&buffer[pos],"%f %f",
1469 &view.rot[0],
1470 &view.rot[1]);
1471
1472 if(n < 2)
1473 { printf("Error on line %d of config file %s\n",lineno, fname);
1474 printf("scene rotate must have 2 values.\n");
1475 bailout = 1;
1476 }
1477
1478 }
1479 else
1480 {
1481 n = sscanf(&buffer[pos],"%f %f %f",
1482 &curr_object->rotate[0],
1483 &curr_object->rotate[1],
1484 &curr_object->rotate[2]);
1485
1486 if(n < 3)
1487 { printf("Error on line %d of config file %s\n",lineno, fname);
1488 printf("object rotate must have 3 values.\n");
1489 bailout = 1;
1490 }
1491 }
1492 }
1493 else if(!strcmp(token, "switch"))
1494 {
1495 obj = new lp_obj_parm_t;
1496 obj->group = -1; // does not belong to group
1497 obj->pos[0] = 0.;
1498 obj->pos[1] = 0.;
1499 obj->pos[2] = 0.;
1500 obj->color[0] = 1.;
1501 obj->color[1] = 0.;
1502 obj->color[2] = 0.;
1503 obj->scale[0] = 0.1875;
1504 obj->scale[1] = 0.1875;
1505 obj->scale[2] = 0.1875;
1506
1507 gtoken(buffer,token,TOKENSIZE,&pos); // get name
1508
1509 n = addSwitch(token, obj, &buffer[pos], this);
1510 if(n >= 0)
1511 { bailout = 1;
1512 n += pos;
1513 printf("Error on line %d of config file %s\n",lineno, fname);
1514
1515 printf("%s\n",buffer);
1516 for(i=0;i<n;i++)
1517 putchar(' ');
1518 printf("^\n");
1519 }
1520
1521 }
1522 else if(!strcmp(token, "t")) // texture coordinate
1523 { int n;
1524
1525 if(!curr_element || !curr_object)
1526 { printf("Error on line %d of config file %s\n",lineno, fname);
1527 printf("texture coord defined outside of a polygon or line\n");
1528 bailout = 1;
1529 break;
1530 }
1531 else
1532 {
1533 if(!curr_vertex)
1534 { printf("Error on line %d of config file %s\n",lineno, fname);
1535 printf("texture coord defined before a vertex coordinate was defined.\n");
1536 bailout = 1;
1537 break;
1538 }
1539
1540 n = sscanf(&buffer[pos],"%f %f",
1541 &curr_vertex->st[0],
1542 &curr_vertex->st[1]);
1543
1544 if(n < 2)
1545 { printf("Error on line %d of config file %s\n",lineno, fname);
1546 printf("texture coordinate must have 2 coordinates (e.g. t <s> <t>).\n");
1547 bailout = 1;
1548 break;
1549 }
1550 curr_element->have_tcoords = 1;
1551 }
1552 }
1553 else if(!strcmp(token, "texture")) // texture
1554 {
1555 char *texture_path = NULL;
1556 int len;
1557
1558 if(!curr_object)
1559 { printf("Error on line %d of config file %s\n",lineno, fname);
1560 printf("texture defined outside of an object.\n");
1561 bailout = 1;
1562 break;
1563 }
1564
1565 if(!gtoken(buffer,token,TOKENSIZE,&pos))
1566 { printf("Error on line %d of config file %s\n",lineno, fname);
1567 printf("texture with no path to jpeg file defined.\n");
1568 bailout = 1;
1569 break;
1570 }
1571
1572 len = strlen(config_root_path) + strlen(token) + 1;
1573
1574 texture_path = new char[len+1];
1575 strcpy(texture_path, config_root_path);
1576 strcat(texture_path, "/");
1577 strcat(texture_path, token);
1578 texture_path[len] = 0;
1579
1580
1581 if( !(curr_object->texture_num = textures.addTexture(texture_path)))
1582 { printf("Error on line %d of config file %s\n",lineno, texture_path);
1583 printf("could not load texture '%s'.\n", texture_path);
1584 bailout = 1;
1585 break;
1586 }
1587
1588 delete texture_path;
1589
1590 }
1591 else if(!strcmp(token, "texture_scale"))
1592 { int n;
1593
1594 if(!curr_object)
1595 { printf("Error on line %d of config file %s\n",lineno, fname);
1596 printf("texture_scale defined outside of an object\n");
1597 bailout = 1;
1598 }
1599 else
1600 {
1601 n = sscanf(&buffer[pos],"%f %f",
1602 &curr_object->texture_scale[0],
1603 &curr_object->texture_scale[1]);
1604
1605 if(n < 2)
1606 { printf("Error on line %d of config file %s\n",lineno, fname);
1607 printf("texture_scale must have 2 (x y) values.\n");
1608 bailout = 1;
1609 }
1610
1611 }
1612 }
1613 else if(!strcmp(token, "texture_translate"))
1614 { int n;
1615
1616 if(!curr_object)
1617 { printf("Error on line %d of config file %s\n",lineno, fname);
1618 printf("texture_translate defined outside of an object\n");
1619 bailout = 1;
1620 }
1621 else
1622 {
1623 n = sscanf(&buffer[pos],"%f %f",
1624 &curr_object->texture_translate[0],
1625 &curr_object->texture_translate[1]);
1626
1627 if(n < 2)
1628 { printf("Error on line %d of config file %s\n",lineno, fname);
1629 printf("texture_translate must have 2 (x y) values.\n");
1630 bailout = 1;
1631 }
1632
1633 }
1634 }
1635 else if(!strcmp(token, "translate"))
1636 { int n;
1637
1638 if(!curr_object)
1639 {
1640 n = sscanf(&buffer[pos],"%f %f %f",
1641 &view.pan[0],
1642 &view.pan[1],
1643 &view.pan[2]);
1644
1645 if(n < 3)
1646 { printf("Error on line %d of config file %s\n",lineno, fname);
1647 printf("scene translate must have 3 values.\n");
1648 bailout = 1;
1649 }
1650
1651 }
1652 }
1653 else if(!strcmp(token, "tristrip"))
1654 {
1655 if(!curr_object)
1656 { printf("Error on line %d of config file %s\n",lineno, fname);
1657 printf("tristrip defined outside of an object\n");
1658 bailout = 1;
1659 }
1660 else
1661 {
1662 if(!(curr_element = curr_object->addElement(curr_object)))
1663 { printf("could not allocate memory for tristrip.\n");
1664 bailout = 1;
1665 }
1666 else
1667 { curr_element->type = LP_TRISTRIP;
1668 curr_element->setTextureManager(&textures);
1669 }
1670 }
1671 }
1672 else if(!strcmp(token, "v")) // vertex
1673 { int n;
1674
1675 if(!curr_element || !curr_object)
1676 { printf("Error on line %d of config file %s\n",lineno, fname);
1677 printf("vertex defined outside of a polygon or line\n");
1678 bailout = 1;
1679 }
1680 else
1681 {
1682 if(!(curr_vertex = curr_element->addVertex()))
1683 { printf("could not allocate memory for vertex.\n");
1684 bailout = 1;
1685 }
1686
1687 n = sscanf(&buffer[pos],"%f %f %f",
1688 &curr_vertex->xyz[0],
1689 &curr_vertex->xyz[1],
1690 &curr_vertex->xyz[2]);
1691
1692 if(n < 2)
1693 { printf("Error on line %d of config file %s\n",lineno, fname);
1694 printf("vertex must have 2 or 3 coordinates.\n");
1695 bailout = 1;
1696 }
1697
1698 }
1699 }
1700 else
1701 {
1702 printf("Error: unknown statement on line %d of config file %s\n",lineno, fname);
1703 bailout = 1;
1704
1705 }
1706 } // end while(!feof)
1707
1708 delete fname;
1709 fclose(fd);
1710
1711 if(!bailout)
1712 {
1713 genGraphicsData();
1714 resolveObjectInstances();
1715
1716 for(i=0;i<num_lights;i++)
1717 lights[i]->setupData();
1718
1719 for(i=0;i<num_switches;i++)
1720 switches[i]->setupData(i);
1721 }
1722 return(!bailout);
1723 } // end readConfig()
1724
1725 lpLight *
findLightByName(char * name)1726 Lpanel::findLightByName(char *name)
1727 { int i;
1728
1729 for(i=0;i<num_lights;i++)
1730 { if( !strcmp(lights[i]->name, name))
1731 return lights[i];
1732 }
1733
1734 return 0;
1735 }
1736
1737 // parse var=v,v,v
1738
1739 enum parse_states { GET_VAR, GET_VAL };
1740
1741
1742
1743 void
printLights(void)1744 Lpanel::printLights(void)
1745 { int i;
1746
1747 printf("lights:\n");
1748 for(i=0;i<num_lights;i++)
1749 lights[i]->print();
1750
1751 }
1752
1753 void
resolveObjectInstances(void)1754 Lpanel::resolveObjectInstances(void)
1755 {
1756 int i,j;
1757 lpObject *p;
1758
1759 for(i=0;i<num_objects;i++)
1760 {
1761 if(objects[i]->instance_name)
1762 { if( (p = findObjectByName(objects[i]->instance_name)))
1763 objects[i]->instance_object = p;
1764 else
1765 fprintf(stderr,"Error: object %s instances object %s which cannot be found.\n",
1766 objects[i]->name, objects[i]->instance_name);
1767 }
1768 }
1769
1770 for(i=0;i<num_objects;i++)
1771 {
1772 p = objects[i]->instance_object;
1773 while(p)
1774 {
1775 for(j=0;j<3;j++)
1776 {
1777 objects[i]->bbox.xyz_min[j] = min(objects[i]->bbox.xyz_min[j], p->bbox.xyz_min[j]);
1778 objects[i]->bbox.xyz_max[j] = max(objects[i]->bbox.xyz_max[j], p->bbox.xyz_max[j]);
1779 }
1780 p = p->instance_object;
1781 }
1782
1783 }
1784 }
1785
1786 void
sampleData(void)1787 Lpanel::sampleData(void)
1788 { int i;
1789
1790 // mutex lock
1791 pthread_mutex_lock(&data_sample_lock);
1792
1793 if( *simclock < old_clock )
1794 {
1795 fprintf(stderr,"libfrontpanel: Warning clock went backwards (current=%lld previous=%lld.\n", *simclock, old_clock);
1796
1797 }
1798 old_clock = *simclock;
1799
1800 for(i=0;i<num_lights;i++)
1801 lights[i]->sampleData();
1802 // mutex unlock
1803 pthread_mutex_unlock(&data_sample_lock);
1804
1805 }
1806
1807 void
sampleDataWarp(int clockwarp)1808 Lpanel::sampleDataWarp(int clockwarp)
1809 { int i;
1810
1811 clock_warp = clockwarp;
1812
1813 for(i=0;i<num_lights;i++)
1814 lights[i]->sampleData();
1815
1816 clock_warp = 0;
1817 }
1818
1819 void
sampleLightGroup(int groupnum,int clockval)1820 Lpanel::sampleLightGroup(int groupnum, int clockval)
1821 { int i;
1822
1823 if(groupnum < 0 || groupnum >= LP_MAX_LIGHT_GROUPS)
1824 {
1825 fprintf(stderr, "sampleLightGroup: groupnum (%d) must be in the range of (0-%d). \n",
1826 groupnum, LP_MAX_LIGHT_GROUPS-1);
1827 }
1828
1829 clock_warp = clockval;
1830
1831 for(i=0;i<light_groups[groupnum].num_items;i++)
1832 lights[ light_groups[groupnum].list[i] ]->sampleData();
1833
1834 clock_warp = 0;
1835 }
1836
1837 void
setConfigRootPath(const char * path)1838 Lpanel::setConfigRootPath(const char *path)
1839 {
1840 if(config_root_path) delete config_root_path;
1841 config_root_path = new char [strlen(path) + 1];
1842 strcpy(config_root_path,path);
1843
1844 }
1845
1846 // -------------
1847 // lpLight class
1848 // -------------
1849
lpLight(void)1850 lpLight::lpLight(void)
1851 {
1852 bindtype = LBINDTYPE_BIT; // default to bind to bit
1853 parms = NULL;
1854 name = NULL;
1855 obj_refname = NULL;
1856 obj_ref = NULL;
1857 sampleDataFunc = sampleData8_error;
1858 drawFunc = drawLightGraphics;
1859 t1 = t2 = on_time = 1;
1860 old_clock = 0;
1861 dirty = 0;
1862 state = 0;
1863 old_state = 0;
1864 intensity = 1.;
1865
1866 smoothing = 0; // no intensity smoothing for bindtype of FLOATV
1867 intense_curr_idx = 0;
1868 intense_samples[0] = 0.;
1869 intense_samples[1] = 0.;
1870 color[0] = 0.2;
1871 color[1] = 0.;
1872 color[2] = 0.;
1873 default_runflag = 0;
1874 runflag = &default_runflag;
1875 }
1876
~lpLight(void)1877 lpLight::~lpLight(void)
1878 {
1879 if(name) delete name;
1880 if(obj_refname) delete obj_refname;
1881 if(parms) delete parms;
1882 }
1883
1884 void
bindRunFlag(uint8 * addr)1885 lpLight::bindRunFlag(uint8 *addr)
1886 {
1887 runflag = (uint8 *) addr;
1888 }
1889
1890 void
bindSimclock(uint64 * addr,int * clockwarp)1891 lpLight::bindSimclock(uint64 *addr, int *clockwarp)
1892 {
1893
1894 simclock = addr;
1895 clock_warp = clockwarp;
1896 }
1897
1898
1899 void
draw(void)1900 lpLight::draw(void)
1901 {
1902 int i;
1903 float *fp;
1904
1905 switch(bindtype)
1906 {
1907
1908 case LBINDTYPE_BIT:
1909
1910 if(*runflag)
1911 { if(dirty) calcIntensity();
1912 }
1913 else
1914 {
1915 for(i=0;i<3;i++)
1916 { color[i] = parms->color[i] * (float) state + (parms->color[i] * .2);
1917 color[i] = min(color[i],1.0);
1918 }
1919 }
1920 break;
1921
1922 case LBINDTYPE_FLOATV:
1923
1924 fp = (float *) dataptr;
1925
1926 //intensity = fp[bitnum];
1927
1928 //if(intensity > 1.0) intensity = 1.0;
1929
1930 if(smoothing)
1931 { intense_curr += intense_incr;
1932 if(intense_curr > 1.0) intense_curr = 1.0;
1933 else if(intense_curr < 0.0) intense_curr = 0.0;
1934 intensity = intense_curr;
1935 }
1936
1937 for(i=0;i<3;i++)
1938 { color[i] = parms->color[i] * intensity + (parms->color[i] * .2);
1939 color[i] = min(color[i],1.0);
1940 }
1941 //printf("xyzzy: intense=%f bitnum=%d\n",intensity, bitnum);
1942 break;
1943
1944 }
1945
1946 #if DEBUG
1947 #if 0
1948 if(!strcmp(name,"LED_ADDR_00") ||
1949 !strcmp(name,"LED_ADDR_01") ||
1950 !strcmp(name,"LED_ADDR_10") )
1951 #endif
1952
1953
1954 if(!strcmp(name,"LED_ADDR_15"))
1955 {
1956 fprintf(stderr, "draw: %s %f\n",name, intensity);
1957 }
1958 #endif
1959
1960 glPushMatrix();
1961 glTranslatef(parms->pos[0], parms->pos[1], parms->pos[2]);
1962 glScalef(parms->scale[0], parms->scale[1], parms->scale[2]);
1963
1964
1965 glColor3fv(&color[0]);
1966
1967 (*drawFunc)(this);
1968
1969 glPopMatrix();
1970 }
1971
1972 void
print(void)1973 lpLight::print(void)
1974 {
1975 printf("light: name=%s\n", name);
1976
1977 printf("obj: pos=%f %f %f size=%f %f %f color=%f %f %f\n",
1978 parms->pos[0],
1979 parms->pos[1],
1980 parms->pos[2],
1981 parms->scale[0],
1982 parms->scale[1],
1983 parms->scale[2],
1984 parms->color[0],
1985 parms->color[1],
1986 parms->color[2]);
1987 }
1988
1989 void
bindData8(uint8 * ptr)1990 lpLight::bindData8(uint8 *ptr)
1991 {
1992 sampleDataFunc = sampleData8;
1993 dataptr = (uint8*) ptr;
1994 }
1995 void
bindData8invert(uint8 * ptr)1996 lpLight::bindData8invert(uint8 *ptr)
1997 {
1998 sampleDataFunc = sampleData8invert;
1999 dataptr = (uint8*) ptr;
2000 }
2001
2002 void
bindData16(uint16 * ptr)2003 lpLight::bindData16(uint16 *ptr)
2004 {
2005 // xyzzy
2006 sampleDataFunc = sampleData16;
2007 dataptr = (uint16*) ptr;
2008 }
2009
2010 void
bindDatafv(float * ptr)2011 lpLight::bindDatafv(float *ptr)
2012 {
2013 sampleDataFunc = sampleDatafv;
2014 dataptr = (float *) ptr;
2015 bindtype = LBINDTYPE_FLOATV;
2016 }
2017
2018 void
bindData16invert(uint16 * ptr)2019 lpLight::bindData16invert(uint16 *ptr)
2020 {
2021 sampleDataFunc = sampleData16invert;
2022 dataptr = (uint16*) ptr;
2023 }
2024
2025 void
bindData32(uint32 * ptr)2026 lpLight::bindData32(uint32 *ptr)
2027 {
2028 sampleDataFunc = sampleData32;
2029 dataptr = (uint32*) ptr;
2030 }
2031
2032 void
bindData32invert(uint32 * ptr)2033 lpLight::bindData32invert(uint32 *ptr)
2034 {
2035 sampleDataFunc = sampleData32invert;
2036 dataptr = (uint32*) ptr;
2037 }
2038
2039 void
bindData64(uint64 * ptr)2040 lpLight::bindData64(uint64 *ptr)
2041 {
2042 sampleDataFunc = sampleData64;
2043 dataptr = (uint64*) ptr;
2044 }
2045
2046 void
bindData64invert(uint64 * ptr)2047 lpLight::bindData64invert(uint64 *ptr)
2048 {
2049 sampleDataFunc = sampleData64invert;
2050 dataptr = (uint64*) ptr;
2051 }
2052
2053
2054 void
calcIntensity(void)2055 lpLight::calcIntensity(void)
2056 {
2057 int i;
2058 unsigned int dt;
2059 uint64 clock_delta;
2060
2061 int logit = 0;
2062
2063 clock_delta = old_clock - start_clock;
2064 if(clock_delta == 0)
2065 {// intensity = 0.;
2066 return;
2067 }
2068 else
2069 intensity = (float) ((double) on_time / (double) (clock_delta) * 2.0);
2070 if(intensity > 1.0) intensity = 1.0;
2071
2072 #if 0
2073 //printf("calcIntensity runflag = %d\n",*runflag);
2074 if(*runflag)
2075 //if(!strcmp(name,"LED_ADDR_15") && intensity > .2)
2076 if(!strcmp(name,"LED_ADDR_15") )
2077 {
2078
2079 fprintf(stderr, "dbg: draw: %s intense=%f on_time=%d old_clock=%d start_clock=%d old-start=%d\n",name, intensity, on_time, old_clock, start_clock,old_clock-start_clock);
2080 }
2081 #endif
2082
2083 start_clock = *simclock;
2084 on_time = 0;
2085 dirty = 0;
2086
2087
2088
2089 for(i=0;i<3;i++)
2090 { color[i] = parms->color[i] * intensity + parms->color[i] * .2;
2091 // color[i] = min(color[i],1.0);
2092 if(color[i] > 1.0) color[i] = 1.0;
2093 }
2094
2095
2096 }
2097
2098
2099 void
sampleData(void)2100 lpLight::sampleData(void)
2101 {
2102 (*sampleDataFunc)(this);
2103 }
2104
2105 void
setupData(void)2106 lpLight::setupData(void)
2107 {
2108
2109
2110 if(obj_refname)
2111 { if( !( obj_ref = panel->findObjectByName(obj_refname)))
2112 {
2113 fprintf(stderr, "error: light %s references object %s which cannot be found.\n",
2114 name, obj_refname);
2115 return;
2116 }
2117
2118 drawFunc = drawLightObject;
2119 }
2120
2121 }
2122
2123 void
setName(const char * _name)2124 lpLight::setName(const char *_name)
2125 { int n;
2126
2127 n = strlen(_name);
2128 name = new char[n+1];
2129 strcpy(name,_name);
2130 }
2131
2132
2133 int
smoothLight(char * name,int nframes)2134 Lpanel::smoothLight(char *name, int nframes)
2135 {
2136 char **namelist;
2137 int num_names;
2138 int i, status = 1;
2139 lpLight *light;
2140
2141 if( nframes <0)
2142 {
2143 fprintf(stderr, "smoothLight: light %s error. nframes = %d must be >=0 \n", namelist[i], nframes);
2144 return 0;
2145 }
2146
2147 num_names = xpand(name, &namelist);
2148
2149 for(i=0;i<num_names;i++)
2150 {
2151
2152 light = findLightByName(namelist[i]);
2153
2154 if(light)
2155 {
2156 light->smoothing = nframes;
2157 }
2158 else
2159 {
2160 if(!ignore_bind_errors) fprintf(stderr, "smoothLight: light %s not found\n", namelist[i]);
2161 status = 0;
2162 }
2163 if(namelist[i]) delete namelist[i];
2164 }
2165
2166 return status;
2167 }
2168
2169