Blender  V2.59
sca.c
Go to the documentation of this file.
00001 /*
00002  * $Id: sca.c 37455 2011-06-13 17:08:33Z dfelinto $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * these all are linked to objects (listbase)
00029  * all data is 'direct data', not Blender lib data.
00030  */
00031 
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <float.h>
00040 
00041 #include "MEM_guardedalloc.h"
00042 
00043 #include "DNA_controller_types.h"
00044 #include "DNA_sensor_types.h"
00045 #include "DNA_actuator_types.h"
00046 #include "DNA_object_types.h"
00047 
00048 #include "BLI_blenlib.h"
00049 #include "BKE_utildefines.h"
00050 #include "BKE_global.h"
00051 #include "BKE_main.h"
00052 #include "BKE_library.h"
00053 #include "BKE_sca.h"
00054 
00055 /* ******************* SENSORS ************************ */
00056 
00057 void free_sensor(bSensor *sens)
00058 {
00059         if(sens->links) MEM_freeN(sens->links);
00060         if(sens->data) MEM_freeN(sens->data);
00061         MEM_freeN(sens);
00062         
00063 }
00064 
00065 void free_sensors(ListBase *lb)
00066 {
00067         bSensor *sens;
00068         
00069         while((sens= lb->first)) {
00070                 BLI_remlink(lb, sens);
00071                 free_sensor(sens);
00072         }
00073 }
00074 
00075 bSensor *copy_sensor(bSensor *sens)
00076 {
00077         bSensor *sensn;
00078         
00079         sensn= MEM_dupallocN(sens);
00080         sensn->flag |= SENS_NEW;
00081         if(sens->data) {
00082                 sensn->data= MEM_dupallocN(sens->data);
00083         }
00084 
00085         if(sens->links) sensn->links= MEM_dupallocN(sens->links);
00086         
00087         return sensn;
00088 }
00089 
00090 void copy_sensors(ListBase *lbn, ListBase *lbo)
00091 {
00092         bSensor *sens, *sensn;
00093         
00094         lbn->first= lbn->last= NULL;
00095         sens= lbo->first;
00096         while(sens) {
00097                 sensn= copy_sensor(sens);
00098                 BLI_addtail(lbn, sensn);
00099                 sens= sens->next;
00100         }
00101 }
00102 
00103 void init_sensor(bSensor *sens)
00104 {
00105         /* also use when sensor changes type */
00106         bNearSensor *ns;
00107         bMouseSensor *ms;
00108         bJoystickSensor *js;
00109         bRaySensor *rs;
00110         
00111         if(sens->data) MEM_freeN(sens->data);
00112         sens->data= NULL;
00113         sens->pulse = 0;
00114         
00115         switch(sens->type) {
00116         case SENS_ALWAYS:
00117                 sens->pulse = 0;
00118                 break;
00119         case SENS_TOUCH:
00120                 sens->data= MEM_callocN(sizeof(bTouchSensor), "touchsens");
00121                 break;
00122         case SENS_NEAR:
00123                 ns=sens->data= MEM_callocN(sizeof(bNearSensor), "nearsens");
00124                 ns->dist= 1.0;
00125                 ns->resetdist= 2.0;
00126                 break;
00127         case SENS_KEYBOARD:
00128                 sens->data= MEM_callocN(sizeof(bKeyboardSensor), "keysens");
00129                 break;
00130         case SENS_PROPERTY:
00131                 sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
00132                 break;
00133         case SENS_ARMATURE:
00134                 sens->data= MEM_callocN(sizeof(bArmatureSensor), "armsens");
00135                 break;
00136         case SENS_ACTUATOR:
00137                 sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
00138                 break;
00139         case SENS_DELAY:
00140                 sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
00141                 break;
00142         case SENS_MOUSE:
00143                 ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
00144                 ms->type= 1; // LEFTMOUSE workaround because Mouse Sensor types enum starts in 1
00145                 break;
00146         case SENS_COLLISION:
00147                 sens->data= MEM_callocN(sizeof(bCollisionSensor), "colsens");
00148                 break;
00149         case SENS_RADAR:
00150                 sens->data= MEM_callocN(sizeof(bRadarSensor), "radarsens");
00151                 break;
00152         case SENS_RANDOM:
00153                 sens->data= MEM_callocN(sizeof(bRandomSensor), "randomsens");
00154                 break;
00155         case SENS_RAY:
00156                 sens->data= MEM_callocN(sizeof(bRaySensor), "raysens");
00157                 rs = sens->data;
00158                 rs->range = 0.01f;
00159                 break;
00160         case SENS_MESSAGE:
00161                 sens->data= MEM_callocN(sizeof(bMessageSensor), "messagesens");
00162                 break;
00163         case SENS_JOYSTICK:
00164                 sens->data= MEM_callocN(sizeof(bJoystickSensor), "joysticksens");
00165                 js= sens->data;
00166                 js->hatf = SENS_JOY_HAT_UP;
00167                 js->axis = 1;
00168                 js->hat = 1;
00169                 break;
00170         default:
00171                 ; /* this is very severe... I cannot make any memory for this        */
00172                 /* logic brick...                                                    */
00173         }
00174 }
00175 
00176 bSensor *new_sensor(int type)
00177 {
00178         bSensor *sens;
00179 
00180         sens= MEM_callocN(sizeof(bSensor), "Sensor");
00181         sens->type= type;
00182         sens->flag= SENS_SHOW;
00183         
00184         init_sensor(sens);
00185         
00186         strcpy(sens->name, "sensor");
00187 // XXX  make_unique_prop_names(sens->name);
00188         
00189         return sens;
00190 }
00191 
00192 /* ******************* CONTROLLERS ************************ */
00193 
00194 void unlink_controller(bController *cont)
00195 {
00196         bSensor *sens;
00197         Object *ob;
00198         
00199         /* check for controller pointers in sensors */
00200         ob= G.main->object.first;
00201         while(ob) {
00202                 sens= ob->sensors.first;
00203                 while(sens) {
00204                         unlink_logicbricks((void **)&cont, (void ***)&(sens->links), &sens->totlinks);
00205                         sens= sens->next;
00206                 }
00207                 ob= ob->id.next;
00208         }
00209 }
00210 
00211 void unlink_controllers(ListBase *lb)
00212 {
00213         bController *cont;
00214         
00215         for (cont= lb->first; cont; cont= cont->next)
00216                 unlink_controller(cont);        
00217 }
00218 
00219 void free_controller(bController *cont)
00220 {
00221         if(cont->links) MEM_freeN(cont->links);
00222 
00223         /* the controller itself */
00224         if(cont->data) MEM_freeN(cont->data);
00225         MEM_freeN(cont);
00226         
00227 }
00228 
00229 void free_controllers(ListBase *lb)
00230 {
00231         bController *cont;
00232         
00233         while((cont= lb->first)) {
00234                 BLI_remlink(lb, cont);
00235                 if(cont->slinks) MEM_freeN(cont->slinks);
00236                 free_controller(cont);
00237         }
00238 }
00239 
00240 bController *copy_controller(bController *cont)
00241 {
00242         bController *contn;
00243         
00244         cont->mynew=contn= MEM_dupallocN(cont);
00245         contn->flag |= CONT_NEW;
00246         if(cont->data) {
00247                 contn->data= MEM_dupallocN(cont->data);
00248         }
00249 
00250         if(cont->links) contn->links= MEM_dupallocN(cont->links);
00251         contn->slinks= NULL;
00252         contn->totslinks= 0;
00253         
00254         return contn;
00255 }
00256 
00257 void copy_controllers(ListBase *lbn, ListBase *lbo)
00258 {
00259         bController *cont, *contn;
00260         
00261         lbn->first= lbn->last= NULL;
00262         cont= lbo->first;
00263         while(cont) {
00264                 contn= copy_controller(cont);
00265                 BLI_addtail(lbn, contn);
00266                 cont= cont->next;
00267         }
00268 }
00269 
00270 void init_controller(bController *cont)
00271 {
00272         /* also use when controller changes type, leave actuators... */
00273         
00274         if(cont->data) MEM_freeN(cont->data);
00275         cont->data= NULL;
00276         
00277         switch(cont->type) {
00278         case CONT_EXPRESSION:
00279                 cont->data= MEM_callocN(sizeof(bExpressionCont), "expcont");
00280                 break;
00281         case CONT_PYTHON:
00282                 cont->data= MEM_callocN(sizeof(bPythonCont), "pycont");
00283                 break;
00284         }
00285 }
00286 
00287 bController *new_controller(int type)
00288 {
00289         bController *cont;
00290 
00291         cont= MEM_callocN(sizeof(bController), "Controller");
00292         cont->type= type;
00293         cont->flag= CONT_SHOW;
00294 
00295         init_controller(cont);
00296         
00297         strcpy(cont->name, "cont");
00298 // XXX  make_unique_prop_names(cont->name);
00299         
00300         return cont;
00301 }
00302 
00303 /* ******************* ACTUATORS ************************ */
00304 
00305 void unlink_actuator(bActuator *act)
00306 {
00307         bController *cont;
00308         Object *ob;
00309         
00310         /* check for actuator pointers in controllers */
00311         ob= G.main->object.first;
00312         while(ob) {
00313                 cont= ob->controllers.first;
00314                 while(cont) {
00315                         unlink_logicbricks((void **)&act, (void ***)&(cont->links), &cont->totlinks);
00316                         cont= cont->next;
00317                 }
00318                 ob= ob->id.next;
00319         }
00320 }
00321 
00322 void unlink_actuators(ListBase *lb)
00323 {
00324         bActuator *act;
00325         
00326         for (act= lb->first; act; act= act->next)
00327                 unlink_actuator(act);
00328 }
00329 
00330 void free_actuator(bActuator *act)
00331 {
00332         bSoundActuator *sa;
00333 
00334         if(act->data) {
00335                 switch (act->type) {
00336                 case ACT_SOUND:
00337                         sa = (bSoundActuator *) act->data;
00338                         if(sa->sound)
00339                                 id_us_min((ID *) sa->sound);
00340                         break;
00341                 }
00342 
00343                 MEM_freeN(act->data);
00344         }
00345         MEM_freeN(act);
00346 }
00347 
00348 void free_actuators(ListBase *lb)
00349 {
00350         bActuator *act;
00351         
00352         while((act= lb->first)) {
00353                 BLI_remlink(lb, act);
00354                 free_actuator(act);
00355         }
00356 }
00357 
00358 bActuator *copy_actuator(bActuator *act)
00359 {
00360         bActuator *actn;
00361         bSoundActuator *sa;
00362         
00363         act->mynew=actn= MEM_dupallocN(act);
00364         actn->flag |= ACT_NEW;
00365         if(act->data) {
00366                 actn->data= MEM_dupallocN(act->data);
00367         }
00368         
00369         switch (act->type) {
00370                 case ACT_SOUND:
00371                         sa= (bSoundActuator *)act->data;
00372                         if(sa->sound)
00373                                 id_us_plus((ID *) sa->sound);
00374                         break;
00375         }
00376         return actn;
00377 }
00378 
00379 void copy_actuators(ListBase *lbn, ListBase *lbo)
00380 {
00381         bActuator *act, *actn;
00382         
00383         lbn->first= lbn->last= NULL;
00384         act= lbo->first;
00385         while(act) {
00386                 actn= copy_actuator(act);
00387                 BLI_addtail(lbn, actn);
00388                 act= act->next;
00389         }
00390 }
00391 
00392 void init_actuator(bActuator *act)
00393 {
00394         /* also use when actuator changes type */
00395         bCameraActuator *ca;
00396         bObjectActuator *oa;
00397         bRandomActuator *ra;
00398         bSoundActuator *sa;
00399         
00400         if(act->data) MEM_freeN(act->data);
00401         act->data= NULL;
00402         
00403         switch(act->type) {
00404         case ACT_ACTION:
00405         case ACT_SHAPEACTION:
00406                 act->data= MEM_callocN(sizeof(bActionActuator), "actionact");
00407                 break;
00408         case ACT_SOUND:
00409                 sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
00410                 sa->volume = 1.0f;
00411                 sa->sound3D.rolloff_factor = 1.0f;
00412                 sa->sound3D.reference_distance = 1.0f;
00413                 sa->sound3D.max_gain = 1.0f;
00414                 sa->sound3D.cone_inner_angle = 360.0f;
00415                 sa->sound3D.cone_outer_angle = 360.0f;
00416                 sa->sound3D.max_distance = FLT_MAX;
00417                 break;
00418         case ACT_OBJECT:
00419                 act->data= MEM_callocN(sizeof(bObjectActuator), "objectact");
00420                 oa= act->data;
00421                 oa->flag= 15;
00422                 break;
00423         case ACT_IPO:
00424                 act->data= MEM_callocN(sizeof(bIpoActuator), "ipoact");
00425                 break;
00426         case ACT_PROPERTY:
00427                 act->data= MEM_callocN(sizeof(bPropertyActuator), "propact");
00428                 break;
00429         case ACT_CAMERA:
00430                 act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
00431                 ca = act->data;
00432                 ca->axis = ACT_CAMERA_X;
00433                 ca->damping = 1.0/32.0;
00434                 break;
00435         case ACT_EDIT_OBJECT:
00436                 act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
00437                 break;
00438         case ACT_CONSTRAINT:
00439                 act->data= MEM_callocN(sizeof(bConstraintActuator), "cons act");
00440                 break;
00441         case ACT_SCENE:
00442                 act->data= MEM_callocN(sizeof(bSceneActuator), "scene act");
00443                 break;
00444         case ACT_GROUP:
00445                 act->data= MEM_callocN(sizeof(bGroupActuator), "group act");
00446                 break;
00447         case ACT_RANDOM:
00448                 act->data= MEM_callocN(sizeof(bRandomActuator), "random act");
00449                 ra=act->data;
00450                 ra->float_arg_1 = 0.1f;
00451                 break;
00452         case ACT_MESSAGE:
00453                 act->data= MEM_callocN(sizeof(bMessageActuator), "message act");
00454                 break;
00455         case ACT_GAME:
00456                 act->data= MEM_callocN(sizeof(bGameActuator), "game act");
00457                 break;
00458         case ACT_VISIBILITY:
00459                 act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
00460                 break;
00461         case ACT_2DFILTER:
00462                 act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
00463                 break;
00464         case ACT_PARENT:
00465                 act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
00466                 break;
00467         case ACT_STATE:
00468                 act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
00469                 break;
00470         case ACT_ARMATURE:
00471                 act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
00472                 break;
00473         default:
00474                 ; /* this is very severe... I cannot make any memory for this        */
00475                 /* logic brick...                                                    */
00476         }
00477 }
00478 
00479 bActuator *new_actuator(int type)
00480 {
00481         bActuator *act;
00482 
00483         act= MEM_callocN(sizeof(bActuator), "Actuator");
00484         act->type= type;
00485         act->flag= ACT_SHOW;
00486         
00487         init_actuator(act);
00488         
00489         strcpy(act->name, "act");
00490 // XXX  make_unique_prop_names(act->name);
00491         
00492         return act;
00493 }
00494 
00495 /* ******************** GENERAL ******************* */
00496 void clear_sca_new_poins_ob(Object *ob)
00497 {
00498         bSensor *sens;
00499         bController *cont;
00500         bActuator *act;
00501         
00502         sens= ob->sensors.first;
00503         while(sens) {
00504                 sens->flag &= ~SENS_NEW;
00505                 sens= sens->next;
00506         }
00507         cont= ob->controllers.first;
00508         while(cont) {
00509                 cont->mynew= NULL;
00510                 cont->flag &= ~CONT_NEW;
00511                 cont= cont->next;
00512         }
00513         act= ob->actuators.first;
00514         while(act) {
00515                 act->mynew= NULL;
00516                 act->flag &= ~ACT_NEW;
00517                 act= act->next;
00518         }
00519 }
00520 
00521 void clear_sca_new_poins(void)
00522 {
00523         Object *ob;
00524         
00525         ob= G.main->object.first;
00526         while(ob) {
00527                 clear_sca_new_poins_ob(ob);
00528                 ob= ob->id.next;        
00529         }
00530 }
00531 
00532 void set_sca_new_poins_ob(Object *ob)
00533 {
00534         bSensor *sens;
00535         bController *cont;
00536         bActuator *act;
00537         int a;
00538         
00539         sens= ob->sensors.first;
00540         while(sens) {
00541                 if(sens->flag & SENS_NEW) {
00542                         for(a=0; a<sens->totlinks; a++) {
00543                                 if(sens->links[a] && sens->links[a]->mynew)
00544                                         sens->links[a]= sens->links[a]->mynew;
00545                         }
00546                 }
00547                 sens= sens->next;
00548         }
00549 
00550         cont= ob->controllers.first;
00551         while(cont) {
00552                 if(cont->flag & CONT_NEW) {
00553                         for(a=0; a<cont->totlinks; a++) {
00554                                 if( cont->links[a] && cont->links[a]->mynew)
00555                                         cont->links[a]= cont->links[a]->mynew;
00556                         }
00557                 }
00558                 cont= cont->next;
00559         }
00560         
00561         
00562         act= ob->actuators.first;
00563         while(act) {
00564                 if(act->flag & ACT_NEW) {
00565                         if(act->type==ACT_EDIT_OBJECT) {
00566                                 bEditObjectActuator *eoa= act->data;
00567                                 ID_NEW(eoa->ob);
00568                         }
00569                         else if(act->type==ACT_SCENE) {
00570                                 bSceneActuator *sca= act->data;
00571                                 ID_NEW(sca->camera);
00572                         }
00573                         else if(act->type==ACT_CAMERA) {
00574                                 bCameraActuator *ca= act->data;
00575                                 ID_NEW(ca->ob);
00576                         }
00577                         else if(act->type==ACT_OBJECT) {
00578                                 bObjectActuator *oa= act->data;
00579                                 ID_NEW(oa->reference);
00580                         }
00581                         else if(act->type==ACT_MESSAGE) {
00582                                 bMessageActuator *ma= act->data;
00583                                 ID_NEW(ma->toObject);
00584                         }
00585                         else if(act->type==ACT_PARENT) {
00586                                 bParentActuator *para = act->data;
00587                                 ID_NEW(para->ob);
00588                         }
00589                         else if(act->type==ACT_ARMATURE) {
00590                                 bArmatureActuator *aa = act->data;
00591                                 ID_NEW(aa->target);
00592                                 ID_NEW(aa->subtarget);
00593                         }
00594                         else if(act->type==ACT_PROPERTY) {
00595                                 bPropertyActuator *pa= act->data;
00596                                 ID_NEW(pa->ob);
00597                         }
00598                 }
00599                 act= act->next;
00600         }
00601 }
00602 
00603 
00604 void set_sca_new_poins(void)
00605 {
00606         Object *ob;
00607         
00608         ob= G.main->object.first;
00609         while(ob) {
00610                 set_sca_new_poins_ob(ob);
00611                 ob= ob->id.next;        
00612         }
00613 }
00614 
00615 void sca_remove_ob_poin(Object *obt, Object *ob)
00616 {
00617         bSensor *sens;
00618         bMessageSensor *ms;
00619         bActuator *act;
00620         bCameraActuator *ca;
00621         bObjectActuator *oa;
00622         bSceneActuator *sa;
00623         bEditObjectActuator *eoa;
00624         bPropertyActuator *pa;
00625         bMessageActuator *ma;
00626         bParentActuator *para;
00627         bArmatureActuator *aa;
00628 
00629         sens= obt->sensors.first;
00630         while(sens) {
00631                 switch(sens->type) {
00632                 case SENS_MESSAGE:
00633                         ms= sens->data;
00634                         if(ms->fromObject==ob) ms->fromObject= NULL;
00635                 }
00636                 sens= sens->next;
00637         }
00638 
00639         act= obt->actuators.first;
00640         while(act) {
00641                 switch(act->type) {
00642                 case ACT_CAMERA:
00643                         ca= act->data;
00644                         if(ca->ob==ob) ca->ob= NULL;
00645                         break;
00646                 case ACT_OBJECT:
00647                         oa= act->data;
00648                         if(oa->reference==ob) oa->reference= NULL;
00649                         break;
00650                 case ACT_PROPERTY:
00651                         pa= act->data;
00652                         if(pa->ob==ob) pa->ob= NULL;
00653                         break;
00654                 case ACT_SCENE:
00655                         sa= act->data;
00656                         if(sa->camera==ob) sa->camera= NULL;
00657                         break;
00658                 case ACT_EDIT_OBJECT:
00659                         eoa= act->data;
00660                         if(eoa->ob==ob) eoa->ob= NULL;
00661                         break;
00662                 case ACT_MESSAGE:
00663                         ma= act->data;
00664                         if(ma->toObject==ob) ma->toObject= NULL;
00665                         break;
00666                 case ACT_PARENT:
00667                         para = act->data;
00668                         if (para->ob==ob) para->ob = NULL;
00669                         break;
00670                 case ACT_ARMATURE:
00671                         aa = act->data;
00672                         if (aa->target == ob) aa->target = NULL;
00673                         if (aa->subtarget == ob) aa->subtarget = NULL;
00674                         break;
00675                 }
00676                 act= act->next;
00677         }       
00678 }
00679 
00680 /* ******************** INTERFACE ******************* */
00681 void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
00682 {
00683         bSensor *sens, *tmp;
00684 
00685         int val;
00686         val = move_up ? 1:2;
00687 
00688         /* make sure this sensor belongs to this object */
00689         sens= ob->sensors.first;
00690         while(sens) {
00691                 if(sens == sens_to_move) break;
00692                 sens= sens->next;
00693         }
00694         if(!sens) return;
00695 
00696         /* move up */
00697         if( val==1 && sens->prev) {
00698                 for (tmp=sens->prev; tmp; tmp=tmp->prev) {
00699                         if (tmp->flag & SENS_VISIBLE)
00700                                 break;
00701                 }
00702                 if (tmp) {
00703                         BLI_remlink(&ob->sensors, sens);
00704                         BLI_insertlinkbefore(&ob->sensors, tmp, sens);
00705                 }
00706         }
00707         /* move down */
00708         else if( val==2 && sens->next) {
00709                 for (tmp=sens->next; tmp; tmp=tmp->next) {
00710                         if (tmp->flag & SENS_VISIBLE)
00711                                 break;
00712                 }
00713                 if (tmp) {
00714                         BLI_remlink(&ob->sensors, sens);
00715                         BLI_insertlink(&ob->sensors, tmp, sens);
00716                 }
00717         }
00718 }
00719 
00720 void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
00721 {
00722         bController *cont, *tmp;
00723 
00724         int val;
00725         val = move_up ? 1:2;
00726 
00727         /* make sure this controller belongs to this object */
00728         cont= ob->controllers.first;
00729         while(cont) {
00730                 if(cont == cont_to_move) break;
00731                 cont= cont->next;
00732         }
00733         if(!cont) return;
00734 
00735         /* move up */
00736         if( val==1 && cont->prev) {
00737                 /* locate the controller that has the same state mask but is earlier in the list */
00738                 tmp = cont->prev;
00739                 while(tmp) {
00740                         if(tmp->state_mask & cont->state_mask) 
00741                                 break;
00742                         tmp = tmp->prev;
00743                 }
00744                 if (tmp) {
00745                         BLI_remlink(&ob->controllers, cont);
00746                         BLI_insertlinkbefore(&ob->controllers, tmp, cont);
00747                 }
00748         }
00749 
00750         /* move down */
00751         else if( val==2 && cont->next) {
00752                 tmp = cont->next;
00753                 while(tmp) {
00754                         if(tmp->state_mask & cont->state_mask) 
00755                                 break;
00756                         tmp = tmp->next;
00757                 }
00758                 BLI_remlink(&ob->controllers, cont);
00759                 BLI_insertlink(&ob->controllers, tmp, cont);
00760         }
00761 }
00762 
00763 void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
00764 {
00765         bActuator *act, *tmp;
00766         int val;
00767 
00768         val = move_up ? 1:2;
00769 
00770         /* make sure this actuator belongs to this object */
00771         act= ob->actuators.first;
00772         while(act) {
00773                 if(act == act_to_move) break;
00774                 act= act->next;
00775         }
00776         if(!act) return;
00777 
00778         /* move up */
00779         if( val==1 && act->prev) {
00780                 /* locate the first visible actuators before this one */
00781                 for (tmp = act->prev; tmp; tmp=tmp->prev) {
00782                         if (tmp->flag & ACT_VISIBLE)
00783                                 break;
00784                 }
00785                 if (tmp) {
00786                         BLI_remlink(&ob->actuators, act);
00787                         BLI_insertlinkbefore(&ob->actuators, tmp, act);
00788                 }
00789         }
00790         /* move down */
00791         else if( val==2 && act->next) {
00792                 /* locate the first visible actuators after this one */
00793                 for (tmp=act->next; tmp; tmp=tmp->next) {
00794                         if (tmp->flag & ACT_VISIBLE)
00795                                 break;
00796                 }
00797                 if (tmp) {
00798                         BLI_remlink(&ob->actuators, act);
00799                         BLI_insertlink(&ob->actuators, tmp, act);
00800                 }
00801         }
00802 }
00803 
00804 void link_logicbricks(void **poin, void ***ppoin, short *tot, short size)
00805 {
00806         void **old_links= NULL;
00807         
00808         int ibrick;
00809 
00810         /* check if the bricks are already linked */
00811         for (ibrick=0; ibrick < *tot; ibrick++) {
00812                 if ((*ppoin)[ibrick] == *poin)
00813                         return;
00814         }
00815 
00816         if (*ppoin) {
00817                 old_links= *ppoin;
00818 
00819                 (*tot) ++;
00820                 *ppoin = MEM_callocN((*tot)*size, "new link");
00821         
00822                 for (ibrick=0; ibrick < *(tot) - 1; ibrick++) {
00823                         (*ppoin)[ibrick] = old_links[ibrick];
00824                 }
00825                 (*ppoin)[ibrick] = *poin;
00826 
00827                 if(old_links) MEM_freeN(old_links);
00828         }
00829         else {
00830                 (*tot) = 1;
00831                 *ppoin = MEM_callocN((*tot)*size, "new link");
00832                 (*ppoin)[0] = *poin;
00833         }
00834 }
00835 
00836 void unlink_logicbricks(void **poin, void ***ppoin, short *tot)
00837 {
00838         int ibrick, removed;
00839 
00840         removed= 0;
00841         for (ibrick=0; ibrick < *tot; ibrick++) {
00842                 if(removed) (*ppoin)[ibrick - removed] = (*ppoin)[ibrick];
00843                 else if((*ppoin)[ibrick] == *poin) removed = 1;
00844         }
00845 
00846         if (removed) {
00847                 (*tot) --;
00848 
00849                 if(*tot == 0) {
00850                         MEM_freeN(*ppoin);
00851                         (*ppoin)= NULL;
00852                 }
00853                 return;
00854         }
00855 }