Spelling Cleanup
[blender.git] / source / gameengine / Converter / KX_ConvertSensors.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * Conversion of Blender data blocks to KX sensor system
27  */
28
29 /** \file gameengine/Converter/KX_ConvertSensors.cpp
30  *  \ingroup bgeconv
31  */
32
33
34 #include <stdio.h>
35
36 #if defined(WIN32) && !defined(FREE_WINDOWS)
37 #pragma warning (disable : 4786)
38 #endif //WIN32
39
40 #include "wm_event_types.h"
41 #include "KX_BlenderSceneConverter.h"
42 #include "KX_ConvertSensors.h"
43
44 /* This little block needed for linking to Blender... */
45 #if defined(WIN32) && !defined(FREE_WINDOWS)
46 #include "BLI_winstuff.h"
47 #endif
48
49 #include "DNA_object_types.h"
50 #include "DNA_material_types.h"
51 #include "DNA_sensor_types.h"
52 #include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
53 probably misplaced */
54 /* end of blender include block */
55
56 #include "RAS_IPolygonMaterial.h"
57 // Sensors
58 #include "KX_GameObject.h"
59 #include "RAS_MeshObject.h"
60 #include "SCA_KeyboardSensor.h"
61 #include "SCA_MouseSensor.h"
62 #include "SCA_AlwaysSensor.h"
63 #include "KX_TouchSensor.h"
64 #include "KX_NearSensor.h"
65 #include "KX_RadarSensor.h"
66 #include "KX_MouseFocusSensor.h"
67 #include "KX_ArmatureSensor.h"
68 #include "SCA_JoystickSensor.h"
69 #include "KX_NetworkMessageSensor.h"
70 #include "SCA_ActuatorSensor.h"
71 #include "SCA_DelaySensor.h"
72
73
74 #include "SCA_PropertySensor.h"
75 #include "SCA_RandomSensor.h"
76 #include "KX_RaySensor.h"
77 #include "SCA_EventManager.h"
78 #include "SCA_LogicManager.h"
79 #include "KX_BlenderInputDevice.h"
80 #include "KX_Scene.h"
81 #include "IntValue.h"
82 #include "KX_BlenderKeyboardDevice.h"
83 #include "KX_BlenderGL.h"
84 #include "RAS_ICanvas.h"
85 #include "PHY_IPhysicsEnvironment.h"
86
87 #include "KX_KetsjiEngine.h"
88 #include "KX_BlenderSceneConverter.h"
89 #include "BL_BlenderDataConversion.h"
90
91 void BL_ConvertSensors(struct Object* blenderobject,
92                                            class KX_GameObject* gameobj,
93                                            SCA_LogicManager* logicmgr,
94                                            KX_Scene* kxscene,
95                                            KX_KetsjiEngine* kxengine,
96                                            int activeLayerBitInfo,
97                                            bool isInActiveLayer,
98                                            RAS_ICanvas* canvas,
99                                            KX_BlenderSceneConverter* converter
100                                            )
101 {
102
103         int executePriority = 0;
104         int uniqueint = 0;
105         int count = 0;
106         bSensor* sens = (bSensor*)blenderobject->sensors.first;
107         bool pos_pulsemode = false;
108         bool neg_pulsemode = false;
109         int frequency = 0;
110         bool invert = false;
111         bool level = false;
112         bool tap = false;
113         
114         while (sens)
115         {
116                 sens = sens->next;
117                 count++;
118         }
119         gameobj->ReserveSensor(count);
120         sens = (bSensor*)blenderobject->sensors.first;
121         while(sens)
122         {
123                 SCA_ISensor* gamesensor=NULL;
124                 /* All sensors have a pulse toggle, frequency, and invert field.     */
125                 /* These are extracted here, and set when the sensor is added to the */
126                 /* list.                                                             */
127                 pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
128                 neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
129                 
130                 frequency = sens->freq;
131                 invert    = !(sens->invert == 0);
132                 level     = !(sens->level == 0);
133                 tap       = !(sens->tap == 0);
134
135                 switch (sens->type)
136                 {
137                 case  SENS_ALWAYS:
138                         {
139                                 
140                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
141                                 if (eventmgr)
142                                 {
143                                         gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
144                                 }
145                                 
146                                 break;
147                         }
148                         
149                 case  SENS_DELAY:
150                         {
151                                 // we can reuse the Always event manager for the delay sensor
152                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
153                                 if (eventmgr)
154                                 {
155                                         bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
156                                         gamesensor = new SCA_DelaySensor(eventmgr, 
157                                                 gameobj,
158                                                 delaysensor->delay,
159                                                 delaysensor->duration,
160                                                 (delaysensor->flag & SENS_DELAY_REPEAT) != 0);
161                                 }
162                                 break;
163                         }
164
165                 case SENS_COLLISION:
166                         {
167                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
168                                 if (eventmgr)
169                                 {
170                                         // collision sensor can sense both materials and properties. 
171                                         
172                                         bool bFindMaterial = false, bTouchPulse = false;
173                                         
174                                         bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
175                                         
176                                         bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
177                                         bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
178                                         
179                                         
180                                         STR_String touchPropOrMatName = ( bFindMaterial ? 
181                                                 blendertouchsensor->materialName:
182                                         (blendertouchsensor->name ? blendertouchsensor->name: ""));
183                                         
184                                         
185                                         if (gameobj->GetPhysicsController())
186                                         {       
187                                                 gamesensor = new KX_TouchSensor(eventmgr,
188                                                         gameobj,
189                                                         bFindMaterial,
190                                                         bTouchPulse,
191                                                         touchPropOrMatName);
192                                         }
193                                         
194                                 }
195                                 
196                                 break;
197                         }
198                 case SENS_TOUCH:
199                         {
200                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
201                                 if (eventmgr)
202                                 {
203                                         STR_String touchpropertyname;
204                                         bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
205                                         
206                                         if (blendertouchsensor->ma)
207                                         {
208                                                 touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
209                                         }
210                                         bool bFindMaterial = true;
211                                         if (gameobj->GetPhysicsController())
212                                         {       
213                                                 gamesensor = new KX_TouchSensor(eventmgr,
214                                                         gameobj,
215                                                         bFindMaterial,
216                                                         false,
217                                                         touchpropertyname);
218                                         }
219                                 }
220                                 break;
221                         }
222                 case SENS_MESSAGE:
223                         {
224                                 KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
225                                         logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
226                                 if (eventmgr) {
227                                         bMessageSensor* msgSens = (bMessageSensor*) sens->data; 
228                                         
229                                         /* Get our NetworkScene */
230                                         NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
231                                         /* filter on the incoming subjects, might be empty */
232                                         STR_String subject = (msgSens->subject
233                                                 ? (char*)msgSens->subject
234                                                 : "");
235                                         
236                                         gamesensor = new KX_NetworkMessageSensor(
237                                                 eventmgr,               // our eventmanager
238                                                 NetworkScene,   // our NetworkScene
239                                                 gameobj,                // the sensor controlling object
240                                                 subject);               // subject to filter on
241                                 }
242                                 break;
243                         }
244                 case SENS_NEAR:
245                         {
246                                 
247                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
248                                 if (eventmgr)
249                                 {
250                                         STR_String nearpropertyname;    
251                                         bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
252                                         if (blendernearsensor->name)
253                                         {
254                                                 // only objects that own this property will be taken into account
255                                                 nearpropertyname = (char*) blendernearsensor->name;
256                                         }
257                                         
258                                         //DT_ShapeHandle shape  =       DT_Sphere(0.0);
259                                         
260                                         // this sumoObject is not deleted by a gameobj, so delete it ourself
261                                         // later (memleaks)!
262                                         float radius = blendernearsensor->dist;
263                                         PHY__Vector3 pos;
264                                         const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
265                                         pos[0] = (float)wpos[0];
266                                         pos[1] = (float)wpos[1];
267                                         pos[2] = (float)wpos[2];
268                                         pos[3] = 0.f;
269                                         bool bFindMaterial = false;
270                                         PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
271
272                                         //will be done in KX_TouchEventManager::RegisterSensor()  
273                                         //if (isInActiveLayer)
274                                         //      kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
275
276                                                 
277
278                                         gamesensor = new KX_NearSensor(eventmgr,gameobj,
279                                                 blendernearsensor->dist,
280                                                 blendernearsensor->resetdist,
281                                                 bFindMaterial,
282                                                 nearpropertyname,
283                                                 physCtrl);
284                                         
285                                 }
286                                 break;
287                         }
288                         
289                         
290                 case SENS_KEYBOARD:
291                         {
292                                 /* temporary input device, for converting the code for the keyboard sensor */
293                                 
294                                 bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
295                                 SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
296                                 if (eventmgr)
297                                 {
298                                         gamesensor = new SCA_KeyboardSensor(eventmgr,
299                                                 ConvertKeyCode(blenderkeybdsensor->key),
300                                                 ConvertKeyCode(blenderkeybdsensor->qual),
301                                                 ConvertKeyCode(blenderkeybdsensor->qual2),
302                                                 (blenderkeybdsensor->type == SENS_ALL_KEYS),
303                                                 blenderkeybdsensor->targetName,
304                                                 blenderkeybdsensor->toggleName,
305                                                 gameobj); //                    blenderkeybdsensor->pad);
306                                         
307                                 } 
308                                 
309                                 break;
310                         }
311                 case SENS_MOUSE:
312                         {
313                                 int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;                        
314                                 int trackfocus = 0;
315                                 bMouseSensor *bmouse = (bMouseSensor *)sens->data;
316                                 
317                                 /* There are two main types of mouse sensors. If there is
318                                 * no focus-related behavior requested, we can make do
319                                 * with a basic sensor. This cuts down memory usage and
320                                 * gives a slight performance gain. */
321                                 
322                                 SCA_MouseManager *eventmgr 
323                                         = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
324                                 if (eventmgr) {
325                                         
326                                         /* Determine key mode. There is at most one active mode. */
327                                         switch (bmouse->type) {
328                                         case BL_SENS_MOUSE_LEFT_BUTTON:
329                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
330                                                 break;
331                                         case BL_SENS_MOUSE_MIDDLE_BUTTON:
332                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
333                                                 break;
334                                         case BL_SENS_MOUSE_RIGHT_BUTTON:
335                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
336                                                 break;
337                                         case BL_SENS_MOUSE_WHEEL_UP:
338                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
339                                                 break;
340                                         case BL_SENS_MOUSE_WHEEL_DOWN:
341                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
342                                                 break;
343                                         case BL_SENS_MOUSE_MOVEMENT:
344                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
345                                                 break;
346                                         case BL_SENS_MOUSE_MOUSEOVER:
347                                                 trackfocus = 1;
348                                                 break;
349                                         case BL_SENS_MOUSE_MOUSEOVER_ANY:
350                                                 trackfocus = 2;
351                                                 break;
352
353                                         default:
354                                                 ; /* error */
355                                         }
356                                         
357                                         /* initial mouse position */                             
358                                         int startx  = canvas->GetWidth()/2;
359                                         int starty = canvas->GetHeight()/2;
360                                         
361                                         if (!trackfocus) {
362                                                 /* plain, simple mouse sensor */
363                                                 gamesensor = new SCA_MouseSensor(eventmgr,
364                                                         startx,starty,
365                                                         keytype,
366                                                         gameobj);
367                                         } else {
368                                                 /* give us a focus-aware sensor */
369                                                 gamesensor = new KX_MouseFocusSensor(eventmgr,
370                                                         startx,
371                                                         starty,
372                                                         keytype,
373                                                         trackfocus,
374                                                         (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
375                                                         kxscene,
376                                                         kxengine,
377                                                         gameobj); 
378                                         }
379                                 } else {
380                                         //                              cout << "\n Could't find mouse event manager..."; - should throw an error here... 
381                                 }
382                                 break;
383                         }
384                 case SENS_PROPERTY:
385                         {
386                                 bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
387                                 SCA_EventManager* eventmgr 
388                                         = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
389                                 if (eventmgr)
390                                 {
391                                         STR_String propname=blenderpropsensor->name;
392                                         STR_String propval=blenderpropsensor->value;
393                                         STR_String propmaxval=blenderpropsensor->maxvalue;
394                                         
395                                         SCA_PropertySensor::KX_PROPSENSOR_TYPE 
396                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
397                                         
398                                         /* Better do an explicit conversion here! (was implicit      */
399                                         /* before...)                                                */
400                                         switch(blenderpropsensor->type) {
401                                         case SENS_PROP_EQUAL:
402                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
403                                                 break;
404                                         case SENS_PROP_NEQUAL:
405                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
406                                                 break;
407                                         case SENS_PROP_INTERVAL:
408                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
409                                                 break;
410                                         case SENS_PROP_CHANGED:
411                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
412                                                 break;
413                                         case SENS_PROP_EXPRESSION:
414                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
415                                                 /* error */
416                                                 break;
417                                         default:
418                                                 ; /* error */
419                                         }
420                                         gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
421                                 }
422                                 
423                                 break;
424                         }
425                 case SENS_ACTUATOR:
426                         {
427                                 bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
428                                 // we will reuse the property event manager, there is nothing special with this sensor
429                                 SCA_EventManager* eventmgr 
430                                         = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
431                                 if (eventmgr)
432                                 {
433                                         STR_String propname=blenderactsensor->name;
434                                         gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
435                                 }
436                                 break;
437                         }
438                         
439                 case SENS_ARMATURE:
440                         {
441                                 bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
442                                 // we will reuse the property event manager, there is nothing special with this sensor
443                                 SCA_EventManager* eventmgr 
444                                         = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
445                                 if (eventmgr)
446                                 {
447                                         STR_String bonename=blenderarmsensor->posechannel;
448                                         STR_String constraintname=blenderarmsensor->constraint;
449                                         gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
450                                 }
451                                 break;
452                         }
453
454                 case SENS_RADAR:
455                         {
456                                 
457                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
458                                 if (eventmgr)
459                                 {
460                                         STR_String radarpropertyname;
461                                         STR_String touchpropertyname;
462                                         bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
463                                         
464                                         int radaraxis = blenderradarsensor->axis;
465                                         
466                                         if (blenderradarsensor->name)
467                                         {
468                                                 // only objects that own this property will be taken into account
469                                                 radarpropertyname = (char*) blenderradarsensor->name;
470                                         }
471                                         
472                                         MT_Scalar coneheight = blenderradarsensor->range;
473                                         
474                                         // janco: the angle was doubled, so should I divide the factor in 2
475                                         // or the blenderradarsensor->angle?
476                                         // nzc: the angle is the opening angle. We need to init with 
477                                         // the axis-hull angle,so /2.0.
478                                         MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
479                                         //MT_Scalar coneradius = coneheight * (factor / 2);
480                                         MT_Scalar coneradius = coneheight * factor;
481                                         
482                                         
483                                         // this sumoObject is not deleted by a gameobj, so delete it ourself
484                                         // later (memleaks)!
485                                         MT_Scalar smallmargin = 0.0;
486                                         MT_Scalar largemargin = 0.0;
487                                         
488                                         bool bFindMaterial = false;
489                                         PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight);
490
491                                         gamesensor = new KX_RadarSensor(
492                                                 eventmgr,
493                                                 gameobj,
494                                                 ctrl,
495                                                 coneradius,
496                                                 coneheight,
497                                                 radaraxis,
498                                                 smallmargin,
499                                                 largemargin,
500                                                 bFindMaterial,
501                                                 radarpropertyname);
502                                                 
503                                 }
504                         
505                                 break;
506                         }
507                 case SENS_RAY:
508                         {
509                                 bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
510                                 
511                                 //blenderradarsensor->angle;
512                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
513                                 if (eventmgr)
514                                 {
515                                         bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
516                                         bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
517                                         
518                                         STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
519
520                                         // don't want to get rays of length 0.0 or so
521                                         double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
522                                         int axis = blenderraysensor->axisflag;
523
524                                         
525                                         gamesensor = new KX_RaySensor(eventmgr,
526                                                                                                   gameobj,
527                                                                                                   checkname,
528                                                                                                   bFindMaterial,
529                                                                                                   bXRay,
530                                                                                                   distance,
531                                                                                                   axis,
532                                                                                                   kxscene);
533
534                                 }
535                                 break;
536                         }
537                         
538                 case SENS_RANDOM:
539                         {
540                                 bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
541                                 // some files didn't write randomsensor, avoid crash now for NULL ptr's
542                                 if (blenderrndsensor)
543                                 {
544                                         SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
545                                         if (eventmgr)
546                                         {
547                                                 int randomSeed = blenderrndsensor->seed;
548                                                 if (randomSeed == 0)
549                                                 {
550                                                         randomSeed = (int)(kxengine->GetRealTime()*100000.0);
551                                                         randomSeed ^= (intptr_t)blenderrndsensor;
552                                                 }
553                                                 gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
554                                         }
555                                 }
556                                 break;
557                         }
558                 case SENS_JOYSTICK:
559                         {
560                                 int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
561                                 
562                                 bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
563                                 
564                                 SCA_JoystickManager *eventmgr 
565                                         = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
566                                 if (eventmgr) 
567                                 {
568                                         int axis        =0;
569                                         int axisf       =0;
570                                         int button      =0;
571                                         int hat         =0; 
572                                         int hatf        =0;
573                                         int prec        =0;
574                                         
575                                         switch(bjoy->type)
576                                         {
577                                         case SENS_JOY_AXIS:
578                                                 axis    = bjoy->axis;
579                                                 axisf   = bjoy->axisf;
580                                                 prec    = bjoy->precision;
581                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
582                                                 break;
583                                         case SENS_JOY_BUTTON:
584                                                 button  = bjoy->button;
585                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
586                                                 break;
587                                         case SENS_JOY_HAT:
588                                                 hat             = bjoy->hat;
589                                                 hatf    = bjoy->hatf;
590                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
591                                                 break;
592                                         case SENS_JOY_AXIS_SINGLE:
593                                                 axis    = bjoy->axis_single;
594                                                 prec    = bjoy->precision;
595                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
596                                                 break;
597                                         default:
598                                                 printf("Error: bad case statement\n");
599                                                 break;
600                                         }
601                                         gamesensor = new SCA_JoystickSensor(
602                                                 eventmgr,
603                                                 gameobj,
604                                                 bjoy->joyindex,
605                                                 joysticktype,
606                                                 axis,axisf,
607                                                 prec,
608                                                 button,
609                                                 hat,hatf,
610                                                 (bjoy->flag & SENS_JOY_ANY_EVENT));
611                                 } 
612                                 else
613                                 {
614                                         printf("Error there was a problem finding the event manager\n");
615                                 }
616
617                                 break;
618                         }
619                 default:
620                         {
621                         }
622                 }
623
624                 if (gamesensor)
625                 {
626                         gamesensor->SetExecutePriority(executePriority++);
627                         STR_String uniquename = sens->name;
628                         uniquename += "#SENS#";
629                         uniqueint++;
630                         CIntValue* uniqueval = new CIntValue(uniqueint);
631                         uniquename += uniqueval->GetText();
632                         uniqueval->Release();
633                         
634                         /* Conversion succeeded, so we can set the generic props here.   */
635                         gamesensor->SetPulseMode(pos_pulsemode, 
636                                                                          neg_pulsemode, 
637                                                                          frequency);
638                         gamesensor->SetInvert(invert);
639                         gamesensor->SetLevel(level);
640                         gamesensor->SetTap(tap);
641                         gamesensor->SetName(sens->name);                        
642                         
643                         gameobj->AddSensor(gamesensor);
644                         
645                         // only register to manager if it's in an active layer
646                         // Make registration dynamic: only when sensor is activated
647                         //if (isInActiveLayer)
648                         //      gamesensor->RegisterToManager();
649                         
650                         gamesensor->ReserveController(sens->totlinks);
651                         for (int i=0;i<sens->totlinks;i++)
652                         {
653                                 bController* linkedcont = (bController*) sens->links[i];
654                                 if (linkedcont) {
655                                         SCA_IController* gamecont = converter->FindGameController(linkedcont);
656
657                                         if (gamecont) {
658                                                 logicmgr->RegisterToSensor(gamecont,gamesensor);
659                                         } else {
660                                                 printf(
661                                                         "Warning, sensor \"%s\" could not find its controller "
662                                                         "(link %d of %d) from object \"%s\"\n"
663                                                         "\tthere has been an error converting the blender controller for the game engine,"
664                                                         "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
665                                         }
666                                 } else {
667                                         printf(
668                                                 "Warning, sensor \"%s\" has lost a link to a controller "
669                                                 "(link %d of %d) from object \"%s\"\n"
670                                                 "\tpossible causes are partially appended objects or an error reading the file,"
671                                                 "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
672                                 }
673                         }
674                         // special case: Keyboard sensor with no link
675                         // this combination is usually used for key logging. 
676                         if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
677                                 // Force the registration so that the sensor runs
678                                 gamesensor->IncLink();
679                         }
680                                 
681                         // done with gamesensor
682                         gamesensor->Release();
683                         
684                 }
685                 sens=sens->next;
686         }
687 }
688