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