070cc9b4757604aa0a27d13a46c591342b2ca3f4
[blender.git] / source / blender / src / buttons_logic.c
1 /**
2  * $Id$ 
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdlib.h>
34 #include <math.h>
35 #include <string.h>
36
37 #ifndef WIN32
38 #include <unistd.h>
39 #else
40 #include <io.h>
41 #endif   
42
43 #include "MEM_guardedalloc.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_arithb.h"
47
48 #include "DNA_action_types.h"
49 #include "DNA_material_types.h"
50 #include "DNA_sensor_types.h"
51 #include "DNA_actuator_types.h"
52 #include "DNA_controller_types.h"
53 #include "DNA_property_types.h"
54 #include "DNA_object_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_space_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_sound_types.h"
59 #include "DNA_text_types.h"
60 #include "DNA_userdef_types.h"
61 #include "DNA_view3d_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_world_types.h"
64
65 #include "BKE_library.h"
66 #include "BKE_global.h"
67 #include "BKE_main.h"
68 #include "BKE_sca.h"
69 #include "BKE_property.h"
70
71 #include "BIF_gl.h"
72 #include "BIF_resources.h"
73 #include "BIF_space.h"
74 #include "BIF_interface.h"
75 #include "BIF_butspace.h"
76 #include "BIF_screen.h"
77 #include "BIF_keyval.h"
78 #include "BIF_editsound.h"
79
80 #include "BIF_editsca.h"
81
82
83 #include "BDR_editcurve.h"
84 #include "BDR_editobject.h"
85 #include "BSE_headerbuttons.h"
86 #include "BSE_filesel.h"
87
88 #include "blendef.h"
89 #include "mydevice.h"
90 #include "nla.h"        /* For __NLA : Important, do not remove */
91 #include "butspace.h" // own module
92
93 /* internals */
94 void buttons_enji(uiBlock *, Object *);
95 void buttons_ketsji(uiBlock *, Object *);
96 void buttons_bullet(uiBlock *, Object *);
97
98 /****/
99
100 static ID **get_selected_and_linked_obs(short *count, short scavisflag);
101 static char *actuator_pup(Object *owner);
102
103 /****/
104
105
106 static void del_property(void *selpropv, void *data2_unused)
107 {
108         bProperty *prop, *selprop= selpropv;
109         Object *ob;
110         int a=0;
111                 
112         ob= OBACT;
113         if(ob==NULL) return;
114
115         prop= ob->prop.first;
116         while(prop) {
117                 if(prop==selprop) {
118                         if (strcmp(prop->name,"Text") == 0) {
119                                 allqueue(REDRAWVIEW3D, 0);
120                         }
121                         BLI_remlink(&ob->prop, prop);
122                         free_property(prop);
123                         break;
124                 }
125                 a++;
126                 prop= prop->next;
127         }
128         BIF_undo_push("Delete property");
129         allqueue(REDRAWBUTSLOGIC, 0);
130         
131 }
132
133 static int vergname(const void *v1, const void *v2)
134 {
135         char **x1, **x2;
136         
137         x1= (char **)v1;
138         x2= (char **)v2;
139         
140         return strcmp(*x1, *x2);
141 }
142
143 void make_unique_prop_names(char *str)
144 {
145         Object *ob;
146         bProperty *prop;
147         bSensor *sens;
148         bController *cont;
149         bActuator *act;
150         ID **idar;
151         short a, obcount, propcount=0, nr;
152         char **names;
153         
154         /* this function is called by a Button, and gives the current
155          * stringpointer as an argument, this is the one that can change
156          */
157
158         idar= get_selected_and_linked_obs(&obcount, BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_CONT_SEL|BUTS_CONT_ACT);
159         
160         /* for each object, make properties and sca names unique */
161         
162         /* count total names */
163         for(a=0; a<obcount; a++) {
164                 ob= (Object *)idar[a];
165                 propcount+= BLI_countlist(&ob->prop);
166                 propcount+= BLI_countlist(&ob->sensors);
167                 propcount+= BLI_countlist(&ob->controllers);
168                 propcount+= BLI_countlist(&ob->actuators);
169         }       
170         if(propcount==0) {
171                 if(idar) MEM_freeN(idar);
172                 return;
173         }
174         
175         /* make names array for sorting */
176         names= MEM_callocN(propcount*sizeof(void *), "names");
177
178         /* count total names */
179         nr= 0;
180         for(a=0; a<obcount; a++) {
181                 ob= (Object *)idar[a];
182                 prop= ob->prop.first;
183                 while(prop) {
184                         names[nr++]= prop->name;
185                         prop= prop->next;
186                 }
187                 sens= ob->sensors.first;
188                 while(sens) {
189                         names[nr++]= sens->name;
190                         sens= sens->next;
191                 }
192                 cont= ob->controllers.first;
193                 while(cont) {
194                         names[nr++]= cont->name;
195                         cont= cont->next;
196                 }
197                 act= ob->actuators.first;
198                 while(act) {
199                         names[nr++]= act->name;
200                         act= act->next;
201                 }
202         }
203
204         qsort(names, propcount, sizeof(void *), vergname);
205         
206         /* now we check for double names, and change them */
207         
208         for(nr=0; nr<propcount; nr++) {
209                 if(names[nr]!=str && strcmp( names[nr], str )==0 ) {
210                         BLI_newname(str, +1);
211                 }
212         }
213         
214         MEM_freeN(idar);
215         MEM_freeN(names);
216 }
217
218 static void make_unique_prop_names_cb(void *strv, void *redraw_view3d_flagv)
219 {
220         char *str= strv;
221         int redraw_view3d_flag= (int) redraw_view3d_flagv;
222
223         make_unique_prop_names(str);
224         if (redraw_view3d_flag) allqueue(REDRAWVIEW3D, 0);
225 }
226
227 static void sca_move_sensor(void *datav, void *data2_unused)
228 {
229         bSensor *sens_to_delete= datav;
230         int val;
231         Base *base;
232         bSensor *sens;
233         
234         val= pupmenu("Move up%x1|Move down %x2");
235         
236         if(val>0) {
237                 /* now find out which object has this ... */
238                 base= FIRSTBASE;
239                 while(base) {
240                 
241                         sens= base->object->sensors.first;
242                         while(sens) {
243                                 if(sens == sens_to_delete) break;
244                                 sens= sens->next;
245                         }
246                         
247                         if(sens) {
248                                 if( val==1 && sens->prev) {
249                                         BLI_remlink(&base->object->sensors, sens);
250                                         BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens);
251                                 }
252                                 else if( val==2 && sens->next) {
253                                         BLI_remlink(&base->object->sensors, sens);
254                                         BLI_insertlink(&base->object->sensors, sens->next, sens);
255                                 }
256                                 BIF_undo_push("Move sensor");
257                                 allqueue(REDRAWBUTSLOGIC, 0);
258                                 break;
259                         }
260                         
261                         base= base->next;
262                 }
263         }
264 }
265
266 static void sca_move_controller(void *datav, void *data2_unused)
267 {
268         bController *controller_to_del= datav;
269         int val;
270         Base *base;
271         bController *cont;
272         
273         val= pupmenu("Move up%x1|Move down %x2");
274         
275         if(val>0) {
276                 /* now find out which object has this ... */
277                 base= FIRSTBASE;
278                 while(base) {
279                 
280                         cont= base->object->controllers.first;
281                         while(cont) {
282                                 if(cont == controller_to_del) break;
283                                 cont= cont->next;
284                         }
285                         
286                         if(cont) {
287                                 if( val==1 && cont->prev) {
288                                         BLI_remlink(&base->object->controllers, cont);
289                                         BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont);
290                                 }
291                                 else if( val==2 && cont->next) {
292                                         BLI_remlink(&base->object->controllers, cont);
293                                         BLI_insertlink(&base->object->controllers, cont->next, cont);
294                                 }
295                                 BIF_undo_push("Move controller");
296                                 allqueue(REDRAWBUTSLOGIC, 0);
297                                 break;
298                         }
299                         
300                         base= base->next;
301                 }
302         }
303 }
304
305 static void sca_move_actuator(void *datav, void *data2_unused)
306 {
307         bActuator *actuator_to_move= datav;
308         int val;
309         Base *base;
310         bActuator *act;
311         
312         val= pupmenu("Move up%x1|Move down %x2");
313         
314         if(val>0) {
315                 /* now find out which object has this ... */
316                 base= FIRSTBASE;
317                 while(base) {
318                 
319                         act= base->object->actuators.first;
320                         while(act) {
321                                 if(act == actuator_to_move) break;
322                                 act= act->next;
323                         }
324                         
325                         if(act) {
326                                 if( val==1 && act->prev) {
327                                         BLI_remlink(&base->object->actuators, act);
328                                         BLI_insertlinkbefore(&base->object->actuators, act->prev, act);
329                                 }
330                                 else if( val==2 && act->next) {
331                                         BLI_remlink(&base->object->actuators, act);
332                                         BLI_insertlink(&base->object->actuators, act->next, act);
333                                 }
334                                 BIF_undo_push("Move actuator");
335                                 allqueue(REDRAWBUTSLOGIC, 0);
336                                 break;
337                         }
338                         
339                         base= base->next;
340                 }
341         }
342 }
343
344 void do_logic_buts(unsigned short event)
345 {
346         bProperty *prop;
347         bSensor *sens;
348         bController *cont;
349         bActuator *act;
350         Base *base;
351         Object *ob;
352         int didit;
353         
354         ob= OBACT;
355         if(ob==0) return;
356         
357         switch(event) {
358
359         case B_SETSECTOR:
360                 /* check for inconsistant types */
361                 ob->gameflag &= ~(OB_PROP|OB_MAINACTOR|OB_DYNAMIC|OB_ACTOR);
362                 ob->dtx |= OB_BOUNDBOX;
363                 allqueue(REDRAWBUTSGAME, 0);
364                 allqueue(REDRAWVIEW3D, 0);
365                 break;
366                 
367         case B_SETPROP:
368                 /* check for inconsistant types */
369                 ob->gameflag &= ~(OB_SECTOR|OB_MAINACTOR|OB_DYNAMIC|OB_ACTOR);
370                 allqueue(REDRAWBUTSGAME, 0);
371                 allqueue(REDRAWVIEW3D, 0);
372                 break;
373
374         case B_SETACTOR:
375         case B_SETDYNA:
376         case B_SETMAINACTOR:
377                 ob->gameflag &= ~(OB_SECTOR|OB_PROP);
378                 allqueue(REDRAWBUTSGAME, 0);
379                 allqueue(REDRAWVIEW3D, 0);
380                 break;
381
382
383         case B_ADD_PROP:
384                 prop= new_property(PROP_FLOAT);
385                 make_unique_prop_names(prop->name);
386                 BLI_addtail(&ob->prop, prop);
387                 BIF_undo_push("Add property");
388                 allqueue(REDRAWBUTSLOGIC, 0);
389                 break;
390         
391         case B_CHANGE_PROP:
392                 prop= ob->prop.first;
393                 while(prop) {
394                         if(prop->type!=prop->otype) {
395                                 init_property(prop);
396                                 if (strcmp(prop->name, "Text") == 0) {
397                                         allqueue(REDRAWVIEW3D, 0);
398                                 }
399                         }
400                         prop= prop->next;
401                 }
402                 allqueue(REDRAWBUTSLOGIC, 0);
403                 break;
404         
405         case B_ADD_SENS:
406                 base= FIRSTBASE;
407                 while(base) {
408                         if(base->object->scaflag & OB_ADDSENS) {
409                                 base->object->scaflag &= ~OB_ADDSENS;
410                                 sens= new_sensor(SENS_ALWAYS);
411                                 BLI_addtail(&(base->object->sensors), sens);
412                                 make_unique_prop_names(sens->name);
413                                 base->object->scaflag |= OB_SHOWSENS;
414                         }
415                         base= base->next;
416                 }
417                 
418                 BIF_undo_push("Add sensor");
419                 allqueue(REDRAWBUTSLOGIC, 0);
420                 break;
421
422         case B_CHANGE_SENS:
423                 base= FIRSTBASE;
424                 while(base) {
425                         sens= base->object->sensors.first;
426                         while(sens) {
427                                 if(sens->type != sens->otype) {
428                                         init_sensor(sens);
429                                         sens->otype= sens->type;
430                                         break;
431                                 }
432                                 sens= sens->next;
433                         }
434                         base= base->next;
435                 }
436                 allqueue(REDRAWBUTSLOGIC, 0);
437                 break;
438         
439         case B_DEL_SENS:
440                 base= FIRSTBASE;
441                 while(base) {
442                         sens= base->object->sensors.first;
443                         while(sens) {
444                                 if(sens->flag & SENS_DEL) {
445                                         BLI_remlink(&(base->object->sensors), sens);
446                                         free_sensor(sens);
447                                         break;
448                                 }
449                                 sens= sens->next;
450                         }
451                         base= base->next;
452                 }
453                 BIF_undo_push("Delete sensor");
454                 allqueue(REDRAWBUTSLOGIC, 0);
455                 break;
456         
457         case B_ADD_CONT:
458                 base= FIRSTBASE;
459                 while(base) {
460                         if(base->object->scaflag & OB_ADDCONT) {
461                                 base->object->scaflag &= ~OB_ADDCONT;
462                                 cont= new_controller(CONT_LOGIC_AND);
463                                 make_unique_prop_names(cont->name);
464                                 base->object->scaflag |= OB_SHOWCONT;
465                                 BLI_addtail(&(base->object->controllers), cont);
466                         }
467                         base= base->next;
468                 }
469                 BIF_undo_push("Add controller");
470                 allqueue(REDRAWBUTSLOGIC, 0);
471                 break;
472
473         case B_CHANGE_CONT:
474                 base= FIRSTBASE;
475                 while(base) {
476                         cont= base->object->controllers.first;
477                         while(cont) {
478                                 if(cont->type != cont->otype) {
479                                         init_controller(cont);
480                                         cont->otype= cont->type;
481                                         break;
482                                 }
483                                 cont= cont->next;
484                         }
485                         base= base->next;
486                 }
487                 allqueue(REDRAWBUTSLOGIC, 0);
488                 break;
489         
490
491         case B_DEL_CONT:
492                 base= FIRSTBASE;
493                 while(base) {
494                         cont= base->object->controllers.first;
495                         while(cont) {
496                                 if(cont->flag & CONT_DEL) {
497                                         BLI_remlink(&(base->object->controllers), cont);
498                                         unlink_controller(cont);
499                                         free_controller(cont);
500                                         break;
501                                 }
502                                 cont= cont->next;
503                         }
504                         base= base->next;
505                 }
506                 BIF_undo_push("Delete controller");
507                 allqueue(REDRAWBUTSLOGIC, 0);
508                 break;
509         
510         case B_ADD_ACT:
511                 base= FIRSTBASE;
512                 while(base) {
513                         if(base->object->scaflag & OB_ADDACT) {
514                                 base->object->scaflag &= ~OB_ADDACT;
515                                 act= new_actuator(ACT_OBJECT);
516                                 make_unique_prop_names(act->name);
517                                 BLI_addtail(&(base->object->actuators), act);
518                                 base->object->scaflag |= OB_SHOWACT;
519                         }
520                         base= base->next;
521                 }
522                 BIF_undo_push("Add actuator");
523                 allqueue(REDRAWBUTSLOGIC, 0);
524                 break;
525
526         case B_CHANGE_ACT:
527                 base= FIRSTBASE;
528                 while(base) {
529                         act= base->object->actuators.first;
530                         while(act) {
531                                 if(act->type != act->otype) {
532                                         init_actuator(act);
533                                         act->otype= act->type;
534                                         break;
535                                 }
536                                 act= act->next;
537                         }
538                         base= base->next;
539                 }
540                 allqueue(REDRAWBUTSLOGIC, 0);
541                 break;
542
543         case B_DEL_ACT:
544                 base= FIRSTBASE;
545                 while(base) {
546                         act= base->object->actuators.first;
547                         while(act) {
548                                 if(act->flag & ACT_DEL) {
549                                         BLI_remlink(&(base->object->actuators), act);
550                                         unlink_actuator(act);
551                                         free_actuator(act);
552                                         break;
553                                 }
554                                 act= act->next;
555                         }
556                         base= base->next;
557                 }
558                 BIF_undo_push("Delete actuator");
559                 allqueue(REDRAWBUTSLOGIC, 0);
560                 break;
561         
562         case B_SOUNDACT_BROWSE:
563                 /* since we don't know which... */
564                 didit= 0;
565                 base= FIRSTBASE;
566                 while(base)
567                 {
568                         act= base->object->actuators.first;
569                         while(act)
570                         {
571                                 if(act->type==ACT_SOUND)
572                                 {
573                                         bSoundActuator *sa= act->data;
574                                         if(sa->sndnr)
575                                         {
576                                                 bSound *sound= G.main->sound.first;
577                                                 int nr= 1;
578
579                                                 if(sa->sndnr == -2) {
580                                                         activate_databrowse((ID *)G.main->sound.first, ID_SO, 0, B_SOUNDACT_BROWSE,
581                                                                                         &sa->sndnr, do_logic_buts);
582                                                         break;
583                                                 }
584
585                                                 while(sound)
586                                                 {
587                                                         if(nr==sa->sndnr)
588                                                                 break;
589                                                         nr++;
590                                                         sound= sound->id.next;
591                                                 }
592                                                 
593                                                 if(sa->sound)
594                                                         sa->sound->id.us--;
595                                                 
596                                                 sa->sound= sound;
597                                                 
598                                                 if(sound)
599                                                         sound->id.us++;
600                                                 
601                                                 sa->sndnr= 0;
602                                                 didit= 1;
603                                         }
604                                 }
605                                 act= act->next;
606                         }
607                         if(didit)
608                                 break;
609                         base= base->next;
610                 }
611                 allqueue(REDRAWBUTSLOGIC, 0);
612                 allqueue(REDRAWSOUND, 0);
613
614                 break;
615         }
616 }
617
618
619 static char *sensor_name(int type)
620 {
621         switch (type) {
622         case SENS_ALWAYS:
623                 return "Always";
624         case SENS_TOUCH:
625                 return "Touch";
626         case SENS_NEAR:
627                 return "Near";
628         case SENS_KEYBOARD:
629                 return "Keyboard";
630         case SENS_PROPERTY:
631                 return "Property";
632         case SENS_MOUSE:
633                 return "Mouse";
634         case SENS_COLLISION:
635                 return "Collision";
636         case SENS_RADAR:
637                 return "Radar";
638         case SENS_RANDOM:
639                 return "Random";
640         case SENS_RAY:
641                 return "Ray";
642         case SENS_MESSAGE:
643                 return "Message";
644         case SENS_JOYSTICK:
645                 return "Joystick";
646         }
647         return "unknown";
648 }
649
650 static char *sensor_pup(void)
651 {
652         /* the number needs to match defines in game.h */
653         return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|"
654                 "Touch %x1|Collision %x6|Near %x2|Radar %x7|"
655                 "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11";
656 }
657
658 static char *controller_name(int type)
659 {
660         switch (type) {
661         case CONT_LOGIC_AND:
662                 return "AND";
663         case CONT_LOGIC_OR:
664                 return "OR";
665         case CONT_EXPRESSION:
666                 return "Expression";
667         case CONT_PYTHON:
668                 return "Python";
669         }
670         return "unknown";
671 }
672
673 static char *controller_pup(void)
674 {
675         return "Controllers   %t|AND %x0|OR %x1|Expression %x2|Python %x3";
676 }
677
678 static char *actuator_name(int type)
679 {
680         switch (type) {
681         case ACT_ACTION:
682                 return "Action";
683         case ACT_OBJECT:
684                 return "Motion";
685         case ACT_IPO:
686                 return "Ipo";
687         case ACT_LAMP:
688                 return "Lamp";
689         case ACT_CAMERA:
690                 return "Camera";
691         case ACT_MATERIAL:
692                 return "Material";
693         case ACT_SOUND:
694                 return "Sound";
695         case ACT_CD:
696                 return "CD";
697         case ACT_PROPERTY:
698                 return "Property";
699         case ACT_EDIT_OBJECT:
700                 return "Edit Object";
701         case ACT_CONSTRAINT:
702                 return "Constraint";
703         case ACT_SCENE:
704                 return "Scene";
705         case ACT_GROUP:
706                 return "Group";
707         case ACT_RANDOM:
708                 return "Random";
709         case ACT_MESSAGE:
710                 return "Message";
711         case ACT_GAME:
712                 return "Game";
713         case ACT_VISIBILITY:
714                 return "Visibility";
715         case ACT_2DFILTER:
716                 return "2D Filter";
717         case ACT_PARENT:
718                 return "Parent";
719         }
720         return "unknown";
721 }
722
723
724
725
726 static char *actuator_pup(Object *owner)
727 {
728         switch (owner->type)
729         {
730         case OB_ARMATURE:
731                 return "Actuators  %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
732                         "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
733                         "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
734                         "|Visibility %x18|2D Filter %x19|Parent %x20";
735                 break;
736         default:
737                 return "Actuators  %t|Motion %x0|Constraint %x9|Ipo %x1"
738                         "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
739                         "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
740                         "|Visibility %x18|2D Filter %x19|Parent %x20";
741         }
742 }
743
744
745
746 static void set_sca_ob(Object *ob)
747 {
748         bController *cont;
749         bActuator *act;
750
751         cont= ob->controllers.first;
752         while(cont) {
753                 cont->mynew= (bController *)ob;
754                 cont= cont->next;
755         }
756         act= ob->actuators.first;
757         while(act) {
758                 act->mynew= (bActuator *)ob;
759                 act= act->next;
760         }
761 }
762
763 static ID **get_selected_and_linked_obs(short *count, short scavisflag)
764 {
765         Base *base;
766         Object *ob, *obt;
767         ID **idar;
768         bSensor *sens;
769         bController *cont;
770         unsigned int lay;
771         int a, nr, doit;
772         
773         /* we need a sorted object list */
774         /* set scavisflags flags in Objects to indicate these should be evaluated */
775         /* also hide ob pointers in ->new entries of controllerss/actuators */
776         
777         *count= 0;
778         
779         if(G.scene==NULL) return NULL;
780         
781         ob= G.main->object.first;
782         while(ob) {
783                 ob->scavisflag= 0;
784                 set_sca_ob(ob);
785                 ob= ob->id.next;
786         }
787         
788         if(G.vd) lay= G.vd->lay;
789         else lay= G.scene->lay;
790         
791         base= FIRSTBASE;
792         while(base) {
793                 if(base->lay & lay) {
794                         if(base->flag & SELECT) {
795                                 if(scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
796                                 if(scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
797                                 if(scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT;
798                         }
799                 }
800                 base= base->next;
801         }
802
803         if(OBACT) {
804                 if(scavisflag & BUTS_SENS_ACT) OBACT->scavisflag |= OB_VIS_SENS;
805                 if(scavisflag & BUTS_CONT_ACT) OBACT->scavisflag |= OB_VIS_CONT;
806                 if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT;
807         }
808         
809         if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) {
810                 doit= 1;
811                 while(doit) {
812                         doit= 0;
813                         
814                         ob= G.main->object.first;
815                         while(ob) {
816                         
817                                 /* 1st case: select sensor when controller selected */
818                                 if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) {
819                                         sens= ob->sensors.first;
820                                         while(sens) {
821                                                 for(a=0; a<sens->totlinks; a++) {
822                                                         if(sens->links[a]) {
823                                                                 obt= (Object *)sens->links[a]->mynew;
824                                                                 if(obt && (obt->scavisflag & OB_VIS_CONT)) {
825                                                                         doit= 1;
826                                                                         ob->scavisflag |= OB_VIS_SENS;
827                                                                         break;
828                                                                 }
829                                                         }
830                                                 }
831                                                 if(doit) break;
832                                                 sens= sens->next;
833                                         }
834                                 }
835                                 
836                                 /* 2nd case: select cont when act selected */
837                                 if((scavisflag & BUTS_CONT_LINK)  && (ob->scavisflag & OB_VIS_CONT)==0) {
838                                         cont= ob->controllers.first;
839                                         while(cont) {
840                                                 for(a=0; a<cont->totlinks; a++) {
841                                                         if(cont->links[a]) {
842                                                                 obt= (Object *)cont->links[a]->mynew;
843                                                                 if(obt && (obt->scavisflag & OB_VIS_ACT)) {
844                                                                         doit= 1;
845                                                                         ob->scavisflag |= OB_VIS_CONT;
846                                                                         break;
847                                                                 }
848                                                         }
849                                                 }
850                                                 if(doit) break;
851                                                 cont= cont->next;
852                                         }
853                                 }
854                                 
855                                 /* 3rd case: select controller when sensor selected */
856                                 if((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_SENS)) {
857                                         sens= ob->sensors.first;
858                                         while(sens) {
859                                                 for(a=0; a<sens->totlinks; a++) {
860                                                         if(sens->links[a]) {
861                                                                 obt= (Object *)sens->links[a]->mynew;
862                                                                 if(obt && (obt->scavisflag & OB_VIS_CONT)==0) {
863                                                                         doit= 1;
864                                                                         obt->scavisflag |= OB_VIS_CONT;
865                                                                 }
866                                                         }
867                                                 }
868                                                 sens= sens->next;
869                                         }
870                                 }
871                                 
872                                 /* 4th case: select actuator when controller selected */
873                                 if( (scavisflag & BUTS_ACT_LINK)  && (ob->scavisflag & OB_VIS_CONT)) {
874                                         cont= ob->controllers.first;
875                                         while(cont) {
876                                                 for(a=0; a<cont->totlinks; a++) {
877                                                         if(cont->links[a]) {
878                                                                 obt= (Object *)cont->links[a]->mynew;
879                                                                 if(obt && (obt->scavisflag & OB_VIS_ACT)==0) {
880                                                                         doit= 1;
881                                                                         obt->scavisflag |= OB_VIS_ACT;
882                                                                 }
883                                                         }
884                                                 }
885                                                 cont= cont->next;
886                                         }
887                                         
888                                 }
889                                 ob= ob->id.next;
890                         }
891                 }
892         } 
893         
894         /* now we count */
895         ob= G.main->object.first;
896         while(ob) {
897                 if( ob->scavisflag ) (*count)++;
898                 ob= ob->id.next;
899         }
900
901         if(*count==0) return NULL;
902         if(*count>24) *count= 24;               /* temporal */
903         
904         idar= MEM_callocN( (*count)*sizeof(void *), "idar");
905         
906         ob= G.main->object.first;
907         nr= 0;
908         while(ob) {
909                 if( ob->scavisflag ) {
910                         idar[nr]= (ID *)ob;
911                         nr++;
912                 }
913                 if(nr>=24) break;
914                 ob= ob->id.next;
915         }
916         
917         /* just to be sure... these were set in set_sca_done_ob() */
918         clear_sca_new_poins();
919         
920         return idar;
921 }
922
923
924 static int get_col_sensor(int type)
925 {
926         switch(type) {
927         case SENS_ALWAYS:               return TH_BUT_ACTION;
928         case SENS_TOUCH:                return TH_BUT_NEUTRAL;
929         case SENS_COLLISION:    return TH_BUT_SETTING;
930         case SENS_NEAR:                 return TH_BUT_SETTING1; 
931         case SENS_KEYBOARD:             return TH_BUT_SETTING2;
932         case SENS_PROPERTY:             return TH_BUT_NUM;
933         case SENS_MOUSE:                return TH_BUT_TEXTFIELD;
934         case SENS_RADAR:                return TH_BUT_POPUP;
935         case SENS_RANDOM:               return TH_BUT_NEUTRAL;
936         case SENS_RAY:                  return TH_BUT_SETTING1;
937         case SENS_MESSAGE:              return TH_BUT_SETTING2;
938         case SENS_JOYSTICK:             return TH_BUT_NEUTRAL;
939         default:                                return TH_BUT_NEUTRAL;
940         }
941 }
942 static void set_col_sensor(int type, int medium)
943 {
944         int col= get_col_sensor(type);
945         BIF_ThemeColorShade(col, medium?30:0);
946 }
947
948 /**
949  * Draws a toggle for pulse mode, a frequency field and a toggle to invert
950  * the value of this sensor. Operates on the shared data block of sensors.
951  */
952 static void draw_default_sensor_header(bSensor *sens,
953                                                                 uiBlock *block,
954                                                                 short x,
955                                                                 short y,
956                                                                 short w) 
957 {
958         /* Pulsing and frequency */
959         uiDefIconButBitS(block, TOG, SENS_PULSE_REPEAT, 1, ICON_DOTSUP,
960                          (short)(x + 10 + 0. * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
961                          &sens->pulse, 0.0, 0.0, 0, 0,
962                          "Activate TRUE level triggering (pulse mode)");
963
964         uiDefIconButBitS(block, TOG, SENS_NEG_PULSE_MODE, 1, ICON_DOTSDOWN,
965                          (short)(x + 10 + 0.15 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
966                          &sens->pulse, 0.0, 0.0, 0, 0,
967                          "Activate FALSE level triggering (pulse mode)");
968         uiDefButS(block, NUM, 1, "f:",
969                          (short)(x + 10 + 0.3 * (w-20)), (short)(y - 19), (short)(0.275 * (w-20)), 19,
970                          &sens->freq, 0.0, 10000.0, 0, 0,
971                          "Delay between repeated pulses (in logic tics, 0 = no delay)");
972         
973         /* value or shift? */
974         uiDefButS(block, TOG, 1, "Inv",
975                          (short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
976                          &sens->invert, 0.0, 0.0, 0, 0,
977                          "Invert the level (output) of this sensor");
978 }
979
980 static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
981 {
982         bNearSensor      *ns           = NULL;
983         bTouchSensor     *ts           = NULL;
984         bKeyboardSensor  *ks           = NULL;
985         bPropertySensor  *ps           = NULL;
986         bMouseSensor     *ms           = NULL;
987         bCollisionSensor *cs           = NULL;
988         bRadarSensor     *rs           = NULL;
989         bRandomSensor    *randomSensor = NULL;
990         bRaySensor       *raySens      = NULL;
991         bMessageSensor   *mes          = NULL;
992         bJoystickSensor  *joy              = NULL;
993
994         short ysize;
995         char *str;
996         
997         /* yco is at the top of the rect, draw downwards */
998         
999         uiBlockSetEmboss(block, UI_EMBOSSM);
1000         
1001         set_col_sensor(sens->type, 0);
1002         
1003         switch (sens->type)
1004         {
1005         case SENS_ALWAYS:
1006                 {
1007                         ysize= 24;
1008                         
1009                         glRects(xco, yco-ysize, xco+width, yco);
1010                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1011                         
1012                         draw_default_sensor_header(sens, block, xco, yco, width);
1013                         
1014                         yco-= ysize;
1015                         
1016                         break;
1017                 }
1018         case SENS_TOUCH:
1019                 {
1020                         ysize= 48; 
1021                         
1022                         glRects(xco, yco-ysize, xco+width, yco); 
1023                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1024                         
1025                         draw_default_sensor_header(sens, block, xco, yco, width);
1026                         
1027                         ts= sens->data; 
1028                         
1029                         /* uiDefBut(block, TEX, 1, "Property:", xco,yco-22,width, 19, &ts->name, 0, 31, 0, 0, "Only look for Objects with this property"); */
1030                         uiDefIDPoinBut(block, test_matpoin_but, ID_MA, 1, "MA:",(short)(xco + 10),(short)(yco-44), (short)(width - 20), 19, &ts->ma,  "Only look for floors with this Material"); 
1031                         ///* uiDefButF(block, NUM, 1, "Margin:",        xco+width/2,yco-44,width/2, 19, &ts->dist, 0.0, 10.0, 100, 0, "Extra margin (distance) for larger sensitivity"); 
1032                         yco-= ysize; 
1033                         break; 
1034                 }
1035         case SENS_COLLISION:
1036                 {
1037                         ysize= 48;
1038                         
1039                         glRects(xco, yco-ysize, xco+width, yco);
1040                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1041                         
1042                         draw_default_sensor_header(sens, block, xco, yco, width);
1043                         cs= sens->data;
1044                         
1045                         /* The collision sensor will become a generic collision (i.e. it     */
1046                         /* absorb the old touch sensor).                                     */
1047
1048                         uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P",(short)(xco + 10),(short)(yco - 44),
1049                                 (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0,
1050                                 "Toggle collision on material or property.");
1051                         
1052                         if (cs->mode & SENS_COLLISION_MATERIAL) {
1053                                 uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.20 * (width-20)),
1054                                         (short)(yco-44), (short)(0.8*(width-20)), 19, &cs->materialName, 0, 31, 0, 0,
1055                                         "Only look for Objects with this material");
1056                         } else {
1057                                 uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.20 * (width-20)), (short)(yco-44),
1058                                         (short)(0.8*(width-20)), 19, &cs->name, 0, 31, 0, 0,
1059                                         "Only look for Objects with this property");
1060                         }
1061         
1062                         /*              uiDefButS(block, NUM, 1, "Damp:",       xco+10+width-90,yco-24, 70, 19, &cs->damp, 0, 250, 0, 0, "For 'damp' time don't detect another collision"); */
1063                         
1064                         yco-= ysize;
1065                         break;
1066                 }
1067         case SENS_NEAR:
1068                 {
1069                         ysize= 72;
1070                         
1071                         glRects(xco, yco-ysize, xco+width, yco);
1072                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1073                         
1074                         draw_default_sensor_header(sens, block, xco, yco, width);
1075                         ns= sens->data;
1076                         
1077                         uiDefBut(block, TEX, 1, "Property:",(short)(10+xco),(short)(yco-44), (short)(width-20), 19,
1078                                 &ns->name, 0, 31, 0, 0, "Only look for Objects with this property");
1079                         uiDefButF(block, NUM, 1, "Dist",(short)(10+xco),(short)(yco-68),(short)((width-22)/2), 19,
1080                                 &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance");
1081                         uiDefButF(block, NUM, 1, "Reset",(short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19,
1082                                 &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); 
1083                         yco-= ysize;
1084                         break;
1085                 }
1086         case SENS_RADAR:
1087                 {
1088                         ysize= 72; 
1089                         
1090                         glRects(xco, yco-ysize, xco+width, yco);
1091                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1092                         
1093                         draw_default_sensor_header(sens, block, xco, yco, width);
1094                         
1095                         rs= sens->data;
1096                         
1097                         uiDefBut(block, TEX, 1, "Prop:",
1098                                          (short)(10+xco),(short)(yco-44), (short)(0.7 * (width-20)), 19,
1099                                          &rs->name, 0, 31, 0, 0,
1100                                          "Only look for Objects with this property");
1101
1102                         str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; 
1103                         uiDefButS(block, MENU, B_REDR, str,
1104                                 (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19,
1105                                 &rs->axis, 2.0, 31, 0, 0,
1106                                 "Specify along which axis the radar cone is cast.");
1107                                 
1108                         uiDefButF(block, NUM, 1, "Ang:",
1109                                          (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19,
1110                                          &rs->angle, 0.0, 179.9, 10, 0,
1111                                          "Opening angle of the radar cone.");
1112                         uiDefButF(block, NUM, 1, "Dist:",
1113                                          (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19,
1114                                          &rs->range, 0.01, 10000.0, 100, 0,
1115                                          "Depth of the radar cone");
1116                         yco-= ysize;
1117                         break;
1118                 }
1119         case SENS_KEYBOARD:
1120                 {
1121                         /* 5 lines: 120 height */
1122                         ysize= 120;
1123                         
1124                         glRects(xco, yco-ysize, xco+width, yco);
1125                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1126                         
1127                         /* header line */
1128                         draw_default_sensor_header(sens, block, xco, yco, width);
1129                         ks= sens->data;
1130                         
1131                         /* line 2: hotkey and allkeys toggle */
1132                         uiDefKeyevtButS(block, B_DIFF, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code");
1133                         
1134                         /* line 3: two key modifyers (qual1, qual2) */
1135                         uiDefKeyevtButS(block, B_DIFF, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code");
1136                         uiDefKeyevtButS(block, B_DIFF, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code");
1137                         
1138                         /* labels for line 1 and 2 */
1139                         uiDefBut(block, LABEL, 0, "Key",          xco, yco-44, 40, 19, NULL, 0, 0, 0, 0, "");
1140                         uiDefBut(block, LABEL, 0, "Hold",         xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, "");
1141                         
1142                         /* part of line 1 */
1143                         uiBlockSetCol(block, TH_BUT_SETTING2);
1144                         uiDefButBitS(block, TOG, 1, 0, "All keys",        xco+40+(width/2), yco-44, (width/2)-50, 19,
1145                                 &ks->type, 0, 0, 0, 0, "");
1146                         
1147                         /* line 4: toggle property for string logging mode */
1148                         uiDefBut(block, TEX, 1, "LogToggle: ",
1149                                 xco+10, yco-92, (width-20), 19,
1150                                 ks->toggleName, 0, 31, 0, 0,
1151                                 "Property that indicates whether to log "
1152                                 "keystrokes as a string.");
1153                         
1154                         /* line 5: target property for string logging mode */
1155                         uiDefBut(block, TEX, 1, "Target: ",
1156                                 xco+10, yco-116, (width-20), 19,
1157                                 ks->targetName, 0, 31, 0, 0,
1158                                 "Property that receives the keystrokes in case "
1159                                 "a string is logged.");
1160                         
1161                         yco-= ysize;
1162                         break;
1163                 }
1164         case SENS_PROPERTY:
1165                 {
1166                         ysize= 96;
1167                         
1168                         glRects(xco, yco-ysize, xco+width, yco);
1169                         uiEmboss((float)xco, (float)yco-ysize,
1170                                 (float)xco+width, (float)yco, 1);
1171                         
1172                         draw_default_sensor_header(sens, block, xco, yco, width);
1173                         ps= sens->data;
1174                         
1175                         str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; 
1176                         /* str= "Type %t|Equal %x0|Not Equal %x1"; */
1177                         uiDefButI(block, MENU, B_REDR, str,                     xco+30,yco-44,width-60, 19,
1178                                 &ps->type, 0, 31, 0, 0, "Type");
1179                         
1180                         if (ps->type != SENS_PROP_EXPRESSION)
1181                         {
1182                                 uiDefBut(block, TEX, 1, "Prop: ",                       xco+30,yco-68,width-60, 19,
1183                                         ps->name, 0, 31, 0, 0,  "Property name");
1184                         }
1185                         
1186                         if(ps->type == SENS_PROP_INTERVAL)
1187                         {
1188                                 uiDefBut(block, TEX, 1, "Min: ",                xco,yco-92,width/2, 19,
1189                                         ps->value, 0, 31, 0, 0, "test for min value");
1190                                 uiDefBut(block, TEX, 1, "Max: ",                xco+width/2,yco-92,width/2, 19,
1191                                         ps->maxvalue, 0, 31, 0, 0, "test for max value");
1192                         }
1193                         else if(ps->type == SENS_PROP_CHANGED);
1194                         else
1195                         {
1196                                 uiDefBut(block, TEX, 1, "Value: ",              xco+30,yco-92,width-60, 19,
1197                                         ps->value, 0, 31, 0, 0, "test for value");
1198                         }
1199                         
1200                         yco-= ysize;
1201                         break;
1202                 }
1203         case SENS_MOUSE:
1204                 {
1205                         ms= sens->data;
1206                         /* Two lines: 48 pixels high. */
1207                         ysize = 48;
1208                         
1209                         glRects(xco, yco-ysize, xco+width, yco);
1210                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1211                         
1212                         /* line 1: header */
1213                         draw_default_sensor_header(sens, block, xco, yco, width);
1214                         
1215                         /* Line 2: type selection. The number are a bit mangled to get
1216                         * proper compatibility with older .blend files. */
1217                         str= "Type %t|Left button %x1|Middle button %x2|"
1218                                 "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; 
1219                         uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, width-20, 19,
1220                                 &ms->type, 0, 31, 0, 0,
1221                                 "Specify the type of event this mouse sensor should trigger on.");
1222                         
1223                         yco-= ysize;
1224                         break;
1225                 }
1226         case SENS_RANDOM:
1227                 {
1228                         ysize = 48;
1229                         
1230                         glRects(xco, yco-ysize, xco+width, yco);
1231                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1232                         
1233                         draw_default_sensor_header(sens, block, xco, yco, width);
1234                         randomSensor = sens->data;
1235                         /* some files were wrongly written, avoid crash now */
1236                         if (randomSensor)
1237                         {
1238                                 uiDefButI(block, NUM, 1, "Seed: ",              xco+10,yco-44,(width-20), 19,
1239                                         &randomSensor->seed, 0, 1000, 0, 0,
1240                                         "Initial seed of the generator. (Choose 0 for not random)");
1241                         }
1242                         yco-= ysize;
1243                         break;
1244                 }
1245         case SENS_RAY:
1246                 {
1247                         ysize = 72;
1248                         glRects(xco, yco-ysize, xco+width, yco);
1249                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1250                         
1251                         draw_default_sensor_header(sens, block, xco, yco, width);
1252                         raySens = sens->data;
1253                         
1254                         /* 1. property or material */
1255                         uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P",
1256                                 xco + 10,yco - 44, 0.20 * (width-20), 19,
1257                                 &raySens->mode, 0.0, 0.0, 0, 0,
1258                                 "Toggle collision on material or property.");
1259                         
1260                         if (raySens->mode & SENS_COLLISION_MATERIAL)
1261                         {
1262                                 uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19,
1263                                         &raySens->matname, 0, 31, 0, 0,
1264                                         "Only look for Objects with this material");
1265                         }
1266                         else
1267                         {
1268                                 uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19,
1269                                         &raySens->propname, 0, 31, 0, 0,
1270                                         "Only look for Objects with this property");
1271                         }
1272                         
1273                         /* 2. sensing range */
1274                         uiDefButF(block, NUM, 1, "Range", xco+10, yco-68, 0.6 * (width-20), 19,
1275                                 &raySens->range, 0.01, 10000.0, 100, 0,
1276                                 "Sense objects no farther than this distance");
1277                         
1278                         /* 3. axis choice */
1279                         str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; 
1280                         uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
1281                                 &raySens->axisflag, 2.0, 31, 0, 0,
1282                                 "Specify along which axis the ray is cast.");
1283                         
1284                         yco-= ysize;            
1285                         break;
1286                 }
1287         case SENS_MESSAGE:
1288                 {
1289                         mes = sens->data;
1290                         ysize = 2 * 24; /* total number of lines * 24 pixels/line */
1291                         
1292                         glRects(xco, yco-ysize, xco+width, yco);
1293                         uiEmboss((float)xco, (float)yco-ysize,
1294                                 (float)xco+width, (float)yco, 1);
1295                         
1296                         /* line 1: header line */
1297                         draw_default_sensor_header(sens, block, xco, yco, width);
1298                         
1299                         /* line 2: Subject filter */
1300                         uiDefBut(block, TEX, 1, "Subject: ",
1301                                 (xco+10), (yco-44), (width-20), 19,
1302                                 mes->subject, 0, 31, 0, 0,
1303                                 "Optional subject filter: only accept messages with this subject"
1304                                 ", or empty for all");
1305                         
1306                         yco -= ysize;
1307                         break;
1308                 }
1309                 case SENS_JOYSTICK:
1310                 {
1311
1312                         ysize =  72;
1313                         
1314                         glRects(xco, yco-ysize, xco+width, yco);
1315                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1316                         
1317                         /* line 1: header */
1318                         draw_default_sensor_header(sens, block, xco, yco, width);
1319
1320                         joy= sens->data;
1321                         
1322
1323                         str= "Type %t|Button %x0|Axis %x1|Hat%x2"; 
1324                         uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, 0.6 * (width-20), 19,
1325                                 &joy->type, 0, 31, 0, 0,
1326                                 "The type of event this joystick sensor is triggered on.");
1327                         
1328                         if(joy->type == SENS_JOY_BUTTON)
1329                         {
1330                                 uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.6 * (width-20), 19,
1331                                 &joy->button, 0, 18, 100, 0,
1332                                 "Specify which button to use");
1333                                 
1334                                 str = "Type %t|Pressed %x0|Released %x1"; 
1335                                 uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
1336                                 &joy->buttonf, 2.0, 31, 0, 0,
1337                                 "Button pressed or released.");
1338                         }
1339                         else if(joy->type == SENS_JOY_AXIS)
1340                         {
1341                                 uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.6 * (width-20), 19,
1342                                 &joy->axis, 1, 2.0, 100, 0,
1343                                 "Specify which axis to use");
1344
1345                                 uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20),yco-44, 0.4 * (width-20), 19,
1346                                 &joy->precision, 0, 32768.0, 100, 0,
1347                                 "Specify the precision of the axis");
1348
1349                                 str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; 
1350                                 uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
1351                                 &joy->axisf, 2.0, 31, 0, 0,
1352                                 "The direction of the axis");
1353                         }
1354                         else
1355                         {
1356                                 uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.6 * (width-20), 19,
1357                                 &joy->hat, 1, 2.0, 100, 0,
1358                                 "Specify which hat to use");
1359                                 
1360                                 uiDefButI(block, NUM, 1, "Direction:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
1361                                 &joy->hatf, 0, 12, 100, 0,
1362                                 "Specify hat direction");
1363                         }
1364                         yco-= ysize;
1365                         break;
1366                 }
1367         }
1368         
1369         uiBlockSetEmboss(block, UI_EMBOSSM);
1370         uiBlockSetCol(block, TH_AUTO);
1371         
1372         return yco-4;
1373 }
1374
1375
1376
1377 static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco, short yco, short width)
1378 {
1379         bExpressionCont *ec;
1380         bPythonCont *pc;
1381         short ysize;
1382         
1383         uiBlockSetEmboss(block, UI_EMBOSSM);
1384         
1385         switch (cont->type) {
1386         case CONT_EXPRESSION:
1387                 ysize= 28;
1388
1389                 BIF_ThemeColor(TH_BUT_SETTING);
1390                 glRects(xco, yco-ysize, xco+width, yco);
1391                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1392                 
1393                 /* uiDefBut(block, LABEL, 1, "Not yet...", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, ""); */
1394                 ec= cont->data; 
1395                 /* uiDefBut(block, BUT, 1, "Variables", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, "Available variables for expression"); */
1396                 uiDefBut(block, TEX, 1, "Exp:",         xco + 10 , yco-21, width-20, 19,
1397                                  ec->str, 0, 127, 0, 0,
1398                                  "Expression"); 
1399                 
1400                 yco-= ysize;
1401                 break;
1402         case CONT_PYTHON:
1403                 ysize= 28;
1404                 
1405                 if(cont->data==NULL) init_controller(cont);
1406                 pc= cont->data;
1407                 
1408                 BIF_ThemeColor(TH_BUT_SETTING1);
1409                 glRects(xco, yco-ysize, xco+width, yco);
1410                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1411
1412                 uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+45,yco-24,width-90, 19, &pc->text, "");
1413                 
1414                 yco-= ysize;
1415                 break;
1416                 
1417         default:
1418                 ysize= 4;
1419
1420                 BIF_ThemeColor(TH_BUT_NEUTRAL);
1421                 glRects(xco, yco-ysize, xco+width, yco);
1422                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1423                 
1424                 yco-= ysize;
1425         }
1426         
1427         uiBlockSetEmboss(block, UI_EMBOSSM);
1428         uiBlockSetCol(block, TH_AUTO);
1429
1430         return yco;
1431 }
1432
1433 static int get_col_actuator(int type)
1434 {
1435         switch(type) {
1436         case ACT_ACTION:                return TH_BUT_ACTION;
1437         case ACT_OBJECT:                return TH_BUT_NEUTRAL;
1438         case ACT_IPO:                   return TH_BUT_SETTING;
1439         case ACT_PROPERTY:              return TH_BUT_SETTING1;
1440         case ACT_SOUND:                 return TH_BUT_SETTING2;
1441         case ACT_CD:                    return TH_BUT_NUM;
1442         case ACT_CAMERA:                return TH_BUT_TEXTFIELD;
1443         case ACT_EDIT_OBJECT:           return TH_BUT_POPUP;
1444         case ACT_GROUP:                 return TH_BUT_ACTION;
1445         case ACT_RANDOM:                return TH_BUT_NEUTRAL;
1446         case ACT_SCENE:                 return TH_BUT_SETTING;
1447         case ACT_MESSAGE:               return TH_BUT_SETTING1;
1448         case ACT_GAME:                  return TH_BUT_SETTING2;
1449         case ACT_VISIBILITY:            return TH_BUT_NUM;
1450         case ACT_CONSTRAINT:            return TH_BUT_ACTION;
1451         default:                                return TH_BUT_NEUTRAL;
1452         }
1453 }
1454 static void set_col_actuator(int item, int medium) 
1455 {
1456         int col= get_col_actuator(item);
1457         BIF_ThemeColorShade(col, medium?30:10);
1458         
1459 }
1460
1461 static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width)
1462 {
1463         bSoundActuator      *sa      = NULL;
1464         bCDActuator                     *cda     = NULL;
1465         bObjectActuator     *oa      = NULL;
1466         bIpoActuator        *ia      = NULL;
1467         bPropertyActuator   *pa      = NULL;
1468         bCameraActuator     *ca      = NULL;
1469         bEditObjectActuator *eoa     = NULL;
1470         bConstraintActuator *coa     = NULL;
1471         bSceneActuator      *sca     = NULL;
1472         bGroupActuator      *ga      = NULL;
1473         bRandomActuator     *randAct = NULL;
1474         bMessageActuator    *ma      = NULL;
1475         bActionActuator     *aa      = NULL;
1476         bGameActuator       *gma     = NULL;
1477         bVisibilityActuator *visAct  = NULL;
1478         bTwoDFilterActuator     *tdfa    = NULL;
1479         bParentActuator     *parAct  = NULL;
1480         
1481         float *fp;
1482         short ysize = 0, wval;
1483         char *str;
1484         int myline;
1485
1486         /* yco is at the top of the rect, draw downwards */
1487         uiBlockSetEmboss(block, UI_EMBOSSM);
1488         set_col_actuator(act->type, 0);
1489         
1490         switch (act->type)
1491         {
1492         case ACT_OBJECT:
1493                 {
1494                         ysize= 129;
1495                         
1496                         glRects(xco, yco-ysize, xco+width, yco);
1497                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1498                         
1499                         oa = act->data;
1500                         wval = (width-100)/3;
1501                         
1502                         uiDefBut(block, LABEL, 0, "Force",      xco, yco-22, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
1503                         uiDefButF(block, NUM, 0, "",            xco+45, yco-22, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
1504                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-22, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
1505                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-22, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
1506                         
1507                         uiDefBut(block, LABEL, 0, "Torque", xco, yco-41, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
1508                         uiDefButF(block, NUM, 0, "",            xco+45, yco-41, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
1509                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-41, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
1510                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-41, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
1511                         
1512                         uiDefBut(block, LABEL, 0, "dLoc",       xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
1513                         uiDefButF(block, NUM, 0, "",            xco+45, yco-64, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
1514                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-64, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
1515                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-64, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
1516                         
1517                         uiDefBut(block, LABEL, 0, "dRot",       xco, yco-83, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
1518                         uiDefButF(block, NUM, 0, "",            xco+45, yco-83, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
1519                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-83, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
1520                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-83, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
1521                         
1522                         uiDefBut(block, LABEL, 0, "linV",       xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
1523                         uiDefButF(block, NUM, 0, "",            xco+45, yco-106, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
1524                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-106, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
1525                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-106, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
1526                         
1527                         uiDefBut(block, LABEL, 0, "angV",       xco, yco-125, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
1528                         uiDefButF(block, NUM, 0, "",            xco+45, yco-125, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
1529                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
1530                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
1531                         
1532                         uiDefButBitI(block, TOG, ACT_FORCE_LOCAL, 0, "L",               xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1533                         uiDefButBitI(block, TOG, ACT_TORQUE_LOCAL, 0, "L",              xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1534                         uiDefButBitI(block, TOG, ACT_DLOC_LOCAL, 0, "L",                xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1535                         uiDefButBitI(block, TOG, ACT_DROT_LOCAL, 0, "L",                xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1536                         uiDefButBitI(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1537                         uiDefButBitI(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
1538                         
1539                         uiDefButBitI(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
1540                         
1541                         yco-= ysize;
1542                         break;
1543                 }
1544         case ACT_ACTION:
1545                 {
1546                         /* DrawAct */
1547 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
1548                         ysize = 112;
1549 #else
1550                         ysize= 92;
1551 #endif
1552                         
1553                         glRects(xco, yco-ysize, xco+width, yco);
1554                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1555                         
1556                         aa = act->data;
1557                         wval = (width-60)/3;
1558                         
1559                         //              str= "Action types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
1560 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
1561                         str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6|Displacement %x7";
1562 #else
1563                         str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
1564 #endif
1565                         uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
1566                         uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30, yco-44, width-60, 19, &aa->act, "Action name");
1567                         
1568                         if(aa->type == ACT_ACTION_FROM_PROP)
1569                         {
1570                                 uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-64, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
1571                         }
1572                         else
1573                         {
1574                                 uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-64, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
1575                                 uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
1576                         }
1577                         
1578                         
1579                         
1580                         uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-84, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending");
1581                         uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-84, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers");
1582                         
1583 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
1584                         if(aa->type == ACT_ACTION_MOTION)
1585                         {
1586                                 uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-104, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
1587                         }
1588 #endif
1589                         
1590                         yco-=ysize;
1591                         break;
1592                 }
1593         case ACT_IPO:
1594                 {
1595                         ia= act->data;
1596                         
1597                         ysize= 52;
1598                         
1599                         glRects(xco, yco-ysize, xco+width, yco);
1600                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1601                         
1602                         str = "Ipo types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
1603                         
1604                         uiDefButS(block, MENU, B_REDR, str,             xco+20, yco-24, width-40 - (width-40)/3, 19, &ia->type, 0, 0, 0, 0, "");
1605                         uiDefButBitS(block, TOG, ACT_IPOCHILD,  B_REDR, 
1606                                 "Child",        xco+20+0.666*(width-40), yco-24, (width-40)/3, 19, 
1607                                 &ia->flag, 0, 0, 0, 0, 
1608                                 "Add all children Objects as well");
1609
1610                         if(ia->type==ACT_IPO_FROM_PROP) {
1611                                 uiDefBut(block, TEX, 0, 
1612                                         "Prop: ",               xco+20, yco-44, width-40, 19, 
1613                                         ia->name, 0.0, 31.0, 0, 0, 
1614                                         "Use this property to define the Ipo position");
1615                         }
1616                         else {
1617                                 uiDefButI(block, NUM, 0, 
1618                                         "Sta",          xco+20, yco-44, (width-100)/2, 19, 
1619                                         &ia->sta, 0.0, MAXFRAMEF, 0, 0, 
1620                                         "Start frame");
1621                                 uiDefButI(block, NUM, 0, 
1622                                         "End",          xco+18+(width-90)/2, yco-44, (width-100)/2, 19, 
1623                                         &ia->end, 0.0, MAXFRAMEF, 0, 0, 
1624                                         "End frame");
1625                                 
1626                                 uiDefButBitS(block, TOG, ACT_IPOFORCE, B_REDR, 
1627                                         "Force", xco+width-78, yco-44, 43, 19, 
1628                                         &ia->flag, 0, 0, 0, 0, 
1629                                         "Convert Ipo to force"); 
1630                                 
1631                                 /* Only show the do-force-local toggle if force is requested */
1632                                 if (ia->flag & ACT_IPOFORCE) {
1633                                         uiDefButBitS(block, TOG, ACT_IPOFORCE_LOCAL, 0, 
1634                                                 "L", xco+width-35, yco-44, 15, 19, 
1635                                                 &ia->flag, 0, 0, 0, 0, 
1636                                                 "Let the force-ipo act in local coordinates."); 
1637                                 }
1638                                 
1639                         }
1640                         yco-= ysize;
1641                         break;
1642                 }
1643         case ACT_PROPERTY:
1644                 {
1645                         ysize= 68;
1646                         
1647                         glRects(xco, yco-ysize, xco+width, yco);
1648                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1649                         
1650                         pa= act->data;
1651                         
1652                         str= "Type   %t|Assign   %x0|Add %x1|Copy %x2";
1653                         uiDefButI(block, MENU, B_REDR, str,             xco+30,yco-24,width-60, 19, &pa->type, 0, 31, 0, 0, "Type");
1654                         
1655                         uiDefBut(block, TEX, 1, "Prop: ",               xco+30,yco-44,width-60, 19, pa->name, 0, 31, 0, 0, "Property name");
1656                         
1657                         if(pa->type==ACT_PROP_COPY) {
1658                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-64, (width-20)/2, 19, &(pa->ob), "Copy from this Object");
1659                                 uiDefBut(block, TEX, 1, "Prop: ",               xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, 31, 0, 0, "Copy this property");
1660                         }
1661                         else {
1662                                 uiDefBut(block, TEX, 1, "Value: ",              xco+30,yco-64,width-60, 19, pa->value, 0, 31, 0, 0, "change with this value");
1663                         }
1664                         yco-= ysize;
1665                         
1666                         break;
1667                 }
1668     case ACT_SOUND:
1669                 {
1670                         ysize = 70;
1671                         
1672                         sa = act->data;
1673                         sa->sndnr = 0;
1674                         
1675                         wval = (width-20)/2;
1676                         glRects(xco, yco-ysize, xco+width, yco);
1677                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1678                         
1679                         if(G.main->sound.first) {
1680                                 IDnames_to_pupstring(&str, "Sound files", NULL, &(G.main->sound), (ID *)sa->sound, &(sa->sndnr));
1681                                 /* reset this value, it is for handling the event */
1682                                 sa->sndnr = 0;
1683                                 uiDefButS(block, MENU, B_SOUNDACT_BROWSE, str, xco+10,yco-22,20,19, &(sa->sndnr), 0, 0, 0, 0, "");      
1684
1685                                 if(sa->sound) {
1686                                         char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4";
1687                                         uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,width-40,19, sa->sound->id.name+2,    0.0, 21.0, 0, 0, "");
1688                                         uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, "");
1689                                         uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->sound->volume, 0.0,  1.0, 0, 0, "Sets the volume of this sound");
1690                                         uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->sound->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound");
1691                                 }
1692                                 MEM_freeN(str);
1693                         } 
1694                         else {
1695                                 uiDefBut(block, LABEL, 0, "Use Sound window (F10) to load samples", xco, yco-24, width, 19, NULL, 0, 0, 0, 0, "");
1696                         }
1697                                         
1698                         yco-= ysize;
1699                         
1700                         break;
1701                 }
1702         case ACT_CD:
1703                 {
1704                         char cd_type_str[] = "Sound mode %t|Play all tracks %x0|Play one track %x1|"
1705                                 "Volume %x3|Stop %x4|Pause %x5|Resume %x6";
1706                         cda = act->data;
1707
1708                         if (cda) {
1709                                 if (cda->track == 0) {
1710                                         cda->track = 1;
1711                                         cda->volume = 1;
1712                                         cda->type = ACT_CD_PLAY_ALL;
1713                                 }
1714                                 
1715                                 if (cda->type == ACT_CD_PLAY_TRACK || cda->type == ACT_CD_LOOP_TRACK) {
1716                                         ysize = 48;
1717                                         glRects(xco, yco-ysize, xco+width, yco);
1718                                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1719                                         uiDefButS(block, NUM, 0, "Track:", xco+10,yco-44,width-20, 19, &cda->track, 1, 99, 0, 0, "Select the track to be played");
1720                                 }
1721                                 else if (cda->type == ACT_CD_VOLUME) {
1722                                         ysize = 48;
1723                                         glRects(xco, yco-ysize, xco+width, yco);
1724                                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1725                                         uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-44,width-20, 19, &cda->volume, 0, 1, 0, 0, "Set the volume for CD playback");
1726                                 }
1727                                 else {
1728                                         ysize = 28;
1729                                         glRects(xco, yco-ysize, xco+width, yco);
1730                                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1731                                 }
1732                                 uiDefButS(block, MENU, B_REDR, cd_type_str,xco+10,yco-22,width-20, 19, &cda->type, 0.0, 0.0, 0, 0, "");
1733                         }
1734                         yco-= ysize;
1735                         break;
1736                 }
1737         case ACT_CAMERA:
1738
1739                 ysize= 48;
1740         
1741                 glRects(xco, yco-ysize, xco+width, yco);
1742                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1743                 
1744                 ca= act->data;
1745         
1746                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object");
1747                 uiDefButF(block, NUM, 0, "Height:",     xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, "");
1748                 
1749                 uiDefButF(block, NUM, 0, "Min:",        xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, "");
1750                 
1751                 if(ca->axis==0) ca->axis= 'x';
1752                 uiDefButS(block, ROW, 0, "X",   xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis");
1753                 uiDefButS(block, ROW, 0, "Y",   xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis");
1754                 
1755                 uiDefButF(block, NUM, 0, "Max:",        xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, "");
1756
1757                 yco-= ysize;
1758         
1759          break;
1760                                 
1761         case ACT_EDIT_OBJECT:
1762                 
1763                 eoa= act->data;
1764
1765                 if(eoa->type==ACT_EDOB_ADD_OBJECT) {
1766                         int wval; /* just a temp width */
1767                         ysize = 72;
1768                         glRects(xco, yco-ysize, xco+width, yco);
1769                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1770          
1771                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object (cant be on an visible layer)");
1772                         uiDefButI(block, NUM, 0, "Time:",       xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives");
1773
1774                         wval= (width-60)/3;
1775                         uiDefBut(block, LABEL, 0, "linV",       xco,           yco-68,   45, 19,
1776                                          NULL, 0, 0, 0, 0,
1777                                          "Velocity upon creation.");
1778                         uiDefButF(block, NUM, 0, "",            xco+45,        yco-68, wval, 19,
1779                                          eoa->linVelocity, -100.0, 100.0, 10, 0,
1780                                          "Velocity upon creation, x component.");
1781                         uiDefButF(block, NUM, 0, "",            xco+45+wval,   yco-68, wval, 19,
1782                                          eoa->linVelocity+1, -100.0, 100.0, 10, 0,
1783                                          "Velocity upon creation, y component.");
1784                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-68, wval, 19,
1785                                          eoa->linVelocity+2, -100.0, 100.0, 10, 0,
1786                                          "Velocity upon creation, z component.");
1787                         uiDefButBitS(block, TOG, 2, 0, "L", xco+45+3*wval, yco-68, 15, 19,
1788                                          &eoa->localflag, 0.0, 0.0, 0, 0,
1789                                          "Apply the transformation locally");
1790
1791                 }
1792                 else if(eoa->type==ACT_EDOB_END_OBJECT) {
1793                         ysize= 28;
1794                         glRects(xco, yco-ysize, xco+width, yco);
1795                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1796                 }
1797                 else if(eoa->type==ACT_EDOB_REPLACE_MESH) {
1798                         ysize= 48;
1799                         glRects(xco, yco-ysize, xco+width, yco);
1800                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1801          
1802                         uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:",               xco+40, yco-44, (width-80), 19, &(eoa->me), "replace the existing mesh with this one");
1803                 }
1804                 else if(eoa->type==ACT_EDOB_TRACK_TO) {
1805                         ysize= 48;
1806                         glRects(xco, yco-ysize, xco+width, yco);
1807                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1808          
1809                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object");
1810                         uiDefButI(block, NUM, 0, "Time:",       xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes");
1811                         uiDefButS(block, TOG, 0, "3D",  xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking");
1812                 }
1813                 
1814                 str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3";
1815                 uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, "");
1816
1817                 yco-= ysize;
1818         
1819         break;
1820  
1821         case ACT_CONSTRAINT:
1822         
1823                 ysize= 44;
1824         
1825                 glRects(xco, yco-ysize, xco+width, yco);
1826                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1827                 
1828                 coa= act->data;
1829                 
1830 /*              str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
1831                 str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
1832                 uiDefButS(block, MENU, 1, str,          xco+10, yco-40, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
1833         
1834                 uiDefButS(block, NUM,           0, "Damp:",     xco+10, yco-20, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
1835                 uiDefBut(block, LABEL,                  0, "Min",       xco+80, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
1836                 uiDefBut(block, LABEL,                  0, "Max",       xco+80+(width-90)/2, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
1837
1838                 if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
1839                 else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
1840                 else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
1841                 else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
1842                 else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
1843                 else fp= coa->minrot+2;
1844                 
1845                 uiDefButF(block, NUM, 0, "",            xco+80, yco-40, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
1846                 uiDefButF(block, NUM, 0, "",            xco+80+(width-90)/2, yco-40, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
1847
1848                 yco-= ysize;
1849         
1850         break;
1851  
1852         case ACT_SCENE:
1853                 sca= act->data; 
1854                 
1855                 if(sca->type==ACT_SCENE_RESTART) { 
1856                         ysize= 28; 
1857                         glRects(xco, yco-ysize, xco+width, yco); 
1858                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1859                 } 
1860                 else if(sca->type==ACT_SCENE_CAMERA) { 
1861                         
1862                         ysize= 48; 
1863                         glRects(xco, yco-ysize, xco+width, yco); 
1864                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1865          
1866                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera"); 
1867                 } 
1868                 else if(sca->type==ACT_SCENE_SET) { 
1869                         
1870                         ysize= 48; 
1871                         glRects(xco, yco-ysize, xco+width, yco); 
1872                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1873         
1874                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); 
1875                 } 
1876                 else if(sca->type==ACT_SCENE_ADD_FRONT) { 
1877                         
1878                         ysize= 48; 
1879                         glRects(xco, yco-ysize, xco+width, yco); 
1880                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1881         
1882                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); 
1883                 } 
1884                 else if(sca->type==ACT_SCENE_ADD_BACK) { 
1885                         
1886                         ysize= 48; 
1887                         glRects(xco, yco-ysize, xco+width, yco); 
1888                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1889         
1890                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); 
1891                 } 
1892                 else if(sca->type==ACT_SCENE_REMOVE) { 
1893                         
1894                         ysize= 48; 
1895                         glRects(xco, yco-ysize, xco+width, yco); 
1896                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1897         
1898                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene");
1899                 } 
1900                 else if(sca->type==ACT_SCENE_SUSPEND) { 
1901                         
1902                         ysize= 48; 
1903                         glRects(xco, yco-ysize, xco+width, yco); 
1904                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1905         
1906                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene");
1907                 } 
1908                 else if(sca->type==ACT_SCENE_RESUME) { 
1909                         
1910                         ysize= 48; 
1911                         glRects(xco, yco-ysize, xco+width, yco); 
1912                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1913         
1914                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene");
1915                 } 
1916
1917                 str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7";
1918                 uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); 
1919
1920                 yco-= ysize; 
1921                 break; 
1922         case ACT_GAME:
1923                 {
1924                         gma = act->data; 
1925                         if (gma->type == ACT_GAME_LOAD)
1926                         {
1927                                 //ysize = 68;
1928                                 ysize = 48;
1929                                 glRects(xco, yco-ysize, xco+width, yco); 
1930                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1931                                 uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file");
1932 //                              uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation");
1933                         }
1934 /*                      else if (gma->type == ACT_GAME_START)
1935                         {
1936                                 ysize = 68; 
1937                                 glRects(xco, yco-ysize, xco+width, yco); 
1938                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1939
1940                                 uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file");
1941                                 uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation");
1942                         }
1943 */                      else if (gma->type == ACT_GAME_RESTART)
1944                         {
1945                                 ysize = 28; 
1946                                 glRects(xco, yco-ysize, xco+width, yco); 
1947                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1948                         }
1949                         else if (gma->type == ACT_GAME_QUIT)
1950                         {
1951                                 ysize = 28; 
1952                                 glRects(xco, yco-ysize, xco+width, yco); 
1953                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
1954                         }
1955
1956                         //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3";
1957                         str = "Scene %t|Start new game%x0|Restart this game%x2|Quit this game %x3";
1958                         uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); 
1959                         
1960                         yco -= ysize; 
1961                         break; 
1962                 }
1963         case ACT_GROUP:
1964                 ga= act->data;
1965
1966                 ysize= 52;
1967
1968                 glRects(xco, yco-ysize, xco+width, yco);
1969                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
1970                 
1971                 str= "GroupKey types   %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5";
1972
1973                 uiDefButS(block, MENU, 1, str,                  xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, "");
1974                 if(ga->type==ACT_GROUP_SET) {
1975                         uiDefBut(block, TEX, 0, "Key: ",                xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, 31.0, 0, 0, "This name defines groupkey to be set");
1976                         uiDefButI(block, NUM, 0, "Frame:",      xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame");
1977                 }
1978                 else if(ga->type==ACT_GROUP_FROM_PROP) {
1979                         uiDefBut(block, TEX, 0, "Prop: ",               xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position");
1980                 }
1981                 else {
1982                         uiDefButI(block, NUM, 0, "Sta",         xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
1983                         uiDefButI(block, NUM, 0, "End",         xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame");
1984                 }
1985                 yco-= ysize;
1986                 break;
1987
1988         case ACT_VISIBILITY:
1989                 ysize = 24;
1990
1991                 glRects(xco, yco-ysize, xco+width, yco);
1992                 uiEmboss((float)xco,
1993                          (float)yco-ysize, (float)xco+width, (float)yco, 1);
1994                 
1995                 visAct = act->data;
1996
1997                 str= "Visibility %t|Visible %x0|Invisible %x1";
1998
1999                 uiDefButI(block, MENU, B_REDR, str,
2000                           xco + 10, yco - 24, width - 20, 19, &visAct->flag,
2001                           0.0, 0.0, 0, 0,
2002                           "Make the object invisible or visible.");
2003 /*
2004                 uiDefButBitI(block, TOG, ACT_VISIBILITY_INVISIBLE, 0,
2005                           "Invisible",
2006                           xco + 10, yco - 24, width - 20, 19, &visAct->flag,
2007                           0.0, 0.0, 0, 0,
2008                           "Make the object invisible or visible.");
2009 */
2010                 yco-= ysize;
2011
2012                 break;
2013                 
2014         case ACT_RANDOM:
2015                 ysize  = 69;
2016
2017                 glRects(xco, yco-ysize, xco+width, yco);
2018                 uiEmboss((float)xco,
2019                                   (float)yco-ysize, (float)xco+width, (float)yco, 1);
2020                 
2021                 randAct = act->data;
2022
2023                 /* 1. seed */
2024                 uiDefButI(block, NUM, 1, "Seed: ",              (xco+10),yco-24, 0.4 *(width-20), 19,
2025                                  &randAct->seed, 0, 1000, 0, 0,
2026                                  "Initial seed of the random generator. Use Python for more freedom. "
2027                                  " (Choose 0 for not random)");
2028
2029                 /* 2. distribution type */
2030                 /* One pick per distribution. These numbers MUST match the #defines  */
2031                 /* in game.h !!!                                                     */
2032                 str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1"
2033                         "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4"
2034                         "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7"
2035                         "|Float Normal %x8|Float Neg. Exp. %x9";
2036                 uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19,
2037                                  &randAct->distribution, 0.0, 0.0, 0, 0,
2038                                  "Choose the type of distribution");
2039
2040                 /* 3. property */
2041                 uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19,
2042                                  &randAct->propname, 0, 31, 0, 0,
2043                                  "Assign the random value to this property"); 
2044
2045                 /*4. and 5. arguments for the distribution*/
2046                 switch (randAct->distribution) {
2047                 case ACT_RANDOM_BOOL_CONST:
2048                         uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19,
2049                                          &randAct->int_arg_1, 2.0, 1, 0, 0,
2050                                          "Always false or always true");                        
2051                         break;
2052                 case ACT_RANDOM_BOOL_UNIFORM:
2053                         uiDefBut(block, LABEL, 0, "     Do a 50-50 pick.",      (xco+10), yco-64, (width-20), 19,
2054                                          NULL, 0, 0, 0, 0,
2055                                          "Choose between true and false, 50% chance each.");
2056                         break;
2057                 case ACT_RANDOM_BOOL_BERNOUILLI:
2058                         uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19,
2059                                          &randAct->float_arg_1, 0.0, 1.0, 0, 0,
2060                                          "Pick a number between 0 and 1. Success if you stay "
2061                                          "below this value");                   
2062                         break;
2063                 case ACT_RANDOM_INT_CONST:
2064                         uiDefButI(block, NUM, 1, "Value: ",             (xco+10), yco-64, (width-20), 19,
2065                                          &randAct->int_arg_1, -1000, 1000, 0, 0,
2066                                          "Always return this number");
2067                         break;
2068                 case ACT_RANDOM_INT_UNIFORM:
2069                         uiDefButI(block, NUM, 1, "Min: ",               (xco+10), yco-64, (width-20)/2, 19,
2070                                          &randAct->int_arg_1, -1000, 1000, 0, 0,
2071                                          "Choose a number from a range. "
2072                                          "Lower boundary of the range.");
2073                         uiDefButI(block, NUM, 1, "Max: ",               (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
2074                                          &randAct->int_arg_2, -1000, 1000, 0, 0,
2075                                          "Choose a number from a range. "
2076                                          "Upper boundary of the range.");
2077                         break;
2078                 case ACT_RANDOM_INT_POISSON:
2079                         uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19,
2080                                          &randAct->float_arg_1, 0.01, 100.0, 0, 0,
2081                                          "Expected mean value of the distribution.");                                           
2082                         break;
2083                 case ACT_RANDOM_FLOAT_CONST:
2084                         uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19,
2085                                          &randAct->float_arg_1, 0.0, 1.0, 0, 0,
2086                                          "Always return this number");
2087                         break;
2088                 case ACT_RANDOM_FLOAT_UNIFORM:
2089                         uiDefButF(block, NUM, 1, "Min: ",               (xco+10), yco-64, (width-20)/2, 19,
2090                                          &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
2091                                          "Choose a number from a range. "
2092                                          "Lower boundary of the range.");
2093                         uiDefButF(block, NUM, 1, "Max: ",               (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
2094                                          &randAct->float_arg_2, -10000.0, 10000.0, 0, 0,
2095                                          "Choose a number from a range. "
2096                                          "Upper boundary of the range.");
2097                         break;
2098                 case ACT_RANDOM_FLOAT_NORMAL:
2099                         uiDefButF(block, NUM, 1, "Mean: ",              (xco+10), yco-64, (width-20)/2, 19,
2100                                          &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
2101                                          "A normal distribution. Mean of the distribution.");
2102                         uiDefButF(block, NUM, 1, "SD: ",                (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
2103                                          &randAct->float_arg_2, 0.0, 10000.0, 0, 0,
2104                                          "A normal distribution. Standard deviation of the "
2105                                          "distribution.");
2106                         break;
2107                 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
2108                         uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19,
2109                                          &randAct->float_arg_1, 0.001, 10000.0, 0, 0,
2110                                          "Negative exponential dropoff.");
2111                         break;
2112                 default:
2113                         ; /* don't know what this distro is... can be useful for testing */
2114                         /* though :)                                                     */
2115                 }
2116
2117                 yco-= ysize;
2118                 break;
2119         case ACT_MESSAGE:
2120                 ma = act->data;
2121
2122 #define MESSAGE_SENSOR_TO_FIELD_WORKS   /* Really?  Not really.  Don't remove this ifdef yet */
2123
2124 #ifdef MESSAGE_SENSOR_TO_FIELD_WORKS
2125                 ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */
2126 #else
2127                 ysize = 4 + (2 * 24); /* footer + number of lines * 24 pixels/line */
2128 #endif
2129                 glRects(xco, yco-ysize, xco+width, yco);
2130                 uiEmboss((float)xco,        (float)yco-ysize,
2131                                  (float)xco+width,  (float)yco, 1);
2132
2133                 myline=1;
2134
2135
2136 #ifdef MESSAGE_SENSOR_TO_FIELD_WORKS
2137                 /* line 1: To */
2138                 uiDefBut(block, TEX, 1, "To: ",
2139                         (xco+10), (yco-(myline++*24)), (width-20), 19,
2140                         &ma->toPropName, 0, 31, 0, 0,
2141                         "Optional send message to objects with this name only"
2142                         ", or empty to broadcast");
2143
2144 #endif
2145
2146                 /* line 2: Message Subject */
2147                 uiDefBut(block, TEX, 1, "Subject: ",
2148                 (xco+10), (yco-(myline++*24)), (width-20), 19,
2149                 &ma->subject, 0, 31, 0, 0,
2150                 "Optional message subject. This is what can be filtered on.");
2151
2152                 /* line 3: Text/Property */
2153                 uiDefButBitS(block, TOG, 1, B_REDR, "T/P",
2154                         (xco+10),(yco-(myline*24)), (0.20 * (width-20)), 19,
2155                         &ma->bodyType, 0.0, 0.0, 0, 0,
2156                         "Toggle message type: either Text or a PropertyName.");
2157
2158                 if (ma->bodyType == ACT_MESG_MESG)
2159                 {
2160                 /* line 3: Message Body */
2161                 uiDefBut(block, TEX, 1, "Body: ",
2162                 (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
2163                 &ma->body, 0, 31, 0, 0,
2164                 "Optional message body Text");
2165                 } else
2166                 {
2167                         /* line 3: Property body (set by property) */
2168                         uiDefBut(block, TEX, 1, "Propname: ",
2169                 (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
2170                         &ma->body, 0, 31, 0, 0,
2171                         "The message body will be set by the Property Value");
2172                 }
2173                 
2174                 yco -= ysize;
2175                 break;
2176         case ACT_2DFILTER:
2177                 tdfa = act->data;
2178
2179                 ysize = 50;
2180                 if(tdfa->type == ACT_2DFILTER_CUSTOMFILTER)
2181                 {
2182                         ysize +=20;
2183                 }
2184         glRects( xco, yco-ysize, xco+width, yco ); 
2185                 uiEmboss( (float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1 );
2186
2187                 switch(tdfa->type)
2188                 {
2189                         case ACT_2DFILTER_MOTIONBLUR:
2190                                 if(!tdfa->flag)
2191                                 {
2192                                         uiDefButS(block, TOG, B_REDR, "D",      xco+30,yco-44,19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur");
2193                                         uiDefButF(block, NUM, B_REDR, "Value:", xco+52,yco-44,width-82,19,&tdfa->float_arg,0.0,1.0,0.0,0.0,"Set motion blur value");
2194                                 }
2195                                 else
2196                                 {
2197                                         uiDefButS(block, TOG, B_REDR, "Disabled",       xco+30,yco-44,width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur");
2198                                 }
2199                                 break;
2200                         case ACT_2DFILTER_BLUR:
2201                         case ACT_2DFILTER_SHARPEN:
2202                         case ACT_2DFILTER_DILATION:
2203                         case ACT_2DFILTER_EROSION:
2204                         case ACT_2DFILTER_LAPLACIAN:
2205                         case ACT_2DFILTER_SOBEL:
2206                         case ACT_2DFILTER_PREWITT:
2207                         case ACT_2DFILTER_GRAYSCALE:
2208                         case ACT_2DFILTER_SEPIA:
2209                         case ACT_2DFILTER_INVERT:
2210                         case ACT_2DFILTER_NOFILTER:
2211                         case ACT_2DFILTER_DISABLED:
2212                         case ACT_2DFILTER_ENABLED:
2213                                 uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
2214                                 break;
2215                         case ACT_2DFILTER_CUSTOMFILTER:
2216                                 uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
2217                                 uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
2218                                 break;
2219                 }
2220                 
2221                 str= "2D Filter   %t|Motion Blur   %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|"
2222                                 "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|"
2223                                 "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|";
2224                 uiDefButS(block, MENU, B_REDR, str,     xco+30,yco-24,width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type");
2225                 
2226                 yco -= ysize;
2227         break;
2228         case ACT_PARENT:
2229                 parAct = act->data; 
2230
2231                 if(parAct->type==ACT_PARENT_SET) { 
2232                         
2233                         ysize= 48; 
2234                         glRects(xco, yco-ysize, xco+width, yco); 
2235                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
2236          
2237                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent"); 
2238                 }
2239                 else if(parAct->type==ACT_PARENT_REMOVE) { 
2240                         
2241                         ysize= 28; 
2242                         glRects(xco, yco-ysize, xco+width, yco); 
2243                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
2244                 }
2245
2246                 str= "Parent %t|Set Parent %x0|Remove Parent %x1";
2247                 uiDefButI(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &parAct->type, 0.0, 0.0, 0, 0, ""); 
2248
2249                 yco-= ysize; 
2250                 break; 
2251         default:
2252                 ysize= 4;
2253
2254                 glRects(xco, yco-ysize, xco+width, yco);
2255                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
2256                 
2257                 yco-= ysize;
2258                 break;
2259         }
2260
2261         uiBlockSetEmboss(block, UI_EMBOSSM);
2262
2263         return yco-4;
2264 }
2265
2266 static void do_sensor_menu(void *arg, int event)
2267 {       
2268         ID **idar;
2269         Object *ob;
2270         bSensor *sens;
2271         short count, a;
2272         
2273         idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
2274         
2275         for(a=0; a<count; a++) {
2276                 ob= (Object *)idar[a];
2277                 if(event==0 || event==2) ob->scaflag |= OB_SHOWSENS;
2278                 else if(event==1) ob->scaflag &= ~OB_SHOWSENS;
2279         }
2280                 
2281         for(a=0; a<count; a++) {
2282                 ob= (Object *)idar[a];
2283                 sens= ob->sensors.first;
2284                 while(sens) {
2285                         if(event==2) sens->flag |= SENS_SHOW;
2286                         else if(event==3) sens->flag &= ~SENS_SHOW;
2287                         sens= sens->next;
2288                 }
2289         }
2290
2291         if(idar) MEM_freeN(idar);
2292         allqueue(REDRAWBUTSLOGIC, 0);
2293 }
2294
2295 static uiBlock *sensor_menu(void *arg_unused)
2296 {
2297         uiBlock *block;
2298         int yco=0;
2299         
2300         block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win);
2301         uiBlockSetButmFunc(block, do_sensor_menu, NULL);
2302         
2303         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
2304         uiDefBut(block, BUTM, 1, "Hide Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
2305         uiDefBut(block, SEPR, 0, "",    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
2306         uiDefBut(block, BUTM, 1, "Show Sensors",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
2307         uiDefBut(block, BUTM, 1, "Hide Sensors",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
2308
2309         uiBlockSetDirection(block, UI_TOP);
2310         
2311         return block;
2312 }
2313
2314 static void do_controller_menu(void *arg, int event)
2315 {       
2316         ID **idar;
2317         Object *ob;
2318         bController *cont;
2319         short count, a;
2320         
2321         idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
2322         
2323         for(a=0; a<count; a++) {
2324                 ob= (Object *)idar[a];
2325                 if(event==0 || event==2) ob->scaflag |= OB_SHOWCONT;
2326                 else if(event==1) ob->scaflag &= ~OB_SHOWCONT;
2327         }
2328
2329         for(a=0; a<count; a++) {
2330                 ob= (Object *)idar[a];
2331                 cont= ob->controllers.first;
2332                 while(cont) {
2333                         if(event==2) cont->flag |= CONT_SHOW;
2334                         else if(event==3) cont->flag &= ~CONT_SHOW;
2335                         cont= cont->next;
2336                 }
2337         }
2338
2339         if(idar) MEM_freeN(idar);
2340         allqueue(REDRAWBUTSLOGIC, 0);
2341 }
2342
2343 static uiBlock *controller_menu(void *arg_unused)
2344 {
2345         uiBlock *block;
2346         int yco=0;
2347         
2348         block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win);
2349         uiBlockSetButmFunc(block, do_controller_menu, NULL);
2350         
2351         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
2352         uiDefBut(block, BUTM, 1, "Hide Objects",        0,(short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
2353         uiDefBut(block, SEPR, 0, "",                                    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
2354         uiDefBut(block, BUTM, 1, "Show Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
2355         uiDefBut(block, BUTM, 1, "Hide Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
2356
2357         uiBlockSetDirection(block, UI_TOP);
2358         
2359         return block;
2360 }
2361
2362 static void do_actuator_menu(void *arg, int event)
2363 {       
2364         ID **idar;
2365         Object *ob;
2366         bActuator *act;
2367         short count, a;
2368         
2369         idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
2370         
2371         for(a=0; a<count; a++) {
2372                 ob= (Object *)idar[a];
2373                 if(event==0 || event==2) ob->scaflag |= OB_SHOWACT;
2374                 else if(event==1) ob->scaflag &= ~OB_SHOWACT;
2375         }
2376
2377         for(a=0; a<count; a++) {
2378                 ob= (Object *)idar[a];
2379                 act= ob->actuators.first;
2380                 while(act) {
2381                         if(event==2) act->flag |= ACT_SHOW;
2382                         else if(event==3) act->flag &= ~ACT_SHOW;
2383                         act= act->next;
2384                 }
2385         }
2386
2387         if(idar) MEM_freeN(idar);
2388         allqueue(REDRAWBUTSLOGIC, 0);
2389 }
2390
2391 static uiBlock *actuator_menu(void *arg_unused)
2392 {
2393         uiBlock *block;
2394         int xco=0;
2395         
2396         block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win);
2397         uiBlockSetButmFunc(block, do_actuator_menu, NULL);
2398         
2399         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
2400         uiDefBut(block, BUTM, 1, "Hide Objects",        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
2401         uiDefBut(block, SEPR, 0, "",    0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
2402         uiDefBut(block, BUTM, 1, "Show Actuators",      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
2403         uiDefBut(block, BUTM, 1, "Hide Actuators",      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
2404
2405         uiBlockSetDirection(block, UI_TOP);
2406         
2407         return block;
2408 }
2409
2410
2411 void buttons_enji(uiBlock *block, Object *ob)
2412 {
2413         uiDefButBitI(block, TOG, OB_SECTOR, B_SETSECTOR, "Sector",
2414                          10,205,65,19, &ob->gameflag, 0, 0, 0, 0, 
2415                          "All game elements should be in the Sector boundbox");
2416         uiDefButBitI(block, TOG, OB_PROP, B_SETPROP, "Prop",
2417                          75,205,65,19, &ob->gameflag, 0, 0, 0, 0, 
2418                          "An Object fixed within a sector");
2419         uiBlockSetCol(block, BUTPURPLE);
2420         uiDefButBitI(block, TOG, OB_ACTOR, B_SETACTOR, "Actor",
2421                          140,205,65,19, &ob->gameflag, 0, 0, 0, 0, 
2422                          "Objects that are evaluated by the engine ");
2423         if(ob->gameflag & OB_ACTOR) {   
2424                 uiDefButBitI(block, TOG, OB_DYNAMIC, B_SETDYNA, "Dynamic",
2425                                  205,205,75,19, &ob->gameflag, 0, 0, 0, 0, 
2426                                  "Motion defined by laws of physics");
2427                 uiDefButBitI(block, TOG, OB_MAINACTOR, B_SETMAINACTOR, "MainActor",
2428                                  280,205,70,19, &ob->gameflag, 0, 0, 0, 0, "");
2429                 
2430                 if(ob->gameflag & OB_DYNAMIC) {
2431                         uiDefButBitI(block, TOG, OB_DO_FH, B_DIFF, "Do Fh",
2432                                          10,185,50,19, &ob->gameflag, 0, 0, 0, 0, 
2433                                          "Use Fh settings in Materials");
2434                         uiDefButBitI(block, TOG, OB_ROT_FH, B_DIFF, "Rot Fh",
2435                                          60,185,50,19, &ob->gameflag, 0, 0, 0, 0, 
2436                                          "Use face normal to rotate Object");
2437                 
2438                         uiBlockSetCol(block, BUTGREY);
2439                         uiDefButF(block, NUM, B_DIFF, "Mass:",
2440                                          110, 185, 120, 19, &ob->mass, 0.01, 100.0, 10, 0, 
2441                                          "The mass of the Object");
2442                         uiDefButF(block, NUM, REDRAWVIEW3D, "Size:",
2443                                          230, 185, 120, 19, &ob->inertia, 0.01, 10.0, 10, 0, 
2444                                          "Bounding sphere size");
2445                         uiDefButF(block, NUM, B_DIFF, "Damp:",
2446                                          10, 165, 100, 19, &ob->damping, 0.0, 1.0, 10, 0, 
2447                                          "General movement damping");
2448                         uiDefButF(block, NUM, B_DIFF, "RotDamp:",
2449                                          110, 165, 120, 19, &ob->rdamping, 0.0, 1.0, 10, 0, 
2450                                          "General rotation damping");
2451                 }
2452         }
2453
2454 }
2455
2456 void buttons_ketsji(uiBlock *block, Object *ob)
2457 {
2458         uiDefButBitI(block, TOG, OB_ACTOR, B_REDR, "Actor",
2459                           10,205,55,19, &ob->gameflag, 0, 0, 0, 0,
2460                           "Objects that are evaluated by the engine ");
2461         if(ob->gameflag & OB_ACTOR) {   
2462                 uiDefButBitI(block, TOG, OB_GHOST, B_REDR, "Ghost", 65,205,55,19, 
2463                                   &ob->gameflag, 0, 0, 0, 0, 
2464                                   "Objects that don't restitute collisions (like a ghost)");
2465                 uiDefButBitI(block, TOG, OB_DYNAMIC, B_REDR, "Dynamic", 120,205,70,19, 
2466                                   &ob->gameflag, 0, 0, 0, 0, 
2467                                   "Motion defined by laws of physics");
2468         
2469                 if(ob->gameflag & OB_DYNAMIC) {
2470                         uiDefButBitI(block, TOG, OB_RIGID_BODY, B_REDR, "Rigid Body", 190,205,80,19, 
2471                                           &ob->gameflag, 0, 0, 0, 0, 
2472                                           "Enable rolling physics");
2473                         uiDefButBitI(block, TOG, OB_COLLISION_RESPONSE, B_REDR, "No sleeping", 270,205,80,19, 
2474                                           &ob->gameflag, 0, 0, 0, 0, 
2475                                           "Disable auto (de)activation");
2476
2477                         uiDefButBitI(block, TOG, OB_DO_FH, B_DIFF, "Do Fh", 10,185,50,19, 
2478                                           &ob->gameflag, 0, 0, 0, 0, 
2479                                           "Use Fh settings in Materials");
2480                         uiDefButBitI(block, TOG, OB_ROT_FH, B_DIFF, "Rot Fh", 60,185,50,19, 
2481                                           &ob->gameflag, 0, 0, 0, 0, 
2482                                           "Use face normal to rotate Object");
2483                         uiDefButF(block, NUM, B_DIFF, "Mass:", 110, 185, 80, 19, 
2484                                           &ob->mass, 0.01, 10000.0, 10, 0, 
2485                                           "The mass of the Object");
2486                         uiDefButF(block, NUM, REDRAWVIEW3D, "Radius:", 190, 185, 80, 19, 
2487                                           &ob->inertia, 0.01, 10.0, 10, 0, 
2488                                           "Bounding sphere radius");
2489                         uiDefButF(block, NUM, B_DIFF, "Form:", 270, 185, 80, 19, 
2490                                           &ob->formfactor, 0.01, 100.0, 10, 0, 
2491                                           "Form factor");
2492
2493                         uiDefButF(block, NUM, B_DIFF, "Damp:", 10, 165, 100, 19, 
2494                                           &ob->damping, 0.0, 1.0, 10, 0, 
2495                                           "General movement damping");
2496                         uiDefButF(block, NUM, B_DIFF, "RotDamp:", 110, 165, 120, 19, 
2497                                           &ob->rdamping, 0.0, 1.0, 10, 0, 
2498                                           "General rotation damping");
2499                         uiDefButBitI(block, TOG, OB_ANISOTROPIC_FRICTION, B_REDR, "Anisotropic", 
2500                                           230, 165, 120, 19,
2501                                           &ob->gameflag, 0.0, 1.0, 10, 0,
2502                                           "Enable anisotropic friction");                       
2503                 }
2504
2505                 if (ob->gameflag & OB_ANISOTROPIC_FRICTION) {
2506                         uiDefButF(block, NUM, B_DIFF, "x friction:", 10, 145, 114, 19,
2507                                           &ob->anisotropicFriction[0], 0.0, 1.0, 10, 0,
2508                                           "Relative friction coefficient in the x-direction.");
2509                         uiDefButF(block, NUM, B_DIFF, "y friction:", 124, 145, 113, 19,
2510                                           &ob->anisotropicFriction[1], 0.0, 1.0, 10, 0,
2511                                           "Relative friction coefficient in the y-direction.");
2512                         uiDefButF(block, NUM, B_DIFF, "z friction:", 237, 145, 113, 19,
2513                                           &ob->anisotropicFriction[2], 0.0, 1.0, 10, 0,
2514                                           "Relative friction coefficient in the z-direction.");
2515                 }
2516         }
2517
2518         if (!(ob->gameflag & OB_GHOST)) {
2519                 uiBlockBeginAlign(block);
2520                 uiDefButBitI(block, TOG, OB_BOUNDS, B_REDR, "Bounds", 10, 125, 75, 19,
2521                                 &ob->gameflag, 0, 0,0, 0,
2522                                 "Specify a bounds object for physics");
2523                 if (ob->gameflag & OB_BOUNDS) {
2524                         uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4",
2525                                 85, 125, 160, 19, &ob->boundtype, 0, 0, 0, 0, "Selects the collision type");
2526                         uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 250,125,100,19, 
2527                                           &ob->gameflag, 0, 0, 0, 0, 
2528                                           "Add Children");
2529                 }
2530                 uiBlockEndAlign(block);
2531         }
2532 }
2533
2534 void buttons_bullet(uiBlock *block, Object *ob)
2535 {
2536         uiBlockBeginAlign(block);
2537         uiDefButBitI(block, TOG, OB_ACTOR, B_REDR, "Actor",
2538                           10,205,55,19, &ob->gameflag, 0, 0, 0, 0,
2539                           "Objects that are evaluated by the engine ");
2540         if(ob->gameflag & OB_ACTOR) {   
2541                 uiDefButBitI(block, TOG, OB_GHOST, B_REDR, "Ghost", 65,205,55,19, 
2542                                   &ob->gameflag, 0, 0, 0, 0, 
2543                                   "Objects that don't restitute collisions (like a ghost)");
2544                 uiDefButBitI(block, TOG, OB_DYNAMIC, B_REDR, "Dynamic", 120,205,70,19, 
2545                                   &ob->gameflag, 0, 0, 0, 0, 
2546                                   "Motion defined by laws of physics");
2547         
2548                 if(ob->gameflag & OB_DYNAMIC) {
2549                         uiDefButBitI(block, TOG, OB_RIGID_BODY, B_REDR, "Rigid Body", 190,205,80,19, 
2550                                           &ob->gameflag, 0, 0, 0, 0, 
2551                                           "Enable rolling physics");
2552                         uiDefButBitI(block, TOG, OB_COLLISION_RESPONSE, B_REDR, "No sleeping", 270,205,80,19, 
2553                                           &ob->gameflag, 0, 0, 0, 0, 
2554                                           "Disable auto (de)activation");
2555
2556                         uiDefButF(block, NUM, B_DIFF, "Mass:", 10, 185, 170, 19, 
2557                                           &ob->mass, 0.01, 10000.0, 10, 2, 
2558                                           "The mass of the Object");
2559                         uiDefButF(block, NUM, REDRAWVIEW3D, "Radius:", 180, 185, 170, 19, 
2560                                           &ob->inertia, 0.01, 10.0, 10, 2, 
2561                                           "Bounding sphere radius");
2562
2563                         uiDefButF(block, NUMSLI, B_DIFF, "Damp ", 10, 165, 150, 19, 
2564                                           &ob->damping, 0.0, 1.0, 10, 0, 
2565                                           "General movement damping");
2566                         uiDefButF(block, NUMSLI, B_DIFF, "RotDamp ", 160, 165, 190, 19, 
2567                                           &ob->rdamping, 0.0, 1.0, 10, 0, 
2568                                           "General rotation damping");
2569                 }
2570         }
2571         uiBlockEndAlign(block);
2572
2573         uiBlockBeginAlign(block);
2574         uiDefButBitI(block, TOG, OB_BOUNDS, B_REDR, "Bounds", 10, 125, 75, 19,
2575                      &ob->gameflag, 0, 0,0, 0,
2576                      "Specify a bounds object for physics");
2577         if (ob->gameflag & OB_BOUNDS) {
2578                 uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4",
2579                   //almost ready to enable this one:                    uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4|Dynamic Mesh %x5|",
2580                           85, 125, 160, 19, &ob->boundtype, 0, 0, 0, 0, "Selects the collision type");
2581                 uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 250,125,100,19, 
2582                              &ob->gameflag, 0, 0, 0, 0, 
2583                              "Add Children");
2584         }
2585         uiBlockEndAlign(block);
2586 }
2587
2588 /* never used, see CVS 1.134 for the code */
2589 /*  static FreeCamera *new_freecamera(void) */
2590
2591 /* never used, see CVS 1.120 for the code */
2592 /*  static uiBlock *freecamera_menu(void) */
2593
2594
2595 void logic_buts(void)
2596 {
2597         ID **idar;
2598         Object *ob;
2599         bProperty *prop;
2600         bSensor *sens;
2601         bController *cont;
2602         bActuator *act;
2603         uiBlock *block;
2604         uiBut *but;
2605         World *wrld;
2606         int a;
2607         short xco, yco, count, width, ycoo;
2608         char *pupstr, name[32];
2609
2610         wrld= G.scene->world;
2611
2612         ob= OBACT;
2613
2614         if(ob==0) return;
2615         uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2616
2617         sprintf(name, "buttonswin %d", curarea->win);
2618         block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSS, UI_HELV, curarea->win);
2619         
2620         uiBlockSetCol(block, TH_BUT_SETTING2);
2621
2622         if(wrld) {
2623                 switch(wrld->physicsEngine) {
2624                 case WOPHY_ENJI:
2625                         buttons_enji(block, ob);
2626                         break;
2627                 case WOPHY_BULLET:
2628                         buttons_bullet(block, ob);
2629                         break;
2630                 default:
2631                         buttons_ketsji(block, ob);
2632                         break;
2633                 }
2634         }
2635         else buttons_ketsji(block, ob);
2636         
2637         uiBlockSetCol(block, TH_AUTO);
2638         uiBlockBeginAlign(block);
2639         uiDefBut(block, BUT, B_ADD_PROP, "Add Property",                10, 90, 340, 24,
2640                          NULL, 0.0, 100.0, 100, 0,
2641                          "");
2642         
2643         pupstr= "Types %t|Bool %x0|Int %x1|Float %x2|String %x3|Timer %x5";
2644         
2645         a= 0;
2646         prop= ob->prop.first;
2647         while(prop) {
2648                 but= uiDefBut(block, BUT, 1, "Del",             10, (short)(70-20*a), 40, 20, NULL, 0.0, 0.0, 1, (float)a, "");
2649                 uiButSetFunc(but, del_property, prop, NULL);
2650                 uiDefButS(block, MENU, B_CHANGE_PROP, pupstr,           50, (short)(70-20*a), 60, 20, &prop->type, 0, 0, 0, 0, "");
2651                 but= uiDefBut(block, TEX, 1, "Name:",                                   110, (short)(70-20*a), 110, 20, prop->name, 0, 31, 0, 0, "");
2652                 uiButSetFunc(but, make_unique_prop_names_cb, prop->name, (void*) 1);
2653                 
2654                 if(prop->type==PROP_BOOL) {
2655                         uiDefButBitI(block, TOG, 1, B_REDR, "True",             220, (short)(70-20*a), 55, 20, &prop->data, 0, 0, 0, 0, "");
2656                         uiDefButBitI(block, TOGN, 1, B_REDR, "False",   270, (short)(70-20*a), 55, 20, &prop->data, 0, 0, 0, 0, "");
2657                 }
2658                 else if(prop->type==PROP_INT) 
2659                         uiDefButI(block, NUM, B_REDR, "",                       220, (short)(70-20*a), 110, 20, &prop->data, -10000, 10000, 0, 0, "");
2660                 else if(prop->type==PROP_FLOAT) 
2661                         uiDefButF(block, NUM, B_REDR, "",                       220, (short)(70-20*a), 110, 20, (float*) &prop->data, -10000, 10000, 100, 3, "");
2662                 else if(prop->type==PROP_STRING) 
2663                         uiDefBut(block, TEX, B_REDR, "",                                220, (short)(70-20*a), 110, 20, prop->poin, 0, 127, 0, 0, "");
2664                 else if(prop->type==PROP_TIME) 
2665                         uiDefButF(block, NUM, B_REDR, "",                       220, (short)(70-20*a), 110, 20, (float*) &prop->data, -10000, 10000, 100, 3, "");
2666                 
2667                 uiDefButBitS(block, TOG, PROP_DEBUG, B_REDR, "D",               330, (short)(70-20*a), 20, 20, &prop->flag, 0, 0, 0, 0, "Print Debug info");
2668                 
2669                 a++;
2670                 prop= prop->next;
2671                 
2672         }
2673         uiBlockEndAlign(block);
2674
2675         uiClearButLock();
2676
2677         idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
2678         
2679         /* ******************************* */
2680         xco= 375; yco= 170; width= 230;
2681
2682         uiBlockSetEmboss(block, UI_EMBOSSP);
2683         uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, "");
2684         uiBlockSetEmboss(block, UI_EMBOSS);
2685         
2686         uiBlockBeginAlign(block);
2687         uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
2688         uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
2689         uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
2690         uiBlockEndAlign(block);
2691         
2692         for(a=0; a<count; a++) {
2693                 ob= (Object *)idar[a];
2694                 uiClearButLock();
2695                 uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2696                 
2697                 if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
2698                 
2699                 /* presume it is only objects for now */
2700                 uiBlockSetEmboss(block, UI_EMBOSS);
2701                 uiBlockBeginAlign(block);
2702                 if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
2703                 uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
2704                 if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
2705                 uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
2706                 uiBlockEndAlign(block);
2707                 yco-=20;
2708                 
2709                 if(ob->scaflag & OB_SHOWSENS) {
2710                         
2711                         sens= ob->sensors.first;
2712                         while(sens) {
2713                                 uiBlockSetEmboss(block, UI_EMBOSSM);
2714                                 uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,      xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
2715                                 uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
2716
2717                                 ycoo= yco;
2718                                 if(sens->flag & SENS_SHOW)
2719                                 {
2720                                         uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),     (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
2721                                         but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
2722                                         uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
2723
2724                                         sens->otype= sens->type;
2725                                         yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
2726                                         if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
2727                                 }
2728                                 else {
2729                                         set_col_sensor(sens->type, 1);
2730                                         glRecti(xco+22, yco, xco+width-22,yco+19);
2731                                         but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
2732                                         uiButSetFunc(but, sca_move_sensor, sens, NULL);
2733                                         but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
2734                                         uiButSetFunc(but, sca_move_sensor, sens, NULL);
2735                                 }
2736
2737                                 but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
2738                                 uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
2739
2740                                 yco-=20;
2741
2742                                 sens= sens->next;
2743                         }
2744                         yco-= 6;
2745                 }
2746         }
2747
2748         /* ******************************* */
2749         xco= 675; yco= 170; width= 230;
2750
2751         uiBlockSetEmboss(block, UI_EMBOSSP);
2752         uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
2753         uiBlockSetEmboss(block, UI_EMBOSS);
2754         
2755         uiBlockBeginAlign(block);
2756         uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
2757         uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
2758         uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
2759         uiBlockEndAlign(block);
2760         
2761         ob= OBACT;
2762         
2763         for(a=0; a<count; a++) {
2764                 ob= (Object *)idar[a];
2765                 uiClearButLock();
2766                 uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2767                 if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
2768
2769                 /* presume it is only objects for now */
2770                 uiBlockSetEmboss(block, UI_EMBOSS);
2771                 uiBlockBeginAlign(block);
2772                 if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
2773                 uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
2774                 if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
2775                 uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
2776                 uiBlockEndAlign(block);
2777                 yco-=20;
2778                 
2779                 if(ob->scaflag & OB_SHOWCONT) {
2780                 
2781                         cont= ob->controllers.first;
2782                         while(cont) {
2783                                 uiBlockSetEmboss(block, UI_EMBOSSM);
2784                                 uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,      xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
2785                                 uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
2786