Merging r50192 through r50223 from trunk into soc-2011-tomato
[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  */
27
28 /** \file gameengine/Converter/KX_ConvertSensors.cpp
29  *  \ingroup bgeconv
30  *
31  * Conversion of Blender data blocks to KX sensor system
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,
306                                                 KX_KetsjiEngine::GetExitKey()); //                      blenderkeybdsensor->pad);
307                                         
308                                 } 
309                                 
310                                 break;
311                         }
312                 case SENS_MOUSE:
313                         {
314                                 int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;                        
315                                 int trackfocus = 0;
316                                 bMouseSensor *bmouse = (bMouseSensor *)sens->data;
317                                 
318                                 /* There are two main types of mouse sensors. If there is
319                                  * no focus-related behavior requested, we can make do
320                                  * with a basic sensor. This cuts down memory usage and
321                                  * gives a slight performance gain. */
322                                 
323                                 SCA_MouseManager *eventmgr 
324                                         = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
325                                 if (eventmgr) {
326                                         
327                                         /* Determine key mode. There is at most one active mode. */
328                                         switch (bmouse->type) {
329                                         case BL_SENS_MOUSE_LEFT_BUTTON:
330                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
331                                                 break;
332                                         case BL_SENS_MOUSE_MIDDLE_BUTTON:
333                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
334                                                 break;
335                                         case BL_SENS_MOUSE_RIGHT_BUTTON:
336                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
337                                                 break;
338                                         case BL_SENS_MOUSE_WHEEL_UP:
339                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
340                                                 break;
341                                         case BL_SENS_MOUSE_WHEEL_DOWN:
342                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
343                                                 break;
344                                         case BL_SENS_MOUSE_MOVEMENT:
345                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
346                                                 break;
347                                         case BL_SENS_MOUSE_MOUSEOVER:
348                                                 trackfocus = 1;
349                                                 break;
350                                         case BL_SENS_MOUSE_MOUSEOVER_ANY:
351                                                 trackfocus = 2;
352                                                 break;
353
354                                         default:
355                                                 ; /* error */
356                                         }
357                                         
358                                         /* initial mouse position */                             
359                                         int startx  = canvas->GetWidth()/2;
360                                         int starty = canvas->GetHeight()/2;
361                                         
362                                         if (!trackfocus) {
363                                                 /* plain, simple mouse sensor */
364                                                 gamesensor = new SCA_MouseSensor(eventmgr,
365                                                         startx,starty,
366                                                         keytype,
367                                                         gameobj);
368                                         } else {
369                                                 /* give us a focus-aware sensor */
370                                                 gamesensor = new KX_MouseFocusSensor(eventmgr,
371                                                         startx,
372                                                         starty,
373                                                         keytype,
374                                                         trackfocus,
375                                                         (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
376                                                         kxscene,
377                                                         kxengine,
378                                                         gameobj); 
379                                         }
380                                 } else {
381                                         //                              cout << "\n Could't find mouse event manager..."; - should throw an error here... 
382                                 }
383                                 break;
384                         }
385                 case SENS_PROPERTY:
386                         {
387                                 bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
388                                 SCA_EventManager* eventmgr 
389                                         = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
390                                 if (eventmgr)
391                                 {
392                                         STR_String propname=blenderpropsensor->name;
393                                         STR_String propval=blenderpropsensor->value;
394                                         STR_String propmaxval=blenderpropsensor->maxvalue;
395                                         
396                                         SCA_PropertySensor::KX_PROPSENSOR_TYPE 
397                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
398                                         
399                                         /* Better do an explicit conversion here! (was implicit      */
400                                         /* before...)                                                */
401                                         switch(blenderpropsensor->type) {
402                                         case SENS_PROP_EQUAL:
403                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
404                                                 break;
405                                         case SENS_PROP_NEQUAL:
406                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
407                                                 break;
408                                         case SENS_PROP_INTERVAL:
409                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
410                                                 break;
411                                         case SENS_PROP_CHANGED:
412                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
413                                                 break;
414                                         case SENS_PROP_EXPRESSION:
415                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
416                                                 /* error */
417                                                 break;
418                                         default:
419                                                 ; /* error */
420                                         }
421                                         gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
422                                 }
423                                 
424                                 break;
425                         }
426                 case SENS_ACTUATOR:
427                         {
428                                 bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
429                                 // we will reuse the property event manager, there is nothing special with this sensor
430                                 SCA_EventManager* eventmgr 
431                                         = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
432                                 if (eventmgr)
433                                 {
434                                         STR_String propname=blenderactsensor->name;
435                                         gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
436                                 }
437                                 break;
438                         }
439                         
440                 case SENS_ARMATURE:
441                         {
442                                 bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
443                                 // we will reuse the property event manager, there is nothing special with this sensor
444                                 SCA_EventManager* eventmgr 
445                                         = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
446                                 if (eventmgr)
447                                 {
448                                         STR_String bonename=blenderarmsensor->posechannel;
449                                         STR_String constraintname=blenderarmsensor->constraint;
450                                         gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
451                                 }
452                                 break;
453                         }
454
455                 case SENS_RADAR:
456                         {
457                                 
458                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
459                                 if (eventmgr)
460                                 {
461                                         STR_String radarpropertyname;
462                                         STR_String touchpropertyname;
463                                         bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
464                                         
465                                         int radaraxis = blenderradarsensor->axis;
466                                         
467                                         if (blenderradarsensor->name)
468                                         {
469                                                 // only objects that own this property will be taken into account
470                                                 radarpropertyname = (char*) blenderradarsensor->name;
471                                         }
472                                         
473                                         MT_Scalar coneheight = blenderradarsensor->range;
474                                         
475                                         // janco: the angle was doubled, so should I divide the factor in 2
476                                         // or the blenderradarsensor->angle?
477                                         // nzc: the angle is the opening angle. We need to init with 
478                                         // the axis-hull angle,so /2.0.
479                                         MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle) / 2.0f));
480                                         //MT_Scalar coneradius = coneheight * (factor / 2);
481                                         MT_Scalar coneradius = coneheight * factor;
482                                         
483                                         
484                                         // this sumoObject is not deleted by a gameobj, so delete it ourself
485                                         // later (memleaks)!
486                                         MT_Scalar smallmargin = 0.0;
487                                         MT_Scalar largemargin = 0.0;
488                                         
489                                         bool bFindMaterial = false;
490                                         PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight);
491
492                                         gamesensor = new KX_RadarSensor(
493                                                 eventmgr,
494                                                 gameobj,
495                                                 ctrl,
496                                                 coneradius,
497                                                 coneheight,
498                                                 radaraxis,
499                                                 smallmargin,
500                                                 largemargin,
501                                                 bFindMaterial,
502                                                 radarpropertyname);
503                                                 
504                                 }
505                         
506                                 break;
507                         }
508                 case SENS_RAY:
509                         {
510                                 bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
511                                 
512                                 //blenderradarsensor->angle;
513                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
514                                 if (eventmgr)
515                                 {
516                                         bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
517                                         bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
518                                         
519                                         STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
520
521                                         // don't want to get rays of length 0.0 or so
522                                         double distance = (blenderraysensor->range < 0.01f ? 0.01f : blenderraysensor->range);
523                                         int axis = blenderraysensor->axisflag;
524
525                                         
526                                         gamesensor = new KX_RaySensor(eventmgr,
527                                                                                                   gameobj,
528                                                                                                   checkname,
529                                                                                                   bFindMaterial,
530                                                                                                   bXRay,
531                                                                                                   distance,
532                                                                                                   axis,
533                                                                                                   kxscene);
534
535                                 }
536                                 break;
537                         }
538                         
539                 case SENS_RANDOM:
540                         {
541                                 bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
542                                 // some files didn't write randomsensor, avoid crash now for NULL ptr's
543                                 if (blenderrndsensor)
544                                 {
545                                         SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
546                                         if (eventmgr)
547                                         {
548                                                 int randomSeed = blenderrndsensor->seed;
549                                                 if (randomSeed == 0)
550                                                 {
551                                                         randomSeed = (int)(kxengine->GetRealTime()*100000.0);
552                                                         randomSeed ^= (intptr_t)blenderrndsensor;
553                                                 }
554                                                 gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
555                                         }
556                                 }
557                                 break;
558                         }
559                 case SENS_JOYSTICK:
560                         {
561                                 int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
562                                 
563                                 bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
564                                 
565                                 SCA_JoystickManager *eventmgr 
566                                         = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
567                                 if (eventmgr) 
568                                 {
569                                         int axis        =0;
570                                         int axisf       =0;
571                                         int button      =0;
572                                         int hat         =0; 
573                                         int hatf        =0;
574                                         int prec        =0;
575                                         
576                                         switch(bjoy->type)
577                                         {
578                                         case SENS_JOY_AXIS:
579                                                 axis    = bjoy->axis;
580                                                 axisf   = bjoy->axisf;
581                                                 prec    = bjoy->precision;
582                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
583                                                 break;
584                                         case SENS_JOY_BUTTON:
585                                                 button  = bjoy->button;
586                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
587                                                 break;
588                                         case SENS_JOY_HAT:
589                                                 hat             = bjoy->hat;
590                                                 hatf    = bjoy->hatf;
591                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
592                                                 break;
593                                         case SENS_JOY_AXIS_SINGLE:
594                                                 axis    = bjoy->axis_single;
595                                                 prec    = bjoy->precision;
596                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
597                                                 break;
598                                         default:
599                                                 printf("Error: bad case statement\n");
600                                                 break;
601                                         }
602                                         gamesensor = new SCA_JoystickSensor(
603                                                 eventmgr,
604                                                 gameobj,
605                                                 bjoy->joyindex,
606                                                 joysticktype,
607                                                 axis,axisf,
608                                                 prec,
609                                                 button,
610                                                 hat,hatf,
611                                                 (bjoy->flag & SENS_JOY_ANY_EVENT));
612                                 } 
613                                 else
614                                 {
615                                         printf("Error there was a problem finding the event manager\n");
616                                 }
617
618                                 break;
619                         }
620                 default:
621                         {
622                         }
623                 }
624
625                 if (gamesensor)
626                 {
627                         gamesensor->SetExecutePriority(executePriority++);
628                         STR_String uniquename = sens->name;
629                         uniquename += "#SENS#";
630                         uniqueint++;
631                         CIntValue* uniqueval = new CIntValue(uniqueint);
632                         uniquename += uniqueval->GetText();
633                         uniqueval->Release();
634                         
635                         /* Conversion succeeded, so we can set the generic props here.   */
636                         gamesensor->SetPulseMode(pos_pulsemode, 
637                                                                          neg_pulsemode, 
638                                                                          frequency);
639                         gamesensor->SetInvert(invert);
640                         gamesensor->SetLevel(level);
641                         gamesensor->SetTap(tap);
642                         gamesensor->SetName(sens->name);                        
643                         
644                         gameobj->AddSensor(gamesensor);
645                         
646                         // only register to manager if it's in an active layer
647                         // Make registration dynamic: only when sensor is activated
648                         //if (isInActiveLayer)
649                         //      gamesensor->RegisterToManager();
650                         
651                         gamesensor->ReserveController(sens->totlinks);
652                         for (int i=0;i<sens->totlinks;i++)
653                         {
654                                 bController* linkedcont = (bController*) sens->links[i];
655                                 if (linkedcont) {
656                                         SCA_IController* gamecont = converter->FindGameController(linkedcont);
657
658                                         if (gamecont) {
659                                                 logicmgr->RegisterToSensor(gamecont,gamesensor);
660                                         }
661                                         else {
662                                                 printf("Warning, sensor \"%s\" could not find its controller "
663                                                        "(link %d of %d) from object \"%s\"\n"
664                                                        "\tthere has been an error converting the blender controller for the game engine,"
665                                                        "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
666                                         }
667                                 }
668                                 else {
669                                         printf("Warning, sensor \"%s\" has lost a link to a controller "
670                                                "(link %d of %d) from object \"%s\"\n"
671                                                "\tpossible causes are partially appended objects or an error reading the file,"
672                                                "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
673                                 }
674                         }
675                         // special case: Keyboard sensor with no link
676                         // this combination is usually used for key logging. 
677                         if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
678                                 // Force the registration so that the sensor runs
679                                 gamesensor->IncLink();
680                         }
681                                 
682                         // done with gamesensor
683                         gamesensor->Release();
684                         
685                 }
686                 sens=sens->next;
687         }
688 }
689