doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / Converter / KX_ConvertControllers.cpp
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include "MEM_guardedalloc.h"
30
31 #include "KX_BlenderSceneConverter.h"
32 #include "KX_ConvertControllers.h"
33 #include "KX_Python.h"
34
35 // Controller
36 #include "SCA_ANDController.h"
37 #include "SCA_ORController.h"
38 #include "SCA_NANDController.h"
39 #include "SCA_NORController.h"
40 #include "SCA_XORController.h"
41 #include "SCA_XNORController.h"
42 #include "SCA_PythonController.h"
43 #include "SCA_ExpressionController.h"
44
45 #include "SCA_LogicManager.h"
46 #include "KX_GameObject.h"
47 #include "IntValue.h"
48
49 /* This little block needed for linking to Blender... */
50 #ifdef WIN32
51 #include "BLI_winstuff.h"
52 #endif
53
54 #include "DNA_object_types.h"
55 #include "DNA_controller_types.h"
56 #include "DNA_text_types.h"
57
58 #include "BKE_text.h"
59
60 #include "BLI_blenlib.h"
61
62 /* end of blender include block */
63
64
65         static void
66 LinkControllerToActuators(
67         SCA_IController *game_controller,
68         bController* bcontr,    
69         SCA_LogicManager* logicmgr,
70         KX_BlenderSceneConverter* converter
71 ) {
72         // Iterate through the actuators of the game blender
73         // controller and find the corresponding ketsji actuator.
74
75         game_controller->ReserveActuator(bcontr->totlinks);
76         for (int i=0;i<bcontr->totlinks;i++)
77         {
78                 bActuator* bact = (bActuator*) bcontr->links[i];
79                 SCA_IActuator *game_actuator = converter->FindGameActuator(bact);
80                 if (game_actuator) {
81                         logicmgr->RegisterToActuator(game_controller, game_actuator);
82                 }
83         }
84 }
85
86
87 void BL_ConvertControllers(
88         struct Object* blenderobject,
89         class KX_GameObject* gameobj,
90         SCA_LogicManager* logicmgr,
91         int activeLayerBitInfo,
92         bool isInActiveLayer,
93         KX_BlenderSceneConverter* converter
94 ) {
95         int uniqueint=0;
96         int count = 0;
97         int executePriority=0;
98         bController* bcontr = (bController*)blenderobject->controllers.first;
99         while (bcontr)
100         {
101                 bcontr = bcontr->next;
102                 count++;
103         }
104         gameobj->ReserveController(count);
105         bcontr = (bController*)blenderobject->controllers.first;
106         while (bcontr)
107         {
108                 SCA_IController* gamecontroller = NULL;
109                 switch(bcontr->type)
110                 {
111                         case CONT_LOGIC_AND:
112                         {
113                                 gamecontroller = new SCA_ANDController(gameobj);
114                                 break;
115                         }
116                         case CONT_LOGIC_OR:
117                         {
118                                 gamecontroller = new SCA_ORController(gameobj);
119                                 break;
120                         }
121                         case CONT_LOGIC_NAND:
122                         {
123                                 gamecontroller = new SCA_NANDController(gameobj);
124                                 break;
125                         }
126                         case CONT_LOGIC_NOR:
127                         {
128                                 gamecontroller = new SCA_NORController(gameobj);
129                                 break;
130                         }
131                         case CONT_LOGIC_XOR:
132                         {
133                                 gamecontroller = new SCA_XORController(gameobj);
134                                 break;
135                         }
136                         case CONT_LOGIC_XNOR:
137                         {
138                                 gamecontroller = new SCA_XNORController(gameobj);
139                                 break;
140                         }
141                         case CONT_EXPRESSION:
142                         {
143                                 bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
144                                 STR_String expressiontext = STR_String(bexpcont->str);
145                                 if (expressiontext.Length() > 0)
146                                 {
147                                         gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
148                                 }
149                                 break;
150                         }
151                         case CONT_PYTHON:
152                         {
153                                 bPythonCont* pycont = (bPythonCont*) bcontr->data;
154                                 SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
155                                 gamecontroller = pyctrl;
156 #ifdef WITH_PYTHON
157
158                                 pyctrl->SetNamespace(converter->GetPyNamespace());
159                                 
160                                 if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
161                                         if (pycont->text)
162                                         {
163                                                 char *buf;
164                                                 // this is some blender specific code
165                                                 buf= txt_to_buf(pycont->text);
166                                                 if (buf)
167                                                 {
168                                                         pyctrl->SetScriptText(STR_String(buf));
169                                                         pyctrl->SetScriptName(pycont->text->id.name+2);
170                                                         MEM_freeN(buf);
171                                                 }
172                                                 
173                                         }
174                                 }
175                                 else {
176                                         /* let the controller print any warnings here when importing */
177                                         pyctrl->SetScriptText(STR_String(pycont->module)); 
178                                         pyctrl->SetScriptName(pycont->module); /* will be something like module.func so using it as the name is OK */
179
180                                         if(pycont->flag & CONT_PY_DEBUG) {
181                                                 printf("\nDebuging \"%s\", module for object %s\n\texpect worse performance.\n", pycont->module, blenderobject->id.name+2);
182                                                 pyctrl->SetDebug(true);
183                                         }
184                                 }
185                                 
186 #endif // WITH_PYTHON
187
188                                 break;
189                         }
190                         default:
191                         {
192                                 
193                         }
194                 }
195
196                 if (gamecontroller)
197                 {
198                         LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
199                         gamecontroller->SetExecutePriority(executePriority++);
200                         gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0);
201                         gamecontroller->SetState(bcontr->state_mask);
202                         STR_String uniquename = bcontr->name;
203                         uniquename += "#CONTR#";
204                         uniqueint++;
205                         CIntValue* uniqueval = new CIntValue(uniqueint);
206                         uniquename += uniqueval->GetText();
207                         uniqueval->Release();
208                         gamecontroller->SetName(uniquename);
209                         gameobj->AddController(gamecontroller);
210                         
211                         converter->RegisterGameController(gamecontroller, bcontr);
212
213 #ifdef WITH_PYTHON
214                         if (bcontr->type==CONT_PYTHON) {
215                                 SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
216                                 /* not strictly needed but gives syntax errors early on and
217                                  * gives more predictable performance for larger scripts */
218                                 if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
219                                         pyctrl->Compile();
220                                 else {
221                                         /* We cant do this because importing runs the script which could end up accessing
222                                          * internal BGE functions, this is unstable while we're converting the scene.
223                                          * This is a pitty because its useful to see errors at startup but cant help it */
224                                         
225                                         // pyctrl->Import();
226                                 }
227                         }
228 #endif // WITH_PYTHON
229
230                         //done with gamecontroller
231                         gamecontroller->Release();
232                 }
233                 
234                 bcontr = bcontr->next;
235         }
236
237 }